summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addon-sdk/source/python-lib/mozrunner/killableprocess.py8
-rw-r--r--b2g/LICENSE373
-rw-r--r--b2g/Makefile.in6
-rw-r--r--b2g/app.mozbuild15
-rw-r--r--b2g/app/Makefile.in66
-rw-r--r--b2g/app/b2g.js1018
-rw-r--r--b2g/app/macbuild/Contents/Info.plist.in67
-rw-r--r--b2g/app/macbuild/Contents/MacOS-files.in9
-rw-r--r--b2g/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in5
-rw-r--r--b2g/app/moz.build76
-rw-r--r--b2g/app/nsBrowserApp.cpp239
-rw-r--r--b2g/app/ua-update.json.in51
-rw-r--r--b2g/branding/branding-common.mozbuild23
-rw-r--r--b2g/branding/browserhtml/app.icnsbin256255 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/app.icobin370070 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/background.pngbin129900 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/configure.sh5
-rw-r--r--b2g/branding/browserhtml/content/about.pngbin25842 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/content/favicon32.pngbin2670 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/content/icon48.pngbin5302 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/content/icon64.pngbin8267 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/content/jar.mn10
-rw-r--r--b2g/branding/browserhtml/content/logo.pngbin19488 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/content/logoWordmark.pngbin14021 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/content/moz.build7
-rw-r--r--b2g/branding/browserhtml/content/splash.pngbin19610 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/default.pngbin36395 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/disk.icnsbin891873 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/dsstorebin12292 -> 0 bytes
-rw-r--r--b2g/branding/browserhtml/locales/en-US/brand.dtd7
-rw-r--r--b2g/branding/browserhtml/locales/en-US/brand.properties6
-rw-r--r--b2g/branding/browserhtml/locales/jar.mn11
-rw-r--r--b2g/branding/browserhtml/locales/moz.build7
-rw-r--r--b2g/branding/browserhtml/moz.build10
-rw-r--r--b2g/branding/horizon/app.icnsbin53371 -> 0 bytes
-rw-r--r--b2g/branding/horizon/app.icobin15086 -> 0 bytes
-rw-r--r--b2g/branding/horizon/background.pngbin129900 -> 0 bytes
-rw-r--r--b2g/branding/horizon/configure.sh5
-rw-r--r--b2g/branding/horizon/content/about.pngbin25842 -> 0 bytes
-rw-r--r--b2g/branding/horizon/content/favicon32.pngbin2670 -> 0 bytes
-rw-r--r--b2g/branding/horizon/content/icon48.pngbin5302 -> 0 bytes
-rw-r--r--b2g/branding/horizon/content/icon64.pngbin8267 -> 0 bytes
-rw-r--r--b2g/branding/horizon/content/jar.mn10
-rw-r--r--b2g/branding/horizon/content/logo.pngbin19488 -> 0 bytes
-rw-r--r--b2g/branding/horizon/content/logoWordmark.pngbin14021 -> 0 bytes
-rw-r--r--b2g/branding/horizon/content/moz.build7
-rw-r--r--b2g/branding/horizon/content/splash.pngbin19610 -> 0 bytes
-rw-r--r--b2g/branding/horizon/default.pngbin51360 -> 0 bytes
-rw-r--r--b2g/branding/horizon/disk.icnsbin891873 -> 0 bytes
-rw-r--r--b2g/branding/horizon/dsstorebin12292 -> 0 bytes
-rw-r--r--b2g/branding/horizon/locales/en-US/brand.dtd8
-rw-r--r--b2g/branding/horizon/locales/en-US/brand.properties6
-rw-r--r--b2g/branding/horizon/locales/jar.mn11
-rw-r--r--b2g/branding/horizon/locales/moz.build7
-rw-r--r--b2g/branding/horizon/moz.build10
-rw-r--r--b2g/branding/official/app.icnsbin11953 -> 0 bytes
-rw-r--r--b2g/branding/official/app.icobin4286 -> 0 bytes
-rw-r--r--b2g/branding/official/background.pngbin129900 -> 0 bytes
-rw-r--r--b2g/branding/official/configure.sh6
-rw-r--r--b2g/branding/official/content/about.pngbin25842 -> 0 bytes
-rw-r--r--b2g/branding/official/content/favicon32.pngbin2670 -> 0 bytes
-rw-r--r--b2g/branding/official/content/icon48.pngbin5302 -> 0 bytes
-rw-r--r--b2g/branding/official/content/icon64.pngbin8267 -> 0 bytes
-rw-r--r--b2g/branding/official/content/jar.mn10
-rw-r--r--b2g/branding/official/content/logo.pngbin19488 -> 0 bytes
-rw-r--r--b2g/branding/official/content/logoWordmark.pngbin14021 -> 0 bytes
-rw-r--r--b2g/branding/official/content/moz.build7
-rw-r--r--b2g/branding/official/content/splash.pngbin19610 -> 0 bytes
-rw-r--r--b2g/branding/official/default.pngbin4762 -> 0 bytes
-rw-r--r--b2g/branding/official/disk.icnsbin891873 -> 0 bytes
-rw-r--r--b2g/branding/official/dsstorebin12292 -> 0 bytes
-rw-r--r--b2g/branding/official/locales/en-US/brand.dtd8
-rw-r--r--b2g/branding/official/locales/en-US/brand.properties6
-rw-r--r--b2g/branding/official/locales/jar.mn11
-rw-r--r--b2g/branding/official/locales/moz.build7
-rw-r--r--b2g/branding/official/moz.build10
-rw-r--r--b2g/branding/unofficial/app.icnsbin11953 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/app.icobin4286 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/background.pngbin129900 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/configure.sh6
-rw-r--r--b2g/branding/unofficial/content/about.pngbin16858 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/content/favicon32.pngbin1761 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/content/icon48.pngbin4053 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/content/icon64.pngbin5897 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/content/jar.mn10
-rw-r--r--b2g/branding/unofficial/content/logo.pngbin19844 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/content/logoWordmark.pngbin15088 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/content/moz.build7
-rw-r--r--b2g/branding/unofficial/content/splash.pngbin19766 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/default.pngbin4762 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/disk.icnsbin891873 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/dsstorebin12292 -> 0 bytes
-rw-r--r--b2g/branding/unofficial/locales/en-US/brand.dtd8
-rw-r--r--b2g/branding/unofficial/locales/en-US/brand.properties6
-rw-r--r--b2g/branding/unofficial/locales/jar.mn11
-rw-r--r--b2g/branding/unofficial/locales/moz.build7
-rw-r--r--b2g/branding/unofficial/moz.build10
-rw-r--r--b2g/build.mk31
-rw-r--r--b2g/chrome/content/ErrorPage.js73
-rw-r--r--b2g/chrome/content/aboutCertError.xhtml233
-rw-r--r--b2g/chrome/content/arrow.svg5
-rw-r--r--b2g/chrome/content/blank.css7
-rw-r--r--b2g/chrome/content/blank.html10
-rw-r--r--b2g/chrome/content/content.css321
-rw-r--r--b2g/chrome/content/desktop.css59
-rw-r--r--b2g/chrome/content/desktop.js179
-rw-r--r--b2g/chrome/content/devtools/adb.js233
-rw-r--r--b2g/chrome/content/devtools/debugger.js397
-rw-r--r--b2g/chrome/content/devtools/hud.js1017
-rw-r--r--b2g/chrome/content/identity.js166
-rw-r--r--b2g/chrome/content/images/arrowdown-16.pngbin246 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/arrowright-16.pngbin235 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/desktop/home-black.pngbin331 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/desktop/home-white.pngbin276 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/desktop/rotate.pngbin657 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/error.pngbin433 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/errorpage-larry-black.pngbin850 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/errorpage-larry-white.pngbin886 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/errorpage-warning.pngbin631 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/exitfullscreen-hdpi.pngbin3409 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/fullscreen-hdpi.pngbin3382 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/mute-hdpi.pngbin3217 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/pause-hdpi.pngbin3042 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/play-hdpi.pngbin3318 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/scrubber-hdpi.pngbin3967 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/throbber.pngbin11862 -> 0 bytes
-rw-r--r--b2g/chrome/content/images/unmute-hdpi.pngbin3259 -> 0 bytes
-rw-r--r--b2g/chrome/content/netError.css131
-rw-r--r--b2g/chrome/content/screen.js276
-rw-r--r--b2g/chrome/content/settings.js698
-rw-r--r--b2g/chrome/content/shell.css81
-rw-r--r--b2g/chrome/content/shell.html66
-rw-r--r--b2g/chrome/content/shell.js1308
-rw-r--r--b2g/chrome/content/shell_remote.html19
-rw-r--r--b2g/chrome/content/shell_remote.js139
-rw-r--r--b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js40
-rw-r--r--b2g/chrome/content/test/mochitest/RecordingStatusHelper.js82
-rw-r--r--b2g/chrome/content/test/mochitest/file_getusermedia_iframe.html36
-rw-r--r--b2g/chrome/content/test/mochitest/mochitest.ini11
-rw-r--r--b2g/chrome/content/test/mochitest/moz.build7
-rw-r--r--b2g/chrome/content/test/mochitest/test_recordingStatus_basic.html119
-rw-r--r--b2g/chrome/content/test/mochitest/test_recordingStatus_iframe.html71
-rw-r--r--b2g/chrome/content/test/mochitest/test_recordingStatus_kill_content_process.html72
-rw-r--r--b2g/chrome/content/test/mochitest/test_recordingStatus_multiple_requests.html108
-rw-r--r--b2g/chrome/content/touchcontrols.css233
-rw-r--r--b2g/chrome/jar.mn60
-rw-r--r--b2g/chrome/moz.build13
-rw-r--r--b2g/common.configure32
-rw-r--r--b2g/components/AboutServiceWorkers.jsm183
-rw-r--r--b2g/components/ActivityChannel.jsm64
-rw-r--r--b2g/components/AlertsHelper.jsm279
-rw-r--r--b2g/components/AlertsService.js153
-rw-r--r--b2g/components/B2GAboutRedirector.js78
-rw-r--r--b2g/components/B2GAppMigrator.js152
-rw-r--r--b2g/components/B2GComponents.manifest108
-rw-r--r--b2g/components/B2GPresentationDevicePrompt.js87
-rw-r--r--b2g/components/BootstrapCommandLine.js52
-rw-r--r--b2g/components/Bootstraper.jsm156
-rw-r--r--b2g/components/CommandLine.js29
-rw-r--r--b2g/components/ContentPermissionPrompt.js461
-rw-r--r--b2g/components/ContentRequestHelper.jsm68
-rw-r--r--b2g/components/DebuggerActors.js83
-rw-r--r--b2g/components/DirectoryProvider.js295
-rw-r--r--b2g/components/ErrorPage.jsm187
-rw-r--r--b2g/components/FilePicker.js223
-rw-r--r--b2g/components/Frames.jsm146
-rw-r--r--b2g/components/FxAccountsMgmtService.jsm173
-rw-r--r--b2g/components/FxAccountsUIGlue.js39
-rw-r--r--b2g/components/GaiaChrome.cpp188
-rw-r--r--b2g/components/GaiaChrome.h44
-rw-r--r--b2g/components/GlobalSimulatorScreen.jsm90
-rw-r--r--b2g/components/HelperAppDialog.js115
-rw-r--r--b2g/components/LogCapture.jsm221
-rw-r--r--b2g/components/LogParser.jsm257
-rw-r--r--b2g/components/LogShake.jsm588
-rw-r--r--b2g/components/MailtoProtocolHandler.js46
-rw-r--r--b2g/components/OMAContentHandler.js57
-rw-r--r--b2g/components/OopCommandLine.js46
-rw-r--r--b2g/components/OrientationChangeHandler.jsm70
-rw-r--r--b2g/components/PresentationRequestUIGlue.js116
-rw-r--r--b2g/components/ProcessGlobal.js202
-rw-r--r--b2g/components/RecoveryService.js160
-rw-r--r--b2g/components/SafeMode.jsm150
-rw-r--r--b2g/components/Screenshot.jsm43
-rw-r--r--b2g/components/SignInToWebsite.jsm444
-rw-r--r--b2g/components/SimulatorScreen.js117
-rw-r--r--b2g/components/SmsProtocolHandler.js74
-rw-r--r--b2g/components/SystemAppProxy.jsm377
-rw-r--r--b2g/components/SystemMessageInternal.js64
-rw-r--r--b2g/components/TelProtocolHandler.js60
-rw-r--r--b2g/components/TelURIParser.jsm120
-rw-r--r--b2g/components/UpdatePrompt.js783
-rw-r--r--b2g/components/moz.build91
-rw-r--r--b2g/components/nsIGaiaChrome.idl15
-rw-r--r--b2g/components/nsISystemMessagesInternal.idl51
-rw-r--r--b2g/components/test/mochitest/SandboxPromptTest.html57
-rw-r--r--b2g/components/test/mochitest/filepicker_path_handler_chrome.js31
-rw-r--r--b2g/components/test/mochitest/mochitest.ini28
-rw-r--r--b2g/components/test/mochitest/permission_handler_chrome.js36
-rw-r--r--b2g/components/test/mochitest/presentation_prompt_handler_chrome.js94
-rw-r--r--b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js32
-rw-r--r--b2g/components/test/mochitest/screenshot_helper.js40
-rw-r--r--b2g/components/test/mochitest/systemapp_helper.js173
-rw-r--r--b2g/components/test/mochitest/test_filepicker_path.html130
-rw-r--r--b2g/components/test/mochitest/test_permission_deny.html83
-rw-r--r--b2g/components/test/mochitest/test_permission_gum_remember.html170
-rw-r--r--b2g/components/test/mochitest/test_permission_visibilitychange.html57
-rw-r--r--b2g/components/test/mochitest/test_presentation_device_prompt.html145
-rw-r--r--b2g/components/test/mochitest/test_presentation_request_ui_glue.html105
-rw-r--r--b2g/components/test/mochitest/test_sandbox_permission.html104
-rw-r--r--b2g/components/test/mochitest/test_screenshot.html31
-rw-r--r--b2g/components/test/mochitest/test_systemapp.html31
-rw-r--r--b2g/components/test/moz.build8
-rw-r--r--b2g/components/test/unit/data/test_logger_filebin4037 -> 0 bytes
-rw-r--r--b2g/components/test/unit/head_identity.js159
-rw-r--r--b2g/components/test/unit/head_logshake_gonk.js58
-rw-r--r--b2g/components/test/unit/test_aboutserviceworkers.js142
-rw-r--r--b2g/components/test/unit/test_bug793310.js39
-rw-r--r--b2g/components/test/unit/test_bug832946.js18
-rw-r--r--b2g/components/test/unit/test_fxaccounts.js212
-rw-r--r--b2g/components/test/unit/test_logcapture.js13
-rw-r--r--b2g/components/test/unit/test_logcapture_gonk.js70
-rw-r--r--b2g/components/test/unit/test_logparser.js75
-rw-r--r--b2g/components/test/unit/test_logshake.js218
-rw-r--r--b2g/components/test/unit/test_logshake_gonk.js61
-rw-r--r--b2g/components/test/unit/test_logshake_gonk_compression.js76
-rw-r--r--b2g/components/test/unit/test_logshake_readLog_gonk.js65
-rw-r--r--b2g/components/test/unit/test_signintowebsite.js322
-rw-r--r--b2g/components/test/unit/xpcshell.ini49
-rw-r--r--b2g/config/aries/config.json52
-rw-r--r--b2g/config/aries/releng-aries.manifest27
-rw-r--r--b2g/config/aries/sources.xml162
-rw-r--r--b2g/config/desktop/config.json8
-rw-r--r--b2g/config/gaia.json7
-rw-r--r--b2g/config/mozconfigs/common24
-rw-r--r--b2g/config/mozconfigs/common.override8
-rw-r--r--b2g/config/mozconfigs/ics_armv7a_gecko/debug20
-rw-r--r--b2g/config/mozconfigs/ics_armv7a_gecko/nightly21
-rw-r--r--b2g/config/mozconfigs/linux32_gecko/debug34
-rw-r--r--b2g/config/mozconfigs/linux32_gecko/nightly36
-rw-r--r--b2g/config/mozconfigs/linux64_gecko/nightly36
-rw-r--r--b2g/config/mozconfigs/macosx64_gecko/debug33
-rw-r--r--b2g/config/mozconfigs/macosx64_gecko/nightly34
-rw-r--r--b2g/config/mozconfigs/win32_gecko/debug29
-rw-r--r--b2g/config/mozconfigs/win32_gecko/nightly30
-rw-r--r--b2g/config/nexus-5-l/config.json55
-rw-r--r--b2g/config/nexus-5-l/releng-nexus5.manifest19
-rw-r--r--b2g/config/nexus-5-l/sources.xml162
-rw-r--r--b2g/config/tooltool-manifests/linux32/releng.manifest32
-rw-r--r--b2g/config/tooltool-manifests/macosx64/releng.manifest24
-rw-r--r--b2g/config/tooltool-manifests/win32/releng.manifest22
-rw-r--r--b2g/confvars.sh45
-rw-r--r--b2g/dev/app.mozbuild21
-rw-r--r--b2g/dev/app/moz.build15
-rw-r--r--b2g/dev/app/mulet.js20
-rw-r--r--b2g/dev/build.mk6
-rw-r--r--b2g/dev/config/mozconfigs/linux64/mulet10
-rw-r--r--b2g/dev/config/mozconfigs/linux64/mulet-hazards13
-rw-r--r--b2g/dev/config/mozconfigs/linux64/mulet_dbg14
-rw-r--r--b2g/dev/config/mozconfigs/macosx64/mulet27
-rw-r--r--b2g/dev/config/mozconfigs/win32/mulet13
-rw-r--r--b2g/dev/config/tooltool-manifests/linux64/hazard.manifest48
-rw-r--r--b2g/dev/config/tooltool-manifests/linux64/releng.manifest48
-rw-r--r--b2g/dev/config/tooltool-manifests/macosx64/releng.manifest24
-rw-r--r--b2g/dev/config/tooltool-manifests/win32/releng.manifest22
-rw-r--r--b2g/dev/confvars.sh12
-rw-r--r--b2g/dev/moz.configure9
-rw-r--r--b2g/gaia/Makefile.in14
-rw-r--r--b2g/gaia/moz.build20
-rw-r--r--b2g/gaia/run-b2g.c50
-rw-r--r--b2g/gaia/run-b2g.cpp102
-rw-r--r--b2g/graphene/app.mozbuild17
-rw-r--r--b2g/graphene/build.mk5
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/common24
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/common.override5
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/linux32/debug25
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/linux32/nightly25
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/linux64/debug25
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/linux64/nightly25
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/macosx64/debug23
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/macosx64/nightly23
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/win32/debug19
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/win32/nightly18
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/win64/debug23
-rw-r--r--b2g/graphene/config/horizon-mozconfigs/win64/nightly26
-rw-r--r--b2g/graphene/config/mozconfigs/common24
-rw-r--r--b2g/graphene/config/mozconfigs/common.override5
-rw-r--r--b2g/graphene/config/mozconfigs/linux32/debug25
-rw-r--r--b2g/graphene/config/mozconfigs/linux32/nightly25
-rw-r--r--b2g/graphene/config/mozconfigs/linux64/debug25
-rw-r--r--b2g/graphene/config/mozconfigs/linux64/nightly25
-rw-r--r--b2g/graphene/config/mozconfigs/macosx64/debug23
-rw-r--r--b2g/graphene/config/mozconfigs/macosx64/nightly23
-rw-r--r--b2g/graphene/config/mozconfigs/win32/debug19
-rw-r--r--b2g/graphene/config/mozconfigs/win32/nightly18
-rw-r--r--b2g/graphene/config/mozconfigs/win64/debug23
-rw-r--r--b2g/graphene/config/mozconfigs/win64/nightly26
-rw-r--r--b2g/graphene/confvars.sh53
-rw-r--r--b2g/graphene/graphene.js59
-rw-r--r--b2g/graphene/moz.configure7
-rw-r--r--b2g/graphene/settings.json3
-rw-r--r--b2g/installer/Makefile.in135
-rwxr-xr-xb2g/installer/flash.bat73
-rw-r--r--b2g/installer/moz.build6
-rw-r--r--b2g/installer/package-manifest.in845
-rw-r--r--b2g/installer/removed-files.in45
-rw-r--r--b2g/locales/Makefile.in149
-rw-r--r--b2g/locales/all-locales3
-rw-r--r--b2g/locales/en-US/b2g-l10n.js12
-rw-r--r--b2g/locales/en-US/chrome/graphene.properties5
-rw-r--r--b2g/locales/en-US/chrome/overrides/aboutCertError.dtd38
-rw-r--r--b2g/locales/en-US/chrome/overrides/appstrings.properties39
-rw-r--r--b2g/locales/en-US/defines.inc9
-rw-r--r--b2g/locales/filter.py15
-rw-r--r--b2g/locales/jar.mn75
-rw-r--r--b2g/locales/l10n.ini13
-rw-r--r--b2g/locales/moz.build7
-rw-r--r--b2g/moz.build14
-rw-r--r--b2g/moz.configure32
-rw-r--r--b2g/simulator/bootstrap.js4
-rw-r--r--b2g/simulator/build_xpi.py148
-rw-r--r--b2g/simulator/custom-prefs.js8
-rw-r--r--b2g/simulator/custom-settings.json6
-rw-r--r--b2g/simulator/icon.pngbin4762 -> 0 bytes
-rw-r--r--b2g/simulator/icon64.pngbin7858 -> 0 bytes
-rw-r--r--b2g/simulator/install.rdf.in52
-rw-r--r--b2g/test/b2g-unittest-requirements.txt8
-rw-r--r--b2g/test/emulator.manifest6
-rw-r--r--browser/app/firefox.exe.manifest1
-rw-r--r--browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in8
-rw-r--r--browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build3
-rw-r--r--browser/app/profile/firefox.js8
-rw-r--r--browser/base/content/test/alerts/.eslintrc.js7
-rw-r--r--browser/base/content/test/alerts/browser.ini12
-rw-r--r--browser/base/content/test/alerts/browser_notification_close.js71
-rw-r--r--browser/base/content/test/alerts/browser_notification_do_not_disturb.js80
-rw-r--r--browser/base/content/test/alerts/browser_notification_open_settings.js58
-rw-r--r--browser/base/content/test/alerts/browser_notification_permission_migration.js45
-rw-r--r--browser/base/content/test/alerts/browser_notification_remove_permission.js72
-rw-r--r--browser/base/content/test/alerts/browser_notification_replace.js38
-rw-r--r--browser/base/content/test/alerts/browser_notification_tab_switching.js80
-rw-r--r--browser/base/content/test/alerts/file_dom_notifications.html39
-rw-r--r--browser/base/content/test/alerts/head.js71
-rw-r--r--browser/base/content/test/captivePortal/browser.ini9
-rw-r--r--browser/base/content/test/captivePortal/browser_CaptivePortalWatcher.js119
-rw-r--r--browser/base/content/test/captivePortal/browser_CaptivePortalWatcher_1.js91
-rw-r--r--browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js82
-rw-r--r--browser/base/content/test/captivePortal/head.js181
-rw-r--r--browser/base/content/test/chrome/.eslintrc.js7
-rw-r--r--browser/base/content/test/chrome/chrome.ini3
-rw-r--r--browser/base/content/test/chrome/test_aboutCrashed.xul86
-rw-r--r--browser/base/content/test/general/.eslintrc.js8
-rw-r--r--browser/base/content/test/general/POSTSearchEngine.xml6
-rw-r--r--browser/base/content/test/general/aboutHome_content_script.js6
-rw-r--r--browser/base/content/test/general/accounts_testRemoteCommands.html83
-rw-r--r--browser/base/content/test/general/alltabslistener.html8
-rw-r--r--browser/base/content/test/general/app_bug575561.html18
-rw-r--r--browser/base/content/test/general/app_subframe_bug575561.html12
-rw-r--r--browser/base/content/test/general/audio.oggbin14293 -> 0 bytes
-rw-r--r--browser/base/content/test/general/benignPage.html12
-rw-r--r--browser/base/content/test/general/browser.ini494
-rw-r--r--browser/base/content/test/general/browser_PageMetaData_pushstate.js29
-rw-r--r--browser/base/content/test/general/browser_aboutAccounts.js499
-rw-r--r--browser/base/content/test/general/browser_aboutCertError.js409
-rw-r--r--browser/base/content/test/general/browser_aboutHealthReport.js139
-rw-r--r--browser/base/content/test/general/browser_aboutHome.js668
-rw-r--r--browser/base/content/test/general/browser_aboutHome_wrapsCorrectly.js28
-rw-r--r--browser/base/content/test/general/browser_aboutNetError.js47
-rw-r--r--browser/base/content/test/general/browser_aboutSupport_newtab_security_state.js26
-rw-r--r--browser/base/content/test/general/browser_accesskeys.js82
-rw-r--r--browser/base/content/test/general/browser_addCertException.js50
-rw-r--r--browser/base/content/test/general/browser_addKeywordSearch.js81
-rw-r--r--browser/base/content/test/general/browser_alltabslistener.js206
-rw-r--r--browser/base/content/test/general/browser_audioTabIcon.js504
-rw-r--r--browser/base/content/test/general/browser_backButtonFitts.js42
-rw-r--r--browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js76
-rw-r--r--browser/base/content/test/general/browser_blob-channelname.js11
-rw-r--r--browser/base/content/test/general/browser_blockHPKP.js101
-rw-r--r--browser/base/content/test/general/browser_bookmark_popup.js431
-rw-r--r--browser/base/content/test/general/browser_bookmark_titles.js98
-rw-r--r--browser/base/content/test/general/browser_bug1015721.js54
-rw-r--r--browser/base/content/test/general/browser_bug1045809.js68
-rw-r--r--browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js36
-rw-r--r--browser/base/content/test/general/browser_bug1261299.js73
-rw-r--r--browser/base/content/test/general/browser_bug1297539.js114
-rw-r--r--browser/base/content/test/general/browser_bug1299667.js71
-rw-r--r--browser/base/content/test/general/browser_bug321000.js80
-rw-r--r--browser/base/content/test/general/browser_bug356571.js93
-rw-r--r--browser/base/content/test/general/browser_bug380960.js11
-rw-r--r--browser/base/content/test/general/browser_bug386835.js89
-rw-r--r--browser/base/content/test/general/browser_bug406216.js54
-rw-r--r--browser/base/content/test/general/browser_bug408415.js45
-rw-r--r--browser/base/content/test/general/browser_bug409481.js83
-rw-r--r--browser/base/content/test/general/browser_bug409624.js57
-rw-r--r--browser/base/content/test/general/browser_bug413915.js62
-rw-r--r--browser/base/content/test/general/browser_bug416661.js43
-rw-r--r--browser/base/content/test/general/browser_bug417483.js30
-rw-r--r--browser/base/content/test/general/browser_bug419612.js32
-rw-r--r--browser/base/content/test/general/browser_bug422590.js50
-rw-r--r--browser/base/content/test/general/browser_bug423833.js138
-rw-r--r--browser/base/content/test/general/browser_bug424101.js52
-rw-r--r--browser/base/content/test/general/browser_bug427559.js38
-rw-r--r--browser/base/content/test/general/browser_bug431826.js50
-rw-r--r--browser/base/content/test/general/browser_bug432599.js127
-rw-r--r--browser/base/content/test/general/browser_bug435035.js17
-rw-r--r--browser/base/content/test/general/browser_bug435325.js69
-rw-r--r--browser/base/content/test/general/browser_bug441778.js46
-rw-r--r--browser/base/content/test/general/browser_bug455852.js20
-rw-r--r--browser/base/content/test/general/browser_bug460146.js51
-rw-r--r--browser/base/content/test/general/browser_bug462289.js81
-rw-r--r--browser/base/content/test/general/browser_bug462673.js36
-rw-r--r--browser/base/content/test/general/browser_bug477014.js25
-rw-r--r--browser/base/content/test/general/browser_bug479408.js17
-rw-r--r--browser/base/content/test/general/browser_bug479408_sample.html4
-rw-r--r--browser/base/content/test/general/browser_bug481560.js21
-rw-r--r--browser/base/content/test/general/browser_bug484315.js23
-rw-r--r--browser/base/content/test/general/browser_bug491431.js34
-rw-r--r--browser/base/content/test/general/browser_bug495058.js38
-rw-r--r--browser/base/content/test/general/browser_bug517902.js42
-rw-r--r--browser/base/content/test/general/browser_bug519216.js45
-rw-r--r--browser/base/content/test/general/browser_bug520538.js15
-rw-r--r--browser/base/content/test/general/browser_bug521216.js50
-rw-r--r--browser/base/content/test/general/browser_bug533232.js36
-rw-r--r--browser/base/content/test/general/browser_bug537013.js135
-rw-r--r--browser/base/content/test/general/browser_bug537474.js8
-rw-r--r--browser/base/content/test/general/browser_bug550565.js44
-rw-r--r--browser/base/content/test/general/browser_bug553455.js1200
-rw-r--r--browser/base/content/test/general/browser_bug555224.js40
-rw-r--r--browser/base/content/test/general/browser_bug555767.js54
-rw-r--r--browser/base/content/test/general/browser_bug559991.js42
-rw-r--r--browser/base/content/test/general/browser_bug561636.js370
-rw-r--r--browser/base/content/test/general/browser_bug563588.js30
-rw-r--r--browser/base/content/test/general/browser_bug565575.js14
-rw-r--r--browser/base/content/test/general/browser_bug567306.js50
-rw-r--r--browser/base/content/test/general/browser_bug575561.js97
-rw-r--r--browser/base/content/test/general/browser_bug575830.js33
-rw-r--r--browser/base/content/test/general/browser_bug577121.js29
-rw-r--r--browser/base/content/test/general/browser_bug578534.js23
-rw-r--r--browser/base/content/test/general/browser_bug579872.js28
-rw-r--r--browser/base/content/test/general/browser_bug580638.js60
-rw-r--r--browser/base/content/test/general/browser_bug580956.js26
-rw-r--r--browser/base/content/test/general/browser_bug581242.js21
-rw-r--r--browser/base/content/test/general/browser_bug581253.js86
-rw-r--r--browser/base/content/test/general/browser_bug585558.js153
-rw-r--r--browser/base/content/test/general/browser_bug585785.js35
-rw-r--r--browser/base/content/test/general/browser_bug585830.js25
-rw-r--r--browser/base/content/test/general/browser_bug590206.js163
-rw-r--r--browser/base/content/test/general/browser_bug592338.js163
-rw-r--r--browser/base/content/test/general/browser_bug594131.js21
-rw-r--r--browser/base/content/test/general/browser_bug595507.js36
-rw-r--r--browser/base/content/test/general/browser_bug596687.js25
-rw-r--r--browser/base/content/test/general/browser_bug597218.js38
-rw-r--r--browser/base/content/test/general/browser_bug609700.js20
-rw-r--r--browser/base/content/test/general/browser_bug623893.js37
-rw-r--r--browser/base/content/test/general/browser_bug624734.js29
-rw-r--r--browser/base/content/test/general/browser_bug633691.js28
-rw-r--r--browser/base/content/test/general/browser_bug647886.js40
-rw-r--r--browser/base/content/test/general/browser_bug655584.js23
-rw-r--r--browser/base/content/test/general/browser_bug664672.js19
-rw-r--r--browser/base/content/test/general/browser_bug676619.js124
-rw-r--r--browser/base/content/test/general/browser_bug678392-1.html12
-rw-r--r--browser/base/content/test/general/browser_bug678392-2.html12
-rw-r--r--browser/base/content/test/general/browser_bug678392.js191
-rw-r--r--browser/base/content/test/general/browser_bug710878.js34
-rw-r--r--browser/base/content/test/general/browser_bug719271.js95
-rw-r--r--browser/base/content/test/general/browser_bug724239.js11
-rw-r--r--browser/base/content/test/general/browser_bug734076.js114
-rw-r--r--browser/base/content/test/general/browser_bug735471.js23
-rw-r--r--browser/base/content/test/general/browser_bug749738.js29
-rw-r--r--browser/base/content/test/general/browser_bug763468_perwindowpb.js70
-rw-r--r--browser/base/content/test/general/browser_bug767836_perwindowpb.js90
-rw-r--r--browser/base/content/test/general/browser_bug817947.js55
-rw-r--r--browser/base/content/test/general/browser_bug822367.js187
-rw-r--r--browser/base/content/test/general/browser_bug832435.js23
-rw-r--r--browser/base/content/test/general/browser_bug839103.js120
-rw-r--r--browser/base/content/test/general/browser_bug882977.js29
-rw-r--r--browser/base/content/test/general/browser_bug902156.js174
-rw-r--r--browser/base/content/test/general/browser_bug906190.js240
-rw-r--r--browser/base/content/test/general/browser_bug963945.js23
-rw-r--r--browser/base/content/test/general/browser_bug970746.js121
-rw-r--r--browser/base/content/test/general/browser_bug970746.xhtml20
-rw-r--r--browser/base/content/test/general/browser_clipboard.js174
-rw-r--r--browser/base/content/test/general/browser_clipboard_pastefile.js62
-rw-r--r--browser/base/content/test/general/browser_contentAltClick.js107
-rw-r--r--browser/base/content/test/general/browser_contentAreaClick.js307
-rw-r--r--browser/base/content/test/general/browser_contentSearchUI.js771
-rw-r--r--browser/base/content/test/general/browser_contextmenu.js996
-rw-r--r--browser/base/content/test/general/browser_contextmenu_childprocess.js84
-rw-r--r--browser/base/content/test/general/browser_contextmenu_input.js243
-rw-r--r--browser/base/content/test/general/browser_csp_block_all_mixedcontent.js55
-rw-r--r--browser/base/content/test/general/browser_ctrlTab.js185
-rw-r--r--browser/base/content/test/general/browser_datachoices_notification.js221
-rw-r--r--browser/base/content/test/general/browser_decoderDoctor.js122
-rw-r--r--browser/base/content/test/general/browser_devedition.js129
-rw-r--r--browser/base/content/test/general/browser_discovery.js162
-rw-r--r--browser/base/content/test/general/browser_documentnavigation.js266
-rw-r--r--browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js221
-rw-r--r--browser/base/content/test/general/browser_double_close_tab.js80
-rw-r--r--browser/base/content/test/general/browser_drag.js45
-rw-r--r--browser/base/content/test/general/browser_duplicateIDs.js8
-rw-r--r--browser/base/content/test/general/browser_e10s_about_process.js114
-rw-r--r--browser/base/content/test/general/browser_e10s_chrome_process.js150
-rw-r--r--browser/base/content/test/general/browser_e10s_javascript.js11
-rw-r--r--browser/base/content/test/general/browser_e10s_switchbrowser.js261
-rw-r--r--browser/base/content/test/general/browser_favicon_change.js41
-rw-r--r--browser/base/content/test/general/browser_favicon_change_not_in_document.js34
-rw-r--r--browser/base/content/test/general/browser_feed_discovery.js33
-rw-r--r--browser/base/content/test/general/browser_findbarClose.js35
-rw-r--r--browser/base/content/test/general/browser_focusonkeydown.js26
-rw-r--r--browser/base/content/test/general/browser_fullscreen-window-open.js347
-rw-r--r--browser/base/content/test/general/browser_fxa_migrate.js18
-rw-r--r--browser/base/content/test/general/browser_fxa_oauth.html30
-rw-r--r--browser/base/content/test/general/browser_fxa_oauth.js327
-rw-r--r--browser/base/content/test/general/browser_fxa_oauth_with_keys.html33
-rw-r--r--browser/base/content/test/general/browser_fxa_web_channel.html138
-rw-r--r--browser/base/content/test/general/browser_fxa_web_channel.js210
-rw-r--r--browser/base/content/test/general/browser_fxaccounts.js261
-rw-r--r--browser/base/content/test/general/browser_gZipOfflineChild.js80
-rw-r--r--browser/base/content/test/general/browser_gestureSupport.js670
-rw-r--r--browser/base/content/test/general/browser_getshortcutoruri.js143
-rw-r--r--browser/base/content/test/general/browser_hide_removing.js39
-rw-r--r--browser/base/content/test/general/browser_homeDrop.js90
-rw-r--r--browser/base/content/test/general/browser_identity_UI.js146
-rw-r--r--browser/base/content/test/general/browser_insecureLoginForms.js162
-rw-r--r--browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js39
-rw-r--r--browser/base/content/test/general/browser_keywordBookmarklets.js54
-rw-r--r--browser/base/content/test/general/browser_keywordSearch.js88
-rw-r--r--browser/base/content/test/general/browser_keywordSearch_postData.js94
-rw-r--r--browser/base/content/test/general/browser_lastAccessedTab.js47
-rw-r--r--browser/base/content/test/general/browser_mcb_redirect.js314
-rw-r--r--browser/base/content/test/general/browser_menuButtonBadgeManager.js46
-rw-r--r--browser/base/content/test/general/browser_menuButtonFitts.js32
-rw-r--r--browser/base/content/test/general/browser_middleMouse_noJSPaste.js34
-rw-r--r--browser/base/content/test/general/browser_minimize.js18
-rw-r--r--browser/base/content/test/general/browser_misused_characters_in_strings.js244
-rw-r--r--browser/base/content/test/general/browser_mixedContentFramesOnHttp.js34
-rw-r--r--browser/base/content/test/general/browser_mixedContentFromOnunload.js49
-rw-r--r--browser/base/content/test/general/browser_mixed_content_cert_override.js54
-rw-r--r--browser/base/content/test/general/browser_mixedcontent_securityflags.js70
-rw-r--r--browser/base/content/test/general/browser_modifiedclick_inherit_principal.js30
-rw-r--r--browser/base/content/test/general/browser_newTabDrop.js99
-rw-r--r--browser/base/content/test/general/browser_newWindowDrop.js120
-rw-r--r--browser/base/content/test/general/browser_newwindow_focus.js96
-rw-r--r--browser/base/content/test/general/browser_no_mcb_on_http_site.js106
-rw-r--r--browser/base/content/test/general/browser_offlineQuotaNotification.js95
-rw-r--r--browser/base/content/test/general/browser_overflowScroll.js91
-rw-r--r--browser/base/content/test/general/browser_pageInfo.js38
-rw-r--r--browser/base/content/test/general/browser_page_style_menu.js97
-rw-r--r--browser/base/content/test/general/browser_page_style_menu_update.js67
-rw-r--r--browser/base/content/test/general/browser_pageinfo_svg_image.js38
-rw-r--r--browser/base/content/test/general/browser_parsable_css.js376
-rw-r--r--browser/base/content/test/general/browser_parsable_script.js132
-rw-r--r--browser/base/content/test/general/browser_permissions.js202
-rw-r--r--browser/base/content/test/general/browser_pinnedTabs.js75
-rw-r--r--browser/base/content/test/general/browser_plainTextLinks.js146
-rw-r--r--browser/base/content/test/general/browser_printpreview.js74
-rw-r--r--browser/base/content/test/general/browser_private_browsing_window.js65
-rw-r--r--browser/base/content/test/general/browser_private_no_prompt.js12
-rw-r--r--browser/base/content/test/general/browser_purgehistory_clears_sh.js60
-rw-r--r--browser/base/content/test/general/browser_refreshBlocker.js135
-rw-r--r--browser/base/content/test/general/browser_registerProtocolHandler_notification.html15
-rw-r--r--browser/base/content/test/general/browser_registerProtocolHandler_notification.js43
-rw-r--r--browser/base/content/test/general/browser_relatedTabs.js51
-rw-r--r--browser/base/content/test/general/browser_remoteTroubleshoot.js93
-rw-r--r--browser/base/content/test/general/browser_remoteWebNavigation_postdata.js50
-rw-r--r--browser/base/content/test/general/browser_removeTabsToTheEnd.js24
-rw-r--r--browser/base/content/test/general/browser_restore_isAppTab.js160
-rw-r--r--browser/base/content/test/general/browser_sanitize-passwordDisabledHosts.js39
-rw-r--r--browser/base/content/test/general/browser_sanitize-sitepermissions.js52
-rw-r--r--browser/base/content/test/general/browser_sanitize-timespans.js733
-rw-r--r--browser/base/content/test/general/browser_sanitizeDialog.js1027
-rw-r--r--browser/base/content/test/general/browser_save_link-perwindowpb.js199
-rw-r--r--browser/base/content/test/general/browser_save_link_when_window_navigates.js173
-rw-r--r--browser/base/content/test/general/browser_save_private_link_perwindowpb.js116
-rw-r--r--browser/base/content/test/general/browser_save_video.js87
-rw-r--r--browser/base/content/test/general/browser_save_video_frame.js125
-rw-r--r--browser/base/content/test/general/browser_scope.js10
-rw-r--r--browser/base/content/test/general/browser_selectTabAtIndex.js81
-rw-r--r--browser/base/content/test/general/browser_selectpopup.js563
-rw-r--r--browser/base/content/test/general/browser_ssl_error_reports.js174
-rw-r--r--browser/base/content/test/general/browser_star_hsts.js85
-rw-r--r--browser/base/content/test/general/browser_star_hsts.sjs13
-rw-r--r--browser/base/content/test/general/browser_subframe_favicons_not_used.js20
-rw-r--r--browser/base/content/test/general/browser_syncui.js205
-rw-r--r--browser/base/content/test/general/browser_tabDrop.js103
-rw-r--r--browser/base/content/test/general/browser_tabReorder.js49
-rw-r--r--browser/base/content/test/general/browser_tab_close_dependent_window.js24
-rw-r--r--browser/base/content/test/general/browser_tab_detach_restore.js34
-rw-r--r--browser/base/content/test/general/browser_tab_drag_drop_perwindow.js216
-rw-r--r--browser/base/content/test/general/browser_tab_dragdrop.js186
-rw-r--r--browser/base/content/test/general/browser_tab_dragdrop2.js57
-rw-r--r--browser/base/content/test/general/browser_tab_dragdrop2_frame1.xul169
-rw-r--r--browser/base/content/test/general/browser_tabbar_big_widgets.js29
-rw-r--r--browser/base/content/test/general/browser_tabfocus.js565
-rw-r--r--browser/base/content/test/general/browser_tabkeynavigation.js156
-rw-r--r--browser/base/content/test/general/browser_tabopen_reflows.js157
-rw-r--r--browser/base/content/test/general/browser_tabs_close_beforeunload.js49
-rw-r--r--browser/base/content/test/general/browser_tabs_isActive.js152
-rw-r--r--browser/base/content/test/general/browser_tabs_owner.js44
-rw-r--r--browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js126
-rw-r--r--browser/base/content/test/general/browser_trackingUI_1.js170
-rw-r--r--browser/base/content/test/general/browser_trackingUI_2.js96
-rw-r--r--browser/base/content/test/general/browser_trackingUI_3.js52
-rw-r--r--browser/base/content/test/general/browser_trackingUI_4.js109
-rw-r--r--browser/base/content/test/general/browser_trackingUI_5.js131
-rw-r--r--browser/base/content/test/general/browser_trackingUI_6.js46
-rw-r--r--browser/base/content/test/general/browser_trackingUI_telemetry.js145
-rw-r--r--browser/base/content/test/general/browser_typeAheadFind.js22
-rw-r--r--browser/base/content/test/general/browser_unknownContentType_title.js33
-rw-r--r--browser/base/content/test/general/browser_unloaddialogs.js41
-rw-r--r--browser/base/content/test/general/browser_utilityOverlay.js112
-rw-r--r--browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js55
-rw-r--r--browser/base/content/test/general/browser_visibleFindSelection.js52
-rw-r--r--browser/base/content/test/general/browser_visibleTabs.js97
-rw-r--r--browser/base/content/test/general/browser_visibleTabs_bookmarkAllPages.js34
-rw-r--r--browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js66
-rw-r--r--browser/base/content/test/general/browser_visibleTabs_contextMenu.js72
-rw-r--r--browser/base/content/test/general/browser_visibleTabs_tabPreview.js41
-rw-r--r--browser/base/content/test/general/browser_web_channel.html189
-rw-r--r--browser/base/content/test/general/browser_web_channel.js436
-rw-r--r--browser/base/content/test/general/browser_web_channel_iframe.html96
-rw-r--r--browser/base/content/test/general/browser_windowactivation.js183
-rw-r--r--browser/base/content/test/general/browser_windowopen_reflows.js117
-rw-r--r--browser/base/content/test/general/browser_zbug569342.js80
-rw-r--r--browser/base/content/test/general/bug1262648_string_with_newlines.dtd3
-rw-r--r--browser/base/content/test/general/bug364677-data.xml5
-rw-r--r--browser/base/content/test/general/bug364677-data.xml^headers^1
-rw-r--r--browser/base/content/test/general/bug395533-data.txt6
-rw-r--r--browser/base/content/test/general/bug592338.html24
-rw-r--r--browser/base/content/test/general/bug792517-2.html5
-rw-r--r--browser/base/content/test/general/bug792517.html5
-rw-r--r--browser/base/content/test/general/bug792517.sjs13
-rw-r--r--browser/base/content/test/general/bug839103.css1
-rw-r--r--browser/base/content/test/general/clipboard_pastefile.html37
-rw-r--r--browser/base/content/test/general/close_beforeunload.html8
-rw-r--r--browser/base/content/test/general/close_beforeunload_opens_second_tab.html3
-rw-r--r--browser/base/content/test/general/contentSearchUI.html21
-rw-r--r--browser/base/content/test/general/contentSearchUI.js209
-rw-r--r--browser/base/content/test/general/content_aboutAccounts.js87
-rw-r--r--browser/base/content/test/general/contextmenu_common.js324
-rw-r--r--browser/base/content/test/general/ctxmenu-image.pngbin5401 -> 0 bytes
-rw-r--r--browser/base/content/test/general/discovery.html8
-rw-r--r--browser/base/content/test/general/download_page.html47
-rw-r--r--browser/base/content/test/general/dummy_page.html9
-rw-r--r--browser/base/content/test/general/feed_discovery.html73
-rw-r--r--browser/base/content/test/general/feed_tab.html17
-rw-r--r--browser/base/content/test/general/file_bug1045809_1.html7
-rw-r--r--browser/base/content/test/general/file_bug1045809_2.html7
-rw-r--r--browser/base/content/test/general/file_bug822367_1.html18
-rw-r--r--browser/base/content/test/general/file_bug822367_1.js1
-rw-r--r--browser/base/content/test/general/file_bug822367_2.html16
-rw-r--r--browser/base/content/test/general/file_bug822367_3.html27
-rw-r--r--browser/base/content/test/general/file_bug822367_4.html18
-rw-r--r--browser/base/content/test/general/file_bug822367_4.js1
-rw-r--r--browser/base/content/test/general/file_bug822367_4B.html18
-rw-r--r--browser/base/content/test/general/file_bug822367_5.html24
-rw-r--r--browser/base/content/test/general/file_bug822367_6.html16
-rw-r--r--browser/base/content/test/general/file_bug902156.js5
-rw-r--r--browser/base/content/test/general/file_bug902156_1.html15
-rw-r--r--browser/base/content/test/general/file_bug902156_2.html17
-rw-r--r--browser/base/content/test/general/file_bug902156_3.html15
-rw-r--r--browser/base/content/test/general/file_bug906190.js5
-rw-r--r--browser/base/content/test/general/file_bug906190.sjs17
-rw-r--r--browser/base/content/test/general/file_bug906190_1.html15
-rw-r--r--browser/base/content/test/general/file_bug906190_2.html15
-rw-r--r--browser/base/content/test/general/file_bug906190_3_4.html14
-rw-r--r--browser/base/content/test/general/file_bug906190_redirected.html15
-rw-r--r--browser/base/content/test/general/file_bug970276_favicon1.icobin1406 -> 0 bytes
-rw-r--r--browser/base/content/test/general/file_bug970276_favicon2.icobin1406 -> 0 bytes
-rw-r--r--browser/base/content/test/general/file_bug970276_popup1.html14
-rw-r--r--browser/base/content/test/general/file_bug970276_popup2.html12
-rw-r--r--browser/base/content/test/general/file_csp_block_all_mixedcontent.html9
-rw-r--r--browser/base/content/test/general/file_csp_block_all_mixedcontent.js3
-rw-r--r--browser/base/content/test/general/file_documentnavigation_frameset.html12
-rw-r--r--browser/base/content/test/general/file_double_close_tab.html15
-rw-r--r--browser/base/content/test/general/file_favicon_change.html13
-rw-r--r--browser/base/content/test/general/file_favicon_change_not_in_document.html21
-rw-r--r--browser/base/content/test/general/file_fullscreen-window-open.html24
-rw-r--r--browser/base/content/test/general/file_generic_favicon.icobin1406 -> 0 bytes
-rw-r--r--browser/base/content/test/general/file_mediaPlayback.html2
-rw-r--r--browser/base/content/test/general/file_mixedContentFramesOnHttp.html14
-rw-r--r--browser/base/content/test/general/file_mixedContentFromOnunload.html18
-rw-r--r--browser/base/content/test/general/file_mixedContentFromOnunload_test1.html14
-rw-r--r--browser/base/content/test/general/file_mixedContentFromOnunload_test2.html15
-rw-r--r--browser/base/content/test/general/file_mixedPassiveContent.html13
-rw-r--r--browser/base/content/test/general/file_trackingUI_6.html16
-rw-r--r--browser/base/content/test/general/file_trackingUI_6.js2
-rw-r--r--browser/base/content/test/general/file_trackingUI_6.js^headers^1
-rw-r--r--browser/base/content/test/general/file_with_favicon.html12
-rw-r--r--browser/base/content/test/general/fxa_profile_handler.sjs34
-rw-r--r--browser/base/content/test/general/gZipOfflineChild.cacheManifest2
-rw-r--r--browser/base/content/test/general/gZipOfflineChild.cacheManifest^headers^1
-rw-r--r--browser/base/content/test/general/gZipOfflineChild.htmlbin303 -> 0 bytes
-rw-r--r--browser/base/content/test/general/gZipOfflineChild.html^headers^2
-rw-r--r--browser/base/content/test/general/gZipOfflineChild_uncompressed.html21
-rw-r--r--browser/base/content/test/general/head.js1069
-rw-r--r--browser/base/content/test/general/head_plain.js27
-rw-r--r--browser/base/content/test/general/healthreport_pingData.js17
-rw-r--r--browser/base/content/test/general/healthreport_testRemoteCommands.html243
-rw-r--r--browser/base/content/test/general/insecure_opener.html9
-rw-r--r--browser/base/content/test/general/mochitest.ini27
-rw-r--r--browser/base/content/test/general/moz.pngbin580 -> 0 bytes
-rw-r--r--browser/base/content/test/general/navigating_window_with_download.html7
-rw-r--r--browser/base/content/test/general/offlineByDefault.js17
-rw-r--r--browser/base/content/test/general/offlineChild.cacheManifest2
-rw-r--r--browser/base/content/test/general/offlineChild.cacheManifest^headers^1
-rw-r--r--browser/base/content/test/general/offlineChild.html20
-rw-r--r--browser/base/content/test/general/offlineChild2.cacheManifest2
-rw-r--r--browser/base/content/test/general/offlineChild2.cacheManifest^headers^1
-rw-r--r--browser/base/content/test/general/offlineChild2.html20
-rw-r--r--browser/base/content/test/general/offlineEvent.cacheManifest2
-rw-r--r--browser/base/content/test/general/offlineEvent.cacheManifest^headers^1
-rw-r--r--browser/base/content/test/general/offlineEvent.html9
-rw-r--r--browser/base/content/test/general/offlineQuotaNotification.cacheManifest7
-rw-r--r--browser/base/content/test/general/offlineQuotaNotification.html9
-rw-r--r--browser/base/content/test/general/page_style_sample.html41
-rw-r--r--browser/base/content/test/general/parsingTestHelpers.jsm131
-rw-r--r--browser/base/content/test/general/permissions.html14
-rw-r--r--browser/base/content/test/general/pinning_headers.sjs23
-rw-r--r--browser/base/content/test/general/print_postdata.sjs22
-rw-r--r--browser/base/content/test/general/refresh_header.sjs24
-rw-r--r--browser/base/content/test/general/refresh_meta.sjs36
-rw-r--r--browser/base/content/test/general/searchSuggestionEngine.sjs9
-rw-r--r--browser/base/content/test/general/searchSuggestionEngine.xml9
-rw-r--r--browser/base/content/test/general/searchSuggestionEngine2.xml9
-rw-r--r--browser/base/content/test/general/ssl_error_reports.sjs91
-rw-r--r--browser/base/content/test/general/subtst_contextmenu.html73
-rw-r--r--browser/base/content/test/general/subtst_contextmenu_input.html29
-rw-r--r--browser/base/content/test/general/subtst_contextmenu_xul.xul9
-rw-r--r--browser/base/content/test/general/svg_image.html11
-rw-r--r--browser/base/content/test/general/test-mixedcontent-securityerrors.html21
-rw-r--r--browser/base/content/test/general/test_bug364677.html32
-rw-r--r--browser/base/content/test/general/test_bug395533.html38
-rw-r--r--browser/base/content/test/general/test_bug435035.html1
-rw-r--r--browser/base/content/test/general/test_bug462673.html18
-rw-r--r--browser/base/content/test/general/test_bug628179.html10
-rw-r--r--browser/base/content/test/general/test_bug839103.html10
-rw-r--r--browser/base/content/test/general/test_bug959531.html9
-rw-r--r--browser/base/content/test/general/test_mcb_double_redirect_image.html23
-rw-r--r--browser/base/content/test/general/test_mcb_redirect.html15
-rw-r--r--browser/base/content/test/general/test_mcb_redirect.js5
-rw-r--r--browser/base/content/test/general/test_mcb_redirect.sjs22
-rw-r--r--browser/base/content/test/general/test_mcb_redirect_image.html23
-rw-r--r--browser/base/content/test/general/test_no_mcb_on_http_site_font.css10
-rw-r--r--browser/base/content/test/general/test_no_mcb_on_http_site_font.html47
-rw-r--r--browser/base/content/test/general/test_no_mcb_on_http_site_font2.css1
-rw-r--r--browser/base/content/test/general/test_no_mcb_on_http_site_font2.html48
-rw-r--r--browser/base/content/test/general/test_no_mcb_on_http_site_img.css3
-rw-r--r--browser/base/content/test/general/test_no_mcb_on_http_site_img.html47
-rw-r--r--browser/base/content/test/general/test_offlineNotification.html129
-rw-r--r--browser/base/content/test/general/test_offline_gzip.html21
-rw-r--r--browser/base/content/test/general/test_process_flags_chrome.html10
-rw-r--r--browser/base/content/test/general/test_remoteTroubleshoot.html50
-rw-r--r--browser/base/content/test/general/title_test.svg59
-rw-r--r--browser/base/content/test/general/trackingPage.html12
-rw-r--r--browser/base/content/test/general/unknownContentType_file.pif1
-rw-r--r--browser/base/content/test/general/unknownContentType_file.pif^headers^1
-rw-r--r--browser/base/content/test/general/video.oggbin285310 -> 0 bytes
-rw-r--r--browser/base/content/test/general/web_video.html10
-rw-r--r--browser/base/content/test/general/web_video1.ogvbin28942 -> 0 bytes
-rw-r--r--browser/base/content/test/general/web_video1.ogv^headers^3
-rw-r--r--browser/base/content/test/general/zoom_test.html14
-rw-r--r--browser/base/content/test/newtab/.eslintrc.js7
-rw-r--r--browser/base/content/test/newtab/browser.ini55
-rw-r--r--browser/base/content/test/newtab/browser_newtab_1188015.js26
-rw-r--r--browser/base/content/test/newtab/browser_newtab_background_captures.js64
-rw-r--r--browser/base/content/test/newtab/browser_newtab_block.js95
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug1145428.js87
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug1178586.js83
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug1194895.js146
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug1271075.js32
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug721442.js28
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug722273.js73
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug723102.js24
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug723121.js42
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug725996.js35
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug734043.js34
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug735987.js32
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug752841.js56
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug765628.js32
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug876313.js24
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug991111.js35
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug991210.js34
-rw-r--r--browser/base/content/test/newtab/browser_newtab_bug998387.js39
-rw-r--r--browser/base/content/test/newtab/browser_newtab_disable.js49
-rw-r--r--browser/base/content/test/newtab/browser_newtab_drag_drop.js95
-rw-r--r--browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js63
-rw-r--r--browser/base/content/test/newtab/browser_newtab_drop_preview.js41
-rw-r--r--browser/base/content/test/newtab/browser_newtab_enhanced.js228
-rw-r--r--browser/base/content/test/newtab/browser_newtab_focus.js48
-rw-r--r--browser/base/content/test/newtab/browser_newtab_perwindow_private_browsing.js56
-rw-r--r--browser/base/content/test/newtab/browser_newtab_reflow_load.js37
-rw-r--r--browser/base/content/test/newtab/browser_newtab_reportLinkAction.js83
-rw-r--r--browser/base/content/test/newtab/browser_newtab_search.js247
-rw-r--r--browser/base/content/test/newtab/browser_newtab_sponsored_icon_click.js53
-rw-r--r--browser/base/content/test/newtab/browser_newtab_undo.js47
-rw-r--r--browser/base/content/test/newtab/browser_newtab_unpin.js56
-rw-r--r--browser/base/content/test/newtab/browser_newtab_update.js48
-rw-r--r--browser/base/content/test/newtab/content-reflows.js26
-rw-r--r--browser/base/content/test/newtab/head.js552
-rw-r--r--browser/base/content/test/newtab/searchEngine1x2xLogo.xml9
-rw-r--r--browser/base/content/test/newtab/searchEngine1xLogo.xml7
-rw-r--r--browser/base/content/test/newtab/searchEngine2xLogo.xml7
-rw-r--r--browser/base/content/test/newtab/searchEngineFavicon.xml6
-rw-r--r--browser/base/content/test/newtab/searchEngineNoLogo.xml5
-rw-r--r--browser/base/content/test/plugins/.eslintrc.js7
-rw-r--r--browser/base/content/test/plugins/blockNoPlugins.xml7
-rw-r--r--browser/base/content/test/plugins/blockPluginHard.xml11
-rw-r--r--browser/base/content/test/plugins/blockPluginInfoURL.xml12
-rw-r--r--browser/base/content/test/plugins/blockPluginVulnerableNoUpdate.xml11
-rw-r--r--browser/base/content/test/plugins/blockPluginVulnerableUpdatable.xml11
-rw-r--r--browser/base/content/test/plugins/blocklist_proxy.js78
-rw-r--r--browser/base/content/test/plugins/browser.ini78
-rw-r--r--browser/base/content/test/plugins/browser_CTP_context_menu.js69
-rw-r--r--browser/base/content/test/plugins/browser_CTP_crashreporting.js233
-rw-r--r--browser/base/content/test/plugins/browser_CTP_data_urls.js255
-rw-r--r--browser/base/content/test/plugins/browser_CTP_drag_drop.js96
-rw-r--r--browser/base/content/test/plugins/browser_CTP_hide_overlay.js88
-rw-r--r--browser/base/content/test/plugins/browser_CTP_iframe.js48
-rw-r--r--browser/base/content/test/plugins/browser_CTP_multi_allow.js99
-rw-r--r--browser/base/content/test/plugins/browser_CTP_nonplugins.js58
-rw-r--r--browser/base/content/test/plugins/browser_CTP_notificationBar.js151
-rw-r--r--browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js120
-rw-r--r--browser/base/content/test/plugins/browser_CTP_remove_navigate.js79
-rw-r--r--browser/base/content/test/plugins/browser_CTP_resize.js130
-rw-r--r--browser/base/content/test/plugins/browser_CTP_zoom.js62
-rw-r--r--browser/base/content/test/plugins/browser_blocking.js349
-rw-r--r--browser/base/content/test/plugins/browser_blocklist_content.js104
-rw-r--r--browser/base/content/test/plugins/browser_bug743421.js119
-rw-r--r--browser/base/content/test/plugins/browser_bug744745.js50
-rw-r--r--browser/base/content/test/plugins/browser_bug787619.js65
-rw-r--r--browser/base/content/test/plugins/browser_bug797677.js43
-rw-r--r--browser/base/content/test/plugins/browser_bug812562.js80
-rw-r--r--browser/base/content/test/plugins/browser_bug818118.js40
-rw-r--r--browser/base/content/test/plugins/browser_bug820497.js71
-rw-r--r--browser/base/content/test/plugins/browser_clearplugindata.html30
-rw-r--r--browser/base/content/test/plugins/browser_clearplugindata.js127
-rw-r--r--browser/base/content/test/plugins/browser_clearplugindata_noage.html30
-rw-r--r--browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js34
-rw-r--r--browser/base/content/test/plugins/browser_pageInfo_plugins.js191
-rw-r--r--browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js207
-rw-r--r--browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js254
-rw-r--r--browser/base/content/test/plugins/browser_plugin_reloading.js85
-rw-r--r--browser/base/content/test/plugins/browser_pluginnotification.js626
-rw-r--r--browser/base/content/test/plugins/browser_plugins_added_dynamically.js137
-rw-r--r--browser/base/content/test/plugins/browser_private_clicktoplay.js216
-rw-r--r--browser/base/content/test/plugins/head.js396
-rw-r--r--browser/base/content/test/plugins/plugin_add_dynamically.html18
-rw-r--r--browser/base/content/test/plugins/plugin_alternate_content.html9
-rw-r--r--browser/base/content/test/plugins/plugin_big.html9
-rw-r--r--browser/base/content/test/plugins/plugin_both.html10
-rw-r--r--browser/base/content/test/plugins/plugin_both2.html10
-rw-r--r--browser/base/content/test/plugins/plugin_bug744745.html12
-rw-r--r--browser/base/content/test/plugins/plugin_bug749455.html8
-rw-r--r--browser/base/content/test/plugins/plugin_bug787619.html9
-rw-r--r--browser/base/content/test/plugins/plugin_bug797677.html5
-rw-r--r--browser/base/content/test/plugins/plugin_bug820497.html17
-rw-r--r--browser/base/content/test/plugins/plugin_clickToPlayAllow.html9
-rw-r--r--browser/base/content/test/plugins/plugin_clickToPlayDeny.html9
-rw-r--r--browser/base/content/test/plugins/plugin_crashCommentAndURL.html27
-rw-r--r--browser/base/content/test/plugins/plugin_data_url.html11
-rw-r--r--browser/base/content/test/plugins/plugin_hidden_to_visible.html11
-rw-r--r--browser/base/content/test/plugins/plugin_iframe.html9
-rw-r--r--browser/base/content/test/plugins/plugin_outsideScrollArea.html25
-rw-r--r--browser/base/content/test/plugins/plugin_overlayed.html27
-rw-r--r--browser/base/content/test/plugins/plugin_positioned.html12
-rw-r--r--browser/base/content/test/plugins/plugin_small.html9
-rw-r--r--browser/base/content/test/plugins/plugin_small_2.html9
-rw-r--r--browser/base/content/test/plugins/plugin_syncRemoved.html15
-rw-r--r--browser/base/content/test/plugins/plugin_test.html9
-rw-r--r--browser/base/content/test/plugins/plugin_test2.html10
-rw-r--r--browser/base/content/test/plugins/plugin_test3.html9
-rw-r--r--browser/base/content/test/plugins/plugin_two_types.html9
-rw-r--r--browser/base/content/test/plugins/plugin_unknown.html9
-rw-r--r--browser/base/content/test/plugins/plugin_zoom.html10
-rw-r--r--browser/base/content/test/popupNotifications/.eslintrc.js7
-rw-r--r--browser/base/content/test/popupNotifications/browser.ini18
-rw-r--r--browser/base/content/test/popupNotifications/browser_displayURI.js28
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification.js203
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_2.js266
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_3.js305
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_4.js294
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_checkbox.js211
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js74
-rw-r--r--browser/base/content/test/popupNotifications/browser_reshow_in_background.js52
-rw-r--r--browser/base/content/test/popupNotifications/head.js303
-rw-r--r--browser/base/content/test/popups/browser.ini4
-rw-r--r--browser/base/content/test/popups/browser_popupUI.js37
-rw-r--r--browser/base/content/test/popups/browser_popup_blocker.js96
-rw-r--r--browser/base/content/test/popups/popup_blocker.html13
-rw-r--r--browser/base/content/test/referrer/.eslintrc.js7
-rw-r--r--browser/base/content/test/referrer/browser.ini24
-rw-r--r--browser/base/content/test/referrer/browser_referrer_middle_click.js20
-rw-r--r--browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js27
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js59
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js31
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js63
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_private.js22
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js21
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_window.js22
-rw-r--r--browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js32
-rw-r--r--browser/base/content/test/referrer/browser_referrer_simple_click.js20
-rw-r--r--browser/base/content/test/referrer/file_referrer_policyserver.sjs37
-rw-r--r--browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs36
-rw-r--r--browser/base/content/test/referrer/file_referrer_testserver.sjs31
-rw-r--r--browser/base/content/test/referrer/head.js265
-rw-r--r--browser/base/content/test/siteIdentity/browser.ini8
-rw-r--r--browser/base/content/test/siteIdentity/browser_identityBlock_focus.js62
-rw-r--r--browser/base/content/test/siteIdentity/browser_identityPopup_focus.js27
-rw-r--r--browser/base/content/test/siteIdentity/head.js6
-rw-r--r--browser/base/content/test/social/.eslintrc.js7
-rw-r--r--browser/base/content/test/social/blocklist.xml6
-rw-r--r--browser/base/content/test/social/browser.ini23
-rw-r--r--browser/base/content/test/social/browser_aboutHome_activation.js229
-rw-r--r--browser/base/content/test/social/browser_addons.js217
-rw-r--r--browser/base/content/test/social/browser_blocklist.js211
-rw-r--r--browser/base/content/test/social/browser_share.js396
-rw-r--r--browser/base/content/test/social/browser_social_activation.js270
-rw-r--r--browser/base/content/test/social/head.js273
-rw-r--r--browser/base/content/test/social/microformats.html18
-rw-r--r--browser/base/content/test/social/moz.pngbin580 -> 0 bytes
-rw-r--r--browser/base/content/test/social/opengraph/og_invalid_url.html11
-rw-r--r--browser/base/content/test/social/opengraph/opengraph.html13
-rw-r--r--browser/base/content/test/social/opengraph/shortlink_linkrel.html10
-rw-r--r--browser/base/content/test/social/opengraph/shorturl_link.html10
-rw-r--r--browser/base/content/test/social/opengraph/shorturl_linkrel.html25
-rw-r--r--browser/base/content/test/social/share.html9
-rw-r--r--browser/base/content/test/social/share_activate.html35
-rw-r--r--browser/base/content/test/social/social_activate.html41
-rw-r--r--browser/base/content/test/social/social_activate_basic.html41
-rw-r--r--browser/base/content/test/social/social_activate_iframe.html11
-rw-r--r--browser/base/content/test/social/social_crash_content_helper.js31
-rw-r--r--browser/base/content/test/social/social_postActivation.html12
-rw-r--r--browser/base/content/test/tabPrompts/.eslintrc.js7
-rw-r--r--browser/base/content/test/tabPrompts/browser.ini4
-rw-r--r--browser/base/content/test/tabPrompts/browser_closeTabSpecificPanels.js41
-rw-r--r--browser/base/content/test/tabPrompts/browser_multiplePrompts.js72
-rw-r--r--browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js66
-rw-r--r--browser/base/content/test/tabPrompts/openPromptOffTimeout.html10
-rw-r--r--browser/base/content/test/tabcrashed/browser.ini13
-rw-r--r--browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js152
-rw-r--r--browser/base/content/test/tabcrashed/browser_clearEmail.js85
-rw-r--r--browser/base/content/test/tabcrashed/browser_showForm.js40
-rw-r--r--browser/base/content/test/tabcrashed/browser_shown.js203
-rw-r--r--browser/base/content/test/tabcrashed/browser_withoutDump.js36
-rw-r--r--browser/base/content/test/tabcrashed/head.js110
-rw-r--r--browser/base/content/test/tabs/.eslintrc.js7
-rw-r--r--browser/base/content/test/tabs/browser.ini4
-rw-r--r--browser/base/content/test/tabs/browser_tabSpinnerProbe.js93
-rw-r--r--browser/base/content/test/tabs/browser_tabSwitchPrintPreview.js29
-rw-r--r--browser/base/content/test/urlbar/.eslintrc.js7
-rw-r--r--browser/base/content/test/urlbar/authenticate.sjs220
-rw-r--r--browser/base/content/test/urlbar/browser.ini101
-rw-r--r--browser/base/content/test/urlbar/browser_URLBarSetURI.js100
-rw-r--r--browser/base/content/test/urlbar/browser_action_keyword.js119
-rw-r--r--browser/base/content/test/urlbar/browser_action_keyword_override.js40
-rw-r--r--browser/base/content/test/urlbar/browser_action_searchengine.js36
-rw-r--r--browser/base/content/test/urlbar/browser_action_searchengine_alias.js35
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js57
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_autoselect.js92
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_cursor.js17
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js48
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_enter_race.js122
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_no_title.js15
-rw-r--r--browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js102
-rw-r--r--browser/base/content/test/urlbar/browser_bug1003461-switchtab-override.js61
-rw-r--r--browser/base/content/test/urlbar/browser_bug1024133-switchtab-override-keynav.js37
-rw-r--r--browser/base/content/test/urlbar/browser_bug1025195_switchToTabHavingURI_aOpenParams.js124
-rw-r--r--browser/base/content/test/urlbar/browser_bug1070778.js55
-rw-r--r--browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js29
-rw-r--r--browser/base/content/test/urlbar/browser_bug1225194-remotetab.js16
-rw-r--r--browser/base/content/test/urlbar/browser_bug304198.js109
-rw-r--r--browser/base/content/test/urlbar/browser_bug556061.js98
-rw-r--r--browser/base/content/test/urlbar/browser_bug562649.js24
-rw-r--r--browser/base/content/test/urlbar/browser_bug623155.js137
-rw-r--r--browser/base/content/test/urlbar/browser_bug783614.js13
-rw-r--r--browser/base/content/test/urlbar/browser_canonizeURL.js42
-rw-r--r--browser/base/content/test/urlbar/browser_dragdropURL.js15
-rw-r--r--browser/base/content/test/urlbar/browser_locationBarCommand.js218
-rw-r--r--browser/base/content/test/urlbar/browser_locationBarExternalLoad.js65
-rw-r--r--browser/base/content/test/urlbar/browser_moz_action_link.js31
-rw-r--r--browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js49
-rw-r--r--browser/base/content/test/urlbar/browser_search_favicon.js52
-rw-r--r--browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar.js216
-rw-r--r--browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar_perwindowpb.js84
-rw-r--r--browser/base/content/test/urlbar/browser_urlHighlight.js134
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js104
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarAutoFillTrimURLs.js49
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarCopying.js232
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarDecode.js97
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarDelete.js39
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarEnter.js45
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarEnterAfterMouseOver.js69
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarFocusedCmdK.js17
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarHashChangeProxyState.js111
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarKeepStateAcrossTabSwitches.js49
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarOneOffs.js232
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarPrivateBrowsingWindowChange.js41
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarRaceWithTabs.js57
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarRevert.js37
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarSearchSingleWordNotification.js198
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js66
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js254
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarSearchTelemetry.js216
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarStop.js30
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarTrimURLs.js98
-rw-r--r--browser/base/content/test/urlbar/browser_urlbarUpdateForDomainCompletion.js17
-rw-r--r--browser/base/content/test/urlbar/browser_urlbar_autoFill_backspaced.js146
-rw-r--r--browser/base/content/test/urlbar/browser_urlbar_blanking.js35
-rw-r--r--browser/base/content/test/urlbar/browser_urlbar_locationchange_urlbar_edit_dos.js41
-rw-r--r--browser/base/content/test/urlbar/browser_urlbar_remoteness_switch.js39
-rw-r--r--browser/base/content/test/urlbar/browser_urlbar_searchsettings.js30
-rw-r--r--browser/base/content/test/urlbar/browser_urlbar_stop_pending.js138
-rw-r--r--browser/base/content/test/urlbar/browser_wyciwyg_urlbarCopying.js31
-rw-r--r--browser/base/content/test/urlbar/dummy_page.html9
-rw-r--r--browser/base/content/test/urlbar/file_blank_but_not_blank.html2
-rw-r--r--browser/base/content/test/urlbar/file_urlbar_edit_dos.html23
-rw-r--r--browser/base/content/test/urlbar/head.js205
-rw-r--r--browser/base/content/test/urlbar/moz.pngbin580 -> 0 bytes
-rw-r--r--browser/base/content/test/urlbar/print_postdata.sjs22
-rw-r--r--browser/base/content/test/urlbar/redirect_bug623155.sjs16
-rw-r--r--browser/base/content/test/urlbar/searchSuggestionEngine.sjs9
-rw-r--r--browser/base/content/test/urlbar/searchSuggestionEngine.xml9
-rw-r--r--browser/base/content/test/urlbar/slow-page.sjs22
-rw-r--r--browser/base/content/test/urlbar/test_wyciwyg_copying.html13
-rw-r--r--browser/base/content/test/webrtc/.eslintrc.js7
-rw-r--r--browser/base/content/test/webrtc/browser.ini11
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media.js554
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js109
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_in_frame.js266
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_tear_off_tab.js109
-rw-r--r--browser/base/content/test/webrtc/get_user_media.html55
-rw-r--r--browser/base/content/test/webrtc/get_user_media_content_script.js85
-rw-r--r--browser/base/content/test/webrtc/head.js453
-rw-r--r--browser/base/moz.build28
-rw-r--r--browser/branding/official/pref/firefox-branding.js2
-rw-r--r--browser/components/contextualidentity/moz.build7
-rw-r--r--browser/components/contextualidentity/test/browser/.eslintrc.js11
-rw-r--r--browser/components/contextualidentity/test/browser/browser.ini30
-rw-r--r--browser/components/contextualidentity/test/browser/browser_aboutURLs.js49
-rw-r--r--browser/components/contextualidentity/test/browser/browser_blobUrl.js78
-rw-r--r--browser/components/contextualidentity/test/browser/browser_broadcastchannel.js80
-rw-r--r--browser/components/contextualidentity/test/browser/browser_count_and_remove.js34
-rw-r--r--browser/components/contextualidentity/test/browser/browser_eme.js186
-rw-r--r--browser/components/contextualidentity/test/browser/browser_favicon.js140
-rw-r--r--browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js219
-rw-r--r--browser/components/contextualidentity/test/browser/browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js86
-rw-r--r--browser/components/contextualidentity/test/browser/browser_forgetAPI_quota_clearStoragesForPrincipal.js147
-rw-r--r--browser/components/contextualidentity/test/browser/browser_forgetaboutsite.js352
-rw-r--r--browser/components/contextualidentity/test/browser/browser_imageCache.js59
-rw-r--r--browser/components/contextualidentity/test/browser/browser_middleClick.js41
-rw-r--r--browser/components/contextualidentity/test/browser/browser_newtabButton.js35
-rw-r--r--browser/components/contextualidentity/test/browser/browser_serviceworkers.js108
-rw-r--r--browser/components/contextualidentity/test/browser/browser_usercontext.js86
-rw-r--r--browser/components/contextualidentity/test/browser/browser_usercontextid_tabdrop.js134
-rw-r--r--browser/components/contextualidentity/test/browser/browser_windowName.js74
-rw-r--r--browser/components/contextualidentity/test/browser/browser_windowOpen.js41
-rw-r--r--browser/components/contextualidentity/test/browser/empty_file.html5
-rw-r--r--browser/components/contextualidentity/test/browser/favicon-normal32.pngbin344 -> 0 bytes
-rw-r--r--browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html23
-rw-r--r--browser/components/contextualidentity/test/browser/file_set_storages.html41
-rw-r--r--browser/components/contextualidentity/test/browser/serviceworker.html12
-rw-r--r--browser/components/contextualidentity/test/browser/worker.js1
-rw-r--r--browser/components/customizableui/moz.build5
-rw-r--r--browser/components/customizableui/test/.eslintrc.js7
-rw-r--r--browser/components/customizableui/test/browser.ini154
-rw-r--r--browser/components/customizableui/test/browser_1003588_no_specials_in_panel.js107
-rw-r--r--browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js108
-rw-r--r--browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js71
-rw-r--r--browser/components/customizableui/test/browser_1042100_default_placements_update.js107
-rw-r--r--browser/components/customizableui/test/browser_1058573_showToolbarsDropdown.js25
-rw-r--r--browser/components/customizableui/test/browser_1087303_button_fullscreen.js46
-rw-r--r--browser/components/customizableui/test/browser_1087303_button_preferences.js50
-rw-r--r--browser/components/customizableui/test/browser_1089591_still_customizable_after_reset.js24
-rw-r--r--browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js31
-rw-r--r--browser/components/customizableui/test/browser_1161838_inserted_new_default_buttons.js78
-rw-r--r--browser/components/customizableui/test/browser_873501_handle_specials.js79
-rw-r--r--browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js185
-rw-r--r--browser/components/customizableui/test/browser_876944_customize_mode_create_destroy.js61
-rw-r--r--browser/components/customizableui/test/browser_877006_missing_view.js41
-rw-r--r--browser/components/customizableui/test/browser_877178_unregisterArea.js50
-rw-r--r--browser/components/customizableui/test/browser_877447_skip_missing_ids.js25
-rw-r--r--browser/components/customizableui/test/browser_878452_drag_to_panel.js65
-rw-r--r--browser/components/customizableui/test/browser_880164_customization_context_menus.js414
-rw-r--r--browser/components/customizableui/test/browser_880382_drag_wide_widgets_in_panel.js497
-rw-r--r--browser/components/customizableui/test/browser_884402_customize_from_overflow.js81
-rw-r--r--browser/components/customizableui/test/browser_885052_customize_mode_observers_disabed.js45
-rw-r--r--browser/components/customizableui/test/browser_885530_showInPrivateBrowsing.js134
-rw-r--r--browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js46
-rw-r--r--browser/components/customizableui/test/browser_887438_currentset_shim.js75
-rw-r--r--browser/components/customizableui/test/browser_888817_currentset_updating.js57
-rw-r--r--browser/components/customizableui/test/browser_890140_orphaned_placeholders.js210
-rw-r--r--browser/components/customizableui/test/browser_890262_destroyWidget_after_add_to_panel.js68
-rw-r--r--browser/components/customizableui/test/browser_892955_isWidgetRemovable_for_removed_widgets.js30
-rw-r--r--browser/components/customizableui/test/browser_892956_destroyWidget_defaultPlacements.js24
-rw-r--r--browser/components/customizableui/test/browser_901207_searchbar_in_panel.js113
-rw-r--r--browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js31
-rw-r--r--browser/components/customizableui/test/browser_913972_currentset_overflow.js55
-rw-r--r--browser/components/customizableui/test/browser_914138_widget_API_overflowable_toolbar.js131
-rw-r--r--browser/components/customizableui/test/browser_914863_disabled_help_quit_buttons.js16
-rw-r--r--browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js38
-rw-r--r--browser/components/customizableui/test/browser_923857_customize_mode_event_wrapping_during_reset.js24
-rw-r--r--browser/components/customizableui/test/browser_927717_customize_drag_empty_toolbar.js26
-rw-r--r--browser/components/customizableui/test/browser_932928_show_notice_when_palette_empty.js35
-rw-r--r--browser/components/customizableui/test/browser_934113_menubar_removable.js30
-rw-r--r--browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js89
-rw-r--r--browser/components/customizableui/test/browser_938980_navbar_collapsed.js121
-rw-r--r--browser/components/customizableui/test/browser_938995_indefaultstate_nonremovable.js25
-rw-r--r--browser/components/customizableui/test/browser_940013_registerToolbarNode_calls_registerArea.js70
-rw-r--r--browser/components/customizableui/test/browser_940307_panel_click_closure_handling.js136
-rw-r--r--browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js22
-rw-r--r--browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js31
-rw-r--r--browser/components/customizableui/test/browser_942581_unregisterArea_keeps_placements.js106
-rw-r--r--browser/components/customizableui/test/browser_943683_migration_test.js50
-rw-r--r--browser/components/customizableui/test/browser_944887_destroyWidget_should_destroy_in_palette.js17
-rw-r--r--browser/components/customizableui/test/browser_945739_showInPrivateBrowsing_customize_mode.js35
-rw-r--r--browser/components/customizableui/test/browser_947914_button_addons.js33
-rw-r--r--browser/components/customizableui/test/browser_947914_button_copy.js59
-rw-r--r--browser/components/customizableui/test/browser_947914_button_cut.js57
-rw-r--r--browser/components/customizableui/test/browser_947914_button_find.js22
-rw-r--r--browser/components/customizableui/test/browser_947914_button_history.js24
-rw-r--r--browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js48
-rw-r--r--browser/components/customizableui/test/browser_947914_button_newWindow.js47
-rw-r--r--browser/components/customizableui/test/browser_947914_button_paste.js41
-rw-r--r--browser/components/customizableui/test/browser_947914_button_print.js45
-rw-r--r--browser/components/customizableui/test/browser_947914_button_savePage.js20
-rw-r--r--browser/components/customizableui/test/browser_947914_button_zoomIn.js37
-rw-r--r--browser/components/customizableui/test/browser_947914_button_zoomOut.js38
-rw-r--r--browser/components/customizableui/test/browser_947914_button_zoomReset.js40
-rw-r--r--browser/components/customizableui/test/browser_947987_removable_default.js68
-rw-r--r--browser/components/customizableui/test/browser_948985_non_removable_defaultArea.js32
-rw-r--r--browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js52
-rw-r--r--browser/components/customizableui/test/browser_956602_remove_special_widget.js31
-rw-r--r--browser/components/customizableui/test/browser_962069_drag_to_overflow_chevron.js54
-rw-r--r--browser/components/customizableui/test/browser_962884_opt_in_disable_hyphens.js67
-rw-r--r--browser/components/customizableui/test/browser_963639_customizing_attribute_non_customizable_toolbar.js34
-rw-r--r--browser/components/customizableui/test/browser_967000_button_charEncoding.js62
-rw-r--r--browser/components/customizableui/test/browser_967000_button_feeds.js60
-rw-r--r--browser/components/customizableui/test/browser_967000_button_sync.js335
-rw-r--r--browser/components/customizableui/test/browser_968447_bookmarks_toolbar_items_in_panel.js65
-rw-r--r--browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js56
-rw-r--r--browser/components/customizableui/test/browser_969427_recreate_destroyed_widget_after_reset.js34
-rw-r--r--browser/components/customizableui/test/browser_969661_character_encoding_navbar_disabled.js26
-rw-r--r--browser/components/customizableui/test/browser_970511_undo_restore_default.js128
-rw-r--r--browser/components/customizableui/test/browser_972267_customizationchange_events.js46
-rwxr-xr-xbrowser/components/customizableui/test/browser_973641_button_addon.js71
-rw-r--r--browser/components/customizableui/test/browser_973932_addonbar_currentset.js30
-rw-r--r--browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js145
-rw-r--r--browser/components/customizableui/test/browser_976792_insertNodeInWindow.js414
-rw-r--r--browser/components/customizableui/test/browser_978084_dragEnd_after_move.js46
-rw-r--r--browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js51
-rw-r--r--browser/components/customizableui/test/browser_981305_separator_insertion.js73
-rw-r--r--browser/components/customizableui/test/browser_981418-widget-onbeforecreated-handler.js93
-rw-r--r--browser/components/customizableui/test/browser_982656_restore_defaults_builtin_widgets.js57
-rw-r--r--browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js267
-rw-r--r--browser/components/customizableui/test/browser_985815_propagate_setToolbarVisibility.js45
-rw-r--r--browser/components/customizableui/test/browser_987177_destroyWidget_xul.js33
-rw-r--r--browser/components/customizableui/test/browser_987177_xul_wrapper_updating.js74
-rwxr-xr-xbrowser/components/customizableui/test/browser_987185_syncButton.js77
-rw-r--r--browser/components/customizableui/test/browser_987492_window_api.js54
-rw-r--r--browser/components/customizableui/test/browser_987640_charEncoding.js60
-rw-r--r--browser/components/customizableui/test/browser_988072_sidebar_events.js392
-rw-r--r--browser/components/customizableui/test/browser_989338_saved_placements_not_resaved.js56
-rw-r--r--browser/components/customizableui/test/browser_989751_subviewbutton_class.js62
-rw-r--r--browser/components/customizableui/test/browser_992747_toggle_noncustomizable_toolbar.js26
-rw-r--r--browser/components/customizableui/test/browser_993322_widget_notoolbar.js36
-rw-r--r--browser/components/customizableui/test/browser_995164_registerArea_during_customize_mode.js149
-rw-r--r--browser/components/customizableui/test/browser_996364_registerArea_different_properties.js112
-rw-r--r--browser/components/customizableui/test/browser_996635_remove_non_widgets.js43
-rw-r--r--browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js81
-rw-r--r--browser/components/customizableui/test/browser_check_tooltips_in_navbar.js14
-rw-r--r--browser/components/customizableui/test/browser_customizemode_contextmenu_menubuttonstate.js24
-rw-r--r--browser/components/customizableui/test/browser_panel_toggle.js43
-rw-r--r--browser/components/customizableui/test/browser_switch_to_customize_mode.js34
-rw-r--r--browser/components/customizableui/test/head.js499
-rw-r--r--browser/components/customizableui/test/support/feeds_test_page.html10
-rw-r--r--browser/components/customizableui/test/support/test-feed.xml23
-rw-r--r--browser/components/customizableui/test/support/test_967000_charEncoding_page.html11
-rw-r--r--browser/components/dirprovider/tests/unit/.eslintrc.js7
-rw-r--r--browser/components/downloads/moz.build9
-rw-r--r--browser/components/downloads/test/browser/.eslintrc.js7
-rw-r--r--browser/components/downloads/test/browser/browser.ini15
-rw-r--r--browser/components/downloads/test/browser/browser_basic_functionality.js56
-rw-r--r--browser/components/downloads/test/browser/browser_confirm_unblock_download.js92
-rw-r--r--browser/components/downloads/test/browser/browser_downloads_panel_block.js183
-rw-r--r--browser/components/downloads/test/browser/browser_downloads_panel_footer.js95
-rw-r--r--browser/components/downloads/test/browser/browser_downloads_panel_height.js29
-rw-r--r--browser/components/downloads/test/browser/browser_first_download_panel.js57
-rw-r--r--browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js62
-rw-r--r--browser/components/downloads/test/browser/browser_indicatorDrop.js67
-rw-r--r--browser/components/downloads/test/browser/browser_libraryDrop.js72
-rw-r--r--browser/components/downloads/test/browser/browser_overflow_anchor.js115
-rw-r--r--browser/components/downloads/test/browser/head.js300
-rw-r--r--browser/components/downloads/test/unit/.eslintrc.js7
-rw-r--r--browser/components/downloads/test/unit/head.js18
-rw-r--r--browser/components/downloads/test/unit/test_DownloadsCommon.js37
-rw-r--r--browser/components/downloads/test/unit/xpcshell.ini7
-rw-r--r--browser/components/extensions/moz.build3
-rw-r--r--browser/components/extensions/test/browser/.eslintrc.js36
-rw-r--r--browser/components/extensions/test/browser/browser.ini115
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_context.js398
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_disabled.js68
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon.js321
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon_permissions.js210
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_popup.js413
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js304
-rw-r--r--browser/components/extensions/test/browser/browser_ext_browserAction_simple.js59
-rw-r--r--browser/components/extensions/test/browser/browser_ext_commands_execute_browser_action.js113
-rw-r--r--browser/components/extensions/test/browser/browser_ext_commands_execute_page_action.js133
-rw-r--r--browser/components/extensions/test/browser/browser_ext_commands_getAll.js81
-rw-r--r--browser/components/extensions/test/browser/browser_ext_commands_onCommand.js229
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contentscript_connect.js67
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus.js342
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js96
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus_icons.js76
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus_onclick.js196
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js100
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus_uninstall.js84
-rw-r--r--browser/components/extensions/test/browser/browser_ext_contextMenus_urlPatterns.js254
-rw-r--r--browser/components/extensions/test/browser/browser_ext_currentWindow.js149
-rw-r--r--browser/components/extensions/test/browser/browser_ext_getViews.js198
-rw-r--r--browser/components/extensions/test/browser/browser_ext_incognito_popup.js108
-rw-r--r--browser/components/extensions/test/browser/browser_ext_incognito_views.js121
-rw-r--r--browser/components/extensions/test/browser/browser_ext_lastError.js55
-rw-r--r--browser/components/extensions/test/browser/browser_ext_legacy_extension_context_contentscript.js173
-rw-r--r--browser/components/extensions/test/browser/browser_ext_omnibox.js286
-rw-r--r--browser/components/extensions/test/browser/browser_ext_optionsPage_privileges.js66
-rw-r--r--browser/components/extensions/test/browser/browser_ext_pageAction_context.js178
-rw-r--r--browser/components/extensions/test/browser/browser_ext_pageAction_popup.js238
-rw-r--r--browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js169
-rw-r--r--browser/components/extensions/test/browser/browser_ext_pageAction_simple.js60
-rw-r--r--browser/components/extensions/test/browser/browser_ext_pageAction_title.js226
-rw-r--r--browser/components/extensions/test/browser/browser_ext_popup_api_injection.js101
-rw-r--r--browser/components/extensions/test/browser/browser_ext_popup_background.js133
-rw-r--r--browser/components/extensions/test/browser/browser_ext_popup_corners.js98
-rw-r--r--browser/components/extensions/test/browser/browser_ext_popup_sendMessage.js93
-rw-r--r--browser/components/extensions/test/browser/browser_ext_popup_shutdown.js77
-rw-r--r--browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage.js276
-rw-r--r--browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage_uninstall.js101
-rw-r--r--browser/components/extensions/test/browser/browser_ext_runtime_setUninstallURL.js94
-rw-r--r--browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js97
-rw-r--r--browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_private.js61
-rw-r--r--browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js96
-rw-r--r--browser/components/extensions/test/browser/browser_ext_sessions_restore.js134
-rw-r--r--browser/components/extensions/test/browser/browser_ext_simple.js57
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tab_runtimeConnect.js74
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_audio.js203
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_captureVisibleTab.js155
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js156
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_create.js166
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_create_invalid_url.js66
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_detectLanguage.js47
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_duplicate.js146
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_events.js280
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_executeScript.js234
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_executeScript_bad.js217
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js189
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_executeScript_no_create.js67
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_executeScript_runAt.js107
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_getCurrent.js70
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js86
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_move.js103
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_move_window.js98
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_move_window_multiple.js43
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_move_window_pinned.js42
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js126
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js198
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_query.js224
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_reload.js54
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_reload_bypass_cache.js58
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js95
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_sendMessage.js227
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_update.js45
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_update_url.js110
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_zoom.js222
-rw-r--r--browser/components/extensions/test/browser/browser_ext_topwindowid.js23
-rw-r--r--browser/components/extensions/test/browser/browser_ext_webNavigation_frameId0.js45
-rw-r--r--browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js168
-rw-r--r--browser/components/extensions/test/browser/browser_ext_webNavigation_urlbar_transitions.js251
-rw-r--r--browser/components/extensions/test/browser/browser_ext_webRequest.js95
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows.js33
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_allowScriptsToClose.js61
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_create.js142
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_create_params.js33
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js140
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_create_url.js84
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_events.js115
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_size.js114
-rw-r--r--browser/components/extensions/test/browser/browser_ext_windows_update.js189
-rw-r--r--browser/components/extensions/test/browser/context.html23
-rw-r--r--browser/components/extensions/test/browser/context_tabs_onUpdated_iframe.html19
-rw-r--r--browser/components/extensions/test/browser/context_tabs_onUpdated_page.html18
-rw-r--r--browser/components/extensions/test/browser/ctxmenu-image.pngbin5401 -> 0 bytes
-rw-r--r--browser/components/extensions/test/browser/file_bypass_cache.sjs11
-rw-r--r--browser/components/extensions/test/browser/file_dummy.html9
-rw-r--r--browser/components/extensions/test/browser/file_iframe_document.html10
-rw-r--r--browser/components/extensions/test/browser/file_iframe_document.sjs41
-rw-r--r--browser/components/extensions/test/browser/file_language_fr_en.html14
-rw-r--r--browser/components/extensions/test/browser/file_language_ja.html10
-rw-r--r--browser/components/extensions/test/browser/file_language_tlh.html12
-rw-r--r--browser/components/extensions/test/browser/file_popup_api_injection_a.html10
-rw-r--r--browser/components/extensions/test/browser/file_popup_api_injection_b.html10
-rw-r--r--browser/components/extensions/test/browser/head.js263
-rw-r--r--browser/components/extensions/test/browser/head_pageAction.js157
-rw-r--r--browser/components/extensions/test/browser/head_sessions.js47
-rw-r--r--browser/components/extensions/test/browser/searchSuggestionEngine.sjs9
-rw-r--r--browser/components/extensions/test/browser/searchSuggestionEngine.xml9
-rw-r--r--browser/components/extensions/test/mochitest/mochitest.ini6
-rw-r--r--browser/components/extensions/test/mochitest/test_ext_all_apis.html75
-rw-r--r--browser/components/extensions/test/xpcshell/.eslintrc.js9
-rw-r--r--browser/components/extensions/test/xpcshell/head.js55
-rw-r--r--browser/components/extensions/test/xpcshell/test_ext_bookmarks.js601
-rw-r--r--browser/components/extensions/test/xpcshell/test_ext_history.js487
-rw-r--r--browser/components/extensions/test/xpcshell/test_ext_manifest_commands.js24
-rw-r--r--browser/components/extensions/test/xpcshell/test_ext_manifest_omnibox.js61
-rw-r--r--browser/components/extensions/test/xpcshell/test_ext_manifest_permissions.js57
-rw-r--r--browser/components/extensions/test/xpcshell/xpcshell.ini11
-rw-r--r--browser/components/feeds/moz.build7
-rw-r--r--browser/components/feeds/test/.eslintrc.js7
-rw-r--r--browser/components/feeds/test/bug368464-data.xml18
-rw-r--r--browser/components/feeds/test/bug408328-data.xml63
-rw-r--r--browser/components/feeds/test/bug436801-data.xml44
-rw-r--r--browser/components/feeds/test/bug494328-data.xml24
-rw-r--r--browser/components/feeds/test/bug589543-data.xml23
-rw-r--r--browser/components/feeds/test/chrome/.eslintrc.js7
-rw-r--r--browser/components/feeds/test/chrome/chrome.ini10
-rw-r--r--browser/components/feeds/test/chrome/sample_feed.atom23
-rw-r--r--browser/components/feeds/test/chrome/test_423060.xul56
-rw-r--r--browser/components/feeds/test/chrome/test_bug368464.html32
-rw-r--r--browser/components/feeds/test/chrome/test_bug408328.html37
-rw-r--r--browser/components/feeds/test/chrome/test_maxSniffing.html37
-rw-r--r--browser/components/feeds/test/mochitest.ini14
-rw-r--r--browser/components/feeds/test/test_bug436801.html118
-rw-r--r--browser/components/feeds/test/test_bug494328.html36
-rw-r--r--browser/components/feeds/test/test_bug589543.html32
-rw-r--r--browser/components/feeds/test/test_registerHandler.html85
-rw-r--r--browser/components/feeds/test/unit/.eslintrc.js7
-rw-r--r--browser/components/feeds/test/unit/head_feeds.js5
-rw-r--r--browser/components/feeds/test/unit/test_355473.js43
-rw-r--r--browser/components/feeds/test/unit/test_758990.js42
-rw-r--r--browser/components/feeds/test/unit/xpcshell.ini8
-rw-r--r--browser/components/feeds/test/valid-feed.xml23
-rw-r--r--browser/components/feeds/test/valid-unsniffable-feed.xml32
-rw-r--r--browser/components/migration/moz.build9
-rw-r--r--browser/components/migration/tests/browser/.eslintrc.js9
-rw-r--r--browser/components/migration/tests/browser/browser.ini3
-rw-r--r--browser/components/migration/tests/browser/browser_undo_notification.js67
-rw-r--r--browser/components/migration/tests/browser/browser_undo_notification_multiple_dismissal.js122
-rw-r--r--browser/components/migration/tests/browser/browser_undo_notification_wording.js67
-rw-r--r--browser/components/migration/tests/marionette/manifest.ini5
-rw-r--r--browser/components/migration/tests/marionette/test_refresh_firefox.py416
-rw-r--r--browser/components/migration/tests/unit/.eslintrc.js7
-rw-r--r--browser/components/migration/tests/unit/AppData/Local/Google/Chrome/User Data/Default/Login Databin22528 -> 0 bytes
-rw-r--r--browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Default/Cookiesbin10240 -> 0 bytes
-rw-r--r--browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Local State22
-rw-r--r--browser/components/migration/tests/unit/Library/Safari/Bookmarks.plistbin1860 -> 0 bytes
-rw-r--r--browser/components/migration/tests/unit/head_migration.js69
-rw-r--r--browser/components/migration/tests/unit/test_Chrome_cookies.js51
-rw-r--r--browser/components/migration/tests/unit/test_Chrome_passwords.js219
-rw-r--r--browser/components/migration/tests/unit/test_Edge_availability.js20
-rw-r--r--browser/components/migration/tests/unit/test_Edge_db_migration.js471
-rw-r--r--browser/components/migration/tests/unit/test_IE7_passwords.js397
-rw-r--r--browser/components/migration/tests/unit/test_IE_bookmarks.js44
-rw-r--r--browser/components/migration/tests/unit/test_IE_cookies.js111
-rw-r--r--browser/components/migration/tests/unit/test_Safari_bookmarks.js46
-rw-r--r--browser/components/migration/tests/unit/test_automigration.js695
-rw-r--r--browser/components/migration/tests/unit/test_fx_telemetry.js288
-rw-r--r--browser/components/migration/tests/unit/xpcshell.ini26
-rw-r--r--browser/components/moz.build16
-rw-r--r--browser/components/newtab/moz.build6
-rw-r--r--browser/components/newtab/tests/browser/.eslintrc.js7
-rw-r--r--browser/components/newtab/tests/browser/blue_page.html9
-rw-r--r--browser/components/newtab/tests/browser/browser.ini16
-rw-r--r--browser/components/newtab/tests/browser/browser_PreviewProvider.js90
-rw-r--r--browser/components/newtab/tests/browser/browser_newtab_overrides.js139
-rw-r--r--browser/components/newtab/tests/browser/browser_newtabmessages.js222
-rw-r--r--browser/components/newtab/tests/browser/browser_newtabwebchannel.js251
-rw-r--r--browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js52
-rw-r--r--browser/components/newtab/tests/browser/dummy_page.html10
-rw-r--r--browser/components/newtab/tests/browser/newtabmessages_places.html49
-rw-r--r--browser/components/newtab/tests/browser/newtabmessages_prefs.html32
-rw-r--r--browser/components/newtab/tests/browser/newtabmessages_preview.html37
-rw-r--r--browser/components/newtab/tests/browser/newtabmessages_search.html113
-rw-r--r--browser/components/newtab/tests/browser/newtabwebchannel_basic.html36
-rw-r--r--browser/components/newtab/tests/xpcshell/.eslintrc.js7
-rw-r--r--browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js236
-rw-r--r--browser/components/newtab/tests/xpcshell/test_NewTabPrefsProvider.js50
-rw-r--r--browser/components/newtab/tests/xpcshell/test_NewTabSearchProvider.js82
-rw-r--r--browser/components/newtab/tests/xpcshell/test_NewTabURL.js52
-rw-r--r--browser/components/newtab/tests/xpcshell/test_PlacesProvider.js358
-rw-r--r--browser/components/newtab/tests/xpcshell/xpcshell.ini11
-rw-r--r--browser/components/originattributes/moz.build16
-rw-r--r--browser/components/originattributes/test/browser/.eslintrc.js7
-rw-r--r--browser/components/originattributes/test/browser/browser.ini64
-rw-r--r--browser/components/originattributes/test/browser/browser_blobURLIsolation.js97
-rw-r--r--browser/components/originattributes/test/browser/browser_broadcastChannel.js47
-rw-r--r--browser/components/originattributes/test/browser/browser_cache.js259
-rw-r--r--browser/components/originattributes/test/browser/browser_clientAuth.js44
-rw-r--r--browser/components/originattributes/test/browser/browser_cookieIsolation.js31
-rw-r--r--browser/components/originattributes/test/browser/browser_favicon_firstParty.js343
-rw-r--r--browser/components/originattributes/test/browser/browser_favicon_userContextId.js257
-rw-r--r--browser/components/originattributes/test/browser/browser_firstPartyIsolation.js174
-rw-r--r--browser/components/originattributes/test/browser/browser_httpauth.js54
-rw-r--r--browser/components/originattributes/test/browser/browser_imageCacheIsolation.js80
-rw-r--r--browser/components/originattributes/test/browser/browser_localStorageIsolation.js24
-rw-r--r--browser/components/originattributes/test/browser/browser_sharedworker.js26
-rw-r--r--browser/components/originattributes/test/browser/dummy.html9
-rw-r--r--browser/components/originattributes/test/browser/file_broadcastChannel.html16
-rw-r--r--browser/components/originattributes/test/browser/file_broadcastChanneliFrame.html15
-rw-r--r--browser/components/originattributes/test/browser/file_cache.html25
-rw-r--r--browser/components/originattributes/test/browser/file_favicon.html11
-rw-r--r--browser/components/originattributes/test/browser/file_favicon.pngbin344 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_favicon.png^headers^1
-rw-r--r--browser/components/originattributes/test/browser/file_favicon_cache.html11
-rw-r--r--browser/components/originattributes/test/browser/file_favicon_cache.pngbin344 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_favicon_thirdParty.html11
-rw-r--r--browser/components/originattributes/test/browser/file_firstPartyBasic.html8
-rw-r--r--browser/components/originattributes/test/browser/file_sharedworker.html10
-rw-r--r--browser/components/originattributes/test/browser/file_sharedworker.js9
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.audio.oggbin2603 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.embed.pngbin95 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.fetch.html8
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.iframe.html18
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.img.pngbin95 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.import.js1
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.link.css1
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.object.pngbin95 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.request.html8
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.script.js1
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.sharedworker.js1
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.track.vtt13
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.video.ogvbin16049 -> 0 bytes
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.worker.fetch.html8
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.worker.js9
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.worker.request.html8
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.worker.xhr.html8
-rw-r--r--browser/components/originattributes/test/browser/file_thirdPartyChild.xhr.html8
-rw-r--r--browser/components/originattributes/test/browser/head.js365
-rw-r--r--browser/components/originattributes/test/browser/test.html20
-rw-r--r--browser/components/originattributes/test/browser/test.js1
-rw-r--r--browser/components/originattributes/test/browser/test.js^headers^1
-rw-r--r--browser/components/originattributes/test/browser/test2.html12
-rw-r--r--browser/components/originattributes/test/browser/test2.js1
-rw-r--r--browser/components/originattributes/test/browser/test2.js^headers^1
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty.html15
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty_cookie.html13
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty_html_redirect.html9
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty_http_redirect.html9
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty_http_redirect.html^headers^2
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty_iframe_http_redirect.html13
-rw-r--r--browser/components/originattributes/test/browser/test_firstParty_postMessage.html28
-rw-r--r--browser/components/originattributes/test/browser/window.html13
-rw-r--r--browser/components/originattributes/test/browser/worker_blobify.js11
-rw-r--r--browser/components/originattributes/test/browser/worker_deblobify.js31
-rw-r--r--browser/components/originattributes/test/mochitest/file_empty.html2
-rw-r--r--browser/components/originattributes/test/mochitest/mochitest.ini5
-rw-r--r--browser/components/originattributes/test/mochitest/test_permissions_api.html207
-rw-r--r--browser/components/places/moz.build7
-rw-r--r--browser/components/places/tests/browser/.eslintrc.js7
-rw-r--r--browser/components/places/tests/browser/bookmark_dummy_1.html9
-rw-r--r--browser/components/places/tests/browser/bookmark_dummy_2.html9
-rw-r--r--browser/components/places/tests/browser/browser.ini58
-rw-r--r--browser/components/places/tests/browser/browser_0_library_left_pane_migration.js90
-rw-r--r--browser/components/places/tests/browser/browser_410196_paste_into_tags.js114
-rw-r--r--browser/components/places/tests/browser/browser_416459_cut.js83
-rw-r--r--browser/components/places/tests/browser/browser_423515.js173
-rw-r--r--browser/components/places/tests/browser/browser_425884.js127
-rw-r--r--browser/components/places/tests/browser/browser_435851_copy_query.js59
-rw-r--r--browser/components/places/tests/browser/browser_475045.js65
-rw-r--r--browser/components/places/tests/browser/browser_555547.js66
-rw-r--r--browser/components/places/tests/browser/browser_bookmarkProperties_addFolderDefaultButton.js53
-rw-r--r--browser/components/places/tests/browser/browser_bookmarkProperties_addKeywordForThisSearch.js110
-rw-r--r--browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js39
-rw-r--r--browser/components/places/tests/browser/browser_bookmarkProperties_editTagContainer.js71
-rw-r--r--browser/components/places/tests/browser/browser_bookmarkProperties_readOnlyRoot.js42
-rw-r--r--browser/components/places/tests/browser/browser_bookmark_all_tabs.js37
-rw-r--r--browser/components/places/tests/browser/browser_bookmarklet_windowOpen.js61
-rw-r--r--browser/components/places/tests/browser/browser_bookmarksProperties.js450
-rw-r--r--browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js256
-rw-r--r--browser/components/places/tests/browser/browser_forgetthissite_single.js78
-rw-r--r--browser/components/places/tests/browser/browser_history_sidebar_search.js64
-rw-r--r--browser/components/places/tests/browser/browser_library_batch_delete.js114
-rw-r--r--browser/components/places/tests/browser/browser_library_commands.js235
-rw-r--r--browser/components/places/tests/browser/browser_library_downloads.js70
-rw-r--r--browser/components/places/tests/browser/browser_library_infoBox.js197
-rw-r--r--browser/components/places/tests/browser/browser_library_left_pane_fixnames.js94
-rw-r--r--browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js41
-rw-r--r--browser/components/places/tests/browser/browser_library_middleclick.js279
-rw-r--r--browser/components/places/tests/browser/browser_library_openFlatContainer.js42
-rw-r--r--browser/components/places/tests/browser/browser_library_open_leak.js23
-rw-r--r--browser/components/places/tests/browser/browser_library_panel_leak.js54
-rw-r--r--browser/components/places/tests/browser/browser_library_search.js182
-rw-r--r--browser/components/places/tests/browser/browser_library_views_liveupdate.js300
-rw-r--r--browser/components/places/tests/browser/browser_markPageAsFollowedLink.js68
-rw-r--r--browser/components/places/tests/browser/browser_sidebarpanels_click.js157
-rw-r--r--browser/components/places/tests/browser/browser_sort_in_library.js249
-rw-r--r--browser/components/places/tests/browser/browser_toolbarbutton_menu_context.js53
-rw-r--r--browser/components/places/tests/browser/browser_views_liveupdate.js475
-rw-r--r--browser/components/places/tests/browser/frameLeft.html8
-rw-r--r--browser/components/places/tests/browser/frameRight.html8
-rw-r--r--browser/components/places/tests/browser/framedPage.html9
-rw-r--r--browser/components/places/tests/browser/head.js460
-rw-r--r--browser/components/places/tests/browser/keyword_form.html17
-rw-r--r--browser/components/places/tests/browser/pageopeningwindow.html9
-rw-r--r--browser/components/places/tests/browser/sidebarpanels_click_test_page.html7
-rw-r--r--browser/components/places/tests/chrome/.eslintrc.js7
-rw-r--r--browser/components/places/tests/chrome/chrome.ini15
-rw-r--r--browser/components/places/tests/chrome/head.js7
-rw-r--r--browser/components/places/tests/chrome/test_0_bug510634.xul99
-rw-r--r--browser/components/places/tests/chrome/test_0_multiple_left_pane.xul85
-rw-r--r--browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul89
-rw-r--r--browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul91
-rw-r--r--browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul83
-rw-r--r--browser/components/places/tests/chrome/test_bug549192.xul120
-rw-r--r--browser/components/places/tests/chrome/test_bug549491.xul78
-rw-r--r--browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul170
-rw-r--r--browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul99
-rw-r--r--browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul204
-rw-r--r--browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul86
-rw-r--r--browser/components/places/tests/chrome/test_treeview_date.xul159
-rw-r--r--browser/components/places/tests/unit/.eslintrc.js7
-rw-r--r--browser/components/places/tests/unit/bookmarks.glue.html16
-rw-r--r--browser/components/places/tests/unit/bookmarks.glue.json1
-rw-r--r--browser/components/places/tests/unit/corruptDB.sqlitebin32772 -> 0 bytes
-rw-r--r--browser/components/places/tests/unit/distribution.ini27
-rw-r--r--browser/components/places/tests/unit/head_bookmarks.js133
-rw-r--r--browser/components/places/tests/unit/test_421483.js103
-rw-r--r--browser/components/places/tests/unit/test_PUIU_makeTransaction.js361
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js33
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_corrupt.js59
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js52
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js55
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_distribution.js125
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_migrate.js70
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_prefs.js240
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_restore.js62
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js285
-rw-r--r--browser/components/places/tests/unit/test_browserGlue_urlbar_defaultbehavior_migration.js150
-rw-r--r--browser/components/places/tests/unit/test_clearHistory_shutdown.js181
-rw-r--r--browser/components/places/tests/unit/test_leftpane_corruption_handling.js174
-rw-r--r--browser/components/places/tests/unit/xpcshell.ini25
-rw-r--r--browser/components/preferences/in-content/tests/.eslintrc.js7
-rw-r--r--browser/components/preferences/in-content/tests/browser.ini43
-rw-r--r--browser/components/preferences/in-content/tests/browser_advanced_update.js158
-rw-r--r--browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js76
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug1018066_resetScrollPosition.js24
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js43
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.js92
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul33
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug410900.js46
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug705422.js144
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug731866.js52
-rw-r--r--browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js52
-rw-r--r--browser/components/preferences/in-content/tests/browser_change_app_handler.js98
-rw-r--r--browser/components/preferences/in-content/tests/browser_connection.js99
-rw-r--r--browser/components/preferences/in-content/tests/browser_connection_bug388287.js125
-rw-r--r--browser/components/preferences/in-content/tests/browser_cookies_exceptions.js348
-rw-r--r--browser/components/preferences/in-content/tests/browser_defaultbrowser_alwayscheck.js103
-rw-r--r--browser/components/preferences/in-content/tests/browser_healthreport.js62
-rw-r--r--browser/components/preferences/in-content/tests/browser_homepages_filter_aboutpreferences.js20
-rw-r--r--browser/components/preferences/in-content/tests/browser_notifications_do_not_disturb.js44
-rw-r--r--browser/components/preferences/in-content/tests/browser_permissions_urlFieldHidden.js45
-rw-r--r--browser/components/preferences/in-content/tests/browser_privacypane_1.js18
-rw-r--r--browser/components/preferences/in-content/tests/browser_privacypane_3.js17
-rw-r--r--browser/components/preferences/in-content/tests/browser_privacypane_4.js25
-rw-r--r--browser/components/preferences/in-content/tests/browser_privacypane_5.js17
-rw-r--r--browser/components/preferences/in-content/tests/browser_privacypane_8.js26
-rw-r--r--browser/components/preferences/in-content/tests/browser_proxy_backup.js65
-rw-r--r--browser/components/preferences/in-content/tests/browser_sanitizeOnShutdown_prefLocked.js37
-rw-r--r--browser/components/preferences/in-content/tests/browser_searchsuggestions.js43
-rw-r--r--browser/components/preferences/in-content/tests/browser_security.js130
-rw-r--r--browser/components/preferences/in-content/tests/browser_subdialogs.js293
-rw-r--r--browser/components/preferences/in-content/tests/browser_telemetry.js52
-rw-r--r--browser/components/preferences/in-content/tests/head.js165
-rw-r--r--browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js330
-rw-r--r--browser/components/preferences/in-content/tests/subdialog.xul27
-rw-r--r--browser/components/preferences/in-content/tests/subdialog2.xul27
-rw-r--r--browser/components/preferences/moz.build7
-rw-r--r--browser/components/privatebrowsing/moz.build7
-rw-r--r--browser/components/privatebrowsing/test/browser/.eslintrc.js7
-rw-r--r--browser/components/privatebrowsing/test/browser/browser.ini54
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_DownloadLastDirWithCPS.js282
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js115
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js24
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutSessionRestore.js23
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_blobUrl.js45
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js138
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js53
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js88
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html33
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_context_and_chromeFlags.js60
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js42
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js93
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js95
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_toggle.js105
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_favicon.js293
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js54
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html13
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_lastpbcontextexited.js49
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js25
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js36
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page.html11
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page2.html10
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page1.html10
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page2.html10
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_newtab_from_popup.js61
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_noSessionRestoreMenuOption.js23
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_nonbrowser.js19
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js133
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html8
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.js72
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js95
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js70
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js47
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html13
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sidebar.js92
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js38
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js82
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js43
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js77
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html9
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js37
-rw-r--r--browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js64
-rw-r--r--browser/components/privatebrowsing/test/browser/empty_file.html1
-rw-r--r--browser/components/privatebrowsing/test/browser/file_favicon.html11
-rw-r--r--browser/components/privatebrowsing/test/browser/file_favicon.pngbin344 -> 0 bytes
-rw-r--r--browser/components/privatebrowsing/test/browser/file_favicon.png^headers^1
-rw-r--r--browser/components/privatebrowsing/test/browser/head.js63
-rw-r--r--browser/components/privatebrowsing/test/browser/popup.html12
-rw-r--r--browser/components/privatebrowsing/test/browser/title.sjs22
-rw-r--r--browser/components/safebrowsing/content/test/.eslintrc.js7
-rw-r--r--browser/components/safebrowsing/content/test/browser.ini8
-rw-r--r--browser/components/safebrowsing/content/test/browser_bug400731.js58
-rw-r--r--browser/components/safebrowsing/content/test/browser_bug415846.js86
-rw-r--r--browser/components/safebrowsing/content/test/browser_whitelisted.js41
-rw-r--r--browser/components/safebrowsing/content/test/head.js55
-rw-r--r--browser/components/search/moz.build7
-rw-r--r--browser/components/search/test/.eslintrc.js7
-rw-r--r--browser/components/search/test/426329.xml11
-rw-r--r--browser/components/search/test/483086-1.xml10
-rw-r--r--browser/components/search/test/483086-2.xml10
-rw-r--r--browser/components/search/test/browser.ini44
-rw-r--r--browser/components/search/test/browser_426329.js250
-rw-r--r--browser/components/search/test/browser_483086.js49
-rw-r--r--browser/components/search/test/browser_aboutSearchReset.js159
-rw-r--r--browser/components/search/test/browser_abouthome_behavior.js144
-rw-r--r--browser/components/search/test/browser_addEngine.js105
-rw-r--r--browser/components/search/test/browser_amazon.js82
-rw-r--r--browser/components/search/test/browser_amazon_behavior.js166
-rw-r--r--browser/components/search/test/browser_bing.js118
-rw-r--r--browser/components/search/test/browser_bing_behavior.js166
-rw-r--r--browser/components/search/test/browser_contextSearchTabPosition.js62
-rw-r--r--browser/components/search/test/browser_contextmenu.js101
-rw-r--r--browser/components/search/test/browser_google.js100
-rw-r--r--browser/components/search/test/browser_google_behavior.js165
-rw-r--r--browser/components/search/test/browser_google_codes.js161
-rw-r--r--browser/components/search/test/browser_healthreport.js82
-rw-r--r--browser/components/search/test/browser_hiddenOneOffs_cleanup.js99
-rw-r--r--browser/components/search/test/browser_hiddenOneOffs_diacritics.js59
-rw-r--r--browser/components/search/test/browser_oneOffContextMenu.js105
-rw-r--r--browser/components/search/test/browser_oneOffContextMenu_setDefault.js195
-rw-r--r--browser/components/search/test/browser_oneOffHeader.js142
-rw-r--r--browser/components/search/test/browser_private_search_perwindowpb.js76
-rw-r--r--browser/components/search/test/browser_searchbar_keyboard_navigation.js425
-rw-r--r--browser/components/search/test/browser_searchbar_openpopup.js521
-rw-r--r--browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js354
-rw-r--r--browser/components/search/test/browser_webapi.js92
-rw-r--r--browser/components/search/test/browser_yahoo.js132
-rw-r--r--browser/components/search/test/browser_yahoo_behavior.js166
-rw-r--r--browser/components/search/test/head.js156
-rw-r--r--browser/components/search/test/opensearch.html9
-rw-r--r--browser/components/search/test/test.html8
-rw-r--r--browser/components/search/test/testEngine.xml12
-rw-r--r--browser/components/search/test/testEngine_diacritics.xml12
-rw-r--r--browser/components/search/test/testEngine_dupe.xml12
-rw-r--r--browser/components/search/test/testEngine_mozsearch.xml14
-rw-r--r--browser/components/search/test/webapi.html16
-rw-r--r--browser/components/selfsupport/moz.build4
-rw-r--r--browser/components/selfsupport/test/.eslintrc.js7
-rw-r--r--browser/components/selfsupport/test/browser.ini3
-rw-r--r--browser/components/selfsupport/test/browser_selfsupportAPI.js88
-rw-r--r--browser/components/sessionstore/moz.build6
-rw-r--r--browser/components/sessionstore/test/.eslintrc.js7
-rw-r--r--browser/components/sessionstore/test/browser.ini242
-rw-r--r--browser/components/sessionstore/test/browser_1234021.js18
-rw-r--r--browser/components/sessionstore/test/browser_1234021_page.html6
-rw-r--r--browser/components/sessionstore/test/browser_248970_b_perwindowpb.js166
-rw-r--r--browser/components/sessionstore/test/browser_248970_b_sample.html37
-rw-r--r--browser/components/sessionstore/test/browser_339445.js32
-rw-r--r--browser/components/sessionstore/test/browser_339445_sample.html18
-rw-r--r--browser/components/sessionstore/test/browser_345898.js44
-rw-r--r--browser/components/sessionstore/test/browser_350525.js102
-rw-r--r--browser/components/sessionstore/test/browser_354894_perwindowpb.js474
-rw-r--r--browser/components/sessionstore/test/browser_367052.js41
-rw-r--r--browser/components/sessionstore/test/browser_393716.js71
-rw-r--r--browser/components/sessionstore/test/browser_394759_basic.js92
-rw-r--r--browser/components/sessionstore/test/browser_394759_behavior.js76
-rw-r--r--browser/components/sessionstore/test/browser_394759_perwindowpb.js55
-rw-r--r--browser/components/sessionstore/test/browser_394759_purge.js130
-rw-r--r--browser/components/sessionstore/test/browser_423132.js59
-rw-r--r--browser/components/sessionstore/test/browser_423132_sample.html14
-rw-r--r--browser/components/sessionstore/test/browser_447951.js65
-rw-r--r--browser/components/sessionstore/test/browser_447951_sample.html5
-rw-r--r--browser/components/sessionstore/test/browser_454908.js47
-rw-r--r--browser/components/sessionstore/test/browser_454908_sample.html8
-rw-r--r--browser/components/sessionstore/test/browser_456342.js49
-rw-r--r--browser/components/sessionstore/test/browser_456342_sample.xhtml36
-rw-r--r--browser/components/sessionstore/test/browser_459906.js62
-rw-r--r--browser/components/sessionstore/test/browser_459906_empty.html3
-rw-r--r--browser/components/sessionstore/test/browser_459906_sample.html41
-rw-r--r--browser/components/sessionstore/test/browser_461634.js85
-rw-r--r--browser/components/sessionstore/test/browser_461743.js39
-rw-r--r--browser/components/sessionstore/test/browser_461743_sample.html56
-rw-r--r--browser/components/sessionstore/test/browser_463205.js40
-rw-r--r--browser/components/sessionstore/test/browser_463205_sample.html7
-rw-r--r--browser/components/sessionstore/test/browser_463206.js53
-rw-r--r--browser/components/sessionstore/test/browser_463206_sample.html11
-rw-r--r--browser/components/sessionstore/test/browser_464199.js85
-rw-r--r--browser/components/sessionstore/test/browser_464620_a.html54
-rw-r--r--browser/components/sessionstore/test/browser_464620_a.js48
-rw-r--r--browser/components/sessionstore/test/browser_464620_b.html58
-rw-r--r--browser/components/sessionstore/test/browser_464620_b.js48
-rw-r--r--browser/components/sessionstore/test/browser_464620_xd.html5
-rw-r--r--browser/components/sessionstore/test/browser_465215.js28
-rw-r--r--browser/components/sessionstore/test/browser_465223.js45
-rw-r--r--browser/components/sessionstore/test/browser_466937.js42
-rw-r--r--browser/components/sessionstore/test/browser_466937_sample.html22
-rw-r--r--browser/components/sessionstore/test/browser_467409-backslashplosion.js74
-rw-r--r--browser/components/sessionstore/test/browser_477657.js60
-rw-r--r--browser/components/sessionstore/test/browser_480893.js47
-rw-r--r--browser/components/sessionstore/test/browser_485482.js37
-rw-r--r--browser/components/sessionstore/test/browser_485482_sample.html12
-rw-r--r--browser/components/sessionstore/test/browser_485563.js26
-rw-r--r--browser/components/sessionstore/test/browser_490040.js65
-rw-r--r--browser/components/sessionstore/test/browser_491168.js42
-rw-r--r--browser/components/sessionstore/test/browser_491577.js120
-rw-r--r--browser/components/sessionstore/test/browser_495495.js46
-rw-r--r--browser/components/sessionstore/test/browser_500328.js120
-rw-r--r--browser/components/sessionstore/test/browser_506482.js73
-rw-r--r--browser/components/sessionstore/test/browser_514751.js38
-rw-r--r--browser/components/sessionstore/test/browser_522375.js21
-rw-r--r--browser/components/sessionstore/test/browser_522545.js269
-rw-r--r--browser/components/sessionstore/test/browser_524745.js42
-rw-r--r--browser/components/sessionstore/test/browser_526613.js72
-rw-r--r--browser/components/sessionstore/test/browser_528776.js21
-rw-r--r--browser/components/sessionstore/test/browser_579868.js30
-rw-r--r--browser/components/sessionstore/test/browser_579879.js20
-rw-r--r--browser/components/sessionstore/test/browser_580512.js81
-rw-r--r--browser/components/sessionstore/test/browser_581937.js19
-rw-r--r--browser/components/sessionstore/test/browser_586068-apptabs.js58
-rw-r--r--browser/components/sessionstore/test/browser_586068-apptabs_ondemand.js53
-rw-r--r--browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js113
-rw-r--r--browser/components/sessionstore/test/browser_586068-cascade.js54
-rw-r--r--browser/components/sessionstore/test/browser_586068-multi_window.js70
-rw-r--r--browser/components/sessionstore/test/browser_586068-reload.js54
-rw-r--r--browser/components/sessionstore/test/browser_586068-select.js69
-rw-r--r--browser/components/sessionstore/test/browser_586068-window_state.js59
-rw-r--r--browser/components/sessionstore/test/browser_586068-window_state_override.js59
-rw-r--r--browser/components/sessionstore/test/browser_586147.js52
-rw-r--r--browser/components/sessionstore/test/browser_588426.js41
-rw-r--r--browser/components/sessionstore/test/browser_589246.js242
-rw-r--r--browser/components/sessionstore/test/browser_590268.js137
-rw-r--r--browser/components/sessionstore/test/browser_590563.js74
-rw-r--r--browser/components/sessionstore/test/browser_595601-restore_hidden.js112
-rw-r--r--browser/components/sessionstore/test/browser_597071.js36
-rw-r--r--browser/components/sessionstore/test/browser_599909.js120
-rw-r--r--browser/components/sessionstore/test/browser_600545.js89
-rw-r--r--browser/components/sessionstore/test/browser_601955.js54
-rw-r--r--browser/components/sessionstore/test/browser_607016.js98
-rw-r--r--browser/components/sessionstore/test/browser_615394-SSWindowState_events.js361
-rw-r--r--browser/components/sessionstore/test/browser_618151.js65
-rw-r--r--browser/components/sessionstore/test/browser_623779.js13
-rw-r--r--browser/components/sessionstore/test/browser_624727.js35
-rw-r--r--browser/components/sessionstore/test/browser_625016.js82
-rw-r--r--browser/components/sessionstore/test/browser_628270.js52
-rw-r--r--browser/components/sessionstore/test/browser_635418.js55
-rw-r--r--browser/components/sessionstore/test/browser_636279.js101
-rw-r--r--browser/components/sessionstore/test/browser_637020.js66
-rw-r--r--browser/components/sessionstore/test/browser_637020_slow.sjs21
-rw-r--r--browser/components/sessionstore/test/browser_644409-scratchpads.js68
-rw-r--r--browser/components/sessionstore/test/browser_645428.js22
-rw-r--r--browser/components/sessionstore/test/browser_659591.js33
-rw-r--r--browser/components/sessionstore/test/browser_662743.js110
-rw-r--r--browser/components/sessionstore/test/browser_662743_sample.html15
-rw-r--r--browser/components/sessionstore/test/browser_662812.js36
-rw-r--r--browser/components/sessionstore/test/browser_665702-state_session.js24
-rw-r--r--browser/components/sessionstore/test/browser_682507.js16
-rw-r--r--browser/components/sessionstore/test/browser_687710.js44
-rw-r--r--browser/components/sessionstore/test/browser_687710_2.js64
-rw-r--r--browser/components/sessionstore/test/browser_694378.js33
-rw-r--r--browser/components/sessionstore/test/browser_701377.js41
-rw-r--r--browser/components/sessionstore/test/browser_705597.js58
-rw-r--r--browser/components/sessionstore/test/browser_707862.js61
-rw-r--r--browser/components/sessionstore/test/browser_739531.js47
-rw-r--r--browser/components/sessionstore/test/browser_739531_sample.html25
-rw-r--r--browser/components/sessionstore/test/browser_739805.js41
-rw-r--r--browser/components/sessionstore/test/browser_819510_perwindowpb.js120
-rw-r--r--browser/components/sessionstore/test/browser_911547.js63
-rw-r--r--browser/components/sessionstore/test/browser_911547_sample.html19
-rw-r--r--browser/components/sessionstore/test/browser_911547_sample.html^headers^1
-rw-r--r--browser/components/sessionstore/test/browser_aboutPrivateBrowsing.js21
-rw-r--r--browser/components/sessionstore/test/browser_aboutSessionRestore.js55
-rw-r--r--browser/components/sessionstore/test/browser_async_duplicate_tab.js78
-rw-r--r--browser/components/sessionstore/test/browser_async_flushes.js113
-rw-r--r--browser/components/sessionstore/test/browser_async_remove_tab.js242
-rw-r--r--browser/components/sessionstore/test/browser_async_window_flushing.js178
-rw-r--r--browser/components/sessionstore/test/browser_attributes.js73
-rw-r--r--browser/components/sessionstore/test/browser_background_tab_crash.js221
-rw-r--r--browser/components/sessionstore/test/browser_backup_recovery.js206
-rw-r--r--browser/components/sessionstore/test/browser_broadcast.js131
-rw-r--r--browser/components/sessionstore/test/browser_capabilities.js76
-rw-r--r--browser/components/sessionstore/test/browser_cleaner.js157
-rw-r--r--browser/components/sessionstore/test/browser_cookies.js173
-rw-r--r--browser/components/sessionstore/test/browser_cookies.sjs21
-rw-r--r--browser/components/sessionstore/test/browser_crashedTabs.js462
-rw-r--r--browser/components/sessionstore/test/browser_dying_cache.js66
-rw-r--r--browser/components/sessionstore/test/browser_dynamic_frames.js87
-rw-r--r--browser/components/sessionstore/test/browser_forget_async_closings.js144
-rw-r--r--browser/components/sessionstore/test/browser_form_restore_events.js63
-rw-r--r--browser/components/sessionstore/test/browser_form_restore_events_sample.html99
-rw-r--r--browser/components/sessionstore/test/browser_formdata.js194
-rw-r--r--browser/components/sessionstore/test/browser_formdata_cc.js79
-rw-r--r--browser/components/sessionstore/test/browser_formdata_format.js113
-rw-r--r--browser/components/sessionstore/test/browser_formdata_format_sample.html7
-rw-r--r--browser/components/sessionstore/test/browser_formdata_sample.html20
-rw-r--r--browser/components/sessionstore/test/browser_formdata_xpath.js151
-rw-r--r--browser/components/sessionstore/test/browser_formdata_xpath_sample.html37
-rw-r--r--browser/components/sessionstore/test/browser_frame_history.js170
-rwxr-xr-xbrowser/components/sessionstore/test/browser_frame_history_a.html5
-rwxr-xr-xbrowser/components/sessionstore/test/browser_frame_history_b.html10
-rwxr-xr-xbrowser/components/sessionstore/test/browser_frame_history_c.html5
-rwxr-xr-xbrowser/components/sessionstore/test/browser_frame_history_c1.html5
-rwxr-xr-xbrowser/components/sessionstore/test/browser_frame_history_c2.html5
-rw-r--r--browser/components/sessionstore/test/browser_frame_history_index.html10
-rw-r--r--browser/components/sessionstore/test/browser_frame_history_index2.html4
-rw-r--r--browser/components/sessionstore/test/browser_frame_history_index_blank.html5
-rw-r--r--browser/components/sessionstore/test/browser_frametree.js131
-rw-r--r--browser/components/sessionstore/test/browser_frametree_sample.html8
-rw-r--r--browser/components/sessionstore/test/browser_frametree_sample_frameset.html11
-rw-r--r--browser/components/sessionstore/test/browser_global_store.js45
-rw-r--r--browser/components/sessionstore/test/browser_history_persist.js93
-rw-r--r--browser/components/sessionstore/test/browser_label_and_icon.js53
-rw-r--r--browser/components/sessionstore/test/browser_merge_closed_tabs.js71
-rw-r--r--browser/components/sessionstore/test/browser_multiple_navigateAndRestore.js36
-rw-r--r--browser/components/sessionstore/test/browser_newtab_userTypedValue.js72
-rw-r--r--browser/components/sessionstore/test/browser_pageStyle.js89
-rw-r--r--browser/components/sessionstore/test/browser_pageStyle_sample.html16
-rw-r--r--browser/components/sessionstore/test/browser_pageStyle_sample_nested.html9
-rw-r--r--browser/components/sessionstore/test/browser_page_title.js45
-rw-r--r--browser/components/sessionstore/test/browser_parentProcessRestoreHash.js95
-rw-r--r--browser/components/sessionstore/test/browser_pending_tabs.js35
-rw-r--r--browser/components/sessionstore/test/browser_privatetabs.js133
-rw-r--r--browser/components/sessionstore/test/browser_purge_shistory.js59
-rw-r--r--browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js342
-rw-r--r--browser/components/sessionstore/test/browser_replace_load.js52
-rw-r--r--browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js171
-rw-r--r--browser/components/sessionstore/test/browser_restore_redirect.js69
-rw-r--r--browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js56
-rw-r--r--browser/components/sessionstore/test/browser_scrollPositions.js153
-rw-r--r--browser/components/sessionstore/test/browser_scrollPositionsReaderMode.js67
-rw-r--r--browser/components/sessionstore/test/browser_scrollPositions_readerModeArticle.html26
-rw-r--r--browser/components/sessionstore/test/browser_scrollPositions_sample.html8
-rw-r--r--browser/components/sessionstore/test/browser_scrollPositions_sample_frameset.html11
-rw-r--r--browser/components/sessionstore/test/browser_send_async_message_oom.js75
-rw-r--r--browser/components/sessionstore/test/browser_sessionHistory.js240
-rw-r--r--browser/components/sessionstore/test/browser_sessionHistory_slow.sjs21
-rw-r--r--browser/components/sessionstore/test/browser_sessionStorage.html27
-rw-r--r--browser/components/sessionstore/test/browser_sessionStorage.js188
-rw-r--r--browser/components/sessionstore/test/browser_sessionStorage_size.js51
-rw-r--r--browser/components/sessionstore/test/browser_sessionStoreContainer.js141
-rw-r--r--browser/components/sessionstore/test/browser_swapDocShells.js35
-rw-r--r--browser/components/sessionstore/test/browser_switch_remoteness.js49
-rw-r--r--browser/components/sessionstore/test/browser_undoCloseById.js118
-rw-r--r--browser/components/sessionstore/test/browser_unrestored_crashedTabs.js69
-rw-r--r--browser/components/sessionstore/test/browser_upgrade_backup.js134
-rw-r--r--browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js26
-rw-r--r--browser/components/sessionstore/test/browser_windowStateContainer.js122
-rw-r--r--browser/components/sessionstore/test/content-forms.js133
-rw-r--r--browser/components/sessionstore/test/content.js222
-rw-r--r--browser/components/sessionstore/test/head.js564
-rw-r--r--browser/components/sessionstore/test/restore_redirect_http.html0
-rw-r--r--browser/components/sessionstore/test/restore_redirect_http.html^headers^2
-rw-r--r--browser/components/sessionstore/test/restore_redirect_js.html10
-rw-r--r--browser/components/sessionstore/test/restore_redirect_target.html8
-rw-r--r--browser/components/sessionstore/test/unit/.eslintrc.js7
-rw-r--r--browser/components/sessionstore/test/unit/data/sessionCheckpoints_all.json1
-rw-r--r--browser/components/sessionstore/test/unit/data/sessionstore_invalid.js3
-rw-r--r--browser/components/sessionstore/test/unit/data/sessionstore_valid.js3
-rw-r--r--browser/components/sessionstore/test/unit/head.js32
-rw-r--r--browser/components/sessionstore/test/unit/test_backup_once.js130
-rw-r--r--browser/components/sessionstore/test/unit/test_histogram_corrupt_files.js114
-rw-r--r--browser/components/sessionstore/test/unit/test_shutdown_cleanup.js127
-rw-r--r--browser/components/sessionstore/test/unit/test_startup_invalid_session.js21
-rw-r--r--browser/components/sessionstore/test/unit/test_startup_nosession_async.js22
-rw-r--r--browser/components/sessionstore/test/unit/test_startup_session_async.js27
-rw-r--r--browser/components/sessionstore/test/unit/xpcshell.ini16
-rw-r--r--browser/components/shell/moz.build6
-rw-r--r--browser/components/shell/test/.eslintrc.js7
-rw-r--r--browser/components/shell/test/browser.ini6
-rw-r--r--browser/components/shell/test/browser_420786.js88
-rw-r--r--browser/components/shell/test/browser_633221.js7
-rw-r--r--browser/components/shell/test/unit/.eslintrc.js7
-rw-r--r--browser/components/shell/test/unit/test_421977.js123
-rw-r--r--browser/components/shell/test/unit/xpcshell.ini7
-rw-r--r--browser/components/syncedtabs/moz.build7
-rw-r--r--browser/components/syncedtabs/test/browser/.eslintrc.js7
-rw-r--r--browser/components/syncedtabs/test/browser/browser.ini4
-rw-r--r--browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js410
-rw-r--r--browser/components/syncedtabs/test/browser/head.js19
-rw-r--r--browser/components/syncedtabs/test/xpcshell/.eslintrc.js7
-rw-r--r--browser/components/syncedtabs/test/xpcshell/head.js29
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_EventEmitter.js35
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js218
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckStore.js64
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js266
-rw-r--r--browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js155
-rw-r--r--browser/components/syncedtabs/test/xpcshell/xpcshell.ini10
-rw-r--r--browser/components/tests/browser/.eslintrc.js7
-rw-r--r--browser/components/tests/browser/browser.ini4
-rw-r--r--browser/components/tests/browser/browser_bug538331.js426
-rw-r--r--browser/components/tests/browser/browser_contentpermissionprompt.js166
-rw-r--r--browser/components/tests/unit/.eslintrc.js7
-rw-r--r--browser/components/tests/unit/data/engine-de-DE.xml8
-rw-r--r--browser/components/tests/unit/distribution.ini58
-rw-r--r--browser/components/tests/unit/head.js9
-rw-r--r--browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js32
-rw-r--r--browser/components/tests/unit/test_distribution.js152
-rw-r--r--browser/components/tests/unit/xpcshell.ini10
-rw-r--r--browser/components/translation/moz.build8
-rw-r--r--browser/components/translation/test/.eslintrc.js7
-rw-r--r--browser/components/translation/test/bing.sjs234
-rw-r--r--browser/components/translation/test/browser.ini13
-rw-r--r--browser/components/translation/test/browser_translation_bing.js133
-rw-r--r--browser/components/translation/test/browser_translation_exceptions.js327
-rw-r--r--browser/components/translation/test/browser_translation_infobar.js216
-rw-r--r--browser/components/translation/test/browser_translation_telemetry.js300
-rw-r--r--browser/components/translation/test/browser_translation_yandex.js130
-rw-r--r--browser/components/translation/test/fixtures/bug1022725-fr.html15
-rw-r--r--browser/components/translation/test/fixtures/result-da39a3ee5e.txt22
-rw-r--r--browser/components/translation/test/fixtures/result-yandex-d448894848.json1
-rw-r--r--browser/components/translation/test/unit/.eslintrc.js7
-rw-r--r--browser/components/translation/test/unit/test_cld2.js463
-rw-r--r--browser/components/translation/test/unit/xpcshell.ini7
-rw-r--r--browser/components/translation/test/yandex.sjs199
-rw-r--r--browser/components/uitour/moz.build7
-rw-r--r--browser/components/uitour/test/.eslintrc.js7
-rw-r--r--browser/components/uitour/test/browser.ini49
-rw-r--r--browser/components/uitour/test/browser_UITour.js408
-rw-r--r--browser/components/uitour/test/browser_UITour2.js83
-rw-r--r--browser/components/uitour/test/browser_UITour3.js181
-rw-r--r--browser/components/uitour/test/browser_UITour_annotation_size_attributes.js42
-rw-r--r--browser/components/uitour/test/browser_UITour_availableTargets.js114
-rw-r--r--browser/components/uitour/test/browser_UITour_defaultBrowser.js61
-rw-r--r--browser/components/uitour/test/browser_UITour_detach_tab.js94
-rw-r--r--browser/components/uitour/test/browser_UITour_forceReaderMode.js17
-rw-r--r--browser/components/uitour/test/browser_UITour_heartbeat.js755
-rw-r--r--browser/components/uitour/test/browser_UITour_modalDialog.js104
-rw-r--r--browser/components/uitour/test/browser_UITour_observe.js85
-rw-r--r--browser/components/uitour/test/browser_UITour_panel_close_annotation.js153
-rw-r--r--browser/components/uitour/test/browser_UITour_pocket.js82
-rw-r--r--browser/components/uitour/test/browser_UITour_registerPageID.js108
-rw-r--r--browser/components/uitour/test/browser_UITour_resetProfile.js48
-rw-r--r--browser/components/uitour/test/browser_UITour_showNewTab.js17
-rw-r--r--browser/components/uitour/test/browser_UITour_sync.js105
-rw-r--r--browser/components/uitour/test/browser_UITour_toggleReaderMode.js16
-rw-r--r--browser/components/uitour/test/browser_backgroundTab.js46
-rw-r--r--browser/components/uitour/test/browser_closeTab.js18
-rw-r--r--browser/components/uitour/test/browser_fxa.js68
-rw-r--r--browser/components/uitour/test/browser_no_tabs.js102
-rw-r--r--browser/components/uitour/test/browser_openPreferences.js36
-rw-r--r--browser/components/uitour/test/browser_openSearchPanel.js33
-rw-r--r--browser/components/uitour/test/browser_showMenu_controlCenter.js44
-rw-r--r--browser/components/uitour/test/browser_trackingProtection.js90
-rw-r--r--browser/components/uitour/test/browser_trackingProtection_tour.js77
-rw-r--r--browser/components/uitour/test/head.js449
-rw-r--r--browser/components/uitour/test/image.pngbin56060 -> 0 bytes
-rw-r--r--browser/components/uitour/test/uitour.html42
-rwxr-xr-xbrowser/confvars.sh4
-rw-r--r--browser/extensions/formautofill/moz.build4
-rw-r--r--browser/extensions/formautofill/test/browser/.eslintrc.js7
-rw-r--r--browser/extensions/formautofill/test/browser/browser.ini3
-rw-r--r--browser/extensions/formautofill/test/browser/browser_check_installed.js14
-rw-r--r--browser/extensions/formautofill/test/unit/.eslintrc5
-rw-r--r--browser/extensions/formautofill/test/unit/head.js81
-rw-r--r--browser/extensions/formautofill/test/unit/test_autofillFormFields.js200
-rw-r--r--browser/extensions/formautofill/test/unit/test_collectFormFields.js122
-rw-r--r--browser/extensions/formautofill/test/unit/test_populateFieldValues.js106
-rw-r--r--browser/extensions/formautofill/test/unit/test_profileStorage.js222
-rw-r--r--browser/extensions/formautofill/test/unit/xpcshell.ini12
-rw-r--r--browser/extensions/moz.build8
-rw-r--r--browser/extensions/pdfjs/moz.build2
-rw-r--r--browser/extensions/pdfjs/test/.eslintrc.js7
-rw-r--r--browser/extensions/pdfjs/test/browser.ini10
-rw-r--r--browser/extensions/pdfjs/test/browser_pdfjs_main.js67
-rw-r--r--browser/extensions/pdfjs/test/browser_pdfjs_navigation.js283
-rw-r--r--browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js65
-rw-r--r--browser/extensions/pdfjs/test/browser_pdfjs_views.js67
-rw-r--r--browser/extensions/pdfjs/test/browser_pdfjs_zoom.js154
-rw-r--r--browser/extensions/pdfjs/test/file_pdfjs_test.pdfbin150611 -> 0 bytes
-rw-r--r--browser/extensions/pdfjs/test/head.js15
-rw-r--r--browser/extensions/pocket/moz.build2
-rw-r--r--browser/extensions/pocket/test/.eslintrc.js7
-rw-r--r--browser/extensions/pocket/test/browser.ini6
-rw-r--r--browser/extensions/pocket/test/browser_pocket_ui_check.js61
-rw-r--r--browser/extensions/pocket/test/head.js67
-rw-r--r--browser/extensions/pocket/test/test.html11
-rw-r--r--browser/extensions/webcompat/moz.build2
-rw-r--r--browser/extensions/webcompat/test/browser/.eslintrc.js7
-rw-r--r--browser/extensions/webcompat/test/browser/browser.ini3
-rw-r--r--browser/extensions/webcompat/test/browser/browser_check_installed.js13
-rw-r--r--browser/installer/windows/moz.build2
-rw-r--r--browser/locales/Makefile.in2
-rw-r--r--browser/locales/en-US/chrome/browser-region/region.properties4
-rw-r--r--browser/locales/en-US/chrome/overrides/netError.dtd2
-rw-r--r--browser/locales/generic/profile/bookmarks.html.in29
-rw-r--r--browser/locales/jar.mn1
-rw-r--r--browser/locales/search/list.json372
-rw-r--r--browser/locales/searchplugins/allaannonser-sv-SE.xml17
-rw-r--r--browser/locales/searchplugins/allegro-pl.xml17
-rw-r--r--browser/locales/searchplugins/amazon-en-GB.xml18
-rw-r--r--browser/locales/searchplugins/amazon-france.xml18
-rw-r--r--browser/locales/searchplugins/amazon-in.xml17
-rw-r--r--browser/locales/searchplugins/amazon-it.xml18
-rw-r--r--browser/locales/searchplugins/amazon-jp.xml30
-rw-r--r--browser/locales/searchplugins/amazondotcn.xml20
-rw-r--r--browser/locales/searchplugins/amazondotcom-de.xml18
-rw-r--r--browser/locales/searchplugins/amazondotcom.xml18
-rw-r--r--browser/locales/searchplugins/atlas-sk.xml15
-rw-r--r--browser/locales/searchplugins/azerdict.xml18
-rw-r--r--browser/locales/searchplugins/azet-sk.xml15
-rw-r--r--browser/locales/searchplugins/baidu.xml22
-rw-r--r--browser/locales/searchplugins/bbc-alba.xml19
-rw-r--r--browser/locales/searchplugins/bing.xml6
-rw-r--r--browser/locales/searchplugins/bok-NO.xml16
-rw-r--r--browser/locales/searchplugins/bolcom-fy-NL.xml13
-rw-r--r--browser/locales/searchplugins/bolcom-nl.xml13
-rw-r--r--browser/locales/searchplugins/bookplus-fi.xml15
-rw-r--r--browser/locales/searchplugins/buscape.xml15
-rw-r--r--browser/locales/searchplugins/ceneji.xml15
-rw-r--r--browser/locales/searchplugins/chambers-en-GB.xml16
-rw-r--r--browser/locales/searchplugins/cnrtl-tlfi-fr.xml16
-rw-r--r--browser/locales/searchplugins/danawa-kr.xml15
-rw-r--r--browser/locales/searchplugins/daum-kr.xml21
-rw-r--r--browser/locales/searchplugins/ddg.xml10
-rw-r--r--browser/locales/searchplugins/diccionariu-alla.xml14
-rw-r--r--browser/locales/searchplugins/dict-enlv.xml15
-rw-r--r--browser/locales/searchplugins/diec2.xml15
-rw-r--r--browser/locales/searchplugins/diribg.xml17
-rw-r--r--browser/locales/searchplugins/drae.xml13
-rw-r--r--browser/locales/searchplugins/dunaj-sk.xml18
-rw-r--r--browser/locales/searchplugins/eki-ee.xml19
-rw-r--r--browser/locales/searchplugins/elebila.xml16
-rw-r--r--browser/locales/searchplugins/eudict.xml16
-rw-r--r--browser/locales/searchplugins/faclair-beag.xml13
-rw-r--r--browser/locales/searchplugins/findbook-zh-TW.xml18
-rw-r--r--browser/locales/searchplugins/flip.xml19
-rw-r--r--browser/locales/searchplugins/freelang.xml18
-rw-r--r--browser/locales/searchplugins/google-nocodes.xml16
-rw-r--r--browser/locales/searchplugins/google.xml18
-rw-r--r--browser/locales/searchplugins/gujaratilexicon.xml18
-rw-r--r--browser/locales/searchplugins/gulesider-NO.xml16
-rw-r--r--browser/locales/searchplugins/heureka-cz.xml18
-rw-r--r--browser/locales/searchplugins/hoepli.xml17
-rw-r--r--browser/locales/searchplugins/images/yandex-en.icobin1691 -> 0 bytes
-rw-r--r--browser/locales/searchplugins/kannadastore.xml14
-rw-r--r--browser/locales/searchplugins/kaz-kk.xml16
-rw-r--r--browser/locales/searchplugins/klask.xml17
-rw-r--r--browser/locales/searchplugins/leit-is.xml15
-rw-r--r--browser/locales/searchplugins/leo_ende_de-rm.xml18
-rw-r--r--browser/locales/searchplugins/leo_ende_de.xml18
-rw-r--r--browser/locales/searchplugins/list-am.xml16
-rw-r--r--browser/locales/searchplugins/longdo.xml20
-rw-r--r--browser/locales/searchplugins/mailru.xml21
-rw-r--r--browser/locales/searchplugins/mapy-cz.xml15
-rw-r--r--browser/locales/searchplugins/marktplaats-fy-NL.xml15
-rw-r--r--browser/locales/searchplugins/marktplaats-nl.xml15
-rw-r--r--browser/locales/searchplugins/mercadolibre-ar.xml15
-rw-r--r--browser/locales/searchplugins/mercadolibre-cl.xml15
-rw-r--r--browser/locales/searchplugins/mercadolibre-mx.xml15
-rw-r--r--browser/locales/searchplugins/mercadolivre.xml15
-rw-r--r--browser/locales/searchplugins/meta-ua.xml20
-rw-r--r--browser/locales/searchplugins/metamarket.xml16
-rw-r--r--browser/locales/searchplugins/morfix-dic.xml38
-rw-r--r--browser/locales/searchplugins/najdi-si.xml16
-rw-r--r--browser/locales/searchplugins/naver-kr.xml22
-rw-r--r--browser/locales/searchplugins/neti-ee.xml15
-rw-r--r--browser/locales/searchplugins/odpiralni.xml15
-rw-r--r--browser/locales/searchplugins/olx.xml17
-rw-r--r--browser/locales/searchplugins/oshiete-goo.xml15
-rw-r--r--browser/locales/searchplugins/osta-ee.xml14
-rw-r--r--browser/locales/searchplugins/ozonru.xml20
-rw-r--r--browser/locales/searchplugins/palasprint.xml15
-rw-r--r--browser/locales/searchplugins/paroledigenova-lij.xml19
-rw-r--r--browser/locales/searchplugins/pledarigrond.xml12
-rw-r--r--browser/locales/searchplugins/pogodak.xml15
-rw-r--r--browser/locales/searchplugins/portalbgdict.xml17
-rw-r--r--browser/locales/searchplugins/priberam.xml27
-rw-r--r--browser/locales/searchplugins/priceru.xml15
-rw-r--r--browser/locales/searchplugins/prisjakt-sv-SE.xml19
-rw-r--r--browser/locales/searchplugins/pwn-pl.xml14
-rw-r--r--browser/locales/searchplugins/qxl-NO.xml16
-rw-r--r--browser/locales/searchplugins/rakuten.xml16
-rw-r--r--browser/locales/searchplugins/rediff.xml15
-rw-r--r--browser/locales/searchplugins/reta-vortaro.xml16
-rw-r--r--browser/locales/searchplugins/salidzinilv.xml19
-rw-r--r--browser/locales/searchplugins/sapo.xml15
-rw-r--r--browser/locales/searchplugins/seznam-cz.xml17
-rw-r--r--browser/locales/searchplugins/slovnik-sk.xml15
-rw-r--r--browser/locales/searchplugins/sslv.xml15
-rw-r--r--browser/locales/searchplugins/sztaki-en-hu.xml21
-rw-r--r--browser/locales/searchplugins/tearma.xml14
-rw-r--r--browser/locales/searchplugins/termau.xml13
-rw-r--r--browser/locales/searchplugins/twitter-ja.xml15
-rw-r--r--browser/locales/searchplugins/twitter.xml15
-rw-r--r--browser/locales/searchplugins/tyda-sv-SE.xml14
-rw-r--r--browser/locales/searchplugins/vatera.xml18
-rw-r--r--browser/locales/searchplugins/webdunia.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-NN.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-NO.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-af.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-an.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ar.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-as.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ast.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-az.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-bg.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-bn.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-br.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-bs.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ca.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-cy.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-cz.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-da.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-de.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-dsb.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-el.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-eo.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-es.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-et.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-eu.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-fa.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-fi.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-fr.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-fy-NL.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ga-IE.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-gd.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-gl.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-gn.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-gu.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-he.xml19
-rwxr-xr-xbrowser/locales/searchplugins/wikipedia-hi.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-hr.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-hsb.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-hu.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-hy.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-id.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-is.xml21
-rw-r--r--browser/locales/searchplugins/wikipedia-it.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ja.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ka.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-kab.xml18
-rw-r--r--browser/locales/searchplugins/wikipedia-kk.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-km.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-kn.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-kr.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-lij.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-lt.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-lv.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-mk.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ml.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-mr.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ms.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-my.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ne.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-nl.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-or.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-pa.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-pl.xml21
-rw-r--r--browser/locales/searchplugins/wikipedia-pt.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-rm.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ru.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-si.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-sk.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-sl.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-sq.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-sr.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-sv-SE.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ta.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-te.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-th.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-tl.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-tr.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-uk.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-ur.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-uz.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-vi.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-wo.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-zh-CN.xml19
-rw-r--r--browser/locales/searchplugins/wikipedia-zh-TW.xml20
-rw-r--r--browser/locales/searchplugins/wikipedia.xml2
-rw-r--r--browser/locales/searchplugins/wikipediaro.xml19
-rw-r--r--browser/locales/searchplugins/wiktionary-te.xml19
-rw-r--r--browser/locales/searchplugins/wolnelektury-pl.xml17
-rw-r--r--browser/locales/searchplugins/yahoo-NO.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-answer-zh-TW.xml16
-rw-r--r--browser/locales/searchplugins/yahoo-ar.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-bid-zh-TW.xml15
-rw-r--r--browser/locales/searchplugins/yahoo-br.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-ch.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-cl.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-de.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-en-CA.xml28
-rw-r--r--browser/locales/searchplugins/yahoo-en-GB.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-es.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-espanol.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-fi.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-france.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-fy-NL.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-id.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-in.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-it.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-jp-auctions.xml17
-rw-r--r--browser/locales/searchplugins/yahoo-jp.xml16
-rw-r--r--browser/locales/searchplugins/yahoo-mx.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-sv-SE.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-tl.xml22
-rw-r--r--browser/locales/searchplugins/yahoo-zh-TW-HK.xml27
-rw-r--r--browser/locales/searchplugins/yahoo-zh-TW.xml27
-rw-r--r--browser/locales/searchplugins/yahoo.xml10
-rw-r--r--browser/locales/searchplugins/yandex-az.xml17
-rw-r--r--browser/locales/searchplugins/yandex-en.xml17
-rw-r--r--browser/locales/searchplugins/yandex-kk.xml22
-rw-r--r--browser/locales/searchplugins/yandex-ru.xml22
-rw-r--r--browser/locales/searchplugins/yandex-tr.xml22
-rw-r--r--browser/locales/searchplugins/yandex-uk.xml16
-rw-r--r--browser/locales/searchplugins/zing-mp3.xml17
-rw-r--r--browser/locales/searchplugins/zoznam-sk.xml15
-rw-r--r--browser/modules/moz.build6
-rw-r--r--browser/modules/test/.eslintrc.js7
-rw-r--r--browser/modules/test/browser.ini42
-rw-r--r--browser/modules/test/browser_BrowserUITelemetry_buckets.js97
-rw-r--r--browser/modules/test/browser_BrowserUITelemetry_defaults.js37
-rw-r--r--browser/modules/test/browser_BrowserUITelemetry_sidebar.js56
-rw-r--r--browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js114
-rw-r--r--browser/modules/test/browser_ContentSearch.js425
-rw-r--r--browser/modules/test/browser_NetworkPrioritizer.js165
-rw-r--r--browser/modules/test/browser_PermissionUI.js445
-rw-r--r--browser/modules/test/browser_ProcessHangNotifications.js189
-rw-r--r--browser/modules/test/browser_SelfSupportBackend.js214
-rw-r--r--browser/modules/test/browser_UnsubmittedCrashHandler.js680
-rw-r--r--browser/modules/test/browser_UsageTelemetry.js268
-rw-r--r--browser/modules/test/browser_UsageTelemetry_content.js121
-rw-r--r--browser/modules/test/browser_UsageTelemetry_content_aboutHome.js84
-rw-r--r--browser/modules/test/browser_UsageTelemetry_private_and_restore.js90
-rw-r--r--browser/modules/test/browser_UsageTelemetry_searchbar.js195
-rw-r--r--browser/modules/test/browser_UsageTelemetry_urlbar.js220
-rw-r--r--browser/modules/test/browser_taskbar_preview.js100
-rw-r--r--browser/modules/test/browser_urlBar_zoom.js73
-rw-r--r--browser/modules/test/contentSearch.js64
-rw-r--r--browser/modules/test/contentSearchBadImage.xml6
-rw-r--r--browser/modules/test/contentSearchSuggestions.sjs9
-rw-r--r--browser/modules/test/contentSearchSuggestions.xml6
-rw-r--r--browser/modules/test/head.js113
-rw-r--r--browser/modules/test/unit/social/.eslintrc.js7
-rw-r--r--browser/modules/test/unit/social/blocklist.xml6
-rw-r--r--browser/modules/test/unit/social/head.js210
-rw-r--r--browser/modules/test/unit/social/test_SocialService.js166
-rw-r--r--browser/modules/test/unit/social/test_SocialServiceMigration21.js54
-rw-r--r--browser/modules/test/unit/social/test_SocialServiceMigration22.js67
-rw-r--r--browser/modules/test/unit/social/test_SocialServiceMigration29.js61
-rw-r--r--browser/modules/test/unit/social/test_social.js32
-rw-r--r--browser/modules/test/unit/social/test_socialDisabledStartup.js29
-rw-r--r--browser/modules/test/unit/social/xpcshell.ini13
-rw-r--r--browser/modules/test/usageTelemetrySearchSuggestions.sjs9
-rw-r--r--browser/modules/test/usageTelemetrySearchSuggestions.xml6
-rw-r--r--browser/modules/test/xpcshell/.eslintrc.js7
-rw-r--r--browser/modules/test/xpcshell/test_AttributionCode.js110
-rw-r--r--browser/modules/test/xpcshell/test_DirectoryLinksProvider.js1854
-rw-r--r--browser/modules/test/xpcshell/test_LaterRun.js138
-rw-r--r--browser/modules/test/xpcshell/test_SitePermissions.js115
-rw-r--r--browser/modules/test/xpcshell/xpcshell.ini11
-rw-r--r--browser/themes/shared/customizableui/panelUI.inc.css59
-rw-r--r--browser/themes/shared/customizableui/whimsy.pngbin6639 -> 0 bytes
-rw-r--r--browser/themes/shared/customizableui/whimsy@2x.pngbin18370 -> 0 bytes
-rw-r--r--browser/themes/shared/jar.inc.mn2
-rw-r--r--build/mobile/b2gautomation.py4
-rw-r--r--build/mobile/remoteautomation.py4
-rw-r--r--build/moz.configure/toolchain.configure4
-rw-r--r--build/release/info.py2
-rw-r--r--build/variables.py2
-rw-r--r--config/external/moz.build2
-rw-r--r--db/sqlite3/src/sqlite3.c6657
-rw-r--r--db/sqlite3/src/sqlite3.h108
-rw-r--r--devtools/client/framework/test/browser.ini2
-rw-r--r--devtools/shared/gcli/source/lib/gcli/commands/commands.js6
-rw-r--r--devtools/shared/gcli/source/lib/gcli/commands/help.js2
-rw-r--r--devtools/shared/webconsole/test/chrome.ini2
-rw-r--r--dom/base/nsJSEnvironment.cpp5
-rw-r--r--dom/base/nsScriptLoader.cpp5
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp73
-rw-r--r--dom/system/NetworkGeolocationProvider.js41
-rw-r--r--dom/workers/RuntimeService.cpp67
-rw-r--r--dom/workers/RuntimeService.h13
-rw-r--r--dom/workers/WorkerPrefs.h3
-rw-r--r--dom/workers/WorkerPrivate.cpp60
-rw-r--r--dom/workers/WorkerPrivate.h5
-rw-r--r--dom/workers/Workers.h8
-rw-r--r--editor/composer/nsEditorSpellCheck.cpp300
-rw-r--r--gfx/graphite2/ChangeLog31
-rw-r--r--gfx/graphite2/include/graphite2/XmlLog.h55
-rw-r--r--gfx/graphite2/src/Bidi.cpp826
-rw-r--r--gfx/graphite2/src/GlyphFaceCache.cpp149
-rw-r--r--gfx/graphite2/src/Rule.cpp31
-rw-r--r--gfx/graphite2/src/XmlTraceLog.cpp219
-rw-r--r--gfx/graphite2/src/XmlTraceLogTags.cpp169
-rw-r--r--gfx/graphite2/src/inc/Bidi.h126
-rw-r--r--gfx/graphite2/src/inc/GlyphFaceCache.h103
-rw-r--r--gfx/graphite2/src/inc/Shrinker.h119
-rw-r--r--gfx/graphite2/src/moz.build3
-rw-r--r--gfx/thebes/gfxPrefs.h1
-rw-r--r--image/DecoderFactory.cpp14
-rw-r--r--image/DecoderFactory.h1
-rw-r--r--image/VectorImage.cpp11
-rw-r--r--image/build/nsImageModule.cpp1
-rw-r--r--image/decoders/moz.build1
-rw-r--r--image/decoders/nsWebPDecoder.cpp467
-rw-r--r--image/decoders/nsWebPDecoder.h91
-rw-r--r--image/imgLoader.cpp5
-rw-r--r--image/test/gtest/TestLoader.cpp84
-rw-r--r--image/test/gtest/moz.build1
-rw-r--r--ipc/testshell/XPCShellEnvironment.cpp18
-rw-r--r--js/src/builtin/TestingFunctions.cpp208
-rw-r--r--js/src/devtools/automation/variants/compacting1
-rw-r--r--js/src/devtools/automation/variants/rootanalysis1
-rw-r--r--js/src/gc/Allocator.cpp7
-rw-r--r--js/src/gc/GCInternals.h45
-rw-r--r--js/src/gc/GCRuntime.h116
-rw-r--r--js/src/gc/Heap.h16
-rw-r--r--js/src/gc/Nursery.cpp91
-rw-r--r--js/src/gc/Nursery.h12
-rw-r--r--js/src/gc/Verifier.cpp414
-rw-r--r--js/src/gc/Zone.h6
-rw-r--r--js/src/gdb/progressbar.py4
-rw-r--r--js/src/jit-test/tests/ion/bug730152.js4
-rw-r--r--js/src/jit-test/tests/ion/bug732758.js1
-rw-r--r--js/src/jit/CompileWrappers.h4
-rw-r--r--js/src/jit/VMFunctions.cpp10
-rw-r--r--js/src/js-config.h.in4
-rw-r--r--js/src/jsapi-tests/testGCFinalizeCallback.cpp30
-rw-r--r--js/src/jsapi-tests/testGCHeapPostBarriers.cpp4
-rw-r--r--js/src/jsapi-tests/testGCMarking.cpp25
-rw-r--r--js/src/jsapi-tests/testGCUniqueId.cpp4
-rw-r--r--js/src/jsapi-tests/tests.h35
-rw-r--r--js/src/jsapi.cpp31
-rw-r--r--js/src/jsapi.h16
-rw-r--r--js/src/jsgc.cpp661
-rw-r--r--js/src/jsgc.h25
-rw-r--r--js/src/jsgcinlines.h6
-rw-r--r--js/src/jspubtd.h2
-rw-r--r--js/src/jsutil.h2
-rw-r--r--js/src/old-configure.in11
-rw-r--r--js/src/shell/js.cpp27
-rw-r--r--js/src/tests/lib/progressbar.py4
-rw-r--r--js/src/tests/lib/tasks_unix.py8
-rw-r--r--js/src/tests/lib/tasks_win.py4
-rw-r--r--js/src/tests/shell.js15
-rw-r--r--js/src/vm/Caches-inl.h3
-rw-r--r--js/src/vm/EnvironmentObject.h3
-rw-r--r--js/src/vm/Interpreter.cpp10
-rw-r--r--js/src/vm/Runtime.cpp3
-rw-r--r--js/src/vm/Runtime.h2
-rw-r--r--js/xpconnect/idl/xpccomponents.idl5
-rw-r--r--js/xpconnect/src/XPCComponents.cpp9
-rw-r--r--js/xpconnect/src/XPCJSContext.cpp10
-rw-r--r--js/xpconnect/src/XPCShellImpl.cpp18
-rw-r--r--layout/base/nsCSSRendering.cpp126
-rw-r--r--layout/reftests/css-gradients/linear-premul-ref.html1
-rw-r--r--layout/reftests/css-gradients/linear-premul.html1
-rw-r--r--layout/reftests/css-gradients/radial-premul-ref.html1
-rw-r--r--layout/reftests/css-gradients/radial-premul.html1
-rw-r--r--layout/reftests/css-gradients/reftest.list2
-rw-r--r--layout/style/nsCSSPseudoElements.h3
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.cpp44
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.h5
-rw-r--r--media/libwebp/AUTHORS38
-rw-r--r--media/libwebp/COPYING30
-rw-r--r--media/libwebp/MOZCHANGES3
-rw-r--r--media/libwebp/NEWS176
-rw-r--r--media/libwebp/PATENTS23
-rw-r--r--media/libwebp/README750
-rw-r--r--media/libwebp/README.mux223
-rw-r--r--media/libwebp/dec/alpha_dec.c232
-rw-r--r--media/libwebp/dec/alphai_dec.h54
-rw-r--r--media/libwebp/dec/buffer_dec.c300
-rw-r--r--media/libwebp/dec/common_dec.h54
-rw-r--r--media/libwebp/dec/frame_dec.c812
-rw-r--r--media/libwebp/dec/idec_dec.c892
-rw-r--r--media/libwebp/dec/io_dec.c645
-rw-r--r--media/libwebp/dec/moz.build26
-rw-r--r--media/libwebp/dec/quant_dec.c110
-rw-r--r--media/libwebp/dec/tree_dec.c528
-rw-r--r--media/libwebp/dec/vp8_dec.c721
-rw-r--r--media/libwebp/dec/vp8_dec.h185
-rw-r--r--media/libwebp/dec/vp8i_dec.h320
-rw-r--r--media/libwebp/dec/vp8l_dec.c1671
-rw-r--r--media/libwebp/dec/vp8li_dec.h135
-rw-r--r--media/libwebp/dec/webp_dec.c843
-rw-r--r--media/libwebp/dec/webpi_dec.h133
-rw-r--r--media/libwebp/demux/demux.c965
-rw-r--r--media/libwebp/demux/moz.build17
-rw-r--r--media/libwebp/dsp/alpha_processing.c397
-rw-r--r--media/libwebp/dsp/alpha_processing_sse2.c285
-rw-r--r--media/libwebp/dsp/alpha_processing_sse41.c92
-rw-r--r--media/libwebp/dsp/common_sse2.h194
-rw-r--r--media/libwebp/dsp/dec.c795
-rw-r--r--media/libwebp/dsp/dec_clip_tables.c366
-rw-r--r--media/libwebp/dsp/dec_neon.c1639
-rw-r--r--media/libwebp/dsp/dec_sse2.c1231
-rw-r--r--media/libwebp/dsp/dec_sse41.c46
-rw-r--r--media/libwebp/dsp/dsp.h594
-rw-r--r--media/libwebp/dsp/filters.c273
-rw-r--r--media/libwebp/dsp/filters_sse2.c330
-rw-r--r--media/libwebp/dsp/lossless.c663
-rw-r--r--media/libwebp/dsp/lossless.h229
-rw-r--r--media/libwebp/dsp/lossless_common.h210
-rw-r--r--media/libwebp/dsp/lossless_neon.c642
-rw-r--r--media/libwebp/dsp/lossless_sse2.c677
-rw-r--r--media/libwebp/dsp/mips_macro.h200
-rw-r--r--media/libwebp/dsp/moz.build53
-rw-r--r--media/libwebp/dsp/msa_macro.h1390
-rw-r--r--media/libwebp/dsp/neon.h100
-rw-r--r--media/libwebp/dsp/rescaler.c244
-rw-r--r--media/libwebp/dsp/rescaler_neon.c186
-rw-r--r--media/libwebp/dsp/rescaler_sse2.c375
-rw-r--r--media/libwebp/dsp/upsampling.c266
-rw-r--r--media/libwebp/dsp/upsampling_neon.c281
-rw-r--r--media/libwebp/dsp/upsampling_sse2.c249
-rw-r--r--media/libwebp/dsp/yuv.c337
-rw-r--r--media/libwebp/dsp/yuv.h238
-rw-r--r--media/libwebp/dsp/yuv_sse2.c863
-rw-r--r--media/libwebp/enc/backward_references_enc.h207
-rw-r--r--media/libwebp/enc/cost_enc.h82
-rw-r--r--media/libwebp/enc/delta_palettization_enc.h25
-rw-r--r--media/libwebp/enc/histogram_enc.h123
-rw-r--r--media/libwebp/enc/vp8i_enc.h520
-rw-r--r--media/libwebp/enc/vp8li_enc.h95
-rw-r--r--media/libwebp/moz.build28
-rw-r--r--media/libwebp/moz/cpu.cpp44
-rw-r--r--media/libwebp/moz/moz.build17
-rw-r--r--media/libwebp/update.sh76
-rw-r--r--media/libwebp/utils/bit_reader_inl_utils.h190
-rw-r--r--media/libwebp/utils/bit_reader_utils.c222
-rw-r--r--media/libwebp/utils/bit_reader_utils.h174
-rw-r--r--media/libwebp/utils/bit_writer_utils.h146
-rw-r--r--media/libwebp/utils/color_cache_utils.c49
-rw-r--r--media/libwebp/utils/color_cache_utils.h85
-rw-r--r--media/libwebp/utils/endian_inl_utils.h100
-rw-r--r--media/libwebp/utils/filters_utils.c76
-rw-r--r--media/libwebp/utils/filters_utils.h32
-rw-r--r--media/libwebp/utils/huffman_encode_utils.h60
-rw-r--r--media/libwebp/utils/huffman_utils.c223
-rw-r--r--media/libwebp/utils/huffman_utils.h88
-rw-r--r--media/libwebp/utils/moz.build26
-rw-r--r--media/libwebp/utils/quant_levels_dec_utils.c284
-rw-r--r--media/libwebp/utils/quant_levels_dec_utils.h35
-rw-r--r--media/libwebp/utils/quant_levels_utils.c140
-rw-r--r--media/libwebp/utils/quant_levels_utils.h36
-rw-r--r--media/libwebp/utils/random_utils.c43
-rw-r--r--media/libwebp/utils/random_utils.h63
-rw-r--r--media/libwebp/utils/rescaler_utils.c146
-rw-r--r--media/libwebp/utils/rescaler_utils.h101
-rw-r--r--media/libwebp/utils/thread_utils.c356
-rw-r--r--media/libwebp/utils/thread_utils.h93
-rw-r--r--media/libwebp/utils/utils.c330
-rw-r--r--media/libwebp/utils/utils.h178
-rw-r--r--media/libwebp/webp/config.h147
-rw-r--r--media/libwebp/webp/decode.h493
-rw-r--r--media/libwebp/webp/demux.h358
-rw-r--r--media/libwebp/webp/encode.h542
-rw-r--r--media/libwebp/webp/format_constants.h87
-rw-r--r--media/libwebp/webp/mux.h530
-rw-r--r--media/libwebp/webp/mux_types.h98
-rw-r--r--media/libwebp/webp/types.h52
-rwxr-xr-xmedia/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py2
-rw-r--r--mfbt/Attributes.h4
-rw-r--r--mfbt/Compiler.h4
-rw-r--r--mobile/android/config/version.txt1
-rw-r--r--mobile/android/config/version_display.txt1
-rw-r--r--mobile/android/confvars.sh4
-rw-r--r--mobile/android/extensions/flyweb/install.rdf.in6
-rw-r--r--mobile/android/extensions/flyweb/moz.build3
-rw-r--r--modules/libpref/init/all.js14
-rw-r--r--netwerk/base/security-prefs.js16
-rw-r--r--netwerk/mime/nsMimeTypes.h1
-rw-r--r--old-configure.in16
-rw-r--r--parser/htmlparser/nsExpatDriver.cpp14
-rw-r--r--parser/htmlparser/nsExpatDriver.h7
-rw-r--r--python/mock-1.0.0/tests/testhelpers.py6
-rw-r--r--python/mozbuild/mozbuild/android_version_code.py2
-rw-r--r--python/mozbuild/mozbuild/jar.py2
-rw-r--r--python/mozbuild/mozbuild/preprocessor.py17
-rw-r--r--python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py2
-rw-r--r--python/psutil/docs/conf.py2
-rwxr-xr-xpython/psutil/examples/top.py2
-rw-r--r--security/manager/ssl/nsNSSComponent.cpp31
-rwxr-xr-xsecurity/nss/gtests/google_test/gtest/test/gtest_xml_output_unittest.py2
-rw-r--r--testing/specialpowers/content/specialpowersAPI.js4
-rw-r--r--toolkit/forgetaboutsite/ForgetAboutSite.jsm2
-rw-r--r--toolkit/mozapps/update/nsUpdateService.js14
-rw-r--r--tools/docs/conf.py2
-rw-r--r--uriloader/exthandler/nsExternalHelperAppService.cpp1
2511 files changed, 35616 insertions, 178620 deletions
diff --git a/addon-sdk/source/python-lib/mozrunner/killableprocess.py b/addon-sdk/source/python-lib/mozrunner/killableprocess.py
index daf52f0c9..21eac6965 100644
--- a/addon-sdk/source/python-lib/mozrunner/killableprocess.py
+++ b/addon-sdk/source/python-lib/mozrunner/killableprocess.py
@@ -217,7 +217,7 @@ class Popen(subprocess.Popen):
# timeout is now in milliseconds
timeout = timeout * 1000
- starttime = datetime.datetime.now()
+ starttime = datetime.datetime.utcnow()
if mswindows:
if timeout is None:
@@ -234,7 +234,7 @@ class Popen(subprocess.Popen):
# Returns 1 if running, 0 if not, -1 if timed out
def check():
- now = datetime.datetime.now()
+ now = datetime.datetime.utcnow()
diff = now - starttime
if (diff.seconds * 1000000 + diff.microseconds) < (timeout * 1000): # (1000*1000)
if self._job:
@@ -302,7 +302,7 @@ class Popen(subprocess.Popen):
returncode = False
- now = datetime.datetime.now()
+ now = datetime.datetime.utcnow()
diff = now - starttime
while (diff.seconds * 1000 * 1000 + diff.microseconds) < (timeout * 1000) and ( returncode is False ):
if group is True:
@@ -311,7 +311,7 @@ class Popen(subprocess.Popen):
if subprocess.poll() is not None:
returncode = self.returncode
time.sleep(.5)
- now = datetime.datetime.now()
+ now = datetime.datetime.utcnow()
diff = now - starttime
return self.returncode
diff --git a/b2g/LICENSE b/b2g/LICENSE
deleted file mode 100644
index 14e2f777f..000000000
--- a/b2g/LICENSE
+++ /dev/null
@@ -1,373 +0,0 @@
-Mozilla Public License Version 2.0
-==================================
-
-1. Definitions
---------------
-
-1.1. "Contributor"
- means each individual or legal entity that creates, contributes to
- the creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
- means the combination of the Contributions of others (if any) used
- by a Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
- means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
- means Source Code Form to which the initial Contributor has attached
- the notice in Exhibit A, the Executable Form of such Source Code
- Form, and Modifications of such Source Code Form, in each case
- including portions thereof.
-
-1.5. "Incompatible With Secondary Licenses"
- means
-
- (a) that the initial Contributor has attached the notice described
- in Exhibit B to the Covered Software; or
-
- (b) that the Covered Software was made available under the terms of
- version 1.1 or earlier of the License, but not also under the
- terms of a Secondary License.
-
-1.6. "Executable Form"
- means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
- means a work that combines Covered Software with other material, in
- a separate file or files, that is not Covered Software.
-
-1.8. "License"
- means this document.
-
-1.9. "Licensable"
- means having the right to grant, to the maximum extent possible,
- whether at the time of the initial grant or subsequently, any and
- all of the rights conveyed by this License.
-
-1.10. "Modifications"
- means any of the following:
-
- (a) any file in Source Code Form that results from an addition to,
- deletion from, or modification of the contents of Covered
- Software; or
-
- (b) any new file in Source Code Form that contains any Covered
- Software.
-
-1.11. "Patent Claims" of a Contributor
- means any patent claim(s), including without limitation, method,
- process, and apparatus claims, in any patent Licensable by such
- Contributor that would be infringed, but for the grant of the
- License, by the making, using, selling, offering for sale, having
- made, import, or transfer of either its Contributions or its
- Contributor Version.
-
-1.12. "Secondary License"
- means either the GNU General Public License, Version 2.0, the GNU
- Lesser General Public License, Version 2.1, the GNU Affero General
- Public License, Version 3.0, or any later versions of those
- licenses.
-
-1.13. "Source Code Form"
- means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
- means an individual or a legal entity exercising rights under this
- License. For legal entities, "You" includes any entity that
- controls, is controlled by, or is under common control with You. For
- purposes of this definition, "control" means (a) the power, direct
- or indirect, to cause the direction or management of such entity,
- whether by contract or otherwise, or (b) ownership of more than
- fifty percent (50%) of the outstanding shares or beneficial
- ownership of such entity.
-
-2. License Grants and Conditions
---------------------------------
-
-2.1. Grants
-
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license:
-
-(a) under intellectual property rights (other than patent or trademark)
- Licensable by such Contributor to use, reproduce, make available,
- modify, display, perform, distribute, and otherwise exploit its
- Contributions, either on an unmodified basis, with Modifications, or
- as part of a Larger Work; and
-
-(b) under Patent Claims of such Contributor to make, use, sell, offer
- for sale, have made, import, and otherwise transfer either its
- Contributions or its Contributor Version.
-
-2.2. Effective Date
-
-The licenses granted in Section 2.1 with respect to any Contribution
-become effective for each Contribution on the date the Contributor first
-distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
-The licenses granted in this Section 2 are the only rights granted under
-this License. No additional rights or licenses will be implied from the
-distribution or licensing of Covered Software under this License.
-Notwithstanding Section 2.1(b) above, no patent license is granted by a
-Contributor:
-
-(a) for any code that a Contributor has removed from Covered Software;
- or
-
-(b) for infringements caused by: (i) Your and any other third party's
- modifications of Covered Software, or (ii) the combination of its
- Contributions with other software (except as part of its Contributor
- Version); or
-
-(c) under Patent Claims infringed by Covered Software in the absence of
- its Contributions.
-
-This License does not grant any rights in the trademarks, service marks,
-or logos of any Contributor (except as may be necessary to comply with
-the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
-No Contributor makes additional grants as a result of Your choice to
-distribute the Covered Software under a subsequent version of this
-License (see Section 10.2) or under the terms of a Secondary License (if
-permitted under the terms of Section 3.3).
-
-2.5. Representation
-
-Each Contributor represents that the Contributor believes its
-Contributions are its original creation(s) or it has sufficient rights
-to grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
-This License is not intended to limit any rights You have under
-applicable copyright doctrines of fair use, fair dealing, or other
-equivalents.
-
-2.7. Conditions
-
-Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
-in Section 2.1.
-
-3. Responsibilities
--------------------
-
-3.1. Distribution of Source Form
-
-All distribution of Covered Software in Source Code Form, including any
-Modifications that You create or to which You contribute, must be under
-the terms of this License. You must inform recipients that the Source
-Code Form of the Covered Software is governed by the terms of this
-License, and how they can obtain a copy of this License. You may not
-attempt to alter or restrict the recipients' rights in the Source Code
-Form.
-
-3.2. Distribution of Executable Form
-
-If You distribute Covered Software in Executable Form then:
-
-(a) such Covered Software must also be made available in Source Code
- Form, as described in Section 3.1, and You must inform recipients of
- the Executable Form how they can obtain a copy of such Source Code
- Form by reasonable means in a timely manner, at a charge no more
- than the cost of distribution to the recipient; and
-
-(b) You may distribute such Executable Form under the terms of this
- License, or sublicense it under different terms, provided that the
- license for the Executable Form does not attempt to limit or alter
- the recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
-You may create and distribute a Larger Work under terms of Your choice,
-provided that You also comply with the requirements of this License for
-the Covered Software. If the Larger Work is a combination of Covered
-Software with a work governed by one or more Secondary Licenses, and the
-Covered Software is not Incompatible With Secondary Licenses, this
-License permits You to additionally distribute such Covered Software
-under the terms of such Secondary License(s), so that the recipient of
-the Larger Work may, at their option, further distribute the Covered
-Software under the terms of either this License or such Secondary
-License(s).
-
-3.4. Notices
-
-You may not remove or alter the substance of any license notices
-(including copyright notices, patent notices, disclaimers of warranty,
-or limitations of liability) contained within the Source Code Form of
-the Covered Software, except that You may alter any license notices to
-the extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
-You may choose to offer, and to charge a fee for, warranty, support,
-indemnity or liability obligations to one or more recipients of Covered
-Software. However, You may do so only on Your own behalf, and not on
-behalf of any Contributor. You must make it absolutely clear that any
-such warranty, support, indemnity, or liability obligation is offered by
-You alone, and You hereby agree to indemnify every Contributor for any
-liability incurred by such Contributor as a result of warranty, support,
-indemnity or liability terms You offer. You may include additional
-disclaimers of warranty and limitations of liability specific to any
-jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
----------------------------------------------------
-
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Software due to
-statute, judicial order, or regulation then You must: (a) comply with
-the terms of this License to the maximum extent possible; and (b)
-describe the limitations and the code they affect. Such description must
-be placed in a text file included with all distributions of the Covered
-Software under this License. Except to the extent prohibited by statute
-or regulation, such description must be sufficiently detailed for a
-recipient of ordinary skill to be able to understand it.
-
-5. Termination
---------------
-
-5.1. The rights granted under this License will terminate automatically
-if You fail to comply with any of its terms. However, if You become
-compliant, then the rights granted under this License from a particular
-Contributor are reinstated (a) provisionally, unless and until such
-Contributor explicitly and finally terminates Your grants, and (b) on an
-ongoing basis, if such Contributor fails to notify You of the
-non-compliance by some reasonable means prior to 60 days after You have
-come back into compliance. Moreover, Your grants from a particular
-Contributor are reinstated on an ongoing basis if such Contributor
-notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
-from such Contributor, and You become compliant prior to 30 days after
-Your receipt of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
-infringement claim (excluding declaratory judgment actions,
-counter-claims, and cross-claims) alleging that a Contributor Version
-directly or indirectly infringes any patent, then the rights granted to
-You by any and all Contributors for the Covered Software under Section
-2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all
-end user license agreements (excluding distributors and resellers) which
-have been validly granted by You or Your distributors under this License
-prior to termination shall survive termination.
-
-************************************************************************
-* *
-* 6. Disclaimer of Warranty *
-* ------------------------- *
-* *
-* Covered Software is provided under this License on an "as is" *
-* basis, without warranty of any kind, either expressed, implied, or *
-* statutory, including, without limitation, warranties that the *
-* Covered Software is free of defects, merchantable, fit for a *
-* particular purpose or non-infringing. The entire risk as to the *
-* quality and performance of the Covered Software is with You. *
-* Should any Covered Software prove defective in any respect, You *
-* (not any Contributor) assume the cost of any necessary servicing, *
-* repair, or correction. This disclaimer of warranty constitutes an *
-* essential part of this License. No use of any Covered Software is *
-* authorized under this License except under this disclaimer. *
-* *
-************************************************************************
-
-************************************************************************
-* *
-* 7. Limitation of Liability *
-* -------------------------- *
-* *
-* Under no circumstances and under no legal theory, whether tort *
-* (including negligence), contract, or otherwise, shall any *
-* Contributor, or anyone who distributes Covered Software as *
-* permitted above, be liable to You for any direct, indirect, *
-* special, incidental, or consequential damages of any character *
-* including, without limitation, damages for lost profits, loss of *
-* goodwill, work stoppage, computer failure or malfunction, or any *
-* and all other commercial damages or losses, even if such party *
-* shall have been informed of the possibility of such damages. This *
-* limitation of liability shall not apply to liability for death or *
-* personal injury resulting from such party's negligence to the *
-* extent applicable law prohibits such limitation. Some *
-* jurisdictions do not allow the exclusion or limitation of *
-* incidental or consequential damages, so this exclusion and *
-* limitation may not apply to You. *
-* *
-************************************************************************
-
-8. Litigation
--------------
-
-Any litigation relating to this License may be brought only in the
-courts of a jurisdiction where the defendant maintains its principal
-place of business and such litigation shall be governed by laws of that
-jurisdiction, without reference to its conflict-of-law provisions.
-Nothing in this Section shall prevent a party's ability to bring
-cross-claims or counter-claims.
-
-9. Miscellaneous
-----------------
-
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent
-necessary to make it enforceable. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-shall not be used to construe this License against a Contributor.
-
-10. Versions of the License
----------------------------
-
-10.1. New Versions
-
-Mozilla Foundation is the license steward. Except as provided in Section
-10.3, no one other than the license steward has the right to modify or
-publish new versions of this License. Each version will be given a
-distinguishing version number.
-
-10.2. Effect of New Versions
-
-You may distribute the Covered Software under the terms of the version
-of the License under which You originally received the Covered Software,
-or under the terms of any subsequent version published by the license
-steward.
-
-10.3. Modified Versions
-
-If you create software not governed by this License, and you want to
-create a new license for such software, you may create and use a
-modified version of this License if you rename the license and remove
-any references to the name of the license steward (except to note that
-such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
-Licenses
-
-If You choose to distribute Source Code Form that is Incompatible With
-Secondary Licenses under the terms of this version of the License, the
-notice described in Exhibit B of this License must be attached.
-
-Exhibit A - Source Code Form License Notice
--------------------------------------------
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular
-file, then You may include the notice in a location (such as a LICENSE
-file in a relevant directory) where a recipient would be likely to look
-for such a notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
----------------------------------------------------------
-
- This Source Code Form is "Incompatible With Secondary Licenses", as
- defined by the Mozilla Public License, v. 2.0.
diff --git a/b2g/Makefile.in b/b2g/Makefile.in
deleted file mode 100644
index 9b3e1e08a..000000000
--- a/b2g/Makefile.in
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/config/rules.mk
-include $(topsrcdir)/testing/testsuite-targets.mk
diff --git a/b2g/app.mozbuild b/b2g/app.mozbuild
deleted file mode 100644
index 4587438d5..000000000
--- a/b2g/app.mozbuild
+++ /dev/null
@@ -1,15 +0,0 @@
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-include('/toolkit/toolkit.mozbuild')
-
-if CONFIG['MOZ_EXTENSIONS']:
- DIRS += ['/extensions']
-
-DIRS += [
- '/%s' % CONFIG['MOZ_BRANDING_DIRECTORY'],
- '/b2g',
-]
diff --git a/b2g/app/Makefile.in b/b2g/app/Makefile.in
deleted file mode 100644
index 6b50b87f7..000000000
--- a/b2g/app/Makefile.in
+++ /dev/null
@@ -1,66 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Make sure the standalone glue doesn't try to get libxpcom.so from b2g/app.
-NSDISTMODE = copy
-
-include $(topsrcdir)/config/rules.mk
-
-APP_ICON = app
-
-APP_BINARY = $(MOZ_APP_NAME)$(BIN_SUFFIX)
-
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-
-APP_NAME = $(MOZ_APP_DISPLAYNAME)
-APP_VERSION = $(MOZ_APP_VERSION)
-
-ifdef MOZ_DEBUG
-APP_NAME := $(APP_NAME)Debug
-endif
-
-AB_CD = $(MOZ_UI_LOCALE)
-
-ifeq (zh-TW,$(AB_CD))
-LPROJ_ROOT := $(subst -,_,$(AB_CD))
-else
-LPROJ_ROOT := $(firstword $(subst -, ,$(AB_CD)))
-endif
-LPROJ := Contents/Resources/$(LPROJ_ROOT).lproj
-
-clean clobber repackage::
- rm -rf $(DIST)/$(APP_NAME).app
-
-libs-preqs = \
- $(call mkdir_deps,$(DIST)/$(APP_NAME).app/Contents/MacOS) \
- $(call mkdir_deps,$(DIST)/$(APP_NAME).app/$(LPROJ)) \
- $(NULL)
-
-.PHONY: repackage
-tools repackage:: $(libs-preqs)
- rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
- rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/$(LPROJ)
- sed -e 's/%MOZ_APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MOZ_APP_NAME%/$(MOZ_APP_NAME)/' -e 's/%APP_VERSION%/$(APP_VERSION)/' -e 's/%APP_NAME%/$(APP_NAME)/' -e 's/%APP_BINARY%/$(APP_BINARY)/' $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
- sed -e 's/%APP_VERSION%/$(APP_VERSION)/' -e 's/%APP_NAME%/$(APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/$(LPROJ)/InfoPlist.strings
- rsync -a --exclude 'mangle' --exclude 'shlibsign' --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/Resources
- rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/MacOS
- $(RM) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
- rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
- cp -RL $(DIST)/branding/app.icns $(DIST)/$(APP_NAME).app/Contents/Resources/$(MOZ_APP_NAME).icns
- printf APPLMOZB > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
-
-else # MOZ_WIDGET_TOOLKIT != cocoa
-
-libs::
- $(NSINSTALL) -D $(DIST)/bin/chrome/icons/default
-
-# Copy the app icon for b2g-desktop
-ifeq ($(OS_ARCH),WINNT)
- cp $(DIST)/branding/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/$(APP_ICON).ico
- cp $(DIST)/branding/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/default.ico
-else ifneq (gonk,$(MOZ_WIDGET_TOOLKIT))
- cp $(DIST)/branding/default.png $(DIST)/bin/chrome/icons/default/default.png
-endif
-
-endif
diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js
deleted file mode 100644
index ec2f2a0f1..000000000
--- a/b2g/app/b2g.js
+++ /dev/null
@@ -1,1018 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#filter substitution
-
-// For the all MOZ_MULET ifdef conditions in this file: see bug 1174234
-
-#ifndef MOZ_MULET
-pref("toolkit.defaultChromeURI", "chrome://b2g/content/shell.html");
-pref("browser.chromeURL", "chrome://b2g/content/");
-#endif
-
-#ifdef MOZ_MULET
-// Set FxOS as the default homepage
-// bug 1000122: this pref is fetched as a complex value,
-// so that it can't be set a just a string.
-// data: url is a workaround this.
-pref("browser.startup.homepage", "data:text/plain,browser.startup.homepage=chrome://b2g/content/shell.html");
-pref("b2g.is_mulet", true);
-// Prevent having the firstrun page
-pref("startup.homepage_welcome_url", "");
-pref("browser.shell.checkDefaultBrowser", false);
-// Automatically open devtools on the firefox os panel
-pref("devtools.toolbox.host", "side");
-pref("devtools.toolbox.sidebar.width", 800);
-// Disable session store to ensure having only one tab opened
-pref("browser.sessionstore.max_tabs_undo", 0);
-pref("browser.sessionstore.max_windows_undo", 0);
-pref("browser.sessionstore.restore_on_demand", false);
-pref("browser.sessionstore.resume_from_crash", false);
-// No e10s on mulet
-pref("browser.tabs.remote.autostart.1", false);
-pref("browser.tabs.remote.autostart.2", false);
-#endif
-
-// Bug 945235: Prevent all bars to be considered visible:
-pref("toolkit.defaultChromeFeatures", "chrome,dialog=no,close,resizable,scrollbars,extrachrome");
-
-// Disable focus rings
-pref("browser.display.focus_ring_width", 0);
-
-// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
-pref("browser.viewport.scaleRatio", -1);
-
-/* disable text selection */
-pref("browser.ignoreNativeFrameTextSelection", true);
-
-/* cache prefs */
-#ifdef MOZ_WIDGET_GONK
-pref("browser.cache.disk.enable", true);
-pref("browser.cache.disk.capacity", 55000); // kilobytes
-pref("browser.cache.disk.parent_directory", "/cache");
-#endif
-pref("browser.cache.disk.smart_size.enabled", false);
-pref("browser.cache.disk.smart_size.first_run", false);
-
-pref("browser.cache.memory.enable", true);
-pref("browser.cache.memory.capacity", 1024); // kilobytes
-
-pref("browser.cache.memory_limit", 2048); // 2 MB
-
-/* image cache prefs */
-pref("image.cache.size", 1048576); // bytes
-pref("canvas.image.cache.limit", 20971520); // 20 MB
-
-/* offline cache prefs */
-pref("browser.offline-apps.notify", false);
-pref("browser.cache.offline.enable", true);
-pref("offline-apps.allow_by_default", true);
-
-/* protocol warning prefs */
-pref("network.protocol-handler.warn-external.tel", false);
-pref("network.protocol-handler.warn-external.mailto", false);
-pref("network.protocol-handler.warn-external.vnd.youtube", false);
-
-/* http prefs */
-pref("network.http.pipelining", true);
-pref("network.http.pipelining.ssl", true);
-pref("network.http.proxy.pipelining", true);
-pref("network.http.pipelining.maxrequests" , 6);
-pref("network.http.keep-alive.timeout", 109);
-pref("network.http.max-connections", 20);
-pref("network.http.max-persistent-connections-per-server", 6);
-pref("network.http.max-persistent-connections-per-proxy", 20);
-
-// Keep the old default of accepting all cookies,
-// no matter if you already visited the website or not
-pref("network.cookie.cookieBehavior", 0);
-
-// spdy
-pref("network.http.spdy.push-allowance", 32768);
-pref("network.http.spdy.default-hpack-buffer", 4096); // 4k
-
-// See bug 545869 for details on why these are set the way they are
-pref("network.buffer.cache.count", 24);
-pref("network.buffer.cache.size", 16384);
-
-// predictive actions
-pref("network.predictor.enabled", false); // disabled on b2g
-pref("network.predictor.max-db-size", 2097152); // bytes
-pref("network.predictor.preserve", 50); // percentage of predictor data to keep when cleaning up
-
-/* session history */
-pref("browser.sessionhistory.max_entries", 50);
-pref("browser.sessionhistory.contentViewerTimeout", 360);
-
-/* session store */
-pref("browser.sessionstore.resume_session_once", false);
-pref("browser.sessionstore.resume_from_crash", true);
-pref("browser.sessionstore.resume_from_crash_timeout", 60); // minutes
-pref("browser.sessionstore.interval", 10000); // milliseconds
-pref("browser.sessionstore.max_tabs_undo", 1);
-
-/* these should help performance */
-pref("mozilla.widget.force-24bpp", true);
-pref("mozilla.widget.use-buffer-pixmap", true);
-pref("mozilla.widget.disable-native-theme", true);
-pref("layout.reflow.synthMouseMove", false);
-#ifndef MOZ_X11
-pref("layers.enable-tiles", true);
-#endif
-pref("layers.low-precision-buffer", true);
-pref("layers.low-precision-opacity", "0.5");
-pref("layers.progressive-paint", true);
-
-/* download manager (don't show the window or alert) */
-pref("browser.download.useDownloadDir", true);
-pref("browser.download.folderList", 1); // Default to ~/Downloads
-pref("browser.download.manager.showAlertOnComplete", false);
-pref("browser.download.manager.showAlertInterval", 2000);
-pref("browser.download.manager.retention", 2);
-pref("browser.download.manager.showWhenStarting", false);
-pref("browser.download.manager.closeWhenDone", true);
-pref("browser.download.manager.openDelay", 0);
-pref("browser.download.manager.focusWhenStarting", false);
-pref("browser.download.manager.flashCount", 2);
-pref("browser.download.manager.displayedHistoryDays", 7);
-
-/* download helper */
-pref("browser.helperApps.deleteTempFileOnExit", false);
-
-/* password manager */
-pref("signon.rememberSignons", true);
-pref("signon.expireMasterPassword", false);
-
-/* autocomplete */
-pref("browser.formfill.enable", true);
-
-/* spellcheck */
-pref("layout.spellcheckDefault", 0);
-
-/* block popups by default, and notify the user about blocked popups */
-pref("dom.disable_open_during_load", true);
-pref("privacy.popups.showBrowserMessage", true);
-
-pref("keyword.enabled", true);
-pref("browser.fixup.domainwhitelist.localhost", true);
-
-pref("accessibility.typeaheadfind", false);
-pref("accessibility.typeaheadfind.timeout", 5000);
-pref("accessibility.typeaheadfind.flashBar", 1);
-pref("accessibility.typeaheadfind.linksonly", false);
-pref("accessibility.typeaheadfind.casesensitive", 0);
-
-// SSL error page behaviour
-pref("browser.ssl_override_behavior", 2);
-pref("browser.xul.error_pages.expert_bad_cert", false);
-
-// disable updating
-pref("browser.search.update", false);
-
-// tell the search service that we don't really expose the "current engine"
-pref("browser.search.noCurrentEngine", true);
-
-// enable xul error pages
-pref("browser.xul.error_pages.enabled", true);
-
-// disable color management
-pref("gfx.color_management.mode", 0);
-
-// don't allow JS to move and resize existing windows
-pref("dom.disable_window_move_resize", true);
-
-// prevent click image resizing for nsImageDocument
-pref("browser.enable_click_image_resizing", false);
-
-// controls which bits of private data to clear. by default we clear them all.
-pref("privacy.item.cache", true);
-pref("privacy.item.cookies", true);
-pref("privacy.item.offlineApps", true);
-pref("privacy.item.history", true);
-pref("privacy.item.formdata", true);
-pref("privacy.item.downloads", true);
-pref("privacy.item.passwords", true);
-pref("privacy.item.sessions", true);
-pref("privacy.item.geolocation", true);
-pref("privacy.item.siteSettings", true);
-pref("privacy.item.syncAccount", true);
-
-// base url for the wifi geolocation network provider
-pref("geo.provider.use_mls", false);
-pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
-
-// base url for the stumbler
-pref("geo.stumbler.url", "https://location.services.mozilla.com/v1/geosubmit?key=%MOZILLA_API_KEY%");
-
-// enable geo
-pref("geo.enabled", true);
-
-// content sink control -- controls responsiveness during page load
-// see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9
-pref("content.sink.enable_perf_mode", 2); // 0 - switch, 1 - interactive, 2 - perf
-pref("content.sink.pending_event_mode", 0);
-pref("content.sink.perf_deflect_count", 1000000);
-pref("content.sink.perf_parse_time", 50000000);
-
-// Maximum scripts runtime before showing an alert
-// Disable the watchdog thread for B2G. See bug 870043 comment 31.
-pref("dom.use_watchdog", false);
-
-// The slow script dialog can be triggered from inside the JS engine as well,
-// ensure that those calls don't accidentally trigger the dialog.
-pref("dom.max_script_run_time", 0);
-pref("dom.max_chrome_script_run_time", 0);
-
-// plugins
-pref("plugin.disable", true);
-pref("dom.ipc.plugins.enabled", true);
-
-// product URLs
-// The breakpad report server to link to in about:crashes
-pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
-pref("app.releaseNotesURL", "https://www.mozilla.com/%LOCALE%/b2g/%VERSION%/releasenotes/");
-pref("app.support.baseURL", "https://support.mozilla.com/b2g");
-pref("app.privacyURL", "https://www.mozilla.com/%LOCALE%/m/privacy.html");
-pref("app.creditsURL", "https://www.mozilla.org/credits/");
-pref("app.featuresURL", "https://www.mozilla.com/%LOCALE%/b2g/features/");
-pref("app.faqURL", "https://www.mozilla.com/%LOCALE%/b2g/faq/");
-
-// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
-pref("security.alternate_certificate_error_page", "certerror");
-
-pref("security.warn_viewing_mixed", false); // Warning is disabled. See Bug 616712.
-
-// Block insecure active content on https pages
-pref("security.mixed_content.block_active_content", true);
-
-// 2 = strict certificate pinning checks.
-// This default preference is more strict than Firefox because B2G
-// currently does not have a way to install local root certificates.
-// Strict checking is effectively equivalent to non-strict checking as
-// long as that is true. If an ability to add local certificates is
-// added, there may be a need to change this pref.
-pref("security.cert_pinning.enforcement_level", 2);
-
-
-// Override some named colors to avoid inverse OS themes
-pref("ui.-moz-dialog", "#efebe7");
-pref("ui.-moz-dialogtext", "#101010");
-pref("ui.-moz-field", "#fff");
-pref("ui.-moz-fieldtext", "#1a1a1a");
-pref("ui.-moz-buttonhoverface", "#f3f0ed");
-pref("ui.-moz-buttonhovertext", "#101010");
-pref("ui.-moz-combobox", "#fff");
-pref("ui.-moz-comboboxtext", "#101010");
-pref("ui.buttonface", "#ece7e2");
-pref("ui.buttonhighlight", "#fff");
-pref("ui.buttonshadow", "#aea194");
-pref("ui.buttontext", "#101010");
-pref("ui.captiontext", "#101010");
-pref("ui.graytext", "#b1a598");
-pref("ui.highlighttext", "#1a1a1a");
-pref("ui.threeddarkshadow", "#000");
-pref("ui.threedface", "#ece7e2");
-pref("ui.threedhighlight", "#fff");
-pref("ui.threedlightshadow", "#ece7e2");
-pref("ui.threedshadow", "#aea194");
-pref("ui.windowframe", "#efebe7");
-
-// Themable via mozSettings
-pref("ui.menu", "#f97c17");
-pref("ui.menutext", "#ffffff");
-pref("ui.infobackground", "#343e40");
-pref("ui.infotext", "#686868");
-pref("ui.window", "#ffffff");
-pref("ui.windowtext", "#000000");
-pref("ui.highlight", "#b2f2ff");
-
-// replace newlines with spaces on paste into single-line text boxes
-pref("editor.singleLine.pasteNewlines", 2);
-
-// threshold where a tap becomes a drag, in 1/240" reference pixels
-// The names of the preferences are to be in sync with EventStateManager.cpp
-pref("ui.dragThresholdX", 25);
-pref("ui.dragThresholdY", 25);
-
-// Layers Acceleration. We can only have nice things on gonk, because
-// they're not maintained anywhere else.
-#ifndef MOZ_WIDGET_GONK
-pref("dom.ipc.tabs.disabled", true);
-pref("layers.async-pan-zoom.enabled", false);
-#else
-pref("dom.ipc.tabs.disabled", false);
-pref("layers.acceleration.disabled", false);
-pref("gfx.content.azure.backends", "cairo");
-#endif
-
-// Web Notifications
-pref("notification.feature.enabled", true);
-
-// prevent video elements from preloading too much data
-pref("media.preload.default", 1); // default to preload none
-pref("media.preload.auto", 2); // preload metadata if preload=auto
-pref("media.cache_size", 4096); // 4MB media cache
-// Try to save battery by not resuming reading from a connection until we fall
-// below 10s of buffered data.
-pref("media.cache_resume_threshold", 10);
-pref("media.cache_readahead_limit", 30);
-
-#ifdef MOZ_FMP4
-// Enable/Disable Gonk Decoder Module
-pref("media.gonk.enabled", true);
-#endif
-
-//Encrypted media extensions.
-pref("media.eme.enabled", true);
-pref("media.eme.apiVisible", true);
-// The default number of decoded video frames that are enqueued in
-// MediaDecoderReader's mVideoQueue.
-pref("media.video-queue.default-size", 3);
-
-// optimize images' memory usage
-pref("image.downscale-during-decode.enabled", true);
-pref("image.mem.allow_locking_in_content_processes", true);
-// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
-// Almost everything that was factored into 'max_decoded_image_kb' is now stored
-// in the surface cache. 1/8 of main memory is 32MB on a 256MB device, which is
-// about the same as the old 'max_decoded_image_kb'.
-pref("image.mem.surfacecache.max_size_kb", 131072); // 128MB
-pref("image.mem.surfacecache.size_factor", 8); // 1/8 of main memory
-pref("image.mem.surfacecache.discard_factor", 2); // Discard 1/2 of the surface cache at a time.
-pref("image.mem.surfacecache.min_expiration_ms", 86400000); // 24h, we rely on the out of memory hook
-
-pref("dom.w3c_touch_events.safetyX", 0); // escape borders in units of 1/240"
-pref("dom.w3c_touch_events.safetyY", 120); // escape borders in units of 1/240"
-
-// True if this is the first time we are showing about:firstrun
-pref("browser.firstrun.show.uidiscovery", true);
-pref("browser.firstrun.show.localepicker", true);
-
-// initiated by a user
-pref("content.ime.strict_policy", true);
-
-// True if you always want dump() to work
-//
-// On Android, you also need to do the following for the output
-// to show up in logcat:
-//
-// $ adb shell stop
-// $ adb shell setprop log.redirect-stdio true
-// $ adb shell start
-pref("browser.dom.window.dump.enabled", false);
-
-// Default Content Security Policy to apply to certified apps.
-// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
-pref("security.apps.certified.CSP.default", "default-src * data: blob:; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline' app://theme.gaiamobile.org");
-
-// handle links targeting new windows
-// 1=current window/tab, 2=new window, 3=new tab in most recent window
-pref("browser.link.open_newwindow", 3);
-
-// 0: no restrictions - divert everything
-// 1: don't divert window.open at all
-// 2: don't divert window.open with features
-pref("browser.link.open_newwindow.restriction", 0);
-
-// Enable browser frames (including OOP, except on Windows, where it doesn't
-// work), but make in-process browser frames the default.
-pref("dom.mozBrowserFramesEnabled", true);
-
-// Enable a (virtually) unlimited number of mozbrowser processes.
-// We'll run out of PIDs on UNIX-y systems before we hit this limit.
-pref("dom.ipc.processCount", 100000);
-
-pref("dom.ipc.browser_frames.oop_by_default", false);
-
-#if !defined(MOZ_MULET) && !defined(MOZ_GRAPHENE)
-pref("dom.meta-viewport.enabled", true);
-#endif
-
-//The waiting time in network manager.
-pref("network.gonk.ms-release-mms-connection", 30000);
-
-// Shortnumber matching needed for e.g. Brazil:
-// 03187654321 can be found with 87654321
-pref("dom.phonenumber.substringmatching.BR", 8);
-pref("dom.phonenumber.substringmatching.CO", 10);
-pref("dom.phonenumber.substringmatching.VE", 7);
-pref("dom.phonenumber.substringmatching.CL", 8);
-pref("dom.phonenumber.substringmatching.PE", 7);
-
-// NetworkStats
-#ifdef MOZ_WIDGET_GONK
-pref("dom.mozNetworkStats.enabled", true);
-pref("dom.webapps.firstRunWithSIM", true);
-#endif
-
-#ifdef MOZ_B2G_RIL
-// SingleVariant
-pref("dom.mozApps.single_variant_sourcedir", "/persist/svoperapps");
-#endif
-
-// WebSettings
-pref("dom.mozSettings.enabled", true);
-pref("dom.mozPermissionSettings.enabled", true);
-
-// controls if we want camera support
-pref("device.camera.enabled", true);
-pref("media.realtime_decoder.enabled", true);
-
-// TCPSocket
-pref("dom.mozTCPSocket.enabled", true);
-
-// "Preview" landing of bug 710563, which is bogged down in analysis
-// of talos regression. This is a needed change for higher-framerate
-// CSS animations, and incidentally works around an apparent bug in
-// our handling of requestAnimationFrame() listeners, which are
-// supposed to enable this REPEATING_PRECISE_CAN_SKIP behavior. The
-// secondary bug isn't really worth investigating since it's obseleted
-// by bug 710563.
-pref("layout.frame_rate.precise", true);
-
-// Handle hardware buttons in the b2g chrome package
-pref("b2g.keys.menu.enabled", true);
-
-// Display simulator software buttons
-pref("b2g.software-buttons", false);
-
-// Screen timeout in seconds
-pref("power.screen.timeout", 60);
-
-pref("full-screen-api.enabled", true);
-
-#ifndef MOZ_WIDGET_GONK
-// If we're not actually on physical hardware, don't make the top level widget
-// fullscreen when transitioning to fullscreen. This means in emulated
-// environments (like the b2g desktop client) we won't make the client window
-// fill the whole screen, we'll just make the content fill the client window,
-// i.e. it won't give the impression to content that the number of device
-// screen pixels changes!
-pref("full-screen-api.ignore-widgets", true);
-#endif
-
-pref("media.volume.steps", 10);
-
-#ifdef ENABLE_MARIONETTE
-//Enable/disable marionette server, set listening port
-pref("marionette.defaultPrefs.enabled", true);
-pref("marionette.defaultPrefs.port", 2828);
-#ifndef MOZ_WIDGET_GONK
-// On desktop builds, we need to force the socket to listen on localhost only
-pref("marionette.force-local", true);
-#endif
-#endif
-
-#ifdef MOZ_UPDATER
-// When we're applying updates, we can't let anything hang us on
-// quit+restart. The user has no recourse.
-pref("shutdown.watchdog.timeoutSecs", 10);
-// Timeout before the update prompt automatically installs the update
-pref("b2g.update.apply-prompt-timeout", 60000); // milliseconds
-// Amount of time to wait after the user is idle before prompting to apply an update
-pref("b2g.update.apply-idle-timeout", 600000); // milliseconds
-// Amount of time after which connection will be restarted if no progress
-pref("b2g.update.download-watchdog-timeout", 120000); // milliseconds
-pref("b2g.update.download-watchdog-max-retries", 5);
-
-pref("app.update.enabled", true);
-pref("app.update.auto", false);
-pref("app.update.silent", false);
-pref("app.update.staging.enabled", true);
-pref("app.update.service.enabled", true);
-
-pref("app.update.url", "https://aus5.mozilla.org/update/5/%PRODUCT%/%VERSION%/%BUILD_ID%/%PRODUCT_DEVICE%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%IMEI%/update.xml");
-pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
-
-// Interval at which update manifest is fetched. In units of seconds.
-pref("app.update.interval", 86400); // 1 day
-// Don't throttle background updates.
-pref("app.update.download.backgroundInterval", 0);
-
-// Retry update socket connections every 30 seconds in the cases of certain kinds of errors
-pref("app.update.socket.retryTimeout", 30000);
-
-// Max of 20 consecutive retries (total 10 minutes) before giving up and marking
-// the update download as failed.
-// Note: Offline errors will always retry when the network comes online.
-pref("app.update.socket.maxErrors", 20);
-
-// Enable update logging for now, to diagnose growing pains in the
-// field.
-pref("app.update.log", true);
-
-// SystemUpdate API
-pref("dom.system_update.active", "@mozilla.org/updates/update-prompt;1");
-#else
-// Explicitly disable the shutdown watchdog. It's enabled by default.
-// When the updater is disabled, we want to know about shutdown hangs.
-pref("shutdown.watchdog.timeoutSecs", -1);
-#endif
-
-// Allow webapps update checking
-pref("webapps.update.enabled", true);
-
-// Check daily for apps updates.
-pref("webapps.update.interval", 86400);
-
-// Extensions preferences
-pref("extensions.update.enabled", false);
-pref("extensions.getAddons.cache.enabled", false);
-
-// Context Menu
-pref("ui.click_hold_context_menus", true);
-pref("ui.click_hold_context_menus.delay", 400);
-
-// Enable device storage
-pref("device.storage.enabled", true);
-
-// Enable pre-installed applications
-pref("dom.webapps.useCurrentProfile", true);
-
-// Enable system message
-pref("dom.sysmsg.enabled", true);
-pref("media.plugins.enabled", false);
-pref("media.rtsp.enabled", true);
-pref("media.rtsp.video.enabled", true);
-
-// Disable printing (particularly, window.print())
-pref("dom.disable_window_print", true);
-
-// Disable window.showModalDialog
-pref("dom.disable_window_showModalDialog", true);
-
-// Enable new experimental html forms
-pref("dom.experimental_forms", true);
-pref("dom.forms.number", true);
-
-// Don't enable <input type=color> yet as we don't have a color picker
-// implemented for b2g (bug 875751)
-pref("dom.forms.color", false);
-
-// This preference instructs the JS engine to discard the
-// source of any privileged JS after compilation. This saves
-// memory, but makes things like Function.prototype.toSource()
-// fail.
-pref("javascript.options.discardSystemSource", true);
-
-// XXXX REMOVE FOR PRODUCTION. Turns on GC and CC logging
-pref("javascript.options.mem.log", false);
-
-// Increase mark slice time from 10ms to 30ms
-pref("javascript.options.mem.gc_incremental_slice_ms", 30);
-
-// Increase time to get more high frequency GC on benchmarks from 1000ms to 1500ms
-pref("javascript.options.mem.gc_high_frequency_time_limit_ms", 1500);
-
-pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 300);
-pref("javascript.options.mem.gc_high_frequency_heap_growth_min", 120);
-pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 40);
-pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 0);
-pref("javascript.options.mem.gc_low_frequency_heap_growth", 120);
-pref("javascript.options.mem.high_water_mark", 6);
-pref("javascript.options.mem.gc_allocation_threshold_mb", 1);
-pref("javascript.options.mem.gc_min_empty_chunk_count", 1);
-pref("javascript.options.mem.gc_max_empty_chunk_count", 2);
-
-// Show/Hide scrollbars when active/inactive
-pref("ui.showHideScrollbars", 1);
-pref("ui.useOverlayScrollbars", 1);
-pref("ui.scrollbarFadeBeginDelay", 450);
-pref("ui.scrollbarFadeDuration", 0);
-
-// Scrollbar position follows the document `dir` attribute
-pref("layout.scrollbar.side", 1);
-
-// CSS Scroll Snapping
-pref("layout.css.scroll-snap.enabled", true);
-
-// Enable the ProcessPriorityManager, and give processes with no visible
-// documents a 1s grace period before they're eligible to be marked as
-// background. Background processes that are perceivable due to playing
-// media are given a longer grace period to accomodate changing tracks, etc.
-pref("dom.ipc.processPriorityManager.enabled", true);
-pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
-pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000);
-pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
-
-// Number of different background/foreground levels for background/foreground
-// processes. We use these different levels to force the low-memory killer to
-// kill processes in a LRU order.
-pref("dom.ipc.processPriorityManager.BACKGROUND.LRUPoolLevels", 5);
-pref("dom.ipc.processPriorityManager.BACKGROUND_PERCEIVABLE.LRUPoolLevels", 4);
-
-// Kernel parameters for process priorities. These affect how processes are
-// killed on low-memory and their relative CPU priorities.
-//
-// The kernel can only accept 6 (OomScoreAdjust, KillUnderKB) pairs. But it is
-// okay, kernel will still kill processes with larger OomScoreAdjust first even
-// its OomScoreAdjust don't have a corresponding KillUnderKB.
-
-pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
-pref("hal.processPriorityManager.gonk.MASTER.KillUnderKB", 4096);
-pref("hal.processPriorityManager.gonk.MASTER.cgroup", "");
-
-pref("hal.processPriorityManager.gonk.PREALLOC.OomScoreAdjust", 67);
-pref("hal.processPriorityManager.gonk.PREALLOC.cgroup", "apps/bg_non_interactive");
-
-pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.OomScoreAdjust", 67);
-pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.KillUnderKB", 5120);
-pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.cgroup", "apps/critical");
-
-pref("hal.processPriorityManager.gonk.FOREGROUND.OomScoreAdjust", 134);
-pref("hal.processPriorityManager.gonk.FOREGROUND.KillUnderKB", 6144);
-pref("hal.processPriorityManager.gonk.FOREGROUND.cgroup", "apps");
-
-pref("hal.processPriorityManager.gonk.FOREGROUND_KEYBOARD.OomScoreAdjust", 200);
-pref("hal.processPriorityManager.gonk.FOREGROUND_KEYBOARD.cgroup", "apps");
-
-pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.OomScoreAdjust", 400);
-pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.KillUnderKB", 8192);
-pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.cgroup", "apps/bg_perceivable");
-
-pref("hal.processPriorityManager.gonk.BACKGROUND.OomScoreAdjust", 667);
-pref("hal.processPriorityManager.gonk.BACKGROUND.KillUnderKB", 20480);
-pref("hal.processPriorityManager.gonk.BACKGROUND.cgroup", "apps/bg_non_interactive");
-
-// Control group definitions (i.e., CPU priority groups) for B2G processes.
-//
-// memory_swappiness - 0 - The kernel will swap only to avoid an out of memory condition
-// memory_swappiness - 60 - The default value.
-// memory_swappiness - 100 - The kernel will swap aggressively.
-
-// Foreground apps
-pref("hal.processPriorityManager.gonk.cgroups.apps.cpu_shares", 1024);
-pref("hal.processPriorityManager.gonk.cgroups.apps.cpu_notify_on_migrate", 0);
-pref("hal.processPriorityManager.gonk.cgroups.apps.memory_swappiness", 10);
-
-// Foreground apps with high priority, 16x more CPU than foreground ones
-pref("hal.processPriorityManager.gonk.cgroups.apps/critical.cpu_shares", 16384);
-pref("hal.processPriorityManager.gonk.cgroups.apps/critical.cpu_notify_on_migrate", 0);
-pref("hal.processPriorityManager.gonk.cgroups.apps/critical.memory_swappiness", 0);
-
-// Background perceivable apps, ~10x less CPU than foreground ones
-pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.cpu_shares", 103);
-pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.cpu_notify_on_migrate", 0);
-pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.memory_swappiness", 60);
-
-// Background apps, ~20x less CPU than foreground ones and ~2x less than perceivable ones
-pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.cpu_shares", 52);
-pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.cpu_notify_on_migrate", 0);
-pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.memory_swappiness", 100);
-
-// By default the compositor thread on gonk runs without real-time priority. RT
-// priority can be enabled by setting this pref to a value between 1 and 99.
-// Note that audio processing currently runs at RT priority 2 or 3 at most.
-//
-// If RT priority is disabled, then the compositor nice value is used. We prefer
-// to use a nice value of -4, which matches Android's preferences. Setting a preference
-// of RT priority 1 would mean it is higher than audio, which is -16. The compositor
-// priority must be below the audio thread.
-//
-// Do not change these values without gfx team review.
-pref("hal.gonk.COMPOSITOR.rt_priority", 0);
-pref("hal.gonk.COMPOSITOR.nice", -4);
-
-// Fire a memory pressure event when the system has less than Xmb of memory
-// remaining. You should probably set this just above Y.KillUnderKB for
-// the highest priority class Y that you want to make an effort to keep alive.
-// (For example, we want BACKGROUND_PERCEIVABLE to stay alive.) If you set
-// this too high, then we'll send out a memory pressure event every Z seconds
-// (see below), even while we have processes that we would happily kill in
-// order to free up memory.
-pref("gonk.notifyHardLowMemUnderKB", 14336);
-
-// Fire a memory pressure event when the system has less than Xmb of memory
-// remaining and then switch to the hard trigger, see above. This should be
-// placed above the BACKGROUND priority class.
-pref("gonk.notifySoftLowMemUnderKB", 43008);
-
-// We wait this long before polling the memory-pressure fd after seeing one
-// memory pressure event. (When we're not under memory pressure, we sit
-// blocked on a poll(), and this pref has no effect.)
-pref("gonk.systemMemoryPressureRecoveryPollMS", 5000);
-
-// Enable pre-launching content processes for improved startup time
-// (hiding latency).
-pref("dom.ipc.processPrelaunch.enabled", true);
-// Wait this long before pre-launching a new subprocess.
-pref("dom.ipc.processPrelaunch.delayMs", 5000);
-
-pref("dom.ipc.reuse_parent_app", false);
-
-// When a process receives a system message, we hold a CPU wake lock on its
-// behalf for this many seconds, or until it handles the system message,
-// whichever comes first.
-pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
-
-// Ignore the "dialog=1" feature in window.open.
-pref("dom.disable_window_open_dialog_feature", true);
-
-// Enable before keyboard events and after keyboard events.
-pref("dom.beforeAfterKeyboardEvent.enabled", true);
-
-// Screen reader support
-pref("accessibility.accessfu.activate", 2);
-pref("accessibility.accessfu.quicknav_modes", "Link,Heading,FormElement,Landmark,ListItem");
-// Active quicknav mode, index value of list from quicknav_modes
-pref("accessibility.accessfu.quicknav_index", 0);
-// Setting for an utterance order (0 - description first, 1 - description last).
-pref("accessibility.accessfu.utterance", 1);
-// Whether to skip images with empty alt text
-pref("accessibility.accessfu.skip_empty_images", true);
-// Setting to change the verbosity of entered text (0 - none, 1 - characters,
-// 2 - words, 3 - both)
-pref("accessibility.accessfu.keyboard_echo", 3);
-
-// Enable hit-target fluffing
-pref("ui.touch.radius.enabled", true);
-pref("ui.touch.radius.leftmm", 3);
-pref("ui.touch.radius.topmm", 5);
-pref("ui.touch.radius.rightmm", 3);
-pref("ui.touch.radius.bottommm", 2);
-
-pref("ui.mouse.radius.enabled", true);
-pref("ui.mouse.radius.leftmm", 3);
-pref("ui.mouse.radius.topmm", 5);
-pref("ui.mouse.radius.rightmm", 3);
-pref("ui.mouse.radius.bottommm", 2);
-
-// Disable native prompt
-pref("browser.prompt.allowNative", false);
-
-// Minimum delay in milliseconds between network activity notifications (0 means
-// no notifications). The delay is the same for both download and upload, though
-// they are handled separately. This pref is only read once at startup:
-// a restart is required to enable a new value.
-pref("network.activity.blipIntervalMilliseconds", 250);
-
-// By default we want the NetworkManager service to manage Gecko's offline
-// status for us according to the state of Wifi/cellular data connections.
-// In some environments, such as the emulator or hardware with other network
-// connectivity, this is not desireable, however, in which case this pref
-// can be flipped to false.
-pref("network.gonk.manage-offline-status", true);
-
-// On Firefox Mulet, we can't enable shared JSM scope
-// as it breaks most Firefox JSMs (see bug 961777)
-#ifndef MOZ_MULET
-// Break any JSMs or JS components that rely on shared scope
-#ifndef DEBUG
-pref("jsloader.reuseGlobal", true);
-#endif
-#endif
-
-// Enable font inflation for browser tab content.
-pref("font.size.inflation.minTwips", 120);
-// And disable it for lingering master-process UI.
-pref("font.size.inflation.disabledInMasterProcess", true);
-
-// Enable freeing dirty pages when minimizing memory; this reduces memory
-// consumption when applications are sent to the background.
-pref("memory.free_dirty_pages", true);
-
-// Enable the Linux-specific, system-wide memory reporter.
-pref("memory.system_memory_reporter", true);
-
-// Don't dump memory reports on OOM, by default.
-pref("memory.dump_reports_on_oom", false);
-
-pref("layout.framevisibility.numscrollportwidths", 1);
-pref("layout.framevisibility.numscrollportheights", 1);
-
-// Wait up to this much milliseconds when orientation changed
-pref("layers.orientation.sync.timeout", 1000);
-
-// Animate the orientation change
-pref("b2g.orientation.animate", true);
-
-// Don't discard WebGL contexts for foreground apps on memory
-// pressure.
-pref("webgl.can-lose-context-in-foreground", false);
-
-// Allow nsMemoryInfoDumper to create a fifo in the temp directory. We use
-// this fifo to trigger about:memory dumps, among other things.
-pref("memory_info_dumper.watch_fifo.enabled", true);
-pref("memory_info_dumper.watch_fifo.directory", "/data/local");
-
-// See ua-update.json.in for the packaged UA override list
-pref("general.useragent.updates.enabled", true);
-pref("general.useragent.updates.url", "https://dynamicua.cdn.mozilla.net/0/%APP_ID%");
-pref("general.useragent.updates.interval", 604800); // 1 week
-pref("general.useragent.updates.retry", 86400); // 1 day
-// Device ID can be composed of letter, numbers, hyphen ("-") and dot (".")
-pref("general.useragent.device_id", "");
-
-// Add Mozilla AudioChannel APIs.
-pref("media.useAudioChannelAPI", true);
-
-pref("b2g.version", @MOZ_B2G_VERSION@);
-pref("b2g.osName", @MOZ_B2G_OS_NAME@);
-
-// Disable console buffering to save memory.
-pref("consoleservice.buffered", false);
-
-#ifdef MOZ_WIDGET_GONK
-// Performance testing suggests 2k is a better page size for SQLite.
-pref("toolkit.storage.pageSize", 2048);
-#endif
-
-// The url of the manifest we use for ADU pings.
-pref("ping.manifestURL", "https://marketplace.firefox.com/packaged.webapp");
-
-// Enable the disk space watcher
-pref("disk_space_watcher.enabled", true);
-
-// SNTP preferences.
-pref("network.sntp.maxRetryCount", 10);
-pref("network.sntp.refreshPeriod", 86400); // In seconds.
-pref("network.sntp.pools", // Servers separated by ';'.
- "0.pool.ntp.org;1.pool.ntp.org;2.pool.ntp.org;3.pool.ntp.org");
-pref("network.sntp.port", 123);
-pref("network.sntp.timeout", 30); // In seconds.
-
-// Allow ADB to run for this many hours before disabling
-// (only applies when marionette is disabled)
-// 0 disables the timer.
-pref("b2g.adb.timeout-hours", 12);
-
-// InputMethod so we can do soft keyboards
-pref("dom.mozInputMethod.enabled", true);
-
-// Absolute path to the devtool unix domain socket file used
-// to communicate with a usb cable via adb forward
-pref("devtools.debugger.unix-domain-socket", "/data/local/debugger-socket");
-
-// enable Skia/GL (OpenGL-accelerated 2D drawing) for large enough 2d canvases,
-// falling back to Skia/software for smaller canvases
-#ifdef MOZ_WIDGET_GONK
-pref("gfx.canvas.azure.backends", "skia");
-pref("gfx.canvas.azure.accelerated", true);
-#endif
-
-// Turn on dynamic cache size for Skia
-pref("gfx.canvas.skiagl.dynamic-cache", true);
-
-// Limit skia to canvases the size of the device screen or smaller
-pref("gfx.canvas.max-size-for-skia-gl", -1);
-
-// enable fence with readpixels for SurfaceStream
-pref("gfx.gralloc.fence-with-readpixels", true);
-
-// enable screen mirroring to external display
-pref("gfx.screen-mirroring.enabled", true);
-
-// The url of the page used to display network error details.
-pref("b2g.neterror.url", "net_error.html");
-
-// Enable Web Speech synthesis API
-pref("media.webspeech.synth.enabled", true);
-
-// Enable Web Speech recognition API
-pref("media.webspeech.recognition.enable", true);
-
-// Downloads API
-pref("dom.mozDownloads.enabled", true);
-pref("dom.downloads.max_retention_days", 7);
-
-// External Helper Application Handling
-//
-// All external helper application handling can require the docshell to be
-// active before allowing the external helper app service to handle content.
-//
-// To prevent SD card DoS attacks via downloads we disable background handling.
-//
-pref("security.exthelperapp.disable_background_handling", true);
-
-// Inactivity time in milliseconds after which we shut down the OS.File worker.
-pref("osfile.reset_worker_delay", 5000);
-
-// APZ physics settings, tuned by UX designers
-pref("apz.axis_lock.mode", 2); // Use "sticky" axis locking
-pref("apz.fling_curve_function_x1", "0.41");
-pref("apz.fling_curve_function_y1", "0.0");
-pref("apz.fling_curve_function_x2", "0.80");
-pref("apz.fling_curve_function_y2", "1.0");
-pref("apz.fling_curve_threshold_inches_per_ms", "0.01");
-pref("apz.fling_friction", "0.0019");
-pref("apz.max_velocity_inches_per_ms", "0.07");
-pref("apz.overscroll.enabled", true);
-pref("apz.displayport_expiry_ms", 0); // causes issues on B2G, see bug 1250924
-
-// For event-regions based hit-testing
-pref("layout.event-regions.enabled", true);
-
-// This preference allows FirefoxOS apps (and content, I think) to force
-// the use of software (instead of hardware accelerated) 2D canvases by
-// creating a context like this:
-//
-// canvas.getContext('2d', { willReadFrequently: true })
-//
-// Using a software canvas can save memory when JS calls getImageData()
-// on the canvas frequently. See bug 884226.
-pref("gfx.canvas.willReadFrequently.enable", true);
-
-// Disable autofocus until we can have it not bring up the keyboard.
-// https://bugzilla.mozilla.org/show_bug.cgi?id=965763
-pref("browser.autofocus", false);
-
-// Enable wakelock
-pref("dom.wakelock.enabled", true);
-
-// Enable webapps add-ons
-pref("dom.apps.reviewer_paths", "/reviewers/,/extension/reviewers/");
-
-// New implementation to unify touch-caret and selection-carets.
-pref("layout.accessiblecaret.enabled", true);
-
-// Show the selection bars at the two ends of the selection highlight. Required
-// by the spec in bug 921965.
-pref("layout.accessiblecaret.bar.enabled", true);
-
-// Hide the caret in cursor mode after 3 seconds.
-pref("layout.accessiblecaret.timeout_ms", 3000);
-
-// Hide carets and text selection dialog during scrolling.
-pref("layout.accessiblecaret.always_show_when_scrolling", false);
-
-// Enable sync with Firefox Accounts.
-pref("services.sync.fxaccounts.enabled", true);
-pref("identity.fxaccounts.enabled", true);
-
-pref("identity.fxaccounts.remote.oauth.uri", "https://oauth.accounts.firefox.com/v1");
-pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
-
-// Disable Firefox Accounts device registration until bug 1238895 is fixed.
-pref("identity.fxaccounts.skipDeviceRegistration", true);
-
-// Enable mapped array buffer.
-pref("dom.mapped_arraybuffer.enabled", true);
-
-// SystemUpdate API
-pref("dom.system_update.enabled", true);
-
-// UDPSocket API
-pref("dom.udpsocket.enabled", true);
-
-// Enable TV Manager API
-pref("dom.tv.enabled", true);
-
-// Enable Inputport Manager API
-pref("dom.inputport.enabled", true);
-
-pref("dom.mozSettings.SettingsDB.debug.enabled", true);
-pref("dom.mozSettings.SettingsManager.debug.enabled", true);
-pref("dom.mozSettings.SettingsRequestManager.debug.enabled", true);
-pref("dom.mozSettings.SettingsService.debug.enabled", true);
-
-pref("dom.mozSettings.SettingsDB.verbose.enabled", false);
-pref("dom.mozSettings.SettingsManager.verbose.enabled", false);
-pref("dom.mozSettings.SettingsRequestManager.verbose.enabled", false);
-pref("dom.mozSettings.SettingsService.verbose.enabled", false);
-
-// Controlling whether we want to allow forcing some Settings
-// IndexedDB transactions to be opened as readonly or keep everything as
-// readwrite.
-pref("dom.mozSettings.allowForceReadOnly", false);
-
-// Comma separated list of activity names that can only be provided by
-// the system app in dev mode.
-pref("dom.activities.developer_mode_only", "import-app");
-
-// mulet apparently loads firefox.js as well as b2g.js, so we have to explicitly
-// disable serviceworkers and push here to get them disabled in mulet.
-pref("dom.serviceWorkers.enabled", false);
-pref("dom.push.enabled", false);
-
-#if defined(RELEASE_OR_BETA)
-// Bug 1278848: Enable service worker notifications on release B2G once
-// they're ready.
-pref("dom.webnotifications.serviceworker.enabled", false);
-#else
-pref("dom.webnotifications.serviceworker.enabled", true);
-#endif
-
-// Retain at most 10 processes' layers buffers
-pref("layers.compositor-lru-size", 10);
-
-// In B2G by deafult any AudioChannelAgent is muted when created.
-pref("dom.audiochannel.mutedByDefault", true);
-
-// Default device name for Presentation API
-pref("dom.presentation.device.name", "Firefox OS");
-
-// Enable notification of performance timing
-pref("dom.performance.enable_notify_performance_timing", true);
-
-// Multi-screen
-pref("b2g.multiscreen.chrome_remote_url", "chrome://b2g/content/shell_remote.html");
-pref("b2g.multiscreen.system_remote_url", "index_remote.html");
-
-// Audio competing between tabs
-pref("dom.audiochannel.audioCompeting", false);
-
-// Because we can't have nice things.
-#ifdef MOZ_GRAPHENE
-#include ../graphene/graphene.js
-#endif
diff --git a/b2g/app/macbuild/Contents/Info.plist.in b/b2g/app/macbuild/Contents/Info.plist.in
deleted file mode 100644
index d5ea85f4d..000000000
--- a/b2g/app/macbuild/Contents/Info.plist.in
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleExecutable</key>
- <string>%APP_BINARY%</string>
- <key>CFBundleGetInfoString</key>
- <string>%APP_NAME% %APP_VERSION%</string>
- <key>CFBundleIconFile</key>
- <string>%MOZ_APP_NAME%.icns</string>
- <key>CFBundleIdentifier</key>
- <string>org.mozilla.b2g</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>%MOZ_APP_VERSION%</string>
- <key>CFBundleName</key>
- <string>%APP_NAME%</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>%APP_VERSION%</string>
- <key>CFBundleSignature</key>
- <string>MOZB</string>
- <key>CFBundleVersion</key>
- <string>%APP_VERSION%</string>
- <key>NSAppleScriptEnabled</key>
- <true/>
- <key>CGDisableCoalescedUpdates</key>
- <true/>
- <key>NSHighResolutionCapable</key>
- <true/>
- <key>NSPrincipalClass</key>
- <string>GeckoNSApplication</string>
- <key>CFBundleURLTypes</key>
- <array>
- <dict>
- <key>CFBundleURLIconFile</key>
- <string>document.icns</string>
- <key>CFBundleURLName</key>
- <string>http URL</string>
- <key>CFBundleURLSchemes</key>
- <array>
- <string>http</string>
- </array>
- </dict>
- <dict>
- <key>CFBundleURLIconFile</key>
- <string>document.icns</string>
- <key>CFBundleURLName</key>
- <string>https URL</string>
- <key>CFBundleURLSchemes</key>
- <array>
- <string>https</string>
- </array>
- </dict>
- <dict>
- <key>CFBundleURLName</key>
- <string>ftp URL</string>
- <key>CFBundleURLSchemes</key>
- <array>
- <string>ftp</string>
- </array>
- </dict>
- </array>
-</dict>
-</plist>
diff --git a/b2g/app/macbuild/Contents/MacOS-files.in b/b2g/app/macbuild/Contents/MacOS-files.in
deleted file mode 100644
index 4cefd2ff9..000000000
--- a/b2g/app/macbuild/Contents/MacOS-files.in
+++ /dev/null
@@ -1,9 +0,0 @@
-/*.app/***
-/*.dylib
-/b2g
-/certutil
-/gtest/***
-/pk12util
-/ssltunnel
-/xpcshell
-/XUL
diff --git a/b2g/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in b/b2g/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
deleted file mode 100644
index ddd3e0afa..000000000
--- a/b2g/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
+++ /dev/null
@@ -1,5 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-CFBundleName = "%APP_NAME%";
diff --git a/b2g/app/moz.build b/b2g/app/moz.build
deleted file mode 100644
index b28889065..000000000
--- a/b2g/app/moz.build
+++ /dev/null
@@ -1,76 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-if CONFIG['GAIADIR']:
- GeckoProgram(CONFIG['MOZ_APP_NAME'] + "-bin")
-else:
- GeckoProgram(CONFIG['MOZ_APP_NAME'])
-
-SOURCES += [
- 'nsBrowserApp.cpp',
-]
-if CONFIG['_MSC_VER']:
- # Always enter a Windows program through wmain, whether or not we're
- # a console application.
- WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
-
-USE_LIBS += [
- 'zlib',
-]
-
-for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION', 'MOZ_UPDATER'):
- DEFINES[var] = CONFIG[var]
-
-LOCAL_INCLUDES += [
- '!/build',
- '/toolkit/xre',
- '/xpcom/base',
- '/xpcom/build',
-]
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
- LOCAL_INCLUDES += [
- '/widget/gonk/libdisplay',
- ]
-
- LDFLAGS += ['-Wl,--export-dynamic']
-
- USE_LIBS += [
- 'display',
- 'mozpng',
- ]
- OS_LIBS += [
- 'ui',
- 'EGL',
- 'hardware_legacy',
- 'hardware',
- 'cutils',
- ]
- OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
- if CONFIG['ANDROID_VERSION'] in ('17', '18', '19', '21', '22'):
- OS_LIBS += [
- 'gui',
- 'suspend',
- ]
- OS_LIBS += [
- 'binder',
- 'utils',
- ]
-
-DISABLE_STL_WRAPPING = True
-
-if CONFIG['OS_ARCH'] == 'WINNT':
- OS_LIBS += [
- 'version',
- ]
-
-JS_PREFERENCE_PP_FILES += [
- 'b2g.js',
-]
-
-FINAL_TARGET_PP_FILES += [
- 'ua-update.json.in',
-]
diff --git a/b2g/app/nsBrowserApp.cpp b/b2g/app/nsBrowserApp.cpp
deleted file mode 100644
index 967b54b76..000000000
--- a/b2g/app/nsBrowserApp.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsXULAppAPI.h"
-#include "application.ini.h"
-#include "nsXPCOMGlue.h"
-#if defined(XP_WIN)
-#include <windows.h>
-#include <stdlib.h>
-#elif defined(XP_UNIX)
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "nsCOMPtr.h"
-#include "nsIFile.h"
-#include "nsStringGlue.h"
-
-#ifdef XP_WIN
-// we want a wmain entry point
-#include "nsWindowsWMain.cpp"
-#define strcasecmp _stricmp
-#endif
-
-#ifdef MOZ_WIDGET_GONK
-#include "BootAnimation.h"
-#endif
-
-#include "BinaryPath.h"
-
-#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
-
-#ifdef MOZ_WIDGET_GONK
-# include <binder/ProcessState.h>
-#endif
-
-#include "mozilla/Sprintf.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/WindowsDllBlocklist.h"
-
-static void Output(const char *fmt, ... )
-{
- va_list ap;
- va_start(ap, fmt);
-
-#if defined(XP_WIN) && !MOZ_WINCONSOLE
- wchar_t msg[2048];
- _vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap);
- MessageBoxW(nullptr, msg, L"XULRunner", MB_OK | MB_ICONERROR);
-#else
- vfprintf(stderr, fmt, ap);
-#endif
-
- va_end(ap);
-}
-
-/**
- * Return true if |arg| matches the given argument name.
- */
-static bool IsArg(const char* arg, const char* s)
-{
- if (*arg == '-')
- {
- if (*++arg == '-')
- ++arg;
- return !strcasecmp(arg, s);
- }
-
-#if defined(XP_WIN)
- if (*arg == '/')
- return !strcasecmp(++arg, s);
-#endif
-
- return false;
-}
-
-XRE_GetFileFromPathType XRE_GetFileFromPath;
-XRE_CreateAppDataType XRE_CreateAppData;
-XRE_FreeAppDataType XRE_FreeAppData;
-XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
-XRE_mainType XRE_main;
-
-static const nsDynamicFunctionLoad kXULFuncs[] = {
- { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
- { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
- { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
- { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
- { "XRE_main", (NSFuncPtr*) &XRE_main },
- { nullptr, nullptr }
-};
-
-static int do_main(int argc, char* argv[])
-{
- nsCOMPtr<nsIFile> appini;
- nsresult rv;
-
- // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
- // Note that -app must be the *first* argument.
- const char *appDataFile = getenv("XUL_APP_FILE");
- if (appDataFile && *appDataFile) {
- rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
- if (NS_FAILED(rv)) {
- Output("Invalid path found: '%s'", appDataFile);
- return 255;
- }
- }
- else if (argc > 1 && IsArg(argv[1], "app")) {
- if (argc == 2) {
- Output("Incorrect number of arguments passed to -app");
- return 255;
- }
-
- rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
- if (NS_FAILED(rv)) {
- Output("application.ini path not recognized: '%s'", argv[2]);
- return 255;
- }
-
- char appEnv[MAXPATHLEN];
- SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
- if (putenv(strdup(appEnv))) {
- Output("Couldn't set %s.\n", appEnv);
- return 255;
- }
- argv[2] = argv[0];
- argv += 2;
- argc -= 2;
- }
-
-#ifdef MOZ_WIDGET_GONK
- /* Start boot animation */
- mozilla::StartBootAnimation();
-#endif
-
- if (appini) {
- nsXREAppData *appData;
- rv = XRE_CreateAppData(appini, &appData);
- if (NS_FAILED(rv)) {
- Output("Couldn't read application.ini");
- return 255;
- }
- int result = XRE_main(argc, argv, appData, 0);
- XRE_FreeAppData(appData);
- return result;
- }
-
- return XRE_main(argc, argv, &sAppData, 0);
-}
-
-int main(int argc, char* argv[])
-{
- char exePath[MAXPATHLEN];
-
-#ifdef MOZ_WIDGET_GONK
- // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
- // receive binder calls, though not necessary to send binder calls.
- // ProcessState::Self() also needs to be called once on the main thread to
- // register the main thread with the binder driver.
- android::ProcessState::self()->startThreadPool();
-#endif
-
- nsresult rv;
- rv = mozilla::BinaryPath::Get(argv[0], exePath);
- if (NS_FAILED(rv)) {
- Output("Couldn't calculate the application directory.\n");
- return 255;
- }
-
- char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
- if (!lastSlash || ((lastSlash - exePath) + sizeof(XPCOM_DLL) + 1 > MAXPATHLEN))
- return 255;
-
- strcpy(++lastSlash, XPCOM_DLL);
-
-#if defined(XP_UNIX)
- // If the b2g app is launched from adb shell, then the shell will wind
- // up being the process group controller. This means that we can't send
- // signals to the process group (useful for profiling).
- // We ignore the return value since setsid() fails if we're already the
- // process group controller (the normal situation).
- (void)setsid();
-#endif
-
-#ifdef HAS_DLL_BLOCKLIST
- DllBlocklist_Initialize();
-#endif
-
- // We do this because of data in bug 771745
- XPCOMGlueEnablePreload();
-
- rv = XPCOMGlueStartup(exePath);
- if (NS_FAILED(rv)) {
- Output("Couldn't load XPCOM.\n");
- return 255;
- }
- // Reset exePath so that it is the directory name and not the xpcom dll name
- *lastSlash = 0;
-
- rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
- if (NS_FAILED(rv)) {
- Output("Couldn't load XRE functions.\n");
- return 255;
- }
-
- int result;
- {
- ScopedLogging log;
- char **_argv;
-
- /*
- * Duplicate argument vector to conform non-const argv of
- * do_main() since XRE_main() is very stupid with non-const argv.
- */
- _argv = new char *[argc + 1];
- for (int i = 0; i < argc; i++) {
- size_t len = strlen(argv[i]) + 1;
- _argv[i] = new char[len];
- MOZ_ASSERT(_argv[i] != nullptr);
- memcpy(_argv[i], argv[i], len);
- }
- _argv[argc] = nullptr;
-
- result = do_main(argc, _argv);
-
- for (int i = 0; i < argc; i++) {
- delete[] _argv[i];
- }
- delete[] _argv;
- }
-
- return result;
-}
diff --git a/b2g/app/ua-update.json.in b/b2g/app/ua-update.json.in
deleted file mode 100644
index cb4c66d12..000000000
--- a/b2g/app/ua-update.json.in
+++ /dev/null
@@ -1,51 +0,0 @@
-#filter slashslash
-// Everything after the first // on a line will be removed by the preproccesor.
-// Send these sites a custom user-agent. Bugs should be included with an entry.
-{
- // bug 826347, msn.com
- "msn.com": "\\(Mobile#(Android 4.4.4; Mobile",
- // bug 826353, itau.com.br
- "itau.com.br": "\\(Mobile#(Android; Mobile",
- // bug 826510, r7.com
- "r7.com": "\\(Mobile#(Android; Mobile",
- // bug 827622, bing.com
- "bing.com": "\\(Mobile#(Android; Mobile",
- // bug 827626, magazineluiza.com.br
- "magazineluiza.com.br": "\\(Mobile#(Android; Mobile",
- // bug 827670, elpais.com.co
- "elpais.com.co": "\\(Mobile#(Android 4.4.4; Mobile",
- // bug 828416, loteriasyapuestas.es
- "loteriasyapuestas.es": "\\(Mobile#(Android; Mobile",
- // bug 828418, bbva.es
- "bbva.es": "\\(Mobile#(Android; Mobile",
- // bug 828439, movistar.com.ve
- "movistar.com.ve": "\\(Mobile#(Android; Mobile",
- // bug 843132, comunio.es
- "comunio.es": "\\(Mobile#(Android; Mobile",
- // bug 843151, citibank.com
- "citibank.com": "\\(Mobile#(Android; Mobile",
- // bug 843153, games.com
- "games.com": "\\(Mobile#(Android; Mobile",
- // bug 843160, ehow.com
- "ehow.com": "\\(Mobile#(Android; Mobile",
- // bug 878228, blikk.hu
- "blikk.hu": "\\(Mobile#(Android; Mobile",
- // bug 878238, koponyeg.hu
- "koponyeg.hu": "\\(Mobile#(Android; Mobile",
- // bug 878240, kuruc.info
- "kuruc.info": "\\(Mobile#(Android; Mobile",
- // bug 878242, nemzetisport.hu
- "nemzetisport.hu": "\\(Mobile#(Android; Mobile",
- // bug 878246, port.hu
- "port.hu": "\\(Mobile#(Android; Mobile",
- // bug 878249, portfolio.hu
- "portfolio.hu": "\\(Mobile#(Android; Mobile",
- // bug 878260, cdm.me
- "cdm.me": "\\(Mobile#(Android; Mobile",
- // bug 878262, download.com
- "download.com": "\\(Mobile#(Android; Mobile",
- // bug 878273, livescore.com
- "livescore.com": "\\(Mobile#(Android; Mobile",
- // bug 878653, redstarbelgrade.info
- "redstarbelgrade.info": "\\(Mobile#(Android; Mobile"
-}
diff --git a/b2g/branding/branding-common.mozbuild b/b2g/branding/branding-common.mozbuild
deleted file mode 100644
index ae4aeb285..000000000
--- a/b2g/branding/branding-common.mozbuild
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-@template
-def B2GBranding():
- if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
- BRANDING_FILES += [
- 'app.ico',
- ]
- elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
- BRANDING_FILES += [
- 'app.icns',
- 'background.png',
- 'disk.icns',
- 'dsstore',
- ]
- elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
- BRANDING_FILES += [
- 'default.png',
- ]
diff --git a/b2g/branding/browserhtml/app.icns b/b2g/branding/browserhtml/app.icns
deleted file mode 100644
index 3d680134e..000000000
--- a/b2g/branding/browserhtml/app.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/app.ico b/b2g/branding/browserhtml/app.ico
deleted file mode 100644
index 04596e4d0..000000000
--- a/b2g/branding/browserhtml/app.ico
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/background.png b/b2g/branding/browserhtml/background.png
deleted file mode 100644
index db5576a33..000000000
--- a/b2g/branding/browserhtml/background.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/configure.sh b/b2g/branding/browserhtml/configure.sh
deleted file mode 100644
index 71c6129d2..000000000
--- a/b2g/branding/browserhtml/configure.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOZ_APP_DISPLAYNAME=Browser.html
diff --git a/b2g/branding/browserhtml/content/about.png b/b2g/branding/browserhtml/content/about.png
deleted file mode 100644
index 3cc1444f6..000000000
--- a/b2g/branding/browserhtml/content/about.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/content/favicon32.png b/b2g/branding/browserhtml/content/favicon32.png
deleted file mode 100644
index ac4a6968b..000000000
--- a/b2g/branding/browserhtml/content/favicon32.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/content/icon48.png b/b2g/branding/browserhtml/content/icon48.png
deleted file mode 100644
index b7513c2e4..000000000
--- a/b2g/branding/browserhtml/content/icon48.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/content/icon64.png b/b2g/branding/browserhtml/content/icon64.png
deleted file mode 100644
index c8bee8fca..000000000
--- a/b2g/branding/browserhtml/content/icon64.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/content/jar.mn b/b2g/branding/browserhtml/content/jar.mn
deleted file mode 100644
index 8a2c16964..000000000
--- a/b2g/branding/browserhtml/content/jar.mn
+++ /dev/null
@@ -1,10 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-chrome.jar:
-% content branding %content/branding/ contentaccessible=yes
- content/branding/about.png (about.png)
- content/branding/logoWordmark.png (logoWordmark.png)
- content/branding/logo.png (logo.png)
- content/branding/favicon32.png (favicon32.png)
diff --git a/b2g/branding/browserhtml/content/logo.png b/b2g/branding/browserhtml/content/logo.png
deleted file mode 100644
index 9d9d0c57e..000000000
--- a/b2g/branding/browserhtml/content/logo.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/content/logoWordmark.png b/b2g/branding/browserhtml/content/logoWordmark.png
deleted file mode 100644
index 878363181..000000000
--- a/b2g/branding/browserhtml/content/logoWordmark.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/content/moz.build b/b2g/branding/browserhtml/content/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/browserhtml/content/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/browserhtml/content/splash.png b/b2g/branding/browserhtml/content/splash.png
deleted file mode 100644
index 84ab581d2..000000000
--- a/b2g/branding/browserhtml/content/splash.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/default.png b/b2g/branding/browserhtml/default.png
deleted file mode 100644
index ae4736223..000000000
--- a/b2g/branding/browserhtml/default.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/disk.icns b/b2g/branding/browserhtml/disk.icns
deleted file mode 100644
index c49b7b878..000000000
--- a/b2g/branding/browserhtml/disk.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/dsstore b/b2g/branding/browserhtml/dsstore
deleted file mode 100644
index 657101d6e..000000000
--- a/b2g/branding/browserhtml/dsstore
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/browserhtml/locales/en-US/brand.dtd b/b2g/branding/browserhtml/locales/en-US/brand.dtd
deleted file mode 100644
index 6c3088d70..000000000
--- a/b2g/branding/browserhtml/locales/en-US/brand.dtd
+++ /dev/null
@@ -1,7 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!ENTITY brandShortName "Browser.html">
-<!ENTITY brandFullName "Mozilla Browser.html">
-<!ENTITY vendorShortName "Mozilla">
diff --git a/b2g/branding/browserhtml/locales/en-US/brand.properties b/b2g/branding/browserhtml/locales/en-US/brand.properties
deleted file mode 100644
index 897d1a800..000000000
--- a/b2g/branding/browserhtml/locales/en-US/brand.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-brandShortName=Browser.html
-brandFullName=Mozilla Browser.html
diff --git a/b2g/branding/browserhtml/locales/jar.mn b/b2g/branding/browserhtml/locales/jar.mn
deleted file mode 100644
index 2ea47e168..000000000
--- a/b2g/branding/browserhtml/locales/jar.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-#filter substitution
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-@AB_CD@.jar:
-% locale branding @AB_CD@ %locale/branding/
-# Branding only exists in en-US
- locale/branding/brand.dtd (en-US/brand.dtd)
- locale/branding/brand.properties (en-US/brand.properties)
diff --git a/b2g/branding/browserhtml/locales/moz.build b/b2g/branding/browserhtml/locales/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/browserhtml/locales/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/browserhtml/moz.build b/b2g/branding/browserhtml/moz.build
deleted file mode 100644
index bf7aff4c0..000000000
--- a/b2g/branding/browserhtml/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['content', 'locales']
-
-include('../branding-common.mozbuild')
-B2GBranding()
diff --git a/b2g/branding/horizon/app.icns b/b2g/branding/horizon/app.icns
deleted file mode 100644
index 6c7b9f5b5..000000000
--- a/b2g/branding/horizon/app.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/app.ico b/b2g/branding/horizon/app.ico
deleted file mode 100644
index 49eb90419..000000000
--- a/b2g/branding/horizon/app.ico
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/background.png b/b2g/branding/horizon/background.png
deleted file mode 100644
index db5576a33..000000000
--- a/b2g/branding/horizon/background.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/configure.sh b/b2g/branding/horizon/configure.sh
deleted file mode 100644
index 65774e384..000000000
--- a/b2g/branding/horizon/configure.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOZ_APP_DISPLAYNAME=Horizon
diff --git a/b2g/branding/horizon/content/about.png b/b2g/branding/horizon/content/about.png
deleted file mode 100644
index 3cc1444f6..000000000
--- a/b2g/branding/horizon/content/about.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/content/favicon32.png b/b2g/branding/horizon/content/favicon32.png
deleted file mode 100644
index ac4a6968b..000000000
--- a/b2g/branding/horizon/content/favicon32.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/content/icon48.png b/b2g/branding/horizon/content/icon48.png
deleted file mode 100644
index b7513c2e4..000000000
--- a/b2g/branding/horizon/content/icon48.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/content/icon64.png b/b2g/branding/horizon/content/icon64.png
deleted file mode 100644
index c8bee8fca..000000000
--- a/b2g/branding/horizon/content/icon64.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/content/jar.mn b/b2g/branding/horizon/content/jar.mn
deleted file mode 100644
index 8a2c16964..000000000
--- a/b2g/branding/horizon/content/jar.mn
+++ /dev/null
@@ -1,10 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-chrome.jar:
-% content branding %content/branding/ contentaccessible=yes
- content/branding/about.png (about.png)
- content/branding/logoWordmark.png (logoWordmark.png)
- content/branding/logo.png (logo.png)
- content/branding/favicon32.png (favicon32.png)
diff --git a/b2g/branding/horizon/content/logo.png b/b2g/branding/horizon/content/logo.png
deleted file mode 100644
index 9d9d0c57e..000000000
--- a/b2g/branding/horizon/content/logo.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/content/logoWordmark.png b/b2g/branding/horizon/content/logoWordmark.png
deleted file mode 100644
index 878363181..000000000
--- a/b2g/branding/horizon/content/logoWordmark.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/content/moz.build b/b2g/branding/horizon/content/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/horizon/content/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/horizon/content/splash.png b/b2g/branding/horizon/content/splash.png
deleted file mode 100644
index 84ab581d2..000000000
--- a/b2g/branding/horizon/content/splash.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/default.png b/b2g/branding/horizon/default.png
deleted file mode 100644
index 0e6a4016c..000000000
--- a/b2g/branding/horizon/default.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/disk.icns b/b2g/branding/horizon/disk.icns
deleted file mode 100644
index c49b7b878..000000000
--- a/b2g/branding/horizon/disk.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/dsstore b/b2g/branding/horizon/dsstore
deleted file mode 100644
index 657101d6e..000000000
--- a/b2g/branding/horizon/dsstore
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/horizon/locales/en-US/brand.dtd b/b2g/branding/horizon/locales/en-US/brand.dtd
deleted file mode 100644
index ad7a938b5..000000000
--- a/b2g/branding/horizon/locales/en-US/brand.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!ENTITY brandShortName "Horizon">
-<!ENTITY brandFullName "Mozilla Horizon">
-<!ENTITY vendorShortName "Mozilla">
-<!ENTITY logoTrademark "Horizon and the Horizon logos are trademarks of the Mozilla Foundation.">
diff --git a/b2g/branding/horizon/locales/en-US/brand.properties b/b2g/branding/horizon/locales/en-US/brand.properties
deleted file mode 100644
index ce9e209cf..000000000
--- a/b2g/branding/horizon/locales/en-US/brand.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-brandShortName=Horizon
-brandFullName=Mozilla Horizon
diff --git a/b2g/branding/horizon/locales/jar.mn b/b2g/branding/horizon/locales/jar.mn
deleted file mode 100644
index 2ea47e168..000000000
--- a/b2g/branding/horizon/locales/jar.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-#filter substitution
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-@AB_CD@.jar:
-% locale branding @AB_CD@ %locale/branding/
-# Branding only exists in en-US
- locale/branding/brand.dtd (en-US/brand.dtd)
- locale/branding/brand.properties (en-US/brand.properties)
diff --git a/b2g/branding/horizon/locales/moz.build b/b2g/branding/horizon/locales/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/horizon/locales/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/horizon/moz.build b/b2g/branding/horizon/moz.build
deleted file mode 100644
index bf7aff4c0..000000000
--- a/b2g/branding/horizon/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['content', 'locales']
-
-include('../branding-common.mozbuild')
-B2GBranding()
diff --git a/b2g/branding/official/app.icns b/b2g/branding/official/app.icns
deleted file mode 100644
index eba850aae..000000000
--- a/b2g/branding/official/app.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/app.ico b/b2g/branding/official/app.ico
deleted file mode 100644
index 5d4a61dc9..000000000
--- a/b2g/branding/official/app.ico
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/background.png b/b2g/branding/official/background.png
deleted file mode 100644
index db5576a33..000000000
--- a/b2g/branding/official/background.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/configure.sh b/b2g/branding/official/configure.sh
deleted file mode 100644
index 127a0f1a1..000000000
--- a/b2g/branding/official/configure.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOZ_APP_DISPLAYNAME=B2G
-MOZ_UPDATER=
diff --git a/b2g/branding/official/content/about.png b/b2g/branding/official/content/about.png
deleted file mode 100644
index 3cc1444f6..000000000
--- a/b2g/branding/official/content/about.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/content/favicon32.png b/b2g/branding/official/content/favicon32.png
deleted file mode 100644
index ac4a6968b..000000000
--- a/b2g/branding/official/content/favicon32.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/content/icon48.png b/b2g/branding/official/content/icon48.png
deleted file mode 100644
index b7513c2e4..000000000
--- a/b2g/branding/official/content/icon48.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/content/icon64.png b/b2g/branding/official/content/icon64.png
deleted file mode 100644
index c8bee8fca..000000000
--- a/b2g/branding/official/content/icon64.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/content/jar.mn b/b2g/branding/official/content/jar.mn
deleted file mode 100644
index 8a2c16964..000000000
--- a/b2g/branding/official/content/jar.mn
+++ /dev/null
@@ -1,10 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-chrome.jar:
-% content branding %content/branding/ contentaccessible=yes
- content/branding/about.png (about.png)
- content/branding/logoWordmark.png (logoWordmark.png)
- content/branding/logo.png (logo.png)
- content/branding/favicon32.png (favicon32.png)
diff --git a/b2g/branding/official/content/logo.png b/b2g/branding/official/content/logo.png
deleted file mode 100644
index 9d9d0c57e..000000000
--- a/b2g/branding/official/content/logo.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/content/logoWordmark.png b/b2g/branding/official/content/logoWordmark.png
deleted file mode 100644
index 878363181..000000000
--- a/b2g/branding/official/content/logoWordmark.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/content/moz.build b/b2g/branding/official/content/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/official/content/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/official/content/splash.png b/b2g/branding/official/content/splash.png
deleted file mode 100644
index 84ab581d2..000000000
--- a/b2g/branding/official/content/splash.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/default.png b/b2g/branding/official/default.png
deleted file mode 100644
index c4307fc84..000000000
--- a/b2g/branding/official/default.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/disk.icns b/b2g/branding/official/disk.icns
deleted file mode 100644
index c49b7b878..000000000
--- a/b2g/branding/official/disk.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/dsstore b/b2g/branding/official/dsstore
deleted file mode 100644
index 657101d6e..000000000
--- a/b2g/branding/official/dsstore
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/official/locales/en-US/brand.dtd b/b2g/branding/official/locales/en-US/brand.dtd
deleted file mode 100644
index 1a6f39148..000000000
--- a/b2g/branding/official/locales/en-US/brand.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!ENTITY brandShortName "Firefox">
-<!ENTITY brandFullName "Mozilla Firefox">
-<!ENTITY vendorShortName "Mozilla">
-<!ENTITY logoTrademark "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
diff --git a/b2g/branding/official/locales/en-US/brand.properties b/b2g/branding/official/locales/en-US/brand.properties
deleted file mode 100644
index d0203e35a..000000000
--- a/b2g/branding/official/locales/en-US/brand.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-brandShortName=Firefox
-brandFullName=Mozilla Firefox
diff --git a/b2g/branding/official/locales/jar.mn b/b2g/branding/official/locales/jar.mn
deleted file mode 100644
index 2ea47e168..000000000
--- a/b2g/branding/official/locales/jar.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-#filter substitution
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-@AB_CD@.jar:
-% locale branding @AB_CD@ %locale/branding/
-# Branding only exists in en-US
- locale/branding/brand.dtd (en-US/brand.dtd)
- locale/branding/brand.properties (en-US/brand.properties)
diff --git a/b2g/branding/official/locales/moz.build b/b2g/branding/official/locales/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/official/locales/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/official/moz.build b/b2g/branding/official/moz.build
deleted file mode 100644
index bf7aff4c0..000000000
--- a/b2g/branding/official/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['content', 'locales']
-
-include('../branding-common.mozbuild')
-B2GBranding()
diff --git a/b2g/branding/unofficial/app.icns b/b2g/branding/unofficial/app.icns
deleted file mode 100644
index eba850aae..000000000
--- a/b2g/branding/unofficial/app.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/app.ico b/b2g/branding/unofficial/app.ico
deleted file mode 100644
index 5d4a61dc9..000000000
--- a/b2g/branding/unofficial/app.ico
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/background.png b/b2g/branding/unofficial/background.png
deleted file mode 100644
index db5576a33..000000000
--- a/b2g/branding/unofficial/background.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/configure.sh b/b2g/branding/unofficial/configure.sh
deleted file mode 100644
index 127a0f1a1..000000000
--- a/b2g/branding/unofficial/configure.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOZ_APP_DISPLAYNAME=B2G
-MOZ_UPDATER=
diff --git a/b2g/branding/unofficial/content/about.png b/b2g/branding/unofficial/content/about.png
deleted file mode 100644
index 3819f6337..000000000
--- a/b2g/branding/unofficial/content/about.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/content/favicon32.png b/b2g/branding/unofficial/content/favicon32.png
deleted file mode 100644
index 3f04acd50..000000000
--- a/b2g/branding/unofficial/content/favicon32.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/content/icon48.png b/b2g/branding/unofficial/content/icon48.png
deleted file mode 100644
index 3ae248c85..000000000
--- a/b2g/branding/unofficial/content/icon48.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/content/icon64.png b/b2g/branding/unofficial/content/icon64.png
deleted file mode 100644
index fe980153b..000000000
--- a/b2g/branding/unofficial/content/icon64.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/content/jar.mn b/b2g/branding/unofficial/content/jar.mn
deleted file mode 100644
index 8a2c16964..000000000
--- a/b2g/branding/unofficial/content/jar.mn
+++ /dev/null
@@ -1,10 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-chrome.jar:
-% content branding %content/branding/ contentaccessible=yes
- content/branding/about.png (about.png)
- content/branding/logoWordmark.png (logoWordmark.png)
- content/branding/logo.png (logo.png)
- content/branding/favicon32.png (favicon32.png)
diff --git a/b2g/branding/unofficial/content/logo.png b/b2g/branding/unofficial/content/logo.png
deleted file mode 100644
index 91377a312..000000000
--- a/b2g/branding/unofficial/content/logo.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/content/logoWordmark.png b/b2g/branding/unofficial/content/logoWordmark.png
deleted file mode 100644
index a3017f59e..000000000
--- a/b2g/branding/unofficial/content/logoWordmark.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/content/moz.build b/b2g/branding/unofficial/content/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/unofficial/content/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/unofficial/content/splash.png b/b2g/branding/unofficial/content/splash.png
deleted file mode 100644
index 25a0830ea..000000000
--- a/b2g/branding/unofficial/content/splash.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/default.png b/b2g/branding/unofficial/default.png
deleted file mode 100644
index c4307fc84..000000000
--- a/b2g/branding/unofficial/default.png
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/disk.icns b/b2g/branding/unofficial/disk.icns
deleted file mode 100644
index c49b7b878..000000000
--- a/b2g/branding/unofficial/disk.icns
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/dsstore b/b2g/branding/unofficial/dsstore
deleted file mode 100644
index 657101d6e..000000000
--- a/b2g/branding/unofficial/dsstore
+++ /dev/null
Binary files differ
diff --git a/b2g/branding/unofficial/locales/en-US/brand.dtd b/b2g/branding/unofficial/locales/en-US/brand.dtd
deleted file mode 100644
index 1a6f39148..000000000
--- a/b2g/branding/unofficial/locales/en-US/brand.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!ENTITY brandShortName "Firefox">
-<!ENTITY brandFullName "Mozilla Firefox">
-<!ENTITY vendorShortName "Mozilla">
-<!ENTITY logoTrademark "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
diff --git a/b2g/branding/unofficial/locales/en-US/brand.properties b/b2g/branding/unofficial/locales/en-US/brand.properties
deleted file mode 100644
index d0203e35a..000000000
--- a/b2g/branding/unofficial/locales/en-US/brand.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-brandShortName=Firefox
-brandFullName=Mozilla Firefox
diff --git a/b2g/branding/unofficial/locales/jar.mn b/b2g/branding/unofficial/locales/jar.mn
deleted file mode 100644
index 5a77695c9..000000000
--- a/b2g/branding/unofficial/locales/jar.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-#filter substitution
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-@AB_CD@.jar:
-% locale branding @AB_CD@ %locale/branding/
-# Nightly branding only exists in en-US
- locale/branding/brand.dtd (en-US/brand.dtd)
- locale/branding/brand.properties (en-US/brand.properties)
diff --git a/b2g/branding/unofficial/locales/moz.build b/b2g/branding/unofficial/locales/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/branding/unofficial/locales/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/branding/unofficial/moz.build b/b2g/branding/unofficial/moz.build
deleted file mode 100644
index bf7aff4c0..000000000
--- a/b2g/branding/unofficial/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['content', 'locales']
-
-include('../branding-common.mozbuild')
-B2GBranding()
diff --git a/b2g/build.mk b/b2g/build.mk
deleted file mode 100644
index 31e20b580..000000000
--- a/b2g/build.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
-
-installer:
- @$(MAKE) -C b2g/installer installer
-
-package:
- @$(MAKE) -C b2g/installer
-
-install::
- @echo 'B2G can't be installed directly.'
- @exit 1
-
-upload::
- @$(MAKE) -C b2g/installer upload
-
-ifdef ENABLE_TESTS
-# Implemented in testing/testsuite-targets.mk
-
-mochitest-browser-chrome:
- $(RUN_MOCHITEST) --flavor=browser
- $(CHECK_TEST_ERROR)
-
-mochitest:: mochitest-browser-chrome
-
-.PHONY: mochitest-browser-chrome
-endif
-
diff --git a/b2g/chrome/content/ErrorPage.js b/b2g/chrome/content/ErrorPage.js
deleted file mode 100644
index d51782466..000000000
--- a/b2g/chrome/content/ErrorPage.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-var Cu = Components.utils;
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-
-dump("############ ErrorPage.js\n");
-
-var ErrorPageHandler = {
- _reload: function() {
- docShell.QueryInterface(Ci.nsIWebNavigation).reload(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
- },
-
- _certErrorPageEventHandler: function(e) {
- let target = e.originalTarget;
- let errorDoc = target.ownerDocument;
-
- // If the event came from an ssl error page, it is one of the "Add
- // Exception…" buttons.
- if (/^about:certerror\?e=nssBadCert/.test(errorDoc.documentURI)) {
- let permanent = errorDoc.getElementById("permanentExceptionButton");
- let temp = errorDoc.getElementById("temporaryExceptionButton");
- if (target == temp || target == permanent) {
- sendAsyncMessage("ErrorPage:AddCertException", {
- url: errorDoc.location.href,
- isPermanent: target == permanent
- });
- }
- }
- },
-
- _bindPageEvent: function(target) {
- if (!target) {
- return;
- }
-
- if (/^about:certerror/.test(target.documentURI)) {
- let errorPageEventHandler = this._certErrorPageEventHandler.bind(this);
- addEventListener("click", errorPageEventHandler, true, false);
- let listener = function() {
- removeEventListener("click", errorPageEventHandler, true);
- removeEventListener("pagehide", listener, true);
- }.bind(this);
-
- addEventListener("pagehide", listener, true);
- }
- },
-
- domContentLoadedHandler: function(e) {
- let target = e.originalTarget;
- let targetDocShell = target.defaultView
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation);
- if (targetDocShell != docShell) {
- return;
- }
- this._bindPageEvent(target);
- },
-
- init: function() {
- addMessageListener("ErrorPage:ReloadPage", this._reload.bind(this));
- addEventListener('DOMContentLoaded',
- this.domContentLoadedHandler.bind(this),
- true);
- this._bindPageEvent(content.document);
- }
-};
-
-ErrorPageHandler.init();
diff --git a/b2g/chrome/content/aboutCertError.xhtml b/b2g/chrome/content/aboutCertError.xhtml
deleted file mode 100644
index 616657e54..000000000
--- a/b2g/chrome/content/aboutCertError.xhtml
+++ /dev/null
@@ -1,233 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html [
- <!ENTITY % htmlDTD
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "DTD/xhtml1-strict.dtd">
- %htmlDTD;
- <!ENTITY % globalDTD
- SYSTEM "chrome://global/locale/global.dtd">
- %globalDTD;
- <!ENTITY % certerrorDTD
- SYSTEM "chrome://b2g-l10n/locale/aboutCertError.dtd">
- %certerrorDTD;
-]>
-
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>&certerror.pagetitle;</title>
- <meta name="viewport" content="width=device-width; user-scalable=false" />
- <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
- <!-- This page currently uses the same favicon as neterror.xhtml.
- If the location of the favicon is changed for both pages, the
- FAVICON_ERRORPAGE_URL symbol in toolkit/components/places/src/nsFaviconService.h
- should be updated. If this page starts using a different favicon
- than neterrorm nsFaviconService->SetAndLoadFaviconForPage
- should be updated to ignore this one as well. -->
- <link rel="icon" type="image/png" id="favicon" sizes="64x64" href="chrome://global/skin/icons/warning-64.png"/>
-
- <script type="application/javascript"><![CDATA[
- // Error url MUST be formatted like this:
- // about:certerror?e=error&u=url&d=desc
-
- // Note that this file uses document.documentURI to get
- // the URL (with the format from above). This is because
- // document.location.href gets the current URI off the docshell,
- // which is the URL displayed in the location bar, i.e.
- // the URI that the user attempted to load.
-
- function getCSSClass()
- {
- var url = document.documentURI;
- var matches = url.match(/s\=([^&]+)\&/);
- // s is optional, if no match just return nothing
- if (!matches || matches.length < 2)
- return "";
-
- // parenthetical match is the second entry
- return decodeURIComponent(matches[1]);
- }
-
- function getDescription()
- {
- var url = document.documentURI;
- var desc = url.search(/d\=/);
-
- // desc == -1 if not found; if so, return an empty string
- // instead of what would turn out to be portions of the URI
- if (desc == -1)
- return "";
-
- return decodeURIComponent(url.slice(desc + 2));
- }
-
- function initPage()
- {
- // Replace the "#1" string in the intro with the hostname. Trickier
- // than it might seem since we want to preserve the <b> tags, but
- // not allow for any injection by just using innerHTML. Instead,
- // just find the right target text node.
- var intro = document.getElementById('introContentP1');
- function replaceWithHost(node) {
- if (node.textContent == "#1")
- node.textContent = location.host;
- else
- for(var i = 0; i < node.childNodes.length; i++)
- replaceWithHost(node.childNodes[i]);
- };
- replaceWithHost(intro);
-
- if (getCSSClass() == "expertBadCert") {
- toggle('technicalContent');
- toggle('expertContent');
- }
-
- var tech = document.getElementById("technicalContentText");
- if (tech)
- tech.textContent = getDescription();
-
- addDomainErrorLink();
- }
-
- /* In the case of SSL error pages about domain mismatch, see if
- we can hyperlink the user to the correct site. We don't want
- to do this generically since it allows MitM attacks to redirect
- users to a site under attacker control, but in certain cases
- it is safe (and helpful!) to do so. Bug 402210
- */
- function addDomainErrorLink() {
- // Rather than textContent, we need to treat description as HTML
- var sd = document.getElementById("technicalContentText");
- if (sd) {
- var desc = getDescription();
-
- // sanitize description text - see bug 441169
-
- // First, find the index of the <a> tag we care about, being careful not to
- // use an over-greedy regex
- var re = /<a id="cert_domain_link" title="([^"]+)">/;
- var result = re.exec(desc);
- if(!result)
- return;
-
- // Remove sd's existing children
- sd.textContent = "";
-
- // Everything up to the link should be text content
- sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
-
- // Now create the link itself
- var anchorEl = document.createElement("a");
- anchorEl.setAttribute("id", "cert_domain_link");
- anchorEl.setAttribute("title", result[1]);
- anchorEl.appendChild(document.createTextNode(result[1]));
- sd.appendChild(anchorEl);
-
- // Finally, append text for anything after the closing </a>
- sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length)));
- }
-
- var link = document.getElementById('cert_domain_link');
- if (!link)
- return;
-
- var okHost = link.getAttribute("title");
- var thisHost = document.location.hostname;
- var proto = document.location.protocol;
-
- // If okHost is a wildcard domain ("*.example.com") let's
- // use "www" instead. "*.example.com" isn't going to
- // get anyone anywhere useful. bug 432491
- okHost = okHost.replace(/^\*\./, "www.");
-
- /* case #1:
- * example.com uses an invalid security certificate.
- *
- * The certificate is only valid for www.example.com
- *
- * Make sure to include the "." ahead of thisHost so that
- * a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
- *
- * We'd normally just use a RegExp here except that we lack a
- * library function to escape them properly (bug 248062), and
- * domain names are famous for having '.' characters in them,
- * which would allow spurious and possibly hostile matches.
- */
- if (endsWith(okHost, "." + thisHost))
- link.href = proto + okHost;
-
- /* case #2:
- * browser.garage.maemo.org uses an invalid security certificate.
- *
- * The certificate is only valid for garage.maemo.org
- */
- if (endsWith(thisHost, "." + okHost))
- link.href = proto + okHost;
-
- // If we set a link, meaning there's something helpful for
- // the user here, expand the section by default
- if (link.href && getCSSClass() != "expertBadCert")
- toggle("technicalContent");
- }
-
- function endsWith(haystack, needle) {
- return haystack.slice(-needle.length) == needle;
- }
-
- function toggle(id) {
- var el = document.getElementById(id);
- if (el.getAttribute("collapsed"))
- el.setAttribute("collapsed", false);
- else
- el.setAttribute("collapsed", true);
- }
- ]]></script>
- </head>
-
- <body id="errorPage" class="certerror" dir="&locale.dir;">
-
- <!-- Error Title -->
- <div id="errorTitle">
- <h1 class="errorTitleText">&certerror.longpagetitle;</h1>
- </div>
-
- <!-- PAGE CONTAINER (for styling purposes only) -->
- <div id="errorPageContainer">
-
- <!-- LONG CONTENT (the section most likely to require scrolling) -->
- <div id="errorLongContent">
- <div id="introContent">
- <p id="introContentP1">&certerror.introPara1;</p>
- </div>
-
- <!-- The following sections can be unhidden by default by setting the
- "browser.xul.error_pages.expert_bad_cert" pref to true -->
- <div id="technicalContent" collapsed="true">
- <h2 onclick="toggle('technicalContent');" id="technicalContentHeading">&certerror.technical.heading;</h2>
- <p id="technicalContentText"/>
- </div>
-
- <div id="expertContent" collapsed="true">
- <h2 onclick="toggle('expertContent');" id="expertContentHeading">&certerror.expert.heading;</h2>
- <div>
- <p>&certerror.expert.content;</p>
- <p>&certerror.expert.contentPara2;</p>
- <button id="temporaryExceptionButton">&certerror.addTemporaryException.label;</button>
- <button id="permanentExceptionButton">&certerror.addPermanentException.label;</button>
- </div>
- </div>
- </div>
- </div>
-
- <!--
- - Note: It is important to run the script this way, instead of using
- - an onload handler. This is because error pages are loaded as
- - LOAD_BACKGROUND, which means that onload handlers will not be executed.
- -->
- <script type="application/javascript">initPage();</script>
-
- </body>
-</html>
diff --git a/b2g/chrome/content/arrow.svg b/b2g/chrome/content/arrow.svg
deleted file mode 100644
index d3d9e8246..000000000
--- a/b2g/chrome/content/arrow.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-
-<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="11px" style="position: absolute; top: -moz-calc(50% - 2px);">
- <polyline points="1 1 5 6 9 1" stroke="#414141" stroke-width="2" stroke-linecap="round" fill="transparent" stroke-linejoin="round"/>
-</svg>
diff --git a/b2g/chrome/content/blank.css b/b2g/chrome/content/blank.css
deleted file mode 100644
index 71914be1f..000000000
--- a/b2g/chrome/content/blank.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-body {
- background: black;
-}
diff --git a/b2g/chrome/content/blank.html b/b2g/chrome/content/blank.html
deleted file mode 100644
index b8b20e2c6..000000000
--- a/b2g/chrome/content/blank.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this file,
- - You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<html>
- <head>
- <link rel="stylesheet" href="blank.css" type="text/css" media="all" />
- </head>
-</html>
diff --git a/b2g/chrome/content/content.css b/b2g/chrome/content/content.css
deleted file mode 100644
index bb478087e..000000000
--- a/b2g/chrome/content/content.css
+++ /dev/null
@@ -1,321 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@namespace url("http://www.w3.org/1999/xhtml");
-@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-/* Style the scrollbars */
-xul|window xul|scrollbar {
- display: none;
-}
-
-/* Bug 1041576 - Scrollable with scrollgrab should not have scrollbars */
-
-@-moz-document domain(system.gaiamobile.org) {
- .browser-container > xul|scrollbar {
- display: none;
- }
-}
-
-%ifdef MOZ_GRAPHENE
-.moz-noscrollbars > xul|scrollbar {
- display: none;
-}
-%endif
-
-xul|scrollbar[root="true"] {
- position: relative;
- z-index: 2147483647;
-}
-
-xul|scrollbar {
- -moz-appearance: none !important;
- background-color: transparent !important;
- background-image: none !important;
- border: 0px solid transparent !important;
- pointer-events: none;
-}
-
-/* Scrollbar code will reset the margin to the correct side depending on
- where layout actually puts the scrollbar */
-xul|scrollbar[orient="vertical"] {
- margin-left: -8px;
- min-width: 8px;
- max-width: 8px;
-}
-
-xul|scrollbar[orient="vertical"] xul|thumb {
- max-width: 6px !important;
- min-width: 6px !important;
-}
-
-xul|scrollbar[orient="horizontal"] {
- margin-top: -8px;
- min-height: 8px;
- max-height: 8px;
-}
-
-xul|scrollbar[orient="horizontal"] xul|thumb {
- max-height: 6px !important;
- min-height: 6px !important;
-}
-
-xul|scrollbar:not([active="true"]),
-xul|scrollbar[disabled] {
- opacity: 0;
-}
-
-xul|scrollbarbutton {
- min-height: 8px !important;
- min-width: 8px !important;
- -moz-appearance: none !important;
- visibility: hidden;
-}
-
-xul|scrollbarbutton[sbattr="scrollbar-up-top"],
-xul|scrollbarbutton[sbattr="scrollbar-bottom-top"] {
- display: none;
-}
-
-xul|thumb {
- background-color: rgba(0, 0, 0, 0.4) !important;
- -moz-border-top-colors: none !important;
- -moz-border-bottom-colors: none !important;
- -moz-border-right-colors: none !important;
- -moz-border-left-colors: none !important;
- border: 1px solid rgba(255, 255, 255, 0.4) !important;
- border-radius: 3px;
-}
-
-xul|scrollbarbutton {
- background-image: none !important;
-}
-
-%ifndef MOZ_GRAPHENE
-/* -moz-touch-enabled? media elements */
-:-moz-any(video, audio) > xul|videocontrols {
- -moz-binding: url("chrome://global/content/bindings/videocontrols.xml#touchControlsGonk");
-}
-
-select:not([size]):not([multiple]) > xul|scrollbar,
-select[size="1"] > xul|scrollbar,
-select:not([size]):not([multiple]) xul|scrollbarbutton,
-select[size="1"] xul|scrollbarbutton {
- display: block;
- margin-left: 0;
- min-width: 16px;
-}
-
-/* Override inverse OS themes */
-select,
-textarea,
-button,
-xul|button,
-* > input:not([type="image"]) {
- -moz-appearance: none !important; /* See bug 598421 for fixing the platform */
- border-radius: 3px;
-}
-
-select[size],
-select[multiple],
-select[size][multiple],
-textarea,
-* > input:not([type="image"]) {
- border-style: solid;
- border-color: #7d7d7d;
- color: #414141;
- background-color: white;
-}
-
-/* Selects are handled by the form helper, see bug 685197 */
-select option, select optgroup {
- pointer-events: none;
-}
-
-select:not([size]):not([multiple]),
-select[size="0"],
-select[size="1"],
-* > input[type="button"],
-* > input[type="submit"],
-* > input[type="reset"],
-button {
- border-style: solid;
- border-color: #7d7d7d;
- color: #414141;
- background: white linear-gradient(rgba(255,255,255,0.2) 0, rgba(215,215,215,0.5) 18px, rgba(115,115,115,0.5) 100%);
-}
-
-input[type="checkbox"] {
- background-color: white;
-}
-
-input[type="radio"] {
- background-color: white;
-}
-
-select {
- border-width: 1px;
- padding: 1px;
-}
-
-select:not([size]):not([multiple]),
-select[size="0"],
-select[size="1"] {
- padding: 0 1px 0 1px;
-}
-
-* > input:not([type="image"]) {
- border-width: 1px;
- padding: 1px;
-}
-
-textarea {
- resize: none;
- border-width: 1px;
- padding-inline-start: 1px;
- padding-inline-end: 1px;
- padding-block-start: 2px;
- padding-block-end: 2px;
-}
-
-input[type="button"],
-input[type="submit"],
-input[type="reset"],
-button {
- border-width: 1px;
- padding-inline-start: 7px;
- padding-inline-end: 7px;
- padding-block-start: 0;
- padding-block-end: 0;
-}
-
-input[type="radio"],
-input[type="checkbox"] {
- border: 1px solid #a7a7a7 !important;
- padding-inline-start: 1px;
- padding-inline-end: 1px;
- padding-block-start: 2px;
- padding-block-end: 2px;
-}
-
-select > button {
- border-width: 0px !important;
- margin: 0px !important;
- padding: 0px !important;
- border-radius: 0;
- color: #414141;
-
- background-image: radial-gradient(at bottom left, #bbbbbb 40%, #f5f5f5), url(arrow.svg) !important;
- background-color: transparent;
- background-position: -15px center, 4px center !important;
- background-repeat: no-repeat, no-repeat !important;
- background-size: 100% 90%, auto auto;
-
- -moz-binding: none !important;
- position: relative !important;
- font-size: inherit;
-}
-
-select[size]:focus,
-select[multiple]:focus,
-select[size][multiple]:focus,
-textarea:focus,
-input[type="file"]:focus > input[type="text"],
-* > input:not([type="image"]):focus {
- outline: 0px !important;
- border-style: solid;
- border-color: rgb(94,128,153);
- background-color: white;
-}
-
-select:not([size]):not([multiple]):focus,
-select[size="0"]:focus,
-select[size="1"]:focus,
-input[type="button"]:focus,
-input[type="submit"]:focus,
-input[type="reset"]:focus,
-button:focus {
- outline: 0px !important;
- border-style: solid;
- border-color: rgb(94,128,153);
- background: white linear-gradient(rgba(255,255,255,0.2) 0, rgba(198,225,256,0.2) 18px, rgba(27,113,177,0.5) 100%);
-}
-
-input[type="checkbox"]:focus,
-input[type="radio"]:focus {
- border-color: #99c6e0 !important;
-}
-
-/* we need to be specific for selects because the above rules are specific too */
-textarea[disabled],
-select[size][disabled],
-select[multiple][disabled],
-select[size][multiple][disabled],
-select:not([size]):not([multiple])[disabled],
-select[size="0"][disabled],
-select[size="1"][disabled],
-button[disabled],
-* > input:not([type="image"])[disabled] {
- color: rgba(0,0,0,0.3);
- border-color: rgba(125,125,125,0.4);
- border-style: solid;
- border-width: 1px;
- background-color: #f5f5f5;
-}
-
-select:not([size]):not([multiple])[disabled],
-select[size="0"][disabled],
-select[size="1"][disabled] {
- background-color: #f5f5f5;
-}
-
-input[type="button"][disabled],
-input[type="submit"][disabled],
-input[type="reset"][disabled],
-button[disabled] {
- padding-inline-start: 7px;
- padding-inline-end: 7px;
- padding-block-start: 0;
- padding-block-end: 0;
- background-color: #f5f5f5;
-}
-
-input[type="radio"][disabled],
-input[type="radio"][disabled]:active,
-input[type="radio"][disabled]:hover,
-input[type="radio"][disabled]:hover:active,
-input[type="checkbox"][disabled],
-input[type="checkbox"][disabled]:active,
-input[type="checkbox"][disabled]:hover,
-input[type="checkbox"][disabled]:hover:active {
- border:1px solid rgba(125,125,125,0.4) !important;
-}
-
-select[disabled] > button {
- opacity: 0.6;
- padding: 1px 7px 1px 7px;
-}
-
-*:any-link:active,
-*[role=button]:active,
-button:active,
-option:active,
-select:active,
-label:active {
- background-color: rgba(141, 184, 216, 0.5);
-}
-
-input[type=number] > div > div, /* work around bug 946184 */
-input[type=number]::-moz-number-spin-box {
- display: none;
-}
-%endif
-
-%ifdef MOZ_WIDGET_GONK
-/* This binding only provide key shortcuts that we can't use on devices */
-input,
-textarea {
--moz-binding: none !important;
-}
-%endif
diff --git a/b2g/chrome/content/desktop.css b/b2g/chrome/content/desktop.css
deleted file mode 100644
index 9612d732c..000000000
--- a/b2g/chrome/content/desktop.css
+++ /dev/null
@@ -1,59 +0,0 @@
-#controls {
- position: absolute;
- left: 0;
- bottom:0;
- right: 0;
- height: 30px;
- background-color: -moz-dialog;
-}
-
-#home-button {
- margin: auto;
- margin-top: 3px;
- width: 24px;
- height: 24px;
- background: #eee url("images/desktop/home-black.png") center no-repeat;
- border: 1px solid #888;
- border-radius: 12px;
- display: block;
-}
-
-#home-button::-moz-focus-inner {
- padding: 0;
- border: 0;
-}
-
-#home-button:hover {
- background-image: url("images/desktop/home-white.png");
- background-color: #ccc;
- border-color: #555;
-}
-
-#home-button.active {
- background-image: url("images/desktop/home-white.png");
- background-color: #888;
- border-color: black;
-}
-
-#rotate-button {
- position: absolute;
- top: 3px;
- bottom: 3px;
- right: 3px;
- width: 24px;
- height: 24px;
- background: #eee url("images/desktop/rotate.png") center no-repeat;
- border: 1px solid #888;
- border-radius: 12px;
- display: block;
-}
-
-#rotate-button:hover {
- background-color: #ccc;
- border-color: #555;
-}
-
-#rotate-button.active {
- background-color: #888;
- border-color: black;
-}
diff --git a/b2g/chrome/content/desktop.js b/b2g/chrome/content/desktop.js
deleted file mode 100644
index 5a1e7ff04..000000000
--- a/b2g/chrome/content/desktop.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
-var isMulet = "ResponsiveUI" in browserWindow;
-
-// Enable touch event shim on desktop that translates mouse events
-// into touch ones
-function enableTouch() {
- let require = Cu.import('resource://devtools/shared/Loader.jsm', {})
- .devtools.require;
- let { TouchEventSimulator } = require('devtools/shared/touch/simulator');
- let touchEventSimulator = new TouchEventSimulator(shell.contentBrowser);
- touchEventSimulator.start();
-}
-
-// Some additional buttons are displayed on simulators to fake hardware buttons.
-function setupButtons() {
- let link = document.createElement('link');
- link.type = 'text/css';
- link.rel = 'stylesheet';
- link.href = 'chrome://b2g/content/desktop.css';
- document.head.appendChild(link);
-
- let footer = document.createElement('footer');
- footer.id = 'controls';
- document.body.appendChild(footer);
- let homeButton = document.createElement('button');
- homeButton.id = 'home-button';
- footer.appendChild(homeButton);
- let rotateButton = document.createElement('button');
- rotateButton.id = 'rotate-button';
- footer.appendChild(rotateButton);
-
- homeButton.addEventListener('mousedown', function() {
- let window = shell.contentBrowser.contentWindow;
- let e = new window.KeyboardEvent('keydown', {key: 'Home'});
- window.dispatchEvent(e);
- homeButton.classList.add('active');
- });
- homeButton.addEventListener('mouseup', function() {
- let window = shell.contentBrowser.contentWindow;
- let e = new window.KeyboardEvent('keyup', {key: 'Home'});
- window.dispatchEvent(e);
- homeButton.classList.remove('active');
- });
-
- Cu.import("resource://gre/modules/GlobalSimulatorScreen.jsm");
- rotateButton.addEventListener('mousedown', function() {
- rotateButton.classList.add('active');
- });
- rotateButton.addEventListener('mouseup', function() {
- GlobalSimulatorScreen.flipScreen();
- rotateButton.classList.remove('active');
- });
-}
-
-function setupStorage() {
- let directory = null;
-
- // Get the --storage-path argument from the command line.
- try {
- let service = Cc['@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds'].getService(Ci.nsISupports);
- let args = service.wrappedJSObject.cmdLine;
- if (args) {
- let path = args.handleFlagWithParam('storage-path', false);
- directory = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- directory.initWithPath(path);
- }
- } catch(e) {
- directory = null;
- }
-
- // Otherwise, default to 'storage' folder within current profile.
- if (!directory) {
- directory = Services.dirsvc.get('ProfD', Ci.nsIFile);
- directory.append('storage');
- if (!directory.exists()) {
- directory.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("755", 8));
- }
- }
- dump("Set storage path to: " + directory.path + "\n");
-
- // This is the magic, where we override the default location for the storages.
- Services.prefs.setCharPref('device.storage.overrideRootDir', directory.path);
-}
-
-function checkDebuggerPort() {
- // XXX: To be removed once bug 942756 lands.
- // We are hacking 'unix-domain-socket' pref by setting a tcp port (number).
- // SocketListener.open detects that it isn't a file path (string), and starts
- // listening on the tcp port given here as command line argument.
-
- // Get the command line arguments that were passed to the b2g client
- let args;
- try {
- let service = Cc["@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds"].getService(Ci.nsISupports);
- args = service.wrappedJSObject.cmdLine;
- } catch(e) {}
-
- if (!args) {
- return;
- }
-
- let dbgport;
- try {
- dbgport = args.handleFlagWithParam('start-debugger-server', false);
- } catch(e) {}
-
- if (dbgport) {
- dump('Opening debugger server on ' + dbgport + '\n');
- Services.prefs.setCharPref('devtools.debugger.unix-domain-socket', dbgport);
- navigator.mozSettings.createLock().set(
- {'debugger.remote-mode': 'adb-devtools'});
- }
-}
-
-
-function initResponsiveDesign() {
- Cu.import('resource://devtools/client/responsivedesign/responsivedesign.jsm');
- ResponsiveUIManager.on('on', function(event, {tab:tab}) {
- let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
- let document = tab.ownerDocument;
-
- // Only tweak reponsive mode for shell.html tabs.
- if (tab.linkedBrowser.contentWindow != window) {
- return;
- }
-
- // Disable transition as they mess up with screen size handler
- responsive.transitionsEnabled = false;
-
- responsive.buildPhoneUI();
-
- responsive.rotatebutton.addEventListener('command', function (evt) {
- GlobalSimulatorScreen.flipScreen();
- evt.stopImmediatePropagation();
- evt.preventDefault();
- }, true);
-
- // Enable touch events
- responsive.enableTouch();
- });
-
-
- let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
- mgr.toggle(browserWindow, browserWindow.gBrowser.selectedTab);
-
-}
-
-function openDevtools() {
- // Open devtool panel while maximizing its size according to screen size
- Services.prefs.setIntPref('devtools.toolbox.sidebar.width',
- browserWindow.outerWidth - 550);
- Services.prefs.setCharPref('devtools.toolbox.host', 'side');
- let {gDevTools} = Cu.import('resource://devtools/client/framework/gDevTools.jsm', {});
- let {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
- let target = devtools.TargetFactory.forTab(browserWindow.gBrowser.selectedTab);
- gDevTools.showToolbox(target);
-}
-
-window.addEventListener('ContentStart', function() {
- // On Firefox Mulet, touch events are enabled within the responsive mode
- if (!isMulet) {
- enableTouch();
- }
- if (Services.prefs.getBoolPref('b2g.software-buttons')) {
- setupButtons();
- }
- checkDebuggerPort();
- setupStorage();
- // On Firefox mulet, we automagically enable the responsive mode
- // and show the devtools
- if (isMulet) {
- initResponsiveDesign(browserWindow);
- openDevtools();
- }
-});
diff --git a/b2g/chrome/content/devtools/adb.js b/b2g/chrome/content/devtools/adb.js
deleted file mode 100644
index cebc6696b..000000000
--- a/b2g/chrome/content/devtools/adb.js
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// This file is only loaded on Gonk to manage ADB state
-
-Components.utils.import("resource://gre/modules/FileUtils.jsm");
-
-const DEBUG = false;
-var debug = function(str) {
- dump("AdbController: " + str + "\n");
-}
-
-var AdbController = {
- locked: undefined,
- remoteDebuggerEnabled: undefined,
- lockEnabled: undefined,
- disableAdbTimer: null,
- disableAdbTimeoutHours: 12,
- umsActive: false,
-
- setLockscreenEnabled: function(value) {
- this.lockEnabled = value;
- DEBUG && debug("setLockscreenEnabled = " + this.lockEnabled);
- this.updateState();
- },
-
- setLockscreenState: function(value) {
- this.locked = value;
- DEBUG && debug("setLockscreenState = " + this.locked);
- this.updateState();
- },
-
- setRemoteDebuggerState: function(value) {
- this.remoteDebuggerEnabled = value;
- DEBUG && debug("setRemoteDebuggerState = " + this.remoteDebuggerEnabled);
- this.updateState();
- },
-
- startDisableAdbTimer: function() {
- if (this.disableAdbTimer) {
- this.disableAdbTimer.cancel();
- } else {
- this.disableAdbTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- try {
- this.disableAdbTimeoutHours =
- Services.prefs.getIntPref("b2g.adb.timeout-hours");
- } catch (e) {
- // This happens if the pref doesn't exist, in which case
- // disableAdbTimeoutHours will still be set to the default.
- }
- }
- if (this.disableAdbTimeoutHours <= 0) {
- DEBUG && debug("Timer to disable ADB not started due to zero timeout");
- return;
- }
-
- DEBUG && debug("Starting timer to disable ADB in " +
- this.disableAdbTimeoutHours + " hours");
- let timeoutMilliseconds = this.disableAdbTimeoutHours * 60 * 60 * 1000;
- this.disableAdbTimer.initWithCallback(this, timeoutMilliseconds,
- Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- stopDisableAdbTimer: function() {
- DEBUG && debug("Stopping timer to disable ADB");
- if (this.disableAdbTimer) {
- this.disableAdbTimer.cancel();
- this.disableAdbTimer = null;
- }
- },
-
- notify: function(aTimer) {
- if (aTimer == this.disableAdbTimer) {
- this.disableAdbTimer = null;
- // The following dump will be the last thing that shows up in logcat,
- // and will at least give the user a clue about why logcat was
- // disconnected, if the user happens to be using logcat.
- debug("ADB timer expired - disabling ADB\n");
- navigator.mozSettings.createLock().set(
- {'debugger.remote-mode': 'disabled'});
- }
- },
-
- updateState: function() {
- this.umsActive = false;
- },
-
- updateStateInternal: function() {
- DEBUG && debug("updateStateInternal: called");
-
- if (this.remoteDebuggerEnabled === undefined ||
- this.lockEnabled === undefined ||
- this.locked === undefined) {
- // Part of initializing the settings database will cause the observers
- // to trigger. We want to wait until both have been initialized before
- // we start changing ther adb state. Without this then we can wind up
- // toggling adb off and back on again (or on and back off again).
- //
- // For completeness, one scenario which toggles adb is using the unagi.
- // The unagi has adb enabled by default (prior to b2g starting). If you
- // have the phone lock disabled and remote debugging enabled, then we'll
- // receive an unlock event and an rde event. However at the time we
- // receive the unlock event we haven't yet received the rde event, so
- // we turn adb off momentarily, which disconnects a logcat that might
- // be running. Changing the defaults (in AdbController) just moves the
- // problem to a different phone, which has adb disabled by default and
- // we wind up turning on adb for a short period when we shouldn't.
- //
- // By waiting until both values are properly initialized, we avoid
- // turning adb on or off accidentally.
- DEBUG && debug("updateState: Waiting for all vars to be initialized");
- return;
- }
-
- // Check if we have a remote debugging session going on. If so, we won't
- // disable adb even if the screen is locked.
- let isDebugging = USBRemoteDebugger.isDebugging;
- DEBUG && debug("isDebugging=" + isDebugging);
-
- // If USB Mass Storage, USB tethering, or a debug session is active,
- // then we don't want to disable adb in an automatic fashion (i.e.
- // when the screen locks or due to timeout).
- let sysUsbConfig = libcutils.property_get("sys.usb.config").split(",");
- let usbFuncActive = this.umsActive || isDebugging;
- usbFuncActive |= (sysUsbConfig.indexOf("rndis") >= 0);
- usbFuncActive |= (sysUsbConfig.indexOf("mtp") >= 0);
-
- let enableAdb = this.remoteDebuggerEnabled &&
- (!(this.lockEnabled && this.locked) || usbFuncActive);
-
- let useDisableAdbTimer = true;
- try {
- if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) {
- // Marionette is enabled. Marionette requires that adb be on (and also
- // requires that remote debugging be off). The fact that marionette
- // is enabled also implies that we're doing a non-production build, so
- // we want adb enabled all of the time.
- enableAdb = true;
- useDisableAdbTimer = false;
- }
- } catch (e) {
- // This means that the pref doesn't exist. Which is fine. We just leave
- // enableAdb alone.
- }
-
- // Check wakelock to prevent adb from disconnecting when phone is locked
- let lockFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- lockFile.initWithPath('/sys/power/wake_lock');
- if(lockFile.exists()) {
- let foStream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- let coStream = Cc["@mozilla.org/intl/converter-input-stream;1"]
- .createInstance(Ci.nsIConverterInputStream);
- let str = {};
- foStream.init(lockFile, FileUtils.MODE_RDONLY, 0, 0);
- coStream.init(foStream, "UTF-8", 0, 0);
- coStream.readString(-1, str);
- coStream.close();
- foStream.close();
- let wakeLockContents = str.value.replace(/\n/, "");
- let wakeLockList = wakeLockContents.split(" ");
- if (wakeLockList.indexOf("adb") >= 0) {
- enableAdb = true;
- useDisableAdbTimer = false;
- DEBUG && debug("Keeping ADB enabled as ADB wakelock is present.");
- } else {
- DEBUG && debug("ADB wakelock not found.");
- }
- } else {
- DEBUG && debug("Wake_lock file not found.");
- }
-
- DEBUG && debug("updateState: enableAdb = " + enableAdb +
- " remoteDebuggerEnabled = " + this.remoteDebuggerEnabled +
- " lockEnabled = " + this.lockEnabled +
- " locked = " + this.locked +
- " usbFuncActive = " + usbFuncActive);
-
- // Configure adb.
- let currentConfig = libcutils.property_get("persist.sys.usb.config");
- let configFuncs = currentConfig.split(",");
- if (currentConfig == "" || currentConfig == "none") {
- // We want to treat none like the empty string.
- // "".split(",") yields [""] and not []
- configFuncs = [];
- }
- let adbIndex = configFuncs.indexOf("adb");
-
- if (enableAdb) {
- // Add adb to the list of functions, if not already present
- if (adbIndex < 0) {
- configFuncs.push("adb");
- }
- } else {
- // Remove adb from the list of functions, if present
- if (adbIndex >= 0) {
- configFuncs.splice(adbIndex, 1);
- }
- }
- let newConfig = configFuncs.join(",");
- if (newConfig == "") {
- // Convert the empty string back into none, since that's what init.rc
- // needs.
- newConfig = "none";
- }
- if (newConfig != currentConfig) {
- DEBUG && debug("updateState: currentConfig = " + currentConfig);
- DEBUG && debug("updateState: newConfig = " + newConfig);
- try {
- libcutils.property_set("persist.sys.usb.config", newConfig);
- } catch(e) {
- Cu.reportError("Error configuring adb: " + e);
- }
- }
- if (useDisableAdbTimer) {
- if (enableAdb && !usbFuncActive) {
- this.startDisableAdbTimer();
- } else {
- this.stopDisableAdbTimer();
- }
- }
- }
-};
-
-SettingsListener.observe("lockscreen.locked", false,
- AdbController.setLockscreenState.bind(AdbController));
-SettingsListener.observe("lockscreen.enabled", false,
- AdbController.setLockscreenEnabled.bind(AdbController));
diff --git a/b2g/chrome/content/devtools/debugger.js b/b2g/chrome/content/devtools/debugger.js
deleted file mode 100644
index 11987a839..000000000
--- a/b2g/chrome/content/devtools/debugger.js
+++ /dev/null
@@ -1,397 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-XPCOMUtils.defineLazyGetter(this, "devtools", function() {
- const { devtools } =
- Cu.import("resource://devtools/shared/Loader.jsm", {});
- return devtools;
-});
-
-XPCOMUtils.defineLazyGetter(this, "DebuggerServer", function() {
- const { DebuggerServer } = devtools.require("devtools/server/main");
- return DebuggerServer;
-});
-
-XPCOMUtils.defineLazyGetter(this, "B2GTabList", function() {
- const { B2GTabList } =
- devtools.require("resource://gre/modules/DebuggerActors.js");
- return B2GTabList;
-});
-
-// Load the discovery module eagerly, so that it can set a device name at
-// startup. This does not cause discovery to start listening for packets, as
-// that only happens once DevTools is enabled.
-devtools.require("devtools/shared/discovery/discovery");
-
-var RemoteDebugger = {
- _listening: false,
-
- /**
- * Prompt the user to accept or decline the incoming connection.
- *
- * @param session object
- * The session object will contain at least the following fields:
- * {
- * authentication,
- * client: {
- * host,
- * port
- * },
- * server: {
- * host,
- * port
- * }
- * }
- * Specific authentication modes may include additional fields. Check
- * the different |allowConnection| methods in
- * devtools/shared/security/auth.js.
- * @return An AuthenticationResult value.
- * A promise that will be resolved to the above is also allowed.
- */
- allowConnection(session) {
- if (this._promptingForAllow) {
- // Don't stack connection prompts if one is already open
- return DebuggerServer.AuthenticationResult.DENY;
- }
- this._listen();
-
- this._promptingForAllow = new Promise(resolve => {
- this._handleAllowResult = detail => {
- this._handleAllowResult = null;
- this._promptingForAllow = null;
- // Newer Gaia supplies |authResult|, which is one of the
- // AuthenticationResult values.
- if (detail.authResult) {
- resolve(detail.authResult);
- } else if (detail.value) {
- resolve(DebuggerServer.AuthenticationResult.ALLOW);
- } else {
- resolve(DebuggerServer.AuthenticationResult.DENY);
- }
- };
-
- shell.sendChromeEvent({
- type: "remote-debugger-prompt",
- session
- });
- });
-
- return this._promptingForAllow;
- },
-
- /**
- * During OOB_CERT authentication, the user must transfer some data through some
- * out of band mechanism from the client to the server to authenticate the
- * devices.
- *
- * This implementation instructs Gaia to continually capture images which are
- * passed back here and run through a QR decoder.
- *
- * @return An object containing:
- * * sha256: hash(ClientCert)
- * * k : K(random 128-bit number)
- * A promise that will be resolved to the above is also allowed.
- */
- receiveOOB() {
- if (this._receivingOOB) {
- return this._receivingOOB;
- }
- this._listen();
-
- const QR = devtools.require("devtools/shared/qrcode/index");
- this._receivingOOB = new Promise((resolve, reject) => {
- this._handleAuthEvent = detail => {
- debug(detail.action);
- if (detail.action === "abort") {
- this._handleAuthEvent = null;
- this._receivingOOB = null;
- reject();
- return;
- }
-
- if (detail.action !== "capture") {
- return;
- }
-
- let url = detail.url;
- QR.decodeFromURI(url).then(data => {
- debug("Got auth data: " + data);
- let oob = JSON.parse(data);
-
- shell.sendChromeEvent({
- type: "devtools-auth",
- action: "stop"
- });
-
- this._handleAuthEvent = null;
- this._receivingOOB = null;
- resolve(oob);
- }).catch(() => {
- debug("No auth data, requesting new capture");
- shell.sendChromeEvent({
- type: "devtools-auth",
- action: "capture"
- });
- });
- };
-
- // Show QR scanning dialog, get an initial capture
- shell.sendChromeEvent({
- type: "devtools-auth",
- action: "start"
- });
- });
-
- return this._receivingOOB;
- },
-
- _listen: function() {
- if (this._listening) {
- return;
- }
-
- this.handleEvent = this.handleEvent.bind(this);
- let content = shell.contentBrowser.contentWindow;
- content.addEventListener("mozContentEvent", this, false, true);
- this._listening = true;
- },
-
- handleEvent: function(event) {
- let detail = event.detail;
- if (detail.type === "remote-debugger-prompt" && this._handleAllowResult) {
- this._handleAllowResult(detail);
- }
- if (detail.type === "devtools-auth" && this._handleAuthEvent) {
- this._handleAuthEvent(detail);
- }
- },
-
- initServer: function() {
- if (DebuggerServer.initialized) {
- return;
- }
-
- // Ask for remote connections.
- DebuggerServer.init();
-
- // /!\ Be careful when adding a new actor, especially global actors.
- // Any new global actor will be exposed and returned by the root actor.
-
- // Add Firefox-specific actors, but prevent tab actors to be loaded in
- // the parent process, unless we enable certified apps debugging.
- let restrictPrivileges = Services.prefs.getBoolPref("devtools.debugger.forbid-certified-apps");
- DebuggerServer.addBrowserActors("navigator:browser", restrictPrivileges);
-
- // Allow debugging of chrome for any process
- if (!restrictPrivileges) {
- DebuggerServer.allowChromeProcess = true;
- }
-
- /**
- * Construct a root actor appropriate for use in a server running in B2G.
- * The returned root actor respects the factories registered with
- * DebuggerServer.addGlobalActor only if certified apps debugging is on,
- * otherwise we used an explicit limited list of global actors
- *
- * * @param connection DebuggerServerConnection
- * The conection to the client.
- */
- DebuggerServer.createRootActor = function createRootActor(connection)
- {
- let parameters = {
- tabList: new B2GTabList(connection),
- // Use an explicit global actor list to prevent exposing
- // unexpected actors
- globalActorFactories: restrictPrivileges ? {
- webappsActor: DebuggerServer.globalActorFactories.webappsActor,
- deviceActor: DebuggerServer.globalActorFactories.deviceActor,
- settingsActor: DebuggerServer.globalActorFactories.settingsActor
- } : DebuggerServer.globalActorFactories
- };
- let { RootActor } = devtools.require("devtools/server/actors/root");
- let root = new RootActor(connection, parameters);
- root.applicationType = "operating-system";
- return root;
- };
-
- if (isGonk) {
- DebuggerServer.on("connectionchange", function() {
- AdbController.updateState();
- });
- }
- }
-};
-
-RemoteDebugger.allowConnection =
- RemoteDebugger.allowConnection.bind(RemoteDebugger);
-RemoteDebugger.receiveOOB =
- RemoteDebugger.receiveOOB.bind(RemoteDebugger);
-
-var USBRemoteDebugger = {
-
- get isDebugging() {
- if (!this._listener) {
- return false;
- }
-
- return DebuggerServer._connections &&
- Object.keys(DebuggerServer._connections).length > 0;
- },
-
- start: function() {
- if (this._listener) {
- return;
- }
-
- RemoteDebugger.initServer();
-
- let portOrPath =
- Services.prefs.getCharPref("devtools.debugger.unix-domain-socket") ||
- "/data/local/debugger-socket";
-
- try {
- debug("Starting USB debugger on " + portOrPath);
- let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
- let authenticator = new AuthenticatorType.Server();
- authenticator.allowConnection = RemoteDebugger.allowConnection;
- this._listener = DebuggerServer.createListener();
- this._listener.portOrPath = portOrPath;
- this._listener.authenticator = authenticator;
- this._listener.open();
- // Temporary event, until bug 942756 lands and offers a way to know
- // when the server is up and running.
- Services.obs.notifyObservers(null, "debugger-server-started", null);
- } catch (e) {
- debug("Unable to start USB debugger server: " + e);
- }
- },
-
- stop: function() {
- if (!this._listener) {
- return;
- }
-
- try {
- this._listener.close();
- this._listener = null;
- } catch (e) {
- debug("Unable to stop USB debugger server: " + e);
- }
- }
-
-};
-
-var WiFiRemoteDebugger = {
-
- start: function() {
- if (this._listener) {
- return;
- }
-
- RemoteDebugger.initServer();
-
- try {
- debug("Starting WiFi debugger");
- let AuthenticatorType = DebuggerServer.Authenticators.get("OOB_CERT");
- let authenticator = new AuthenticatorType.Server();
- authenticator.allowConnection = RemoteDebugger.allowConnection;
- authenticator.receiveOOB = RemoteDebugger.receiveOOB;
- this._listener = DebuggerServer.createListener();
- this._listener.portOrPath = -1 /* any available port */;
- this._listener.authenticator = authenticator;
- this._listener.discoverable = true;
- this._listener.encryption = true;
- this._listener.open();
- let port = this._listener.port;
- debug("Started WiFi debugger on " + port);
- } catch (e) {
- debug("Unable to start WiFi debugger server: " + e);
- }
- },
-
- stop: function() {
- if (!this._listener) {
- return;
- }
-
- try {
- this._listener.close();
- this._listener = null;
- } catch (e) {
- debug("Unable to stop WiFi debugger server: " + e);
- }
- }
-
-};
-
-(function() {
- // Track these separately here so we can determine the correct value for the
- // pref "devtools.debugger.remote-enabled", which is true when either mode of
- // using DevTools is enabled.
- let devtoolsUSB = false;
- let devtoolsWiFi = false;
-
- // Keep the old setting to not break people that won't have updated
- // gaia and gecko.
- SettingsListener.observe("devtools.debugger.remote-enabled", false,
- function(value) {
- devtoolsUSB = value;
- Services.prefs.setBoolPref("devtools.debugger.remote-enabled",
- devtoolsUSB || devtoolsWiFi);
- // This preference is consulted during startup
- Services.prefs.savePrefFile(null);
- try {
- value ? USBRemoteDebugger.start() : USBRemoteDebugger.stop();
- } catch(e) {
- dump("Error while initializing USB devtools: " +
- e + "\n" + e.stack + "\n");
- }
- });
-
- SettingsListener.observe("debugger.remote-mode", "disabled", function(value) {
- if (["disabled", "adb-only", "adb-devtools"].indexOf(value) == -1) {
- dump("Illegal value for debugger.remote-mode: " + value + "\n");
- return;
- }
-
- devtoolsUSB = value == "adb-devtools";
- Services.prefs.setBoolPref("devtools.debugger.remote-enabled",
- devtoolsUSB || devtoolsWiFi);
- // This preference is consulted during startup
- Services.prefs.savePrefFile(null);
-
- try {
- (value == "adb-devtools") ? USBRemoteDebugger.start()
- : USBRemoteDebugger.stop();
- } catch(e) {
- dump("Error while initializing USB devtools: " +
- e + "\n" + e.stack + "\n");
- }
-
- isGonk && AdbController.setRemoteDebuggerState(value != "disabled");
- });
-
- SettingsListener.observe("devtools.remote.wifi.enabled", false,
- function(value) {
- devtoolsWiFi = value;
- Services.prefs.setBoolPref("devtools.debugger.remote-enabled",
- devtoolsUSB || devtoolsWiFi);
- // Allow remote debugging on non-local interfaces when WiFi debug is enabled
- // TODO: Bug 1034411: Lock down to WiFi interface, instead of all interfaces
- Services.prefs.setBoolPref("devtools.debugger.force-local", !value);
- // This preference is consulted during startup
- Services.prefs.savePrefFile(null);
-
- try {
- value ? WiFiRemoteDebugger.start() : WiFiRemoteDebugger.stop();
- } catch(e) {
- dump("Error while initializing WiFi devtools: " +
- e + "\n" + e.stack + "\n");
- }
- });
-})();
diff --git a/b2g/chrome/content/devtools/hud.js b/b2g/chrome/content/devtools/hud.js
deleted file mode 100644
index 64e9d553d..000000000
--- a/b2g/chrome/content/devtools/hud.js
+++ /dev/null
@@ -1,1017 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-// settings.js loads this file when the HUD setting is enabled.
-
-const DEVELOPER_HUD_LOG_PREFIX = 'DeveloperHUD';
-const CUSTOM_HISTOGRAM_PREFIX = 'DEVTOOLS_HUD_CUSTOM_';
-const APPNAME_IDX = 3;
-const HISTNAME_IDX = 4;
-
-XPCOMUtils.defineLazyGetter(this, 'devtools', function() {
- const {devtools} = Cu.import('resource://devtools/shared/Loader.jsm', {});
- return devtools;
-});
-
-XPCOMUtils.defineLazyGetter(this, 'DebuggerClient', function() {
- return devtools.require('devtools/shared/client/main').DebuggerClient;
-});
-
-XPCOMUtils.defineLazyGetter(this, 'WebConsoleUtils', function() {
- return devtools.require('devtools/shared/webconsole/utils').Utils;
-});
-
-XPCOMUtils.defineLazyGetter(this, 'EventLoopLagFront', function() {
- return devtools.require('devtools/shared/fronts/eventlooplag').EventLoopLagFront;
-});
-
-XPCOMUtils.defineLazyGetter(this, 'PerformanceEntriesFront', function() {
- return devtools.require('devtools/server/actors/performance-entries').PerformanceEntriesFront;
-});
-
-XPCOMUtils.defineLazyGetter(this, 'MemoryFront', function() {
- return devtools.require('devtools/server/actors/memory').MemoryFront;
-});
-
-Cu.import('resource://gre/modules/Frames.jsm');
-
-var _telemetryDebug = false;
-
-function telemetryDebug(...args) {
- if (_telemetryDebug) {
- args.unshift('[AdvancedTelemetry]');
- console.log(...args);
- }
-}
-
-/**
- * The Developer HUD is an on-device developer tool that displays widgets,
- * showing visual debug information about apps. Each widget corresponds to a
- * metric as tracked by a metric watcher (e.g. consoleWatcher).
- */
-var developerHUD = {
-
- _targets: new Map(),
- _histograms: new Set(),
- _customHistograms: new Set(),
- _client: null,
- _conn: null,
- _watchers: [],
- _logging: true,
- _telemetry: false,
-
- /**
- * This method registers a metric watcher that will watch one or more metrics
- * on app frames that are being tracked. A watcher must implement the
- * `trackTarget(target)` and `untrackTarget(target)` methods, register
- * observed metrics with `target.register(metric)`, and keep them up-to-date
- * with `target.update(metric, message)` when necessary.
- */
- registerWatcher(watcher) {
- this._watchers.unshift(watcher);
- },
-
- init() {
- if (this._client) {
- return;
- }
-
- if (!DebuggerServer.initialized) {
- RemoteDebugger.initServer();
- }
-
- // We instantiate a local debugger connection so that watchers can use our
- // DebuggerClient to send requests to tab actors (e.g. the consoleActor).
- // Note the special usage of the private _serverConnection, which we need
- // to call connectToChild and set up child process actors on a frame we
- // intend to track. These actors will use the connection to communicate with
- // our DebuggerServer in the parent process.
- let transport = DebuggerServer.connectPipe();
- this._conn = transport._serverConnection;
- this._client = new DebuggerClient(transport);
-
- for (let w of this._watchers) {
- if (w.init) {
- w.init(this._client);
- }
- }
-
- Frames.addObserver(this);
-
- let appFrames = Frames.list().filter(frame => frame.getAttribute('mozapp'));
- for (let frame of appFrames) {
- this.trackFrame(frame);
- }
-
- SettingsListener.observe('hud.logging', this._logging, enabled => {
- this._logging = enabled;
- });
-
- SettingsListener.observe('hud.telemetry.logging', _telemetryDebug, enabled => {
- _telemetryDebug = enabled;
- });
-
- SettingsListener.observe('metrics.selectedMetrics.level', "", level => {
- this._telemetry = (level === 'Enhanced');
- });
- },
-
- uninit() {
- if (!this._client) {
- return;
- }
-
- for (let frame of this._targets.keys()) {
- this.untrackFrame(frame);
- }
-
- Frames.removeObserver(this);
-
- this._client.close();
- delete this._client;
- },
-
- /**
- * This method will ask all registered watchers to track and update metrics
- * on an app frame.
- */
- trackFrame(frame) {
- if (this._targets.has(frame)) {
- return;
- }
-
- DebuggerServer.connectToChild(this._conn, frame).then(actor => {
- let target = new Target(frame, actor);
- this._targets.set(frame, target);
-
- for (let w of this._watchers) {
- w.trackTarget(target);
- }
- });
- },
-
- untrackFrame(frame) {
- let target = this._targets.get(frame);
- if (target) {
- for (let w of this._watchers) {
- w.untrackTarget(target);
- }
-
- target.destroy();
- this._targets.delete(frame);
- }
- },
-
- onFrameCreated(frame, isFirstAppFrame) {
- let mozapp = frame.getAttribute('mozapp');
- if (!mozapp) {
- return;
- }
- this.trackFrame(frame);
- },
-
- onFrameDestroyed(frame, isLastAppFrame) {
- let mozapp = frame.getAttribute('mozapp');
- if (!mozapp) {
- return;
- }
- this.untrackFrame(frame);
- },
-
- log(message) {
- if (this._logging) {
- dump(DEVELOPER_HUD_LOG_PREFIX + ': ' + message + '\n');
- }
- }
-
-};
-
-
-/**
- * A Target object represents all there is to know about a Firefox OS app frame
- * that is being tracked, e.g. a pointer to the frame, current values of watched
- * metrics, and how to notify the front-end when metrics have changed.
- */
-function Target(frame, actor) {
- this.frame = frame;
- this.actor = actor;
- this.metrics = new Map();
- this._appName = null;
-}
-
-Target.prototype = {
-
- get manifest() {
- return this.frame.appManifestURL;
- },
-
- get appName() {
-
- if (this._appName) {
- return this._appName;
- }
-
- let manifest = this.manifest;
- if (!manifest) {
- let msg = DEVELOPER_HUD_LOG_PREFIX + ': Unable to determine app for telemetry metric. src: ' +
- this.frame.src;
- console.error(msg);
- return null;
- }
-
- // "communications" apps are a special case
- if (manifest.indexOf('communications') === -1) {
- let start = manifest.indexOf('/') + 2;
- let end = manifest.indexOf('.', start);
- this._appName = manifest.substring(start, end).toLowerCase();
- } else {
- let src = this.frame.src;
- if (src) {
- // e.g., `app://communications.gaiamobile.org/contacts/index.html`
- let parts = src.split('/');
- let APP = 3;
- let EXPECTED_PARTS_LENGTH = 5;
- if (parts.length === EXPECTED_PARTS_LENGTH) {
- this._appName = parts[APP];
- }
- }
- }
-
- return this._appName;
- },
-
- /**
- * Register a metric that can later be updated. Does not update the front-end.
- */
- register(metric) {
- this.metrics.set(metric, 0);
- },
-
- /**
- * Modify one of a target's metrics, and send out an event to notify relevant
- * parties (e.g. the developer HUD, automated tests, etc).
- */
- update(metric, message) {
- if (!metric.name) {
- throw new Error('Missing metric.name');
- }
-
- if (!metric.value) {
- metric.value = 0;
- }
-
- let metrics = this.metrics;
- if (metrics) {
- metrics.set(metric.name, metric.value);
- }
-
- let data = {
- metrics: [], // FIXME(Bug 982066) Remove this field.
- manifest: this.manifest,
- metric: metric,
- message: message
- };
-
- // FIXME(Bug 982066) Remove this loop.
- if (metrics && metrics.size > 0) {
- for (let name of metrics.keys()) {
- data.metrics.push({name: name, value: metrics.get(name)});
- }
- }
-
- if (message) {
- developerHUD.log('[' + data.manifest + '] ' + data.message);
- }
-
- this._send(data);
- },
-
- /**
- * Nicer way to call update() when the metric value is a number that needs
- * to be incremented.
- */
- bump(metric, message) {
- metric.value = (this.metrics.get(metric.name) || 0) + 1;
- this.update(metric, message);
- },
-
- /**
- * Void a metric value and make sure it isn't displayed on the front-end
- * anymore.
- */
- clear(metric) {
- metric.value = 0;
- this.update(metric);
- },
-
- /**
- * Tear everything down, including the front-end by sending a message without
- * widgets.
- */
- destroy() {
- delete this.metrics;
- this._send({metric: {skipTelemetry: true}});
- },
-
- _send(data) {
- let frame = this.frame;
-
- shell.sendEvent(frame, 'developer-hud-update', Cu.cloneInto(data, frame));
- this._logHistogram(data.metric);
- },
-
- _getAddonHistogram(item) {
- let appName = this._getAddonHistogramName(item, APPNAME_IDX);
- let histName = this._getAddonHistogramName(item, HISTNAME_IDX);
-
- return Services.telemetry.getAddonHistogram(appName, CUSTOM_HISTOGRAM_PREFIX
- + histName);
- },
-
- _getAddonHistogramName(item, index) {
- let array = item.split('_');
- return array[index].toUpperCase();
- },
-
- _clearTelemetryData() {
- developerHUD._histograms.forEach(function(item) {
- Services.telemetry.getKeyedHistogramById(item).clear();
- });
-
- developerHUD._customHistograms.forEach(item => {
- this._getAddonHistogram(item).clear();
- });
- },
-
- _sendTelemetryData() {
- if (!developerHUD._telemetry) {
- return;
- }
- telemetryDebug('calling sendTelemetryData');
- let frame = this.frame;
- let payload = {
- keyedHistograms: {},
- addonHistograms: {}
- };
- // Package the hud histograms.
- developerHUD._histograms.forEach(function(item) {
- payload.keyedHistograms[item] =
- Services.telemetry.getKeyedHistogramById(item).snapshot();
- });
-
- // Package the registered hud custom histograms
- developerHUD._customHistograms.forEach(item => {
- let appName = this._getAddonHistogramName(item, APPNAME_IDX);
- let histName = CUSTOM_HISTOGRAM_PREFIX +
- this._getAddonHistogramName(item, HISTNAME_IDX);
- let addonHist = Services.telemetry.getAddonHistogram(appName, histName).snapshot();
- if (!(appName in payload.addonHistograms)) {
- payload.addonHistograms[appName] = {};
- }
- // Do not include histograms with sum of 0.
- if (addonHist.sum > 0) {
- payload.addonHistograms[appName][histName] = addonHist;
- }
- });
- shell.sendEvent(frame, 'advanced-telemetry-update', Cu.cloneInto(payload, frame));
- },
-
- _logHistogram(metric) {
- if (!developerHUD._telemetry || metric.skipTelemetry) {
- return;
- }
-
- metric.appName = this.appName;
- if (!metric.appName) {
- return;
- }
-
- let metricName = metric.name.toUpperCase();
- let metricAppName = metric.appName.toUpperCase();
- if (!metric.custom) {
- let keyedMetricName = 'DEVTOOLS_HUD_' + metricName;
- try {
- let keyed = Services.telemetry.getKeyedHistogramById(keyedMetricName);
- if (keyed) {
- keyed.add(metric.appName, parseInt(metric.value, 10));
- developerHUD._histograms.add(keyedMetricName);
- telemetryDebug(keyedMetricName, metric.value, metric.appName);
- }
- } catch(err) {
- console.error('Histogram error is metricname added to histograms.json:'
- + keyedMetricName);
- }
- } else {
- let histogramName = CUSTOM_HISTOGRAM_PREFIX + metricAppName + '_'
- + metricName;
- // This is a call to add a value to an existing histogram.
- if (typeof metric.value !== 'undefined') {
- Services.telemetry.getAddonHistogram(metricAppName,
- CUSTOM_HISTOGRAM_PREFIX + metricName).add(parseInt(metric.value, 10));
- telemetryDebug(histogramName, metric.value);
- return;
- }
-
- // The histogram already exists and are not adding data to it.
- if (developerHUD._customHistograms.has(histogramName)) {
- return;
- }
-
- // This is a call to create a new histogram.
- try {
- let metricType = parseInt(metric.type, 10);
- if (metricType === Services.telemetry.HISTOGRAM_COUNT) {
- Services.telemetry.registerAddonHistogram(metricAppName,
- CUSTOM_HISTOGRAM_PREFIX + metricName, metricType);
- } else {
- Services.telemetry.registerAddonHistogram(metricAppName,
- CUSTOM_HISTOGRAM_PREFIX + metricName, metricType, metric.min,
- metric.max, metric.buckets);
- }
- developerHUD._customHistograms.add(histogramName);
- } catch (err) {
- console.error('Histogram error: ' + err);
- }
- }
- }
-};
-
-
-/**
- * The Console Watcher tracks the following metrics in apps: reflows, warnings,
- * and errors, with security errors reported separately.
- */
-var consoleWatcher = {
-
- _client: null,
- _targets: new Map(),
- _watching: {
- reflows: false,
- warnings: false,
- errors: false,
- security: false
- },
- _security: [
- 'Mixed Content Blocker',
- 'Mixed Content Message',
- 'CSP',
- 'Invalid HSTS Headers',
- 'Invalid HPKP Headers',
- 'Insecure Password Field',
- 'SSL',
- 'CORS'
- ],
- _reflowThreshold: 0,
-
- init(client) {
- this._client = client;
- this.consoleListener = this.consoleListener.bind(this);
-
- let watching = this._watching;
-
- for (let key in watching) {
- let metric = key;
- SettingsListener.observe('hud.' + metric, watching[metric], watch => {
- // Watch or unwatch the metric.
- if (watching[metric] = watch) {
- return;
- }
-
- // If unwatched, remove any existing widgets for that metric.
- for (let target of this._targets.values()) {
- target.clear({name: metric});
- }
- });
- }
-
- SettingsListener.observe('hud.reflows.duration', this._reflowThreshold, threshold => {
- this._reflowThreshold = threshold;
- });
-
- client.addListener('logMessage', this.consoleListener);
- client.addListener('pageError', this.consoleListener);
- client.addListener('consoleAPICall', this.consoleListener);
- client.addListener('reflowActivity', this.consoleListener);
- },
-
- trackTarget(target) {
- target.register('reflows');
- target.register('warnings');
- target.register('errors');
- target.register('security');
-
- this._client.request({
- to: target.actor.consoleActor,
- type: 'startListeners',
- listeners: ['LogMessage', 'PageError', 'ConsoleAPI', 'ReflowActivity']
- }, (res) => {
- this._targets.set(target.actor.consoleActor, target);
- });
- },
-
- untrackTarget(target) {
- this._client.request({
- to: target.actor.consoleActor,
- type: 'stopListeners',
- listeners: ['LogMessage', 'PageError', 'ConsoleAPI', 'ReflowActivity']
- }, (res) => { });
-
- this._targets.delete(target.actor.consoleActor);
- },
-
- consoleListener(type, packet) {
- let target = this._targets.get(packet.from);
- let metric = {};
- let output = '';
-
- switch (packet.type) {
-
- case 'pageError':
- let pageError = packet.pageError;
-
- if (pageError.warning || pageError.strict) {
- metric.name = 'warnings';
- output += 'Warning (';
- } else {
- metric.name = 'errors';
- output += 'Error (';
- }
-
- if (this._security.indexOf(pageError.category) > -1) {
- metric.name = 'security';
-
- // Telemetry sends the security error category not the
- // count of security errors.
- target._logHistogram({
- name: 'security_category',
- value: pageError.category
- });
-
- // Indicate that the 'hud' security metric (the count of security
- // errors) should not be sent as a telemetry metric since the
- // security error category is being sent instead.
- metric.skipTelemetry = true;
- }
-
- let {errorMessage, sourceName, category, lineNumber, columnNumber} = pageError;
- output += category + '): "' + (errorMessage.initial || errorMessage) +
- '" in ' + sourceName + ':' + lineNumber + ':' + columnNumber;
- break;
-
- case 'consoleAPICall':
- switch (packet.message.level) {
-
- case 'error':
- metric.name = 'errors';
- output += 'Error (console)';
- break;
-
- case 'warn':
- metric.name = 'warnings';
- output += 'Warning (console)';
- break;
-
- case 'info':
- this.handleTelemetryMessage(target, packet);
-
- // Currently, informational log entries are tracked only by
- // telemetry. Nonetheless, for consistency, we continue here
- // and let the function return normally, when it concludes 'info'
- // entries are not being watched.
- metric.name = 'info';
- break;
-
- default:
- return;
- }
- break;
-
- case 'reflowActivity':
- metric.name = 'reflows';
-
- let {start, end, sourceURL, interruptible} = packet;
- metric.interruptible = interruptible;
- let duration = Math.round((end - start) * 100) / 100;
-
- // Record the reflow if the duration exceeds the threshold.
- if (duration < this._reflowThreshold) {
- return;
- }
-
- output += 'Reflow: ' + duration + 'ms';
- if (sourceURL) {
- output += ' ' + this.formatSourceURL(packet);
- }
-
- // Telemetry also records reflow duration.
- target._logHistogram({
- name: 'reflow_duration',
- value: Math.round(duration)
- });
- break;
-
- default:
- return;
- }
-
- if (developerHUD._telemetry) {
- // Always record telemetry for these metrics.
- if (metric.name === 'errors' || metric.name === 'warnings' || metric.name === 'reflows') {
- let value = target.metrics.get(metric.name);
- metric.value = (value || 0) + 1;
- target._logHistogram(metric);
-
- // Telemetry has already been recorded.
- metric.skipTelemetry = true;
-
- // If the metric is not being watched, persist the incremented value.
- // If the metric is being watched, `target.bump` will increment the value
- // of the metric and will persist the incremented value.
- if (!this._watching[metric.name]) {
- target.metrics.set(metric.name, metric.value);
- }
- }
- }
-
- if (!this._watching[metric.name]) {
- return;
- }
-
- target.bump(metric, output);
- },
-
- formatSourceURL(packet) {
- // Abbreviate source URL
- let source = WebConsoleUtils.abbreviateSourceURL(packet.sourceURL);
-
- // Add function name and line number
- let {functionName, sourceLine} = packet;
- source = 'in ' + (functionName || '<anonymousFunction>') +
- ', ' + source + ':' + sourceLine;
-
- return source;
- },
-
- handleTelemetryMessage(target, packet) {
- if (!developerHUD._telemetry) {
- return;
- }
-
- // If this is a 'telemetry' log entry, create a telemetry metric from
- // the log content.
- let separator = '|';
- let logContent = packet.message.arguments.toString();
-
- if (logContent.indexOf('telemetry') < 0) {
- return;
- }
-
- let telemetryData = logContent.split(separator);
-
- // Positions of the components of a telemetry log entry.
- let TELEMETRY_IDENTIFIER_IDX = 0;
- let NAME_IDX = 1;
- let VALUE_IDX = 2;
- let TYPE_IDX = 2;
- let MIN_IDX = 3;
- let MAX_IDX = 4;
- let BUCKETS_IDX = 5;
- let MAX_CUSTOM_ARGS = 6;
- let MIN_CUSTOM_ARGS = 3;
-
- if (telemetryData[TELEMETRY_IDENTIFIER_IDX] != 'telemetry' ||
- telemetryData.length < MIN_CUSTOM_ARGS ||
- telemetryData.length > MAX_CUSTOM_ARGS) {
- return;
- }
-
- let metric = {
- name: telemetryData[NAME_IDX]
- };
-
- if (metric.name === 'MGMT') {
- metric.value = telemetryData[VALUE_IDX];
- if (metric.value === 'TIMETOSHIP') {
- telemetryDebug('Received a Ship event');
- target._sendTelemetryData();
- } else if (metric.value === 'CLEARMETRICS') {
- target._clearTelemetryData();
- }
- } else {
- if (telemetryData.length === MIN_CUSTOM_ARGS) {
- metric.value = telemetryData[VALUE_IDX];
- } else if (telemetryData.length === MAX_CUSTOM_ARGS) {
- metric.type = telemetryData[TYPE_IDX];
- metric.min = telemetryData[MIN_IDX];
- metric.max = telemetryData[MAX_IDX];
- metric.buckets = telemetryData[BUCKETS_IDX];
- }
- metric.custom = true;
- target._logHistogram(metric);
- }
- }
-};
-developerHUD.registerWatcher(consoleWatcher);
-
-
-var eventLoopLagWatcher = {
- _client: null,
- _fronts: new Map(),
- _active: false,
-
- init(client) {
- this._client = client;
-
- SettingsListener.observe('hud.jank', false, this.settingsListener.bind(this));
- },
-
- settingsListener(value) {
- if (this._active == value) {
- return;
- }
-
- this._active = value;
-
- // Toggle the state of existing fronts.
- let fronts = this._fronts;
- for (let target of fronts.keys()) {
- if (value) {
- fronts.get(target).start();
- } else {
- fronts.get(target).stop();
- target.clear({name: 'jank'});
- }
- }
- },
-
- trackTarget(target) {
- target.register('jank');
-
- let front = new EventLoopLagFront(this._client, target.actor);
- this._fronts.set(target, front);
-
- front.on('event-loop-lag', time => {
- target.update({name: 'jank', value: time}, 'Jank: ' + time + 'ms');
- });
-
- if (this._active) {
- front.start();
- }
- },
-
- untrackTarget(target) {
- let fronts = this._fronts;
- if (fronts.has(target)) {
- fronts.get(target).destroy();
- fronts.delete(target);
- }
- }
-};
-developerHUD.registerWatcher(eventLoopLagWatcher);
-
-/*
- * The performanceEntriesWatcher determines the delta between the epoch
- * of an app's launch time and the epoch of the app's performance entry marks.
- * When it receives an "appLaunch" performance entry mark it records the
- * name of the app being launched and the epoch of when the launch ocurred.
- * When it receives subsequent performance entry events for the app being
- * launched, it records the delta of the performance entry opoch compared
- * to the app-launch epoch and emits an "app-start-time-<performance mark name>"
- * event containing the delta.
- *
- * Additionally, while recording the "app-start-time" for a performance mark,
- * USS memory at the time of the performance mark is also recorded.
- */
-var performanceEntriesWatcher = {
- _client: null,
- _fronts: new Map(),
- _appLaunch: new Map(),
- _supported: [
- 'contentInteractive',
- 'navigationInteractive',
- 'navigationLoaded',
- 'visuallyLoaded',
- 'fullyLoaded',
- 'mediaEnumerated',
- 'scanEnd'
- ],
-
- init(client) {
- this._client = client;
- let setting = 'devtools.telemetry.supported_performance_marks';
- let defaultValue = this._supported.join(',');
-
- SettingsListener.observe(setting, defaultValue, supported => {
- this._supported = supported.split(',');
- });
- },
-
- trackTarget(target) {
- // The performanceEntries watcher doesn't register a metric because
- // currently the metrics generated are not displayed in
- // in the front-end.
-
- let front = new PerformanceEntriesFront(this._client, target.actor);
- this._fronts.set(target, front);
-
- // User timings are always gathered; there is no setting to enable/
- // disable.
- front.start();
-
- front.on('entry', detail => {
-
- // Only process performance marks.
- if (detail.type !== 'mark') {
- return;
- }
-
- let name = detail.name;
- let epoch = detail.epoch;
-
- // If this is an "app launch" mark, record the app that was
- // launched and the epoch of when it was launched.
- if (name.indexOf('appLaunch') !== -1) {
- let CHARS_UNTIL_APP_NAME = 7; // '@app://'
- let startPos = name.indexOf('@app') + CHARS_UNTIL_APP_NAME;
- let endPos = name.indexOf('.');
- let appName = name.slice(startPos, endPos);
- this._appLaunch.set(appName, epoch);
- return;
- }
-
- // Only process supported performance marks
- if (this._supported.indexOf(name) === -1) {
- return;
- }
-
- let origin = detail.origin;
- origin = origin.slice(0, origin.indexOf('.'));
-
- let appLaunchTime = this._appLaunch.get(origin);
-
- // Sanity check: ensure we have an app launch time for the app
- // corresponding to this performance mark.
- if (!appLaunchTime) {
- return;
- }
-
- let time = epoch - appLaunchTime;
- let eventName = 'app_startup_time_' + name;
-
- // Events based on performance marks are for telemetry only, they are
- // not displayed in the HUD front end.
- target._logHistogram({name: eventName, value: time});
-
- memoryWatcher.front(target).residentUnique().then(value => {
- // bug 1215277, need 'v2' for app-memory histograms
- eventName = 'app_memory_' + name + '_v2';
- target._logHistogram({name: eventName, value: value});
- }, err => {
- console.error(err);
- });
- });
- },
-
- untrackTarget(target) {
- let fronts = this._fronts;
- if (fronts.has(target)) {
- fronts.get(target).destroy();
- fronts.delete(target);
- }
- }
-};
-developerHUD.registerWatcher(performanceEntriesWatcher);
-
-/**
- * The Memory Watcher uses devtools actors to track memory usage.
- */
-var memoryWatcher = {
-
- _client: null,
- _fronts: new Map(),
- _timers: new Map(),
- _watching: {
- uss: false,
- appmemory: false,
- jsobjects: false,
- jsstrings: false,
- jsother: false,
- dom: false,
- style: false,
- other: false
- },
- _active: false,
-
- init(client) {
- this._client = client;
- let watching = this._watching;
-
- for (let key in watching) {
- let category = key;
- SettingsListener.observe('hud.' + category, false, watch => {
- watching[category] = watch;
- this.update();
- });
- }
- },
-
- update() {
- let watching = this._watching;
- let active = watching.appmemory || watching.uss;
-
- if (this._active) {
- for (let target of this._fronts.keys()) {
- if (!watching.appmemory) target.clear({name: 'memory'});
- if (!watching.uss) target.clear({name: 'uss'});
- if (!active) clearTimeout(this._timers.get(target));
- }
- } else if (active) {
- for (let target of this._fronts.keys()) {
- this.measure(target);
- }
- }
- this._active = active;
- },
-
- measure(target) {
- let watch = this._watching;
- let format = this.formatMemory;
-
- if (watch.uss) {
- this.front(target).residentUnique().then(value => {
- target.update({name: 'uss', value: value}, 'USS: ' + format(value));
- }, err => {
- console.error(err);
- });
- }
-
- if (watch.appmemory) {
- front.measure().then(data => {
- let total = 0;
- let details = [];
-
- function item(name, condition, value) {
- if (!condition) {
- return;
- }
-
- let v = parseInt(value);
- total += v;
- details.push(name + ': ' + format(v));
- }
-
- item('JS objects', watch.jsobjects, data.jsObjectsSize);
- item('JS strings', watch.jsstrings, data.jsStringsSize);
- item('JS other', watch.jsother, data.jsOtherSize);
- item('DOM', watch.dom, data.domSize);
- item('Style', watch.style, data.styleSize);
- item('Other', watch.other, data.otherSize);
- // TODO Also count images size (bug #976007).
-
- target.update({name: 'memory', value: total},
- 'App Memory: ' + format(total) + ' (' + details.join(', ') + ')');
- }, err => {
- console.error(err);
- });
- }
-
- let timer = setTimeout(() => this.measure(target), 2000);
- this._timers.set(target, timer);
- },
-
- formatMemory(bytes) {
- var prefix = ['','K','M','G','T','P','E','Z','Y'];
- var i = 0;
- for (; bytes > 1024 && i < prefix.length; ++i) {
- bytes /= 1024;
- }
- return (Math.round(bytes * 100) / 100) + ' ' + prefix[i] + 'B';
- },
-
- trackTarget(target) {
- target.register('uss');
- target.register('memory');
- this._fronts.set(target, MemoryFront(this._client, target.actor));
- if (this._active) {
- this.measure(target);
- }
- },
-
- untrackTarget(target) {
- let front = this._fronts.get(target);
- if (front) {
- front.destroy();
- clearTimeout(this._timers.get(target));
- this._fronts.delete(target);
- this._timers.delete(target);
- }
- },
-
- front(target) {
- return this._fronts.get(target);
- }
-};
-developerHUD.registerWatcher(memoryWatcher);
diff --git a/b2g/chrome/content/identity.js b/b2g/chrome/content/identity.js
deleted file mode 100644
index 9c0ad50a2..000000000
--- a/b2g/chrome/content/identity.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This JS shim contains the callbacks to fire DOMRequest events for
-// navigator.pay API within the payment processor's scope.
-
-"use strict";
-
-var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
- "@mozilla.org/childprocessmessagemanager;1",
- "nsIMessageSender");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
- "@mozilla.org/uuid-generator;1",
- "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Logger",
- "resource://gre/modules/identity/LogUtils.jsm");
-
-function log(...aMessageArgs) {
- Logger.log.apply(Logger, ["injected identity.js"].concat(aMessageArgs));
-}
-
-log("\n\n======================= identity.js =======================\n\n");
-
-// This script may be injected more than once into an iframe.
-// It's hard to do this with |const| like we should, so use var instead.
-if (typeof kIdentityJSLoaded === 'undefined') {
- var kIdentityDelegateWatch = "identity-delegate-watch";
- var kIdentityDelegateRequest = "identity-delegate-request";
- var kIdentityDelegateLogout = "identity-delegate-logout";
- var kIdentityDelegateReady = "identity-delegate-ready";
- var kIdentityDelegateFinished = "identity-delegate-finished";
- var kIdentityControllerDoMethod = "identity-controller-doMethod";
- var kIdentktyJSLoaded = true;
-}
-
-var showUI = false;
-var options = {};
-var isLoaded = false;
-var func = null;
-
-/*
- * Message back to the SignInToWebsite pipe. Message should be an
- * object with the following keys:
- *
- * method: one of 'login', 'logout', 'ready'
- * assertion: optional assertion
- */
-function identityCall(message) {
- if (options._internal) {
- message._internal = options._internal;
- }
- sendAsyncMessage(kIdentityControllerDoMethod, message);
-}
-
-/*
- * To close the dialog, we first tell the gecko SignInToWebsite manager that it
- * can clean up. Then we tell the gaia component that we are finished. It is
- * necessary to notify gecko first, so that the message can be sent before gaia
- * destroys our context.
- */
-function closeIdentityDialog() {
- // tell gecko we're done.
- func = null; options = null;
- sendAsyncMessage(kIdentityDelegateFinished);
-}
-
-/*
- * doInternalWatch - call the internal.watch api and relay the results
- * up to the controller.
- */
-function doInternalWatch() {
- log("doInternalWatch:", options, isLoaded);
- if (options && isLoaded) {
- let BrowserID = content.wrappedJSObject.BrowserID;
- BrowserID.internal.watch(function(aParams, aInternalParams) {
- identityCall(aParams);
- if (aParams.method === "ready") {
- closeIdentityDialog();
- }
- },
- JSON.stringify(options),
- function(...things) {
- // internal watch log callback
- log("(watch) internal: ", things);
- }
- );
- }
-}
-
-function doInternalRequest() {
- log("doInternalRequest:", options && isLoaded);
- if (options && isLoaded) {
- var stringifiedOptions = JSON.stringify(options);
- content.wrappedJSObject.BrowserID.internal.get(
- options.origin,
- function(assertion, internalParams) {
- internalParams = internalParams || {};
- if (assertion) {
- identityCall({
- method: 'login',
- assertion: assertion,
- _internalParams: internalParams});
- } else {
- identityCall({
- method: 'cancel'
- });
- }
- closeIdentityDialog();
- },
- stringifiedOptions);
- }
-}
-function doInternalLogout(aOptions) {
- log("doInternalLogout:", (options && isLoaded));
- if (options && isLoaded) {
- let BrowserID = content.wrappedJSObject.BrowserID;
- BrowserID.internal.logout(options.origin, function() {
- identityCall({method:'logout'});
- closeIdentityDialog();
- });
- }
-}
-
-addEventListener("DOMContentLoaded", function(e) {
- content.addEventListener("load", function(e) {
- isLoaded = true;
- // bring da func
- if (func) func();
- });
-});
-
-// listen for request
-addMessageListener(kIdentityDelegateRequest, function(aMessage) {
- log("injected identity.js received", kIdentityDelegateRequest);
- options = aMessage.json;
- showUI = true;
- func = doInternalRequest;
- func();
-});
-
-// listen for watch
-addMessageListener(kIdentityDelegateWatch, function(aMessage) {
- log("injected identity.js received", kIdentityDelegateWatch);
- options = aMessage.json;
- showUI = false;
- func = doInternalWatch;
- func();
-});
-
-// listen for logout
-addMessageListener(kIdentityDelegateLogout, function(aMessage) {
- log("injected identity.js received", kIdentityDelegateLogout);
- options = aMessage.json;
- showUI = false;
- func = doInternalLogout;
- func();
-});
diff --git a/b2g/chrome/content/images/arrowdown-16.png b/b2g/chrome/content/images/arrowdown-16.png
deleted file mode 100644
index c982426f2..000000000
--- a/b2g/chrome/content/images/arrowdown-16.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/arrowright-16.png b/b2g/chrome/content/images/arrowright-16.png
deleted file mode 100644
index 859e98ba6..000000000
--- a/b2g/chrome/content/images/arrowright-16.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/desktop/home-black.png b/b2g/chrome/content/images/desktop/home-black.png
deleted file mode 100644
index c51187ed4..000000000
--- a/b2g/chrome/content/images/desktop/home-black.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/desktop/home-white.png b/b2g/chrome/content/images/desktop/home-white.png
deleted file mode 100644
index 43379d0e9..000000000
--- a/b2g/chrome/content/images/desktop/home-white.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/desktop/rotate.png b/b2g/chrome/content/images/desktop/rotate.png
deleted file mode 100644
index 9da1b5674..000000000
--- a/b2g/chrome/content/images/desktop/rotate.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/error.png b/b2g/chrome/content/images/error.png
deleted file mode 100644
index 58e37283a..000000000
--- a/b2g/chrome/content/images/error.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/errorpage-larry-black.png b/b2g/chrome/content/images/errorpage-larry-black.png
deleted file mode 100644
index 9f2e4a6e7..000000000
--- a/b2g/chrome/content/images/errorpage-larry-black.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/errorpage-larry-white.png b/b2g/chrome/content/images/errorpage-larry-white.png
deleted file mode 100644
index fc153c731..000000000
--- a/b2g/chrome/content/images/errorpage-larry-white.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/errorpage-warning.png b/b2g/chrome/content/images/errorpage-warning.png
deleted file mode 100644
index 8bf9d8e7d..000000000
--- a/b2g/chrome/content/images/errorpage-warning.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/exitfullscreen-hdpi.png b/b2g/chrome/content/images/exitfullscreen-hdpi.png
deleted file mode 100644
index 826e53408..000000000
--- a/b2g/chrome/content/images/exitfullscreen-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/fullscreen-hdpi.png b/b2g/chrome/content/images/fullscreen-hdpi.png
deleted file mode 100644
index 980e78731..000000000
--- a/b2g/chrome/content/images/fullscreen-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/mute-hdpi.png b/b2g/chrome/content/images/mute-hdpi.png
deleted file mode 100644
index 6daf7cf71..000000000
--- a/b2g/chrome/content/images/mute-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/pause-hdpi.png b/b2g/chrome/content/images/pause-hdpi.png
deleted file mode 100644
index c7837f822..000000000
--- a/b2g/chrome/content/images/pause-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/play-hdpi.png b/b2g/chrome/content/images/play-hdpi.png
deleted file mode 100644
index fd64f9697..000000000
--- a/b2g/chrome/content/images/play-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/scrubber-hdpi.png b/b2g/chrome/content/images/scrubber-hdpi.png
deleted file mode 100644
index b965b73d5..000000000
--- a/b2g/chrome/content/images/scrubber-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/throbber.png b/b2g/chrome/content/images/throbber.png
deleted file mode 100644
index c601ec80b..000000000
--- a/b2g/chrome/content/images/throbber.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/images/unmute-hdpi.png b/b2g/chrome/content/images/unmute-hdpi.png
deleted file mode 100644
index 5de342bda..000000000
--- a/b2g/chrome/content/images/unmute-hdpi.png
+++ /dev/null
Binary files differ
diff --git a/b2g/chrome/content/netError.css b/b2g/chrome/content/netError.css
deleted file mode 100644
index 59d06a00c..000000000
--- a/b2g/chrome/content/netError.css
+++ /dev/null
@@ -1,131 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This defines the look-and-feel styling of the error pages.
- * (see: netError.xhtml)
- *
- * Original styling by William Price <bugzilla@mob.rice.edu>
- * Updated for mobile by: Wes Johnston <wjohnston@mozilla.com>
- */
-
-body {
- margin: 0;
- padding: 0 8px 8px;
- font-family: "Nokia Sans", Tahoma, sans-serif !important;
-}
-
-h1 {
- font-size: 22px;
-}
-
-h2 {
- font-size: 16px;
-}
-
-ul {
- margin: 0px;
- padding: 0px 0px 0px 1em;
-}
-
-li {
- margin: 0px;
- padding: 8px 0px;
-}
-
-#errorPage {
- background-color: #CEE6F4;
-}
-
-#errorPage.certerror {
- background-color: #EFD400;
-}
-
-#errorPage.blockedsite {
- background-color: #BF0000;
-}
-
-#errorTitle {
- background: url("chrome://b2g/content/images/errorpage-warning.png") left center no-repeat;
- /* Scaled by .666 of their actual size */
- background-size: 40px 40px;
- background-origin: content-box;
- min-height: 60px;
- margin-left: auto;
- margin-right: auto;
- max-width: 500px;
- margin-left: auto;
- margin-right: auto;
-}
-
-#errorPage.certerror #errorTitle {
- background-image: url("chrome://b2g/content/images/errorpage-larry-black.png");
-}
-
-#errorPage.blockedsite #errorTitle {
- background-image: url("chrome://b2g/content/images/errorpage-larry-white.png");
- color: white;
-}
-
-.errorTitleText {
- padding: 0px 0px 0px 50px;
- display: inline-block;
- vertical-align: middle
-}
-
-#errorPageContainer {
- background-color: white;
- border: 1px solid #999999;
- border-radius: 6px;
- padding: 6px 20px 20px;
- font-size: 14px;
- max-width: 500px;
- margin-left: auto;
- margin-right: auto;
-}
-
-#errorShortDesc > p:empty {
- display: none;
-}
-
-#errorShortDesc > p {
- overflow: auto;
- border-bottom: 1px solid #999999;
- padding-bottom: 1em;
-}
-
-#errorPage.blockedsite #errorShortDesc > p {
- font-weight: bold;
- border-bottom: none;
- padding-bottom: 0px;
-}
-
-#securityOverrideDiv {
- padding-top: 10px;
-}
-
-div[collapsed] {
- padding-left: 15px;
- background-image: url("chrome://b2g/content/images/arrowright-16.png");
- background-size: 11px 11px;
- background-repeat: no-repeat;
- background-position: left 0.3em;
-}
-
-div[collapsed="true"] {
- background-image: url("chrome://b2g/content/images/arrowright-16.png");
-}
-
-div[collapsed="false"] {
- background-image: url("chrome://b2g/content/images/arrowdown-16.png");
-}
-
-div[collapsed="true"] > p,
-div[collapsed="true"] > div {
- display: none;
-}
-
-button {
- padding: 0.3em !important;
-}
diff --git a/b2g/chrome/content/screen.js b/b2g/chrome/content/screen.js
deleted file mode 100644
index a893e8844..000000000
--- a/b2g/chrome/content/screen.js
+++ /dev/null
@@ -1,276 +0,0 @@
-// screen.js:
-// Set the screen size, pixel density and scaling of the b2g client screen
-// based on the --screen command-line option, if there is one.
-//
-// TODO: support multiple device pixels per CSS pixel
-//
-
-var browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
-var isMulet = "ResponsiveUI" in browserWindow;
-Cu.import("resource://gre/modules/GlobalSimulatorScreen.jsm");
-
-window.addEventListener('ContentStart', onStart);
-window.addEventListener('SafeModeStart', onStart);
-
-// We do this on ContentStart and SafeModeStart because querying the
-// displayDPI fails otherwise.
-function onStart() {
- // This is the toplevel <window> element
- let shell = document.getElementById('shell');
-
- // The <browser> element inside it
- let browser = document.getElementById('systemapp');
-
- // Figure out the native resolution of the screen
- let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- let hostDPI = windowUtils.displayDPI;
-
- let DEFAULT_SCREEN = '320x480';
-
- // This is a somewhat random selection of named screens.
- // Add more to this list when we support more hardware.
- // Data from: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
- let screens = {
- iphone: {
- name: 'Apple iPhone', width:320, height:480, dpi:163
- },
- ipad: {
- name: 'Apple iPad', width:1024, height:768, dpi:132
- },
- nexus_s: {
- name: 'Samsung Nexus S', width:480, height:800, dpi:235
- },
- galaxy_s2: {
- name: 'Samsung Galaxy SII (I9100)', width:480, height:800, dpi:219
- },
- galaxy_nexus: {
- name: 'Samsung Galaxy Nexus', width:720, height:1280, dpi:316
- },
- galaxy_tab: {
- name: 'Samsung Galaxy Tab 10.1', width:800, height:1280, dpi:149
- },
- wildfire: {
- name: 'HTC Wildfire', width:240, height:320, dpi:125
- },
- tattoo: {
- name: 'HTC Tattoo', width:240, height:320, dpi:143
- },
- salsa: {
- name: 'HTC Salsa', width:320, height:480, dpi:170
- },
- chacha: {
- name: 'HTC ChaCha', width:320, height:480, dpi:222
- },
- };
-
- // Get the command line arguments that were passed to the b2g client
- let args;
- try {
- let service = Cc["@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds"].getService(Ci.nsISupports);
- args = service.wrappedJSObject.cmdLine;
- } catch(e) {}
-
- let screenarg = null;
-
- // Get the --screen argument from the command line
- try {
- if (args) {
- screenarg = args.handleFlagWithParam('screen', false);
- }
-
- // Override default screen size with a pref
- if (screenarg === null && Services.prefs.prefHasUserValue('b2g.screen.size')) {
- screenarg = Services.prefs.getCharPref('b2g.screen.size');
- }
-
- // If there isn't one, use the default screen
- if (screenarg === null)
- screenarg = DEFAULT_SCREEN;
-
- // With no value, tell the user how to use it
- if (screenarg == '')
- usage();
- }
- catch(e) {
- // If getting the argument value fails, its an error
- usage();
- }
-
- // Special case --screen=full goes into fullscreen mode
- if (screenarg === 'full') {
- shell.setAttribute('sizemode', 'fullscreen');
- return;
- }
-
- let width, height, ratio = 1.0;
- let lastResizedWidth;
-
- if (screenarg in screens) {
- // If this is a named screen, get its data
- let screen = screens[screenarg];
- width = screen.width;
- height = screen.height;
- ratio = screen.ratio;
- } else {
- // Otherwise, parse the resolution and density from the --screen value.
- // The supported syntax is WIDTHxHEIGHT[@DPI]
- let match = screenarg.match(/^(\d+)x(\d+)(@(\d+(\.\d+)?))?$/);
-
- // Display usage information on syntax errors
- if (match == null)
- usage();
-
- // Convert strings to integers
- width = parseInt(match[1], 10);
- height = parseInt(match[2], 10);
- if (match[4])
- ratio = parseFloat(match[4], 10);
-
- // If any of the values came out 0 or NaN or undefined, display usage
- if (!width || !height || !ratio) {
- usage();
- }
- }
-
- Services.prefs.setCharPref('layout.css.devPixelsPerPx',
- ratio == 1 ? -1 : ratio);
- let defaultOrientation = width < height ? 'portrait' : 'landscape';
- GlobalSimulatorScreen.mozOrientation = GlobalSimulatorScreen.screenOrientation = defaultOrientation;
-
- function resize() {
- GlobalSimulatorScreen.width = width;
- GlobalSimulatorScreen.height = height;
-
- // Set the window width and height to desired size plus chrome
- // Include the size of the toolbox displayed under the system app
- let controls = document.getElementById('controls');
- let controlsHeight = controls ? controls.getBoundingClientRect().height : 0;
-
- if (isMulet) {
- let tab = browserWindow.gBrowser.selectedTab;
- let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
- responsive.setSize(width + 16*2,
- height + controlsHeight + 61);
- } else {
- let chromewidth = window.outerWidth - window.innerWidth;
- let chromeheight = window.outerHeight - window.innerHeight + controlsHeight;
-
- if (lastResizedWidth == width) {
- return;
- }
- lastResizedWidth = width;
-
- window.resizeTo(width + chromewidth,
- height + chromeheight);
- }
-
- let frameWidth = width, frameHeight = height;
-
- // If the current app doesn't supports the current screen orientation
- // still resize the window, but rotate its frame so that
- // it is displayed rotated on the side
- let shouldFlip = GlobalSimulatorScreen.mozOrientation != GlobalSimulatorScreen.screenOrientation;
-
- if (shouldFlip) {
- frameWidth = height;
- frameHeight = width;
- }
-
- // Set the browser element to the full unscaled size of the screen
- let style = browser.style;
- style.transform = '';
- style.height = 'calc(100% - ' + controlsHeight + 'px)';
- style.bottom = controlsHeight;
-
- style.width = frameWidth + "px";
- style.height = frameHeight + "px";
-
- if (shouldFlip) {
- // Display the system app with a 90° clockwise rotation
- let shift = Math.floor(Math.abs(frameWidth - frameHeight) / 2);
- style.transform +=
- ' rotate(0.25turn) translate(-' + shift + 'px, -' + shift + 'px)';
- }
- }
-
- // Resize on startup
- resize();
-
- // Catch manual resizes to update the internal device size.
- window.onresize = function() {
- let controls = document.getElementById('controls');
- let controlsHeight = controls ? controls.getBoundingClientRect().height : 0;
-
- width = window.innerWidth;
- height = window.innerHeight - controlsHeight;
-
- queueResize();
- };
-
- // Then resize on each rotation button click,
- // or when the system app lock/unlock the orientation
- Services.obs.addObserver(function orientationChangeListener(subject) {
- let screen = subject.wrappedJSObject;
- let { mozOrientation, screenOrientation } = screen;
-
- // If we have an orientation different than the current one,
- // we switch the sizes
- if (screenOrientation != defaultOrientation) {
- let w = width;
- width = height;
- height = w;
- }
- defaultOrientation = screenOrientation;
-
- queueResize();
- }, 'simulator-adjust-window-size', false);
-
- // Queue resize request in order to prevent race and slowdowns
- // by requesting resize multiple times per loop
- let resizeTimeout;
- function queueResize() {
- if (resizeTimeout) {
- clearTimeout(resizeTimeout);
- }
- resizeTimeout = setTimeout(function () {
- resizeTimeout = null;
- resize();
- }, 0);
- }
-
- // A utility function like console.log() for printing to the terminal window
- // Uses dump(), but enables it first, if necessary
- function print() {
- let dump_enabled =
- Services.prefs.getBoolPref('browser.dom.window.dump.enabled');
-
- if (!dump_enabled)
- Services.prefs.setBoolPref('browser.dom.window.dump.enabled', true);
-
- dump(Array.prototype.join.call(arguments, ' ') + '\n');
-
- if (!dump_enabled)
- Services.prefs.setBoolPref('browser.dom.window.dump.enabled', false);
- }
-
- // Print usage info for --screen and exit
- function usage() {
- // Documentation for the --screen argument
- let msg =
- 'The --screen argument specifies the desired resolution and\n' +
- 'pixel density of the simulated device screen. Use it like this:\n' +
- '\t--screen=WIDTHxHEIGHT\t\t\t// E.g.: --screen=320x480\n' +
- '\t--screen=WIDTHxHEIGHT@DOTS_PER_INCH\t// E.g.: --screen=480x800@250\n' +
- '\t--screen=full\t\t\t\t// run in fullscreen mode\n' +
- '\nYou can also specify certain device names:\n';
- for(let p in screens)
- msg += '\t--screen=' + p + '\t// ' + screens[p].name + '\n';
-
- // Display the usage message
- print(msg);
-
- // Exit the b2g client
- Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
- }
-}
diff --git a/b2g/chrome/content/settings.js b/b2g/chrome/content/settings.js
deleted file mode 100644
index 95921da4c..000000000
--- a/b2g/chrome/content/settings.js
+++ /dev/null
@@ -1,698 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-window.performance.mark('gecko-settings-loadstart');
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-var Cr = Components.results;
-
-// The load order is important here SettingsRequestManager _must_ be loaded
-// prior to using SettingsListener otherwise there is a race in acquiring the
-// lock and fulfilling it. If we ever move SettingsListener or this file down in
-// the load order of shell.html things will likely break.
-Cu.import('resource://gre/modules/SettingsRequestManager.jsm');
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/AppConstants.jsm');
-
-const isGonk = AppConstants.platform === 'gonk';
-
-if (isGonk) {
- XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
- Cu.import("resource://gre/modules/systemlibs.js");
- return libcutils;
- });
-}
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
- "@mozilla.org/uuid-generator;1",
- "nsIUUIDGenerator");
-
-// Once Bug 731746 - Allow chrome JS object to implement nsIDOMEventTarget
-// is resolved this helper could be removed.
-var SettingsListener = {
- _callbacks: {},
-
- init: function sl_init() {
- if ('mozSettings' in navigator && navigator.mozSettings) {
- navigator.mozSettings.onsettingchange = this.onchange.bind(this);
- }
- },
-
- onchange: function sl_onchange(evt) {
- var callback = this._callbacks[evt.settingName];
- if (callback) {
- callback(evt.settingValue);
- }
- },
-
- observe: function sl_observe(name, defaultValue, callback) {
- var settings = window.navigator.mozSettings;
- if (!settings) {
- window.setTimeout(function() { callback(defaultValue); });
- return;
- }
-
- if (!callback || typeof callback !== 'function') {
- throw new Error('Callback is not a function');
- }
-
- var req = settings.createLock().get(name);
- req.addEventListener('success', (function onsuccess() {
- callback(typeof(req.result[name]) != 'undefined' ?
- req.result[name] : defaultValue);
- }));
-
- this._callbacks[name] = callback;
- }
-};
-
-SettingsListener.init();
-
-// =================== Mono Audio ======================
-
-SettingsListener.observe('accessibility.monoaudio.enable', false, function(value) {
- Services.prefs.setBoolPref('accessibility.monoaudio.enable', value);
-});
-
-// =================== Console ======================
-
-SettingsListener.observe('debug.console.enabled', true, function(value) {
- Services.prefs.setBoolPref('consoleservice.enabled', value);
- Services.prefs.setBoolPref('layout.css.report_errors', value);
-});
-
-SettingsListener.observe('homescreen.manifestURL', 'Sentinel Value' , function(value) {
- Services.prefs.setCharPref('dom.mozApps.homescreenURL', value);
-});
-
-// =================== Languages ====================
-SettingsListener.observe('language.current', 'en-US', function(value) {
- Services.prefs.setCharPref('general.useragent.locale', value);
-
- let prefName = 'intl.accept_languages';
- let defaultBranch = Services.prefs.getDefaultBranch(null);
-
- let intl = '';
- try {
- intl = defaultBranch.getComplexValue(prefName,
- Ci.nsIPrefLocalizedString).data;
- } catch(e) {}
-
- // Bug 830782 - Homescreen is in English instead of selected locale after
- // the first run experience.
- // In order to ensure the current intl value is reflected on the child
- // process let's always write a user value, even if this one match the
- // current localized pref value.
- if (!((new RegExp('^' + value + '[^a-z-_] *[,;]?', 'i')).test(intl))) {
- value = value + ', ' + intl;
- } else {
- value = intl;
- }
- Services.prefs.setCharPref(prefName, value);
-
- if (shell.hasStarted() == false) {
- shell.bootstrap();
- }
-});
-
-// =================== RIL ====================
-(function RILSettingsToPrefs() {
- // DSDS default service IDs
- ['mms', 'sms', 'telephony'].forEach(function(key) {
- SettingsListener.observe('ril.' + key + '.defaultServiceId', 0,
- function(value) {
- if (value != null) {
- Services.prefs.setIntPref('dom.' + key + '.defaultServiceId', value);
- }
- });
- });
-})();
-
-//=================== DeviceInfo ====================
-Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
-Components.utils.import('resource://gre/modules/ctypes.jsm');
-(function DeviceInfoToSettings() {
- // MOZ_B2G_VERSION is set in b2g/confvars.sh, and is output as a #define value
- // from configure.in, defaults to 1.0.0 if this value is not exist.
- let os_version = AppConstants.MOZ_B2G_VERSION;
- let os_name = AppConstants.MOZ_B2G_OS_NAME;
-
- let appInfo = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULAppInfo);
-
- // Get the hardware info and firmware revision from device properties.
- let hardware_info = null;
- let firmware_revision = null;
- let product_manufacturer = null;
- let product_model = null;
- let product_device = null;
- let build_number = null;
- if (isGonk) {
- hardware_info = libcutils.property_get('ro.hardware');
- firmware_revision = libcutils.property_get('ro.firmware_revision');
- product_manufacturer = libcutils.property_get('ro.product.manufacturer');
- product_model = libcutils.property_get('ro.product.model');
- product_device = libcutils.property_get('ro.product.device');
- build_number = libcutils.property_get('ro.build.version.incremental');
- }
-
- // Populate deviceinfo settings,
- // copying any existing deviceinfo.os into deviceinfo.previous_os
- let lock = window.navigator.mozSettings.createLock();
- let req = lock.get('deviceinfo.os');
- req.onsuccess = req.onerror = () => {
- let previous_os = req.result && req.result['deviceinfo.os'] || '';
- let software = os_name + ' ' + os_version;
- let setting = {
- 'deviceinfo.build_number': build_number,
- 'deviceinfo.os': os_version,
- 'deviceinfo.previous_os': previous_os,
- 'deviceinfo.software': software,
- 'deviceinfo.platform_version': appInfo.platformVersion,
- 'deviceinfo.platform_build_id': appInfo.platformBuildID,
- 'deviceinfo.hardware': hardware_info,
- 'deviceinfo.firmware_revision': firmware_revision,
- 'deviceinfo.product_manufacturer': product_manufacturer,
- 'deviceinfo.product_model': product_model,
- 'deviceinfo.product_device': product_device
- }
- lock.set(setting);
- }
-})();
-
-// =================== DevTools ====================
-
-var developerHUD;
-SettingsListener.observe('devtools.overlay', false, (value) => {
- if (value) {
- if (!developerHUD) {
- let scope = {};
- Services.scriptloader.loadSubScript('chrome://b2g/content/devtools/hud.js', scope);
- developerHUD = scope.developerHUD;
- }
- developerHUD.init();
- } else {
- if (developerHUD) {
- developerHUD.uninit();
- }
- }
-});
-
-if (isGonk) {
- var LogShake;
- (function() {
- let scope = {};
- Cu.import('resource://gre/modules/LogShake.jsm', scope);
- LogShake = scope.LogShake;
- LogShake.init();
- })();
-
- SettingsListener.observe('devtools.logshake.enabled', false, value => {
- if (value) {
- LogShake.enableDeviceMotionListener();
- } else {
- LogShake.disableDeviceMotionListener();
- }
- });
-
- SettingsListener.observe('devtools.logshake.qa_enabled', false, value => {
- if (value) {
- LogShake.enableQAMode();
- } else {
- LogShake.disableQAMode();
- }
- });
-}
-
-// =================== Device Storage ====================
-SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
- if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {
- // We clear the pref because it used to be erroneously written as a bool
- // and we need to clear it before we can change it to have the correct type.
- Services.prefs.clearUserPref('device.storage.writable.name');
- }
- Services.prefs.setCharPref('device.storage.writable.name', value);
-});
-
-// =================== Privacy ====================
-SettingsListener.observe('privacy.donottrackheader.value', 1, function(value) {
- Services.prefs.setIntPref('privacy.donottrackheader.value', value);
- // If the user specifically disallows tracking, we set the value of
- // app.update.custom (update tracking ID) to an empty string.
- if (value == 1) {
- Services.prefs.setCharPref('app.update.custom', '');
- return;
- }
- // Otherwise, we assure that the update tracking ID exists.
- setUpdateTrackingId();
-});
-
-// =================== Crash Reporting ====================
-SettingsListener.observe('app.reportCrashes', 'ask', function(value) {
- if (value == 'always') {
- Services.prefs.setBoolPref('app.reportCrashes', true);
- } else if (value == 'never') {
- Services.prefs.setBoolPref('app.reportCrashes', false);
- } else {
- Services.prefs.clearUserPref('app.reportCrashes');
- }
- // This preference is consulted during startup.
- Services.prefs.savePrefFile(null);
-});
-
-// ================ Updates ================
-/**
- * For tracking purposes some partners require us to add an UUID to the
- * update URL. The update tracking ID will be an empty string if the
- * do-not-track feature specifically disallows tracking and it is reseted
- * to a different ID if the do-not-track value changes from disallow to allow.
- */
-function setUpdateTrackingId() {
- try {
- let dntEnabled = Services.prefs.getBoolPref('privacy.donottrackheader.enabled');
- let dntValue = Services.prefs.getIntPref('privacy.donottrackheader.value');
- // If the user specifically decides to disallow tracking (1), we just bail out.
- if (dntEnabled && (dntValue == 1)) {
- return;
- }
-
- let trackingId =
- Services.prefs.getPrefType('app.update.custom') ==
- Ci.nsIPrefBranch.PREF_STRING &&
- Services.prefs.getCharPref('app.update.custom');
-
- // If there is no previous registered tracking ID, we generate a new one.
- // This should only happen on first usage or after changing the
- // do-not-track value from disallow to allow.
- if (!trackingId) {
- trackingId = uuidgen.generateUUID().toString().replace(/[{}]/g, "");
- Services.prefs.setCharPref('app.update.custom', trackingId);
- }
- } catch(e) {
- dump('Error getting tracking ID ' + e + '\n');
- }
-}
-setUpdateTrackingId();
-
-(function syncUpdatePrefs() {
- // The update service reads the prefs from the default branch. This is by
- // design, as explained in bug 302721 comment 43. If we are to successfully
- // modify them, that's where we need to make our changes.
- let defaultBranch = Services.prefs.getDefaultBranch(null);
-
- function syncPrefDefault(prefName) {
- // The pref value at boot-time will serve as default for the setting.
- let defaultValue = defaultBranch.getCharPref(prefName);
- let defaultSetting = {};
- defaultSetting[prefName] = defaultValue;
-
- // We back up that value in order to detect pref changes across reboots.
- // Such a change can happen e.g. when the user installs an OTA update that
- // changes the update URL format.
- let backupName = prefName + '.old';
- try {
- // Everything relies on the comparison below: When pushing a new Gecko
- // that changes app.update.url or app.update.channel, we overwrite any
- // existing setting with the new pref value.
- let backupValue = Services.prefs.getCharPref(backupName);
- if (defaultValue !== backupValue) {
- // If the pref has changed since our last backup, overwrite the setting.
- navigator.mozSettings.createLock().set(defaultSetting);
- }
- } catch(e) {
- // There was no backup: Overwrite the setting and create a backup below.
- navigator.mozSettings.createLock().set(defaultSetting);
- }
-
- // Initialize or update the backup value.
- Services.prefs.setCharPref(backupName, defaultValue);
-
- // Propagate setting changes to the pref.
- SettingsListener.observe(prefName, defaultValue, value => {
- if (!value) {
- // If the setting value is invalid, reset it to its default.
- navigator.mozSettings.createLock().set(defaultSetting);
- return;
- }
- // Here we will overwrite the pref with the setting value.
- defaultBranch.setCharPref(prefName, value);
- });
- }
-
- syncPrefDefault('app.update.url');
- syncPrefDefault('app.update.channel');
-})();
-
-// ================ Debug ================
-(function Composer2DSettingToPref() {
- //layers.composer.enabled can be enabled in three ways
- //In order of precedence they are:
- //
- //1. mozSettings "layers.composer.enabled"
- //2. a gecko pref "layers.composer.enabled"
- //3. presence of ro.display.colorfill at the Gonk level
-
- var req = navigator.mozSettings.createLock().get('layers.composer2d.enabled');
- req.onsuccess = function() {
- if (typeof(req.result['layers.composer2d.enabled']) === 'undefined') {
- var enabled = false;
- if (Services.prefs.getPrefType('layers.composer2d.enabled') == Ci.nsIPrefBranch.PREF_BOOL) {
- enabled = Services.prefs.getBoolPref('layers.composer2d.enabled');
- } else if (isGonk) {
- let androidVersion = libcutils.property_get("ro.build.version.sdk");
- if (androidVersion >= 17 ) {
- enabled = true;
- } else {
- enabled = (libcutils.property_get('ro.display.colorfill') === '1');
- }
- }
- navigator.mozSettings.createLock().set({'layers.composer2d.enabled': enabled });
- }
-
- SettingsListener.observe("layers.composer2d.enabled", true, function(value) {
- Services.prefs.setBoolPref("layers.composer2d.enabled", value);
- });
- };
- req.onerror = function() {
- dump("Error configuring layers.composer2d.enabled setting");
- };
-
-})();
-
-// ================ Accessibility ============
-(function setupAccessibility() {
- let accessibilityScope = {};
- SettingsListener.observe("accessibility.screenreader", false, function(value) {
- if (!value) {
- return;
- }
- if (!('AccessFu' in accessibilityScope)) {
- Cu.import('resource://gre/modules/accessibility/AccessFu.jsm',
- accessibilityScope);
- accessibilityScope.AccessFu.attach(window);
- }
- });
-})();
-
-// ================ Theming ============
-(function themingSettingsListener() {
- let themingPrefs = ['ui.menu', 'ui.menutext', 'ui.infobackground', 'ui.infotext',
- 'ui.window', 'ui.windowtext', 'ui.highlight'];
-
- themingPrefs.forEach(function(pref) {
- SettingsListener.observe('gaia.' + pref, null, function(value) {
- if (value) {
- Services.prefs.setCharPref(pref, value);
- }
- });
- });
-})();
-
-// =================== Telemetry ======================
-(function setupTelemetrySettings() {
- let gaiaSettingName = 'debug.performance_data.shared';
- let geckoPrefName = 'toolkit.telemetry.enabled';
- SettingsListener.observe(gaiaSettingName, null, function(value) {
- if (value !== null) {
- // Gaia setting has been set; update Gecko pref to that.
- Services.prefs.setBoolPref(geckoPrefName, value);
- return;
- }
- // Gaia setting has not been set; set the gaia setting to default.
- let prefValue = AppConstants.MOZ_TELEMETRY_ON_BY_DEFAULT;
- try {
- prefValue = Services.prefs.getBoolPref(geckoPrefName);
- } catch (e) {
- // Pref not set; use default value.
- }
- let setting = {};
- setting[gaiaSettingName] = prefValue;
- window.navigator.mozSettings.createLock().set(setting);
- });
-})();
-
-// =================== Low-precision buffer ======================
-(function setupLowPrecisionSettings() {
- // The gaia setting layers.low-precision maps to two gecko prefs
- SettingsListener.observe('layers.low-precision', null, function(value) {
- if (value !== null) {
- // Update gecko from the new Gaia setting
- Services.prefs.setBoolPref('layers.low-precision-buffer', value);
- Services.prefs.setBoolPref('layers.progressive-paint', value);
- } else {
- // Update gaia setting from gecko value
- try {
- let prefValue = Services.prefs.getBoolPref('layers.low-precision-buffer');
- let setting = { 'layers.low-precision': prefValue };
- window.navigator.mozSettings.createLock().set(setting);
- } catch (e) {
- console.log('Unable to read pref layers.low-precision-buffer: ' + e);
- }
- }
- });
-
- // The gaia setting layers.low-opacity maps to a string gecko pref (0.5/1.0)
- SettingsListener.observe('layers.low-opacity', null, function(value) {
- if (value !== null) {
- // Update gecko from the new Gaia setting
- Services.prefs.setCharPref('layers.low-precision-opacity', value ? '0.5' : '1.0');
- } else {
- // Update gaia setting from gecko value
- try {
- let prefValue = Services.prefs.getCharPref('layers.low-precision-opacity');
- let setting = { 'layers.low-opacity': (prefValue == '0.5') };
- window.navigator.mozSettings.createLock().set(setting);
- } catch (e) {
- console.log('Unable to read pref layers.low-precision-opacity: ' + e);
- }
- }
- });
-})();
-
-// ======================= Dogfooders FOTA ==========================
-if (AppConstants.MOZ_B2G_RIL) {
- XPCOMUtils.defineLazyModuleGetter(this, "AppsUtils",
- "resource://gre/modules/AppsUtils.jsm");
-
- SettingsListener.observe('debug.performance_data.dogfooding', false,
- isDogfooder => {
- if (!isDogfooder) {
- dump('AUS:Settings: Not a dogfooder!\n');
- return;
- }
-
- if (!('mozTelephony' in navigator)) {
- dump('AUS:Settings: There is no mozTelephony!\n');
- return;
- }
-
- if (!('mozMobileConnections' in navigator)) {
- dump('AUS:Settings: There is no mozMobileConnections!\n');
- return;
- }
-
- let conn = navigator.mozMobileConnections[0];
- conn.addEventListener('radiostatechange', function onradiostatechange() {
- if (conn.radioState !== 'enabled') {
- return;
- }
-
- conn.removeEventListener('radiostatechange', onradiostatechange);
- navigator.mozTelephony.dial('*#06#').then(call => {
- return call.result.then(res => {
- if (res.success && res.statusMessage
- && (res.serviceCode === 'scImei')) {
- Services.prefs.setCharPref("app.update.imei_hash",
- AppsUtils.computeHash(res.statusMessage, "SHA512"));
- }
- });
- });
- });
- });
-}
-
-// =================== Various simple mapping ======================
-var settingsToObserve = {
- 'accessibility.screenreader_quicknav_modes': {
- prefName: 'accessibility.accessfu.quicknav_modes',
- resetToPref: true,
- defaultValue: ''
- },
- 'accessibility.screenreader_quicknav_index': {
- prefName: 'accessibility.accessfu.quicknav_index',
- resetToPref: true,
- defaultValue: 0
- },
- 'app.update.interval': 86400,
- 'apz.overscroll.enabled': true,
- 'browser.safebrowsing.phishing.enabled': true,
- 'browser.safebrowsing.malware.enabled': true,
- 'debug.fps.enabled': {
- prefName: 'layers.acceleration.draw-fps',
- defaultValue: false
- },
- 'debug.log-animations.enabled': {
- prefName: 'layers.offmainthreadcomposition.log-animations',
- defaultValue: false
- },
- 'debug.paint-flashing.enabled': {
- prefName: 'nglayout.debug.paint_flashing',
- defaultValue: false
- },
- // FIXME: Bug 1185806 - Provide a common device name setting.
- // Borrow device name from developer's menu to avoid multiple name settings.
- 'devtools.discovery.device': {
- prefName: 'dom.presentation.device.name',
- defaultValue: 'Firefox OS'
- },
- 'devtools.eventlooplag.threshold': 100,
- 'devtools.remote.wifi.visible': {
- resetToPref: true
- },
- 'devtools.telemetry.supported_performance_marks': {
- resetToPref: true
- },
-
- 'dom.presentation.discovery.enabled': false,
- 'dom.presentation.discoverable': false,
- 'dom.serviceWorkers.testing.enabled': false,
- 'gfx.layerscope.enabled': false,
- 'layers.draw-borders': false,
- 'layers.draw-tile-borders': false,
- 'layers.dump': false,
- 'layers.enable-tiles': AppConstants.platform !== "win",
- 'layers.enable-tiles': true,
- 'layers.effect.invert': false,
- 'layers.effect.grayscale': false,
- 'layers.effect.contrast': '0.0',
- 'layout.display-list.dump': false,
- 'mms.debugging.enabled': false,
- 'network.debugging.enabled': false,
- 'privacy.donottrackheader.enabled': false,
- 'privacy.trackingprotection.enabled': false,
- 'ril.debugging.enabled': false,
- 'ril.radio.disabled': false,
- 'ril.mms.requestReadReport.enabled': {
- prefName: 'dom.mms.requestReadReport',
- defaultValue: true
- },
- 'ril.mms.requestStatusReport.enabled': {
- prefName: 'dom.mms.requestStatusReport',
- defaultValue: false
- },
- 'ril.mms.retrieval_mode': {
- prefName: 'dom.mms.retrieval_mode',
- defaultValue: 'manual'
- },
- 'ril.sms.requestStatusReport.enabled': {
- prefName: 'dom.sms.requestStatusReport',
- defaultValue: false
- },
- 'ril.sms.strict7BitEncoding.enabled': {
- prefName: 'dom.sms.strict7BitEncoding',
- defaultValue: false
- },
- 'ril.sms.maxReadAheadEntries': {
- prefName: 'dom.sms.maxReadAheadEntries',
- defaultValue: 7
- },
- 'services.sync.enabled': {
- defaultValue: false,
- notifyChange: true
- },
- 'ui.touch.radius.leftmm': {
- resetToPref: true
- },
- 'ui.touch.radius.topmm': {
- resetToPref: true
- },
- 'ui.touch.radius.rightmm': {
- resetToPref: true
- },
- 'ui.touch.radius.bottommm': {
- resetToPref: true
- },
- 'ui.click_hold_context_menus.delay': {
- resetToPref: true
- },
- 'wap.UAProf.tagname': 'x-wap-profile',
- 'wap.UAProf.url': ''
-};
-
-if (AppConstants.MOZ_GRAPHENE) {
- // Restart required
- settingsToObserve['layers.async-pan-zoom.enabled'] = false;
-}
-
-function settingObserver(setPref, prefName, setting) {
- return value => {
- setPref(prefName, value);
- if (setting.notifyChange) {
- SystemAppProxy._sendCustomEvent('mozPrefChromeEvent', {
- prefName: prefName,
- value: value
- });
- }
- };
-}
-
-for (let key in settingsToObserve) {
- let setting = settingsToObserve[key];
-
- // Allow setting to contain flags redefining prefName and defaultValue.
- let prefName = setting.prefName || key;
- let defaultValue = setting.defaultValue;
- if (defaultValue === undefined) {
- defaultValue = setting;
- }
-
- let prefs = Services.prefs;
-
- // If requested, reset setting value and defaultValue to the pref value.
- if (setting.resetToPref) {
- switch (prefs.getPrefType(prefName)) {
- case Ci.nsIPrefBranch.PREF_BOOL:
- defaultValue = prefs.getBoolPref(prefName);
- break;
-
- case Ci.nsIPrefBranch.PREF_INT:
- defaultValue = prefs.getIntPref(prefName);
- break;
-
- case Ci.nsIPrefBranch.PREF_STRING:
- defaultValue = prefs.getCharPref(prefName);
- break;
- }
-
- let setting = {};
- setting[key] = defaultValue;
- window.navigator.mozSettings.createLock().set(setting);
- }
-
- // Figure out the right setter function for this type of pref.
- let setPref;
- switch (typeof defaultValue) {
- case 'boolean':
- setPref = prefs.setBoolPref.bind(prefs);
- break;
-
- case 'number':
- setPref = prefs.setIntPref.bind(prefs);
- break;
-
- case 'string':
- setPref = prefs.setCharPref.bind(prefs);
- break;
- }
-
- SettingsListener.observe(key, defaultValue,
- settingObserver(setPref, prefName, setting));
-};
diff --git a/b2g/chrome/content/shell.css b/b2g/chrome/content/shell.css
deleted file mode 100644
index 34daafd99..000000000
--- a/b2g/chrome/content/shell.css
+++ /dev/null
@@ -1,81 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-html {
- background: black;
- overflow: hidden;
- width: 100%;
- height: 100%;
- padding: 0 !important;
-}
-body {
- margin: 0;
- width: 100%;
- height: 100%;
- overflow: hidden;
-}
-iframe {
- overflow: hidden;
- height: 100%;
- width: 100%;
- border: none;
- position: absolute;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
- z-index: 1;
- -moz-user-select: none;
-}
-
-%ifdef MOZ_GRAPHENE
-
-body.content-loaded > #installing {
- display: none;
-}
-
-#installing {
- z-index: 2;
- position: absolute;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: #F1C40F;
- color: #FFF;
-}
-
-.throbber {
- width: 3px;
- height: 3px;
- border-radius: 100px;
- background-color: #FFF;
- animation-name: throbber;
- animation-duration: 1500ms;
- animation-iteration-count: infinite;
- animation-timing-function: linear;
-}
-
-#titlebar-buttonbox {
- margin: 6px 7px;
- -moz-appearance: -moz-window-button-box;
-}
-
-@keyframes throbber{
- from {
- transform: scale(0);
- opacity: 0.4;
- }
- to {
- transform: scale(400);
- opacity: 0;
- }
-}
-
-%endif
diff --git a/b2g/chrome/content/shell.html b/b2g/chrome/content/shell.html
deleted file mode 100644
index 5507a65aa..000000000
--- a/b2g/chrome/content/shell.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this file,
- - You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml"
- id="shell"
- windowtype="navigator:browser"
-#ifdef ANDROID
- sizemode="fullscreen"
-#endif
-#ifdef MOZ_GRAPHENE
- macanimationtype="document"
- fullscreenbutton="true"
- chromemargin="0,0,0,0"
-#endif
- >
-
-<head>
- <link rel="stylesheet" href="shell.css" type="text/css">
- <script type="text/javascript">
- <!-- Add raptor performance marker -->
- window.performance.mark('gecko-shell-html-load');
- </script>
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/settings.js"> </script>
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/shell.js"> </script>
-
-#ifndef ANDROID
-#ifndef MOZ_GRAPHENE
- <!-- various task that has to happen only on desktop -->
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/desktop.js"> </script>
- <!-- this script handles the screen argument for desktop builds -->
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/screen.js"> </script>
-#endif
-#else
- <!-- this file is only loaded on Gonk to manage ADB state -->
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/devtools/adb.js"> </script>
-#endif
- <!-- manages DevTools server state -->
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/devtools/debugger.js"> </script>
-</head>
- <body id="container">
-#ifndef MOZ_GRAPHENE
-#ifdef MOZ_WIDGET_COCOA
- <!--
- If the document is empty at startup, we don't display the window
- at all on Mac OS...
- -->
- <h1 id="placeholder">wtf mac os!</h1>
-#endif
-#else
- <div id="titlebar-buttonbox"></div>
- <div id="installing">
- <div class="throbber"></div>
- <div class="message"></div>
- </div>
-#endif
- <!-- The html:iframe containing the UI is created here. -->
- </body>
-</html>
diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js
deleted file mode 100644
index d483f9a64..000000000
--- a/b2g/chrome/content/shell.js
+++ /dev/null
@@ -1,1308 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-window.performance.mark('gecko-shell-loadstart');
-
-Cu.import('resource://gre/modules/NotificationDB.jsm');
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
-Cu.import('resource://gre/modules/Keyboard.jsm');
-Cu.import('resource://gre/modules/ErrorPage.jsm');
-Cu.import('resource://gre/modules/AlertsHelper.jsm');
-Cu.import('resource://gre/modules/SystemUpdateService.jsm');
-
-if (isGonk) {
- Cu.import('resource://gre/modules/NetworkStatsService.jsm');
- Cu.import('resource://gre/modules/ResourceStatsService.jsm');
-}
-
-// Identity
-Cu.import('resource://gre/modules/SignInToWebsite.jsm');
-SignInToWebsiteController.init();
-
-Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
-Cu.import('resource://gre/modules/DownloadsAPI.jsm');
-Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm');
-Cu.import('resource://gre/modules/AboutServiceWorkers.jsm');
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Screenshot",
- "resource://gre/modules/Screenshot.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'env',
- '@mozilla.org/process/environment;1',
- 'nsIEnvironment');
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'ss',
- '@mozilla.org/content/style-sheet-service;1',
- 'nsIStyleSheetService');
-
-XPCOMUtils.defineLazyServiceGetter(this, 'gSystemMessenger',
- '@mozilla.org/system-message-internal;1',
- 'nsISystemMessagesInternal');
-
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
- return Cc["@mozilla.org/parentprocessmessagemanager;1"]
- .getService(Ci.nsIMessageListenerManager);
-});
-
-if (isGonk) {
- XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
- Cu.import("resource://gre/modules/systemlibs.js");
- return libcutils;
- });
-}
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'captivePortalDetector',
- '@mozilla.org/toolkit/captive-detector;1',
- 'nsICaptivePortalDetector');
-
-XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
- "resource://gre/modules/SafeBrowsing.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SafeMode",
- "resource://gre/modules/SafeMode.jsm");
-
-window.performance.measure('gecko-shell-jsm-loaded', 'gecko-shell-loadstart');
-
-function debug(str) {
- dump(' -*- Shell.js: ' + str + '\n');
-}
-
-const once = event => {
- let target = shell.contentBrowser;
- return new Promise((resolve, reject) => {
- target.addEventListener(event, function gotEvent(evt) {
- target.removeEventListener(event, gotEvent, false);
- resolve(evt);
- }, false);
- });
-}
-
-function clearCache() {
- let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- cache.clear();
-}
-
-function clearCacheAndReload() {
- // Reload the main frame with a cleared cache.
- debug('Reloading ' + shell.contentBrowser.contentWindow.location);
- clearCache();
- shell.contentBrowser.contentWindow.location.reload(true);
- once('mozbrowserlocationchange').then(
- evt => {
- shell.sendEvent(window, "ContentStart");
- });
-}
-
-function restart() {
- let appStartup = Cc['@mozilla.org/toolkit/app-startup;1']
- .getService(Ci.nsIAppStartup);
- appStartup.quit(Ci.nsIAppStartup.eForceQuit | Ci.nsIAppStartup.eRestart);
-}
-
-function debugCrashReport(aStr) {
- AppConstants.MOZ_CRASHREPORTER && dump('Crash reporter : ' + aStr);
-}
-
-var shell = {
-
- get CrashSubmit() {
- delete this.CrashSubmit;
- if (AppConstants.MOZ_CRASHREPORTER) {
- Cu.import("resource://gre/modules/CrashSubmit.jsm", this);
- return this.CrashSubmit;
- } else {
- dump('Crash reporter : disabled at build time.');
- return this.CrashSubmit = null;
- }
- },
-
- onlineForCrashReport: function shell_onlineForCrashReport() {
- let wifiManager = navigator.mozWifiManager;
- let onWifi = (wifiManager &&
- (wifiManager.connection.status == 'connected'));
- return !Services.io.offline && onWifi;
- },
-
- reportCrash: function shell_reportCrash(isChrome, aCrashID) {
- let crashID = aCrashID;
- try {
- // For chrome crashes, we want to report the lastRunCrashID.
- if (isChrome) {
- crashID = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULRuntime).lastRunCrashID;
- }
- } catch(e) {
- debugCrashReport('Failed to fetch crash id. Crash ID is "' + crashID
- + '" Exception: ' + e);
- }
-
- // Bail if there isn't a valid crashID.
- if (!this.CrashSubmit || !crashID && !this.CrashSubmit.pendingIDs().length) {
- return;
- }
-
- // purge the queue.
- this.CrashSubmit.pruneSavedDumps();
-
- // check for environment affecting crash reporting
- let env = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
- let shutdown = env.get("MOZ_CRASHREPORTER_SHUTDOWN");
- if (shutdown) {
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(Ci.nsIAppStartup.eForceQuit);
- }
-
- let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
- if (noReport) {
- return;
- }
-
- try {
- // Check if we should automatically submit this crash.
- if (Services.prefs.getBoolPref('app.reportCrashes')) {
- this.submitCrash(crashID);
- } else {
- this.deleteCrash(crashID);
- }
- } catch (e) {
- debugCrashReport('Can\'t fetch app.reportCrashes. Exception: ' + e);
- }
-
- // We can get here if we're just submitting old pending crashes.
- // Check that there's a valid crashID so that we only notify the
- // user if a crash just happened and not when we OOM. Bug 829477
- if (crashID) {
- this.sendChromeEvent({
- type: "handle-crash",
- crashID: crashID,
- chrome: isChrome
- });
- }
- },
-
- deleteCrash: function shell_deleteCrash(aCrashID) {
- if (aCrashID) {
- debugCrashReport('Deleting pending crash: ' + aCrashID);
- shell.CrashSubmit.delete(aCrashID);
- }
- },
-
- // this function submit the pending crashes.
- // make sure you are online.
- submitQueuedCrashes: function shell_submitQueuedCrashes() {
- // submit the pending queue.
- let pending = shell.CrashSubmit.pendingIDs();
- for (let crashid of pending) {
- debugCrashReport('Submitting crash: ' + crashid);
- shell.CrashSubmit.submit(crashid);
- }
- },
-
- // This function submits a crash when we're online.
- submitCrash: function shell_submitCrash(aCrashID) {
- if (this.onlineForCrashReport()) {
- this.submitQueuedCrashes();
- return;
- }
-
- debugCrashReport('Not online, postponing.');
-
- Services.obs.addObserver(function observer(subject, topic, state) {
- let network = subject.QueryInterface(Ci.nsINetworkInfo);
- if (network.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED
- && network.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
- shell.submitQueuedCrashes();
-
- Services.obs.removeObserver(observer, topic);
- }
- }, "network-connection-state-changed", false);
- },
-
- get homeURL() {
- try {
- let homeSrc = Services.env.get('B2G_HOMESCREEN');
- if (homeSrc)
- return homeSrc;
- } catch (e) {}
-
- return Services.prefs.getCharPref('b2g.system_startup_url');
- },
-
- get manifestURL() {
- return Services.prefs.getCharPref('b2g.system_manifest_url');
- },
-
- _started: false,
- hasStarted: function shell_hasStarted() {
- return this._started;
- },
-
- bootstrap: function() {
- window.performance.mark('gecko-shell-bootstrap');
-
- // Before anything, check if we want to start in safe mode.
- SafeMode.check(window).then(() => {
- let startManifestURL =
- Cc['@mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap']
- .getService(Ci.nsISupports).wrappedJSObject.startManifestURL;
-
- // If --start-manifest hasn't been specified, we re-use the latest specified manifest.
- // If it's the first launch, we will fallback to b2g.default.start_manifest_url
- if (AppConstants.MOZ_GRAPHENE && !startManifestURL) {
- try {
- startManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
- } catch(e) {}
- }
-
- if (!startManifestURL) {
- try {
- startManifestURL = Services.prefs.getCharPref("b2g.default.start_manifest_url");
- } catch(e) {}
- }
-
- if (startManifestURL) {
- Cu.import('resource://gre/modules/Bootstraper.jsm');
-
- if (AppConstants.MOZ_GRAPHENE && Bootstraper.isInstallRequired(startManifestURL)) {
- // Installing the app my take some time. We don't want to keep the
- // native window hidden.
- showInstallScreen();
- }
-
- Bootstraper.ensureSystemAppInstall(startManifestURL)
- .then(this.start.bind(this))
- .catch(Bootstraper.bailout);
- } else {
- this.start();
- }
- });
- },
-
- start: function shell_start() {
- window.performance.mark('gecko-shell-start');
- this._started = true;
-
- // This forces the initialization of the cookie service before we hit the
- // network.
- // See bug 810209
- let cookies = Cc["@mozilla.org/cookieService;1"];
-
- try {
- let cr = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsICrashReporter);
- // Dogfood id. We might want to remove it in the future.
- // see bug 789466
- try {
- let dogfoodId = Services.prefs.getCharPref('prerelease.dogfood.id');
- if (dogfoodId != "") {
- cr.annotateCrashReport("Email", dogfoodId);
- }
- }
- catch (e) { }
-
- if (isGonk) {
- // Annotate crash report
- let annotations = [ [ "Android_Hardware", "ro.hardware" ],
- [ "Android_Device", "ro.product.device" ],
- [ "Android_CPU_ABI2", "ro.product.cpu.abi2" ],
- [ "Android_CPU_ABI", "ro.product.cpu.abi" ],
- [ "Android_Manufacturer", "ro.product.manufacturer" ],
- [ "Android_Brand", "ro.product.brand" ],
- [ "Android_Model", "ro.product.model" ],
- [ "Android_Board", "ro.product.board" ],
- ];
-
- annotations.forEach(function (element) {
- cr.annotateCrashReport(element[0], libcutils.property_get(element[1]));
- });
-
- let androidVersion = libcutils.property_get("ro.build.version.sdk") +
- "(" + libcutils.property_get("ro.build.version.codename") + ")";
- cr.annotateCrashReport("Android_Version", androidVersion);
-
- SettingsListener.observe("deviceinfo.os", "", function(value) {
- try {
- let cr = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsICrashReporter);
- cr.annotateCrashReport("B2G_OS_Version", value);
- } catch(e) { }
- });
- }
- } catch(e) {
- debugCrashReport('exception: ' + e);
- }
-
- let homeURL = this.homeURL;
- if (!homeURL) {
- let msg = 'Fatal error during startup: No homescreen found: try setting B2G_HOMESCREEN';
- alert(msg);
- return;
- }
-
- let manifestURL = this.manifestURL;
- // <html:iframe id="systemapp"
- // mozbrowser="true" allowfullscreen="true"
- // style="overflow: hidden; height: 100%; width: 100%; border: none;"
- // src="data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
- let systemAppFrame =
- document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
- systemAppFrame.setAttribute('id', 'systemapp');
- systemAppFrame.setAttribute('mozbrowser', 'true');
- systemAppFrame.setAttribute('mozapp', manifestURL);
- systemAppFrame.setAttribute('allowfullscreen', 'true');
- systemAppFrame.setAttribute('src', 'blank.html');
- let container = document.getElementById('container');
-
- if (AppConstants.platform == 'macosx') {
- // See shell.html
- let hotfix = document.getElementById('placeholder');
- if (hotfix) {
- container.removeChild(hotfix);
- }
- }
-
- this.contentBrowser = container.appendChild(systemAppFrame);
-
- let webNav = systemAppFrame.contentWindow
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation);
- webNav.sessionHistory = Cc["@mozilla.org/browser/shistory;1"].createInstance(Ci.nsISHistory);
-
- if (AppConstants.MOZ_GRAPHENE) {
- webNav.QueryInterface(Ci.nsIDocShell).windowDraggingAllowed = true;
- }
-
- let audioChannels = systemAppFrame.allowedAudioChannels;
- audioChannels && audioChannels.forEach(function(audioChannel) {
- // Set all audio channels as unmuted by default
- // because some audio in System app will be played
- // before AudioChannelService[1] is Gaia is loaded.
- // [1]: https://github.com/mozilla-b2g/gaia/blob/master/apps/system/js/audio_channel_service.js
- audioChannel.setMuted(false);
- });
-
- // On firefox mulet, shell.html is loaded in a tab
- // and we have to listen on the chrome event handler
- // to catch key events
- let chromeEventHandler = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler || window;
- // Capture all key events so we can filter out hardware buttons
- // And send them to Gaia via mozChromeEvents.
- // Ideally, hardware buttons wouldn't generate key events at all, or
- // if they did, they would use keycodes that conform to DOM 3 Events.
- // See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=762362
- chromeEventHandler.addEventListener('keydown', this, true);
- chromeEventHandler.addEventListener('keyup', this, true);
-
- window.addEventListener('MozApplicationManifest', this);
- window.addEventListener('MozAfterPaint', this);
- window.addEventListener('sizemodechange', this);
- window.addEventListener('unload', this);
- this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
- this.contentBrowser.addEventListener('mozbrowserscrollviewchange', this, true);
- this.contentBrowser.addEventListener('mozbrowsercaretstatechanged', this);
-
- CustomEventManager.init();
- UserAgentOverrides.init();
- CaptivePortalLoginHelper.init();
-
- this.contentBrowser.src = homeURL;
-
- this._isEventListenerReady = false;
-
- window.performance.mark('gecko-shell-system-frame-set');
-
- ppmm.addMessageListener("content-handler", this);
- ppmm.addMessageListener("dial-handler", this);
- ppmm.addMessageListener("sms-handler", this);
- ppmm.addMessageListener("mail-handler", this);
- ppmm.addMessageListener("file-picker", this);
-
- setTimeout(function() {
- SafeBrowsing.init();
- }, 5000);
- },
-
- stop: function shell_stop() {
- window.removeEventListener('unload', this);
- window.removeEventListener('keydown', this, true);
- window.removeEventListener('keyup', this, true);
- window.removeEventListener('MozApplicationManifest', this);
- window.removeEventListener('sizemodechange', this);
- this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
- this.contentBrowser.removeEventListener('mozbrowserscrollviewchange', this, true);
- this.contentBrowser.removeEventListener('mozbrowsercaretstatechanged', this);
- ppmm.removeMessageListener("content-handler", this);
-
- UserAgentOverrides.uninit();
- },
-
- // If this key event represents a hardware button which needs to be send as
- // a message, broadcasts it with the message set to 'xxx-button-press' or
- // 'xxx-button-release'.
- broadcastHardwareKeys: function shell_broadcastHardwareKeys(evt) {
- let type;
- let message;
-
- let mediaKeys = {
- 'MediaTrackNext': 'media-next-track-button',
- 'MediaTrackPrevious': 'media-previous-track-button',
- 'MediaPause': 'media-pause-button',
- 'MediaPlay': 'media-play-button',
- 'MediaPlayPause': 'media-play-pause-button',
- 'MediaStop': 'media-stop-button',
- 'MediaRewind': 'media-rewind-button',
- 'MediaFastForward': 'media-fast-forward-button'
- };
-
- if (evt.keyCode == evt.DOM_VK_F1) {
- type = 'headset-button';
- message = 'headset-button';
- } else if (mediaKeys[evt.key]) {
- type = 'media-button';
- message = mediaKeys[evt.key];
- } else {
- return;
- }
-
- switch (evt.type) {
- case 'keydown':
- message = message + '-press';
- break;
- case 'keyup':
- message = message + '-release';
- break;
- }
-
- // Let applications receive the headset button and media key press/release message.
- if (message !== this.lastHardwareButtonMessage) {
- this.lastHardwareButtonMessage = message;
- gSystemMessenger.broadcastMessage(type, message);
- }
- },
-
- lastHardwareButtonMessage: null, // property for the hack above
- visibleNormalAudioActive: false,
-
- handleEvent: function shell_handleEvent(evt) {
- function checkReloadKey() {
- if (evt.type !== 'keyup') {
- return false;
- }
-
- try {
- let key = JSON.parse(Services.prefs.getCharPref('b2g.reload_key'));
- return (evt.keyCode == key.key &&
- evt.ctrlKey == key.ctrl &&
- evt.altKey == key.alt &&
- evt.shiftKey == key.shift &&
- evt.metaKey == key.meta);
- } catch(e) {
- debug('Failed to get key: ' + e);
- }
-
- return false;
- }
-
- let content = this.contentBrowser.contentWindow;
- switch (evt.type) {
- case 'keydown':
- case 'keyup':
- if (checkReloadKey()) {
- clearCacheAndReload();
- } else {
- this.broadcastHardwareKeys(evt);
- }
- break;
- case 'sizemodechange':
- if (window.windowState == window.STATE_MINIMIZED && !this.visibleNormalAudioActive) {
- this.contentBrowser.setVisible(false);
- } else {
- this.contentBrowser.setVisible(true);
- }
- break;
- case 'load':
- if (content.document.location == 'about:blank') {
- return;
- }
- content.removeEventListener('load', this, true);
- this.notifyContentWindowLoaded();
- break;
- case 'mozbrowserloadstart':
- if (content.document.location == 'about:blank') {
- this.contentBrowser.addEventListener('mozbrowserlocationchange', this, true);
- return;
- }
-
- this.notifyContentStart();
- break;
- case 'mozbrowserlocationchange':
- if (content.document.location == 'about:blank') {
- return;
- }
-
- this.notifyContentStart();
- break;
- case 'mozbrowserscrollviewchange':
- this.sendChromeEvent({
- type: 'scrollviewchange',
- detail: evt.detail,
- });
- break;
- case 'mozbrowsercaretstatechanged':
- {
- let elt = evt.target;
- let win = elt.ownerDocument.defaultView;
- let offsetX = win.mozInnerScreenX - window.mozInnerScreenX;
- let offsetY = win.mozInnerScreenY - window.mozInnerScreenY;
-
- let rect = elt.getBoundingClientRect();
- offsetX += rect.left;
- offsetY += rect.top;
-
- let data = evt.detail;
- data.offsetX = offsetX;
- data.offsetY = offsetY;
- data.sendDoCommandMsg = null;
-
- shell.sendChromeEvent({
- type: 'caretstatechanged',
- detail: data,
- });
- }
- break;
-
- case 'MozApplicationManifest':
- try {
- if (!Services.prefs.getBoolPref('browser.cache.offline.enable'))
- return;
-
- let contentWindow = evt.originalTarget.defaultView;
- let documentElement = contentWindow.document.documentElement;
- if (!documentElement)
- return;
-
- let manifest = documentElement.getAttribute('manifest');
- if (!manifest)
- return;
-
- let principal = contentWindow.document.nodePrincipal;
- if (Services.perms.testPermissionFromPrincipal(principal, 'offline-app') == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
- if (Services.prefs.getBoolPref('browser.offline-apps.notify')) {
- // FIXME Bug 710729 - Add a UI for offline cache notifications
- return;
- }
- return;
- }
-
- Services.perms.addFromPrincipal(principal, 'offline-app',
- Ci.nsIPermissionManager.ALLOW_ACTION);
-
- let documentURI = Services.io.newURI(contentWindow.document.documentURI,
- null,
- null);
- let manifestURI = Services.io.newURI(manifest, null, documentURI);
- let updateService = Cc['@mozilla.org/offlinecacheupdate-service;1']
- .getService(Ci.nsIOfflineCacheUpdateService);
- updateService.scheduleUpdate(manifestURI, documentURI, principal, window);
- } catch (e) {
- dump('Error while creating offline cache: ' + e + '\n');
- }
- break;
- case 'MozAfterPaint':
- window.removeEventListener('MozAfterPaint', this);
- // This event should be sent before System app returns with
- // system-message-listener-ready mozContentEvent, because it's on
- // the critical launch path of the app.
- SystemAppProxy._sendCustomEvent('mozChromeEvent', {
- type: 'system-first-paint'
- }, /* noPending */ true);
- break;
- case 'unload':
- this.stop();
- break;
- }
- },
-
- // Send an event to a specific window, document or element.
- sendEvent: function shell_sendEvent(target, type, details) {
- if (target === this.contentBrowser) {
- // We must ask SystemAppProxy to send the event in this case so
- // that event would be dispatched from frame.contentWindow instead of
- // on the System app frame.
- SystemAppProxy._sendCustomEvent(type, details);
- return;
- }
-
- let doc = target.document || target.ownerDocument || target;
- let event = doc.createEvent('CustomEvent');
- event.initCustomEvent(type, true, true, details ? details : {});
- target.dispatchEvent(event);
- },
-
- sendCustomEvent: function shell_sendCustomEvent(type, details) {
- SystemAppProxy._sendCustomEvent(type, details);
- },
-
- sendChromeEvent: function shell_sendChromeEvent(details) {
- this.sendCustomEvent("mozChromeEvent", details);
- },
-
- receiveMessage: function shell_receiveMessage(message) {
- var activities = { 'content-handler': { name: 'view', response: null },
- 'dial-handler': { name: 'dial', response: null },
- 'mail-handler': { name: 'new', response: null },
- 'sms-handler': { name: 'new', response: null },
- 'file-picker': { name: 'pick', response: 'file-picked' } };
-
- if (!(message.name in activities))
- return;
-
- let data = message.data;
- let activity = activities[message.name];
-
- let a = new MozActivity({
- name: activity.name,
- data: data
- });
-
- if (activity.response) {
- a.onsuccess = function() {
- let sender = message.target.QueryInterface(Ci.nsIMessageSender);
- sender.sendAsyncMessage(activity.response, { success: true,
- result: a.result });
- }
- a.onerror = function() {
- let sender = message.target.QueryInterface(Ci.nsIMessageSender);
- sender.sendAsyncMessage(activity.response, { success: false });
- }
- }
- },
-
- notifyContentStart: function shell_notifyContentStart() {
- window.performance.mark('gecko-shell-notify-content-start');
- this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
- this.contentBrowser.removeEventListener('mozbrowserlocationchange', this, true);
-
- let content = this.contentBrowser.contentWindow;
- content.addEventListener('load', this, true);
-
- this.reportCrash(true);
-
- SystemAppProxy.registerFrame(shell.contentBrowser);
-
- this.sendEvent(window, 'ContentStart');
-
- Services.obs.notifyObservers(null, 'content-start', null);
-
- if (AppConstants.MOZ_GRAPHENE &&
- Services.prefs.getBoolPref("b2g.nativeWindowGeometry.fullscreen")) {
- window.fullScreen = true;
- }
-
- shell.handleCmdLine();
- },
-
- handleCmdLine: function() {
- // This isn't supported on devices.
- if (!isGonk) {
- let b2gcmds = Cc["@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds"]
- .getService(Ci.nsISupports);
- let args = b2gcmds.wrappedJSObject.cmdLine;
- try {
- // Returns null if -url is not present.
- let url = args.handleFlagWithParam("url", false);
- if (url) {
- this.sendChromeEvent({type: "mozbrowseropenwindow", url});
- args.preventDefault = true;
- }
- } catch(e) {
- // Throws if -url is present with no params.
- }
- }
- },
-
- // This gets called when window.onload fires on the System app content window,
- // which means things in <html> are parsed and statically referenced <script>s
- // and <script defer>s are loaded and run.
- notifyContentWindowLoaded: function shell_notifyContentWindowLoaded() {
- isGonk && libcutils.property_set('sys.boot_completed', '1');
-
- // This will cause Gonk Widget to remove boot animation from the screen
- // and reveals the page.
- Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
-
- SystemAppProxy.setIsLoaded();
- },
-
- // This gets called when the content sends us system-message-listener-ready
- // mozContentEvent, OR when an observer message tell us we should consider
- // the content as ready.
- notifyEventListenerReady: function shell_notifyEventListenerReady() {
- if (this._isEventListenerReady) {
- Cu.reportError('shell.js: SystemApp has already been declared as being ready.');
- return;
- }
- this._isEventListenerReady = true;
-
- if (Services.prefs.getBoolPref('b2g.orientation.animate')) {
- Cu.import('resource://gre/modules/OrientationChangeHandler.jsm');
- }
-
- SystemAppProxy.setIsReady();
- }
-};
-
-Services.obs.addObserver(function onFullscreenOriginChange(subject, topic, data) {
- shell.sendChromeEvent({ type: "fullscreenoriginchange",
- fullscreenorigin: data });
-}, "fullscreen-origin-change", false);
-
-Services.obs.addObserver(function onBluetoothVolumeChange(subject, topic, data) {
- shell.sendChromeEvent({
- type: "bluetooth-volumeset",
- value: data
- });
-}, 'bluetooth-volume-change', false);
-
-Services.obs.addObserver(function(subject, topic, data) {
- shell.sendCustomEvent('mozmemorypressure');
-}, 'memory-pressure', false);
-
-Services.obs.addObserver(function(subject, topic, data) {
- shell.notifyEventListenerReady();
-}, 'system-message-listener-ready', false);
-
-var permissionMap = new Map([
- ['unknown', Services.perms.UNKNOWN_ACTION],
- ['allow', Services.perms.ALLOW_ACTION],
- ['deny', Services.perms.DENY_ACTION],
- ['prompt', Services.perms.PROMPT_ACTION],
-]);
-var permissionMapRev = new Map(Array.from(permissionMap.entries()).reverse());
-
-var CustomEventManager = {
- init: function custevt_init() {
- window.addEventListener("ContentStart", (function(evt) {
- let content = shell.contentBrowser.contentWindow;
- content.addEventListener("mozContentEvent", this, false, true);
- }).bind(this), false);
- },
-
- handleEvent: function custevt_handleEvent(evt) {
- let detail = evt.detail;
- dump('XXX FIXME : Got a mozContentEvent: ' + detail.type + "\n");
-
- switch(detail.type) {
- case 'system-message-listener-ready':
- Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
- break;
- case 'captive-portal-login-cancel':
- CaptivePortalLoginHelper.handleEvent(detail);
- break;
- case 'inputmethod-update-layouts':
- case 'inputregistry-add':
- case 'inputregistry-remove':
- KeyboardHelper.handleEvent(detail);
- break;
- case 'copypaste-do-command':
- Services.obs.notifyObservers({ wrappedJSObject: shell.contentBrowser },
- 'ask-children-to-execute-copypaste-command', detail.cmd);
- break;
- case 'add-permission':
- Services.perms.add(Services.io.newURI(detail.uri, null, null),
- detail.permissionType, permissionMap.get(detail.permission));
- break;
- case 'remove-permission':
- Services.perms.remove(Services.io.newURI(detail.uri, null, null),
- detail.permissionType);
- break;
- case 'test-permission':
- let result = Services.perms.testExactPermission(
- Services.io.newURI(detail.uri, null, null), detail.permissionType);
- // Not equal check here because we want to prevent default only if it's not set
- if (result !== permissionMapRev.get(detail.permission)) {
- evt.preventDefault();
- }
- break;
- case 'shutdown-application':
- let appStartup = Cc['@mozilla.org/toolkit/app-startup;1']
- .getService(Ci.nsIAppStartup);
- appStartup.quit(appStartup.eAttemptQuit);
- break;
- case 'toggle-fullscreen-native-window':
- window.fullScreen = !window.fullScreen;
- Services.prefs.setBoolPref("b2g.nativeWindowGeometry.fullscreen",
- window.fullScreen);
- break;
- case 'minimize-native-window':
- window.minimize();
- break;
- case 'clear-cache-and-reload':
- clearCacheAndReload();
- break;
- case 'clear-cache-and-restart':
- clearCache();
- restart();
- break;
- case 'restart':
- restart();
- break;
- }
- }
-}
-
-var KeyboardHelper = {
- handleEvent: function keyboard_handleEvent(detail) {
- switch (detail.type) {
- case 'inputmethod-update-layouts':
- Keyboard.setLayouts(detail.layouts);
-
- break;
- case 'inputregistry-add':
- case 'inputregistry-remove':
- Keyboard.inputRegistryGlue.returnMessage(detail);
-
- break;
- }
- }
-};
-
-// This is the backend for Gaia's screenshot feature. Gaia requests a
-// screenshot by sending a mozContentEvent with detail.type set to
-// 'take-screenshot'. Then we take a screenshot and send a
-// mozChromeEvent with detail.type set to 'take-screenshot-success'
-// and detail.file set to the an image/png blob
-window.addEventListener('ContentStart', function ss_onContentStart() {
- let content = shell.contentBrowser.contentWindow;
- content.addEventListener('mozContentEvent', function ss_onMozContentEvent(e) {
- if (e.detail.type !== 'take-screenshot')
- return;
-
- try {
- shell.sendChromeEvent({
- type: 'take-screenshot-success',
- file: Screenshot.get()
- });
- } catch (e) {
- dump('exception while creating screenshot: ' + e + '\n');
- shell.sendChromeEvent({
- type: 'take-screenshot-error',
- error: String(e)
- });
- }
- });
-});
-
-(function contentCrashTracker() {
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- let props = aSubject.QueryInterface(Ci.nsIPropertyBag2);
- if (props.hasKey("abnormal") && props.hasKey("dumpID")) {
- shell.reportCrash(false, props.getProperty("dumpID"));
- }
- },
- "ipc:content-shutdown", false);
-})();
-
-var CaptivePortalLoginHelper = {
- init: function init() {
- Services.obs.addObserver(this, 'captive-portal-login', false);
- Services.obs.addObserver(this, 'captive-portal-login-abort', false);
- Services.obs.addObserver(this, 'captive-portal-login-success', false);
- },
- handleEvent: function handleEvent(detail) {
- Services.captivePortalDetector.cancelLogin(detail.id);
- },
- observe: function observe(subject, topic, data) {
- shell.sendChromeEvent(JSON.parse(data));
- }
-}
-
-// Listen for crashes submitted through the crash reporter UI.
-window.addEventListener('ContentStart', function cr_onContentStart() {
- let content = shell.contentBrowser.contentWindow;
- content.addEventListener("mozContentEvent", function cr_onMozContentEvent(e) {
- if (e.detail.type == "submit-crash" && e.detail.crashID) {
- debugCrashReport("submitting crash at user request ", e.detail.crashID);
- shell.submitCrash(e.detail.crashID);
- } else if (e.detail.type == "delete-crash" && e.detail.crashID) {
- debugCrashReport("deleting crash at user request ", e.detail.crashID);
- shell.deleteCrash(e.detail.crashID);
- }
- });
-});
-
-window.addEventListener('ContentStart', function update_onContentStart() {
- if (!AppConstants.MOZ_UPDATER) {
- return;
- }
-
- let promptCc = Cc["@mozilla.org/updates/update-prompt;1"];
- if (!promptCc) {
- return;
- }
-
- let updatePrompt = promptCc.createInstance(Ci.nsIUpdatePrompt);
- if (!updatePrompt) {
- return;
- }
-
- updatePrompt.wrappedJSObject.handleContentStart(shell);
-});
-/* The "GPSChipOn" is to indicate that GPS engine is turned ON by the modem.
- During this GPS engine is turned ON by the modem, we make the location tracking icon visible to user.
- Once GPS engine is turned OFF, the location icon will disappear.
- If GPS engine is not turned ON by the modem or GPS location service is triggered,
- we let GPS service take over the control of showing the location tracking icon.
- The regular sequence of the geolocation-device-events is: starting-> GPSStarting-> shutdown-> GPSShutdown
-*/
-
-
-(function geolocationStatusTracker() {
- let gGeolocationActive = false;
- let GPSChipOn = false;
-
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- let oldState = gGeolocationActive;
- let promptWarning = false;
- switch (aData) {
- case "GPSStarting":
- if (!gGeolocationActive) {
- gGeolocationActive = true;
- GPSChipOn = true;
- promptWarning = true;
- }
- break;
- case "GPSShutdown":
- if (GPSChipOn) {
- gGeolocationActive = false;
- GPSChipOn = false;
- }
- break;
- case "starting":
- gGeolocationActive = true;
- GPSChipOn = false;
- break;
- case "shutdown":
- gGeolocationActive = false;
- break;
- }
-
- if (gGeolocationActive != oldState) {
- shell.sendChromeEvent({
- type: 'geolocation-status',
- active: gGeolocationActive,
- prompt: promptWarning
- });
- }
-}, "geolocation-device-events", false);
-})();
-
-(function headphonesStatusTracker() {
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- shell.sendChromeEvent({
- type: 'headphones-status-changed',
- state: aData
- });
-}, "headphones-status-changed", false);
-})();
-
-(function audioChannelChangedTracker() {
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- shell.sendChromeEvent({
- type: 'audio-channel-changed',
- channel: aData
- });
-}, "audio-channel-changed", false);
-})();
-
-(function defaultVolumeChannelChangedTracker() {
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- shell.sendChromeEvent({
- type: 'default-volume-channel-changed',
- channel: aData
- });
-}, "default-volume-channel-changed", false);
-})();
-
-(function visibleAudioChannelChangedTracker() {
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- shell.sendChromeEvent({
- type: 'visible-audio-channel-changed',
- channel: aData
- });
- shell.visibleNormalAudioActive = (aData == 'normal');
-}, "visible-audio-channel-changed", false);
-})();
-
-(function recordingStatusTracker() {
- // Recording status is tracked per process with following data structure:
- // {<processId>: {<requestURL>: {isApp: <isApp>,
- // count: <N>,
- // audioCount: <N>,
- // videoCount: <N>}}
- let gRecordingActiveProcesses = {};
-
- let recordingHandler = function(aSubject, aTopic, aData) {
- let props = aSubject.QueryInterface(Ci.nsIPropertyBag2);
- let processId = (props.hasKey('childID')) ? props.get('childID')
- : 'main';
- if (processId && !gRecordingActiveProcesses.hasOwnProperty(processId)) {
- gRecordingActiveProcesses[processId] = {};
- }
-
- let commandHandler = function (requestURL, command) {
- let currentProcess = gRecordingActiveProcesses[processId];
- let currentActive = currentProcess[requestURL];
- let wasActive = (currentActive['count'] > 0);
- let wasAudioActive = (currentActive['audioCount'] > 0);
- let wasVideoActive = (currentActive['videoCount'] > 0);
-
- switch (command.type) {
- case 'starting':
- currentActive['count']++;
- currentActive['audioCount'] += (command.isAudio) ? 1 : 0;
- currentActive['videoCount'] += (command.isVideo) ? 1 : 0;
- break;
- case 'shutdown':
- currentActive['count']--;
- currentActive['audioCount'] -= (command.isAudio) ? 1 : 0;
- currentActive['videoCount'] -= (command.isVideo) ? 1 : 0;
- break;
- case 'content-shutdown':
- currentActive['count'] = 0;
- currentActive['audioCount'] = 0;
- currentActive['videoCount'] = 0;
- break;
- }
-
- if (currentActive['count'] > 0) {
- currentProcess[requestURL] = currentActive;
- } else {
- delete currentProcess[requestURL];
- }
-
- // We need to track changes if any active state is changed.
- let isActive = (currentActive['count'] > 0);
- let isAudioActive = (currentActive['audioCount'] > 0);
- let isVideoActive = (currentActive['videoCount'] > 0);
- if ((isActive != wasActive) ||
- (isAudioActive != wasAudioActive) ||
- (isVideoActive != wasVideoActive)) {
- shell.sendChromeEvent({
- type: 'recording-status',
- active: isActive,
- requestURL: requestURL,
- isApp: currentActive['isApp'],
- isAudio: isAudioActive,
- isVideo: isVideoActive
- });
- }
- };
-
- switch (aData) {
- case 'starting':
- case 'shutdown':
- // create page record if it is not existed yet.
- let requestURL = props.get('requestURL');
- if (requestURL &&
- !gRecordingActiveProcesses[processId].hasOwnProperty(requestURL)) {
- gRecordingActiveProcesses[processId][requestURL] = {isApp: props.get('isApp'),
- count: 0,
- audioCount: 0,
- videoCount: 0};
- }
- commandHandler(requestURL, { type: aData,
- isAudio: props.get('isAudio'),
- isVideo: props.get('isVideo')});
- break;
- case 'content-shutdown':
- // iterate through all the existing active processes
- Object.keys(gRecordingActiveProcesses[processId]).forEach(function(requestURL) {
- commandHandler(requestURL, { type: aData,
- isAudio: true,
- isVideo: true});
- });
- break;
- }
-
- // clean up process record if no page record in it.
- if (Object.keys(gRecordingActiveProcesses[processId]).length == 0) {
- delete gRecordingActiveProcesses[processId];
- }
- };
- Services.obs.addObserver(recordingHandler, 'recording-device-events', false);
- Services.obs.addObserver(recordingHandler, 'recording-device-ipc-events', false);
-
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- // send additional recording events if content process is being killed
- let processId = aSubject.QueryInterface(Ci.nsIPropertyBag2).get('childID');
- if (gRecordingActiveProcesses.hasOwnProperty(processId)) {
- Services.obs.notifyObservers(aSubject, 'recording-device-ipc-events', 'content-shutdown');
- }
- }, 'ipc:content-shutdown', false);
-})();
-
-(function volumeStateTracker() {
- Services.obs.addObserver(function(aSubject, aTopic, aData) {
- shell.sendChromeEvent({
- type: 'volume-state-changed',
- active: (aData == 'Shared')
- });
-}, 'volume-state-changed', false);
-})();
-
-if (isGonk) {
- // Devices don't have all the same partition size for /cache where we
- // store the http cache.
- (function setHTTPCacheSize() {
- let path = Services.prefs.getCharPref("browser.cache.disk.parent_directory");
- let volumeService = Cc["@mozilla.org/telephony/volume-service;1"]
- .getService(Ci.nsIVolumeService);
-
- let stats = volumeService.createOrGetVolumeByPath(path).getStats();
-
- // We must set the size in KB, and keep a bit of free space.
- let size = Math.floor(stats.totalBytes / 1024) - 1024;
-
- // keep the default value if it is smaller than the physical partition size.
- let oldSize = Services.prefs.getIntPref("browser.cache.disk.capacity");
- if (size < oldSize) {
- Services.prefs.setIntPref("browser.cache.disk.capacity", size);
- }
- })();
-
- try {
- let gmpService = Cc["@mozilla.org/gecko-media-plugin-service;1"]
- .getService(Ci.mozIGeckoMediaPluginChromeService);
- gmpService.addPluginDirectory("/system/b2g/gmp-clearkey/0.1");
- } catch(e) {
- dump("Failed to add clearkey path! " + e + "\n");
- }
-}
-
-// Calling this observer will cause a shutdown an a profile reset.
-// Use eg. : Services.obs.notifyObservers(null, 'b2g-reset-profile', null);
-Services.obs.addObserver(function resetProfile(subject, topic, data) {
- Services.obs.removeObserver(resetProfile, topic);
-
- // Listening for 'profile-before-change-telemetry' which is late in the
- // shutdown sequence, but still has xpcom access.
- Services.obs.addObserver(function clearProfile(subject, topic, data) {
- Services.obs.removeObserver(clearProfile, topic);
- if (isGonk) {
- let json = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- json.initWithPath('/system/b2g/webapps/webapps.json');
- let toRemove = json.exists()
- // This is a user build, just rm -r /data/local /data/b2g/mozilla
- ? ['/data/local', '/data/b2g/mozilla']
- // This is an eng build. We clear the profile and a set of files
- // under /data/local.
- : ['/data/b2g/mozilla',
- '/data/local/permissions.sqlite',
- '/data/local/storage',
- '/data/local/OfflineCache'];
-
- toRemove.forEach(function(dir) {
- try {
- let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- file.initWithPath(dir);
- file.remove(true);
- } catch(e) { dump(e); }
- });
- } else {
- // Desktop builds.
- let profile = Services.dirsvc.get('ProfD', Ci.nsIFile);
-
- // We don't want to remove everything from the profile, since this
- // would prevent us from starting up.
- let whitelist = ['defaults', 'extensions', 'settings.json',
- 'user.js', 'webapps'];
- let enumerator = profile.directoryEntries;
- while (enumerator.hasMoreElements()) {
- let file = enumerator.getNext().QueryInterface(Ci.nsIFile);
- if (whitelist.indexOf(file.leafName) == -1) {
- file.remove(true);
- }
- }
- }
- },
- 'profile-before-change-telemetry', false);
-
- let appStartup = Cc['@mozilla.org/toolkit/app-startup;1']
- .getService(Ci.nsIAppStartup);
- appStartup.quit(Ci.nsIAppStartup.eForceQuit);
-}, 'b2g-reset-profile', false);
-
-var showInstallScreen;
-
-if (AppConstants.MOZ_GRAPHENE) {
- const restoreWindowGeometry = () => {
- let screenX = Services.prefs.getIntPref("b2g.nativeWindowGeometry.screenX");
- let screenY = Services.prefs.getIntPref("b2g.nativeWindowGeometry.screenY");
- let width = Services.prefs.getIntPref("b2g.nativeWindowGeometry.width");
- let height = Services.prefs.getIntPref("b2g.nativeWindowGeometry.height");
-
- if (screenX == -1) {
- // Center
- screenX = (screen.width - width) / 2;
- screenY = (screen.height - height) / 2;
- }
-
- moveTo(screenX, screenY);
- resizeTo(width, height);
- }
- restoreWindowGeometry();
-
- const saveWindowGeometry = () => {
- window.removeEventListener("unload", saveWindowGeometry);
- Services.prefs.setIntPref("b2g.nativeWindowGeometry.screenX", screenX);
- Services.prefs.setIntPref("b2g.nativeWindowGeometry.screenY", screenY);
- Services.prefs.setIntPref("b2g.nativeWindowGeometry.width", outerWidth);
- Services.prefs.setIntPref("b2g.nativeWindowGeometry.height", outerHeight);
- }
- window.addEventListener("unload", saveWindowGeometry);
-
- var baseWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .treeOwner
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIBaseWindow);
-
- const showNativeWindow = () => baseWindow.visibility = true;
- const hideNativeWindow = () => baseWindow.visibility = false;
-
- showInstallScreen = () => {
- const grapheneStrings =
- Services.strings.createBundle('chrome://b2g-l10n/locale/graphene.properties');
- document.querySelector('#installing > .message').textContent =
- grapheneStrings.GetStringFromName('installing');
- showNativeWindow();
- }
-
- const hideInstallScreen = () => {
- document.body.classList.add('content-loaded');
- }
-
- window.addEventListener('ContentStart', () => {
- shell.contentBrowser.contentWindow.addEventListener('load', () => {
- hideInstallScreen();
- showNativeWindow();
- });
- });
-
- hideNativeWindow();
-}
diff --git a/b2g/chrome/content/shell_remote.html b/b2g/chrome/content/shell_remote.html
deleted file mode 100644
index 4f3f6efc8..000000000
--- a/b2g/chrome/content/shell_remote.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this file,
- - You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml"
- id="shellRemote"
- windowtype="navigator:remote-browser"
- sizemode="fullscreen"
- >
-
-<head>
- <link rel="stylesheet" href="shell.css" type="text/css">
- <script type="application/javascript;version=1.8"
- src="chrome://b2g/content/shell_remote.js"> </script>
-</head>
- <body id="container">
- </body>
-</html>
diff --git a/b2g/chrome/content/shell_remote.js b/b2g/chrome/content/shell_remote.js
deleted file mode 100644
index 1f1115ef0..000000000
--- a/b2g/chrome/content/shell_remote.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/SystemAppProxy.jsm");
-
-function debug(aStr) {
- // dump(" -*- ShellRemote.js: " + aStr + "\n");
-}
-
-var remoteShell = {
-
- _started: false,
-
- get homeURL() {
- let systemAppManifestURL = Services.io.newURI(this.systemAppManifestURL, null, null);
- let shellRemoteURL = Services.prefs.getCharPref("b2g.multiscreen.system_remote_url");
- shellRemoteURL = Services.io.newURI(shellRemoteURL, null, systemAppManifestURL);
- return shellRemoteURL.spec;
- },
-
- get systemAppManifestURL() {
- return Services.prefs.getCharPref("b2g.system_manifest_url");
- },
-
- hasStarted: function () {
- return this._started;
- },
-
- start: function () {
- this._started = true;
- this._isEventListenerReady = false;
- this.id = window.location.hash.substring(1);
-
- let homeURL = this.homeURL;
- if (!homeURL) {
- debug("ERROR! Remote home URL undefined.");
- return;
- }
- let manifestURL = this.systemAppManifestURL;
- // <html:iframe id="this.id"
- // mozbrowser="true"
- // allowfullscreen="true"
- // src="blank.html"/>
- let systemAppFrame =
- document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
- systemAppFrame.setAttribute("id", this.id);
- systemAppFrame.setAttribute("mozbrowser", "true");
- systemAppFrame.setAttribute("mozapp", manifestURL);
- systemAppFrame.setAttribute("allowfullscreen", "true");
- systemAppFrame.setAttribute("src", "blank.html");
-
- let container = document.getElementById("container");
- this.contentBrowser = container.appendChild(systemAppFrame);
- this.contentBrowser.src = homeURL + window.location.hash;
-
- window.addEventListener("unload", this);
- this.contentBrowser.addEventListener("mozbrowserloadstart", this);
- },
-
- stop: function () {
- window.removeEventListener("unload", this);
- this.contentBrowser.removeEventListener("mozbrowserloadstart", this);
- this.contentBrowser.removeEventListener("mozbrowserlocationchange", this, true);
- SystemAppProxy.unregisterFrameWithId(this.id);
- },
-
- notifyContentStart: function(evt) {
- this.contentBrowser.removeEventListener("mozbrowserloadstart", this);
- this.contentBrowser.removeEventListener("mozbrowserlocationchange", this, true);
-
- SystemAppProxy.registerFrameWithId(remoteShell.id, remoteShell.contentBrowser);
- SystemAppProxy.addEventListenerWithId(this.id, "mozContentEvent", this);
-
- let content = this.contentBrowser.contentWindow;
- content.addEventListener("load", this, true);
- },
-
- notifyContentWindowLoaded: function () {
- SystemAppProxy.setIsLoadedWithId(this.id);
- },
-
- notifyEventListenerReady: function () {
- if (this._isEventListenerReady) {
- Cu.reportError("shell_remote.js: SystemApp has already been declared as being ready.");
- return;
- }
- this._isEventListenerReady = true;
- SystemAppProxy.setIsReadyWithId(this.id);
- },
-
- handleEvent: function(evt) {
- debug("Got an event: " + evt.type);
- let content = this.contentBrowser.contentWindow;
-
- switch(evt.type) {
- case "mozContentEvent":
- if (evt.detail.type === "system-message-listener-ready") {
- this.notifyEventListenerReady();
- }
- break;
- case "load":
- if (content.document.location == "about:blank") {
- return;
- }
- content.removeEventListener("load", this, true);
- this.notifyContentWindowLoaded();
- break;
- case "mozbrowserloadstart":
- if (content.document.location == "about:blank") {
- this.contentBrowser.addEventListener("mozbrowserlocationchange", this, true);
- return;
- }
- case "mozbrowserlocationchange":
- if (content.document.location == "about:blank") {
- return;
- }
- this.notifyContentStart();
- break;
- case "unload":
- this.stop();
- break;
- }
- }
-};
-
-window.onload = function() {
- if (remoteShell.hasStarted() == false) {
- remoteShell.start();
- }
-};
-
diff --git a/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js b/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js
deleted file mode 100644
index 1a5ed8274..000000000
--- a/b2g/chrome/content/test/mochitest/RecordingStatusChromeScript.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
-const { Services } = Cu.import('resource://gre/modules/Services.jsm');
-const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
-
-var processId;
-
-function peekChildId(aSubject, aTopic, aData) {
- Services.obs.removeObserver(peekChildId, 'recording-device-events');
- Services.obs.removeObserver(peekChildId, 'recording-device-ipc-events');
- let props = aSubject.QueryInterface(Ci.nsIPropertyBag2);
- if (props.hasKey('childID')) {
- processId = props.get('childID');
- }
-}
-
-addMessageListener('init-chrome-event', function(message) {
- // listen mozChromeEvent and forward to content process.
- let type = message.type;
- SystemAppProxy.addEventListener('mozChromeEvent', function(event) {
- let details = event.detail;
- if (details.type === type) {
- sendAsyncMessage('chrome-event', details);
- }
- }, true);
-
- Services.obs.addObserver(peekChildId, 'recording-device-events', false);
- Services.obs.addObserver(peekChildId, 'recording-device-ipc-events', false);
-});
-
-addMessageListener('fake-content-shutdown', function(message) {
- let props = Cc["@mozilla.org/hash-property-bag;1"]
- .createInstance(Ci.nsIWritablePropertyBag2);
- if (processId) {
- props.setPropertyAsUint64('childID', processId);
- }
- Services.obs.notifyObservers(props, 'recording-device-ipc-events', 'content-shutdown');
-});
diff --git a/b2g/chrome/content/test/mochitest/RecordingStatusHelper.js b/b2g/chrome/content/test/mochitest/RecordingStatusHelper.js
deleted file mode 100644
index 5e3e6814e..000000000
--- a/b2g/chrome/content/test/mochitest/RecordingStatusHelper.js
+++ /dev/null
@@ -1,82 +0,0 @@
-'use strict';
-
-// resolve multiple promise in parallel
-function expectAll(aValue) {
- let deferred = new Promise(function(resolve, reject) {
- let countdown = aValue.length;
- let resolutionValues = new Array(countdown);
-
- for (let i = 0; i < aValue.length; i++) {
- let index = i;
- aValue[i].then(function(val) {
- resolutionValues[index] = val;
- if (--countdown === 0) {
- resolve(resolutionValues);
- }
- }, reject);
- }
- });
-
- return deferred;
-}
-
-function TestInit() {
- let url = SimpleTest.getTestFileURL("RecordingStatusChromeScript.js")
- let script = SpecialPowers.loadChromeScript(url);
-
- let helper = {
- finish: function () {
- script.destroy();
- },
- fakeShutdown: function () {
- script.sendAsyncMessage('fake-content-shutdown', {});
- }
- };
-
- script.addMessageListener('chrome-event', function (message) {
- if (helper.hasOwnProperty('onEvent')) {
- helper.onEvent(message);
- } else {
- ok(false, 'unexpected message: ' + JSON.stringify(message));
- }
- });
-
- script.sendAsyncMessage("init-chrome-event", {
- type: 'recording-status'
- });
-
- return Promise.resolve(helper);
-}
-
-function expectEvent(expected, eventHelper) {
- return new Promise(function(resolve, reject) {
- eventHelper.onEvent = function(message) {
- delete eventHelper.onEvent;
- ok(message, JSON.stringify(message));
- is(message.type, 'recording-status', 'event type: ' + message.type);
- is(message.active, expected.active, 'recording active: ' + message.active);
- is(message.isAudio, expected.isAudio, 'audio recording active: ' + message.isAudio);
- is(message.isVideo, expected.isVideo, 'video recording active: ' + message.isVideo);
- resolve(eventHelper);
- };
- info('waiting for recording-status');
- });
-}
-
-function expectStream(params, callback) {
- return new Promise(function(resolve, reject) {
- var req = navigator.mozGetUserMedia(
- params,
- function(stream) {
- ok(true, 'create media stream');
- callback(stream);
- resolve();
- },
- function(err) {
- ok(false, 'fail to create media stream');
- reject(err);
- }
- );
- info('waiting for gUM result');
- });
-}
diff --git a/b2g/chrome/content/test/mochitest/file_getusermedia_iframe.html b/b2g/chrome/content/test/mochitest/file_getusermedia_iframe.html
deleted file mode 100644
index f2b18eab3..000000000
--- a/b2g/chrome/content/test/mochitest/file_getusermedia_iframe.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Iframe for Recording Status</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript;version=1.7" src="RecordingStatusHelper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-
-<pre id="test">
-<script class="testbody" type="text/javascript;version=1.7">
-
-var localStream;
-
-window.addEventListener('message', function(event) {
- switch (event.data) {
- case 'start':
- let gumDeferred = expectStream({ audio: true,
- fake: true
- }, function(stream) {
- localStream = stream;
- event.source.postMessage('start-finished', window.location.origin);
- });
- break;
- case 'stop':
- localStream.stop();
- localStream = null;
- break;
- }
-}, false);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/chrome/content/test/mochitest/mochitest.ini b/b2g/chrome/content/test/mochitest/mochitest.ini
deleted file mode 100644
index d18a20401..000000000
--- a/b2g/chrome/content/test/mochitest/mochitest.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && toolkit != 'gonk') #require OOP support for mochitest-b2g-desktop, Bug 957554
-support-files =
- RecordingStatusChromeScript.js
- RecordingStatusHelper.js
- file_getusermedia_iframe.html
-
-[test_recordingStatus_basic.html]
-[test_recordingStatus_multiple_requests.html]
-[test_recordingStatus_iframe.html]
-[test_recordingStatus_kill_content_process.html]
diff --git a/b2g/chrome/content/test/mochitest/moz.build b/b2g/chrome/content/test/mochitest/moz.build
deleted file mode 100644
index 3b13ba431..000000000
--- a/b2g/chrome/content/test/mochitest/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOCHITEST_MANIFESTS += ['mochitest.ini']
diff --git a/b2g/chrome/content/test/mochitest/test_recordingStatus_basic.html b/b2g/chrome/content/test/mochitest/test_recordingStatus_basic.html
deleted file mode 100644
index 21f746d33..000000000
--- a/b2g/chrome/content/test/mochitest/test_recordingStatus_basic.html
+++ /dev/null
@@ -1,119 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test for Recording Status</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript;version=1.7" src="RecordingStatusHelper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-
-<pre id="test">
-<script class="testbody" type="text/javascript;version=1.7">
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-function test() {
- let localStreams = [];
- TestInit().then(function(eventHelper) {
- /* step 1: create one audio stream
- * expect: see one mozChromeEvent for audio recording start.
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: false
- }, eventHelper);
-
- let gumDeferred = expectStream({ audio: true,
- fake: true
- }, function(stream) {
- localStreams.push(stream);
- });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 2: close the audio stream
- * expect: see one mozChromeEvent for recording stop.
- */
- let eventDeferred = expectEvent({ active: false,
- isAudio: false,
- isVideo: false,
- }, eventHelper);
-
- localStreams.shift().stop();
- info('stop audio stream');
- return eventDeferred;
- }).then(function(eventHelper) {
- /* step 3: create one video stream
- * expect: see one mozChromeEvent for video recording start
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: false,
- isVideo: true
- }, eventHelper);
-
- let gumDeferred = expectStream({ video: true,
- fake: true
- }, function(stream) {
- localStreams.push(stream);
- });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 4: close the audio stream
- * expect: see one mozChromeEvent for recording stop.
- */
- let eventDeferred = expectEvent({ active: false,
- isAudio: false,
- isVideo: false,
- }, eventHelper);
-
- localStreams.shift().stop();
- info('stop video stream');
- return eventDeferred;
- }).then(function(eventHelper) {
- /* step 3: create one audio/video stream
- * expect: see one mozChromeEvent for audio/video recording start
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: true
- }, eventHelper);
-
- let gumDeferred = expectStream({ audio: true,
- video: true,
- fake: true
- }, function(stream) {
- localStreams.push(stream);
- });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 4: close the audio stream
- * expect: see one mozChromeEvent for recording stop.
- */
- let eventDeferred = expectEvent({ active: false,
- isAudio: false,
- isVideo: false,
- }, eventHelper);
-
- localStreams.shift().stop();
- info('stop audio/video stream');
- return eventDeferred;
- }).then(function(eventHelper) {
- eventHelper.finish();
- SimpleTest.finish();
- });
-}
-
-SpecialPowers.pushPrefEnv({
- "set": [
- ['media.navigator.permission.disabled', true]
- ]
-}, test);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/chrome/content/test/mochitest/test_recordingStatus_iframe.html b/b2g/chrome/content/test/mochitest/test_recordingStatus_iframe.html
deleted file mode 100644
index 88c33c897..000000000
--- a/b2g/chrome/content/test/mochitest/test_recordingStatus_iframe.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test for Recording Status in iframe</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript;version=1.7" src="RecordingStatusHelper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-
-<pre id="test">
-<iframe id="gum-iframe"></iframe>
-<script class="testbody" type="text/javascript;version=1.7">
-SimpleTest.waitForExplicitFinish();
-
-function test() {
- TestInit().then(function(eventHelper) {
- /* step 1: load iframe whilch creates audio stream
- * expect: see one mozChromeEvent for audio recording start.
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: false
- }, eventHelper);
-
- let loadDeferred = new Promise(function(resolve, reject) {
- let gumIframe = document.getElementById('gum-iframe');
- gumIframe.src = 'file_getusermedia_iframe.html';
-
- window.addEventListener('message', function(event) {
- if (event.data === 'start-finished') {
- resolve();
- }
- }, false);
-
- gumIframe.onload = function() {
- info('start audio stream in iframe');
- gumIframe.contentWindow.postMessage('start', window.location.origin);
- };
- });
-
- return expectAll([eventDeferred, loadDeferred]);
- }).then(function([eventHelper]) {
- /* step 2: close the audio stream
- * expect: see one mozChromeEvent for recording stop.
- */
- let eventDeferred = expectEvent({ active: false,
- isAudio: false,
- isVideo: false
- }, eventHelper);
-
- let win = document.getElementById('gum-iframe').contentWindow;
- win.postMessage('stop', window.location.origin);
- info('stop audio stream in iframe');
- return eventDeferred;
- }).then(function(eventHelper) {
- eventHelper.finish();
- SimpleTest.finish();
- });
-}
-
-SpecialPowers.pushPrefEnv({
- "set": [
- ['media.navigator.permission.disabled', true]
- ]
-}, test);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/chrome/content/test/mochitest/test_recordingStatus_kill_content_process.html b/b2g/chrome/content/test/mochitest/test_recordingStatus_kill_content_process.html
deleted file mode 100644
index 239c2c2d5..000000000
--- a/b2g/chrome/content/test/mochitest/test_recordingStatus_kill_content_process.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test for Recording Status after process shutdown</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript;version=1.7" src="RecordingStatusHelper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-
-<pre id="test">
-<script class="testbody" type="text/javascript;version=1.7">
-SimpleTest.waitForExplicitFinish();
-
-function test() {
- let localStreams = [];
- TestInit().then(function(eventHelper) {
- /* step 1: load iframe whilch creates audio stream
- * expect: see one mozChromeEvent for audio recording start.
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: false
- }, eventHelper);
-
- let gumDeferred = expectStream({ audio: true,
- fake: true
- }, function(stream) { localStreams.push(stream); });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 2: create video stream
- * expect: see one mozChromeEvent for audio recording start.
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: true
- }, eventHelper);
-
- let gumDeferred = expectStream({ video: true,
- fake: true
- }, function(stream) { localStreams.push(stream); });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 3: close the audio stream
- * expect: see one mozChromeEvent for recording stop.
- */
- let eventDeferred = expectEvent({ active: false,
- isAudio: false,
- isVideo: false
- }, eventHelper);
-
- eventHelper.fakeShutdown();
- info('simulate content process been killed');
- return eventDeferred;
- }).then(function(eventHelper) {
- eventHelper.finish();
- SimpleTest.finish();
- });
-}
-
-SpecialPowers.pushPrefEnv({
- "set": [
- ['media.navigator.permission.disabled', true]
- ]
-}, test);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/chrome/content/test/mochitest/test_recordingStatus_multiple_requests.html b/b2g/chrome/content/test/mochitest/test_recordingStatus_multiple_requests.html
deleted file mode 100644
index 7d31a94f8..000000000
--- a/b2g/chrome/content/test/mochitest/test_recordingStatus_multiple_requests.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test for Recording Status with multiple gUM requests</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript;version=1.7" src="RecordingStatusHelper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-
-<pre id="test">
-<script class="testbody" type="text/javascript;version=1.7">
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-function test() {
- let localStreams = [];
- TestInit().then(function(eventHelper) {
- /* step 1: create one audio stream
- * expect: see one mozChromeEvent for recording start.
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: false
- }, eventHelper);
-
- let gumDeferred = expectStream({ audio: true,
- fake: true
- }, function(stream) {
- localStreams.push(stream);
- });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 2: create another audio stream
- * expect: no mozChromeEvent after audio stream is created
- */
- let gumDeferred = expectStream({ audio: true,
- fake: true
- }, function(stream) {
- localStreams.push(stream);
- });
-
- return expectAll([Promise.resolve(eventHelper), gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 3: create video stream
- * expect: see one mozChromeEvent for recording start
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: true,
- isVideo: true
- }, eventHelper);
-
- let gumDeferred = expectStream({ video: true,
- fake: true
- }, function(stream) {
- localStreams.push(stream);
- });
-
- return expectAll([eventDeferred, gumDeferred]);
- }).then(function([eventHelper]) {
- /* step 4: stop first audio stream
- * expect: no mozChromeEvent after first audio stream is stopped
- */
- localStreams.shift().stop();
- info('stop the first audio stream');
- return Promise.resolve(eventHelper);
- }).then(function(eventHelper) {
- /* step 5: stop the second audio stream
- * expect: see one mozChromeEvent for audio recording stop.
- */
- let eventDeferred = expectEvent({ active: true,
- isAudio: false,
- isVideo: true
- }, eventHelper);
-
- localStreams.shift().stop();
- info('stop the second audio stream');
- return eventDeferred;
- }).then(function(eventHelper) {
- /* step 6: stop the video stream
- * expect: see one mozChromeEvent for video recording stop.
- */
- let eventDeferred = expectEvent({ active: false,
- isAudio: false,
- isVideo: false
- }, eventHelper);
-
- localStreams.shift().stop();
- info('stop the video stream');
- return eventDeferred;
- }).then(function(eventHelper) {
- eventHelper.finish();
- SimpleTest.finish();
- });
-}
-
-SpecialPowers.pushPrefEnv({
- "set": [
- ['media.navigator.permission.disabled', true]
- ]
-}, test);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/chrome/content/touchcontrols.css b/b2g/chrome/content/touchcontrols.css
deleted file mode 100644
index 7c407c331..000000000
--- a/b2g/chrome/content/touchcontrols.css
+++ /dev/null
@@ -1,233 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
-
-/* video controls */
-.controlsOverlay {
- -moz-box-pack: center;
- -moz-box-align: end;
- -moz-box-flex: 1;
- -moz-box-orient: horizontal;
-}
-
-.controlsOverlay[scaled] {
- /* scaled attribute in videocontrols.css causes conflict
- due to different -moz-box-orient values */
- -moz-box-align: end;
-}
-
-.controlBar {
- -moz-box-flex: 1;
- background-color: rgba(50,50,50,0.8);
- width: 100%;
-}
-
-.buttonsBar {
- -moz-box-flex: 1;
- -moz-box-align: center;
-}
-
-.controlsSpacer {
- display: none;
- -moz-box-flex: 0;
-}
-
-.fullscreenButton,
-.playButton,
-.castingButton,
-.muteButton {
- -moz-appearance: none;
- padding: 2px;
- border: none !important;
- min-height: 24px;
- min-width: 24px;
-}
-
-.fullscreenButton {
- background: url("chrome://b2g/content/images/fullscreen-hdpi.png") no-repeat center;
- background-size: contain;
- background-origin: content-box;
-}
-
-.fullscreenButton[fullscreened="true"] {
- background: url("chrome://b2g/content/images/exitfullscreen-hdpi.png") no-repeat center;
- background-size: contain;
- background-origin: content-box;
-}
-
-.controlBar[fullscreen-unavailable] .fullscreenButton {
- display: none;
-}
-
-.playButton {
- background: url("chrome://b2g/content/images/pause-hdpi.png") no-repeat center;
- background-size: contain;
- background-origin: content-box;
-}
-
-/*
- * Normally the button bar has fullscreen spacer play spacer mute, but if
- * this is an audio control rather than a video control, the fullscreen button
- * is hidden by videocontrols.xml, and that alters the position of the
- * play button. This workaround moves it back to center.
- */
-.controlBar[fullscreen-unavailable] .playButton {
- transform: translateX(28px);
-}
-
-.playButton[paused="true"] {
- background: url("chrome://b2g/content/images/play-hdpi.png") no-repeat center;
- background-size: contain;
- background-origin: content-box;
-}
-
-.castingButton {
- display: none;
-}
-
-.muteButton {
- background: url("chrome://b2g/content/images/mute-hdpi.png") no-repeat center;
- background-size: contain;
- background-origin: content-box;
-}
-
-.muteButton[muted="true"] {
- background: url("chrome://b2g/content/images/unmute-hdpi.png") no-repeat center;
- background-size: contain;
- background-origin: content-box;
-}
-
-/* bars */
-.scrubberStack {
- -moz-box-flex: 1;
- padding: 0px 18px;
-}
-
-.flexibleBar,
-.flexibleBar .progress-bar,
-.bufferBar,
-.bufferBar .progress-bar,
-.progressBar,
-.progressBar .progress-bar,
-.scrubber,
-.scrubber .scale-slider,
-.scrubber .scale-thumb {
- -moz-appearance: none;
- border: none;
- padding: 0px;
- margin: 0px;
- background-color: transparent;
-}
-
-.flexibleBar,
-.bufferBar,
-.progressBar {
- height: 24px;
- padding: 11px 0px;
-}
-
-.flexibleBar {
- padding: 12px 0px;
-}
-
-.flexibleBar .progress-bar {
- border: 1px #777777 solid;
- border-radius: 1px;
-}
-
-.bufferBar .progress-bar {
- border: 2px #AFB1B3 solid;
- border-radius: 2px;
-}
-
-.progressBar .progress-bar {
- border: 2px #FF9500 solid;
- border-radius: 2px;
-}
-
-
-.scrubber {
- margin-left: -8px;
- margin-right: -8px;
-}
-
-.positionLabel, .durationLabel {
- font-family: 'Roboto', Helvetica, Arial, sans-serif;
- font-size: 12px;
- color: white;
-}
-
-.scrubber .scale-thumb {
- display: -moz-box;
- margin: 0px !important;
- padding: 0px !important;
- background: url("chrome://b2g/content/images/scrubber-hdpi.png") no-repeat;
- background-size: 12px 12px;
- height: 12px;
- width: 12px;
-}
-
-.statusOverlay {
- -moz-box-align: center;
- -moz-box-pack: center;
- background-color: rgb(50,50,50);
-}
-
-.statusIcon {
- margin-bottom: 28px;
- width: 36px;
- height: 36px;
-}
-
-.statusIcon[type="throbber"] {
- background: url("chrome://b2g/content/images/throbber.png") no-repeat center;
-}
-
-.statusIcon[type="error"] {
- background: url("chrome://b2g/content/images/error.png") no-repeat center;
-}
-
-/* CSS Transitions */
-.controlBar:not([immediate]) {
- transition-property: opacity;
- transition-duration: 200ms;
-}
-
-.controlBar[fadeout] {
- opacity: 0;
-}
-
-.statusOverlay:not([immediate]) {
- transition-property: opacity;
- transition-duration: 300ms;
- transition-delay: 750ms;
-}
-
-.statusOverlay[fadeout] {
- opacity: 0;
-}
-
-.volumeStack,
-.controlBar[firstshow="true"] .fullscreenButton,
-.controlBar[firstshow="true"] .muteButton,
-.controlBar[firstshow="true"] .scrubberStack,
-.controlBar[firstshow="true"] .durationBox,
-.timeLabel {
- display: none;
-}
-
-/* Error description formatting */
-.errorLabel {
- font-family: Helvetica, Arial, sans-serif;
- font-size: 11px;
- color: #bbb;
- text-shadow:
- -1px -1px 0 #000,
- 1px -1px 0 #000,
- -1px 1px 0 #000,
- 1px 1px 0 #000;
- padding: 0 10px;
- text-align: center;
-}
diff --git a/b2g/chrome/jar.mn b/b2g/chrome/jar.mn
deleted file mode 100644
index 1fdea9a50..000000000
--- a/b2g/chrome/jar.mn
+++ /dev/null
@@ -1,60 +0,0 @@
-#filter substitution
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-chrome.jar:
-% content branding %content/branding/ contentaccessible=yes
-% content b2g %content/
-
- content/arrow.svg (content/arrow.svg)
- content/settings.js (content/settings.js)
-* content/shell.html (content/shell.html)
- content/shell.js (content/shell.js)
- content/shell_remote.html (content/shell_remote.html)
- content/shell_remote.js (content/shell_remote.js)
-* content/shell.css (content/shell.css)
- content/blank.html (content/blank.html)
- content/blank.css (content/blank.css)
-#ifdef MOZ_WIDGET_GONK
- content/devtools/adb.js (content/devtools/adb.js)
-#endif
- content/devtools/debugger.js (content/devtools/debugger.js)
- content/devtools/hud.js (content/devtools/hud.js)
-#ifndef MOZ_WIDGET_GONK
- content/desktop.css (content/desktop.css)
- content/images/desktop/home-black.png (content/images/desktop/home-black.png)
- content/images/desktop/home-white.png (content/images/desktop/home-white.png)
- content/images/desktop/rotate.png (content/images/desktop/rotate.png)
- content/desktop.js (content/desktop.js)
- content/screen.js (content/screen.js)
-#endif
-* content/content.css (content/content.css)
- content/touchcontrols.css (content/touchcontrols.css)
-
- content/identity.js (content/identity.js)
-
-#ifndef MOZ_GRAPHENE
-% override chrome://global/skin/media/videocontrols.css chrome://b2g/content/touchcontrols.css
-#endif
-% override chrome://global/content/aboutCertError.xhtml chrome://b2g/content/aboutCertError.xhtml
-% override chrome://global/skin/netError.css chrome://b2g/content/netError.css
-
- content/ErrorPage.js (content/ErrorPage.js)
- content/aboutCertError.xhtml (content/aboutCertError.xhtml)
- content/netError.css (content/netError.css)
- content/images/errorpage-larry-black.png (content/images/errorpage-larry-black.png)
- content/images/errorpage-larry-white.png (content/images/errorpage-larry-white.png)
- content/images/errorpage-warning.png (content/images/errorpage-warning.png)
- content/images/arrowdown-16.png (content/images/arrowdown-16.png)
- content/images/arrowright-16.png (content/images/arrowright-16.png)
- content/images/scrubber-hdpi.png (content/images/scrubber-hdpi.png)
- content/images/unmute-hdpi.png (content/images/unmute-hdpi.png)
- content/images/pause-hdpi.png (content/images/pause-hdpi.png)
- content/images/play-hdpi.png (content/images/play-hdpi.png)
- content/images/mute-hdpi.png (content/images/mute-hdpi.png)
- content/images/fullscreen-hdpi.png (content/images/fullscreen-hdpi.png)
- content/images/exitfullscreen-hdpi.png (content/images/exitfullscreen-hdpi.png)
- content/images/throbber.png (content/images/throbber.png)
- content/images/error.png (content/images/error.png)
diff --git a/b2g/chrome/moz.build b/b2g/chrome/moz.build
deleted file mode 100644
index 99af44a5c..000000000
--- a/b2g/chrome/moz.build
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEFINES['AB_CD'] = CONFIG['MOZ_UI_LOCALE']
-DEFINES['PACKAGE'] = 'b2g'
-DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
-
-JAR_MANIFESTS += ['jar.mn']
-
-TEST_DIRS += ['content/test/mochitest']
diff --git a/b2g/common.configure b/b2g/common.configure
deleted file mode 100644
index 854de4b15..000000000
--- a/b2g/common.configure
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Truetype fonts for B2G
-# ==============================================================
-option(env='MOZTTDIR', nargs=1, help='Path to truetype fonts for B2G')
-
-@depends('MOZTTDIR')
-@imports('os')
-def mozttdir(value):
- if value:
- path = value[0]
- if not os.path.isdir(path):
- die('MOZTTDIR "%s" is not a valid directory', path)
- return path
-
-set_config('MOZTTDIR', mozttdir)
-
-@depends('MOZTTDIR')
-def package_moztt(value):
- if value:
- return True
-
-set_define('PACKAGE_MOZTT', package_moztt)
-
-imply_option('MOZ_ENABLE_WARNINGS_AS_ERRORS',
- depends(target)(lambda t: t.os == 'Android'), reason='--target')
-
-include('../toolkit/moz.configure')
diff --git a/b2g/components/AboutServiceWorkers.jsm b/b2g/components/AboutServiceWorkers.jsm
deleted file mode 100644
index fe67e9c34..000000000
--- a/b2g/components/AboutServiceWorkers.jsm
+++ /dev/null
@@ -1,183 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict"
-
-this.EXPORTED_SYMBOLS = ["AboutServiceWorkers"];
-
-const { interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
- "@mozilla.org/serviceworkers/manager;1",
- "nsIServiceWorkerManager");
-
-function debug(aMsg) {
- dump("AboutServiceWorkers - " + aMsg + "\n");
-}
-
-function serializeServiceWorkerInfo(aServiceWorkerInfo) {
- if (!aServiceWorkerInfo) {
- throw new Error("Invalid service worker information");
- }
-
- let result = {};
-
- result.principal = {
- origin: aServiceWorkerInfo.principal.originNoSuffix,
- originAttributes: aServiceWorkerInfo.principal.originAttributes
- };
-
- ["scope", "scriptSpec"].forEach(property => {
- result[property] = aServiceWorkerInfo[property];
- });
-
- return result;
-}
-
-
-this.AboutServiceWorkers = {
- get enabled() {
- if (this._enabled) {
- return this._enabled;
- }
- this._enabled = false;
- try {
- this._enabled = Services.prefs.getBoolPref("dom.serviceWorkers.enabled");
- } catch(e) {}
- return this._enabled;
- },
-
- init: function() {
- SystemAppProxy.addEventListener("mozAboutServiceWorkersContentEvent",
- AboutServiceWorkers);
- },
-
- sendResult: function(aId, aResult) {
- SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
- id: aId,
- result: aResult
- });
- },
-
- sendError: function(aId, aError) {
- SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
- id: aId,
- error: aError
- });
- },
-
- handleEvent: function(aEvent) {
- let message = aEvent.detail;
-
- debug("Got content event " + JSON.stringify(message));
-
- if (!message.id || !message.name) {
- dump("Invalid event " + JSON.stringify(message) + "\n");
- return;
- }
-
- let self = AboutServiceWorkers;
-
- switch(message.name) {
- case "init":
- if (!self.enabled) {
- self.sendResult(message.id, {
- enabled: false,
- registrations: []
- });
- return;
- };
-
- let data = gServiceWorkerManager.getAllRegistrations();
- if (!data) {
- self.sendError(message.id, "NoServiceWorkersRegistrations");
- return;
- }
-
- let registrations = [];
-
- for (let i = 0; i < data.length; i++) {
- let info = data.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
- if (!info) {
- dump("AboutServiceWorkers: Invalid nsIServiceWorkerRegistrationInfo " +
- "interface.\n");
- continue;
- }
- registrations.push(serializeServiceWorkerInfo(info));
- }
-
- self.sendResult(message.id, {
- enabled: self.enabled,
- registrations: registrations
- });
- break;
-
- case "update":
- if (!message.scope) {
- self.sendError(message.id, "MissingScope");
- return;
- }
-
- if (!message.principal ||
- !message.principal.originAttributes) {
- self.sendError(message.id, "MissingOriginAttributes");
- return;
- }
-
- gServiceWorkerManager.propagateSoftUpdate(
- message.principal.originAttributes,
- message.scope
- );
-
- self.sendResult(message.id, true);
- break;
-
- case "unregister":
- if (!message.principal ||
- !message.principal.origin ||
- !message.principal.originAttributes ||
- !message.principal.originAttributes.appId ||
- (message.principal.originAttributes.inIsolatedMozBrowser == null)) {
- self.sendError(message.id, "MissingPrincipal");
- return;
- }
-
- let principal = Services.scriptSecurityManager.createCodebasePrincipal(
- // TODO: Bug 1196652. use originNoSuffix
- Services.io.newURI(message.principal.origin, null, null),
- message.principal.originAttributes);
-
- if (!message.scope) {
- self.sendError(message.id, "MissingScope");
- return;
- }
-
- let serviceWorkerUnregisterCallback = {
- unregisterSucceeded: function() {
- self.sendResult(message.id, true);
- },
-
- unregisterFailed: function() {
- self.sendError(message.id, "UnregisterError");
- },
-
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIServiceWorkerUnregisterCallback
- ])
- };
- gServiceWorkerManager.propagateUnregister(principal,
- serviceWorkerUnregisterCallback,
- message.scope);
- break;
- }
- }
-};
-
-AboutServiceWorkers.init();
diff --git a/b2g/components/ActivityChannel.jsm b/b2g/components/ActivityChannel.jsm
deleted file mode 100644
index 9dfa13d67..000000000
--- a/b2g/components/ActivityChannel.jsm
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
- "@mozilla.org/childprocessmessagemanager;1",
- "nsIMessageSender");
-
-XPCOMUtils.defineLazyServiceGetter(this, "contentSecManager",
- "@mozilla.org/contentsecuritymanager;1",
- "nsIContentSecurityManager");
-
-this.EXPORTED_SYMBOLS = ["ActivityChannel"];
-
-this.ActivityChannel = function(aURI, aLoadInfo, aName, aDetails) {
- this._activityName = aName;
- this._activityDetails = aDetails;
- this.originalURI = aURI;
- this.URI = aURI;
- this.loadInfo = aLoadInfo;
-}
-
-this.ActivityChannel.prototype = {
- originalURI: null,
- URI: null,
- owner: null,
- notificationCallbacks: null,
- securityInfo: null,
- contentType: null,
- contentCharset: null,
- contentLength: 0,
- contentDisposition: Ci.nsIChannel.DISPOSITION_INLINE,
- contentDispositionFilename: null,
- contentDispositionHeader: null,
- loadInfo: null,
-
- open: function() {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- open2: function() {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- asyncOpen: function(aListener, aContext) {
- cpmm.sendAsyncMessage(this._activityName, this._activityDetails);
- // Let the listener cleanup.
- aListener.onStopRequest(this, aContext, Cr.NS_OK);
- },
-
- asyncOpen2: function(aListener) {
- // throws an error if security checks fail
- var outListener = contentSecManager.performSecurityCheck(this, aListener);
- this.asyncOpen(outListener, null);
- },
-
- QueryInterface2: XPCOMUtils.generateQI([Ci.nsIChannel])
-}
diff --git a/b2g/components/AlertsHelper.jsm b/b2g/components/AlertsHelper.jsm
deleted file mode 100644
index 820f2406c..000000000
--- a/b2g/components/AlertsHelper.jsm
+++ /dev/null
@@ -1,279 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = [];
-
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cc = Components.classes;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
- "@mozilla.org/system-message-internal;1",
- "nsISystemMessagesInternal");
-
-XPCOMUtils.defineLazyServiceGetter(this, "appsService",
- "@mozilla.org/AppsService;1",
- "nsIAppsService");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage",
- "@mozilla.org/notificationStorage;1",
- "nsINotificationStorage");
-
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
- return Cc["@mozilla.org/parentprocessmessagemanager;1"]
- .getService(Ci.nsIMessageListenerManager);
-});
-
-function debug(str) {
- //dump("=*= AlertsHelper.jsm : " + str + "\n");
-}
-
-const kNotificationIconSize = 128;
-
-const kDesktopNotificationPerm = "desktop-notification";
-
-const kNotificationSystemMessageName = "notification";
-
-const kDesktopNotification = "desktop-notification";
-const kDesktopNotificationShow = "desktop-notification-show";
-const kDesktopNotificationClick = "desktop-notification-click";
-const kDesktopNotificationClose = "desktop-notification-close";
-
-const kTopicAlertClickCallback = "alertclickcallback";
-const kTopicAlertShow = "alertshow";
-const kTopicAlertFinished = "alertfinished";
-
-const kMozChromeNotificationEvent = "mozChromeNotificationEvent";
-const kMozContentNotificationEvent = "mozContentNotificationEvent";
-
-const kMessageAlertNotificationSend = "alert-notification-send";
-const kMessageAlertNotificationClose = "alert-notification-close";
-
-const kMessages = [
- kMessageAlertNotificationSend,
- kMessageAlertNotificationClose
-];
-
-var AlertsHelper = {
-
- _listeners: {},
-
- init: function() {
- Services.obs.addObserver(this, "xpcom-shutdown", false);
- for (let message of kMessages) {
- ppmm.addMessageListener(message, this);
- }
- SystemAppProxy.addEventListener(kMozContentNotificationEvent, this);
- },
-
- observe: function(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "xpcom-shutdown":
- Services.obs.removeObserver(this, "xpcom-shutdown");
- for (let message of kMessages) {
- ppmm.removeMessageListener(message, this);
- }
- SystemAppProxy.removeEventListener(kMozContentNotificationEvent, this);
- break;
- }
- },
-
- handleEvent: function(evt) {
- let detail = evt.detail;
-
- switch(detail.type) {
- case kDesktopNotificationShow:
- case kDesktopNotificationClick:
- case kDesktopNotificationClose:
- this.handleNotificationEvent(detail);
- break;
- default:
- debug("FIXME: Unhandled notification event: " + detail.type);
- break;
- }
- },
-
- handleNotificationEvent: function(detail) {
- if (!detail || !detail.id) {
- return;
- }
-
- let uid = detail.id;
- let listener = this._listeners[uid];
- if (!listener) {
- return;
- }
-
- let topic;
- if (detail.type === kDesktopNotificationClick) {
- topic = kTopicAlertClickCallback;
- } else if (detail.type === kDesktopNotificationShow) {
- topic = kTopicAlertShow;
- } else {
- /* kDesktopNotificationClose */
- topic = kTopicAlertFinished;
- }
-
- if (listener.cookie) {
- try {
- listener.observer.observe(null, topic, listener.cookie);
- } catch (e) { }
- } else {
- if (detail.type === kDesktopNotificationClose && listener.dbId) {
- notificationStorage.delete(listener.manifestURL, listener.dbId);
- }
- }
-
- // we"re done with this notification
- if (detail.type === kDesktopNotificationClose) {
- delete this._listeners[uid];
- }
- },
-
- registerListener: function(alertId, cookie, alertListener) {
- this._listeners[alertId] = { observer: alertListener, cookie: cookie };
- },
-
- registerAppListener: function(uid, listener) {
- this._listeners[uid] = listener;
-
- appsService.getManifestFor(listener.manifestURL).then((manifest) => {
- let app = appsService.getAppByManifestURL(listener.manifestURL);
- let helper = new ManifestHelper(manifest, app.origin, app.manifestURL);
- let getNotificationURLFor = function(messages) {
- if (!messages) {
- return null;
- }
-
- for (let i = 0; i < messages.length; i++) {
- let message = messages[i];
- if (message === kNotificationSystemMessageName) {
- return helper.fullLaunchPath();
- } else if (typeof message === "object" &&
- kNotificationSystemMessageName in message) {
- return helper.resolveURL(message[kNotificationSystemMessageName]);
- }
- }
-
- // No message found...
- return null;
- }
-
- listener.target = getNotificationURLFor(manifest.messages);
-
- // Bug 816944 - Support notification messages for entry_points.
- });
- },
-
- deserializeStructuredClone: function(dataString) {
- if (!dataString) {
- return null;
- }
- let scContainer = Cc["@mozilla.org/docshell/structured-clone-container;1"].
- createInstance(Ci.nsIStructuredCloneContainer);
-
- // The maximum supported structured-clone serialization format version
- // as defined in "js/public/StructuredClone.h"
- let JS_STRUCTURED_CLONE_VERSION = 4;
- scContainer.initFromBase64(dataString, JS_STRUCTURED_CLONE_VERSION);
- let dataObj = scContainer.deserializeToVariant();
-
- // We have to check whether dataObj contains DOM objects (supported by
- // nsIStructuredCloneContainer, but not by Cu.cloneInto), e.g. ImageData.
- // After the structured clone callback systems will be unified, we'll not
- // have to perform this check anymore.
- try {
- let data = Cu.cloneInto(dataObj, {});
- } catch(e) { dataObj = null; }
-
- return dataObj;
- },
-
- showNotification: function(imageURL, title, text, textClickable, cookie,
- uid, dir, lang, dataObj, manifestURL, timestamp,
- behavior) {
- function send(appName, appIcon) {
- SystemAppProxy._sendCustomEvent(kMozChromeNotificationEvent, {
- type: kDesktopNotification,
- id: uid,
- icon: imageURL,
- title: title,
- text: text,
- dir: dir,
- lang: lang,
- appName: appName,
- appIcon: appIcon,
- manifestURL: manifestURL,
- timestamp: timestamp,
- data: dataObj,
- mozbehavior: behavior
- });
- }
-
- if (!manifestURL || !manifestURL.length) {
- send(null, null);
- return;
- }
-
- // If we have a manifest URL, get the icon and title from the manifest
- // to prevent spoofing.
- appsService.getManifestFor(manifestURL).then((manifest) => {
- let app = appsService.getAppByManifestURL(manifestURL);
- let helper = new ManifestHelper(manifest, app.origin, manifestURL);
- send(helper.name, helper.iconURLForSize(kNotificationIconSize));
- });
- },
-
- showAlertNotification: function(aMessage) {
- let data = aMessage.data;
- let currentListener = this._listeners[data.name];
- if (currentListener && currentListener.observer) {
- currentListener.observer.observe(null, kTopicAlertFinished, currentListener.cookie);
- }
-
- let dataObj = this.deserializeStructuredClone(data.dataStr);
- this.registerListener(data.name, data.cookie, data.alertListener);
- this.showNotification(data.imageURL, data.title, data.text,
- data.textClickable, data.cookie, data.name, data.dir,
- data.lang, dataObj, null, data.inPrivateBrowsing);
- },
-
- closeAlert: function(name) {
- SystemAppProxy._sendCustomEvent(kMozChromeNotificationEvent, {
- type: kDesktopNotificationClose,
- id: name
- });
- },
-
- receiveMessage: function(aMessage) {
- if (!aMessage.target.assertAppHasPermission(kDesktopNotificationPerm)) {
- Cu.reportError("Desktop-notification message " + aMessage.name +
- " from a content process with no " + kDesktopNotificationPerm +
- " privileges.");
- return;
- }
-
- switch(aMessage.name) {
- case kMessageAlertNotificationSend:
- this.showAlertNotification(aMessage);
- break;
-
- case kMessageAlertNotificationClose:
- this.closeAlert(aMessage.data.name);
- break;
- }
-
- },
-}
-
-AlertsHelper.init();
diff --git a/b2g/components/AlertsService.js b/b2g/components/AlertsService.js
deleted file mode 100644
index 19a164f0e..000000000
--- a/b2g/components/AlertsService.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cc = Components.classes;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
- "@mozilla.org/system-message-internal;1",
- "nsISystemMessagesInternal");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidGenerator",
- "@mozilla.org/uuid-generator;1",
- "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage",
- "@mozilla.org/notificationStorage;1",
- "nsINotificationStorage");
-
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
- return Cc["@mozilla.org/childprocessmessagemanager;1"]
- .getService(Ci.nsIMessageSender);
-});
-
-function debug(str) {
- dump("=*= AlertsService.js : " + str + "\n");
-}
-
-// -----------------------------------------------------------------------
-// Alerts Service
-// -----------------------------------------------------------------------
-
-const kNotificationSystemMessageName = "notification";
-
-const kMessageAlertNotificationSend = "alert-notification-send";
-const kMessageAlertNotificationClose = "alert-notification-close";
-
-const kTopicAlertShow = "alertshow";
-const kTopicAlertFinished = "alertfinished";
-const kTopicAlertClickCallback = "alertclickcallback";
-
-function AlertsService() {
- Services.obs.addObserver(this, "xpcom-shutdown", false);
-}
-
-AlertsService.prototype = {
- classID: Components.ID("{fe33c107-82a4-41d6-8c64-5353267e04c9}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService,
- Ci.nsIObserver]),
-
- observe: function(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "xpcom-shutdown":
- Services.obs.removeObserver(this, "xpcom-shutdown");
- break;
- }
- },
-
- // nsIAlertsService
- showAlert: function(aAlert, aAlertListener) {
- if (!aAlert) {
- return;
- }
- cpmm.sendAsyncMessage(kMessageAlertNotificationSend, {
- imageURL: aAlert.imageURL,
- title: aAlert.title,
- text: aAlert.text,
- clickable: aAlert.textClickable,
- cookie: aAlert.cookie,
- listener: aAlertListener,
- id: aAlert.name,
- dir: aAlert.dir,
- lang: aAlert.lang,
- dataStr: aAlert.data,
- inPrivateBrowsing: aAlert.inPrivateBrowsing
- });
- },
-
- showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable,
- aCookie, aAlertListener, aName, aBidi,
- aLang, aDataStr, aPrincipal,
- aInPrivateBrowsing) {
- let alert = Cc["@mozilla.org/alert-notification;1"].
- createInstance(Ci.nsIAlertNotification);
-
- alert.init(aName, aImageUrl, aTitle, aText, aTextClickable, aCookie,
- aBidi, aLang, aDataStr, aPrincipal, aInPrivateBrowsing);
-
- this.showAlert(alert, aAlertListener);
- },
-
- closeAlert: function(aName) {
- cpmm.sendAsyncMessage(kMessageAlertNotificationClose, {
- name: aName
- });
- },
-
- // AlertsService.js custom implementation
- _listeners: [],
-
- receiveMessage: function(aMessage) {
- let data = aMessage.data;
- let listener = this._listeners[data.uid];
- if (!listener) {
- return;
- }
-
- let topic = data.topic;
-
- try {
- listener.observer.observe(null, topic, null);
- } catch (e) {
- if (topic === kTopicAlertFinished && listener.dbId) {
- notificationStorage.delete(listener.manifestURL, listener.dbId);
- }
- }
-
- // we're done with this notification
- if (topic === kTopicAlertFinished) {
- delete this._listeners[data.uid];
- }
- },
-
- deserializeStructuredClone: function(dataString) {
- if (!dataString) {
- return null;
- }
- let scContainer = Cc["@mozilla.org/docshell/structured-clone-container;1"].
- createInstance(Ci.nsIStructuredCloneContainer);
-
- // The maximum supported structured-clone serialization format version
- // as defined in "js/public/StructuredClone.h"
- let JS_STRUCTURED_CLONE_VERSION = 4;
- scContainer.initFromBase64(dataString, JS_STRUCTURED_CLONE_VERSION);
- let dataObj = scContainer.deserializeToVariant();
-
- // We have to check whether dataObj contains DOM objects (supported by
- // nsIStructuredCloneContainer, but not by Cu.cloneInto), e.g. ImageData.
- // After the structured clone callback systems will be unified, we'll not
- // have to perform this check anymore.
- try {
- let data = Cu.cloneInto(dataObj, {});
- } catch(e) { dataObj = null; }
-
- return dataObj;
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlertsService]);
diff --git a/b2g/components/B2GAboutRedirector.js b/b2g/components/B2GAboutRedirector.js
deleted file mode 100644
index f4bcf47f4..000000000
--- a/b2g/components/B2GAboutRedirector.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-function debug(msg) {
- //dump("B2GAboutRedirector: " + msg + "\n");
-}
-
-function netErrorURL() {
- let systemManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
- systemManifestURL = Services.io.newURI(systemManifestURL, null, null);
- let netErrorURL = Services.prefs.getCharPref("b2g.neterror.url");
- netErrorURL = Services.io.newURI(netErrorURL, null, systemManifestURL);
- return netErrorURL.spec;
-}
-
-var modules = {
- certerror: {
- uri: "chrome://b2g/content/aboutCertError.xhtml",
- privileged: false,
- hide: true
- },
- neterror: {
- uri: netErrorURL(),
- privileged: false,
- hide: true
- }
-};
-
-function B2GAboutRedirector() {}
-B2GAboutRedirector.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
- classID: Components.ID("{920400b1-cf8f-4760-a9c4-441417b15134}"),
-
- _getModuleInfo: function (aURI) {
- let moduleName = aURI.path.replace(/[?#].*/, "").toLowerCase();
- return modules[moduleName];
- },
-
- // nsIAboutModule
- getURIFlags: function(aURI) {
- let flags;
- let moduleInfo = this._getModuleInfo(aURI);
- if (moduleInfo.hide)
- flags = Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
-
- return flags | Ci.nsIAboutModule.ALLOW_SCRIPT;
- },
-
- newChannel: function(aURI, aLoadInfo) {
- let moduleInfo = this._getModuleInfo(aURI);
-
- var ios = Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
-
- var newURI = ios.newURI(moduleInfo.uri, null, null);
-
- var channel = ios.newChannelFromURIWithLoadInfo(newURI, aLoadInfo);
-
- if (!moduleInfo.privileged) {
- // Setting the owner to null means that we'll go through the normal
- // path in GetChannelPrincipal and create a codebase principal based
- // on the channel's originalURI
- channel.owner = null;
- }
-
- channel.originalURI = aURI;
-
- return channel;
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GAboutRedirector]);
diff --git a/b2g/components/B2GAppMigrator.js b/b2g/components/B2GAppMigrator.js
deleted file mode 100644
index 65671d151..000000000
--- a/b2g/components/B2GAppMigrator.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-function debug(s) {
- dump("-*- B2GAppMigrator.js: " + s + "\n");
-}
-const DEBUG = false;
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-const kMigrationMessageName = "webapps-before-update-merge";
-
-const kIDBDirType = "indexedDBPDir";
-const kProfileDirType = "ProfD";
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "appsService",
- "@mozilla.org/AppsService;1",
- "nsIAppsService");
-
-function B2GAppMigrator() {
-}
-
-B2GAppMigrator.prototype = {
- classID: Components.ID('{7211ece0-b458-4635-9afc-f8d7f376ee95}'),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
- Ci.nsISupportsWeakReference]),
- executeBrowserMigration: function() {
- if (DEBUG) debug("Executing Browser Migration");
- // The browser db file and directory names are hashed the same way
- // everywhere, so it should be the same on all systems. We should
- // be able to just hardcode it.
- let browserDBDirName = "2959517650brreosw";
- let browserDBFileName = browserDBDirName + ".sqlite";
-
- // Storage directories need to be prefixed with the local id of
- // the app
- let browserLocalAppId = appsService.getAppLocalIdByManifestURL("app://browser.gaiamobile.org/manifest.webapp");
- let browserAppStorageDirName = browserLocalAppId + "+f+app+++browser.gaiamobile.org";
-
- // On the phone, the browser db will only be in the old IDB
- // directory, since it only existed up until v2.0. On desktop, it
- // will exist in the profile directory.
- //
- // Uses getDir with filename appending to make sure we don't
- // create extra directories along the way if they don't already
- // exist.
- let browserDBFile = FileUtils.getDir(kIDBDirType,
- ["storage",
- "persistent",
- browserAppStorageDirName,
- "idb"], false, true);
- browserDBFile.append(browserDBFileName);
- let browserDBDir = FileUtils.getDir(kIDBDirType,
- ["storage",
- "persistent",
- browserAppStorageDirName,
- "idb",
- browserDBDirName
- ], false, true);
-
- if (!browserDBFile.exists()) {
- if (DEBUG) debug("Browser DB " + browserDBFile.path + " does not exist, trying profile location");
- browserDBFile = FileUtils.getDir(kProfileDirType,
- ["storage",
- "persistent",
- browserAppStorageDirName,
- "idb"], false, true);
- browserDBFile.append(browserDBFileName);
- if (!browserDBFile.exists()) {
- if (DEBUG) debug("Browser DB " + browserDBFile.path + " does not exist. Cannot copy browser db.");
- return;
- }
- // If we have confirmed we have a DB file, we should also have a
- // directory.
- browserDBDir = FileUtils.getDir(kProfileDirType,
- ["storage",
- "persistent",
- browserAppStorageDirName,
- "idb",
- browserDBDirName
- ], false, true);
- }
-
- let systemLocalAppId = appsService.getAppLocalIdByManifestURL("app://system.gaiamobile.org/manifest.webapp");
- let systemAppStorageDirName = systemLocalAppId + "+f+app+++system.gaiamobile.org";
-
- // This check futureproofs the system DB storage directory. It
- // currently exists outside of the profile but will most likely
- // move into the profile at some point.
- let systemDBDir = FileUtils.getDir(kIDBDirType,
- ["storage",
- "persistent",
- systemAppStorageDirName,
- "idb"], false, true);
-
- if (!systemDBDir.exists()) {
- if (DEBUG) debug("System DB directory " + systemDBDir.path + " does not exist, trying profile location");
- systemDBDir = FileUtils.getDir(kProfileDirType,
- ["storage",
- "persistent",
- systemAppStorageDirName,
- "idb"], false, true);
- if (!systemDBDir.exists()) {
- if (DEBUG) debug("System DB directory " + systemDBDir.path + " does not exist. Cannot copy browser db.");
- return;
- }
- }
-
- if (DEBUG) {
- debug("Browser DB file exists, copying");
- debug("Browser local id: " + browserLocalAppId + "");
- debug("System local id: " + systemLocalAppId + "");
- debug("Browser DB file path: " + browserDBFile.path + "");
- debug("Browser DB dir path: " + browserDBDir.path + "");
- debug("System DB directory path: " + systemDBDir.path + "");
- }
-
- try {
- browserDBFile.copyTo(systemDBDir, browserDBFileName);
- } catch (e) {
- debug("File copy caused error! " + e.name);
- }
- try {
- browserDBDir.copyTo(systemDBDir, browserDBDirName);
- } catch (e) {
- debug("Dir copy caused error! " + e.name);
- }
- if (DEBUG) debug("Browser DB copied successfully");
- },
-
- observe: function(subject, topic, data) {
- switch (topic) {
- case kMigrationMessageName:
- this.executeBrowserMigration();
- break;
- default:
- debug("Unhandled topic: " + topic);
- break;
- }
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GAppMigrator]);
diff --git a/b2g/components/B2GComponents.manifest b/b2g/components/B2GComponents.manifest
deleted file mode 100644
index 53d0032f9..000000000
--- a/b2g/components/B2GComponents.manifest
+++ /dev/null
@@ -1,108 +0,0 @@
-# Scrollbars
-category agent-style-sheets browser-content-stylesheet chrome://b2g/content/content.css
-
-# AlertsService.js
-component {fe33c107-82a4-41d6-8c64-5353267e04c9} AlertsService.js
-contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e04c9}
-
-# ContentPermissionPrompt.js
-component {8c719f03-afe0-4aac-91ff-6c215895d467} ContentPermissionPrompt.js
-contract @mozilla.org/content-permission/prompt;1 {8c719f03-afe0-4aac-91ff-6c215895d467}
-
-#ifdef MOZ_UPDATER
-# UpdatePrompt.js
-component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js
-contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59}
-category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
-#endif
-
-#ifdef MOZ_B2G
-# DirectoryProvider.js
-component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js
-contract @mozilla.org/b2g/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}
-category xpcom-directory-providers b2g-directory-provider @mozilla.org/b2g/directory-provider;1
-#endif
-
-# SystemMessageGlue.js
-component {2846f034-e614-11e3-93cd-74d02b97e723} SystemMessageGlue.js
-contract @mozilla.org/dom/messages/system-message-glue;1 {2846f034-e614-11e3-93cd-74d02b97e723}
-
-# ProcessGlobal.js
-component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js
-contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28}
-category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1
-
-# OMAContentHandler.js
-component {a6b2ab13-9037-423a-9897-dde1081be323} OMAContentHandler.js
-contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.drm.message {a6b2ab13-9037-423a-9897-dde1081be323}
-contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.dd+xml {a6b2ab13-9037-423a-9897-dde1081be323}
-
-# TelProtocolHandler.js
-component {782775dd-7351-45ea-aff1-0ffa872cfdd2} TelProtocolHandler.js
-contract @mozilla.org/network/protocol;1?name=tel {782775dd-7351-45ea-aff1-0ffa872cfdd2}
-
-# SmsProtocolHandler.js
-component {81ca20cb-0dad-4e32-8566-979c8998bd73} SmsProtocolHandler.js
-contract @mozilla.org/network/protocol;1?name=sms {81ca20cb-0dad-4e32-8566-979c8998bd73}
-
-# MailtoProtocolHandler.js
-component {50777e53-0331-4366-a191-900999be386c} MailtoProtocolHandler.js
-contract @mozilla.org/network/protocol;1?name=mailto {50777e53-0331-4366-a191-900999be386c}
-
-# RecoveryService.js
-component {b3caca5d-0bb0-48c6-912b-6be6cbf08832} RecoveryService.js
-contract @mozilla.org/recovery-service;1 {b3caca5d-0bb0-48c6-912b-6be6cbf08832}
-
-# B2GAboutRedirector
-component {920400b1-cf8f-4760-a9c4-441417b15134} B2GAboutRedirector.js
-contract @mozilla.org/network/protocol/about;1?what=certerror {920400b1-cf8f-4760-a9c4-441417b15134}
-contract @mozilla.org/network/protocol/about;1?what=neterror {920400b1-cf8f-4760-a9c4-441417b15134}
-
-#ifndef MOZ_GRAPHENE
-# FilePicker.js
-component {436ff8f9-0acc-4b11-8ec7-e293efba3141} FilePicker.js
-contract @mozilla.org/filepicker;1 {436ff8f9-0acc-4b11-8ec7-e293efba3141}
-#endif
-
-# FxAccountsUIGlue.js
-component {51875c14-91d7-4b8c-b65d-3549e101228c} FxAccountsUIGlue.js
-contract @mozilla.org/fxaccounts/fxaccounts-ui-glue;1 {51875c14-91d7-4b8c-b65d-3549e101228c}
-
-# HelperAppDialog.js
-component {710322af-e6ae-4b0c-b2c9-1474a87b077e} HelperAppDialog.js
-contract @mozilla.org/helperapplauncherdialog;1 {710322af-e6ae-4b0c-b2c9-1474a87b077e}
-
-#ifndef MOZ_WIDGET_GONK
-component {c83c02c0-5d43-4e3e-987f-9173b313e880} SimulatorScreen.js
-contract @mozilla.org/simulator-screen;1 {c83c02c0-5d43-4e3e-987f-9173b313e880}
-category profile-after-change SimulatorScreen @mozilla.org/simulator-screen;1
-
-component {e30b0e13-2d12-4cb0-bc4c-4e617a1bf76e} OopCommandLine.js
-contract @mozilla.org/commandlinehandler/general-startup;1?type=b2goop {e30b0e13-2d12-4cb0-bc4c-4e617a1bf76e}
-category command-line-handler m-b2goop @mozilla.org/commandlinehandler/general-startup;1?type=b2goop
-
-component {385993fe-8710-4621-9fb1-00a09d8bec37} CommandLine.js
-contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds {385993fe-8710-4621-9fb1-00a09d8bec37}
-category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
-#endif
-
-# BootstrapCommandLine.js
-component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js
-contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}
-category command-line-handler m-b2gbootstrap @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap
-
-# B2GAppMigrator.js
-component {7211ece0-b458-4635-9afc-f8d7f376ee95} B2GAppMigrator.js
-contract @mozilla.org/app-migrator;1 {7211ece0-b458-4635-9afc-f8d7f376ee95}
-
-# B2GPresentationDevicePrompt.js
-component {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} B2GPresentationDevicePrompt.js
-contract @mozilla.org/presentation-device/prompt;1 {4a300c26-e99b-4018-ab9b-c48cf9bc4de1}
-
-# PresentationRequestUIGlue.js
-component {ccc8a839-0b64-422b-8a60-fb2af0e376d0} PresentationRequestUIGlue.js
-contract @mozilla.org/presentation/requestuiglue;1 {ccc8a839-0b64-422b-8a60-fb2af0e376d0}
-
-# SystemMessageInternal.js
-component {70589ca5-91ac-4b9e-b839-d6a88167d714} SystemMessageInternal.js
-contract @mozilla.org/system-message-internal;1 {70589ca5-91ac-4b9e-b839-d6a88167d714}
diff --git a/b2g/components/B2GPresentationDevicePrompt.js b/b2g/components/B2GPresentationDevicePrompt.js
deleted file mode 100644
index 998e0b7ac..000000000
--- a/b2g/components/B2GPresentationDevicePrompt.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-function debug(aMsg) {
- //dump("-*- B2GPresentationDevicePrompt: " + aMsg + "\n");
-}
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-const kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID = "@mozilla.org/presentation-device/prompt;1";
-const kB2GPRESENTATIONDEVICEPROMPT_CID = Components.ID("{4a300c26-e99b-4018-ab9b-c48cf9bc4de1}");
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-function B2GPresentationDevicePrompt() {}
-
-B2GPresentationDevicePrompt.prototype = {
- classID: kB2GPRESENTATIONDEVICEPROMPT_CID,
- contractID: kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID,
- classDescription: "B2G Presentation Device Prompt",
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt]),
-
- // nsIPresentationDevicePrompt
- promptDeviceSelection: function(aRequest) {
- let self = this;
- let requestId = Cc["@mozilla.org/uuid-generator;1"]
- .getService(Ci.nsIUUIDGenerator).generateUUID().toString();
-
- SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(aEvent) {
- let detail = aEvent.detail;
- if (detail.id !== requestId) {
- return;
- }
-
- SystemAppProxy.removeEventListener("mozContentEvent", contentEvent);
-
- switch (detail.type) {
- case "presentation-select-result":
- debug("device " + detail.deviceId + " is selected by user");
- let device = self._getDeviceById(detail.deviceId);
- if (!device) {
- debug("cancel request because device is not found");
- aRequest.cancel(Cr.NS_ERROR_DOM_NOT_FOUND_ERR);
- }
- aRequest.select(device);
- break;
- case "presentation-select-deny":
- debug("request canceled by user");
- aRequest.cancel(Cr.NS_ERROR_DOM_NOT_ALLOWED_ERR);
- break;
- }
- });
-
- let detail = {
- type: "presentation-select-device",
- origin: aRequest.origin,
- requestURL: aRequest.requestURL,
- id: requestId,
- };
-
- SystemAppProxy.dispatchEvent(detail);
- },
-
- _getDeviceById: function(aDeviceId) {
- let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"]
- .getService(Ci.nsIPresentationDeviceManager);
- let devices = deviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray);
-
- for (let i = 0; i < devices.length; i++) {
- let device = devices.queryElementAt(i, Ci.nsIPresentationDevice);
- if (device.id === aDeviceId) {
- return device;
- }
- }
-
- return null;
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GPresentationDevicePrompt]);
diff --git a/b2g/components/BootstrapCommandLine.js b/b2g/components/BootstrapCommandLine.js
deleted file mode 100644
index 24d9f5461..000000000
--- a/b2g/components/BootstrapCommandLine.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-
-function BootstrapCommandlineHandler() {
- this.wrappedJSObject = this;
- this.startManifestURL = null;
-}
-
-BootstrapCommandlineHandler.prototype = {
- bailout: function(aMsg) {
- dump("************************************************************\n");
- dump("* /!\\ " + aMsg + "\n");
- dump("************************************************************\n");
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(appStartup.eForceQuit);
- },
-
- handle: function(aCmdLine) {
- this.startManifestURL = null;
-
- try {
- // Returns null if the argument was not specified. Throws
- // NS_ERROR_INVALID_ARG if there is no parameter specified (because
- // it was the last argument or the next argument starts with '-').
- // However, someone could still explicitly pass an empty argument!
- this.startManifestURL = aCmdLine.handleFlagWithParam("start-manifest", false);
- } catch(e) {
- return;
- }
-
- if (!this.startManifestURL) {
- return;
- }
-
- if (!isAbsoluteURI(this.startManifestURL)) {
- this.bailout("The start manifest url must be absolute.");
- return;
- }
- },
-
- helpInfo: "--start-manifest=manifest_url",
- classID: Components.ID("{fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BootstrapCommandlineHandler]);
diff --git a/b2g/components/Bootstraper.jsm b/b2g/components/Bootstraper.jsm
deleted file mode 100644
index 3d3fb37d9..000000000
--- a/b2g/components/Bootstraper.jsm
+++ /dev/null
@@ -1,156 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["Bootstraper"];
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const CC = Components.Constructor;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-
-function debug(aMsg) {
- //dump("-*- Bootstraper: " + aMsg + "\n");
-}
-
-/**
- * This module loads the manifest for app from the --start-url enpoint and
- * ensures that it's installed as the system app.
- */
-this.Bootstraper = {
- _manifestURL: null,
- _startupURL: null,
-
- bailout: function(aMsg) {
- dump("************************************************************\n");
- dump("* /!\\ " + aMsg + "\n");
- dump("************************************************************\n");
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(appStartup.eForceQuit);
- },
-
- installSystemApp: function(aManifest) {
- // Get the appropriate startup url from the manifest launch_path.
- let base = Services.io.newURI(this._manifestURL, null, null);
- let origin = base.prePath;
- let helper = new ManifestHelper(aManifest, origin, this._manifestURL);
- this._startupURL = helper.fullLaunchPath();
-
- return new Promise((aResolve, aReject) => {
- debug("Origin is " + origin);
- let appData = {
- app: {
- installOrigin: origin,
- origin: origin,
- manifest: aManifest,
- manifestURL: this._manifestURL,
- manifestHash: AppsUtils.computeHash(JSON.stringify(aManifest)),
- appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED
- },
- appId: 1,
- isBrowser: false,
- isPackage: false
- };
-
- //DOMApplicationRegistry.confirmInstall(appData, null, aResolve);
- });
- },
-
- /**
- * Resolves to a json manifest.
- */
- loadManifest: function() {
- return new Promise((aResolve, aReject) => {
- debug("Loading manifest " + this._manifestURL);
-
- let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
- .createInstance(Ci.nsIXMLHttpRequest);
- xhr.mozBackgroundRequest = true;
- xhr.open("GET", this._manifestURL);
- xhr.responseType = "json";
- xhr.addEventListener("load", () => {
- if (xhr.status >= 200 && xhr.status < 400) {
- debug("Success loading " + this._manifestURL);
- aResolve(xhr.response);
- } else {
- aReject("Error loading " + this._manifestURL);
- }
- });
- xhr.addEventListener("error", () => {
- aReject("Error loading " + this._manifestURL);
- });
- xhr.send(null);
- });
- },
-
- configure: function() {
- debug("Setting startup prefs... " + this._startupURL);
- Services.prefs.setCharPref("b2g.system_manifest_url", this._manifestURL);
- Services.prefs.setCharPref("b2g.system_startup_url", this._startupURL);
- return Promise.resolve();
- },
-
- /**
- * If a system app is already installed, uninstall it so that we can
- * cleanly replace it by the current one.
- */
- uninstallPreviousSystemApp: function() {
- // TODO: FIXME
- return Promise.resolve();
-
- let oldManifestURL;
- try{
- oldManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
- } catch(e) {
- // No preference set, so nothing to uninstall.
- return Promise.resolve();
- }
-
- let id = DOMApplicationRegistry.getAppLocalIdByManifestURL(oldManifestURL);
- if (id == Ci.nsIScriptSecurityManager.NO_APP_ID) {
- return Promise.resolve();
- }
- debug("Uninstalling " + oldManifestURL);
- return DOMApplicationRegistry.uninstall(oldManifestURL);
- },
-
- /**
- * Check if we are already configured to run from this manifest url.
- */
- isInstallRequired: function(aManifestURL) {
- try {
- if (Services.prefs.getCharPref("b2g.system_manifest_url") == aManifestURL) {
- return false;
- }
- } catch(e) { }
- return true;
- },
-
- /**
- * Resolves once we have installed the app.
- */
- ensureSystemAppInstall: function(aManifestURL) {
- this._manifestURL = aManifestURL;
- debug("Installing app from " + this._manifestURL);
-
- if (!this.isInstallRequired(this._manifestURL)) {
- debug("Already configured for " + this._manifestURL);
- return Promise.resolve();
- }
-
- return new Promise((aResolve, aReject) => {
- this.uninstallPreviousSystemApp.bind(this)
- .then(this.loadManifest.bind(this))
- .then(this.installSystemApp.bind(this))
- .then(this.configure.bind(this))
- .then(aResolve)
- .catch(aReject);
- });
- }
-};
diff --git a/b2g/components/CommandLine.js b/b2g/components/CommandLine.js
deleted file mode 100644
index 6dc48bd33..000000000
--- a/b2g/components/CommandLine.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
-
-// Small helper to expose nsICommandLine object to chrome code
-
-function CommandlineHandler() {
- this.wrappedJSObject = this;
-}
-
-CommandlineHandler.prototype = {
- handle: function(cmdLine) {
- this.cmdLine = cmdLine;
- let win = Services.wm.getMostRecentWindow("navigator:browser");
- if (win && win.shell) {
- win.shell.handleCmdLine();
- }
- },
-
- helpInfo: "",
- classID: Components.ID("{385993fe-8710-4621-9fb1-00a09d8bec37}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandlineHandler]);
diff --git a/b2g/components/ContentPermissionPrompt.js b/b2g/components/ContentPermissionPrompt.js
deleted file mode 100644
index e11b1b458..000000000
--- a/b2g/components/ContentPermissionPrompt.js
+++ /dev/null
@@ -1,461 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict"
-
-function debug(str) {
- //dump("-*- ContentPermissionPrompt: " + str + "\n");
-}
-
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-const Cc = Components.classes;
-
-const PROMPT_FOR_UNKNOWN = ["audio-capture",
- "desktop-notification",
- "geolocation",
- "video-capture"];
-// Due to privary issue, permission requests like GetUserMedia should prompt
-// every time instead of providing session persistence.
-const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"];
-const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
-Cu.import("resource://gre/modules/PermissionsTable.jsm");
-
-var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
-var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
-
-var permissionSpecificChecker = {};
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-/**
- * Determine if a permission should be prompt to user or not.
- *
- * @param aPerm requested permission
- * @param aAction the action according to principal
- * @return true if prompt is required
- */
-function shouldPrompt(aPerm, aAction) {
- return ((aAction == Ci.nsIPermissionManager.PROMPT_ACTION) ||
- (aAction == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
- PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0));
-}
-
-/**
- * Create the default choices for the requested permissions
- *
- * @param aTypesInfo requested permissions
- * @return the default choices for permissions with options, return
- * undefined if no option in all requested permissions.
- */
-function buildDefaultChoices(aTypesInfo) {
- let choices;
- for (let type of aTypesInfo) {
- if (type.options.length > 0) {
- if (!choices) {
- choices = {};
- }
- choices[type.access] = type.options[0];
- }
- }
- return choices;
-}
-
-/**
- * aTypesInfo is an array of {permission, access, action, deny} which keeps
- * the information of each permission. This arrary is initialized in
- * ContentPermissionPrompt.prompt and used among functions.
- *
- * aTypesInfo[].permission : permission name
- * aTypesInfo[].access : permission name + request.access
- * aTypesInfo[].action : the default action of this permission
- * aTypesInfo[].deny : true if security manager denied this app's origin
- * principal.
- * Note:
- * aTypesInfo[].permission will be sent to prompt only when
- * aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
- */
-function rememberPermission(aTypesInfo, aPrincipal, aSession)
-{
- function convertPermToAllow(aPerm, aPrincipal)
- {
- let type =
- permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
- if (shouldPrompt(aPerm, type)) {
- debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
- if (!aSession) {
- permissionManager.addFromPrincipal(aPrincipal,
- aPerm,
- Ci.nsIPermissionManager.ALLOW_ACTION);
- } else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
- permissionManager.addFromPrincipal(aPrincipal,
- aPerm,
- Ci.nsIPermissionManager.ALLOW_ACTION,
- Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
- }
- }
- }
-
- for (let i in aTypesInfo) {
- // Expand the permission to see if we have multiple access properties
- // to convert
- let perm = aTypesInfo[i].permission;
- let access = PermissionsTable[perm].access;
- if (access) {
- for (let idx in access) {
- convertPermToAllow(perm + "-" + access[idx], aPrincipal);
- }
- } else {
- convertPermToAllow(perm, aPrincipal);
- }
- }
-}
-
-function ContentPermissionPrompt() {}
-
-ContentPermissionPrompt.prototype = {
-
- handleExistingPermission: function handleExistingPermission(request,
- typesInfo) {
- typesInfo.forEach(function(type) {
- type.action =
- Services.perms.testExactPermissionFromPrincipal(request.principal,
- type.access);
- if (shouldPrompt(type.access, type.action)) {
- type.action = Ci.nsIPermissionManager.PROMPT_ACTION;
- }
- });
-
- // If all permissions are allowed already and no more than one option,
- // call allow() without prompting.
- let checkAllowPermission = function(type) {
- if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION &&
- type.options.length <= 1) {
- return true;
- }
- return false;
- }
- if (typesInfo.every(checkAllowPermission)) {
- debug("all permission requests are allowed");
- request.allow(buildDefaultChoices(typesInfo));
- return true;
- }
-
- // If all permissions are DENY_ACTION or UNKNOWN_ACTION, call cancel()
- // without prompting.
- let checkDenyPermission = function(type) {
- if (type.action == Ci.nsIPermissionManager.DENY_ACTION ||
- type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
- return true;
- }
- return false;
- }
- if (typesInfo.every(checkDenyPermission)) {
- debug("all permission requests are denied");
- request.cancel();
- return true;
- }
- return false;
- },
-
- // multiple requests should be audio and video
- checkMultipleRequest: function checkMultipleRequest(typesInfo) {
- if (typesInfo.length == 1) {
- return true;
- } else if (typesInfo.length > 1) {
- let checkIfAllowMultiRequest = function(type) {
- return (ALLOW_MULTIPLE_REQUESTS.indexOf(type.access) !== -1);
- }
- if (typesInfo.every(checkIfAllowMultiRequest)) {
- debug("legal multiple requests");
- return true;
- }
- }
-
- return false;
- },
-
- handledByApp: function handledByApp(request, typesInfo) {
- if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
- request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
- // This should not really happen
- request.cancel();
- return true;
- }
-
- let appsService = Cc["@mozilla.org/AppsService;1"]
- .getService(Ci.nsIAppsService);
- let app = appsService.getAppByLocalId(request.principal.appId);
-
- // Check each permission if it's denied by permission manager with app's
- // URL.
- let notDenyAppPrincipal = function(type) {
- let url = Services.io.newURI(app.origin, null, null);
- let principal =
- secMan.createCodebasePrincipal(url,
- {appId: request.principal.appId});
- let result = Services.perms.testExactPermissionFromPrincipal(principal,
- type.access);
-
- if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
- result == Ci.nsIPermissionManager.PROMPT_ACTION) {
- type.deny = false;
- }
- return !type.deny;
- }
- // Cancel the entire request if one of the requested permissions is denied
- if (!typesInfo.every(notDenyAppPrincipal)) {
- request.cancel();
- return true;
- }
-
- return false;
- },
-
- handledByPermissionType: function handledByPermissionType(request, typesInfo) {
- for (let i in typesInfo) {
- if (permissionSpecificChecker.hasOwnProperty(typesInfo[i].permission) &&
- permissionSpecificChecker[typesInfo[i].permission](request)) {
- return true;
- }
- }
-
- return false;
- },
-
- prompt: function(request) {
- // Initialize the typesInfo and set the default value.
- let typesInfo = [];
- let perms = request.types.QueryInterface(Ci.nsIArray);
- for (let idx = 0; idx < perms.length; idx++) {
- let perm = perms.queryElementAt(idx, Ci.nsIContentPermissionType);
- let tmp = {
- permission: perm.type,
- access: (perm.access && perm.access !== "unused") ?
- perm.type + "-" + perm.access : perm.type,
- options: [],
- deny: true,
- action: Ci.nsIPermissionManager.UNKNOWN_ACTION
- };
-
- // Append available options, if any.
- let options = perm.options.QueryInterface(Ci.nsIArray);
- for (let i = 0; i < options.length; i++) {
- let option = options.queryElementAt(i, Ci.nsISupportsString).data;
- tmp.options.push(option);
- }
- typesInfo.push(tmp);
- }
-
- if (secMan.isSystemPrincipal(request.principal)) {
- request.allow(buildDefaultChoices(typesInfo));
- return;
- }
-
-
- if (typesInfo.length == 0) {
- request.cancel();
- return;
- }
-
- if(!this.checkMultipleRequest(typesInfo)) {
- request.cancel();
- return;
- }
-
- if (this.handledByApp(request, typesInfo) ||
- this.handledByPermissionType(request, typesInfo)) {
- return;
- }
-
- // returns true if the request was handled
- if (this.handleExistingPermission(request, typesInfo)) {
- return;
- }
-
- // prompt PROMPT_ACTION request or request with options.
- typesInfo = typesInfo.filter(function(type) {
- return !type.deny && (type.action == Ci.nsIPermissionManager.PROMPT_ACTION || type.options.length > 0) ;
- });
-
- if (!request.element) {
- this.delegatePrompt(request, typesInfo);
- return;
- }
-
- var cancelRequest = function() {
- request.requester.onVisibilityChange = null;
- request.cancel();
- }
-
- var self = this;
-
- // If the request was initiated from a hidden iframe
- // we don't forward it to content and cancel it right away
- request.requester.getVisibility( {
- notifyVisibility: function(isVisible) {
- if (!isVisible) {
- cancelRequest();
- return;
- }
-
- // Monitor the frame visibility and cancel the request if the frame goes
- // away but the request is still here.
- request.requester.onVisibilityChange = {
- notifyVisibility: function(isVisible) {
- if (isVisible)
- return;
-
- self.cancelPrompt(request, typesInfo);
- cancelRequest();
- }
- }
-
- self.delegatePrompt(request, typesInfo, function onCallback() {
- request.requester.onVisibilityChange = null;
- });
- }
- });
-
- },
-
- cancelPrompt: function(request, typesInfo) {
- this.sendToBrowserWindow("cancel-permission-prompt", request,
- typesInfo);
- },
-
- delegatePrompt: function(request, typesInfo, callback) {
- this.sendToBrowserWindow("permission-prompt", request, typesInfo,
- function(type, remember, choices) {
- if (type == "permission-allow") {
- rememberPermission(typesInfo, request.principal, !remember);
- if (callback) {
- callback();
- }
- request.allow(choices);
- return;
- }
-
- let addDenyPermission = function(type) {
- debug("add " + type.permission +
- " to permission manager with DENY_ACTION");
- if (remember) {
- Services.perms.addFromPrincipal(request.principal, type.access,
- Ci.nsIPermissionManager.DENY_ACTION);
- } else if (PERMISSION_NO_SESSION.indexOf(type.access) < 0) {
- Services.perms.addFromPrincipal(request.principal, type.access,
- Ci.nsIPermissionManager.DENY_ACTION,
- Ci.nsIPermissionManager.EXPIRE_SESSION,
- 0);
- }
- }
- try {
- // This will trow if we are canceling because the remote process died.
- // Just eat the exception and call the callback that will cleanup the
- // visibility event listener.
- typesInfo.forEach(addDenyPermission);
- } catch(e) { }
-
- if (callback) {
- callback();
- }
-
- try {
- request.cancel();
- } catch(e) { }
- });
- },
-
- sendToBrowserWindow: function(type, request, typesInfo, callback) {
- let requestId = Cc["@mozilla.org/uuid-generator;1"]
- .getService(Ci.nsIUUIDGenerator).generateUUID().toString();
- if (callback) {
- SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(evt) {
- let detail = evt.detail;
- if (detail.id != requestId)
- return;
- SystemAppProxy.removeEventListener("mozContentEvent", contentEvent);
-
- callback(detail.type, detail.remember, detail.choices);
- })
- }
-
- let principal = request.principal;
- let isApp = principal.appStatus != Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED;
- let remember = (principal.appStatus == Ci.nsIPrincipal.APP_STATUS_PRIVILEGED ||
- principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
- ? true
- : request.remember;
- let isGranted = typesInfo.every(function(type) {
- return type.action == Ci.nsIPermissionManager.ALLOW_ACTION;
- });
- let permissions = {};
- for (let i in typesInfo) {
- debug("prompt " + typesInfo[i].permission);
- permissions[typesInfo[i].permission] = typesInfo[i].options;
- }
-
- let details = {
- type: type,
- permissions: permissions,
- id: requestId,
- // This system app uses the origin from permission events to
- // compare against the mozApp.origin of app windows, so we
- // are not concerned with origin suffixes here (appId, etc).
- origin: principal.originNoSuffix,
- isApp: isApp,
- remember: remember,
- isGranted: isGranted,
- };
-
- if (isApp) {
- details.manifestURL = DOMApplicationRegistry.getManifestURLByLocalId(principal.appId);
- }
-
- // request.element is defined for OOP content, while request.window
- // is defined for In-Process content.
- // In both cases the message needs to be dispatched to the top-level
- // <iframe mozbrowser> container in the system app.
- // So the above code iterates over window.realFrameElement in order
- // to crosss mozbrowser iframes boundaries and find the top-level
- // one in the system app.
- // window.realFrameElement will be |null| if the code try to cross
- // content -> chrome boundaries.
- let targetElement = request.element;
- let targetWindow = request.window || targetElement.ownerDocument.defaultView;
- while (targetWindow.realFrameElement) {
- targetElement = targetWindow.realFrameElement;
- targetWindow = targetElement.ownerDocument.defaultView;
- }
-
- SystemAppProxy.dispatchEvent(details, targetElement);
- },
-
- classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt])
-};
-
-(function() {
- // Do not allow GetUserMedia while in call.
- permissionSpecificChecker["audio-capture"] = function(request) {
- let forbid = false;
-
- if (forbid) {
- request.cancel();
- }
-
- return forbid;
- };
-})();
-
-//module initialization
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
diff --git a/b2g/components/ContentRequestHelper.jsm b/b2g/components/ContentRequestHelper.jsm
deleted file mode 100644
index 14d8d250b..000000000
--- a/b2g/components/ContentRequestHelper.jsm
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["ContentRequestHelper"];
-
-const { interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
- "@mozilla.org/uuid-generator;1",
- "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-function debug(msg) {
- // dump("ContentRequestHelper ** " + msg + "\n");
-}
-
-this.ContentRequestHelper = function() {
-}
-
-ContentRequestHelper.prototype = {
-
- contentRequest: function(aContentEventName, aChromeEventName,
- aInternalEventName, aData) {
- let deferred = Promise.defer();
-
- let id = uuidgen.generateUUID().toString();
-
- SystemAppProxy.addEventListener(aContentEventName,
- function onContentEvent(result) {
- SystemAppProxy.removeEventListener(aContentEventName,
- onContentEvent);
- let msg = result.detail;
- if (!msg || !msg.id || msg.id != id) {
- deferred.reject("InternalErrorWrongContentEvent " +
- JSON.stringify(msg));
- SystemAppProxy.removeEventListener(aContentEventName,
- onContentEvent);
- return;
- }
-
- debug("Got content event " + JSON.stringify(msg));
-
- if (msg.error) {
- deferred.reject(msg.error);
- } else {
- deferred.resolve(msg.result);
- }
- });
-
- let detail = {
- eventName: aInternalEventName,
- id: id,
- data: aData
- };
- debug("Send chrome event " + JSON.stringify(detail));
- SystemAppProxy._sendCustomEvent(aChromeEventName, detail);
-
- return deferred.promise;
- }
-};
diff --git a/b2g/components/DebuggerActors.js b/b2g/components/DebuggerActors.js
deleted file mode 100644
index 318c46e68..000000000
--- a/b2g/components/DebuggerActors.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { Cu } = require("chrome");
-const DevToolsUtils = require("devtools/shared/DevToolsUtils");
-const promise = require("promise");
-const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
-const { BrowserTabList } = require("devtools/server/actors/webbrowser");
-
-XPCOMUtils.defineLazyGetter(this, "Frames", function() {
- const { Frames } =
- Cu.import("resource://gre/modules/Frames.jsm", {});
- return Frames;
-});
-
-/**
- * Unlike the original BrowserTabList which iterates over XUL windows, we
- * override many portions to refer to Frames for the info needed here.
- */
-function B2GTabList(connection) {
- BrowserTabList.call(this, connection);
- this._listening = false;
-}
-
-B2GTabList.prototype = Object.create(BrowserTabList.prototype);
-
-B2GTabList.prototype._getBrowsers = function() {
- return Frames.list().filter(frame => {
- // Ignore app frames
- return !frame.getAttribute("mozapp");
- });
-};
-
-B2GTabList.prototype._getSelectedBrowser = function() {
- return this._getBrowsers().find(frame => {
- // Find the one visible browser (if any)
- return !frame.classList.contains("hidden");
- });
-};
-
-B2GTabList.prototype._checkListening = function() {
- // The conditions from BrowserTabList are merged here, since we must listen to
- // all events with our observer design.
- this._listenForEventsIf(this._onListChanged && this._mustNotify ||
- this._actorByBrowser.size > 0);
-};
-
-B2GTabList.prototype._listenForEventsIf = function(shouldListen) {
- if (this._listening != shouldListen) {
- let op = shouldListen ? "addObserver" : "removeObserver";
- Frames[op](this);
- this._listening = shouldListen;
- }
-};
-
-B2GTabList.prototype.onFrameCreated = function(frame) {
- let mozapp = frame.getAttribute("mozapp");
- if (mozapp) {
- // Ignore app frames
- return;
- }
- this._notifyListChanged();
- this._checkListening();
-};
-
-B2GTabList.prototype.onFrameDestroyed = function(frame) {
- let mozapp = frame.getAttribute("mozapp");
- if (mozapp) {
- // Ignore app frames
- return;
- }
- let actor = this._actorByBrowser.get(frame);
- if (actor) {
- this._handleActorClose(actor, frame);
- }
-};
-
-exports.B2GTabList = B2GTabList;
diff --git a/b2g/components/DirectoryProvider.js b/b2g/components/DirectoryProvider.js
deleted file mode 100644
index a7dccd0c9..000000000
--- a/b2g/components/DirectoryProvider.js
+++ /dev/null
@@ -1,295 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const XRE_OS_UPDATE_APPLY_TO_DIR = "OSUpdApplyToD"
-const UPDATE_ARCHIVE_DIR = "UpdArchD"
-const LOCAL_DIR = "/data/local";
-const UPDATES_DIR = "updates/0";
-const FOTA_DIR = "updates/fota";
-const COREAPPSDIR_PREF = "b2g.coreappsdir"
-
-XPCOMUtils.defineLazyServiceGetter(Services, "env",
- "@mozilla.org/process/environment;1",
- "nsIEnvironment");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "um",
- "@mozilla.org/updates/update-manager;1",
- "nsIUpdateManager");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "volumeService",
- "@mozilla.org/telephony/volume-service;1",
- "nsIVolumeService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
- "@mozilla.org/childprocessmessagemanager;1",
- "nsISyncMessageSender");
-
-XPCOMUtils.defineLazyGetter(this, "gExtStorage", function dp_gExtStorage() {
- return Services.env.get("EXTERNAL_STORAGE");
-});
-
-// This exists to mark the affected code for bug 828858.
-const gUseSDCard = true;
-
-const VERBOSE = 1;
-var log =
- VERBOSE ?
- function log_dump(msg) { dump("DirectoryProvider: " + msg + "\n"); } :
- function log_noop(msg) { };
-
-function DirectoryProvider() {
-}
-
-DirectoryProvider.prototype = {
- classID: Components.ID("{9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}"),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider]),
- _xpcom_factory: XPCOMUtils.generateSingletonFactory(DirectoryProvider),
-
- _profD: null,
-
- getFile: function(prop, persistent) {
- if (AppConstants.platform === "gonk") {
- return this.getFileOnGonk(prop, persistent);
- }
- return this.getFileNotGonk(prop, persistent);
- },
-
- getFileOnGonk: function(prop, persistent) {
- let localProps = ["cachePDir", "webappsDir", "PrefD", "indexedDBPDir",
- "permissionDBPDir", "UpdRootD"];
- if (localProps.indexOf(prop) != -1) {
- let file = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile)
- file.initWithPath(LOCAL_DIR);
- persistent.value = true;
- return file;
- }
- if (prop == "ProfD") {
- let dir = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- dir.initWithPath(LOCAL_DIR+"/tests/profile");
- if (dir.exists()) {
- persistent.value = true;
- return dir;
- }
- }
- if (prop == "coreAppsDir") {
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
- file.initWithPath("/system/b2g");
- persistent.value = true;
- return file;
- }
- if (prop == UPDATE_ARCHIVE_DIR) {
- // getUpdateDir will set persistent to false since it may toggle between
- // /data/local/ and /mnt/sdcard based on free space and/or availability
- // of the sdcard.
- // before download, check if free space is 2.1 times of update.mar
- return this.getUpdateDir(persistent, UPDATES_DIR, 2.1);
- }
- if (prop == XRE_OS_UPDATE_APPLY_TO_DIR) {
- // getUpdateDir will set persistent to false since it may toggle between
- // /data/local/ and /mnt/sdcard based on free space and/or availability
- // of the sdcard.
- // before apply, check if free space is 1.1 times of update.mar
- return this.getUpdateDir(persistent, FOTA_DIR, 1.1);
- }
- return null;
- },
-
- getFileNotGonk: function(prop, persistent) {
- // In desktop builds, coreAppsDir is the same as the profile
- // directory unless otherwise specified. We just need to get the
- // path from the parent, and it is then used to build
- // jar:remoteopenfile:// uris.
- if (prop == "coreAppsDir") {
- let coreAppsDirPref;
- try {
- coreAppsDirPref = Services.prefs.getCharPref(COREAPPSDIR_PREF);
- } catch (e) {
- // coreAppsDirPref may not exist if we're on an older version
- // of gaia, so just fail silently.
- }
- let appsDir;
- // If pref doesn't exist or isn't set, default to old value
- if (!coreAppsDirPref || coreAppsDirPref == "") {
- appsDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
- appsDir.append("webapps");
- } else {
- appsDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile)
- appsDir.initWithPath(coreAppsDirPref);
- }
- persistent.value = true;
- return appsDir;
- } else if (prop == "ProfD") {
- let inParent = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULRuntime)
- .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
- if (inParent) {
- // Just bail out to use the default from toolkit.
- return null;
- }
- if (!this._profD) {
- this._profD = cpmm.sendSyncMessage("getProfD", {})[0];
- }
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- file.initWithPath(this._profD);
- persistent.value = true;
- return file;
- }
- return null;
- },
-
- // The VolumeService only exists on the device, and not on desktop
- volumeHasFreeSpace: function dp_volumeHasFreeSpace(volumePath, requiredSpace) {
- if (!volumePath) {
- return false;
- }
- if (!Services.volumeService) {
- return false;
- }
- let volume = Services.volumeService.createOrGetVolumeByPath(volumePath);
- if (!volume || volume.state !== Ci.nsIVolume.STATE_MOUNTED) {
- return false;
- }
- let stat = volume.getStats();
- if (!stat) {
- return false;
- }
- return requiredSpace <= stat.freeBytes;
- },
-
- findUpdateDirWithFreeSpace: function dp_findUpdateDirWithFreeSpace(requiredSpace, subdir) {
- if (!Services.volumeService) {
- return this.createUpdatesDir(LOCAL_DIR, subdir);
- }
-
- let activeUpdate = Services.um.activeUpdate;
- if (gUseSDCard) {
- if (this.volumeHasFreeSpace(gExtStorage, requiredSpace)) {
- let extUpdateDir = this.createUpdatesDir(gExtStorage, subdir);
- if (extUpdateDir !== null) {
- return extUpdateDir;
- }
- log("Warning: " + gExtStorage + " has enough free space for update " +
- activeUpdate.name + ", but is not writable");
- }
- }
-
- if (this.volumeHasFreeSpace(LOCAL_DIR, requiredSpace)) {
- let localUpdateDir = this.createUpdatesDir(LOCAL_DIR, subdir);
- if (localUpdateDir !== null) {
- return localUpdateDir;
- }
- log("Warning: " + LOCAL_DIR + " has enough free space for update " +
- activeUpdate.name + ", but is not writable");
- }
-
- return null;
- },
-
- getUpdateDir: function dp_getUpdateDir(persistent, subdir, multiple) {
- let defaultUpdateDir = this.getDefaultUpdateDir();
- persistent.value = false;
-
- let activeUpdate = Services.um.activeUpdate;
- if (!activeUpdate) {
- log("Warning: No active update found, using default update dir: " +
- defaultUpdateDir);
- return defaultUpdateDir;
- }
-
- let selectedPatch = activeUpdate.selectedPatch;
- if (!selectedPatch) {
- log("Warning: No selected patch, using default update dir: " +
- defaultUpdateDir);
- return defaultUpdateDir;
- }
-
- let requiredSpace = selectedPatch.size * multiple;
- let updateDir = this.findUpdateDirWithFreeSpace(requiredSpace, subdir);
- if (updateDir) {
- return updateDir;
- }
-
- // If we've gotten this far, there isn't enough free space to download the patch
- // on either external storage or /data/local. All we can do is report the
- // error and let upstream code handle it more gracefully.
- log("Error: No volume found with " + requiredSpace + " bytes for downloading"+
- " update " + activeUpdate.name);
- activeUpdate.errorCode = Cr.NS_ERROR_FILE_TOO_BIG;
- return null;
- },
-
- createUpdatesDir: function dp_createUpdatesDir(root, subdir) {
- let dir = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- dir.initWithPath(root);
- if (!dir.isWritable()) {
- log("Error: " + dir.path + " isn't writable");
- return null;
- }
- dir.appendRelativePath(subdir);
- if (dir.exists()) {
- if (dir.isDirectory() && dir.isWritable()) {
- return dir;
- }
- // subdir is either a file or isn't writable. In either case we
- // can't use it.
- log("Error: " + dir.path + " is a file or isn't writable");
- return null;
- }
- // subdir doesn't exist, and the parent is writable, so try to
- // create it. This can fail if a file named updates exists.
- try {
- dir.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0770', 8));
- } catch (e) {
- // The create failed for some reason. We can't use it.
- log("Error: " + dir.path + " unable to create directory");
- return null;
- }
- return dir;
- },
-
- getDefaultUpdateDir: function dp_getDefaultUpdateDir() {
- let path = gExtStorage;
- if (!path) {
- path = LOCAL_DIR;
- }
-
- if (Services.volumeService) {
- let extVolume = Services.volumeService.createOrGetVolumeByPath(path);
- if (!extVolume) {
- path = LOCAL_DIR;
- }
- }
-
- let dir = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile)
- dir.initWithPath(path);
-
- if (!dir.exists() && path != LOCAL_DIR) {
- // Fallback to LOCAL_DIR if we didn't fallback earlier
- dir.initWithPath(LOCAL_DIR);
-
- if (!dir.exists()) {
- throw Cr.NS_ERROR_FILE_NOT_FOUND;
- }
- }
-
- dir.appendRelativePath("updates");
- return dir;
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);
diff --git a/b2g/components/ErrorPage.jsm b/b2g/components/ErrorPage.jsm
deleted file mode 100644
index 2c0c64c21..000000000
--- a/b2g/components/ErrorPage.jsm
+++ /dev/null
@@ -1,187 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-this.EXPORTED_SYMBOLS = ['ErrorPage'];
-
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const kErrorPageFrameScript = 'chrome://b2g/content/ErrorPage.js';
-
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "CertOverrideService", function () {
- return Cc["@mozilla.org/security/certoverride;1"]
- .getService(Ci.nsICertOverrideService);
-});
-
-/**
- * A class to add exceptions to override SSL certificate problems.
- * The functionality itself is borrowed from exceptionDialog.js.
- */
-function SSLExceptions(aCallback, aUri, aWindow) {
- this._finishCallback = aCallback;
- this._uri = aUri;
- this._window = aWindow;
-};
-
-SSLExceptions.prototype = {
- _finishCallback: null,
- _window: null,
- _uri: null,
- _temporary: null,
- _sslStatus: null,
-
- getInterface: function SSLE_getInterface(aIID) {
- return this.QueryInterface(aIID);
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2]),
-
- /**
- * To collect the SSL status we intercept the certificate error here
- * and store the status for later use.
- */
- notifyCertProblem: function SSLE_notifyCertProblem(aSocketInfo,
- aSslStatus,
- aTargetHost) {
- this._sslStatus = aSslStatus.QueryInterface(Ci.nsISSLStatus);
- Services.tm.currentThread.dispatch({
- run: this._addOverride.bind(this)
- }, Ci.nsIThread.DISPATCH_NORMAL);
- return true; // suppress error UI
- },
-
- /**
- * Attempt to download the certificate for the location specified to get
- * the SSLState for the certificate and the errors.
- */
- _checkCert: function SSLE_checkCert() {
- this._sslStatus = null;
- if (!this._uri) {
- return;
- }
- let req = new this._window.XMLHttpRequest();
- try {
- req.open("GET", this._uri.prePath, true);
- req.channel.notificationCallbacks = this;
- let xhrHandler = (function() {
- req.removeEventListener("load", xhrHandler);
- req.removeEventListener("error", xhrHandler);
- if (!this._sslStatus) {
- // Got response from server without an SSL error.
- if (this._finishCallback) {
- this._finishCallback();
- }
- }
- }).bind(this);
- req.addEventListener("load", xhrHandler);
- req.addEventListener("error", xhrHandler);
- req.send(null);
- } catch (e) {
- // We *expect* exceptions if there are problems with the certificate
- // presented by the site. Log it, just in case, but we can proceed here,
- // with appropriate sanity checks
- Components.utils.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " +
- "This results in a (mostly harmless) exception being thrown. " +
- "Logged for information purposes only: " + e);
- }
- },
-
- /**
- * Internal method to create an override.
- */
- _addOverride: function SSLE_addOverride() {
- let SSLStatus = this._sslStatus;
- let uri = this._uri;
- let flags = 0;
-
- if (SSLStatus.isUntrusted) {
- flags |= Ci.nsICertOverrideService.ERROR_UNTRUSTED;
- }
- if (SSLStatus.isDomainMismatch) {
- flags |= Ci.nsICertOverrideService.ERROR_MISMATCH;
- }
- if (SSLStatus.isNotValidAtThisTime) {
- flags |= Ci.nsICertOverrideService.ERROR_TIME;
- }
-
- CertOverrideService.rememberValidityOverride(
- uri.asciiHost,
- uri.port,
- SSLStatus.serverCert,
- flags,
- this._temporary);
-
- if (this._finishCallback) {
- this._finishCallback();
- }
- },
-
- /**
- * Creates a permanent exception to override all overridable errors for
- * the given URL.
- */
- addException: function SSLE_addException(aTemporary) {
- this._temporary = aTemporary;
- this._checkCert();
- }
-};
-
-var ErrorPage = {
- _addCertException: function(aMessage) {
- let frameLoaderOwner = aMessage.target.QueryInterface(Ci.nsIFrameLoaderOwner);
- let win = frameLoaderOwner.ownerDocument.defaultView;
- let mm = frameLoaderOwner.frameLoader.messageManager;
-
- let uri = Services.io.newURI(aMessage.data.url, null, null);
- let sslExceptions = new SSLExceptions((function() {
- mm.sendAsyncMessage('ErrorPage:ReloadPage');
- }).bind(this), uri, win);
- try {
- sslExceptions.addException(!aMessage.data.isPermanent);
- } catch (e) {
- dump("Failed to set cert exception: " + e + "\n");
- }
- },
-
- _listenError: function(frameLoader) {
- let self = this;
- let frameElement = frameLoader.ownerElement;
- let injectErrorPageScript = function() {
- let mm = frameLoader.messageManager;
- try {
- mm.loadFrameScript(kErrorPageFrameScript, true, true);
- } catch (e) {
- dump('Error loading ' + kErrorPageFrameScript + ' as frame script: ' + e + '\n');
- }
- mm.addMessageListener('ErrorPage:AddCertException', self._addCertException.bind(self));
- frameElement.removeEventListener('mozbrowsererror', injectErrorPageScript, true);
- };
-
- frameElement.addEventListener('mozbrowsererror',
- injectErrorPageScript,
- true // use capture
- );
- },
-
- init: function errorPageInit() {
- Services.obs.addObserver(this, 'inprocess-browser-shown', false);
- Services.obs.addObserver(this, 'remote-browser-shown', false);
- },
-
- observe: function errorPageObserve(aSubject, aTopic, aData) {
- let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
- // Ignore notifications that aren't from a BrowserOrApp
- if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
- return;
- }
- this._listenError(frameLoader);
- }
-};
-
-ErrorPage.init();
diff --git a/b2g/components/FilePicker.js b/b2g/components/FilePicker.js
deleted file mode 100644
index 803eef681..000000000
--- a/b2g/components/FilePicker.js
+++ /dev/null
@@ -1,223 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * No magic constructor behaviour, as is de rigeur for XPCOM.
- * If you must perform some initialization, and it could possibly fail (even
- * due to an out-of-memory condition), you should use an Init method, which
- * can convey failure appropriately (thrown exception in JS,
- * NS_FAILED(nsresult) return in C++).
- *
- * In JS, you can actually cheat, because a thrown exception will cause the
- * CreateInstance call to fail in turn, but not all languages are so lucky.
- * (Though ANSI C++ provides exceptions, they are verboten in Mozilla code
- * for portability reasons -- and even when you're building completely
- * platform-specific code, you can't throw across an XPCOM method boundary.)
- */
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-// FIXME: improve this list of filters.
-const IMAGE_FILTERS = ['image/gif', 'image/jpeg', 'image/pjpeg',
- 'image/png', 'image/svg+xml', 'image/tiff',
- 'image/vnd.microsoft.icon'];
-const VIDEO_FILTERS = ['video/mpeg', 'video/mp4', 'video/ogg',
- 'video/quicktime', 'video/webm', 'video/x-matroska',
- 'video/x-ms-wmv', 'video/x-flv'];
-const AUDIO_FILTERS = ['audio/basic', 'audio/L24', 'audio/mp4',
- 'audio/mpeg', 'audio/ogg', 'audio/vorbis',
- 'audio/vnd.rn-realaudio', 'audio/vnd.wave',
- 'audio/webm'];
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import("resource://gre/modules/osfile.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, 'cpmm',
- '@mozilla.org/childprocessmessagemanager;1',
- 'nsIMessageSender');
-
-function FilePicker() {
-}
-
-FilePicker.prototype = {
- classID: Components.ID('{436ff8f9-0acc-4b11-8ec7-e293efba3141}'),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
-
- /* members */
-
- mParent: undefined,
- mExtraProps: undefined,
- mFilterTypes: undefined,
- mFileEnumerator: undefined,
- mFilePickerShownCallback: undefined,
-
- /* methods */
-
- init: function(parent, title, mode) {
- this.mParent = parent;
- this.mExtraProps = {};
- this.mFilterTypes = [];
- this.mMode = mode;
-
- if (mode != Ci.nsIFilePicker.modeOpen &&
- mode != Ci.nsIFilePicker.modeOpenMultiple) {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- }
- },
-
- /* readonly attribute nsILocalFile file - not implemented; */
- /* readonly attribute nsISimpleEnumerator files - not implemented; */
- /* readonly attribute nsIURI fileURL - not implemented; */
-
- get domFileOrDirectoryEnumerator() {
- return this.mFilesEnumerator;
- },
-
- // We don't support directory selection yet.
- get domFileOrDirectory() {
- return this.mFilesEnumerator ? this.mFilesEnumerator.mFiles[0] : null;
- },
-
- get mode() {
- return this.mMode;
- },
-
- appendFilters: function(filterMask) {
- // Ci.nsIFilePicker.filterHTML is not supported
- // Ci.nsIFilePicker.filterText is not supported
-
- if (filterMask & Ci.nsIFilePicker.filterImages) {
- this.mFilterTypes = this.mFilterTypes.concat(IMAGE_FILTERS);
- // This property is needed for the gallery app pick activity.
- this.mExtraProps['nocrop'] = true;
- }
-
- // Ci.nsIFilePicker.filterXML is not supported
- // Ci.nsIFilePicker.filterXUL is not supported
- // Ci.nsIFilePicker.filterApps is not supported
- // Ci.nsIFilePicker.filterAllowURLs is not supported
-
- if (filterMask & Ci.nsIFilePicker.filterVideo) {
- this.mFilterTypes = this.mFilterTypes.concat(VIDEO_FILTERS);
- }
-
- if (filterMask & Ci.nsIFilePicker.filterAudio) {
- this.mFilterTypes = this.mFilterTypes.concat(AUDIO_FILTERS);
- }
-
- if (filterMask & Ci.nsIFilePicker.filterAll) {
- // This property is needed for the gallery app pick activity.
- this.mExtraProps['nocrop'] = true;
- }
- },
-
- appendFilter: function(title, extensions) {
- // pick activity doesn't support extensions
- },
-
- open: function(aFilePickerShownCallback) {
- this.mFilePickerShownCallback = aFilePickerShownCallback;
-
- cpmm.addMessageListener('file-picked', this);
-
- let detail = {};
- if (this.mFilterTypes) {
- detail.type = this.mFilterTypes;
- }
-
- for (let prop in this.mExtraProps) {
- if (!(prop in detail)) {
- detail[prop] = this.mExtraProps[prop];
- }
- }
-
- cpmm.sendAsyncMessage('file-picker', detail);
- },
-
- fireSuccess: function(file) {
- this.mFilesEnumerator = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
-
- mFiles: [file],
- mIndex: 0,
-
- hasMoreElements: function() {
- return (this.mIndex < this.mFiles.length);
- },
-
- getNext: function() {
- if (this.mIndex >= this.mFiles.length) {
- throw Components.results.NS_ERROR_FAILURE;
- }
- return this.mFiles[this.mIndex++];
- }
- };
-
- if (this.mFilePickerShownCallback) {
- this.mFilePickerShownCallback.done(Ci.nsIFilePicker.returnOK);
- this.mFilePickerShownCallback = null;
- }
- },
-
- fireError: function() {
- if (this.mFilePickerShownCallback) {
- this.mFilePickerShownCallback.done(Ci.nsIFilePicker.returnCancel);
- this.mFilePickerShownCallback = null;
- }
- },
-
- receiveMessage: function(message) {
- if (message.name !== 'file-picked') {
- return;
- }
-
- cpmm.removeMessageListener('file-picked', this);
-
- let data = message.data;
- if (!data.success || !data.result.blob) {
- this.fireError();
- return;
- }
-
- // The name to be shown can be part of the message, or can be taken from
- // the File (if the blob is a File).
- let name = data.result.name;
- if (!name &&
- (data.result.blob instanceof this.mParent.File) &&
- data.result.blob.name) {
- name = data.result.blob.name;
- }
-
- // Let's try to remove the full path and take just the filename.
- if (name) {
- let names = OS.Path.split(name);
- name = names.components[names.components.length - 1];
- }
-
- // the fallback is a filename composed by 'blob' + extension.
- if (!name) {
- name = 'blob';
- if (data.result.blob.type) {
- let mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
- let mimeInfo = mimeSvc.getFromTypeAndExtension(data.result.blob.type, '');
- if (mimeInfo) {
- name += '.' + mimeInfo.primaryExtension;
- }
- }
- }
-
- let file = new this.mParent.File([data.result.blob],
- name,
- { type: data.result.blob.type });
-
- if (file) {
- this.fireSuccess(file);
- } else {
- this.fireError();
- }
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FilePicker]);
diff --git a/b2g/components/Frames.jsm b/b2g/components/Frames.jsm
deleted file mode 100644
index 0eb00cb4c..000000000
--- a/b2g/components/Frames.jsm
+++ /dev/null
@@ -1,146 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-this.EXPORTED_SYMBOLS = ['Frames'];
-
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/SystemAppProxy.jsm');
-
-const listeners = [];
-
-const Observer = {
- // Save a map of (MessageManager => Frame) to be able to dispatch
- // the FrameDestroyed event with a frame reference.
- _frames: new Map(),
-
- // Also save current number of iframes opened by app
- _apps: new Map(),
-
- start: function () {
- Services.obs.addObserver(this, 'remote-browser-shown', false);
- Services.obs.addObserver(this, 'inprocess-browser-shown', false);
- Services.obs.addObserver(this, 'message-manager-close', false);
-
- SystemAppProxy.getFrames().forEach(frame => {
- let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
- this._frames.set(mm, frame);
- let mozapp = frame.getAttribute('mozapp');
- if (mozapp) {
- this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1);
- }
- });
- },
-
- stop: function () {
- Services.obs.removeObserver(this, 'remote-browser-shown');
- Services.obs.removeObserver(this, 'inprocess-browser-shown');
- Services.obs.removeObserver(this, 'message-manager-close');
- this._frames.clear();
- this._apps.clear();
- },
-
- observe: function (subject, topic, data) {
- switch(topic) {
-
- // Listen for frame creation in OOP (device) as well as in parent process (b2g desktop)
- case 'remote-browser-shown':
- case 'inprocess-browser-shown':
- let frameLoader = subject;
-
- // get a ref to the app <iframe>
- frameLoader.QueryInterface(Ci.nsIFrameLoader);
- let frame = frameLoader.ownerElement;
- let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
- this.onMessageManagerCreated(mm, frame);
- break;
-
- // Every time an iframe is destroyed, its message manager also is
- case 'message-manager-close':
- this.onMessageManagerDestroyed(subject);
- break;
- }
- },
-
- onMessageManagerCreated: function (mm, frame) {
- this._frames.set(mm, frame);
-
- let isFirstAppFrame = null;
- let mozapp = frame.getAttribute('mozapp');
- if (mozapp) {
- let count = (this._apps.get(mozapp) || 0) + 1;
- this._apps.set(mozapp, count);
- isFirstAppFrame = (count === 1);
- }
-
- listeners.forEach(function (listener) {
- try {
- listener.onFrameCreated(frame, isFirstAppFrame);
- } catch(e) {
- dump('Exception while calling Frames.jsm listener:' + e + '\n' +
- e.stack + '\n');
- }
- });
- },
-
- onMessageManagerDestroyed: function (mm) {
- let frame = this._frames.get(mm);
- if (!frame) {
- // We received an event for an unknown message manager
- return;
- }
-
- this._frames.delete(mm);
-
- let isLastAppFrame = null;
- let mozapp = frame.getAttribute('mozapp');
- if (mozapp) {
- let count = (this._apps.get(mozapp) || 0) - 1;
- this._apps.set(mozapp, count);
- isLastAppFrame = (count === 0);
- }
-
- listeners.forEach(function (listener) {
- try {
- listener.onFrameDestroyed(frame, isLastAppFrame);
- } catch(e) {
- dump('Exception while calling Frames.jsm listener:' + e + '\n' +
- e.stack + '\n');
- }
- });
- }
-
-};
-
-var Frames = this.Frames = {
-
- list: () => SystemAppProxy.getFrames(),
-
- addObserver: function (listener) {
- if (listeners.indexOf(listener) !== -1) {
- return;
- }
-
- listeners.push(listener);
- if (listeners.length == 1) {
- Observer.start();
- }
- },
-
- removeObserver: function (listener) {
- let idx = listeners.indexOf(listener);
- if (idx !== -1) {
- listeners.splice(idx, 1);
- }
- if (listeners.length === 0) {
- Observer.stop();
- }
- }
-
-};
-
diff --git a/b2g/components/FxAccountsMgmtService.jsm b/b2g/components/FxAccountsMgmtService.jsm
deleted file mode 100644
index e51f46ed7..000000000
--- a/b2g/components/FxAccountsMgmtService.jsm
+++ /dev/null
@@ -1,173 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Some specific (certified) apps need to get access to certain Firefox Accounts
- * functionality that allows them to manage accounts (this is mostly sign up,
- * sign in, logout and delete) and get information about the currently existing
- * ones.
- *
- * This service listens for requests coming from these apps, triggers the
- * appropriate Fx Accounts flows and send reponses back to the UI.
- *
- * The communication mechanism is based in mozFxAccountsContentEvent (for
- * messages coming from the UI) and mozFxAccountsChromeEvent (for messages
- * sent from the chrome side) custom events.
- */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["FxAccountsMgmtService"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager",
- "resource://gre/modules/FxAccountsManager.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-this.FxAccountsMgmtService = {
- _onFulfill: function(aMsgId, aData) {
- SystemAppProxy._sendCustomEvent("mozFxAccountsChromeEvent", {
- id: aMsgId,
- data: aData ? aData : null
- });
- },
-
- _onReject: function(aMsgId, aReason) {
- SystemAppProxy._sendCustomEvent("mozFxAccountsChromeEvent", {
- id: aMsgId,
- error: aReason ? aReason : null
- });
- },
-
- init: function() {
- Services.obs.addObserver(this, ONLOGIN_NOTIFICATION, false);
- Services.obs.addObserver(this, ONVERIFIED_NOTIFICATION, false);
- Services.obs.addObserver(this, ONLOGOUT_NOTIFICATION, false);
- SystemAppProxy.addEventListener("mozFxAccountsContentEvent",
- FxAccountsMgmtService);
- },
-
- observe: function(aSubject, aTopic, aData) {
- log.debug("Observed " + aTopic);
- switch (aTopic) {
- case ONLOGIN_NOTIFICATION:
- case ONVERIFIED_NOTIFICATION:
- case ONLOGOUT_NOTIFICATION:
- // FxAccounts notifications have the form of fxaccounts:*
- SystemAppProxy._sendCustomEvent("mozFxAccountsUnsolChromeEvent", {
- eventName: aTopic.substring(aTopic.indexOf(":") + 1)
- });
- break;
- }
- },
-
- handleEvent: function(aEvent) {
- let msg = aEvent.detail;
- log.debug("MgmtService got content event: " + JSON.stringify(msg));
- let self = FxAccountsMgmtService;
-
- if (!msg.id) {
- return;
- }
-
- if (msg.error) {
- self._onReject(msg.id, msg.error);
- return;
- }
-
- let data = msg.data;
- if (!data) {
- return;
- }
- // Backwards compatibility: handle accountId coming from Gaia
- if (data.accountId && typeof(data.email === "undefined")) {
- data.email = data.accountId;
- delete data.accountId;
- }
-
- // Bug 1202450 dirty hack because Gaia is sending getAccounts.
- if (data.method == "getAccounts") {
- data.method = "getAccount";
- }
-
- switch(data.method) {
- case "getAssertion":
- let principal = Services.scriptSecurityManager.getSystemPrincipal();
- let audience = data.audience || principal.originNoSuffix;
- FxAccountsManager.getAssertion(audience, principal, {
- silent: msg.silent || false
- }).then(result => {
- self._onFulfill(msg.id, result);
- }, reason => {
- self._onReject(msg.id, reason);
- });
- break;
- case "getAccount":
- case "getKeys":
- FxAccountsManager[data.method]().then(
- result => {
- // For the getAccounts case, we only expose the email and
- // verification status so far.
- self._onFulfill(msg.id, result);
- },
- reason => {
- self._onReject(msg.id, reason);
- }
- ).then(null, Components.utils.reportError);
- break;
- case "logout":
- FxAccountsManager.signOut().then(
- () => {
- self._onFulfill(msg.id);
- },
- reason => {
- self._onReject(msg.id, reason);
- }
- ).then(null, Components.utils.reportError);
- break;
- case "queryAccount":
- FxAccountsManager.queryAccount(data.email).then(
- result => {
- self._onFulfill(msg.id, result);
- },
- reason => {
- self._onReject(msg.id, reason);
- }
- ).then(null, Components.utils.reportError);
- break;
- case "resendVerificationEmail":
- FxAccountsManager.resendVerificationEmail().then(
- () => {
- self._onFulfill(msg.id);
- },
- reason => {
- self._onReject(msg.id, reason);
- }
- ).then(null, Components.utils.reportError);
- break;
- case "signIn":
- case "signUp":
- case "refreshAuthentication":
- FxAccountsManager[data.method](data.email, data.password,
- data.fetchKeys).then(
- user => {
- self._onFulfill(msg.id, user);
- },
- reason => {
- self._onReject(msg.id, reason);
- }
- ).then(null, Components.utils.reportError);
- break;
- }
- }
-};
-
-FxAccountsMgmtService.init();
diff --git a/b2g/components/FxAccountsUIGlue.js b/b2g/components/FxAccountsUIGlue.js
deleted file mode 100644
index d62a7d14f..000000000
--- a/b2g/components/FxAccountsUIGlue.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict"
-
-const { interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-Cu.import("resource://gre/modules/ContentRequestHelper.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function FxAccountsUIGlue() {
-}
-
-FxAccountsUIGlue.prototype = {
-
- __proto__: ContentRequestHelper.prototype,
-
- signInFlow: function() {
- return this.contentRequest("mozFxAccountsRPContentEvent",
- "mozFxAccountsUnsolChromeEvent",
- "openFlow");
- },
-
- refreshAuthentication: function(aEmail) {
- return this.contentRequest("mozFxAccountsRPContentEvent",
- "mozFxAccountsUnsolChromeEvent",
- "refreshAuthentication", {
- email: aEmail
- });
- },
-
- classID: Components.ID("{51875c14-91d7-4b8c-b65d-3549e101228c}"),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFxAccountsUIGlue])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FxAccountsUIGlue]);
diff --git a/b2g/components/GaiaChrome.cpp b/b2g/components/GaiaChrome.cpp
deleted file mode 100644
index 2b53750c2..000000000
--- a/b2g/components/GaiaChrome.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "GaiaChrome.h"
-
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsChromeRegistry.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsLocalFile.h"
-#include "nsXULAppAPI.h"
-
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/ModuleUtils.h"
-#include "mozilla/Services.h"
-#include "mozilla/FileLocation.h"
-
-#define NS_GAIACHROME_CID \
- { 0x83f8f999, 0x6b87, 0x4dd8, { 0xa0, 0x93, 0x72, 0x0b, 0xfb, 0x67, 0x4d, 0x38 } }
-
-using namespace mozilla;
-
-StaticRefPtr<GaiaChrome> gGaiaChrome;
-
-NS_IMPL_ISUPPORTS(GaiaChrome, nsIGaiaChrome)
-
-GaiaChrome::GaiaChrome()
- : mPackageName(NS_LITERAL_CSTRING("gaia"))
- , mAppsDir(NS_LITERAL_STRING("apps"))
- , mDataRoot(NS_LITERAL_STRING("/data/local"))
- , mSystemRoot(NS_LITERAL_STRING("/system/b2g"))
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- GetProfileDir();
- Register();
-}
-
-//virtual
-GaiaChrome::~GaiaChrome()
-{
-}
-
-nsresult
-GaiaChrome::GetProfileDir()
-{
- nsCOMPtr<nsIFile> profDir;
- nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
- getter_AddRefs(profDir));
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = profDir->Clone(getter_AddRefs(mProfDir));
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-nsresult
-GaiaChrome::ComputeAppsPath(nsIFile* aPath)
-{
-#if defined(MOZ_MULET)
- aPath->InitWithFile(mProfDir);
-#elif defined(MOZ_WIDGET_GONK)
- nsCOMPtr<nsIFile> locationDetection = new nsLocalFile();
- locationDetection->InitWithPath(mSystemRoot);
- locationDetection->Append(mAppsDir);
- bool appsInSystem = EnsureIsDirectory(locationDetection);
- locationDetection->InitWithPath(mDataRoot);
- locationDetection->Append(mAppsDir);
- bool appsInData = EnsureIsDirectory(locationDetection);
-
- if (!appsInData && !appsInSystem) {
- printf_stderr("!!! NO root directory with apps found\n");
- MOZ_ASSERT(false);
- return NS_ERROR_UNEXPECTED;
- }
-
- aPath->InitWithPath(appsInData ? mDataRoot : mSystemRoot);
-#else
- return NS_ERROR_UNEXPECTED;
-#endif
-
- aPath->Append(mAppsDir);
- aPath->Append(NS_LITERAL_STRING("."));
-
- nsresult rv = EnsureValidPath(aPath);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-bool
-GaiaChrome::EnsureIsDirectory(nsIFile* aPath)
-{
- bool isDir = false;
- aPath->IsDirectory(&isDir);
- return isDir;
-}
-
-nsresult
-GaiaChrome::EnsureValidPath(nsIFile* appsDir)
-{
- // Ensure there is a valid "apps/system" directory
- nsCOMPtr<nsIFile> systemAppDir = new nsLocalFile();
- systemAppDir->InitWithFile(appsDir);
- systemAppDir->Append(NS_LITERAL_STRING("system"));
-
- bool hasSystemAppDir = EnsureIsDirectory(systemAppDir);
- if (!hasSystemAppDir) {
- nsCString path; appsDir->GetNativePath(path);
- // We don't want to continue if the apps path does not exists ...
- printf_stderr("!!! Gaia chrome package is not a directory: %s\n", path.get());
- return NS_ERROR_UNEXPECTED;
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-GaiaChrome::Register()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(nsChromeRegistry::gChromeRegistry != nullptr);
-
- nsCOMPtr<nsIFile> aPath = new nsLocalFile();
- nsresult rv = ComputeAppsPath(aPath);
- NS_ENSURE_SUCCESS(rv, rv);
-
- FileLocation appsLocation(aPath);
- nsCString uri;
- appsLocation.GetURIString(uri);
-
- char* argv[2];
- argv[0] = (char*)mPackageName.get();
- argv[1] = (char*)uri.get();
-
- nsChromeRegistry::ManifestProcessingContext cx(NS_APP_LOCATION, appsLocation);
- nsChromeRegistry::gChromeRegistry->ManifestContent(cx, 0, argv, 0);
-
- return NS_OK;
-}
-
-already_AddRefed<GaiaChrome>
-GaiaChrome::FactoryCreate()
-{
- if (!XRE_IsParentProcess()) {
- return nullptr;
- }
-
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!gGaiaChrome) {
- gGaiaChrome = new GaiaChrome();
- ClearOnShutdown(&gGaiaChrome);
- }
-
- RefPtr<GaiaChrome> service = gGaiaChrome.get();
- return service.forget();
-}
-
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(GaiaChrome,
- GaiaChrome::FactoryCreate)
-
-NS_DEFINE_NAMED_CID(NS_GAIACHROME_CID);
-
-static const mozilla::Module::CIDEntry kGaiaChromeCIDs[] = {
- { &kNS_GAIACHROME_CID, false, nullptr, GaiaChromeConstructor },
- { nullptr }
-};
-
-static const mozilla::Module::ContractIDEntry kGaiaChromeContracts[] = {
- { "@mozilla.org/b2g/gaia-chrome;1", &kNS_GAIACHROME_CID },
- { nullptr }
-};
-
-static const mozilla::Module::CategoryEntry kGaiaChromeCategories[] = {
- { "profile-after-change", "Gaia Chrome Registration", GAIACHROME_CONTRACTID },
- { nullptr }
-};
-
-static const mozilla::Module kGaiaChromeModule = {
- mozilla::Module::kVersion,
- kGaiaChromeCIDs,
- kGaiaChromeContracts,
- kGaiaChromeCategories
-};
-
-NSMODULE_DEFN(GaiaChromeModule) = &kGaiaChromeModule;
diff --git a/b2g/components/GaiaChrome.h b/b2g/components/GaiaChrome.h
deleted file mode 100644
index 290613b81..000000000
--- a/b2g/components/GaiaChrome.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __GAIACHROME_H__
-#define __GAIACHROME_H__
-
-#include "nsIGaiaChrome.h"
-
-#include "nsIFile.h"
-
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-using namespace mozilla;
-
-class GaiaChrome final : public nsIGaiaChrome
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIGAIACHROME
-
- static already_AddRefed<GaiaChrome>
- FactoryCreate();
-
-private:
- nsCString mPackageName;
-
- nsAutoString mAppsDir;
- nsAutoString mDataRoot;
- nsAutoString mSystemRoot;
-
- nsCOMPtr<nsIFile> mProfDir;
-
- GaiaChrome();
- ~GaiaChrome();
-
- nsresult ComputeAppsPath(nsIFile*);
- bool EnsureIsDirectory(nsIFile*);
- nsresult EnsureValidPath(nsIFile*);
- nsresult GetProfileDir();
-};
-
-#endif // __GAIACHROME_H__
diff --git a/b2g/components/GlobalSimulatorScreen.jsm b/b2g/components/GlobalSimulatorScreen.jsm
deleted file mode 100644
index 2895aef96..000000000
--- a/b2g/components/GlobalSimulatorScreen.jsm
+++ /dev/null
@@ -1,90 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-this.EXPORTED_SYMBOLS = [ 'GlobalSimulatorScreen' ];
-
-const Cu = Components.utils;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-
-this.GlobalSimulatorScreen = {
- mozOrientationLocked: false,
-
- // Actual orientation of apps
- mozOrientation: 'portrait',
-
- // The restricted list of actual orientation that can be used
- // if mozOrientationLocked is true
- lockedOrientation: [],
-
- // The faked screen orientation
- // if screenOrientation doesn't match mozOrientation due
- // to lockedOrientation restriction, the app will be displayed
- // on the side on desktop
- screenOrientation: 'portrait',
-
- // Updated by screen.js
- width: 0, height: 0,
-
- lock: function(orientation) {
- this.mozOrientationLocked = true;
-
- // Normalize to portrait or landscape,
- // i.e. the possible values of screenOrientation
- function normalize(str) {
- if (str.match(/^portrait/)) {
- return 'portrait';
- } else if (str.match(/^landscape/)) {
- return 'landscape';
- } else {
- return 'portrait';
- }
- }
- this.lockedOrientation = orientation.map(normalize);
-
- this.updateOrientation();
- },
-
- unlock: function() {
- this.mozOrientationLocked = false;
- this.updateOrientation();
- },
-
- updateOrientation: function () {
- let orientation = this.screenOrientation;
-
- // If the orientation is locked, we have to ensure ending up with a value
- // of lockedOrientation. If none of lockedOrientation values matches
- // the screen orientation we just choose the first locked orientation.
- // This will be the precise scenario where the app is displayed on the
- // side on desktop!
- if (this.mozOrientationLocked &&
- this.lockedOrientation.indexOf(this.screenOrientation) == -1) {
- orientation = this.lockedOrientation[0];
- }
-
- // If the actual orientation changed,
- // we have to fire mozorientation DOM events
- if (this.mozOrientation != orientation) {
- this.mozOrientation = orientation;
-
- // Notify each app screen object to fire the event
- Services.obs.notifyObservers(null, 'simulator-orientation-change', null);
- }
-
- // Finally, in any case, we update the window size and orientation
- // (Use wrappedJSObject trick to be able to pass a raw JS object)
- Services.obs.notifyObservers({wrappedJSObject:this}, 'simulator-adjust-window-size', null);
- },
-
- flipScreen: function() {
- if (this.screenOrientation == 'portrait') {
- this.screenOrientation = 'landscape';
- } else if (this.screenOrientation == 'landscape') {
- this.screenOrientation = 'portrait';
- }
- this.updateOrientation();
- }
-}
diff --git a/b2g/components/HelperAppDialog.js b/b2g/components/HelperAppDialog.js
deleted file mode 100644
index 3709833e1..000000000
--- a/b2g/components/HelperAppDialog.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
- "resource://gre/modules/Downloads.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-
-// -----------------------------------------------------------------------
-// HelperApp Launcher Dialog
-//
-// For now on b2g we never prompt and just download to the default
-// location.
-//
-// -----------------------------------------------------------------------
-
-function HelperAppLauncherDialog() { }
-
-HelperAppLauncherDialog.prototype = {
- classID: Components.ID("{710322af-e6ae-4b0c-b2c9-1474a87b077e}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
-
- show: function(aLauncher, aContext, aReason) {
- aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk;
- aLauncher.saveToDisk(null, false);
- },
-
- promptForSaveToFileAsync: function(aLauncher,
- aContext,
- aDefaultFile,
- aSuggestedFileExt,
- aForcePrompt) {
- // Retrieve the user's default download directory.
- Task.spawn(function*() {
- let file = null;
- try {
- let defaultFolder = yield Downloads.getPreferredDownloadsDirectory();
- let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- dir.initWithPath(defaultFolder);
- file = this.validateLeafName(dir, aDefaultFile, aSuggestedFileExt);
- } catch(e) { }
- aLauncher.saveDestinationAvailable(file);
- }.bind(this)).then(null, Cu.reportError);
- },
-
- validateLeafName: function(aLocalFile, aLeafName, aFileExt) {
- if (!(aLocalFile && this.isUsableDirectory(aLocalFile)))
- return null;
-
- // Remove any leading periods, since we don't want to save hidden files
- // automatically.
- aLeafName = aLeafName.replace(/^\.+/, "");
-
- if (aLeafName == "")
- aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : "");
- aLocalFile.append(aLeafName);
-
- this.makeFileUnique(aLocalFile);
- return aLocalFile;
- },
-
- makeFileUnique: function(aLocalFile) {
- try {
- // Note - this code is identical to that in
- // toolkit/content/contentAreaUtils.js.
- // If you are updating this code, update that code too! We can't share code
- // here since this is called in a js component.
- let collisionCount = 0;
- while (aLocalFile.exists()) {
- collisionCount++;
- if (collisionCount == 1) {
- // Append "(2)" before the last dot in (or at the end of) the filename
- // special case .ext.gz etc files so we don't wind up with .tar(2).gz
- if (aLocalFile.leafName.match(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i))
- aLocalFile.leafName = aLocalFile.leafName.replace(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i, "(2)$&");
- else
- aLocalFile.leafName = aLocalFile.leafName.replace(/(\.[^\.]*)?$/, "(2)$&");
- }
- else {
- // replace the last (n) in the filename with (n+1)
- aLocalFile.leafName = aLocalFile.leafName.replace(/^(.*\()\d+\)/, "$1" + (collisionCount+1) + ")");
- }
- }
- aLocalFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
- }
- catch (e) {
- dump("*** exception in makeFileUnique: " + e + "\n");
-
- if (e.result == Cr.NS_ERROR_FILE_ACCESS_DENIED)
- throw e;
-
- if (aLocalFile.leafName == "" || aLocalFile.isDirectory()) {
- aLocalFile.append("unnamed");
- if (aLocalFile.exists())
- aLocalFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
- }
- }
- },
-
- isUsableDirectory: function(aDirectory) {
- return aDirectory.exists() &&
- aDirectory.isDirectory() &&
- aDirectory.isWritable();
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HelperAppLauncherDialog]);
diff --git a/b2g/components/LogCapture.jsm b/b2g/components/LogCapture.jsm
deleted file mode 100644
index 803028d57..000000000
--- a/b2g/components/LogCapture.jsm
+++ /dev/null
@@ -1,221 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* jshint moz: true */
-/* global Uint8Array, Components, dump */
-
-"use strict";
-
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-
-Cu.importGlobalProperties(['FileReader']);
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Screenshot", "resource://gre/modules/Screenshot.jsm");
-
-this.EXPORTED_SYMBOLS = ["LogCapture"];
-
-const SYSTEM_PROPERTY_KEY_MAX = 32;
-const SYSTEM_PROPERTY_VALUE_MAX = 92;
-
-function debug(msg) {
- dump("LogCapture.jsm: " + msg + "\n");
-}
-
-var LogCapture = {
- ensureLoaded: function() {
- if (!this.ctypes) {
- this.load();
- }
- },
-
- load: function() {
- // load in everything on first use
- Cu.import("resource://gre/modules/ctypes.jsm", this);
-
- this.libc = this.ctypes.open(this.ctypes.libraryName("c"));
-
- this.read = this.libc.declare("read",
- this.ctypes.default_abi,
- this.ctypes.int, // bytes read (out)
- this.ctypes.int, // file descriptor (in)
- this.ctypes.voidptr_t, // buffer to read into (in)
- this.ctypes.size_t // size_t size of buffer (in)
- );
-
- this.open = this.libc.declare("open",
- this.ctypes.default_abi,
- this.ctypes.int, // file descriptor (returned)
- this.ctypes.char.ptr, // path
- this.ctypes.int // flags
- );
-
- this.close = this.libc.declare("close",
- this.ctypes.default_abi,
- this.ctypes.int, // error code (returned)
- this.ctypes.int // file descriptor
- );
-
- this.getpid = this.libc.declare("getpid",
- this.ctypes.default_abi,
- this.ctypes.int // PID
- );
-
- this.property_find_nth =
- this.libc.declare("__system_property_find_nth",
- this.ctypes.default_abi,
- this.ctypes.voidptr_t, // return value: nullable prop_info*
- this.ctypes.unsigned_int); // n: the index of the property to return
-
- this.property_read =
- this.libc.declare("__system_property_read",
- this.ctypes.default_abi,
- this.ctypes.void_t, // return: none
- this.ctypes.voidptr_t, // non-null prop_info*
- this.ctypes.char.ptr, // key
- this.ctypes.char.ptr); // value
-
- this.key_buf = this.ctypes.char.array(SYSTEM_PROPERTY_KEY_MAX)();
- this.value_buf = this.ctypes.char.array(SYSTEM_PROPERTY_VALUE_MAX)();
- },
-
- cleanup: function() {
- this.libc.close();
-
- this.read = null;
- this.open = null;
- this.close = null;
- this.property_find_nth = null;
- this.property_read = null;
- this.key_buf = null;
- this.value_buf = null;
-
- this.libc = null;
- this.ctypes = null;
- },
-
- /**
- * readLogFile
- * Read in /dev/log/{{log}} in nonblocking mode, which will return -1 if
- * reading would block the thread.
- *
- * @param log {String} The log from which to read. Must be present in /dev/log
- * @return {Uint8Array} Raw log data
- */
- readLogFile: function(logLocation) {
- this.ensureLoaded();
-
- const O_READONLY = 0;
- const O_NONBLOCK = 1 << 11;
-
- const BUF_SIZE = 2048;
-
- let BufType = this.ctypes.ArrayType(this.ctypes.char);
- let buf = new BufType(BUF_SIZE);
- let logArray = [];
-
- let logFd = this.open(logLocation, O_READONLY | O_NONBLOCK);
- if (logFd === -1) {
- return null;
- }
-
- let readStart = Date.now();
- let readCount = 0;
- while (true) {
- let count = this.read(logFd, buf, BUF_SIZE);
- readCount += 1;
-
- if (count <= 0) {
- // log has return due to being nonblocking or running out of things
- break;
- }
- for(let i = 0; i < count; i++) {
- logArray.push(buf[i]);
- }
- }
-
- let logTypedArray = new Uint8Array(logArray);
-
- this.close(logFd);
-
- return logTypedArray;
- },
-
- /**
- * Get all system properties as a dict with keys mapping to values
- */
- readProperties: function() {
- this.ensureLoaded();
- let n = 0;
- let propertyDict = {};
-
- while(true) {
- let prop_info = this.property_find_nth(n);
- if(prop_info.isNull()) {
- break;
- }
-
- // read the prop_info into the key and value buffers
- this.property_read(prop_info, this.key_buf, this.value_buf);
- let key = this.key_buf.readString();;
- let value = this.value_buf.readString()
-
- propertyDict[key] = value;
- n++;
- }
-
- return propertyDict;
- },
-
- /**
- * Dumping about:memory to a file in /data/local/tmp/, returning a Promise.
- * Will be resolved with the dumped file name.
- */
- readAboutMemory: function() {
- this.ensureLoaded();
- let deferred = Promise.defer();
-
- // Perform the dump
- let dumper = Cc["@mozilla.org/memory-info-dumper;1"]
- .getService(Ci.nsIMemoryInfoDumper);
-
- let file = "/data/local/tmp/logshake-about_memory-" + this.getpid() + ".json.gz";
- dumper.dumpMemoryReportsToNamedFile(file, function() {
- deferred.resolve(file);
- }, null, false);
-
- return deferred.promise;
- },
-
- /**
- * Dumping screenshot, returning a Promise. Will be resolved with the content
- * as an ArrayBuffer.
- */
- getScreenshot: function() {
- let deferred = Promise.defer();
- try {
- this.ensureLoaded();
-
- let fr = new FileReader();
- fr.onload = function(evt) {
- deferred.resolve(new Uint8Array(evt.target.result));
- };
-
- fr.onerror = function(evt) {
- deferred.reject(evt);
- };
-
- fr.readAsArrayBuffer(Screenshot.get());
- } catch(e) {
- // We pass any errors through to the deferred Promise
- deferred.reject(e);
- }
-
- return deferred.promise;
- }
-};
-
-this.LogCapture = LogCapture;
diff --git a/b2g/components/LogParser.jsm b/b2g/components/LogParser.jsm
deleted file mode 100644
index c40db9767..000000000
--- a/b2g/components/LogParser.jsm
+++ /dev/null
@@ -1,257 +0,0 @@
-/* jshint esnext: true */
-/* global DataView */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["LogParser"];
-
-/**
- * Parse an array read from a /dev/log/ file. Format taken from
- * kernel/drivers/staging/android/logger.h and system/core/logcat/logcat.cpp
- *
- * @param array {Uint8Array} Array read from /dev/log/ file
- * @return {Array} List of log messages
- */
-function parseLogArray(array) {
- let data = new DataView(array.buffer);
- let byteString = String.fromCharCode.apply(null, array);
-
- // Length of bytes that precede the payload of a log message
- // From the 5 Uint32 and 1 Uint8 reads
- const HEADER_LENGTH = 21;
-
- let logMessages = [];
- let pos = 0;
-
- while (pos + HEADER_LENGTH < byteString.length) {
- // Parse a single log entry
-
- // Track current offset from global position
- let offset = 0;
-
- // Length of the entry, discarded
- let length = data.getUint32(pos + offset, true);
- offset += 4;
- // Id of the process which generated the message
- let processId = data.getUint32(pos + offset, true);
- offset += 4;
- // Id of the thread which generated the message
- let threadId = data.getUint32(pos + offset, true);
- offset += 4;
- // Seconds since epoch when this message was logged
- let seconds = data.getUint32(pos + offset, true);
- offset += 4;
- // Nanoseconds since the last second
- let nanoseconds = data.getUint32(pos + offset, true);
- offset += 4;
-
- // Priority in terms of the ANDROID_LOG_* constants (see below)
- // This is where the length field begins counting
- let priority = data.getUint8(pos + offset);
-
- // Reset pos and offset to count from here
- pos += offset;
- offset = 0;
- offset += 1;
-
- // Read the tag and message, represented as null-terminated c-style strings
- let tag = "";
- while (byteString[pos + offset] != "\0") {
- tag += byteString[pos + offset];
- offset ++;
- }
- offset ++;
-
- let message = "";
- // The kernel log driver may have cut off the null byte (logprint.c)
- while (byteString[pos + offset] != "\0" && offset < length) {
- message += byteString[pos + offset];
- offset ++;
- }
-
- // Un-skip the missing null terminator
- if (offset === length) {
- offset --;
- }
-
- offset ++;
-
- pos += offset;
-
- // Log messages are occasionally delimited by newlines, but are also
- // sometimes followed by newlines as well
- if (message.charAt(message.length - 1) === "\n") {
- message = message.substring(0, message.length - 1);
- }
-
- // Add an aditional time property to mimic the milliseconds since UTC
- // expected by Date
- let time = seconds * 1000.0 + nanoseconds/1000000.0;
-
- // Log messages with interleaved newlines are considered to be separate log
- // messages by logcat
- for (let lineMessage of message.split("\n")) {
- logMessages.push({
- processId: processId,
- threadId: threadId,
- seconds: seconds,
- nanoseconds: nanoseconds,
- time: time,
- priority: priority,
- tag: tag,
- message: lineMessage + "\n"
- });
- }
- }
-
- return logMessages;
-}
-
-/**
- * Get a thread-time style formatted string from time
- * @param time {Number} Milliseconds since epoch
- * @return {String} Formatted time string
- */
-function getTimeString(time) {
- let date = new Date(time);
- function pad(number) {
- if ( number < 10 ) {
- return "0" + number;
- }
- return number;
- }
- return pad( date.getMonth() + 1 ) +
- "-" + pad( date.getDate() ) +
- " " + pad( date.getHours() ) +
- ":" + pad( date.getMinutes() ) +
- ":" + pad( date.getSeconds() ) +
- "." + (date.getMilliseconds() / 1000).toFixed(3).slice(2, 5);
-}
-
-/**
- * Pad a string using spaces on the left
- * @param str {String} String to pad
- * @param width {Number} Desired string length
- */
-function padLeft(str, width) {
- while (str.length < width) {
- str = " " + str;
- }
- return str;
-}
-
-/**
- * Pad a string using spaces on the right
- * @param str {String} String to pad
- * @param width {Number} Desired string length
- */
-function padRight(str, width) {
- while (str.length < width) {
- str = str + " ";
- }
- return str;
-}
-
-/** Constant values taken from system/core/liblog */
-const ANDROID_LOG_UNKNOWN = 0;
-const ANDROID_LOG_DEFAULT = 1;
-const ANDROID_LOG_VERBOSE = 2;
-const ANDROID_LOG_DEBUG = 3;
-const ANDROID_LOG_INFO = 4;
-const ANDROID_LOG_WARN = 5;
-const ANDROID_LOG_ERROR = 6;
-const ANDROID_LOG_FATAL = 7;
-const ANDROID_LOG_SILENT = 8;
-
-/**
- * Map a priority number to its abbreviated string equivalent
- * @param priorityNumber {Number} Log-provided priority number
- * @return {String} Priority number's abbreviation
- */
-function getPriorityString(priorityNumber) {
- switch (priorityNumber) {
- case ANDROID_LOG_VERBOSE:
- return "V";
- case ANDROID_LOG_DEBUG:
- return "D";
- case ANDROID_LOG_INFO:
- return "I";
- case ANDROID_LOG_WARN:
- return "W";
- case ANDROID_LOG_ERROR:
- return "E";
- case ANDROID_LOG_FATAL:
- return "F";
- case ANDROID_LOG_SILENT:
- return "S";
- default:
- return "?";
- }
-}
-
-
-/**
- * Mimic the logcat "threadtime" format, generating a formatted string from a
- * log message object.
- * @param logMessage {Object} A log message from the list returned by parseLogArray
- * @return {String} threadtime formatted summary of the message
- */
-function formatLogMessage(logMessage) {
- // MM-DD HH:MM:SS.ms pid tid priority tag: message
- // from system/core/liblog/logprint.c:
- return getTimeString(logMessage.time) +
- " " + padLeft(""+logMessage.processId, 5) +
- " " + padLeft(""+logMessage.threadId, 5) +
- " " + getPriorityString(logMessage.priority) +
- " " + padRight(logMessage.tag, 8) +
- ": " + logMessage.message;
-}
-
-/**
- * Convert a string to a utf-8 Uint8Array
- * @param {String} str
- * @return {Uint8Array}
- */
-function textEncode(str) {
- return new TextEncoder("utf-8").encode(str);
-}
-
-/**
- * Pretty-print an array of bytes read from a log file by parsing then
- * threadtime formatting its entries.
- * @param array {Uint8Array} Array of a log file's bytes
- * @return {Uint8Array} Pretty-printed log
- */
-function prettyPrintLogArray(array) {
- let logMessages = parseLogArray(array);
- return textEncode(logMessages.map(formatLogMessage).join(""));
-}
-
-/**
- * Pretty-print an array read from the list of propreties.
- * @param {Object} Object representing the properties
- * @return {Uint8Array} Human-readable string of property name: property value
- */
-function prettyPrintPropertiesArray(properties) {
- let propertiesString = "";
- for(let propName in properties) {
- propertiesString += "[" + propName + "]: [" + properties[propName] + "]\n";
- }
- return textEncode(propertiesString);
-}
-
-/**
- * Pretty-print a normal array. Does nothing.
- * @param array {Uint8Array} Input array
- * @return {Uint8Array} The same array
- */
-function prettyPrintArray(array) {
- return array;
-}
-
-this.LogParser = {
- parseLogArray: parseLogArray,
- prettyPrintArray: prettyPrintArray,
- prettyPrintLogArray: prettyPrintLogArray,
- prettyPrintPropertiesArray: prettyPrintPropertiesArray
-};
diff --git a/b2g/components/LogShake.jsm b/b2g/components/LogShake.jsm
deleted file mode 100644
index 6426c21de..000000000
--- a/b2g/components/LogShake.jsm
+++ /dev/null
@@ -1,588 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * LogShake is a module which listens for log requests sent by Gaia. In
- * response to a sufficiently large acceleration (a shake), it will save log
- * files to an arbitrary directory which it will then return on a
- * 'capture-logs-success' event with detail.logFilenames representing each log
- * file's name and detail.logPaths representing the patch to each log file or
- * the path to the archive.
- * If an error occurs it will instead produce a 'capture-logs-error' event.
- * We send a capture-logs-start events to notify the system app and the user,
- * since dumping can be a bit long sometimes.
- */
-
-/* enable Mozilla javascript extensions and global strictness declaration,
- * disable valid this checking */
-/* jshint moz: true, esnext: true */
-/* jshint -W097 */
-/* jshint -W040 */
-/* global Services, Components, dump, LogCapture, LogParser,
- OS, Promise, volumeService, XPCOMUtils, SystemAppProxy */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-// Constants for creating zip file taken from toolkit/webapps/tests/head.js
-const PR_RDWR = 0x04;
-const PR_CREATE_FILE = 0x08;
-const PR_TRUNCATE = 0x20;
-
-XPCOMUtils.defineLazyModuleGetter(this, "LogCapture", "resource://gre/modules/LogCapture.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "LogParser", "resource://gre/modules/LogParser.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService",
- "@mozilla.org/power/powermanagerservice;1",
- "nsIPowerManagerService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
- "@mozilla.org/telephony/volume-service;1",
- "nsIVolumeService");
-
-this.EXPORTED_SYMBOLS = ["LogShake"];
-
-function debug(msg) {
- dump("LogShake.jsm: "+msg+"\n");
-}
-
-/**
- * An empirically determined amount of acceleration corresponding to a
- * shake.
- */
-const EXCITEMENT_THRESHOLD = 500;
-/**
- * The maximum fraction to update the excitement value per frame. This
- * corresponds to requiring shaking for approximately 10 motion events (1.6
- * seconds)
- */
-const EXCITEMENT_FILTER_ALPHA = 0.2;
-const DEVICE_MOTION_EVENT = "devicemotion";
-const SCREEN_CHANGE_EVENT = "screenchange";
-const CAPTURE_LOGS_CONTENT_EVENT = "requestSystemLogs";
-const CAPTURE_LOGS_START_EVENT = "capture-logs-start";
-const CAPTURE_LOGS_ERROR_EVENT = "capture-logs-error";
-const CAPTURE_LOGS_SUCCESS_EVENT = "capture-logs-success";
-
-var LogShake = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
-
- /**
- * If LogShake is in QA Mode, which bundles all files into a compressed archive
- */
- qaModeEnabled: false,
-
- /**
- * If LogShake is listening for device motion events. Required due to lag
- * between HAL layer of device motion events and listening for device motion
- * events.
- */
- deviceMotionEnabled: false,
-
- /**
- * We only listen to motion events when the screen is enabled, keep track
- * of its state.
- */
- screenEnabled: true,
-
- /**
- * Flag monitoring if the preference to enable shake to capture is
- * enabled in gaia.
- */
- listenToDeviceMotion: true,
-
- /**
- * If a capture has been requested and is waiting for reads/parsing. Used for
- * debouncing.
- */
- captureRequested: false,
-
- /**
- * The current excitement (movement) level
- */
- excitement: 0,
-
- /**
- * Map of files which have log-type information to their parsers
- */
- LOGS_WITH_PARSERS: {
- "/dev/log/main": LogParser.prettyPrintLogArray,
- "/dev/log/system": LogParser.prettyPrintLogArray,
- "/dev/log/radio": LogParser.prettyPrintLogArray,
- "/dev/log/events": LogParser.prettyPrintLogArray,
- "/proc/cmdline": LogParser.prettyPrintArray,
- "/proc/kmsg": LogParser.prettyPrintArray,
- "/proc/last_kmsg": LogParser.prettyPrintArray,
- "/proc/meminfo": LogParser.prettyPrintArray,
- "/proc/uptime": LogParser.prettyPrintArray,
- "/proc/version": LogParser.prettyPrintArray,
- "/proc/vmallocinfo": LogParser.prettyPrintArray,
- "/proc/vmstat": LogParser.prettyPrintArray,
- "/system/b2g/application.ini": LogParser.prettyPrintArray,
- "/cache/recovery/last_install": LogParser.prettyPrintArray,
- "/cache/recovery/last_kmsg": LogParser.prettyPrintArray,
- "/cache/recovery/last_log": LogParser.prettyPrintArray
- },
-
- /**
- * Start existing, observing motion events if the screen is turned on.
- */
- init: function() {
- // TODO: no way of querying screen state from power manager
- // this.handleScreenChangeEvent({ detail: {
- // screenEnabled: powerManagerService.screenEnabled
- // }});
-
- // However, the screen is always on when we are being enabled because it is
- // either due to the phone starting up or a user enabling us directly.
- this.handleScreenChangeEvent({ detail: {
- screenEnabled: true
- }});
-
- // Reset excitement to clear residual motion
- this.excitement = 0;
-
- SystemAppProxy.addEventListener(CAPTURE_LOGS_CONTENT_EVENT, this, false);
- SystemAppProxy.addEventListener(SCREEN_CHANGE_EVENT, this, false);
-
- Services.obs.addObserver(this, "xpcom-shutdown", false);
- },
-
- /**
- * Handle an arbitrary event, passing it along to the proper function
- */
- handleEvent: function(event) {
- switch (event.type) {
- case DEVICE_MOTION_EVENT:
- if (!this.deviceMotionEnabled) {
- return;
- }
- this.handleDeviceMotionEvent(event);
- break;
-
- case SCREEN_CHANGE_EVENT:
- this.handleScreenChangeEvent(event);
- break;
-
- case CAPTURE_LOGS_CONTENT_EVENT:
- this.startCapture();
- break;
- }
- },
-
- /**
- * Handle an observation from Services.obs
- */
- observe: function(subject, topic) {
- if (topic === "xpcom-shutdown") {
- this.uninit();
- }
- },
-
- enableQAMode: function() {
- debug("Enabling QA Mode");
- this.qaModeEnabled = true;
- },
-
- disableQAMode: function() {
- debug("Disabling QA Mode");
- this.qaModeEnabled = false;
- },
-
- enableDeviceMotionListener: function() {
- this.listenToDeviceMotion = true;
- this.startDeviceMotionListener();
- },
-
- disableDeviceMotionListener: function() {
- this.listenToDeviceMotion = false;
- this.stopDeviceMotionListener();
- },
-
- startDeviceMotionListener: function() {
- if (!this.deviceMotionEnabled &&
- this.listenToDeviceMotion &&
- this.screenEnabled) {
- SystemAppProxy.addEventListener(DEVICE_MOTION_EVENT, this, false);
- this.deviceMotionEnabled = true;
- }
- },
-
- stopDeviceMotionListener: function() {
- SystemAppProxy.removeEventListener(DEVICE_MOTION_EVENT, this, false);
- this.deviceMotionEnabled = false;
- },
-
- /**
- * Handle a motion event, keeping track of "excitement", the magnitude
- * of the device"s acceleration.
- */
- handleDeviceMotionEvent: function(event) {
- // There is a lag between disabling the event listener and event arrival
- // ceasing.
- if (!this.deviceMotionEnabled) {
- return;
- }
-
- let acc = event.accelerationIncludingGravity;
-
- // Updates excitement by a factor of at most alpha, ignoring sudden device
- // motion. See bug #1101994 for more information.
- let newExcitement = acc.x * acc.x + acc.y * acc.y + acc.z * acc.z;
- this.excitement += (newExcitement - this.excitement) * EXCITEMENT_FILTER_ALPHA;
-
- if (this.excitement > EXCITEMENT_THRESHOLD) {
- this.startCapture();
- }
- },
-
- startCapture: function() {
- if (this.captureRequested) {
- return;
- }
- this.captureRequested = true;
- SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_START_EVENT, {});
- this.captureLogs().then(logResults => {
- // On resolution send the success event to the requester
- SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_SUCCESS_EVENT, {
- logPaths: logResults.logPaths,
- logFilenames: logResults.logFilenames
- });
- this.captureRequested = false;
- }, error => {
- // On an error send the error event
- SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_ERROR_EVENT, {error: error});
- this.captureRequested = false;
- });
- },
-
- handleScreenChangeEvent: function(event) {
- this.screenEnabled = event.detail.screenEnabled;
- if (this.screenEnabled) {
- this.startDeviceMotionListener();
- } else {
- this.stopDeviceMotionListener();
- }
- },
-
- /**
- * Captures and saves the current device logs, returning a promise that will
- * resolve to an array of log filenames.
- */
- captureLogs: function() {
- return this.readLogs().then(logArrays => {
- return this.saveLogs(logArrays);
- });
- },
-
- /**
- * Read in all log files, returning their formatted contents
- * @return {Promise<Array>}
- */
- readLogs: function() {
- let logArrays = {};
- let readPromises = [];
-
- try {
- logArrays["properties"] =
- LogParser.prettyPrintPropertiesArray(LogCapture.readProperties());
- } catch (ex) {
- Cu.reportError("Unable to get device properties: " + ex);
- }
-
- // Let Gecko perfom the dump to a file, and just collect it
- let readAboutMemoryPromise = new Promise(resolve => {
- // Wrap the readAboutMemory promise to make it infallible
- LogCapture.readAboutMemory().then(aboutMemory => {
- let file = OS.Path.basename(aboutMemory);
- let logArray;
- try {
- logArray = LogCapture.readLogFile(aboutMemory);
- if (!logArray) {
- debug("LogCapture.readLogFile() returned nothing for about:memory");
- }
- // We need to remove the dumped file, now that we have it in memory
- OS.File.remove(aboutMemory);
- } catch (ex) {
- Cu.reportError("Unable to handle about:memory dump: " + ex);
- }
- logArrays[file] = LogParser.prettyPrintArray(logArray);
- resolve();
- }, ex => {
- Cu.reportError("Unable to get about:memory dump: " + ex);
- resolve();
- });
- });
- readPromises.push(readAboutMemoryPromise);
-
- // Wrap the promise to make it infallible
- let readScreenshotPromise = new Promise(resolve => {
- LogCapture.getScreenshot().then(screenshot => {
- logArrays["screenshot.png"] = screenshot;
- resolve();
- }, ex => {
- Cu.reportError("Unable to get screenshot dump: " + ex);
- resolve();
- });
- });
- readPromises.push(readScreenshotPromise);
-
- for (let loc in this.LOGS_WITH_PARSERS) {
- let logArray;
- try {
- logArray = LogCapture.readLogFile(loc);
- if (!logArray) {
- debug("LogCapture.readLogFile() returned nothing for: " + loc);
- continue;
- }
- } catch (ex) {
- Cu.reportError("Unable to LogCapture.readLogFile('" + loc + "'): " + ex);
- continue;
- }
-
- try {
- logArrays[loc] = this.LOGS_WITH_PARSERS[loc](logArray);
- } catch (ex) {
- Cu.reportError("Unable to parse content of '" + loc + "': " + ex);
- continue;
- }
- }
-
- // Because the promises we depend upon can't fail this means that the
- // blocking log reads will always be honored.
- return Promise.all(readPromises).then(() => {
- return logArrays;
- });
- },
-
- /**
- * Save the formatted arrays of log files to an sdcard if available
- */
- saveLogs: function(logArrays) {
- if (!logArrays || Object.keys(logArrays).length === 0) {
- return Promise.reject("Zero logs saved");
- }
-
- if (this.qaModeEnabled) {
- return makeBaseLogsDirectory().then(writeLogArchive(logArrays),
- rejectFunction("Error making base log directory"));
- } else {
- return makeBaseLogsDirectory().then(makeLogsDirectory,
- rejectFunction("Error making base log directory"))
- .then(writeLogFiles(logArrays),
- rejectFunction("Error creating log directory"));
- }
- },
-
- /**
- * Stop logshake, removing all listeners
- */
- uninit: function() {
- this.stopDeviceMotionListener();
- SystemAppProxy.removeEventListener(SCREEN_CHANGE_EVENT, this, false);
- Services.obs.removeObserver(this, "xpcom-shutdown");
- }
-};
-
-function getLogFilename(logLocation) {
- // sanitize the log location
- let logName = logLocation.replace(/\//g, "-");
- if (logName[0] === "-") {
- logName = logName.substring(1);
- }
-
- // If no extension is provided, default to forcing .log
- let extension = ".log";
- let logLocationExt = logLocation.split(".");
- if (logLocationExt.length > 1) {
- // otherwise, just append nothing
- extension = "";
- }
-
- return logName + extension;
-}
-
-function getSdcardPrefix() {
- return volumeService.getVolumeByName("sdcard").mountPoint;
-}
-
-function getLogDirectoryRoot() {
- return "logs";
-}
-
-function getLogIdentifier() {
- let d = new Date();
- d = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
- let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, "-");
- return timestamp;
-}
-
-function rejectFunction(message) {
- return function(err) {
- debug(message + ": " + err);
- return Promise.reject(err);
- };
-}
-
-function makeBaseLogsDirectory() {
- let sdcardPrefix;
- try {
- sdcardPrefix = getSdcardPrefix();
- } catch(e) {
- // Handles missing sdcard
- return Promise.reject(e);
- }
-
- let dirNameRoot = getLogDirectoryRoot();
-
- let logsRoot = OS.Path.join(sdcardPrefix, dirNameRoot);
-
- debug("Creating base log directory at root " + sdcardPrefix);
-
- return OS.File.makeDir(logsRoot, {from: sdcardPrefix}).then(
- function() {
- return {
- sdcardPrefix: sdcardPrefix,
- basePrefix: dirNameRoot
- };
- }
- );
-}
-
-function makeLogsDirectory({sdcardPrefix, basePrefix}) {
- let dirName = getLogIdentifier();
-
- let logsRoot = OS.Path.join(sdcardPrefix, basePrefix);
- let logsDir = OS.Path.join(logsRoot, dirName);
-
- debug("Creating base log directory at root " + sdcardPrefix);
- debug("Final created directory will be " + logsDir);
-
- return OS.File.makeDir(logsDir, {ignoreExisting: false}).then(
- function() {
- debug("Created: " + logsDir);
- return {
- logPrefix: OS.Path.join(basePrefix, dirName),
- sdcardPrefix: sdcardPrefix
- };
- },
- rejectFunction("Error at OS.File.makeDir for " + logsDir)
- );
-}
-
-function getFile(filename) {
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- file.initWithPath(filename);
- return file;
-}
-
-/**
- * Make a zip file
- * @param {String} absoluteZipFilename - Fully qualified desired location of the zip file
- * @param {Map<String, Uint8Array>} logArrays - Map from log location to log data
- * @return {Array<String>} Paths of entries in the archive
- */
-function makeZipFile(absoluteZipFilename, logArrays) {
- let logFilenames = [];
- let zipWriter = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
- let zipFile = getFile(absoluteZipFilename);
- zipWriter.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
-
- for (let logLocation in logArrays) {
- let logArray = logArrays[logLocation];
- let logFilename = getLogFilename(logLocation);
- logFilenames.push(logFilename);
-
- debug("Adding " + logFilename + " to the zip");
- let logArrayStream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"]
- .createInstance(Ci.nsIArrayBufferInputStream);
- // Set data to be copied, default offset to 0 because it is not present on
- // ArrayBuffer objects
- logArrayStream.setData(logArray.buffer, logArray.byteOffset || 0,
- logArray.byteLength);
-
- zipWriter.addEntryStream(logFilename, Date.now(),
- Ci.nsIZipWriter.COMPRESSION_DEFAULT,
- logArrayStream, false);
- }
- zipWriter.close();
-
- return logFilenames;
-}
-
-function writeLogArchive(logArrays) {
- return function({sdcardPrefix, basePrefix}) {
- // Now the directory is guaranteed to exist, save the logs into their
- // archive file
-
- let zipFilename = getLogIdentifier() + "-logs.zip";
- let zipPath = OS.Path.join(basePrefix, zipFilename);
- let zipPrefix = OS.Path.dirname(zipPath);
- let absoluteZipPath = OS.Path.join(sdcardPrefix, zipPath);
-
- debug("Creating zip file at " + zipPath);
- let logFilenames = [];
- try {
- logFilenames = makeZipFile(absoluteZipPath, logArrays);
- } catch(e) {
- return Promise.reject(e);
- }
- debug("Zip file created");
-
- return {
- logFilenames: logFilenames,
- logPaths: [zipPath],
- compressed: true
- };
- };
-}
-
-function writeLogFiles(logArrays) {
- return function({sdcardPrefix, logPrefix}) {
- // Now the directory is guaranteed to exist, save the logs
- let logFilenames = [];
- let logPaths = [];
- let saveRequests = [];
-
- for (let logLocation in logArrays) {
- debug("Requesting save of " + logLocation);
- let logArray = logArrays[logLocation];
- let logFilename = getLogFilename(logLocation);
- // The local pathrepresents the relative path within the SD card, not the
- // absolute path because Gaia will refer to it using the DeviceStorage
- // API
- let localPath = OS.Path.join(logPrefix, logFilename);
-
- logFilenames.push(logFilename);
- logPaths.push(localPath);
-
- let absolutePath = OS.Path.join(sdcardPrefix, localPath);
- let saveRequest = OS.File.writeAtomic(absolutePath, logArray);
- saveRequests.push(saveRequest);
- }
-
- return Promise.all(saveRequests).then(
- function() {
- return {
- logFilenames: logFilenames,
- logPaths: logPaths,
- compressed: false
- };
- },
- rejectFunction("Error at some save request")
- );
- };
-}
-
-LogShake.init();
-this.LogShake = LogShake;
diff --git a/b2g/components/MailtoProtocolHandler.js b/b2g/components/MailtoProtocolHandler.js
deleted file mode 100644
index 500fb9112..000000000
--- a/b2g/components/MailtoProtocolHandler.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/ActivityChannel.jsm');
-
-function MailtoProtocolHandler() {
-}
-
-MailtoProtocolHandler.prototype = {
-
- scheme: "mailto",
- defaultPort: -1,
- protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
- Ci.nsIProtocolHandler.URI_NOAUTH |
- Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
- Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA,
- allowPort: () => false,
-
- newURI: function Proto_newURI(aSpec, aOriginCharset) {
- let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
- uri.spec = aSpec;
- return uri;
- },
-
- newChannel2: function Proto_newChannel2(aURI, aLoadInfo) {
- return new ActivityChannel(aURI, aLoadInfo,
- "mail-handler",
- { URI: aURI.spec,
- type: "mail" });
- },
-
- newChannel: function Proto_newChannel(aURI) {
- return this.newChannel2(aURI, null);
- },
-
- classID: Components.ID("{50777e53-0331-4366-a191-900999be386c}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MailtoProtocolHandler]);
diff --git a/b2g/components/OMAContentHandler.js b/b2g/components/OMAContentHandler.js
deleted file mode 100644
index 56c87a3b2..000000000
--- a/b2g/components/OMAContentHandler.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
- return Cc["@mozilla.org/childprocessmessagemanager;1"]
- .getService(Ci.nsIMessageSender);
-});
-
-function debug(aMsg) {
- //dump("--*-- OMAContentHandler: " + aMsg + "\n");
-}
-
-const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
-
-function OMAContentHandler() {
-}
-
-OMAContentHandler.prototype = {
- classID: Components.ID("{a6b2ab13-9037-423a-9897-dde1081be323}"),
-
- _xpcom_factory: {
- createInstance: function createInstance(outer, iid) {
- if (outer != null) {
- throw Cr.NS_ERROR_NO_AGGREGATION;
- }
- return new OMAContentHandler().QueryInterface(iid);
- }
- },
-
- handleContent: function handleContent(aMimetype, aContext, aRequest) {
- if (!(aRequest instanceof Ci.nsIChannel)) {
- throw NS_ERROR_WONT_HANDLE_CONTENT;
- }
-
- let detail = {
- "type": aMimetype,
- "url": aRequest.URI.spec
- };
- cpmm.sendAsyncMessage("content-handler", detail);
-
- aRequest.cancel(Cr.NS_BINDING_ABORTED);
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler])
-}
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([OMAContentHandler]);
diff --git a/b2g/components/OopCommandLine.js b/b2g/components/OopCommandLine.js
deleted file mode 100644
index 658bbdde5..000000000
--- a/b2g/components/OopCommandLine.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
-
-function oopCommandlineHandler() {
-}
-
-oopCommandlineHandler.prototype = {
- handle: function(cmdLine) {
- let oopFlag = cmdLine.handleFlag("oop", false);
- if (oopFlag) {
- /**
- * Manipulate preferences by adding to the *default* branch. Adding
- * to the default branch means the changes we make won"t get written
- * back to user preferences.
- */
- let prefs = Services.prefs
- let branch = prefs.getDefaultBranch("");
-
- try {
- // Turn on all OOP services, making desktop run similar to phone
- // environment
- branch.setBoolPref("dom.ipc.tabs.disabled", false);
- branch.setBoolPref("layers.acceleration.disabled", false);
- branch.setBoolPref("layers.offmainthreadcomposition.async-animations", true);
- branch.setBoolPref("layers.async-video.enabled", true);
- branch.setBoolPref("layers.async-pan-zoom.enabled", true);
- branch.setCharPref("gfx.content.azure.backends", "cairo");
- } catch (e) { }
-
- }
- if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
- cmdLine.preventDefault = true;
- }
- },
-
- helpInfo: " --oop Use out-of-process model in B2G\n",
- classID: Components.ID("{e30b0e13-2d12-4cb0-bc4c-4e617a1bf76e}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([oopCommandlineHandler]);
diff --git a/b2g/components/OrientationChangeHandler.jsm b/b2g/components/OrientationChangeHandler.jsm
deleted file mode 100644
index 5007b70e0..000000000
--- a/b2g/components/OrientationChangeHandler.jsm
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = [];
-
-const Cu = Components.utils;
-Cu.import("resource://gre/modules/Services.jsm");
-
-var window = Services.wm.getMostRecentWindow("navigator:browser");
-var system = window.document.getElementById("systemapp");
-
-var OrientationChangeHandler = {
- // Clockwise orientations, looping
- orientations: ["portrait-primary", "landscape-secondary",
- "portrait-secondary", "landscape-primary",
- "portrait-primary"],
-
- lastOrientation: "portrait-primary",
-
- init: function() {
- window.screen.addEventListener("mozorientationchange", this, true);
- },
-
- handleEvent: function(evt) {
- let newOrientation = window.screen.mozOrientation;
- let orientationIndex = this.orientations.indexOf(this.lastOrientation);
- let nextClockwiseOrientation = this.orientations[orientationIndex + 1];
- let fullSwitch = (newOrientation.split("-")[0] ==
- this.lastOrientation.split("-")[0]);
-
- this.lastOrientation = newOrientation;
-
- let angle, xFactor, yFactor;
- if (fullSwitch) {
- angle = 180;
- xFactor = 1;
- } else {
- angle = (nextClockwiseOrientation == newOrientation) ? 90 : -90;
- xFactor = window.innerWidth / window.innerHeight;
- }
- yFactor = 1 / xFactor;
-
- system.style.transition = "";
- system.style.transform = "rotate(" + angle + "deg)" +
- "scale(" + xFactor + ", " + yFactor + ")";
-
- function trigger() {
- system.style.transition = "transform .25s cubic-bezier(.15, .7, .6, .9)";
-
- system.style.opacity = "";
- system.style.transform = "";
- }
-
- // 180deg rotation, no resize
- if (fullSwitch) {
- window.setTimeout(trigger);
- return;
- }
-
- window.addEventListener("resize", function waitForResize(e) {
- window.removeEventListener("resize", waitForResize);
- trigger();
- });
- }
-};
-
-OrientationChangeHandler.init();
diff --git a/b2g/components/PresentationRequestUIGlue.js b/b2g/components/PresentationRequestUIGlue.js
deleted file mode 100644
index 5c50401de..000000000
--- a/b2g/components/PresentationRequestUIGlue.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict"
-
-function debug(aMsg) {
- // dump("-*- PresentationRequestUIGlue: " + aMsg + "\n");
-}
-
-const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-function PresentationRequestUIGlue() { }
-
-PresentationRequestUIGlue.prototype = {
-
- sendRequest: function(aUrl, aSessionId, aDevice) {
- let localDevice;
- try {
- localDevice = aDevice.QueryInterface(Ci.nsIPresentationLocalDevice);
- } catch (e) {}
-
- if (localDevice) {
- return this.sendTo1UA(aUrl, aSessionId, localDevice.windowId);
- } else {
- return this.sendTo2UA(aUrl, aSessionId);
- }
- },
-
- // For 1-UA scenario
- sendTo1UA: function(aUrl, aSessionId, aWindowId) {
- return new Promise((aResolve, aReject) => {
- let handler = (evt) => {
- if (evt.type === "unload") {
- SystemAppProxy.removeEventListenerWithId(aWindowId,
- "unload",
- handler);
- SystemAppProxy.removeEventListenerWithId(aWindowId,
- "mozPresentationContentEvent",
- handler);
- aReject();
- }
- if (evt.type === "mozPresentationContentEvent" &&
- evt.detail.id == aSessionId) {
- SystemAppProxy.removeEventListenerWithId(aWindowId,
- "unload",
- handler);
- SystemAppProxy.removeEventListenerWithId(aWindowId,
- "mozPresentationContentEvent",
- handler);
- this.appLaunchCallback(evt.detail, aResolve, aReject);
- }
- };
- // If system(-remote) app is closed.
- SystemAppProxy.addEventListenerWithId(aWindowId,
- "unload",
- handler);
- // Listen to the result for the opened iframe from front-end.
- SystemAppProxy.addEventListenerWithId(aWindowId,
- "mozPresentationContentEvent",
- handler);
- SystemAppProxy.sendCustomEventWithId(aWindowId,
- "mozPresentationChromeEvent",
- { type: "presentation-launch-receiver",
- url: aUrl,
- id: aSessionId });
- });
- },
-
- // For 2-UA scenario
- sendTo2UA: function(aUrl, aSessionId) {
- return new Promise((aResolve, aReject) => {
- let handler = (evt) => {
- if (evt.type === "mozPresentationContentEvent" &&
- evt.detail.id == aSessionId) {
- SystemAppProxy.removeEventListener("mozPresentationContentEvent",
- handler);
- this.appLaunchCallback(evt.detail, aResolve, aReject);
- }
- };
-
- // Listen to the result for the opened iframe from front-end.
- SystemAppProxy.addEventListener("mozPresentationContentEvent",
- handler);
- SystemAppProxy._sendCustomEvent("mozPresentationChromeEvent",
- { type: "presentation-launch-receiver",
- url: aUrl,
- id: aSessionId });
- });
- },
-
- appLaunchCallback: function(aDetail, aResolve, aReject) {
- switch(aDetail.type) {
- case "presentation-receiver-launched":
- aResolve(aDetail.frame);
- break;
- case "presentation-receiver-permission-denied":
- aReject();
- break;
- }
- },
-
- classID: Components.ID("{ccc8a839-0b64-422b-8a60-fb2af0e376d0}"),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationRequestUIGlue]);
diff --git a/b2g/components/ProcessGlobal.js b/b2g/components/ProcessGlobal.js
deleted file mode 100644
index 94326ad50..000000000
--- a/b2g/components/ProcessGlobal.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-/**
- * This code exists to be a "grab bag" of global code that needs to be
- * loaded per B2G process, but doesn't need to directly interact with
- * web content.
- *
- * (It's written as an XPCOM service because it needs to watch
- * app-startup.)
- */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-XPCOMUtils.defineLazyServiceGetter(this, "settings",
- "@mozilla.org/settingsService;1",
- "nsISettingsService");
-
-function debug(msg) {
- log(msg);
-}
-function log(msg) {
- // This file implements console.log(), so use dump().
- //dump('ProcessGlobal: ' + msg + '\n');
-}
-
-function formatStackFrame(aFrame) {
- let functionName = aFrame.functionName || '<anonymous>';
- return ' at ' + functionName +
- ' (' + aFrame.filename + ':' + aFrame.lineNumber +
- ':' + aFrame.columnNumber + ')';
-}
-
-function ConsoleMessage(aMsg, aLevel) {
- this.timeStamp = Date.now();
- this.msg = aMsg;
-
- switch (aLevel) {
- case 'error':
- case 'assert':
- this.logLevel = Ci.nsIConsoleMessage.error;
- break;
- case 'warn':
- this.logLevel = Ci.nsIConsoleMessage.warn;
- break;
- case 'log':
- case 'info':
- this.logLevel = Ci.nsIConsoleMessage.info;
- break;
- default:
- this.logLevel = Ci.nsIConsoleMessage.debug;
- break;
- }
-}
-
-function toggleUnrestrictedDevtools(unrestricted) {
- Services.prefs.setBoolPref("devtools.debugger.forbid-certified-apps",
- !unrestricted);
- Services.prefs.setBoolPref("dom.apps.developer_mode", unrestricted);
- // TODO: Remove once bug 1125916 is fixed.
- Services.prefs.setBoolPref("network.disable.ipc.security", unrestricted);
- Services.prefs.setBoolPref("dom.webcomponents.enabled", unrestricted);
- let lock = settings.createLock();
- lock.set("developer.menu.enabled", unrestricted, null);
- lock.set("devtools.unrestricted", unrestricted, null);
-}
-
-ConsoleMessage.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleMessage]),
- toString: function() { return this.msg; }
-};
-
-const gFactoryResetFile = "__post_reset_cmd__";
-
-function ProcessGlobal() {}
-ProcessGlobal.prototype = {
- classID: Components.ID('{1a94c87a-5ece-4d11-91e1-d29c29f21b28}'),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
- Ci.nsISupportsWeakReference]),
-
- wipeDir: function(path) {
- log("wipeDir " + path);
- let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- dir.initWithPath(path);
- if (!dir.exists() || !dir.isDirectory()) {
- return;
- }
- let entries = dir.directoryEntries;
- while (entries.hasMoreElements()) {
- let file = entries.getNext().QueryInterface(Ci.nsIFile);
- log("Deleting " + file.path);
- try {
- file.remove(true);
- } catch(e) {}
- }
- },
-
- processCommandsFile: function(text) {
- log("processCommandsFile " + text);
- let lines = text.split("\n");
- lines.forEach((line) => {
- log(line);
- let params = line.split(" ");
- switch (params[0]) {
- case "root":
- log("unrestrict devtools");
- toggleUnrestrictedDevtools(true);
- break;
- case "wipe":
- this.wipeDir(params[1]);
- case "normal":
- log("restrict devtools");
- toggleUnrestrictedDevtools(false);
- break;
- }
- });
- },
-
- cleanupAfterFactoryReset: function() {
- log("cleanupAfterWipe start");
-
- Cu.import("resource://gre/modules/osfile.jsm");
- let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- dir.initWithPath("/persist");
- var postResetFile = dir.exists() ?
- OS.Path.join("/persist", gFactoryResetFile):
- OS.Path.join("/cache", gFactoryResetFile);
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- file.initWithPath(postResetFile);
- if (!file.exists()) {
- debug("No additional command.")
- return;
- }
-
- let promise = OS.File.read(postResetFile);
- promise.then(
- (array) => {
- file.remove(false);
- let decoder = new TextDecoder();
- this.processCommandsFile(decoder.decode(array));
- },
- function onError(error) {
- debug("Error: " + error);
- }
- );
-
- log("cleanupAfterWipe end.");
- },
-
- observe: function pg_observe(subject, topic, data) {
- switch (topic) {
- case 'app-startup': {
- Services.obs.addObserver(this, 'console-api-log-event', false);
- let inParent = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULRuntime)
- .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
- if (inParent) {
- Services.ppmm.addMessageListener("getProfD", function(message) {
- return Services.dirsvc.get("ProfD", Ci.nsIFile).path;
- });
-
- this.cleanupAfterFactoryReset();
- }
- break;
- }
- case 'console-api-log-event': {
- // Pipe `console` log messages to the nsIConsoleService which
- // writes them to logcat on Gonk.
- let message = subject.wrappedJSObject;
- let args = message.arguments;
- let stackTrace = '';
-
- if (message.stacktrace &&
- (message.level == 'assert' || message.level == 'error' || message.level == 'trace')) {
- stackTrace = Array.map(message.stacktrace, formatStackFrame).join('\n');
- } else {
- stackTrace = formatStackFrame(message);
- }
-
- if (stackTrace) {
- args.push('\n' + stackTrace);
- }
-
- let msg = 'Content JS ' + message.level.toUpperCase() + ': ' + Array.join(args, ' ');
- Services.console.logMessage(new ConsoleMessage(msg, message.level));
- break;
- }
- }
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProcessGlobal]);
diff --git a/b2g/components/RecoveryService.js b/b2g/components/RecoveryService.js
deleted file mode 100644
index 493763e6d..000000000
--- a/b2g/components/RecoveryService.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/ctypes.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const RECOVERYSERVICE_CID = Components.ID("{b3caca5d-0bb0-48c6-912b-6be6cbf08832}");
-const RECOVERYSERVICE_CONTRACTID = "@mozilla.org/recovery-service;1";
-
-function log(msg) {
- dump("-*- RecoveryService: " + msg + "\n");
-}
-
-const isGonk = AppConstants.platform === 'gonk';
-
-if (isGonk) {
- var librecovery = (function() {
- let library;
- try {
- library = ctypes.open("librecovery.so");
- } catch (e) {
- log("Unable to open librecovery.so");
- throw Cr.NS_ERROR_FAILURE;
- }
- // Bug 1163956, modify updatePath from ctyps.char.ptr to ctype.char.array(4096)
- // align with librecovery.h. 4096 comes from PATH_MAX
- let FotaUpdateStatus = new ctypes.StructType("FotaUpdateStatus", [
- { result: ctypes.int },
- { updatePath: ctypes.char.array(4096) }
- ]);
-
- return {
- factoryReset: library.declare("factoryReset",
- ctypes.default_abi,
- ctypes.int),
- installFotaUpdate: library.declare("installFotaUpdate",
- ctypes.default_abi,
- ctypes.int,
- ctypes.char.ptr,
- ctypes.int),
-
- FotaUpdateStatus: FotaUpdateStatus,
- getFotaUpdateStatus: library.declare("getFotaUpdateStatus",
- ctypes.default_abi,
- ctypes.int,
- FotaUpdateStatus.ptr)
- };
- })();
-
-}
-
-const gFactoryResetFile = "__post_reset_cmd__";
-
-function RecoveryService() {}
-
-RecoveryService.prototype = {
- classID: RECOVERYSERVICE_CID,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIRecoveryService]),
- classInfo: XPCOMUtils.generateCI({
- classID: RECOVERYSERVICE_CID,
- contractID: RECOVERYSERVICE_CONTRACTID,
- interfaces: [Ci.nsIRecoveryService],
- classDescription: "B2G Recovery Service"
- }),
-
- factoryReset: function RS_factoryReset(reason) {
- if (!isGonk) {
- Cr.NS_ERROR_FAILURE;
- }
-
- function doReset() {
- // If this succeeds, then the device reboots and this never returns
- if (librecovery.factoryReset() != 0) {
- log("Error: Factory reset failed. Trying again after clearing cache.");
- }
- let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- cache.clear();
- if (librecovery.factoryReset() != 0) {
- log("Error: Factory reset failed again");
- }
- }
-
- log("factoryReset " + reason);
- let commands = [];
- if (reason == "wipe") {
- let volumeService = Cc["@mozilla.org/telephony/volume-service;1"]
- .getService(Ci.nsIVolumeService);
- let volNames = volumeService.getVolumeNames();
- log("Found " + volNames.length + " volumes");
-
- for (let i = 0; i < volNames.length; i++) {
- let name = volNames.queryElementAt(i, Ci.nsISupportsString);
- let volume = volumeService.getVolumeByName(name.data);
- log("Got volume: " + name.data + " at " + volume.mountPoint);
- commands.push("wipe " + volume.mountPoint);
- }
- } else if (reason == "root") {
- commands.push("root");
- }
-
- if (commands.length > 0) {
- Cu.import("resource://gre/modules/osfile.jsm");
- let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- dir.initWithPath("/persist");
- var postResetFile = dir.exists() ?
- OS.Path.join("/persist", gFactoryResetFile):
- OS.Path.join("/cache", gFactoryResetFile);
- let encoder = new TextEncoder();
- let text = commands.join("\n");
- let array = encoder.encode(text);
- let promise = OS.File.writeAtomic(postResetFile, array,
- { tmpPath: postResetFile + ".tmp" });
-
- promise.then(doReset, function onError(error) {
- log("Error: " + error);
- });
- } else {
- doReset();
- }
- },
-
- installFotaUpdate: function RS_installFotaUpdate(updatePath) {
- if (!isGonk) {
- throw Cr.NS_ERROR_FAILURE;
- }
-
- // If this succeeds, then the device reboots and this never returns
- if (librecovery.installFotaUpdate(updatePath, updatePath.length) != 0) {
- log("Error: FOTA install failed. Trying again after clearing cache.");
- }
- var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
- cache.clear();
- if (librecovery.installFotaUpdate(updatePath, updatePath.length) != 0) {
- log("Error: FOTA install failed again");
- }
- },
-
- getFotaUpdateStatus: function RS_getFotaUpdateStatus() {
- let status = Ci.nsIRecoveryService.FOTA_UPDATE_UNKNOWN;
-
- if (isGonk) {
- let cStatus = librecovery.FotaUpdateStatus();
-
- if (librecovery.getFotaUpdateStatus(cStatus.address()) == 0) {
- status = cStatus.result;
- }
- }
- return status;
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RecoveryService]);
diff --git a/b2g/components/SafeMode.jsm b/b2g/components/SafeMode.jsm
deleted file mode 100644
index 9f9342f67..000000000
--- a/b2g/components/SafeMode.jsm
+++ /dev/null
@@ -1,150 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["SafeMode"];
-
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const kSafeModePref = "b2g.safe_mode";
-const kSafeModePage = "safe_mode.html";
-
-function debug(aStr) {
- //dump("-*- SafeMode: " + aStr + "\n");
-}
-
-// This module is responsible for checking whether we want to start in safe
-// mode or not. The flow is as follow:
-// - wait for the `b2g.safe_mode` preference to be set to something different
-// than `unset` by nsAppShell
-// - If it's set to `no`, just start normally.
-// - If it's set to `yes`, we load a stripped down system app from safe_mode.html"
-// - This page is responsible to dispatch a mozContentEvent to us.
-// - If the user choose SafeMode, we disable all add-ons.
-// - We go on with startup.
-
-this.SafeMode = {
- // Returns a promise that resolves when nsAppShell has set the
- // b2g.safe_mode_state_ready preference to `true`.
- _waitForPref: function() {
- debug("waitForPref");
- try {
- let currentMode = Services.prefs.getCharPref(kSafeModePref);
- debug("current mode: " + currentMode);
- if (currentMode !== "unset") {
- return Promise.resolve();
- }
- } catch(e) { debug("No current mode available!"); }
-
- // Wait for the preference to toggle.
- return new Promise((aResolve, aReject) => {
- let observer = function(aSubject, aTopic, aData) {
- if (Services.prefs.getCharPref(kSafeModePref)) {
- Services.prefs.removeObserver(kSafeModePref, observer, false);
- aResolve();
- }
- }
-
- Services.prefs.addObserver(kSafeModePref, observer, false);
- });
- },
-
- // Resolves once the user has decided how to start.
- // Note that all the actions happen here, so there is no other action from
- // consumers than to go on.
- _waitForUser: function() {
- debug("waitForUser");
- let isSafeMode = Services.prefs.getCharPref(kSafeModePref) === "yes";
- if (!isSafeMode) {
- return Promise.resolve();
- }
- debug("Starting in Safe Mode!");
-
- // Load $system_app/safe_mode.html as a full screen iframe, and wait for
- // the user to make a choice.
- let shell = SafeMode.window.shell;
- let document = SafeMode.window.document;
- SafeMode.window.screen.mozLockOrientation("portrait");
-
- let url = Services.io.newURI(shell.homeURL, null, null)
- .resolve(kSafeModePage);
- debug("Registry is ready, loading " + url);
- let frame = document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
- frame.setAttribute("mozbrowser", "true");
- frame.setAttribute("mozapp", shell.manifestURL);
- frame.setAttribute("id", "systemapp"); // To keep screen.js happy.
- let contentBrowser = document.body.appendChild(frame);
-
- return new Promise((aResolve, aReject) => {
- let content = contentBrowser.contentWindow;
-
- // Stripped down version of the system app bootstrap.
- function handleEvent(e) {
- switch(e.type) {
- case "mozbrowserloadstart":
- if (content.document.location == "about:blank") {
- contentBrowser.addEventListener("mozbrowserlocationchange", handleEvent, true);
- contentBrowser.removeEventListener("mozbrowserloadstart", handleEvent, true);
- return;
- }
-
- notifyContentStart();
- break;
- case "mozbrowserlocationchange":
- if (content.document.location == "about:blank") {
- return;
- }
-
- contentBrowser.removeEventListener("mozbrowserlocationchange", handleEvent, true);
- notifyContentStart();
- break;
- case "mozContentEvent":
- content.removeEventListener("mozContentEvent", handleEvent, true);
- contentBrowser.parentNode.removeChild(contentBrowser);
-
- if (e.detail == "safemode-yes") {
- // Really starting in safe mode, let's disable add-ons first.
- // TODO: disable add-ons
- aResolve();
- } else {
- aResolve();
- }
- break;
- }
- }
-
- function notifyContentStart() {
- let window = SafeMode.window;
- window.shell.sendEvent(window, "SafeModeStart");
- contentBrowser.setVisible(true);
-
- // browser-ui-startup-complete is used by the AppShell to stop the
- // boot animation and start gecko rendering.
- Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
- content.addEventListener("mozContentEvent", handleEvent, true);
- }
-
- contentBrowser.addEventListener("mozbrowserloadstart", handleEvent, true);
- contentBrowser.src = url;
- });
- },
-
- // Returns a Promise that resolves once we have decided to run in safe mode
- // or not. All the safe mode switching actions happen before resolving the
- // promise.
- check: function(aWindow) {
- debug("check");
- this.window = aWindow;
- if (AppConstants.platform !== "gonk") {
- // For now we only have gonk support.
- return Promise.resolve();
- }
-
- return this._waitForPref().then(this._waitForUser);
- }
-}
diff --git a/b2g/components/Screenshot.jsm b/b2g/components/Screenshot.jsm
deleted file mode 100644
index e6f809375..000000000
--- a/b2g/components/Screenshot.jsm
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm");
-
-this.EXPORTED_SYMBOLS = ['Screenshot'];
-
-var Screenshot = {
- get: function screenshot_get() {
- let systemAppFrame = SystemAppProxy.getFrame();
- let window = systemAppFrame.ownerDocument.defaultView;
- let document = window.document;
-
- var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
- var docRect = document.body.getBoundingClientRect();
- var width = docRect.width;
- var height = docRect.height;
-
- // Convert width and height from CSS pixels (potentially fractional)
- // to device pixels (integer).
- var scale = window.devicePixelRatio;
- canvas.setAttribute('width', Math.round(width * scale));
- canvas.setAttribute('height', Math.round(height * scale));
-
- var context = canvas.getContext('2d');
- var flags =
- context.DRAWWINDOW_DRAW_CARET |
- context.DRAWWINDOW_DRAW_VIEW |
- context.DRAWWINDOW_USE_WIDGET_LAYERS;
- context.scale(scale, scale);
- context.drawWindow(window, 0, 0, width, height, 'rgb(255,255,255)', flags);
-
- return canvas.mozGetAsFile('screenshot', 'image/png');
- }
-};
-this.Screenshot = Screenshot;
diff --git a/b2g/components/SignInToWebsite.jsm b/b2g/components/SignInToWebsite.jsm
deleted file mode 100644
index fd1349d46..000000000
--- a/b2g/components/SignInToWebsite.jsm
+++ /dev/null
@@ -1,444 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * SignInToWebsite.jsm - UX Controller and means for accessing identity
- * cookies on behalf of relying parties.
- *
- * Currently, the b2g security architecture isolates web applications
- * so that each window has access only to a local cookie jar:
- *
- * To prevent Web apps from interfering with one another, each one is
- * hosted on a separate domain, and therefore may only access the
- * resources associated with its domain. These resources include
- * things such as IndexedDB databases, cookies, offline storage,
- * and so forth.
- *
- * -- https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Security/Security_model
- *
- * As a result, an authentication system like Persona cannot share its
- * cookie jar with multiple relying parties, and so would require a
- * fresh login request in every window. This would not be a good
- * experience.
- *
- *
- * In order for navigator.id.request() to maintain state in a single
- * cookie jar, we cause all Persona interactions to take place in a
- * content context that is launched by the system application, with the
- * result that Persona has a single cookie jar that all Relying
- * Parties can use. Since of course those Relying Parties cannot
- * reach into the system cookie jar, the Controller in this module
- * provides a way to get messages and data to and fro between the
- * Relying Party in its window context, and the Persona internal api
- * in its context.
- *
- * On the Relying Party's side, say a web page invokes
- * navigator.id.watch(), to register callbacks, and then
- * navigator.id.request() to request an assertion. The navigator.id
- * calls are provided by nsDOMIdentity. nsDOMIdentity messages down
- * to the privileged DOMIdentity code (using cpmm and ppmm message
- * managers). DOMIdentity stores the state of Relying Party flows
- * using an Identity service (MinimalIdentity.jsm), and emits messages
- * requesting Persona functions (doWatch, doReady, doLogout).
- *
- * The Identity service sends these observer messages to the
- * Controller in this module, which in turn triggers content to open a
- * window to host the Persona js. If user interaction is required,
- * content will open the trusty UI. If user interaction is not required,
- * and we only need to get to Persona functions, content will open a
- * hidden iframe. In either case, a window is opened into which the
- * controller causes the script identity.js to be injected. This
- * script provides the glue between the in-page javascript and the
- * pipe back down to the Controller, translating navigator.internal
- * function callbacks into messages sent back to the Controller.
- *
- * As a result, a navigator.internal function in the hosted popup or
- * iframe can call back to the injected identity.js (doReady, doLogin,
- * or doLogout). identity.js callbacks send messages back through the
- * pipe to the Controller. The controller invokes the corresponding
- * function on the Identity Service (doReady, doLogin, or doLogout).
- * The IdentityService calls the corresponding callback for the
- * correct Relying Party, which causes DOMIdentity to send a message
- * up to the Relying Party through nsDOMIdentity
- * (Identity:RP:Watch:OnLogin etc.), and finally, nsDOMIdentity
- * receives these messages and calls the original callback that the
- * Relying Party registered (navigator.id.watch(),
- * navigator.id.request(), or navigator.id.logout()).
- */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["SignInToWebsiteController"];
-
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "getRandomId",
- "resource://gre/modules/identity/IdentityUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "IdentityService",
- "resource://gre/modules/identity/MinimalIdentity.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Logger",
- "resource://gre/modules/identity/LogUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-// The default persona uri; can be overwritten with toolkit.identity.uri pref.
-// Do this if you want to repoint to a different service for testing.
-// There's no point in setting up an observer to monitor the pref, as b2g prefs
-// can only be overwritten when the profie is recreated. So just get the value
-// on start-up.
-var kPersonaUri = "https://firefoxos.persona.org";
-try {
- kPersonaUri = Services.prefs.getCharPref("toolkit.identity.uri");
-} catch(noSuchPref) {
- // stick with the default value
-}
-
-// JS shim that contains the callback functions that
-// live within the identity UI provisioning frame.
-const kIdentityShimFile = "chrome://b2g/content/identity.js";
-
-// Type of MozChromeEvents to handle id dialogs.
-const kOpenIdentityDialog = "id-dialog-open";
-const kDoneIdentityDialog = "id-dialog-done";
-const kCloseIdentityDialog = "id-dialog-close-iframe";
-
-// Observer messages to communicate to shim
-const kIdentityDelegateWatch = "identity-delegate-watch";
-const kIdentityDelegateRequest = "identity-delegate-request";
-const kIdentityDelegateLogout = "identity-delegate-logout";
-const kIdentityDelegateFinished = "identity-delegate-finished";
-const kIdentityDelegateReady = "identity-delegate-ready";
-
-const kIdentityControllerDoMethod = "identity-controller-doMethod";
-
-function log(...aMessageArgs) {
- Logger.log.apply(Logger, ["SignInToWebsiteController"].concat(aMessageArgs));
-}
-
-log("persona uri =", kPersonaUri);
-
-function sendChromeEvent(details) {
- details.uri = kPersonaUri;
- SystemAppProxy.dispatchEvent(details);
-}
-
-function Pipe() {
- this._watchers = [];
-}
-
-Pipe.prototype = {
- init: function pipe_init() {
- Services.obs.addObserver(this, "identity-child-process-shutdown", false);
- Services.obs.addObserver(this, "identity-controller-unwatch", false);
- },
-
- uninit: function pipe_uninit() {
- Services.obs.removeObserver(this, "identity-child-process-shutdown");
- Services.obs.removeObserver(this, "identity-controller-unwatch");
- },
-
- observe: function Pipe_observe(aSubject, aTopic, aData) {
- let options = {};
- if (aSubject) {
- options = aSubject.wrappedJSObject;
- }
- switch (aTopic) {
- case "identity-child-process-shutdown":
- log("pipe removing watchers by message manager");
- this._removeWatchers(null, options.messageManager);
- break;
-
- case "identity-controller-unwatch":
- log("unwatching", options.id);
- this._removeWatchers(options.id, options.messageManager);
- break;
- }
- },
-
- _addWatcher: function Pipe__addWatcher(aId, aMm) {
- log("Adding watcher with id", aId);
- for (let i = 0; i < this._watchers.length; ++i) {
- let watcher = this._watchers[i];
- if (this._watcher.id === aId) {
- watcher.count++;
- return;
- }
- }
- this._watchers.push({id: aId, count: 1, mm: aMm});
- },
-
- _removeWatchers: function Pipe__removeWatcher(aId, aMm) {
- let checkId = aId !== null;
- let index = -1;
- for (let i = 0; i < this._watchers.length; ++i) {
- let watcher = this._watchers[i];
- if (watcher.mm === aMm &&
- (!checkId || (checkId && watcher.id === aId))) {
- index = i;
- break;
- }
- }
-
- if (index !== -1) {
- if (checkId) {
- if (--(this._watchers[index].count) === 0) {
- this._watchers.splice(index, 1);
- }
- } else {
- this._watchers.splice(index, 1);
- }
- }
-
- if (this._watchers.length === 0) {
- log("No more watchers; clean up persona host iframe");
- let detail = {
- type: kCloseIdentityDialog
- };
- log('telling content to close the dialog');
- // tell content to close the dialog
- sendChromeEvent(detail);
- }
- },
-
- communicate: function(aRpOptions, aContentOptions, aMessageCallback) {
- let rpID = aRpOptions.id;
- let rpMM = aRpOptions.mm;
- if (rpMM) {
- this._addWatcher(rpID, rpMM);
- }
-
- log("RP options:", aRpOptions, "\n content options:", aContentOptions);
-
- // This content variable is injected into the scope of
- // kIdentityShimFile, where it is used to access the BrowserID object
- // and its internal API.
- let mm = null;
- let uuid = getRandomId();
- let self = this;
-
- function removeMessageListeners() {
- if (mm) {
- mm.removeMessageListener(kIdentityDelegateFinished, identityDelegateFinished);
- mm.removeMessageListener(kIdentityControllerDoMethod, aMessageCallback);
- }
- }
-
- function identityDelegateFinished() {
- removeMessageListeners();
-
- let detail = {
- type: kDoneIdentityDialog,
- showUI: aContentOptions.showUI || false,
- id: kDoneIdentityDialog + "-" + uuid,
- requestId: aRpOptions.id
- };
- log('received delegate finished; telling content to close the dialog');
- sendChromeEvent(detail);
- self._removeWatchers(rpID, rpMM);
- }
-
- SystemAppProxy.addEventListener("mozContentEvent", function getAssertion(evt) {
- let msg = evt.detail;
- if (!msg.id.match(uuid)) {
- return;
- }
-
- switch (msg.id) {
- case kOpenIdentityDialog + '-' + uuid:
- if (msg.type === 'cancel') {
- // The user closed the dialog. Clean up and call cancel.
- SystemAppProxy.removeEventListener("mozContentEvent", getAssertion);
- removeMessageListeners();
- aMessageCallback({json: {method: "cancel"}});
- } else {
- // The window has opened. Inject the identity shim file containing
- // the callbacks in the content script. This could be either the
- // visible popup that the user interacts with, or it could be an
- // invisible frame.
- let frame = evt.detail.frame;
- let frameLoader = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
- mm = frameLoader.messageManager;
- try {
- mm.loadFrameScript(kIdentityShimFile, true, true);
- log("Loaded shim", kIdentityShimFile);
- } catch (e) {
- log("Error loading", kIdentityShimFile, "as a frame script:", e);
- }
-
- // There are two messages that the delegate can send back: a "do
- // method" event, and a "finished" event. We pass the do-method
- // events straight to the caller for interpretation and handling.
- // If we receive a "finished" event, then the delegate is done, so
- // we shut down the pipe and clean up.
- mm.addMessageListener(kIdentityControllerDoMethod, aMessageCallback);
- mm.addMessageListener(kIdentityDelegateFinished, identityDelegateFinished);
-
- mm.sendAsyncMessage(aContentOptions.message, aRpOptions);
- }
- break;
-
- case kDoneIdentityDialog + '-' + uuid:
- // Received our assertion. The message manager callbacks will handle
- // communicating back to the IDService. All we have to do is remove
- // this listener.
- SystemAppProxy.removeEventListener("mozContentEvent", getAssertion);
- break;
-
- default:
- log("ERROR - Unexpected message: id=" + msg.id + ", type=" + msg.type + ", errorMsg=" + msg.errorMsg);
- break;
- }
-
- });
-
- // Tell content to open the identity iframe or trusty popup. The parameter
- // showUI signals whether user interaction is needed. If it is, content will
- // open a dialog; if not, a hidden iframe. In each case, BrowserID is
- // available in the context.
- let detail = {
- type: kOpenIdentityDialog,
- showUI: aContentOptions.showUI || false,
- id: kOpenIdentityDialog + "-" + uuid,
- requestId: aRpOptions.id
- };
-
- sendChromeEvent(detail);
- }
-
-};
-
-/*
- * The controller sits between the IdentityService used by DOMIdentity
- * and a content process launches an (invisible) iframe or (visible)
- * trusty UI. Using an injected js script (identity.js), the
- * controller enables the content window to access the persona identity
- * storage in the system cookie jar and send events back via the
- * controller into IdentityService and DOM, and ultimately up to the
- * Relying Party, which is open in a different window context.
- */
-this.SignInToWebsiteController = {
-
- /*
- * Initialize the controller. To use a different content communication pipe,
- * such as when mocking it in tests, pass aOptions.pipe.
- */
- init: function SignInToWebsiteController_init(aOptions) {
- aOptions = aOptions || {};
- this.pipe = aOptions.pipe || new Pipe();
- Services.obs.addObserver(this, "identity-controller-watch", false);
- Services.obs.addObserver(this, "identity-controller-request", false);
- Services.obs.addObserver(this, "identity-controller-logout", false);
- },
-
- uninit: function SignInToWebsiteController_uninit() {
- Services.obs.removeObserver(this, "identity-controller-watch");
- Services.obs.removeObserver(this, "identity-controller-request");
- Services.obs.removeObserver(this, "identity-controller-logout");
- },
-
- observe: function SignInToWebsiteController_observe(aSubject, aTopic, aData) {
- log("observe: received", aTopic, "with", aData, "for", aSubject);
- let options = null;
- if (aSubject) {
- options = aSubject.wrappedJSObject;
- }
- switch (aTopic) {
- case "identity-controller-watch":
- this.doWatch(options);
- break;
- case "identity-controller-request":
- this.doRequest(options);
- break;
- case "identity-controller-logout":
- this.doLogout(options);
- break;
- default:
- Logger.reportError("SignInToWebsiteController", "Unknown observer notification:", aTopic);
- break;
- }
- },
-
- /*
- * options: method required - name of method to invoke
- * assertion optional
- */
- _makeDoMethodCallback: function SignInToWebsiteController__makeDoMethodCallback(aRpId) {
- return function SignInToWebsiteController_methodCallback(aOptions) {
- let message = aOptions.json;
- if (typeof message === 'string') {
- message = JSON.parse(message);
- }
-
- switch (message.method) {
- case "ready":
- IdentityService.doReady(aRpId);
- break;
-
- case "login":
- if (message._internalParams) {
- IdentityService.doLogin(aRpId, message.assertion, message._internalParams);
- } else {
- IdentityService.doLogin(aRpId, message.assertion);
- }
- break;
-
- case "logout":
- IdentityService.doLogout(aRpId);
- break;
-
- case "cancel":
- IdentityService.doCancel(aRpId);
- break;
-
- default:
- log("WARNING: wonky method call:", message.method);
- break;
- }
- };
- },
-
- doWatch: function SignInToWebsiteController_doWatch(aRpOptions) {
- // dom prevents watch from being called twice
- let contentOptions = {
- message: kIdentityDelegateWatch,
- showUI: false
- };
- this.pipe.communicate(aRpOptions, contentOptions,
- this._makeDoMethodCallback(aRpOptions.id));
- },
-
- /**
- * The website is requesting login so the user must choose an identity to use.
- */
- doRequest: function SignInToWebsiteController_doRequest(aRpOptions) {
- log("doRequest", aRpOptions);
- let contentOptions = {
- message: kIdentityDelegateRequest,
- showUI: true
- };
- this.pipe.communicate(aRpOptions, contentOptions,
- this._makeDoMethodCallback(aRpOptions.id));
- },
-
- /*
- *
- */
- doLogout: function SignInToWebsiteController_doLogout(aRpOptions) {
- log("doLogout", aRpOptions);
- let contentOptions = {
- message: kIdentityDelegateLogout,
- showUI: false
- };
- this.pipe.communicate(aRpOptions, contentOptions,
- this._makeDoMethodCallback(aRpOptions.id));
- }
-
-};
diff --git a/b2g/components/SimulatorScreen.js b/b2g/components/SimulatorScreen.js
deleted file mode 100644
index 18d8f5cc4..000000000
--- a/b2g/components/SimulatorScreen.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/DOMRequestHelper.jsm');
-
-XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen',
- 'resource://gre/modules/GlobalSimulatorScreen.jsm');
-
-var DEBUG_PREFIX = 'SimulatorScreen.js - ';
-function debug() {
- //dump(DEBUG_PREFIX + Array.slice(arguments) + '\n');
-}
-
-function fireOrientationEvent(window) {
- let e = new window.Event('mozorientationchange');
- window.screen.dispatchEvent(e);
-}
-
-function hookScreen(window) {
- let nodePrincipal = window.document.nodePrincipal;
- let origin = nodePrincipal.origin;
- if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
- // Only inject screen mock for apps
- return;
- }
-
- let screen = window.wrappedJSObject.screen;
-
- screen.mozLockOrientation = function (orientation) {
- debug('mozLockOrientation:', orientation, 'from', origin);
-
- // Normalize and do some checks against orientation input
- if (typeof(orientation) == 'string') {
- orientation = [orientation];
- }
-
- function isInvalidOrientationString(str) {
- return typeof(str) != 'string' ||
- !str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/);
- }
- if (!Array.isArray(orientation) ||
- orientation.some(isInvalidOrientationString)) {
- Cu.reportError('Invalid orientation "' + orientation + '"');
- return false;
- }
-
- GlobalSimulatorScreen.lock(orientation);
-
- return true;
- };
-
- screen.mozUnlockOrientation = function() {
- debug('mozOrientationUnlock from', origin);
- GlobalSimulatorScreen.unlock();
- return true;
- };
-
- Object.defineProperty(screen, 'width', {
- get: () => GlobalSimulatorScreen.width
- });
- Object.defineProperty(screen, 'height', {
- get: () => GlobalSimulatorScreen.height
- });
- Object.defineProperty(screen, 'mozOrientation', {
- get: () => GlobalSimulatorScreen.mozOrientation
- });
-}
-
-function SimulatorScreen() {}
-SimulatorScreen.prototype = {
- classID: Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
- Ci.nsISupportsWeakReference]),
- _windows: new Map(),
-
- observe: function (subject, topic, data) {
- let windows = this._windows;
- switch (topic) {
- case 'profile-after-change':
- Services.obs.addObserver(this, 'document-element-inserted', false);
- Services.obs.addObserver(this, 'simulator-orientation-change', false);
- Services.obs.addObserver(this, 'inner-window-destroyed', false);
- break;
-
- case 'document-element-inserted':
- let window = subject.defaultView;
- if (!window) {
- return;
- }
-
- hookScreen(window);
-
- var id = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .currentInnerWindowID;
- windows.set(id, window);
- break;
-
- case 'inner-window-destroyed':
- var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
- windows.delete(id);
- break;
-
- case 'simulator-orientation-change':
- windows.forEach(fireOrientationEvent);
- break;
- }
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]);
diff --git a/b2g/components/SmsProtocolHandler.js b/b2g/components/SmsProtocolHandler.js
deleted file mode 100644
index c54018fcf..000000000
--- a/b2g/components/SmsProtocolHandler.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * SmsProtocolHandle.js
- *
- * This file implements the URLs for SMS
- * https://www.rfc-editor.org/rfc/rfc5724.txt
- */
-
-"use strict";
-
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import("resource:///modules/TelURIParser.jsm");
-Cu.import('resource://gre/modules/ActivityChannel.jsm');
-
-function SmsProtocolHandler() {
-}
-
-SmsProtocolHandler.prototype = {
-
- scheme: "sms",
- defaultPort: -1,
- protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
- Ci.nsIProtocolHandler.URI_NOAUTH |
- Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
- Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA,
- allowPort: () => false,
-
- newURI: function Proto_newURI(aSpec, aOriginCharset) {
- let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
- uri.spec = aSpec;
- return uri;
- },
-
- newChannel2: function Proto_newChannel2(aURI, aLoadInfo) {
- let number = TelURIParser.parseURI('sms', aURI.spec);
- let body = "";
- let query = aURI.spec.split("?")[1];
-
- if (query) {
- let params = query.split("&");
- params.forEach(function(aParam) {
- let [name, value] = aParam.split("=");
- if (name === "body") {
- body = decodeURIComponent(value);
- }
- })
- }
-
- if (number || body) {
- return new ActivityChannel(aURI, aLoadInfo,
- "sms-handler",
- { number: number || "",
- type: "websms/sms",
- body: body });
- }
-
- throw Components.results.NS_ERROR_ILLEGAL_VALUE;
- },
-
- newChannel: function Proto_newChannel(aURI) {
- return this.newChannel2(aURI, null);
- },
-
- classID: Components.ID("{81ca20cb-0dad-4e32-8566-979c8998bd73}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SmsProtocolHandler]);
diff --git a/b2g/components/SystemAppProxy.jsm b/b2g/components/SystemAppProxy.jsm
deleted file mode 100644
index b3d5843fc..000000000
--- a/b2g/components/SystemAppProxy.jsm
+++ /dev/null
@@ -1,377 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-
-this.EXPORTED_SYMBOLS = ['SystemAppProxy'];
-
-const kMainSystemAppId = 'main';
-
-var SystemAppProxy = {
- _frameInfoMap: new Map(),
- _pendingLoadedEvents: [],
- _pendingReadyEvents: [],
- _pendingListeners: [],
-
- // To call when a main system app iframe is created
- // Only used for main system app.
- registerFrame: function systemApp_registerFrame(frame) {
- this.registerFrameWithId(kMainSystemAppId, frame);
- },
-
- // To call when a new system(-remote) app iframe is created with ID
- registerFrameWithId: function systemApp_registerFrameWithId(frameId,
- frame) {
- // - Frame ID of main system app is predefined as 'main'.
- // - Frame ID of system-remote app is defined themselves.
- //
- // frameInfo = {
- // isReady: ...,
- // isLoaded: ...,
- // frame: ...
- // }
-
- let frameInfo = { frameId: frameId,
- isReady: false,
- isLoaded: false,
- frame: frame };
-
- this._frameInfoMap.set(frameId, frameInfo);
-
- // Register all DOM event listeners added before we got a ref to
- // this system app iframe.
- this._pendingListeners
- .forEach(args => {
- if (args[0] === frameInfo.frameId) {
- this.addEventListenerWithId.apply(this, args);
- }
- });
- // Removed registered event listeners.
- this._pendingListeners =
- this._pendingListeners
- .filter(args => { return args[0] != frameInfo.frameId; });
- },
-
- unregisterFrameWithId: function systemApp_unregisterFrameWithId(frameId) {
- this._frameInfoMap.delete(frameId);
- // remove all pending event listener to the deleted system(-remote) app
- this._pendingListeners = this._pendingListeners.filter(
- args => { return args[0] != frameId; });
- this._pendingReadyEvents = this._pendingReadyEvents.filter(
- ([evtFrameId]) => { return evtFrameId != frameId });
- this._pendingLoadedEvents = this._pendingLoadedEvents.filter(
- ([evtFrameId]) => { return evtFrameId != frameId });
- },
-
- // Get the main system app frame
- _getMainSystemAppInfo: function systemApp_getMainSystemAppInfo() {
- return this._frameInfoMap.get(kMainSystemAppId);
- },
-
- // Get the main system app frame
- // Only used for the main system app.
- getFrame: function systemApp_getFrame() {
- return this.getFrameWithId(kMainSystemAppId);
- },
-
- // Get the frame of the specific system app
- getFrameWithId: function systemApp_getFrameWithId(frameId) {
- let frameInfo = this._frameInfoMap.get(frameId);
-
- if (!frameInfo) {
- throw new Error('no frame ID is ' + frameId);
- }
- if (!frameInfo.frame) {
- throw new Error('no content window');
- }
- return frameInfo.frame;
- },
-
- // To call when the load event of the main system app document is triggered.
- // i.e. everything that is not lazily loaded are run and done.
- // Only used for the main system app.
- setIsLoaded: function systemApp_setIsLoaded() {
- this.setIsLoadedWithId(kMainSystemAppId);
- },
-
- // To call when the load event of the specific system app document is
- // triggered. i.e. everything that is not lazily loaded are run and done.
- setIsLoadedWithId: function systemApp_setIsLoadedWithId(frameId) {
- let frameInfo = this._frameInfoMap.get(frameId);
- if (!frameInfo) {
- throw new Error('no frame ID is ' + frameId);
- }
-
- if (frameInfo.isLoaded) {
- if (frameInfo.frameId === kMainSystemAppId) {
- Cu.reportError('SystemApp has already been declared as being loaded.');
- }
- else {
- Cu.reportError('SystemRemoteApp (ID: ' + frameInfo.frameId + ') ' +
- 'has already been declared as being loaded.');
- }
- }
-
- frameInfo.isLoaded = true;
-
- // Dispatch all events being queued while the system app was still loading
- this._pendingLoadedEvents
- .forEach(([evtFrameId, evtType, evtDetails]) => {
- if (evtFrameId === frameInfo.frameId) {
- this.sendCustomEventWithId(evtFrameId, evtType, evtDetails, true);
- }
- });
- // Remove sent events.
- this._pendingLoadedEvents =
- this._pendingLoadedEvents
- .filter(([evtFrameId]) => { return evtFrameId != frameInfo.frameId });
- },
-
- // To call when the main system app is ready to receive events
- // i.e. when system-message-listener-ready mozContentEvent is sent.
- // Only used for the main system app.
- setIsReady: function systemApp_setIsReady() {
- this.setIsReadyWithId(kMainSystemAppId);
- },
-
- // To call when the specific system(-remote) app is ready to receive events
- // i.e. when system-message-listener-ready mozContentEvent is sent.
- setIsReadyWithId: function systemApp_setIsReadyWithId(frameId) {
- let frameInfo = this._frameInfoMap.get(frameId);
- if (!frameInfo) {
- throw new Error('no frame ID is ' + frameId);
- }
-
- if (!frameInfo.isLoaded) {
- Cu.reportError('SystemApp.setIsLoaded() should be called before setIsReady().');
- }
-
- if (frameInfo.isReady) {
- Cu.reportError('SystemApp has already been declared as being ready.');
- }
-
- frameInfo.isReady = true;
-
- // Dispatch all events being queued while the system app was still not ready
- this._pendingReadyEvents
- .forEach(([evtFrameId, evtType, evtDetails]) => {
- if (evtFrameId === frameInfo.frameId) {
- this.sendCustomEventWithId(evtFrameId, evtType, evtDetails);
- }
- });
-
- // Remove sent events.
- this._pendingReadyEvents =
- this._pendingReadyEvents
- .filter(([evtFrameId]) => { return evtFrameId != frameInfo.frameId });
- },
-
- /*
- * Common way to send an event to the main system app.
- * Only used for the main system app.
- *
- * // In gecko code:
- * SystemAppProxy.sendCustomEvent('foo', { data: 'bar' });
- * // In system app:
- * window.addEventListener('foo', function (event) {
- * event.details == 'bar'
- * });
- *
- * @param type The custom event type.
- * @param details The event details.
- * @param noPending Set to true to emit this event even before the system
- * app is ready.
- * Event is always pending if the app is not loaded yet.
- * @param target The element who dispatch this event.
- *
- * @returns event? Dispatched event, or null if the event is pending.
- */
- _sendCustomEvent: function systemApp_sendCustomEvent(type,
- details,
- noPending,
- target) {
- let args = Array.prototype.slice.call(arguments);
- return this.sendCustomEventWithId
- .apply(this, [kMainSystemAppId].concat(args));
- },
-
- /*
- * Common way to send an event to the specific system app.
- *
- * // In gecko code (send custom event from main system app):
- * SystemAppProxy.sendCustomEventWithId('main', 'foo', { data: 'bar' });
- * // In system app:
- * window.addEventListener('foo', function (event) {
- * event.details == 'bar'
- * });
- *
- * @param frameId Specify the system(-remote) app who dispatch this event.
- * @param type The custom event type.
- * @param details The event details.
- * @param noPending Set to true to emit this event even before the system
- * app is ready.
- * Event is always pending if the app is not loaded yet.
- * @param target The element who dispatch this event.
- *
- * @returns event? Dispatched event, or null if the event is pending.
- */
- sendCustomEventWithId: function systemApp_sendCustomEventWithId(frameId,
- type,
- details,
- noPending,
- target) {
- let frameInfo = this._frameInfoMap.get(frameId);
- let content = (frameInfo && frameInfo.frame) ?
- frameInfo.frame.contentWindow : null;
- // If the system app isn't loaded yet,
- // queue events until someone calls setIsLoaded
- if (!content || !(frameInfo && frameInfo.isLoaded)) {
- if (noPending) {
- this._pendingLoadedEvents.push([frameId, type, details]);
- } else {
- this._pendingReadyEvents.push([frameId, type, details]);
- }
- return null;
- }
-
- // If the system app isn't ready yet,
- // queue events until someone calls setIsReady
- if (!(frameInfo && frameInfo.isReady) && !noPending) {
- this._pendingReadyEvents.push([frameId, type, details]);
- return null;
- }
-
- let event = content.document.createEvent('CustomEvent');
-
- let payload;
- // If the root object already has __exposedProps__,
- // we consider the caller already wrapped (correctly) the object.
- if ('__exposedProps__' in details) {
- payload = details;
- } else {
- payload = details ? Cu.cloneInto(details, content) : {};
- }
-
- if ((target || content) === frameInfo.frame.contentWindow) {
- dump('XXX FIXME : Dispatch a ' + type + ': ' + details.type + '\n');
- }
-
- event.initCustomEvent(type, true, false, payload);
- (target || content).dispatchEvent(event);
-
- return event;
- },
-
- // Now deprecated, use sendCustomEvent with a custom event name
- dispatchEvent: function systemApp_dispatchEvent(details, target) {
- return this._sendCustomEvent('mozChromeEvent', details, false, target);
- },
-
- dispatchKeyboardEvent: function systemApp_dispatchKeyboardEvent(type, details) {
- try {
- let frameInfo = this._getMainSystemAppInfo();
- let content = (frameInfo && frameInfo.frame) ? frameInfo.frame.contentWindow
- : null;
- if (!content) {
- throw new Error('no content window');
- }
- // If we don't already have a TextInputProcessor, create one now
- if (!this.TIP) {
- this.TIP = Cc['@mozilla.org/text-input-processor;1']
- .createInstance(Ci.nsITextInputProcessor);
- if (!this.TIP) {
- throw new Error('failed to create textInputProcessor');
- }
- }
-
- if (!this.TIP.beginInputTransactionForTests(content)) {
- this.TIP = null;
- throw new Error('beginInputTransaction failed');
- }
-
- let e = new content.KeyboardEvent('', { key: details.key, });
-
- if (type === 'keydown') {
- this.TIP.keydown(e);
- }
- else if (type === 'keyup') {
- this.TIP.keyup(e);
- }
- else {
- throw new Error('unexpected event type: ' + type);
- }
- }
- catch(e) {
- dump('dispatchKeyboardEvent: ' + e + '\n');
- }
- },
-
- // Listen for dom events on the main system app
- addEventListener: function systemApp_addEventListener() {
- let args = Array.prototype.slice.call(arguments);
- this.addEventListenerWithId.apply(this, [kMainSystemAppId].concat(args));
- },
-
- // Listen for dom events on the specific system app
- addEventListenerWithId: function systemApp_addEventListenerWithId(frameId,
- ...args) {
- let frameInfo = this._frameInfoMap.get(frameId);
-
- if (!frameInfo) {
- this._pendingListeners.push(arguments);
- return false;
- }
-
- let content = frameInfo.frame.contentWindow;
- content.addEventListener.apply(content, args);
- return true;
- },
-
- // remove the event listener from the main system app
- removeEventListener: function systemApp_removeEventListener(name, listener) {
- this.removeEventListenerWithId.apply(this, [kMainSystemAppId, name, listener]);
- },
-
- // remove the event listener from the specific system app
- removeEventListenerWithId: function systemApp_removeEventListenerWithId(frameId,
- name,
- listener) {
- let frameInfo = this._frameInfoMap.get(frameId);
-
- if (frameInfo) {
- let content = frameInfo.frame.contentWindow;
- content.removeEventListener.apply(content, [name, listener]);
- }
- else {
- this._pendingListeners = this._pendingListeners.filter(
- args => {
- return args[0] != frameId || args[1] != name || args[2] != listener;
- });
- }
- },
-
- // Get all frame in system app
- getFrames: function systemApp_getFrames(frameId) {
- let frameList = [];
-
- for (let frameId of this._frameInfoMap.keys()) {
- let frameInfo = this._frameInfoMap.get(frameId);
- let systemAppFrame = frameInfo.frame;
- let subFrames = systemAppFrame.contentDocument.querySelectorAll('iframe');
- frameList.push(systemAppFrame);
- for (let i = 0; i < subFrames.length; ++i) {
- frameList.push(subFrames[i]);
- }
- }
- return frameList;
- }
-};
-this.SystemAppProxy = SystemAppProxy;
diff --git a/b2g/components/SystemMessageInternal.js b/b2g/components/SystemMessageInternal.js
deleted file mode 100644
index 287496a50..000000000
--- a/b2g/components/SystemMessageInternal.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/SystemAppProxy.jsm");
-
-function debug(aMsg) {
- dump("-- SystemMessageInternal " + Date.now() + " : " + aMsg + "\n");
-}
-
-// Implementation of the component used by internal users.
-
-function SystemMessageInternal() {
-}
-
-SystemMessageInternal.prototype = {
-
- sendMessage: function(aType, aMessage, aPageURI, aManifestURI, aExtra) {
- debug(`sendMessage ${aType} ${aMessage} ${aPageURI} ${aExtra}`);
- SystemAppProxy._sendCustomEvent("mozSystemMessage", {
- action: "send",
- type: aType,
- message: aMessage,
- pageURI: aPageURI,
- extra: aExtra
- });
- return Promise.resolve();
- },
-
- broadcastMessage: function(aType, aMessage, aExtra) {
- debug(`broadcastMessage ${aType} ${aMessage} ${aExtra}`);
- SystemAppProxy._sendCustomEvent("mozSystemMessage", {
- action: "broadcast",
- type: aType,
- message: aMessage,
- extra: aExtra
- });
- return Promise.resolve();
- },
-
- registerPage: function(aType, aPageURI, aManifestURI) {
- SystemAppProxy._sendCustomEvent("mozSystemMessage", {
- action: "register",
- type: aType,
- pageURI: aPageURI
- });
- debug(`registerPage ${aType} ${aPageURI} ${aManifestURI}`);
- },
-
- classID: Components.ID("{70589ca5-91ac-4b9e-b839-d6a88167d714}"),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesInternal])
-}
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemMessageInternal]);
diff --git a/b2g/components/TelProtocolHandler.js b/b2g/components/TelProtocolHandler.js
deleted file mode 100644
index 021cbcd61..000000000
--- a/b2g/components/TelProtocolHandler.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * TelProtocolHandle.js
- *
- * This file implements the URLs for Telephone Calls
- * https://www.ietf.org/rfc/rfc2806.txt
- */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import("resource:///modules/TelURIParser.jsm");
-Cu.import('resource://gre/modules/ActivityChannel.jsm');
-
-function TelProtocolHandler() {
-}
-
-TelProtocolHandler.prototype = {
-
- scheme: "tel",
- defaultPort: -1,
- protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
- Ci.nsIProtocolHandler.URI_NOAUTH |
- Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
- Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA,
- allowPort: () => false,
-
- newURI: function Proto_newURI(aSpec, aOriginCharset) {
- let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
- uri.spec = aSpec;
- return uri;
- },
-
- newChannel2: function Proto_newChannel(aURI, aLoadInfo) {
- let number = TelURIParser.parseURI('tel', aURI.spec);
-
- if (number) {
- return new ActivityChannel(aURI, aLoadInfo,
- "dial-handler",
- { number: number,
- type: "webtelephony/number" });
- }
-
- throw Components.results.NS_ERROR_ILLEGAL_VALUE;
- },
-
- newChannel: function Proto_newChannel(aURI) {
- return this.newChannel2(aURI, null);
- },
-
- classID: Components.ID("{782775dd-7351-45ea-aff1-0ffa872cfdd2}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelProtocolHandler]);
diff --git a/b2g/components/TelURIParser.jsm b/b2g/components/TelURIParser.jsm
deleted file mode 100644
index 46b0bb8fd..000000000
--- a/b2g/components/TelURIParser.jsm
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["TelURIParser"];
-
-/**
- * Singleton providing functionality for parsing tel: and sms: URIs
- */
-this.TelURIParser = {
- parseURI: function(scheme, uri) {
- // https://www.ietf.org/rfc/rfc2806.txt
- let subscriber = decodeURIComponent(uri.slice((scheme + ':').length));
-
- if (!subscriber.length) {
- return null;
- }
-
- let number = '';
- let pos = 0;
- let len = subscriber.length;
-
- // visual-separator
- let visualSeparator = [ ' ', '-', '.', '(', ')' ];
- let digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
- let dtmfDigits = [ '*', '#', 'A', 'B', 'C', 'D' ];
- let pauseCharacter = [ 'p', 'w' ];
-
- // global-phone-number
- if (subscriber[pos] == '+') {
- number += '+';
- for (++pos; pos < len; ++pos) {
- if (visualSeparator.indexOf(subscriber[pos]) != -1) {
- number += subscriber[pos];
- } else if (digits.indexOf(subscriber[pos]) != -1) {
- number += subscriber[pos];
- } else {
- break;
- }
- }
- }
- // local-phone-number
- else {
- for (; pos < len; ++pos) {
- if (visualSeparator.indexOf(subscriber[pos]) != -1) {
- number += subscriber[pos];
- } else if (digits.indexOf(subscriber[pos]) != -1) {
- number += subscriber[pos];
- } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) {
- number += subscriber[pos];
- } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) {
- number += subscriber[pos];
- } else {
- break;
- }
- }
-
- // this means error
- if (!number.length) {
- return null;
- }
-
- // isdn-subaddress
- if (subscriber.substring(pos, pos + 6) == ';isub=') {
- let subaddress = '';
-
- for (pos += 6; pos < len; ++pos) {
- if (visualSeparator.indexOf(subscriber[pos]) != -1) {
- subaddress += subscriber[pos];
- } else if (digits.indexOf(subscriber[pos]) != -1) {
- subaddress += subscriber[pos];
- } else {
- break;
- }
- }
-
- // FIXME: ignore subaddress - Bug 795242
- }
-
- // post-dial
- if (subscriber.substring(pos, pos + 7) == ';postd=') {
- let subaddress = '';
-
- for (pos += 7; pos < len; ++pos) {
- if (visualSeparator.indexOf(subscriber[pos]) != -1) {
- subaddress += subscriber[pos];
- } else if (digits.indexOf(subscriber[pos]) != -1) {
- subaddress += subscriber[pos];
- } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) {
- subaddress += subscriber[pos];
- } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) {
- subaddress += subscriber[pos];
- } else {
- break;
- }
- }
-
- // FIXME: ignore subaddress - Bug 795242
- }
-
- // area-specific
- if (subscriber.substring(pos, pos + 15) == ';phone-context=') {
- pos += 15;
-
- // global-network-prefix | local-network-prefix | private-prefi
- number = subscriber.substring(pos, subscriber.length) + number;
- }
- }
-
- // Ignore MWI and USSD codes. See 794034.
- if (number.match(/[#\*]/) && !number.match(/^[#\*]\d+$/)) {
- return null;
- }
-
- return number || null;
- }
-};
-
diff --git a/b2g/components/UpdatePrompt.js b/b2g/components/UpdatePrompt.js
deleted file mode 100644
index 1df07204c..000000000
--- a/b2g/components/UpdatePrompt.js
+++ /dev/null
@@ -1,783 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const VERBOSE = 1;
-var log =
- VERBOSE ?
- function log_dump(msg) { dump("UpdatePrompt: "+ msg +"\n"); } :
- function log_noop(msg) { };
-
-const PREF_APPLY_PROMPT_TIMEOUT = "b2g.update.apply-prompt-timeout";
-const PREF_APPLY_IDLE_TIMEOUT = "b2g.update.apply-idle-timeout";
-const PREF_DOWNLOAD_WATCHDOG_TIMEOUT = "b2g.update.download-watchdog-timeout";
-const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries";
-
-const NETWORK_ERROR_OFFLINE = 111;
-const HTTP_ERROR_OFFSET = 1000;
-
-const STATE_DOWNLOADING = 'downloading';
-
-XPCOMUtils.defineLazyServiceGetter(Services, "aus",
- "@mozilla.org/updates/update-service;1",
- "nsIApplicationUpdateService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "um",
- "@mozilla.org/updates/update-manager;1",
- "nsIUpdateManager");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "idle",
- "@mozilla.org/widget/idleservice;1",
- "nsIIdleService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "settings",
- "@mozilla.org/settingsService;1",
- "nsISettingsService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'env',
- '@mozilla.org/process/environment;1',
- 'nsIEnvironment');
-
-function useSettings() {
- // When we're running in the real phone, then we can use settings.
- // But when we're running as part of xpcshell, there is no settings database
- // and trying to use settings in this scenario causes lots of weird
- // assertions at shutdown time.
- if (typeof useSettings.result === "undefined") {
- useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR");
- }
- return useSettings.result;
-}
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
- "resource://gre/modules/SystemAppProxy.jsm");
-
-function UpdateCheckListener(updatePrompt) {
- this._updatePrompt = updatePrompt;
-}
-
-UpdateCheckListener.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener]),
-
- _updatePrompt: null,
-
- onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) {
- if (Services.um.activeUpdate) {
- // We're actively downloading an update, that's the update the user should
- // see, even if a newer update is available.
- this._updatePrompt.setUpdateStatus("active-update");
- this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate);
- return;
- }
-
- if (updateCount == 0) {
- this._updatePrompt.setUpdateStatus("no-updates");
-
- if (this._updatePrompt._systemUpdateListener) {
- this._updatePrompt._systemUpdateListener.onError("no-updates");
- }
-
- return;
- }
-
- let update = Services.aus.selectUpdate(updates, updateCount);
- if (!update) {
- this._updatePrompt.setUpdateStatus("already-latest-version");
-
- if (this._updatePrompt._systemUpdateListener) {
- this._updatePrompt._systemUpdateListener.onError("already-latest-version");
- }
-
- return;
- }
-
- this._updatePrompt.setUpdateStatus("check-complete");
- this._updatePrompt.showUpdateAvailable(update);
- },
-
- onError: function UCL_onError(request, update) {
- // nsIUpdate uses a signed integer for errorCode while any platform errors
- // require all 32 bits.
- let errorCode = update.errorCode >>> 0;
- let isNSError = (errorCode >>> 31) == 1;
- let errorMsg = "check-error-";
-
- if (errorCode == NETWORK_ERROR_OFFLINE) {
- errorMsg = "retry-when-online";
- this._updatePrompt.setUpdateStatus(errorMsg);
- } else if (isNSError) {
- errorMsg = "check-error-" + errorCode;
- this._updatePrompt.setUpdateStatus(errorMsg);
- } else if (errorCode > HTTP_ERROR_OFFSET) {
- let httpErrorCode = errorCode - HTTP_ERROR_OFFSET;
- errorMsg = "check-error-http-" + httpErrorCode;
- this._updatePrompt.setUpdateStatus(errorMsg);
- }
-
- if (this._updatePrompt._systemUpdateListener) {
- this._updatePrompt._systemUpdateListener.onError(errorMsg);
- }
-
- Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
- Services.aus.onError(request, update);
- }
-};
-
-function UpdatePrompt() {
- this.wrappedJSObject = this;
- this._updateCheckListener = new UpdateCheckListener(this);
-}
-
-UpdatePrompt.prototype = {
- classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
- Ci.nsIUpdateCheckListener,
- Ci.nsIRequestObserver,
- Ci.nsIProgressEventSink,
- Ci.nsIObserver,
- Ci.nsISystemUpdateProvider]),
- _xpcom_factory: XPCOMUtils.generateSingletonFactory(UpdatePrompt),
-
- _update: null,
- _applyPromptTimer: null,
- _waitingForIdle: false,
- _updateCheckListner: null,
- _systemUpdateListener: null,
- _availableParameters: {
- "deviceinfo.last_updated": null,
- "gecko.updateStatus": null,
- "app.update.channel": null,
- "app.update.interval": null,
- "app.update.url": null,
- },
- _pendingUpdateAvailablePackageInfo: null,
- _isPendingUpdateReady: false,
- _updateErrorQueue: [ ],
- _receivedUpdatePromptReady: false,
-
- // nsISystemUpdateProvider
- checkForUpdate: function() {
- this.forceUpdateCheck();
- },
-
- startDownload: function() {
- this.downloadUpdate(this._update);
- },
-
- stopDownload: function() {
- this.handleDownloadCancel();
- },
-
- applyUpdate: function() {
- this.handleApplyPromptResult({result: "restart"});
- },
-
- setParameter: function(aName, aValue) {
- if (!this._availableParameters.hasOwnProperty(aName)) {
- return false;
- }
-
- this._availableParameters[aName] = aValue;
-
- switch (aName) {
- case "app.update.channel":
- case "app.update.url":
- Services.prefs.setCharPref(aName, aValue);
- break;
- case "app.update.interval":
- Services.prefs.setIntPref(aName, parseInt(aValue, 10));
- break;
- }
-
- return true;
- },
-
- getParameter: function(aName) {
- if (!this._availableParameters.hasOwnProperty(aName)) {
- return null;
- }
-
- return this._availableParameters[aName];
- },
-
- setListener: function(aListener) {
- this._systemUpdateListener = aListener;
-
- // If an update is available or ready, trigger the event right away at this point.
- if (this._pendingUpdateAvailablePackageInfo) {
- this._systemUpdateListener.onUpdateAvailable(this._pendingUpdateAvailablePackageInfo.type,
- this._pendingUpdateAvailablePackageInfo.version,
- this._pendingUpdateAvailablePackageInfo.description,
- this._pendingUpdateAvailablePackageInfo.buildDate,
- this._pendingUpdateAvailablePackageInfo.size);
- // Set null when the listener is attached.
- this._pendingUpdateAvailablePackageInfo = null;
- }
-
- if (this._isPendingUpdateReady) {
- this._systemUpdateListener.onUpdateReady();
- this._isPendingUpdateReady = false;
- }
- },
-
- unsetListener: function(aListener) {
- this._systemUpdateListener = null;
- },
-
- get applyPromptTimeout() {
- return Services.prefs.getIntPref(PREF_APPLY_PROMPT_TIMEOUT);
- },
-
- get applyIdleTimeout() {
- return Services.prefs.getIntPref(PREF_APPLY_IDLE_TIMEOUT);
- },
-
- handleContentStart: function UP_handleContentStart() {
- SystemAppProxy.addEventListener("mozContentEvent", this);
- },
-
- // nsIUpdatePrompt
-
- // FIXME/bug 737601: we should have users opt-in to downloading
- // updates when on a billed pipe. Initially, opt-in for 3g, but
- // that doesn't cover all cases.
- checkForUpdates: function UP_checkForUpdates() { },
-
- showUpdateAvailable: function UP_showUpdateAvailable(aUpdate) {
- let packageInfo = {};
- packageInfo.version = aUpdate.displayVersion;
- packageInfo.description = aUpdate.statusText;
- packageInfo.buildDate = aUpdate.buildID;
-
- let patch = aUpdate.selectedPatch;
- if (!patch && aUpdate.patchCount > 0) {
- // For now we just check the first patch to get size information if a
- // patch hasn't been selected yet.
- patch = aUpdate.getPatchAt(0);
- }
-
- if (patch) {
- packageInfo.size = patch.size;
- packageInfo.type = patch.type;
- } else {
- log("Warning: no patches available in update");
- }
-
- this._pendingUpdateAvailablePackageInfo = packageInfo;
-
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onUpdateAvailable(packageInfo.type,
- packageInfo.version,
- packageInfo.description,
- packageInfo.buildDate,
- packageInfo.size);
- // Set null since the event is fired.
- this._pendingUpdateAvailablePackageInfo = null;
- }
-
- if (!this.sendUpdateEvent("update-available", aUpdate)) {
-
- log("Unable to prompt for available update, forcing download");
- this.downloadUpdate(aUpdate);
- }
- },
-
- showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) {
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onUpdateReady();
- } else {
- this._isPendingUpdateReady = true;
- }
-
- // The update has been downloaded and staged. We send the update-downloaded
- // event right away. After the user has been idle for a while, we send the
- // update-prompt-restart event, increasing the chances that we can apply the
- // update quietly without user intervention.
- this.sendUpdateEvent("update-downloaded", aUpdate);
-
- if (Services.idle.idleTime >= this.applyIdleTimeout) {
- this.showApplyPrompt(aUpdate);
- return;
- }
-
- let applyIdleTimeoutSeconds = this.applyIdleTimeout / 1000;
- // We haven't been idle long enough, so register an observer
- log("Update is ready to apply, registering idle timeout of " +
- applyIdleTimeoutSeconds + " seconds before prompting.");
-
- this._update = aUpdate;
- this.waitForIdle();
- },
-
- storeUpdateError: function UP_storeUpdateError(aUpdate) {
- log("Storing update error for later use");
- this._updateErrorQueue.push(aUpdate);
- },
-
- sendStoredUpdateError: function UP_sendStoredUpdateError() {
- log("Sending stored update error");
- this._updateErrorQueue.forEach(aUpdate => {
- this.sendUpdateEvent("update-error", aUpdate);
- });
- this._updateErrorQueue = [ ];
- },
-
- showUpdateError: function UP_showUpdateError(aUpdate) {
- log("Update error, state: " + aUpdate.state + ", errorCode: " +
- aUpdate.errorCode);
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onError("update-error: " + aUpdate.errorCode + " " + aUpdate.statusText);
- }
-
- if (!this._receivedUpdatePromptReady) {
- this.storeUpdateError(aUpdate);
- } else {
- this.sendUpdateEvent("update-error", aUpdate);
- }
-
- this.setUpdateStatus(aUpdate.statusText);
- },
-
- showUpdateHistory: function UP_showUpdateHistory(aParent) { },
- showUpdateInstalled: function UP_showUpdateInstalled() {
- this.setParameter("deviceinfo.last_updated", Date.now());
-
- if (useSettings()) {
- let lock = Services.settings.createLock();
- lock.set("deviceinfo.last_updated", Date.now(), null, null);
- }
- },
-
- // Custom functions
-
- waitForIdle: function UP_waitForIdle() {
- if (this._waitingForIdle) {
- return;
- }
-
- this._waitingForIdle = true;
- Services.idle.addIdleObserver(this, this.applyIdleTimeout / 1000);
- Services.obs.addObserver(this, "quit-application", false);
- },
-
- setUpdateStatus: function UP_setUpdateStatus(aStatus) {
- this.setParameter("gecko.updateStatus", aStatus);
-
- if (useSettings()) {
- log("Setting gecko.updateStatus: " + aStatus);
-
- let lock = Services.settings.createLock();
- lock.set("gecko.updateStatus", aStatus, null);
- }
- },
-
- showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
- // Notify update package is ready to apply
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onUpdateReady();
- } else {
- // Set the flag to true and fire the onUpdateReady event when the listener is attached.
- this._isPendingUpdateReady = true;
- }
-
- if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
- log("Unable to prompt, forcing restart");
- this.restartProcess();
- return;
- }
-
- if (AppConstants.MOZ_B2G_RIL) {
- let window = Services.wm.getMostRecentWindow("navigator:browser");
- let pinReq = window.navigator.mozIccManager.getCardLock("pin");
- pinReq.onsuccess = function(e) {
- if (e.target.result.enabled) {
- // The SIM is pin locked. Don't use a fallback timer. This means that
- // the user has to press Install to apply the update. If we use the
- // timer, and the timer reboots the phone, then the phone will be
- // unusable until the SIM is unlocked.
- log("SIM is pin locked. Not starting fallback timer.");
- } else {
- // This means that no pin lock is enabled, so we go ahead and start
- // the fallback timer.
- this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
- }
- }.bind(this);
- pinReq.onerror = function(e) {
- this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
- }.bind(this);
- } else {
- // Schedule a fallback timeout in case the UI is unable to respond or show
- // a prompt for some reason.
- this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
- }
- },
-
- _copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
- "errorCode", "isOSUpdate", "platformVersion",
- "previousAppVersion", "state", "statusText"],
-
- sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
- let detail = {};
- for (let property of this._copyProperties) {
- detail[property] = aUpdate[property];
- }
-
- let patch = aUpdate.selectedPatch;
- if (!patch && aUpdate.patchCount > 0) {
- // For now we just check the first patch to get size information if a
- // patch hasn't been selected yet.
- patch = aUpdate.getPatchAt(0);
- }
-
- if (patch) {
- detail.size = patch.size;
- detail.updateType = patch.type;
- } else {
- log("Warning: no patches available in update");
- }
-
- this._update = aUpdate;
- return this.sendChromeEvent(aType, detail);
- },
-
- sendChromeEvent: function UP_sendChromeEvent(aType, aDetail) {
- let detail = aDetail || {};
- detail.type = aType;
-
- let sent = SystemAppProxy.dispatchEvent(detail);
- if (!sent) {
- log("Warning: Couldn't send update event " + aType +
- ": no content browser. Will send again when content becomes available.");
- return false;
- }
- return true;
- },
-
- handleAvailableResult: function UP_handleAvailableResult(aDetail) {
- // If the user doesn't choose "download", the updater will implicitly call
- // showUpdateAvailable again after a certain period of time
- switch (aDetail.result) {
- case "download":
- this.downloadUpdate(this._update);
- break;
- }
- },
-
- handleApplyPromptResult: function UP_handleApplyPromptResult(aDetail) {
- if (this._applyPromptTimer) {
- this._applyPromptTimer.cancel();
- this._applyPromptTimer = null;
- }
-
- switch (aDetail.result) {
- // Battery not okay, do not wait for idle to re-prompt
- case "low-battery":
- break;
- case "wait":
- // Wait until the user is idle before prompting to apply the update
- this.waitForIdle();
- break;
- case "restart":
- this.finishUpdate();
- this._update = null;
- break;
- }
- },
-
- downloadUpdate: function UP_downloadUpdate(aUpdate) {
- if (!aUpdate) {
- aUpdate = Services.um.activeUpdate;
- if (!aUpdate) {
- log("No active update found to download");
- return;
- }
- }
-
- let status = Services.aus.downloadUpdate(aUpdate, true);
- if (status == STATE_DOWNLOADING) {
- Services.aus.addDownloadListener(this);
- return;
- }
-
- // If the update has already been downloaded and applied, then
- // Services.aus.downloadUpdate will return immediately and not
- // call showUpdateDownloaded, so we detect this.
- if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
- this.showUpdateDownloaded(aUpdate, true);
- return;
- }
-
- log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
- let errorCode = aUpdate.errorCode >>> 0;
- if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) {
- aUpdate.statusText = "file-too-big";
- }
- this.showUpdateError(aUpdate);
- },
-
- handleDownloadCancel: function UP_handleDownloadCancel() {
- log("Pausing download");
- Services.aus.pauseDownload();
- },
-
- finishUpdate: function UP_finishUpdate() {
- if (!this._update.isOSUpdate) {
- // Standard gecko+gaia updates will just need to restart the process
- this.restartProcess();
- return;
- }
-
- try {
- Services.aus.applyOsUpdate(this._update);
- }
- catch (e) {
- this._update.errorCode = Cr.NS_ERROR_FAILURE;
- this.showUpdateError(this._update);
- }
- },
-
- restartProcess: function UP_restartProcess() {
- log("Update downloaded, restarting to apply it");
-
- let callbackAfterSet = function() {
- if (AppConstants.platform !== "gonk") {
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
- } else {
- // NB: on Gonk, we rely on the system process manager to restart us.
- let pmService = Cc["@mozilla.org/power/powermanagerservice;1"]
- .getService(Ci.nsIPowerManagerService);
- pmService.restart();
- }
- }
-
- if (useSettings()) {
- // Save current os version in deviceinfo.previous_os
- let lock = Services.settings.createLock({
- handle: callbackAfterSet,
- handleAbort: function(error) {
- log("Abort callback when trying to set previous_os: " + error);
- callbackAfterSet();
- }
- });
- lock.get("deviceinfo.os", {
- handle: function(name, value) {
- log("Set previous_os to: " + value);
- lock.set("deviceinfo.previous_os", value, null, null);
- }
- });
- }
- },
-
- forceUpdateCheck: function UP_forceUpdateCheck() {
- log("Forcing update check");
-
- let checker = Cc["@mozilla.org/updates/update-checker;1"]
- .createInstance(Ci.nsIUpdateChecker);
- checker.checkForUpdates(this._updateCheckListener, true);
- },
-
- handleEvent: function UP_handleEvent(evt) {
- if (evt.type !== "mozContentEvent") {
- return;
- }
-
- let detail = evt.detail;
- if (!detail) {
- return;
- }
-
- switch (detail.type) {
- case "force-update-check":
- this.forceUpdateCheck();
- break;
- case "update-available-result":
- this.handleAvailableResult(detail);
- // If we started the apply prompt timer, this means that we're waiting
- // for the user to press Later or Install Now. In this situation we
- // don't want to clear this._update, becuase handleApplyPromptResult
- // needs it.
- if (this._applyPromptTimer == null && !this._waitingForIdle) {
- this._update = null;
- }
- break;
- case "update-download-cancel":
- this.handleDownloadCancel();
- break;
- case "update-prompt-apply-result":
- this.handleApplyPromptResult(detail);
- break;
- case "update-prompt-ready":
- this._receivedUpdatePromptReady = true;
- this.sendStoredUpdateError();
- break;
- }
- },
-
- // nsIObserver
-
- observe: function UP_observe(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "idle":
- this._waitingForIdle = false;
- this.showApplyPrompt(this._update);
- // Fall through
- case "quit-application":
- Services.idle.removeIdleObserver(this, this.applyIdleTimeout / 1000);
- Services.obs.removeObserver(this, "quit-application");
- break;
- }
- },
-
- // nsITimerCallback
-
- notify: function UP_notify(aTimer) {
- if (aTimer == this._applyPromptTimer) {
- log("Timed out waiting for result, restarting");
- this._applyPromptTimer = null;
- this.finishUpdate();
- this._update = null;
- return;
- }
- if (aTimer == this._watchdogTimer) {
- log("Download watchdog fired");
- this._watchdogTimer = null;
- this._autoRestartDownload = true;
- Services.aus.pauseDownload();
- return;
- }
- },
-
- createTimer: function UP_createTimer(aTimeoutMs) {
- let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT);
- return timer;
- },
-
- // nsIRequestObserver
-
- _startedSent: false,
-
- _watchdogTimer: null,
-
- _autoRestartDownload: false,
- _autoRestartCount: 0,
-
- startWatchdogTimer: function UP_startWatchdogTimer() {
- let watchdogTimeout = 120000; // 120 seconds
- try {
- watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
- } catch (e) {
- // This means that the preference doesn't exist. watchdogTimeout will
- // retain its default assigned above.
- }
- if (watchdogTimeout <= 0) {
- // 0 implies don't bother using the watchdog timer at all.
- this._watchdogTimer = null;
- return;
- }
- if (this._watchdogTimer) {
- this._watchdogTimer.cancel();
- } else {
- this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- }
- this._watchdogTimer.initWithCallback(this, watchdogTimeout,
- Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- stopWatchdogTimer: function UP_stopWatchdogTimer() {
- if (this._watchdogTimer) {
- this._watchdogTimer.cancel();
- this._watchdogTimer = null;
- }
- },
-
- touchWatchdogTimer: function UP_touchWatchdogTimer() {
- this.startWatchdogTimer();
- },
-
- onStartRequest: function UP_onStartRequest(aRequest, aContext) {
- // Wait until onProgress to send the update-download-started event, in case
- // this request turns out to fail for some reason
- this._startedSent = false;
- this.startWatchdogTimer();
- },
-
- onStopRequest: function UP_onStopRequest(aRequest, aContext, aStatusCode) {
- this.stopWatchdogTimer();
- Services.aus.removeDownloadListener(this);
- let paused = !Components.isSuccessCode(aStatusCode);
- if (!paused) {
- // The download was successful, no need to restart
- this._autoRestartDownload = false;
- }
- if (this._autoRestartDownload) {
- this._autoRestartDownload = false;
- let watchdogMaxRetries = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES);
- this._autoRestartCount++;
- if (this._autoRestartCount > watchdogMaxRetries) {
- log("Download - retry count exceeded - error");
- // We exceeded the max retries. Treat the download like an error,
- // which will give the user a chance to restart manually later.
- this._autoRestartCount = 0;
- if (Services.um.activeUpdate) {
- this.showUpdateError(Services.um.activeUpdate);
- }
- return;
- }
- log("Download - restarting download - attempt " + this._autoRestartCount);
- this.downloadUpdate(null);
- return;
- }
- this._autoRestartCount = 0;
- this.sendChromeEvent("update-download-stopped", {
- paused: paused
- });
- },
-
- // nsIProgressEventSink
-
- onProgress: function UP_onProgress(aRequest, aContext, aProgress,
- aProgressMax) {
- if (this._systemUpdateListener) {
- this._systemUpdateListener.onProgress(aProgress, aProgressMax);
- }
-
- if (aProgress == aProgressMax) {
- // The update.mar validation done by onStopRequest may take
- // a while before the onStopRequest callback is made, so stop
- // the timer now.
- this.stopWatchdogTimer();
- } else {
- this.touchWatchdogTimer();
- }
- if (!this._startedSent) {
- this.sendChromeEvent("update-download-started", {
- total: aProgressMax
- });
- this._startedSent = true;
- }
-
- this.sendChromeEvent("update-download-progress", {
- progress: aProgress,
- total: aProgressMax
- });
- },
-
- onStatus: function UP_onStatus(aRequest, aUpdate, aStatus, aStatusArg) { }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]);
diff --git a/b2g/components/moz.build b/b2g/components/moz.build
deleted file mode 100644
index 9290c5e2a..000000000
--- a/b2g/components/moz.build
+++ /dev/null
@@ -1,91 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['test']
-
-EXTRA_COMPONENTS += [
- 'AlertsService.js',
- 'B2GAboutRedirector.js',
- 'B2GAppMigrator.js',
- 'B2GPresentationDevicePrompt.js',
- 'BootstrapCommandLine.js',
- 'ContentPermissionPrompt.js',
- 'FilePicker.js',
- 'FxAccountsUIGlue.js',
- 'HelperAppDialog.js',
- 'MailtoProtocolHandler.js',
- 'OMAContentHandler.js',
- 'PresentationRequestUIGlue.js',
- 'ProcessGlobal.js',
- 'SmsProtocolHandler.js',
- 'SystemMessageInternal.js',
- 'TelProtocolHandler.js',
-]
-
-if CONFIG['OS_TARGET'] != 'Android':
- EXTRA_COMPONENTS += [
- 'CommandLine.js',
- 'OopCommandLine.js',
- 'SimulatorScreen.js'
- ]
-
-EXTRA_PP_COMPONENTS += [
- 'B2GComponents.manifest',
-]
-
-if CONFIG['MOZ_B2G']:
- EXTRA_COMPONENTS += [
- 'DirectoryProvider.js',
- 'RecoveryService.js',
- ]
-
-if CONFIG['MOZ_UPDATER']:
- EXTRA_COMPONENTS += [
- 'UpdatePrompt.js',
- ]
-
-EXTRA_JS_MODULES += [
- 'AboutServiceWorkers.jsm',
- 'ActivityChannel.jsm',
- 'AlertsHelper.jsm',
- 'Bootstraper.jsm',
- 'ContentRequestHelper.jsm',
- 'DebuggerActors.js',
- 'ErrorPage.jsm',
- 'Frames.jsm',
- 'FxAccountsMgmtService.jsm',
- 'LogCapture.jsm',
- 'LogParser.jsm',
- 'LogShake.jsm',
- 'OrientationChangeHandler.jsm',
- 'SafeMode.jsm',
- 'Screenshot.jsm',
- 'SignInToWebsite.jsm',
- 'SystemAppProxy.jsm',
- 'TelURIParser.jsm',
-]
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
- EXTRA_JS_MODULES += [
- 'GlobalSimulatorScreen.jsm'
- ]
-
-XPIDL_SOURCES += [
- 'nsIGaiaChrome.idl',
- 'nsISystemMessagesInternal.idl'
-]
-
-XPIDL_MODULE = 'gaia_chrome'
-
-UNIFIED_SOURCES += [
- 'GaiaChrome.cpp'
-]
-
-LOCAL_INCLUDES += [
- '/chrome'
-]
-
-FINAL_LIBRARY = 'xul'
diff --git a/b2g/components/nsIGaiaChrome.idl b/b2g/components/nsIGaiaChrome.idl
deleted file mode 100644
index 8e66d8456..000000000
--- a/b2g/components/nsIGaiaChrome.idl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(92a18a98-ab5d-4d02-a024-bdbb3bc89ce1)]
-interface nsIGaiaChrome : nsISupports
-{
- void register();
-};
-
-%{ C++
-#define GAIACHROME_CONTRACTID "@mozilla.org/b2g/gaia-chrome;1"
-%}
diff --git a/b2g/components/nsISystemMessagesInternal.idl b/b2g/components/nsISystemMessagesInternal.idl
deleted file mode 100644
index 775ce0315..000000000
--- a/b2g/components/nsISystemMessagesInternal.idl
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "domstubs.idl"
-
-interface nsIURI;
-interface nsIDOMWindow;
-interface nsIMessageSender;
-
-// Implemented by the contract id @mozilla.org/system-message-internal;1
-
-[scriptable, uuid(59b6beda-f911-4d47-a296-8c81e6abcfb9)]
-interface nsISystemMessagesInternal : nsISupports
-{
- /*
- * Allow any internal user to send a message of a given type to a given page
- * of an app. The message will be sent to all the registered pages of the app
- * when |pageURI| is not specified.
- * @param type The type of the message to be sent.
- * @param message The message payload.
- * @param pageURI The URI of the page that will be opened. Nullable.
- * @param manifestURI The webapp's manifest URI.
- * @param extra Extra opaque information that will be passed around in the observer
- * notification to open the page.
- * returns a Promise
- */
- nsISupports sendMessage(in DOMString type, in jsval message,
- in nsIURI pageURI, in nsIURI manifestURI,
- [optional] in jsval extra);
-
- /*
- * Allow any internal user to broadcast a message of a given type.
- * The application that registers the message will be launched.
- * @param type The type of the message to be sent.
- * @param message The message payload.
- * @param extra Extra opaque information that will be passed around in the observer
- * notification to open the page.
- * returns a Promise
- */
- nsISupports broadcastMessage(in DOMString type, in jsval message,
- [optional] in jsval extra);
-
- /*
- * Registration of a page that wants to be notified of a message type.
- * @param type The message type.
- * @param pageURI The URI of the page that will be opened.
- * @param manifestURI The webapp's manifest URI.
- */
- void registerPage(in DOMString type, in nsIURI pageURI, in nsIURI manifestURI);
-};
diff --git a/b2g/components/test/mochitest/SandboxPromptTest.html b/b2g/components/test/mochitest/SandboxPromptTest.html
deleted file mode 100644
index 54f5fdd48..000000000
--- a/b2g/components/test/mochitest/SandboxPromptTest.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<html>
-<body>
-<script>
-
-var actions = [
- {
- permissions: ["video-capture"],
- action: function() {
- // invoke video-capture permission prompt
- navigator.mozGetUserMedia({video: true}, function () {}, function () {});
- }
- },
- {
- permissions: ["audio-capture", "video-capture"],
- action: function() {
- // invoke audio-capture + video-capture permission prompt
- navigator.mozGetUserMedia({audio: true, video: true}, function () {}, function () {});
- }
- },
- {
- permissions: ["audio-capture"],
- action: function() {
- // invoke audio-capture permission prompt
- navigator.mozGetUserMedia({audio: true}, function () {}, function () {});
- }
- },
- {
- permissions: ["geolocation"],
- action: function() {
- // invoke geolocation permission prompt
- navigator.geolocation.getCurrentPosition(function (pos) {});
- }
- },
- {
- permissions: ["desktop-notification"],
- action: function() {
- // invoke desktop-notification prompt
- Notification.requestPermission(function (perm) {});
- }
- },
-];
-
-// The requested permissions are specified in query string.
-var permissions = JSON.parse(decodeURIComponent(window.location.search.substring(1)));
-for (var i = 0; i < actions.length; i++) {
- if(permissions.length === actions[i].permissions.length &&
- permissions.every(function(permission) {
- return actions[i].permissions.indexOf(permission) >= 0;
- })) {
- actions[i].action();
- break;
- }
-}
-
-</script>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/filepicker_path_handler_chrome.js b/b2g/components/test/mochitest/filepicker_path_handler_chrome.js
deleted file mode 100644
index a175746cb..000000000
--- a/b2g/components/test/mochitest/filepicker_path_handler_chrome.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this file,
-* You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-
-// use ppmm to handle file-picker message.
-var ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1']
- .getService(Ci.nsIMessageListenerManager);
-
-var pickResult = null;
-
-function processPickMessage(message) {
- let sender = message.target.QueryInterface(Ci.nsIMessageSender);
- // reply FilePicker's message
- sender.sendAsyncMessage('file-picked', pickResult);
- // notify caller
- sendAsyncMessage('file-picked-posted', { type: 'file-picked-posted' });
-}
-
-function updatePickResult(result) {
- pickResult = result;
- sendAsyncMessage('pick-result-updated', { type: 'pick-result-updated' });
-}
-
-ppmm.addMessageListener('file-picker', processPickMessage);
-// use update-pick-result to change the expected pick result.
-addMessageListener('update-pick-result', updatePickResult);
diff --git a/b2g/components/test/mochitest/mochitest.ini b/b2g/components/test/mochitest/mochitest.ini
deleted file mode 100644
index 97df32ea2..000000000
--- a/b2g/components/test/mochitest/mochitest.ini
+++ /dev/null
@@ -1,28 +0,0 @@
-[DEFAULT]
-support-files =
- permission_handler_chrome.js
- SandboxPromptTest.html
- filepicker_path_handler_chrome.js
- screenshot_helper.js
- systemapp_helper.js
- presentation_prompt_handler_chrome.js
- presentation_ui_glue_handler_chrome.js
-
-[test_filepicker_path.html]
-skip-if = toolkit != "gonk"
-[test_permission_deny.html]
-skip-if = toolkit != "gonk"
-[test_permission_gum_remember.html]
-skip-if = true # Bug 1019572 - frequent timeouts
-[test_sandbox_permission.html]
-skip-if = toolkit != "gonk"
-[test_screenshot.html]
-skip-if = toolkit != "gonk"
-[test_systemapp.html]
-skip-if = toolkit != "gonk"
-[test_presentation_device_prompt.html]
-skip-if = toolkit != "gonk"
-[test_permission_visibilitychange.html]
-skip-if = toolkit != "gonk"
-[test_presentation_request_ui_glue.html]
-skip-if = toolkit != "gonk"
diff --git a/b2g/components/test/mochitest/permission_handler_chrome.js b/b2g/components/test/mochitest/permission_handler_chrome.js
deleted file mode 100644
index 9bf3e7819..000000000
--- a/b2g/components/test/mochitest/permission_handler_chrome.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-function debug(str) {
- dump("CHROME PERMISSON HANDLER -- " + str + "\n");
-}
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-const { Services } = Cu.import("resource://gre/modules/Services.jsm");
-const { SystemAppProxy } = Cu.import("resource://gre/modules/SystemAppProxy.jsm");
-
-var eventHandler = function(evt) {
- if (!evt.detail || evt.detail.type !== "permission-prompt") {
- return;
- }
-
- sendAsyncMessage("permission-request", evt.detail);
-};
-
-SystemAppProxy.addEventListener("mozChromeEvent", eventHandler);
-
-// need to remove ChromeEvent listener after test finished.
-addMessageListener("teardown", function() {
- SystemAppProxy.removeEventListener("mozChromeEvent", eventHandler);
-});
-
-addMessageListener("permission-response", function(detail) {
- SystemAppProxy._sendCustomEvent('mozContentEvent', detail);
-});
-
diff --git a/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js b/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js
deleted file mode 100644
index 4407e58d2..000000000
--- a/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-'use strict';
-
- function debug(str) {
- dump('presentation_prompt_handler_chrome: ' + str + '\n');
- }
-
-var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
-
-const manager = Cc["@mozilla.org/presentation-device/manager;1"]
- .getService(Ci.nsIPresentationDeviceManager);
-
-const prompt = Cc['@mozilla.org/presentation-device/prompt;1']
- .getService(Ci.nsIPresentationDevicePrompt);
-
-function TestPresentationDevice(options) {
- this.id = options.id;
- this.name = options.name;
- this.type = options.type;
-}
-
-TestPresentationDevice.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
- establishSessionTransport: function() {
- return null;
- },
-};
-
-function TestPresentationRequest(options) {
- this.origin = options.origin;
- this.requestURL = options.requestURL;
-}
-
-TestPresentationRequest.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceRequest]),
- select: function(device) {
- let result = {
- type: 'select',
- device: {
- id: device.id,
- name: device.name,
- type: device.type,
- },
- };
- sendAsyncMessage('presentation-select-result', result);
- },
- cancel: function() {
- let result = {
- type: 'cancel',
- };
- sendAsyncMessage('presentation-select-result', result);
- },
-};
-
-var testDevice = null;
-
-addMessageListener('setup', function(device_options) {
- testDevice = new TestPresentationDevice(device_options);
- manager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(testDevice);
- sendAsyncMessage('setup-complete');
-});
-
-var eventHandler = function(evt) {
- if (!evt.detail || evt.detail.type !== 'presentation-select-device') {
- return;
- }
-
- sendAsyncMessage('presentation-select-device', evt.detail);
-};
-
-SystemAppProxy.addEventListener('mozChromeEvent', eventHandler);
-
-// need to remove ChromeEvent listener after test finished.
-addMessageListener('teardown', function() {
- if (testDevice) {
- manager.removeDevice(testDevice);
- }
- SystemAppProxy.removeEventListener('mozChromeEvent', eventHandler);
-});
-
-addMessageListener('trigger-device-prompt', function(request_options) {
- let request = new TestPresentationRequest(request_options);
- prompt.promptDeviceSelection(request);
-});
-
-addMessageListener('presentation-select-response', function(detail) {
- SystemAppProxy._sendCustomEvent('mozContentEvent', detail);
-});
-
diff --git a/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js b/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js
deleted file mode 100644
index fac16db6c..000000000
--- a/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-'use strict';
-
-var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
-
-const glue = Cc["@mozilla.org/presentation/requestuiglue;1"]
- .createInstance(Ci.nsIPresentationRequestUIGlue);
-
-SystemAppProxy.addEventListener('mozPresentationChromeEvent', function(aEvent) {
- if (!aEvent.detail || aEvent.detail.type !== 'presentation-launch-receiver') {
- return;
- }
- sendAsyncMessage('presentation-launch-receiver', aEvent.detail);
-});
-
-addMessageListener('trigger-ui-glue', function(aData) {
- var promise = glue.sendRequest(aData.url, aData.sessionId);
- promise.then(function(aFrame) {
- sendAsyncMessage('iframe-resolved', aFrame);
- }).catch(function() {
- sendAsyncMessage('iframe-rejected');
- });
-});
-
-addMessageListener('trigger-presentation-content-event', function(aDetail) {
- SystemAppProxy._sendCustomEvent('mozPresentationContentEvent', aDetail);
-});
diff --git a/b2g/components/test/mochitest/screenshot_helper.js b/b2g/components/test/mochitest/screenshot_helper.js
deleted file mode 100644
index 0320a14c1..000000000
--- a/b2g/components/test/mochitest/screenshot_helper.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var Cu = Components.utils;
-var Ci = Components.interfaces;
-
-Cu.importGlobalProperties(['File']);
-
-const { Services } = Cu.import("resource://gre/modules/Services.jsm");
-
-// Load a duplicated copy of the jsm to prevent messing with the currently running one
-var scope = {};
-Services.scriptloader.loadSubScript("resource://gre/modules/Screenshot.jsm", scope);
-const { Screenshot } = scope;
-
-var index = -1;
-function next() {
- index++;
- if (index >= steps.length) {
- assert.ok(false, "Shouldn't get here!");
- return;
- }
- try {
- steps[index]();
- } catch(ex) {
- assert.ok(false, "Caught exception: " + ex);
- }
-}
-
-var steps = [
- function getScreenshot() {
- let screenshot = Screenshot.get();
- assert.ok(screenshot instanceof File,
- "Screenshot.get() returns a File");
- next();
- },
-
- function endOfTest() {
- sendAsyncMessage("finish");
- }
-];
-
-next();
diff --git a/b2g/components/test/mochitest/systemapp_helper.js b/b2g/components/test/mochitest/systemapp_helper.js
deleted file mode 100644
index 768b221fe..000000000
--- a/b2g/components/test/mochitest/systemapp_helper.js
+++ /dev/null
@@ -1,173 +0,0 @@
-var Cu = Components.utils;
-
-const { Services } = Cu.import("resource://gre/modules/Services.jsm");
-
-// Load a duplicated copy of the jsm to prevent messing with the currently running one
-var scope = {};
-Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm", scope);
-const { SystemAppProxy } = scope;
-
-var frame;
-var customEventTarget;
-
-var index = -1;
-function next() {
- index++;
- if (index >= steps.length) {
- assert.ok(false, "Shouldn't get here!");
- return;
- }
- try {
- steps[index]();
- } catch(ex) {
- assert.ok(false, "Caught exception: " + ex);
- }
-}
-
-// Listen for events received by the system app document
-// to ensure that we receive all of them, in an expected order and time
-var isLoaded = false;
-var isReady = false;
-var n = 0;
-function listener(event) {
- if (!isLoaded) {
- assert.ok(false, "Received event before the iframe is loaded");
- return;
- }
- n++;
- if (n == 1) {
- assert.equal(event.type, "mozChromeEvent");
- assert.equal(event.detail.name, "first");
- } else if (n == 2) {
- assert.equal(event.type, "custom");
- assert.equal(event.detail.name, "second");
-
- next(); // call checkEventPendingBeforeLoad
- } else if (n == 3) {
- if (!isReady) {
- assert.ok(false, "Received event before the iframe is loaded");
- return;
- }
-
- assert.equal(event.type, "custom");
- assert.equal(event.detail.name, "third");
- } else if (n == 4) {
- if (!isReady) {
- assert.ok(false, "Received event before the iframe is loaded");
- return;
- }
-
- assert.equal(event.type, "mozChromeEvent");
- assert.equal(event.detail.name, "fourth");
-
- next(); // call checkEventDispatching
- } else if (n == 5) {
- assert.equal(event.type, "custom");
- assert.equal(event.detail.name, "fifth");
- } else if (n === 6) {
- assert.equal(event.type, "mozChromeEvent");
- assert.equal(event.detail.name, "sixth");
- } else if (n === 7) {
- assert.equal(event.type, "custom");
- assert.equal(event.detail.name, "seventh");
- assert.equal(event.target, customEventTarget);
-
- next(); // call checkEventListening();
- } else {
- assert.ok(false, "Unexpected event of type " + event.type);
- }
-}
-
-
-var steps = [
- function earlyEvents() {
- // Immediately try to send events
- SystemAppProxy._sendCustomEvent("mozChromeEvent", { name: "first" }, true);
- SystemAppProxy._sendCustomEvent("custom", { name: "second" }, true);
- next();
- },
-
- function createFrame() {
- // Create a fake system app frame
- let win = Services.wm.getMostRecentWindow("navigator:browser");
- let doc = win.document;
- frame = doc.createElement("iframe");
- doc.documentElement.appendChild(frame);
-
- customEventTarget = frame.contentDocument.body;
-
- // Ensure that events are correctly sent to the frame.
- // `listener` is going to call next()
- frame.contentWindow.addEventListener("mozChromeEvent", listener);
- frame.contentWindow.addEventListener("custom", listener);
-
- // Ensure that listener being registered before the system app is ready
- // are correctly removed from the pending list
- function removedListener() {
- assert.ok(false, "Listener isn't correctly removed from the pending list");
- }
- 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);
- 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
- });
-
- 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" });
- SystemAppProxy.dispatchEvent({ name: "fourth" });
-
- isReady = true;
- SystemAppProxy.setIsReady();
- // Once this 4th event is received, we will run checkEventDispatching
- },
-
- function checkEventDispatching() {
- // Send events after the iframe is ready,
- // they should be dispatched right away
- SystemAppProxy._sendCustomEvent("custom", { name: "fifth" });
- SystemAppProxy.dispatchEvent({ name: "sixth" });
- SystemAppProxy._sendCustomEvent("custom", { name: "seventh" }, false, customEventTarget);
- // Once this 7th event is received, we will run checkEventListening
- },
-
- function checkEventListening() {
- SystemAppProxy.addEventListener("mozContentEvent", function onContentEvent(event) {
- assert.equal(event.detail.name, "first-content", "received a system app event");
- SystemAppProxy.removeEventListener("mozContentEvent", onContentEvent);
-
- next();
- });
- let win = frame.contentWindow;
- win.dispatchEvent(new win.CustomEvent("mozContentEvent", { detail: {name: "first-content"} }));
- },
-
- function endOfTest() {
- frame.remove();
- sendAsyncMessage("finish");
- }
-];
-
-next();
diff --git a/b2g/components/test/mochitest/test_filepicker_path.html b/b2g/components/test/mochitest/test_filepicker_path.html
deleted file mode 100644
index 92c00dc68..000000000
--- a/b2g/components/test/mochitest/test_filepicker_path.html
+++ /dev/null
@@ -1,130 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=949944
--->
-<head>
-<meta charset="utf-8">
-<title>Permission Prompt Test</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body onload="processTestCase()">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=949944"> [B2G][Helix][Browser][Wallpaper] use new File([blob], filename) to return a blob with filename when picking</a>
-<script type="application/javascript">
-
-'use strict';
-
-var testCases = [
- // case 1: returns blob with name
- { pickedResult: { success: true,
- result: {
- type: 'text/plain',
- blob: new Blob(['1234567890'],
- { type: 'text/plain' }),
- name: 'test1.txt'
- }
- },
- fileName: 'test1.txt' },
- // case 2: returns blob without name
- { pickedResult: { success: true,
- result: {
- type: 'text/plain',
- blob: new Blob(['1234567890'],
- { type: 'text/plain' })
- }
- },
- fileName: 'blob.txt' },
- // case 3: returns blob with full path name
- { pickedResult: { success: true,
- result: {
- type: 'text/plain',
- blob: new Blob(['1234567890'],
- { type: 'text/plain' }),
- name: '/full/path/test3.txt'
- }
- },
- fileName: 'test3.txt' },
- // case 4: returns blob relative path name
- { pickedResult: { success: true,
- result: {
- type: 'text/plain',
- blob: new Blob(['1234567890'],
- { type: 'text/plain' }),
- name: 'relative/path/test4.txt'
- }
- },
- fileName: 'test4.txt' },
- // case 5: returns file with name
- { pickedResult: { success: true,
- result: {
- type: 'text/plain',
- blob: new File(['1234567890'],
- 'useless-name.txt',
- { type: 'text/plain' }),
- name: 'test5.txt'
- }
- },
- fileName: 'test5.txt'},
- // case 6: returns file without name. This case may fail because we
- // need to make sure the File can be sent through
- // sendAsyncMessage API.
- { pickedResult: { success: true,
- result: {
- type: 'text/plain',
- blob: new File(['1234567890'],
- 'test6.txt',
- { type: 'text/plain' })
- }
- },
- fileName: 'test6.txt'}
-];
-
-var chromeJS = SimpleTest.getTestFileURL('filepicker_path_handler_chrome.js');
-var chromeScript = SpecialPowers.loadChromeScript(chromeJS);
-var activeTestCase;
-
-chromeScript.addMessageListener('pick-result-updated', handleMessage);
-chromeScript.addMessageListener('file-picked-posted', handleMessage);
-
-// handle messages returned from chromeScript
-function handleMessage(data) {
- var fileInput = document.getElementById('fileInput');
- switch (data.type) {
- case 'pick-result-updated':
- fileInput.click();
- break;
- case 'file-picked-posted':
- is(fileInput.value, activeTestCase.fileName,
- 'File should be able to send through message.');
- processTestCase();
- break;
- }
-}
-
-function processTestCase() {
- if (!testCases.length) {
- SimpleTest.finish();
- return;
- }
- activeTestCase = testCases.shift();
- var expectedResult = activeTestCase.pickedResult;
- if (navigator.userAgent.indexOf('Windows') > -1 &&
- expectedResult.result.name) {
- // If we run at a window box, we need to translate the path from '/' to '\\'
- var name = expectedResult.result.name;
- name = name.replace('/', '\\');
- // If the name is an absolute path, we need to prepend drive letter.
- if (name.startsWith('\\')) {
- name = 'C:' + name;
- }
- // update the expected name.
- expectedResult.result.name = name
- }
- chromeScript.sendAsyncMessage('update-pick-result', expectedResult);
-}
-
-</script>
-<input type="file" id="fileInput">
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_permission_deny.html b/b2g/components/test/mochitest/test_permission_deny.html
deleted file mode 100644
index 29c35bdec..000000000
--- a/b2g/components/test/mochitest/test_permission_deny.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=981113
--->
-<head>
- <meta charset="utf-8">
- <title>Permission Deny Test</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=981113">Test Permission Deny</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
-
-var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js');
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-var gTests = [
- {
- 'video': true,
- },
- {
- 'audio': true,
- 'video': true,
- },
- {
- 'audio': true,
- },
-];
-
-function runNext() {
- if (gTests.length > 0) {
- // Put the requested permission in query string
- let requestedType = gTests.shift();
- info('getUserMedia for ' + JSON.stringify(requestedType));
- navigator.mozGetUserMedia(requestedType, function success() {
- ok(false, 'unexpected success, permission request should be denied');
- runNext();
- }, function failure(err) {
- is(err.name, 'SecurityError', 'expected permission denied');
- runNext();
- });
- } else {
- info('test finished, teardown');
- gScript.sendAsyncMessage('teardown', '');
- gScript.destroy();
- SimpleTest.finish();
- }
-}
-
-gScript.addMessageListener('permission-request', function(detail) {
- let response = {
- id: detail.id,
- type: 'permission-deny',
- remember: false,
- };
- gScript.sendAsyncMessage('permission-response', response);
-});
-
-// Need to change camera permission from ALLOW to PROMPT, otherwise
-// MediaManager will automatically allow video-only gUM request.
-SpecialPowers.pushPermissions([
- {type: 'video-capture', allow: PROMPT_ACTION, context: document},
- {type: 'audio-capture', allow: PROMPT_ACTION, context: document},
- {type: 'camera', allow: PROMPT_ACTION, context: document},
- ], function() {
- SpecialPowers.pushPrefEnv({
- 'set': [
- ['media.navigator.permission.disabled', false],
- ]
- }, runNext);
- }
-);
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_permission_gum_remember.html b/b2g/components/test/mochitest/test_permission_gum_remember.html
deleted file mode 100644
index 1ebfea1ca..000000000
--- a/b2g/components/test/mochitest/test_permission_gum_remember.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=978660
--->
-<head>
- <meta charset="utf-8">
- <title>gUM Remember Permission Test</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978660">Test remembering gUM Permission</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
-
-var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js');
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-gScript.addMessageListener('permission-request', function(detail) {
- ok(false, 'unexpected mozChromeEvent for permission prompt');
- let response = {
- id: detail.id,
- type: 'permission-deny',
- remember: false,
- };
- gScript.sendAsyncMessage('permission-response', response);
-});
-
-var gTests = [
- {
- 'audio': true,
- 'video': {facingMode: 'environment', required: ['facingMode']},
- },
- {
- 'video': {facingMode: 'environment', required: ['facingMode']},
- },
- {
- 'audio': true,
- },
-];
-
-function testGranted() {
- info('test remember permission granted');
- return new Promise(function(resolve, reject) {
- let steps = [].concat(gTests);
- function nextStep() {
- if (steps.length > 0) {
- let requestedType = steps.shift();
- info('getUserMedia for ' + JSON.stringify(requestedType));
- navigator.mozGetUserMedia(requestedType, function success(stream) {
- ok(true, 'expected gUM success');
- stream.stop();
- nextStep();
- }, function failure(err) {
- ok(false, 'unexpected gUM fail: ' + err);
- nextStep();
- });
- } else {
- resolve();
- }
- }
-
- SpecialPowers.pushPermissions([
- {type: 'video-capture', allow: true, context: document},
- {type: 'audio-capture', allow: true, context: document},
- ], nextStep);
- });
-}
-
-function testDenied() {
- info('test remember permission denied');
- return new Promise(function(resolve, reject) {
- let steps = [].concat(gTests);
- function nextStep() {
- if (steps.length > 0) {
- let requestedType = steps.shift();
- info('getUserMedia for ' + JSON.stringify(requestedType));
- navigator.mozGetUserMedia(requestedType, function success(stream) {
- ok(false, 'unexpected gUM success');
- stream.stop();
- nextStep();
- }, function failure(err) {
- ok(true, 'expected gUM fail: ' + err);
- nextStep();
- });
- } else {
- resolve();
- }
- }
-
- SpecialPowers.pushPermissions([
- {type: 'video-capture', allow: false, context: document},
- {type: 'audio-capture', allow: false, context: document},
- ], nextStep);
- });
-}
-
-function testPartialDeniedAudio() {
- info('test remember permission partial denied: audio');
- return new Promise(function(resolve, reject) {
- info('getUserMedia for video and audio');
- function nextStep() {
- navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']},
- audio: true}, function success(stream) {
- ok(false, 'unexpected gUM success');
- stream.stop();
- resolve();
- }, function failure(err) {
- ok(true, 'expected gUM fail: ' + err);
- resolve();
- });
- }
-
- SpecialPowers.pushPermissions([
- {type: 'video-capture', allow: true, context: document},
- {type: 'audio-capture', allow: false, context: document},
- ], nextStep);
- });
-}
-
-function testPartialDeniedVideo() {
- info('test remember permission partial denied: video');
- return new Promise(function(resolve, reject) {
- info('getUserMedia for video and audio');
- function nextStep() {
- navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']},
- audio: true}, function success(stream) {
- ok(false, 'unexpected gUM success');
- stream.stop();
- resolve();
- }, function failure(err) {
- ok(true, 'expected gUM fail: ' + err);
- resolve();
- });
- }
-
- SpecialPowers.pushPermissions([
- {type: 'video-capture', allow: false, context: document},
- {type: 'audio-capture', allow: true, context: document},
- ], nextStep);
- });
-}
-
-function runTests() {
- testGranted()
- .then(testDenied)
- .then(testPartialDeniedAudio)
- .then(testPartialDeniedVideo)
- .then(function() {
- info('test finished, teardown');
- gScript.sendAsyncMessage('teardown', '');
- gScript.destroy();
- SimpleTest.finish();
- });
-}
-
-SpecialPowers.pushPrefEnv({
- 'set': [
- ['media.navigator.permission.disabled', false],
- ]
-}, runTests);
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_permission_visibilitychange.html b/b2g/components/test/mochitest/test_permission_visibilitychange.html
deleted file mode 100644
index cd5694b42..000000000
--- a/b2g/components/test/mochitest/test_permission_visibilitychange.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=951997
--->
-<head>
- <meta charset="utf-8">
- <title>Permission Prompt Test</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1020179">Permission prompt visibilitychange test</a>
-<script type="application/javascript;version=1.8">
-
-"use strict";
-
-var gUrl = SimpleTest.getTestFileURL("permission_handler_chrome.js");
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-
-function testDone() {
- gScript.sendAsyncMessage("teardown", "");
- gScript.destroy();
- SimpleTest.finish();
- alert("setVisible::true");
-}
-
-function runTest() {
- navigator.geolocation.getCurrentPosition(
- function (pos) {
- ok(false, "unexpected success, permission request should be canceled");
- testDone();
- }, function (err) {
- ok(true, "success, permission request is canceled");
- testDone();
- });
-}
-
-gScript.addMessageListener("permission-request", function (detail) {
- info("got permission-request!!!!\n");
- alert("setVisible::false");
-});
-
-// Add permissions to this app. We use ALLOW_ACTION here. The ContentPermissionPrompt
-// should prompt for permission, not allow it without prompt.
-SpecialPowers.pushPrefEnv({"set": [["media.navigator.permission.disabled", false]]},
- function() {
- SpecialPowers.addPermission("geolocation",
- SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION, document);
- runTest();
- });
-
-SimpleTest.waitForExplicitFinish();
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_presentation_device_prompt.html b/b2g/components/test/mochitest/test_presentation_device_prompt.html
deleted file mode 100644
index 9feeca795..000000000
--- a/b2g/components/test/mochitest/test_presentation_device_prompt.html
+++ /dev/null
@@ -1,145 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-<head>
- <meta charset="utf-8">
- <title>Test for Presentation Device Selection</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Test for Presentation Device Selection</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-var contentEventHandler = null;
-
-var gUrl = SimpleTest.getTestFileURL('presentation_prompt_handler_chrome.js');
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-
-function testSetup() {
- info('setup for device selection');
- return new Promise(function(resolve, reject) {
- let device = {
- id: 'test-id',
- name: 'test-name',
- type: 'test-type',
- };
- gScript.addMessageListener('setup-complete', function() {
- resolve(device);
- });
- gScript.sendAsyncMessage('setup', device);
- });
-}
-
-function testSelected(device) {
- info('test device selected by user');
- return new Promise(function(resolve, reject) {
- let request = {
- origin: 'test-origin',
- requestURL: 'test-requestURL',
- };
-
- gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
- gScript.removeMessageListener('presentation-select-device', contentEventHandler);
- ok(true, 'receive user prompt for device selection');
- is(detail.origin, request.origin, 'expected origin');
- is(detail.requestURL, request.requestURL, 'expected requestURL');
- let response = {
- id: detail.id,
- type: 'presentation-select-result',
- deviceId: device.id,
- };
- gScript.sendAsyncMessage('presentation-select-response', response);
-
- gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
- gScript.removeMessageListener('presentation-select-result', resultHandler);
- is(result.type, 'select', 'expect device selected');
- is(result.device.id, device.id, 'expected device id');
- is(result.device.name, device.name, 'expected device name');
- is(result.device.type, device.type, 'expected devcie type');
- resolve();
- });
- });
-
- gScript.sendAsyncMessage('trigger-device-prompt', request);
- });
-}
-
-function testSelectedNotExisted() {
- info('test selected device doesn\'t exist');
- return new Promise(function(resolve, reject) {
- gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
- gScript.removeMessageListener('presentation-select-device', contentEventHandler);
- ok(true, 'receive user prompt for device selection');
- let response = {
- id: detail.id,
- type: 'presentation-select-deny',
- deviceId: undefined, // simulate device Id that doesn't exist
- };
- gScript.sendAsyncMessage('presentation-select-response', response);
-
- gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
- gScript.removeMessageListener('presentation-select-result', resultHandler);
- is(result.type, 'cancel', 'expect user cancel');
- resolve();
- });
- });
-
- let request = {
- origin: 'test-origin',
- requestURL: 'test-requestURL',
- };
- gScript.sendAsyncMessage('trigger-device-prompt', request);
- });
-}
-
-function testDenied() {
- info('test denial of device selection');
- return new Promise(function(resolve, reject) {
- gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
- gScript.removeMessageListener('presentation-select-device', contentEventHandler);
- ok(true, 'receive user prompt for device selection');
- let response = {
- id: detail.id,
- type: 'presentation-select-deny',
- };
- gScript.sendAsyncMessage('presentation-select-response', response);
-
- gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
- gScript.removeMessageListener('presentation-select-result', resultHandler);
- is(result.type, 'cancel', 'expect user cancel');
- resolve();
- });
- });
-
- let request = {
- origin: 'test-origin',
- requestURL: 'test-requestURL',
- };
- gScript.sendAsyncMessage('trigger-device-prompt', request);
- });
-}
-
-function runTests() {
- testSetup()
- .then(testSelected)
- .then(testSelectedNotExisted)
- .then(testDenied)
- .then(function() {
- info('test finished, teardown');
- gScript.sendAsyncMessage('teardown');
- gScript.destroy();
- SimpleTest.finish();
- });
-}
-
-window.addEventListener('load', runTests);
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_presentation_request_ui_glue.html b/b2g/components/test/mochitest/test_presentation_request_ui_glue.html
deleted file mode 100644
index 29ac37221..000000000
--- a/b2g/components/test/mochitest/test_presentation_request_ui_glue.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-<head>
- <meta charset="utf-8">
- <title>Test for Presentation UI Glue</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Test for Presentation UI Glue</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('presentation_ui_glue_handler_chrome.js'));
-
-var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
- .getService(SpecialPowers.Ci.nsIObserverService);
-
-var url = 'http://example.com';
-var sessionId = 'sessionId';
-
-function testLaunchReceiver() {
- return new Promise(function(aResolve, aReject) {
- gScript.addMessageListener('presentation-launch-receiver', function launchReceiverHandler(aDetail) {
- gScript.removeMessageListener('presentation-launch-receiver', launchReceiverHandler);
- ok(true, "A presentation-launch-receiver mozPresentationChromeEvent should be received.");
- is(aDetail.url, url, "Url should be the same.");
- is(aDetail.id, sessionId, "Session ID should be the same.");
-
- aResolve();
- });
-
- gScript.sendAsyncMessage('trigger-ui-glue',
- { url: url,
- sessionId : sessionId });
- });
-}
-
-function testReceiverLaunched() {
- return new Promise(function(aResolve, aReject) {
- gScript.addMessageListener('iframe-resolved', function iframeResolvedHandler(aFrame) {
- gScript.removeMessageListener('iframe-resolved', iframeResolvedHandler);
- ok(true, "The promise should be resolved.");
-
- aResolve();
- });
-
- var iframe = document.createElement('iframe');
- iframe.setAttribute('remote', 'true');
- iframe.setAttribute('mozbrowser', 'true');
- iframe.setAttribute('src', 'http://example.com');
- document.body.appendChild(iframe);
-
- gScript.sendAsyncMessage('trigger-presentation-content-event',
- { type: 'presentation-receiver-launched',
- id: sessionId,
- frame: iframe });
- });
-}
-
-function testLaunchError() {
- return new Promise(function(aResolve, aReject) {
- gScript.addMessageListener('presentation-launch-receiver', function launchReceiverHandler(aDetail) {
- gScript.removeMessageListener('presentation-launch-receiver', launchReceiverHandler);
- ok(true, "A presentation-launch-receiver mozPresentationChromeEvent should be received.");
- is(aDetail.url, url, "Url should be the same.");
- is(aDetail.id, sessionId, "Session ID should be the same.");
-
- gScript.addMessageListener('iframe-rejected', function iframeRejectedHandler() {
- gScript.removeMessageListener('iframe-rejected', iframeRejectedHandler);
- ok(true, "The promise should be rejected.");
- aResolve();
- });
-
- gScript.sendAsyncMessage('trigger-presentation-content-event',
- { type: 'presentation-receiver-permission-denied',
- id: sessionId });
- });
-
- gScript.sendAsyncMessage('trigger-ui-glue',
- { url: url,
- sessionId : sessionId });
- });
-}
-
-function runTests() {
- testLaunchReceiver()
- .then(testReceiverLaunched)
- .then(testLaunchError)
- .then(function() {
- info('test finished, teardown');
- gScript.destroy();
- SimpleTest.finish();
- });
-}
-
-window.addEventListener('load', runTests);
-</script>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_sandbox_permission.html b/b2g/components/test/mochitest/test_sandbox_permission.html
deleted file mode 100644
index cd13599a3..000000000
--- a/b2g/components/test/mochitest/test_sandbox_permission.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=951997
--->
-<head>
- <meta charset="utf-8">
- <title>Permission Prompt Test</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=951997">Permission prompt web content test</a>
-<script type="application/javascript;version=1.8">
-
-"use strict";
-
-const APP_URL = "SandboxPromptTest.html";
-
-var iframe;
-var gUrl = SimpleTest.getTestFileURL("permission_handler_chrome.js");
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-var gResult = [
- {
- "video-capture": ["back"],
- },
- {
- "audio-capture": [""],
- "video-capture": ["back"],
- },
- {
- "audio-capture": [""],
- },
- {
- "geolocation": [],
- },
- {
- "desktop-notification": [],
- }
-];
-
-function runNext() {
- if (gResult.length > 0) {
- // Put the requested permission in query string
- let requestedPermission = JSON.stringify(Object.keys(gResult[0]));
- info('request permissions for ' + requestedPermission);
- iframe.src = APP_URL + '?' + encodeURIComponent(requestedPermission);
- } else {
- info('test finished, teardown');
- gScript.sendAsyncMessage("teardown", "");
- gScript.destroy();
- SimpleTest.finish();
- }
-}
-
-// 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);
- runNext();
- });
-}
-
-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");
-
- for (let type of permissionTypes) {
- ok(expectedValue.hasOwnProperty(type), "expected permission type");
- for (let i in permissions[type]) {
- is(permissions[type][i], expectedValue[type][i], "expected permission option");
- }
- }
- runNext();
-});
-
-// Add permissions to this app. We use ALLOW_ACTION here. The ContentPermissionPrompt
-// should prompt for permission, not allow it without prompt.
-SpecialPowers.pushPrefEnv({"set": [["media.navigator.permission.disabled", false]]},
- function() {
- SpecialPowers.addPermission('video-capture',
- SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
- SpecialPowers.addPermission('audio-capture',
- SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
- SpecialPowers.addPermission('geolocation',
- SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
- SpecialPowers.addPermission('desktop-notification',
- SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
- loadBrowser();
- });
-
-SimpleTest.waitForExplicitFinish();
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_screenshot.html b/b2g/components/test/mochitest/test_screenshot.html
deleted file mode 100644
index d2eeb8d48..000000000
--- a/b2g/components/test/mochitest/test_screenshot.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1136784
--->
-<head>
- <meta charset="utf-8">
- <title>Screenshot Test</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1136784">Screenshot.jsm</a>
-<script type="application/javascript">
-
-"use strict";
-
-var gUrl = SimpleTest.getTestFileURL("screenshot_helper.js");
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-
-SimpleTest.waitForExplicitFinish();
-gScript.addMessageListener("finish", function () {
- SimpleTest.ok(true, "chrome test script finished");
- gScript.destroy();
- SimpleTest.finish();
-});
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/mochitest/test_systemapp.html b/b2g/components/test/mochitest/test_systemapp.html
deleted file mode 100644
index 450094a50..000000000
--- a/b2g/components/test/mochitest/test_systemapp.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=963239
--->
-<head>
- <meta charset="utf-8">
- <title>SystemAppProxy Test</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=963239">SystemAppProxy.jsm</a>
-<script type="application/javascript">
-
-"use strict";
-
-var gUrl = SimpleTest.getTestFileURL("systemapp_helper.js");
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-
-SimpleTest.waitForExplicitFinish();
-gScript.addMessageListener("finish", function () {
- SimpleTest.ok(true, "chrome test script finished");
- gScript.destroy();
- SimpleTest.finish();
-});
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/b2g/components/test/moz.build b/b2g/components/test/moz.build
deleted file mode 100644
index 387e3b811..000000000
--- a/b2g/components/test/moz.build
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
-MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini']
diff --git a/b2g/components/test/unit/data/test_logger_file b/b2g/components/test/unit/data/test_logger_file
deleted file mode 100644
index b1ed7f10a..000000000
--- a/b2g/components/test/unit/data/test_logger_file
+++ /dev/null
Binary files differ
diff --git a/b2g/components/test/unit/head_identity.js b/b2g/components/test/unit/head_identity.js
deleted file mode 100644
index 604a77284..000000000
--- a/b2g/components/test/unit/head_identity.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-// The following boilerplate makes sure that XPCOM calls
-// that use the profile directory work.
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService",
- "resource://gre/modules/identity/MinimalIdentity.jsm",
- "IdentityService");
-
-XPCOMUtils.defineLazyModuleGetter(this,
- "Logger",
- "resource://gre/modules/identity/LogUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this,
- "uuidGenerator",
- "@mozilla.org/uuid-generator;1",
- "nsIUUIDGenerator");
-
-const TEST_URL = "https://myfavoriteflan.com";
-const TEST_USER = "uumellmahaye1969@hotmail.com";
-const TEST_PRIVKEY = "i-am-a-secret";
-const TEST_CERT = "i~like~pie";
-
-// The following are utility functions for Identity testing
-
-function log(...aMessageArgs) {
- Logger.log.apply(Logger, ["test"].concat(aMessageArgs));
-}
-
-function partial(fn) {
- let args = Array.prototype.slice.call(arguments, 1);
- return function() {
- return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
- };
-}
-
-function uuid() {
- return uuidGenerator.generateUUID().toString();
-}
-
-// create a mock "doc" object, which the Identity Service
-// uses as a pointer back into the doc object
-function mockDoc(aParams, aDoFunc) {
- let mockedDoc = {};
- mockedDoc.id = uuid();
-
- // Properties of aParams may include loggedInUser
- Object.keys(aParams).forEach(function(param) {
- mockedDoc[param] = aParams[param];
- });
-
- // the origin is set inside nsDOMIdentity by looking at the
- // document.nodePrincipal.origin. Here we, we must satisfy
- // ourselves with pretending.
- mockedDoc.origin = "https://jedp.gov";
-
- mockedDoc['do'] = aDoFunc;
- mockedDoc.doReady = partial(aDoFunc, 'ready');
- mockedDoc.doLogin = partial(aDoFunc, 'login');
- mockedDoc.doLogout = partial(aDoFunc, 'logout');
- mockedDoc.doError = partial(aDoFunc, 'error');
- mockedDoc.doCancel = partial(aDoFunc, 'cancel');
- mockedDoc.doCoffee = partial(aDoFunc, 'coffee');
-
- return mockedDoc;
-}
-
-// create a mock "pipe" object that would normally communicate
-// messages up to gaia (either the trusty ui or the hidden iframe),
-// and convey messages back down from gaia to the controller through
-// the message callback.
-
-// The mock receiving pipe simulates gaia which, after receiving messages
-// through the pipe, will call back with instructions to invoke
-// certain methods. It mocks what comes back from the other end of
-// the pipe.
-function mockReceivingPipe() {
- let MockedPipe = {
- communicate: function(aRpOptions, aGaiaOptions, aMessageCallback) {
- switch (aGaiaOptions.message) {
- case "identity-delegate-watch":
- aMessageCallback({json: {method: "ready"}});
- break;
- case "identity-delegate-request":
- aMessageCallback({json: {method: "login", assertion: TEST_CERT}});
- break;
- case "identity-delegate-logout":
- aMessageCallback({json: {method: "logout"}});
- break;
- default:
- throw("what the what?? " + aGaiaOptions.message);
- break;
- }
- }
- };
- return MockedPipe;
-}
-
-// The mock sending pipe lets us test what's actually getting put in the
-// pipe.
-function mockSendingPipe(aMessageCallback) {
- let MockedPipe = {
- communicate: function(aRpOptions, aGaiaOptions, aDummyCallback) {
- aMessageCallback(aRpOptions, aGaiaOptions);
- }
- };
- return MockedPipe;
-}
-
-// mimicking callback funtionality for ease of testing
-// this observer auto-removes itself after the observe function
-// is called, so this is meant to observe only ONE event.
-function makeObserver(aObserveTopic, aObserveFunc) {
- let observer = {
- // nsISupports provides type management in C++
- // nsIObserver is to be an observer
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
-
- observe: function (aSubject, aTopic, aData) {
- if (aTopic == aObserveTopic) {
- Services.obs.removeObserver(observer, aObserveTopic);
- aObserveFunc(aSubject, aTopic, aData);
- }
- }
- };
-
- Services.obs.addObserver(observer, aObserveTopic, false);
-}
-
-// a hook to set up the ID service with an identity with keypair and all
-// when ready, invoke callback with the identity. It's there if we need it.
-function setup_test_identity(identity, cert, cb) {
- cb();
-}
-
-// takes a list of functions and returns a function that
-// when called the first time, calls the first func,
-// then the next time the second, etc.
-function call_sequentially() {
- let numCalls = 0;
- let funcs = arguments;
-
- return function() {
- if (!funcs[numCalls]) {
- let argString = Array.prototype.slice.call(arguments).join(",");
- do_throw("Too many calls: " + argString);
- return;
- }
- funcs[numCalls].apply(funcs[numCalls],arguments);
- numCalls += 1;
- };
-}
diff --git a/b2g/components/test/unit/head_logshake_gonk.js b/b2g/components/test/unit/head_logshake_gonk.js
deleted file mode 100644
index e94234f1f..000000000
--- a/b2g/components/test/unit/head_logshake_gonk.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Boostrap LogShake's tests that need gonk support.
- * This is creating a fake sdcard for LogShake tests and importing LogShake and
- * osfile
- */
-
-/* jshint moz: true */
-/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump,
- do_get_profile, OS, volumeService, equal, XPCOMUtils */
-/* exported setup_logshake_mocks */
-
-/* disable use strict warning */
-/* jshint -W097 */
-
-"use strict";
-
-var Cu = Components.utils;
-var Ci = Components.interfaces;
-var Cc = Components.classes;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/osfile.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
- "@mozilla.org/telephony/volume-service;1",
- "nsIVolumeService");
-
-var sdcard;
-
-function setup_logshake_mocks() {
- do_get_profile();
- setup_fs();
-}
-
-function setup_fs() {
- OS.File.makeDir("/data/local/tmp/sdcard/", {from: "/data"}).then(function() {
- setup_sdcard();
- });
-}
-
-function setup_sdcard() {
- let volName = "sdcard";
- let mountPoint = "/data/local/tmp/sdcard";
- volumeService.createFakeVolume(volName, mountPoint);
-
- let vol = volumeService.getVolumeByName(volName);
- ok(vol, "volume shouldn't be null");
- equal(volName, vol.name, "name");
- equal(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state");
-
- ensure_sdcard();
-}
-
-function ensure_sdcard() {
- sdcard = volumeService.getVolumeByName("sdcard").mountPoint;
- ok(sdcard, "Should have a valid sdcard mountpoint");
- run_next_test();
-}
diff --git a/b2g/components/test/unit/test_aboutserviceworkers.js b/b2g/components/test/unit/test_aboutserviceworkers.js
deleted file mode 100644
index d1a7d41aa..000000000
--- a/b2g/components/test/unit/test_aboutserviceworkers.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "AboutServiceWorkers",
- "resource://gre/modules/AboutServiceWorkers.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
- "@mozilla.org/serviceworkers/manager;1",
- "nsIServiceWorkerManager");
-
-const CHROME_MSG = "mozAboutServiceWorkersChromeEvent";
-
-const ORIGINAL_SENDRESULT = AboutServiceWorkers.sendResult;
-const ORIGINAL_SENDERROR = AboutServiceWorkers.sendError;
-
-do_get_profile();
-
-var mockSendResult = (aId, aResult) => {
- let msg = {
- id: aId,
- result: aResult
- };
- Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null);
-};
-
-var mockSendError = (aId, aError) => {
- let msg = {
- id: aId,
- result: aError
- };
- Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null);
-};
-
-function attachMocks() {
- AboutServiceWorkers.sendResult = mockSendResult;
- AboutServiceWorkers.sendError = mockSendError;
-}
-
-function restoreMocks() {
- AboutServiceWorkers.sendResult = ORIGINAL_SENDRESULT;
- AboutServiceWorkers.sendError = ORIGINAL_SENDERROR;
-}
-
-do_register_cleanup(restoreMocks);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * "init" tests
- */
-[
-// Pref disabled, no registrations
-{
- prefEnabled: false,
- expectedMessage: {
- id: Date.now(),
- result: {
- enabled: false,
- registrations: []
- }
- }
-},
-// Pref enabled, no registrations
-{
- prefEnabled: true,
- expectedMessage: {
- id: Date.now(),
- result: {
- enabled: true,
- registrations: []
- }
- }
-}].forEach(test => {
- add_test(function() {
- Services.prefs.setBoolPref("dom.serviceWorkers.enabled", test.prefEnabled);
-
- let id = test.expectedMessage.id;
-
- function onMessage(subject, topic, data) {
- let message = subject.wrappedJSObject;
- let expected = test.expectedMessage;
-
- do_check_true(message.id, "Message should have id");
- do_check_eq(message.id, test.expectedMessage.id,
- "Id should be the expected one");
- do_check_eq(message.result.enabled, expected.result.enabled,
- "Pref should be disabled");
- do_check_true(message.result.registrations, "Registrations should exist");
- do_check_eq(message.result.registrations.length,
- expected.result.registrations.length,
- "Registrations length should be the expected one");
-
- Services.obs.removeObserver(onMessage, CHROME_MSG);
-
- run_next_test();
- }
-
- Services.obs.addObserver(onMessage, CHROME_MSG, false);
-
- attachMocks();
-
- AboutServiceWorkers.handleEvent({ detail: {
- id: id,
- name: "init"
- }});
- });
-});
-
-/**
- * ServiceWorkerManager tests.
- */
-
-// We cannot register a sw via ServiceWorkerManager cause chrome
-// registrations are not allowed.
-// All we can do for now is to test the interface of the swm.
-add_test(function test_swm() {
- do_check_true(gServiceWorkerManager, "SWM exists");
- do_check_true(gServiceWorkerManager.getAllRegistrations,
- "SWM.getAllRegistrations exists");
- do_check_true(typeof gServiceWorkerManager.getAllRegistrations == "function",
- "SWM.getAllRegistrations is a function");
- do_check_true(gServiceWorkerManager.propagateSoftUpdate,
- "SWM.propagateSoftUpdate exists");
- do_check_true(typeof gServiceWorkerManager.propagateSoftUpdate == "function",
-
- "SWM.propagateSoftUpdate is a function");
- do_check_true(gServiceWorkerManager.propagateUnregister,
- "SWM.propagateUnregister exists");
- do_check_true(typeof gServiceWorkerManager.propagateUnregister == "function",
- "SWM.propagateUnregister exists");
-
- run_next_test();
-});
diff --git a/b2g/components/test/unit/test_bug793310.js b/b2g/components/test/unit/test_bug793310.js
deleted file mode 100644
index 2bdb8252e..000000000
--- a/b2g/components/test/unit/test_bug793310.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function run_test() {
- Components.utils.import("resource:///modules/TelURIParser.jsm")
-
- // global-phone-number
- do_check_eq(TelURIParser.parseURI('tel', 'tel:+1234'), '+1234');
-
- // global-phone-number => white space separator
- do_check_eq(TelURIParser.parseURI('tel', 'tel:+123 456 789'), '+123 456 789');
-
- // global-phone-number => ignored chars
- do_check_eq(TelURIParser.parseURI('tel', 'tel:+1234_123'), '+1234');
-
- // global-phone-number => visualSeparator + digits
- do_check_eq(TelURIParser.parseURI('tel', 'tel:+-.()1234567890'), '+-.()1234567890');
-
- // local-phone-number
- do_check_eq(TelURIParser.parseURI('tel', 'tel:1234'), '1234');
-
- // local-phone-number => visualSeparator + digits + dtmfDigits + pauseCharacter
- do_check_eq(TelURIParser.parseURI('tel', 'tel:-.()1234567890ABCDpw'), '-.()1234567890ABCDpw');
-
- // local-phone-number => visualSeparator + digits + dtmfDigits + pauseCharacter + ignored chars
- do_check_eq(TelURIParser.parseURI('tel', 'tel:-.()1234567890ABCDpw_'), '-.()1234567890ABCDpw');
-
- // local-phone-number => isdn-subaddress
- do_check_eq(TelURIParser.parseURI('tel', 'tel:123;isub=123'), '123');
-
- // local-phone-number => post-dial
- do_check_eq(TelURIParser.parseURI('tel', 'tel:123;postd=123'), '123');
-
- // local-phone-number => prefix
- do_check_eq(TelURIParser.parseURI('tel', 'tel:123;phone-context=+0321'), '+0321123');
-
- // local-phone-number => isdn-subaddress + post-dial + prefix
- do_check_eq(TelURIParser.parseURI('tel', 'tel:123;isub=123;postd=123;phone-context=+0321'), '+0321123');
-}
diff --git a/b2g/components/test/unit/test_bug832946.js b/b2g/components/test/unit/test_bug832946.js
deleted file mode 100644
index 4ddbd4280..000000000
--- a/b2g/components/test/unit/test_bug832946.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function run_test() {
- Components.utils.import("resource:///modules/TelURIParser.jsm")
-
- // blocked numbers
- do_check_eq(TelURIParser.parseURI('tel', 'tel:#1234*'), null);
- do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234#'), null);
- do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234*'), null);
- do_check_eq(TelURIParser.parseURI('tel', 'tel:#1234#'), null);
- do_check_eq(TelURIParser.parseURI('tel', 'tel:*#*#7780#*#*'), null);
- do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234AB'), null);
-
- // white list
- do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234'), '*1234');
- do_check_eq(TelURIParser.parseURI('tel', 'tel:#1234'), '#1234');
-}
diff --git a/b2g/components/test/unit/test_fxaccounts.js b/b2g/components/test/unit/test_fxaccounts.js
deleted file mode 100644
index 5de0d6565..000000000
--- a/b2g/components/test/unit/test_fxaccounts.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://testing-common/httpd.js");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsMgmtService",
- "resource://gre/modules/FxAccountsMgmtService.jsm",
- "FxAccountsMgmtService");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager",
- "resource://gre/modules/FxAccountsManager.jsm");
-
-// At end of test, restore original state
-const ORIGINAL_AUTH_URI = Services.prefs.getCharPref("identity.fxaccounts.auth.uri");
-var { SystemAppProxy } = Cu.import("resource://gre/modules/FxAccountsMgmtService.jsm");
-const ORIGINAL_SENDCUSTOM = SystemAppProxy._sendCustomEvent;
-do_register_cleanup(function() {
- Services.prefs.setCharPref("identity.fxaccounts.auth.uri", ORIGINAL_AUTH_URI);
- SystemAppProxy._sendCustomEvent = ORIGINAL_SENDCUSTOM;
- Services.prefs.clearUserPref("identity.fxaccounts.skipDeviceRegistration");
-});
-
-// Make profile available so that fxaccounts can store user data
-do_get_profile();
-
-// Mock the system app proxy; make message passing possible
-var mockSendCustomEvent = function(aEventName, aMsg) {
- Services.obs.notifyObservers({wrappedJSObject: aMsg}, aEventName, null);
-};
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function test_overall() {
- // FxA device registration throws from this context
- Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true);
-
- do_check_neq(FxAccountsMgmtService, null);
-});
-
-// Check that invalid email capitalization is corrected on signIn.
-// https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md#post-v1accountlogin
-add_test(function test_invalidEmailCase_signIn() {
- do_test_pending();
- let clientEmail = "greta.garbo@gmail.com";
- let canonicalEmail = "Greta.Garbo@gmail.COM";
- let attempts = 0;
-
- function writeResp(response, msg) {
- if (typeof msg === "object") {
- msg = JSON.stringify(msg);
- }
- response.bodyOutputStream.write(msg, msg.length);
- }
-
- // Mock of the fxa accounts auth server, reproducing the behavior of
- // /account/login when email capitalization is incorrect on signIn.
- let server = httpd_setup({
- "/account/login": function(request, response) {
- response.setHeader("Content-Type", "application/json");
- attempts += 1;
-
- // Ensure we don't get in an endless loop
- if (attempts > 2) {
- response.setStatusLine(request.httpVersion, 429, "Sorry, you had your chance");
- writeResp(response, {});
- return;
- }
-
- let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
- let jsonBody = JSON.parse(body);
- let email = jsonBody.email;
-
- // The second time through, the accounts client will call the api with
- // the correct email capitalization.
- if (email == canonicalEmail) {
- response.setStatusLine(request.httpVersion, 200, "Yay");
- writeResp(response, {
- uid: "your-uid",
- sessionToken: "your-sessionToken",
- keyFetchToken: "your-keyFetchToken",
- verified: true,
- authAt: 1392144866,
- });
- return;
- }
-
- // If the client has the wrong case on the email, we return a 400, with
- // the capitalization of the email as saved in the accounts database.
- response.setStatusLine(request.httpVersion, 400, "Incorrect email case");
- writeResp(response, {
- code: 400,
- errno: 120,
- error: "Incorrect email case",
- email: canonicalEmail,
- });
- return;
- },
- });
-
- // Point the FxAccountsClient's hawk rest request client to the mock server
- Services.prefs.setCharPref("identity.fxaccounts.auth.uri", server.baseURI);
-
- // FxA device registration throws from this context
- Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true);
-
- // Receive a mozFxAccountsChromeEvent message
- function onMessage(subject, topic, data) {
- let message = subject.wrappedJSObject;
-
- switch (message.id) {
- // When we signed in as "Greta.Garbo", the server should have told us
- // that the proper capitalization is really "greta.garbo". Call
- // getAccounts to get the signed-in user and ensure that the
- // capitalization is correct.
- case "signIn":
- FxAccountsMgmtService.handleEvent({
- detail: {
- id: "getAccounts",
- data: {
- method: "getAccounts",
- }
- }
- });
- break;
-
- // Having initially signed in as "Greta.Garbo", getAccounts should show
- // us that the signed-in user has the properly-capitalized email,
- // "greta.garbo".
- case "getAccounts":
- Services.obs.removeObserver(onMessage, "mozFxAccountsChromeEvent");
-
- do_check_eq(message.data.email, canonicalEmail);
-
- do_test_finished();
- server.stop(run_next_test);
- break;
-
- // We should not receive any other mozFxAccountsChromeEvent messages
- default:
- do_throw("wat!");
- break;
- }
- }
-
- Services.obs.addObserver(onMessage, "mozFxAccountsChromeEvent", false);
-
- SystemAppProxy._sendCustomEvent = mockSendCustomEvent;
-
- // Trigger signIn using an email with incorrect capitalization
- FxAccountsMgmtService.handleEvent({
- detail: {
- id: "signIn",
- data: {
- method: "signIn",
- email: clientEmail,
- password: "123456",
- },
- },
- });
-});
-
-add_test(function testHandleGetAssertionError_defaultCase() {
- do_test_pending();
-
- // FxA device registration throws from this context
- Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true);
-
- FxAccountsManager.getAssertion(null).then(
- success => {
- // getAssertion should throw with invalid audience
- ok(false);
- },
- reason => {
- equal("INVALID_AUDIENCE", reason.error);
- do_test_finished();
- run_next_test();
- }
- )
-});
-
-// End of tests
-// Utility functions follow
-
-function httpd_setup (handlers, port=-1) {
- let server = new HttpServer();
- for (let path in handlers) {
- server.registerPathHandler(path, handlers[path]);
- }
- try {
- server.start(port);
- } catch (ex) {
- dump("ERROR starting server on port " + port + ". Already a process listening?");
- do_throw(ex);
- }
-
- // Set the base URI for convenience.
- let i = server.identity;
- server.baseURI = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort;
-
- return server;
-}
-
-
diff --git a/b2g/components/test/unit/test_logcapture.js b/b2g/components/test/unit/test_logcapture.js
deleted file mode 100644
index 9dbe2bc77..000000000
--- a/b2g/components/test/unit/test_logcapture.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Testing non Gonk-specific code path
- */
-function run_test() {
- Components.utils.import("resource:///modules/LogCapture.jsm");
- run_next_test();
-}
-
-// Trivial test just to make sure we have no syntax error
-add_test(function test_logCapture_loads() {
- ok(LogCapture, "LogCapture object exists");
- run_next_test();
-});
diff --git a/b2g/components/test/unit/test_logcapture_gonk.js b/b2g/components/test/unit/test_logcapture_gonk.js
deleted file mode 100644
index d80f33dd9..000000000
--- a/b2g/components/test/unit/test_logcapture_gonk.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-/**
- * Test that LogCapture successfully reads from the /dev/log devices, returning
- * a Uint8Array of some length, including zero. This tests a few standard
- * log devices
- */
-function run_test() {
- Components.utils.import("resource:///modules/LogCapture.jsm");
- run_next_test();
-}
-
-function verifyLog(log) {
- // log exists
- notEqual(log, null);
- // log has a length and it is non-negative (is probably array-like)
- ok(log.length >= 0);
-}
-
-add_test(function test_readLogFile() {
- let mainLog = LogCapture.readLogFile("/dev/log/main");
- verifyLog(mainLog);
-
- let meminfoLog = LogCapture.readLogFile("/proc/meminfo");
- verifyLog(meminfoLog);
-
- run_next_test();
-});
-
-add_test(function test_readProperties() {
- let propertiesLog = LogCapture.readProperties();
- notEqual(propertiesLog, null, "Properties should not be null");
- notEqual(propertiesLog, undefined, "Properties should not be undefined");
-
- for (let propertyName in propertiesLog) {
- equal(typeof(propertiesLog[propertyName]), "string",
- "Property " + propertyName + " should be a string");
- }
-
- equal(propertiesLog["ro.product.locale.language"], "en",
- "Locale language should be read correctly. See bug 1171577.");
-
- equal(propertiesLog["ro.product.locale.region"], "US",
- "Locale region should be read correctly. See bug 1171577.");
-
- run_next_test();
-});
-
-add_test(function test_readAppIni() {
- let appIni = LogCapture.readLogFile("/system/b2g/application.ini");
- verifyLog(appIni);
-
- run_next_test();
-});
-
-add_test(function test_get_about_memory() {
- let memLog = LogCapture.readAboutMemory();
-
- ok(memLog, "Should have returned a valid Promise object");
-
- memLog.then(file => {
- ok(file, "Should have returned a filename");
- run_next_test();
- }, error => {
- ok(false, "Dumping about:memory promise rejected: " + error);
- run_next_test();
- });
-});
diff --git a/b2g/components/test/unit/test_logparser.js b/b2g/components/test/unit/test_logparser.js
deleted file mode 100644
index 624dcc6e2..000000000
--- a/b2g/components/test/unit/test_logparser.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* jshint moz: true */
-
-var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
-
-function debug(msg) {
- var timestamp = Date.now();
- dump("LogParser: " + timestamp + ": " + msg + "\n");
-}
-
-function run_test() {
- Cu.import("resource:///modules/LogParser.jsm");
- debug("Starting");
- run_next_test();
-}
-
-function makeStream(file) {
- var fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- fileStream.init(file, -1, -1, 0);
- var bis = Cc["@mozilla.org/binaryinputstream;1"]
- .createInstance(Ci.nsIBinaryInputStream);
- bis.setInputStream(fileStream);
- return bis;
-}
-
-add_test(function test_parse_logfile() {
- let loggerFile = do_get_file("data/test_logger_file");
-
- let loggerStream = makeStream(loggerFile);
-
- // Initialize arrays to hold the file contents (lengths are hardcoded)
- let loggerArray = new Uint8Array(loggerStream.readByteArray(4037));
-
- loggerStream.close();
-
- let logMessages = LogParser.parseLogArray(loggerArray);
-
- ok(logMessages.length === 58, "There should be 58 messages in the log");
-
- let expectedLogEntry = {
- processId: 271, threadId: 271,
- seconds: 790796, nanoseconds: 620000001, time: 790796620.000001,
- priority: 4, tag: "Vold",
- message: "Vold 2.1 (the revenge) firing up\n"
- };
-
- deepEqual(expectedLogEntry, logMessages[0]);
- run_next_test();
-});
-
-add_test(function test_print_properties() {
- let properties = {
- "ro.secure": "1",
- "sys.usb.state": "diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb"
- };
-
- let logMessagesRaw = LogParser.prettyPrintPropertiesArray(properties);
- let logMessages = new TextDecoder("utf-8").decode(logMessagesRaw);
- let logMessagesArray = logMessages.split("\n");
-
- ok(logMessagesArray.length === 3, "There should be 3 lines in the log.");
- notEqual(logMessagesArray[0], "", "First line should not be empty");
- notEqual(logMessagesArray[1], "", "Second line should not be empty");
- equal(logMessagesArray[2], "", "Last line should be empty");
-
- let expectedLog = [
- "[ro.secure]: [1]",
- "[sys.usb.state]: [diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb]",
- ""
- ].join("\n");
-
- deepEqual(expectedLog, logMessages);
-
- run_next_test();
-});
diff --git a/b2g/components/test/unit/test_logshake.js b/b2g/components/test/unit/test_logshake.js
deleted file mode 100644
index cfb81b893..000000000
--- a/b2g/components/test/unit/test_logshake.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/**
- * Test the log capturing capabilities of LogShake.jsm
- */
-
-/* jshint moz: true */
-/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */
-/* exported run_test */
-
-/* disable use strict warning */
-/* jshint -W097 */
-"use strict";
-
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/LogCapture.jsm");
-Cu.import("resource://gre/modules/LogShake.jsm");
-
-const EVENTS_PER_SECOND = 6.25;
-const GRAVITY = 9.8;
-
-/**
- * Force logshake to handle a device motion event with given components.
- * Does not use SystemAppProxy because event needs special
- * accelerationIncludingGravity property.
- */
-function sendDeviceMotionEvent(x, y, z) {
- let event = {
- type: "devicemotion",
- accelerationIncludingGravity: {
- x: x,
- y: y,
- z: z
- }
- };
- LogShake.handleEvent(event);
-}
-
-/**
- * Send a screen change event directly, does not use SystemAppProxy due to race
- * conditions.
- */
-function sendScreenChangeEvent(screenEnabled) {
- let event = {
- type: "screenchange",
- detail: {
- screenEnabled: screenEnabled
- }
- };
- LogShake.handleEvent(event);
-}
-
-/**
- * Mock the readLogFile function of LogCapture.
- * Used to detect whether LogShake activates.
- * @return {Array<String>} Locations that LogShake tries to read
- */
-function mockReadLogFile() {
- let readLocations = [];
-
- LogCapture.readLogFile = function(loc) {
- readLocations.push(loc);
- return null; // we don't want to provide invalid data to a parser
- };
-
- // Allow inspection of readLocations by caller
- return readLocations;
-}
-
-/**
- * Send a series of events that corresponds to a shake
- */
-function sendSustainedShake() {
- // Fire a series of devicemotion events that are of shake magnitude
- for (let i = 0; i < 2 * EVENTS_PER_SECOND; i++) {
- sendDeviceMotionEvent(0, 2 * GRAVITY, 2 * GRAVITY);
- }
-
-}
-
-add_test(function test_do_log_capture_after_shaking() {
- // Enable LogShake
- LogShake.init();
-
- let readLocations = mockReadLogFile();
-
- sendSustainedShake();
-
- ok(readLocations.length > 0,
- "LogShake should attempt to read at least one log");
-
- LogShake.uninit();
- run_next_test();
-});
-
-add_test(function test_do_nothing_when_resting() {
- // Enable LogShake
- LogShake.init();
-
- let readLocations = mockReadLogFile();
-
- // Fire several devicemotion events that are relatively tiny
- for (let i = 0; i < 2 * EVENTS_PER_SECOND; i++) {
- sendDeviceMotionEvent(0, GRAVITY, GRAVITY);
- }
-
- ok(readLocations.length === 0,
- "LogShake should not read any logs");
-
- LogShake.uninit();
- run_next_test();
-});
-
-add_test(function test_do_nothing_when_disabled() {
- // Disable LogShake
- LogShake.uninit();
-
- let readLocations = mockReadLogFile();
-
- // Fire a series of events that would normally be a shake
- sendSustainedShake();
-
- ok(readLocations.length === 0,
- "LogShake should not read any logs");
-
- run_next_test();
-});
-
-add_test(function test_do_nothing_when_screen_off() {
- // Enable LogShake
- LogShake.init();
-
- // Send an event as if the screen has been turned off
- sendScreenChangeEvent(false);
-
- let readLocations = mockReadLogFile();
-
- // Fire a series of events that would normally be a shake
- sendSustainedShake();
-
- ok(readLocations.length === 0,
- "LogShake should not read any logs");
-
- // Restore the screen
- sendScreenChangeEvent(true);
-
- LogShake.uninit();
- run_next_test();
-});
-
-add_test(function test_do_log_capture_resilient_readLogFile() {
- // Enable LogShake
- LogShake.init();
-
- let readLocations = [];
- LogCapture.readLogFile = function(loc) {
- readLocations.push(loc);
- throw new Error("Exception during readLogFile for: " + loc);
- };
-
- // Fire a series of events that would normally be a shake
- sendSustainedShake();
-
- ok(readLocations.length > 0,
- "LogShake should attempt to read at least one log");
-
- LogShake.uninit();
- run_next_test();
-});
-
-add_test(function test_do_log_capture_resilient_parseLog() {
- // Enable LogShake
- LogShake.init();
-
- let readLocations = [];
- LogCapture.readLogFile = function(loc) {
- readLocations.push(loc);
- LogShake.LOGS_WITH_PARSERS[loc] = function() {
- throw new Error("Exception during LogParser for: " + loc);
- };
- return null;
- };
-
- // Fire a series of events that would normally be a shake
- sendSustainedShake();
-
- ok(readLocations.length > 0,
- "LogShake should attempt to read at least one log");
-
- LogShake.uninit();
- run_next_test();
-});
-
-add_test(function test_do_nothing_when_dropped() {
- // Enable LogShake
- LogShake.init();
-
- let readLocations = mockReadLogFile();
-
- // We want a series of spikes to be ignored by LogShake. This roughly
- // corresponds to the compare_stairs_sock graph on bug #1101994
-
- for (let i = 0; i < 10 * EVENTS_PER_SECOND; i++) {
- // Fire a devicemotion event that is at rest
- sendDeviceMotionEvent(0, 0, GRAVITY);
- // Fire a spike of motion
- sendDeviceMotionEvent(0, 2 * GRAVITY, 2 * GRAVITY);
- }
-
- ok(readLocations.length === 0,
- "LogShake should not read any logs");
-
- LogShake.uninit();
- run_next_test();
-});
-
-function run_test() {
- run_next_test();
-}
diff --git a/b2g/components/test/unit/test_logshake_gonk.js b/b2g/components/test/unit/test_logshake_gonk.js
deleted file mode 100644
index 28de0263f..000000000
--- a/b2g/components/test/unit/test_logshake_gonk.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Test the log capturing capabilities of LogShake.jsm, checking
- * for Gonk-specific parts
- */
-
-/* jshint moz: true, esnext: true */
-/* global Cu, LogCapture, LogShake, ok, add_test, run_next_test, dump,
- setup_logshake_mocks, OS, sdcard */
-/* exported run_test */
-
-/* disable use strict warning */
-/* jshint -W097 */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Promise.jsm");
-
-function run_test() {
- Cu.import("resource://gre/modules/LogShake.jsm");
- run_next_test();
-}
-
-add_test(setup_logshake_mocks);
-
-add_test(function test_logShake_captureLogs_writes() {
- // Enable LogShake
- LogShake.init();
-
- let expectedFiles = [];
-
- LogShake.captureLogs().then(logResults => {
- LogShake.uninit();
-
- ok(logResults.logFilenames.length > 0, "Should have filenames");
- ok(logResults.logPaths.length > 0, "Should have paths");
- ok(!logResults.compressed, "Should not be compressed");
-
- logResults.logPaths.forEach(f => {
- let p = OS.Path.join(sdcard, f);
- ok(p, "Should have a valid result path: " + p);
-
- let t = OS.File.exists(p).then(rv => {
- ok(rv, "File exists: " + p);
- });
-
- expectedFiles.push(t);
- });
-
- Promise.all(expectedFiles).then(() => {
- ok(true, "Completed all files checks");
- run_next_test();
- });
- },
- error => {
- LogShake.uninit();
-
- ok(false, "Should not have received error: " + error);
-
- run_next_test();
- });
-});
diff --git a/b2g/components/test/unit/test_logshake_gonk_compression.js b/b2g/components/test/unit/test_logshake_gonk_compression.js
deleted file mode 100644
index b5af46081..000000000
--- a/b2g/components/test/unit/test_logshake_gonk_compression.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Test the log capturing capabilities of LogShake.jsm, checking
- * for Gonk-specific parts
- */
-
-/* jshint moz: true, esnext: true */
-/* global Cc, Ci, Cu, LogCapture, LogShake, ok, add_test, run_next_test, dump,
- setup_logshake_mocks, OS, sdcard, FileUtils */
-/* exported run_test */
-
-/* disable use strict warning */
-/* jshint -W097 */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-
-function run_test() {
- Cu.import("resource://gre/modules/LogShake.jsm");
- run_next_test();
-}
-
-add_test(setup_logshake_mocks);
-
-add_test(function test_logShake_captureLogs_writes_zip() {
- // Enable LogShake
- LogShake.init();
-
- let expectedFiles = [];
-
- LogShake.enableQAMode();
-
- LogShake.captureLogs().then(logResults => {
- LogShake.uninit();
-
- ok(logResults.logPaths.length === 1, "Should have zip path");
- ok(logResults.logFilenames.length >= 1, "Should have log filenames");
- ok(logResults.compressed, "Log files should be compressed");
-
- let zipPath = OS.Path.join(sdcard, logResults.logPaths[0]);
- ok(zipPath, "Should have a valid archive path: " + zipPath);
-
- let zipFile = new FileUtils.File(zipPath);
- ok(zipFile, "Should have a valid archive file: " + zipFile);
-
- let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
- .createInstance(Ci.nsIZipReader);
- zipReader.open(zipFile);
-
- let logFilenamesSeen = {};
-
- let zipEntries = zipReader.findEntries(null); // Find all entries
- while (zipEntries.hasMore()) {
- let entryName = zipEntries.getNext();
- let entry = zipReader.getEntry(entryName);
- logFilenamesSeen[entryName] = true;
- ok(!entry.isDirectory, "Archive entry " + entryName + " should be a file");
- }
- zipReader.close();
-
- // TODO: Verify archive contents
- logResults.logFilenames.forEach(filename => {
- ok(logFilenamesSeen[filename], "File " + filename + " should be present in archive");
- });
- run_next_test();
- },
- error => {
- LogShake.uninit();
-
- ok(false, "Should not have received error: " + error);
-
- run_next_test();
- });
-});
-
diff --git a/b2g/components/test/unit/test_logshake_readLog_gonk.js b/b2g/components/test/unit/test_logshake_readLog_gonk.js
deleted file mode 100644
index 003723ad5..000000000
--- a/b2g/components/test/unit/test_logshake_readLog_gonk.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Test the log capturing capabilities of LogShake.jsm under conditions that
- * could cause races
- */
-
-/* jshint moz: true, esnext: true */
-/* global Cu, LogCapture, LogShake, ok, add_test, run_next_test, dump,
- XPCOMUtils, do_get_profile, OS, volumeService, Promise, equal,
- setup_logshake_mocks */
-/* exported run_test */
-
-/* disable use strict warning */
-/* jshint -W097 */
-
-"use strict";
-
-function run_test() {
- Cu.import("resource://gre/modules/LogShake.jsm");
- run_next_test();
-}
-
-add_test(setup_logshake_mocks);
-
-add_test(function test_logShake_captureLogs_waits_to_read() {
- // Enable LogShake
- LogShake.init();
-
- // Save no logs synchronously (except properties)
- LogShake.LOGS_WITH_PARSERS = {};
-
- LogShake.captureLogs().then(logResults => {
- LogShake.uninit();
-
- ok(logResults.logFilenames.length > 0, "Should have filenames");
- ok(logResults.logPaths.length > 0, "Should have paths");
- ok(!logResults.compressed, "Should not be compressed");
-
- // This assumes that the about:memory reading will only fail under abnormal
- // circumstances. It does not check for screenshot.png because
- // systemAppFrame is unavailable during xpcshell tests.
- let hasAboutMemory = false;
-
- logResults.logFilenames.forEach(filename => {
- // Because the about:memory log's filename has the PID in it we can not
- // use simple equality but instead search for the "about_memory" part of
- // the filename which will look like logshake-about_memory-{PID}.json.gz
- if (filename.indexOf("about_memory") < 0) {
- return;
- }
- hasAboutMemory = true;
- });
-
- ok(hasAboutMemory,
- "LogShake's asynchronous read of about:memory should have succeeded.");
-
- run_next_test();
- },
- error => {
- LogShake.uninit();
-
- ok(false, "Should not have received error: " + error);
-
- run_next_test();
- });
-});
diff --git a/b2g/components/test/unit/test_signintowebsite.js b/b2g/components/test/unit/test_signintowebsite.js
deleted file mode 100644
index 38d4fa79e..000000000
--- a/b2g/components/test/unit/test_signintowebsite.js
+++ /dev/null
@@ -1,322 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests for b2g/components/SignInToWebsite.jsm
-
-"use strict";
-
-XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService",
- "resource://gre/modules/identity/MinimalIdentity.jsm",
- "IdentityService");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SignInToWebsiteController",
- "resource://gre/modules/SignInToWebsite.jsm",
- "SignInToWebsiteController");
-
-Cu.import("resource://gre/modules/identity/LogUtils.jsm");
-
-function log(...aMessageArgs) {
- Logger.log.apply(Logger, ["test_signintowebsite"].concat(aMessageArgs));
-}
-
-function test_overall() {
- do_check_neq(MinimalIDService, null);
- run_next_test();
-}
-
-function objectContains(object, subset) {
- let objectKeys = Object.keys(object);
- let subsetKeys = Object.keys(subset);
-
- // can't have fewer keys than the subset
- if (objectKeys.length < subsetKeys.length) {
- return false;
- }
-
- let key;
- let success = true;
- if (subsetKeys.length > 0) {
- for (let i=0; i<subsetKeys.length; i++) {
- key = subsetKeys[i];
-
- // key exists in the source object
- if (typeof object[key] === 'undefined') {
- success = false;
- break;
- }
-
- // recursively check object values
- else if (typeof subset[key] === 'object') {
- if (typeof object[key] !== 'object') {
- success = false;
- break;
- }
- if (! objectContains(object[key], subset[key])) {
- success = false;
- break;
- }
- }
-
- else if (object[key] !== subset[key]) {
- success = false;
- break;
- }
- }
- }
-
- return success;
-}
-
-function test_object_contains() {
- do_test_pending();
-
- let someObj = {
- pies: 42,
- green: "spam",
- flan: {yes: "please"}
- };
- let otherObj = {
- pies: 42,
- flan: {yes: "please"}
- };
- do_check_true(objectContains(someObj, otherObj));
- do_test_finished();
- run_next_test();
-}
-
-function test_mock_doc() {
- do_test_pending();
- let mockedDoc = mockDoc({loggedInUser: null}, function(action, params) {
- do_check_eq(action, 'coffee');
- do_test_finished();
- run_next_test();
- });
-
- // A smoke test to ensure that mockedDoc is functioning correctly.
- // There is presently no doCoffee method in Persona.
- mockedDoc.doCoffee();
-}
-
-function test_watch() {
- do_test_pending();
-
- setup_test_identity("pie@food.gov", TEST_CERT, function() {
- let controller = SignInToWebsiteController;
-
- let mockedDoc = mockDoc({loggedInUser: null}, function(action, params) {
- do_check_eq(action, 'ready');
- controller.uninit();
- MinimalIDService.RP.unwatch(mockedDoc.id);
- do_test_finished();
- run_next_test();
- });
-
- controller.init({pipe: mockReceivingPipe()});
- MinimalIDService.RP.watch(mockedDoc, {});
- });
-}
-
-function test_request_login() {
- do_test_pending();
-
- setup_test_identity("flan@food.gov", TEST_CERT, function() {
- let controller = SignInToWebsiteController;
-
- let mockedDoc = mockDoc({loggedInUser: null}, call_sequentially(
- function(action, params) {
- do_check_eq(action, 'ready');
- do_check_eq(params, undefined);
- },
- function(action, params) {
- do_check_eq(action, 'login');
- do_check_eq(params, TEST_CERT);
- controller.uninit();
- MinimalIDService.RP.unwatch(mockedDoc.id);
- do_test_finished();
- run_next_test();
- }
- ));
-
- controller.init({pipe: mockReceivingPipe()});
- MinimalIDService.RP.watch(mockedDoc, {});
- MinimalIDService.RP.request(mockedDoc.id, {});
- });
-}
-
-function test_request_logout() {
- do_test_pending();
-
- setup_test_identity("flan@food.gov", TEST_CERT, function() {
- let controller = SignInToWebsiteController;
-
- let mockedDoc = mockDoc({loggedInUser: null}, call_sequentially(
- function(action, params) {
- do_check_eq(action, 'ready');
- do_check_eq(params, undefined);
- },
- function(action, params) {
- do_check_eq(action, 'logout');
- do_check_eq(params, undefined);
- controller.uninit();
- MinimalIDService.RP.unwatch(mockedDoc.id);
- do_test_finished();
- run_next_test();
- }
- ));
-
- controller.init({pipe: mockReceivingPipe()});
- MinimalIDService.RP.watch(mockedDoc, {});
- MinimalIDService.RP.logout(mockedDoc.id, {});
- });
-}
-
-function test_request_login_logout() {
- do_test_pending();
-
- setup_test_identity("unagi@food.gov", TEST_CERT, function() {
- let controller = SignInToWebsiteController;
-
- let mockedDoc = mockDoc({loggedInUser: null}, call_sequentially(
- function(action, params) {
- do_check_eq(action, 'ready');
- do_check_eq(params, undefined);
- },
- function(action, params) {
- do_check_eq(action, 'login');
- do_check_eq(params, TEST_CERT);
- },
- function(action, params) {
- do_check_eq(action, 'logout');
- do_check_eq(params, undefined);
- controller.uninit();
- MinimalIDService.RP.unwatch(mockedDoc.id);
- do_test_finished();
- run_next_test();
- }
- ));
-
- controller.init({pipe: mockReceivingPipe()});
- MinimalIDService.RP.watch(mockedDoc, {});
- MinimalIDService.RP.request(mockedDoc.id, {});
- MinimalIDService.RP.logout(mockedDoc.id, {});
- });
-}
-
-function test_logout_everywhere() {
- do_test_pending();
- let logouts = 0;
-
- setup_test_identity("fugu@food.gov", TEST_CERT, function() {
- let controller = SignInToWebsiteController;
-
- let mockedDoc1 = mockDoc({loggedInUser: null}, call_sequentially(
- function(action, params) {
- do_check_eq(action, 'ready');
- },
- function(action, params) {
- do_check_eq(action, 'login');
- },
- function(action, params) {
- // Result of logout from doc2.
- // We don't know what order the logouts will occur in.
- do_check_eq(action, 'logout');
- if (++logouts === 2) {
- do_test_finished();
- run_next_test();
- }
- }
- ));
-
- let mockedDoc2 = mockDoc({loggedInUser: null}, call_sequentially(
- function(action, params) {
- do_check_eq(action, 'ready');
- },
- function(action, params) {
- do_check_eq(action, 'login');
- },
- function(action, params) {
- do_check_eq(action, 'logout');
- if (++logouts === 2) {
- do_test_finished();
- run_next_test();
- }
- }
- ));
-
- controller.init({pipe: mockReceivingPipe()});
- MinimalIDService.RP.watch(mockedDoc1, {});
- MinimalIDService.RP.request(mockedDoc1.id, {});
-
- MinimalIDService.RP.watch(mockedDoc2, {});
- MinimalIDService.RP.request(mockedDoc2.id, {});
-
- // Logs out of both docs because they share the
- // same origin.
- MinimalIDService.RP.logout(mockedDoc2.id, {});
- });
-}
-
-function test_options_pass_through() {
- do_test_pending();
-
- // An meaningless structure for testing that RP messages preserve
- // objects and their parameters as they are passed back and forth.
- let randomMixedParams = {
- loggedInUser: "juanita@mozilla.com",
- forceAuthentication: true,
- forceIssuer: "foo.com",
- someThing: {
- name: "Pertelote",
- legs: 4,
- nested: {bee: "Eric", remaining: "1/2"}
- }
- };
-
- let mockedDoc = mockDoc(randomMixedParams, function(action, params) {});
-
- function pipeOtherEnd(rpOptions, gaiaOptions) {
- // Ensure that every time we receive a message, our mixed
- // random params are contained in that message
- do_check_true(objectContains(rpOptions, randomMixedParams));
-
- switch (gaiaOptions.message) {
- case "identity-delegate-watch":
- MinimalIDService.RP.request(mockedDoc.id, {});
- break;
- case "identity-delegate-request":
- MinimalIDService.RP.logout(mockedDoc.id, {});
- break;
- case "identity-delegate-logout":
- do_test_finished();
- controller.uninit();
- MinimalIDService.RP.unwatch(mockedDoc.id);
- run_next_test();
- break;
- }
- }
-
- let controller = SignInToWebsiteController;
- controller.init({pipe: mockSendingPipe(pipeOtherEnd)});
-
- MinimalIDService.RP.watch(mockedDoc, {});
-}
-
-var TESTS = [
- test_overall,
- test_mock_doc,
- test_object_contains,
-
- test_watch,
- test_request_login,
- test_request_logout,
- test_request_login_logout,
- test_logout_everywhere,
-
- test_options_pass_through
-];
-
-TESTS.forEach(add_test);
-
-function run_test() {
- run_next_test();
-}
diff --git a/b2g/components/test/unit/xpcshell.ini b/b2g/components/test/unit/xpcshell.ini
deleted file mode 100644
index ca3df5bf6..000000000
--- a/b2g/components/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,49 +0,0 @@
-[DEFAULT]
-head =
-tail =
-
-support-files =
- data/test_logger_file
-
-[test_bug793310.js]
-
-[test_bug832946.js]
-
-[test_fxaccounts.js]
-[test_signintowebsite.js]
-head = head_identity.js
-tail =
-
-# testing non gonk-specific stuff
-[test_logcapture.js]
-
-[test_logcapture_gonk.js]
-# can be slow because of what the test does, so let's give it some more time
-# to avoid intermittents: bug 1212395
-requesttimeoutfactor = 2
-# only run on b2g builds due to requiring b2g-specific log files to exist
-skip-if = toolkit != "gonk"
-
-[test_logparser.js]
-
-[test_logshake.js]
-
-[test_logshake_gonk.js]
-# can be slow because of what the test does, so let's give it some more time
-# to avoid intermittents: bug 1144499
-requesttimeoutfactor = 2
-head = head_logshake_gonk.js
-# only run on b2g builds due to requiring b2g-specific log files to exist
-skip-if = (toolkit != "gonk")
-
-[test_logshake_gonk_compression.js]
-head = head_logshake_gonk.js
-# only run on b2g builds due to requiring b2g-specific log files to exist
-skip-if = (toolkit != "gonk")
-
-[test_logshake_readLog_gonk.js]
-head = head_logshake_gonk.js
-# only run on b2g builds due to requiring b2g-specific log files to exist
-skip-if = (toolkit != "gonk")
-
-[test_aboutserviceworkers.js]
diff --git a/b2g/config/aries/config.json b/b2g/config/aries/config.json
deleted file mode 100644
index 1902a3000..000000000
--- a/b2g/config/aries/config.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "config_version": 2,
- "tooltool_manifest": "releng-aries.manifest",
- "mock_target": "mozilla-centos6-x86_64",
- "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools"],
- "mock_files": [
- ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
- ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
- ],
- "build_targets": ["", "blobfree"],
- "upload_files": [
- "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
- "{objdir}/dist/b2g-*.tar.gz",
- "{workdir}/sources.xml",
- "{workdir}/out/target/product/aries/fota-*-update-*.mar"
- ],
- "public_upload_files": [
- "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
- "{objdir}/dist/b2g-*.tar.gz",
- "{workdir}/sources.xml",
- "{objdir}/dist/b2g-update/*.mar",
- "{workdir}/out/target/product/aries/fota-*-update.mar"
- ],
- "zip_files": [
- ["{workdir}/out/target/product/aries/*.img", "out/target/product/aries/"],
- "{workdir}/flash.sh",
- "{workdir}/gecko/b2g/installer/flash.bat",
- "{workdir}/prebuilts/misc/windows/win_flash_tools/*",
- "{workdir}/load-config.sh",
- "{workdir}/.config",
- "{workdir}/sources.xml",
- "{workdir}/profile.sh",
- ["{workdir}/gecko/tools/profiler/merge-profiles.py", "gecko/tools/profiler/"],
- ["{workdir}/scripts/profile-symbolicate.py", "scripts/"],
- ["{workdir}/gecko/tools/rb/fix_stack_using_bpsyms.py", "gecko/tools/rb/"]
- ],
- "env": {
- "VARIANT": "user",
- "MOZILLA_OFFICIAL": "1",
- "MOZ_TELEMETRY_REPORTING": "1",
- "GAIA_KEYBOARD_LAYOUTS": "en,pt-BR,es,de,fr,pl,zh-Hans-Pinyin,zh-Hant-Zhuyin,en-Dvorak"
- },
- "b2g_manifest": "aries.xml",
- "b2g_manifest_intree": true,
- "gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
- "gaia": {
- "l10n": {
- "vcs": "hg",
- "root": "https://hg.mozilla.org/gaia-l10n"
- }
- }
-}
diff --git a/b2g/config/aries/releng-aries.manifest b/b2g/config/aries/releng-aries.manifest
deleted file mode 100644
index a1276ffe3..000000000
--- a/b2g/config/aries/releng-aries.manifest
+++ /dev/null
@@ -1,27 +0,0 @@
-[
-{
-"version": "Android NDK r11b for B2G",
-"algorithm": "sha512",
-"visibility": "internal",
-"filename": "android-ndk-b2g.tar.xz",
-"unpack": true,
-"digest": "bc37c6b2e38f4ff19e3326786312d8f893600e155d35dfba45163bd909e022db852b9c6920863cb498bbe7da8b86a6a387fa024bc9444ce3a8d1715cf2c24b21",
-"size": 292442020
-},
-{
-"algorithm": "sha512",
-"visibility": "internal",
-"filename": "backup-aries_23.0.1.A.5.77.tar.xz",
-"unpack": true,
-"digest": "79c8e390e88cc4765ff7f5f29f3d5337c9037b7eb9414006947d38d34acefdbcf7090c18a366948c682b1c2c9d9ef51012e7be44daa28fdde7b837ade647c257",
-"size": 227555180
-},
-{
-"version": "gcc 4.8.5 + PR64905",
-"size": 80160264,
-"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
-"algorithm": "sha512",
-"filename": "gcc.tar.xz",
-"unpack": "True"
-}
-]
diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml
deleted file mode 100644
index 0ed0a67a6..000000000
--- a/b2g/config/aries/sources.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" ?><manifest>
- <!--
- Remotes
- -->
- <remote fetch="git://github.com/apitrace/" name="apitrace"/>
- <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
- <remote fetch="git://codeaurora.org/" name="caf"/>
- <!--
- B2G repositories for all targets
- -->
- <project name="gaia" path="gaia" remote="b2g" revision="f5d355dfeb559e11fad48901b0bea287ec33b874"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
- <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
- <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
- <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
- <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="f1a61fa8f97cc0a1ac4eca160acc222981b21d90"/>
- <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3618678c472320de386f5ddc27897992d0e148a8"/>
- <!-- B2G specific things. -->
- <project name="platform_build" path="build" remote="b2g" revision="964d9fa4eabe9eb473ef9101ca2a690880f28547">
- <copyfile dest="Makefile" src="core/root.mk"/>
- </project>
- <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
- <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
- <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
- <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c5a77c651bcde37005e6b6e209747edcc6c9361"/>
- <!-- Stock Android things -->
- <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
- <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
- <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
- <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
- <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" remote="caf" revision="c09e1b3a55153d1ba142d5bf548c90487ea71f9e"/>
- <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
- <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" remote="caf" revision="c33513f9de95fcdf4ec832db5e3ebd612382f541"/>
- <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
- <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
- <project name="device/sample" path="device/sample" revision="9c19bbbe0793ebdc427277dc37f9bb4ae20bccb2"/>
- <project name="platform/abi/cpp" path="abi/cpp" revision="18f1b5e28734183ff8073fe86dc46bc4ebba8a59"/>
- <project name="platform/bootable/recovery" path="bootable/recovery" revision="dc8da21282a0c68328d05268433d19b0f2f6a15c"/>
- <project name="platform/external/aac" path="external/aac" revision="fa3eba16446cc8f2f5e2dfc20d86a49dbd37299e"/>
- <project name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e"/>
- <project name="platform/external/bsdiff" path="external/bsdiff" revision="23e322ab19fb7d74c2c37e40ce364d9f709bdcee"/>
- <project name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de"/>
- <project name="platform/external/checkpolicy" path="external/checkpolicy" revision="0d73ef7049feee794f14cf1af88d05dae8139914"/>
- <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="84b7252b0a9d0edc9a1db1e0c518771d26b23058"/>
- <project name="platform/external/dnsmasq" path="external/dnsmasq" revision="a0f273e289166fa488bba261b2d431c9503aed0d"/>
- <project name="platform/external/dropbear" path="external/dropbear" revision="a34ddbe3819bc465968f3676c734b405e655f8b7"/>
- <project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="164ce36fe92b78b92575e56abd101209631b48fc"/>
- <project name="platform/external/elfutils" path="external/elfutils" revision="b23b2dfb354b3ccf5d1c5d39815f02e7048cf516"/>
- <project name="platform/external/expat" path="external/expat" revision="0af0cb3bc7519e567bd9daff3dcd315ab0134a99"/>
- <project name="platform/external/fdlibm" path="external/fdlibm" revision="0da5f683c9ddc9442af3b389b4220e91ccffb320"/>
- <project name="platform/external/flac" path="external/flac" revision="b38b3d2c53c22f542fd764f9d60ef19b49d42e1b"/>
- <project name="platform/external/freetype" path="external/freetype" revision="899c67b6cfcd2010784fbf08c5415af16c526e0c"/>
- <project name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="9241386b62c353302c2f9eccda0672685b252b4d"/>
- <project name="platform/external/genext2fs" path="external/genext2fs" revision="e11a9c7fe6f1cef99aad2f25afaea37b72fe9f93"/>
- <project name="platform/external/giflib" path="external/giflib" revision="9aef3ea079a57c98a9207f8c3b95a5dc08ee74b5"/>
- <project name="platform/external/gtest" path="external/gtest" revision="0f1ce3dd0b880b6ae0cf7f5413702b8ef542efb2"/>
- <project name="platform/external/harfbuzz" path="external/harfbuzz" revision="858f2d28ac741ef139f74bdbdbcefa7560f17c91"/>
- <project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="3309edccdbc2a92eb03a285abb27c1c1c4a88e43"/>
- <project name="platform/external/iproute2" path="external/iproute2" revision="1778c5571f3b9ed213a03ecc80adf74f570b4916"/>
- <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="f4cb1ee4b00abbfb6f968dc25818c23b4b47e584"/>
- <project name="platform/external/iptables" path="external/iptables" revision="ceedcd308d47976e31eda76a8852edd7f92837de"/>
- <project name="platform/external/jack" path="external/jack" revision="5ceb2025ac5d25ed48183ac2d3dac4691fe761fb"/>
- <project name="platform/external/jhead" path="external/jhead" revision="31b17e69a87e4caa50f9c6b1a47c84ef75f79d83"/>
- <project name="platform/external/jpeg" path="external/jpeg" revision="1808bfd1060d2fde90478691a4da8ead0cb0a345"/>
- <project name="platform/external/junit" path="external/junit" revision="01da89f7f8a8f9852e0ec1a490e7d2a0ee3785d5"/>
- <project name="platform/external/libgsm" path="external/libgsm" revision="50761abed8f4734970874165b386cfd4d9599db4"/>
- <project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
- <project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="9e987ccb716624d658f98abc7db2097e11e3d8ed"/>
- <project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
- <project name="platform/external/libogg" path="external/libogg" revision="ec0b24fb1468abe37be4164a6feb16568e036bde"/>
- <project name="platform/external/libpcap" path="external/libpcap" revision="3a7bce5dda6a8db92c9248846d0255e68c3a5b2a"/>
- <project name="platform/external/libpng" path="external/libpng" revision="cdf9c7fe4febaa4a7b3917d56d4180960e48800f"/>
- <project name="platform/external/libselinux" path="external/libselinux" revision="1e2cf2c4a2d15a9b1ca2d353b99fb6884413ffe1"/>
- <project name="platform/external/libsepol" path="external/libsepol" revision="edc447a138ec77236f1cbfd36c1211a38ba21418"/>
- <project name="platform/external/libvpx" path="external/libvpx" revision="ca9281af0bfe816f1ae2fc3e8771524164a0a03c"/>
- <project name="platform/external/mdnsresponder" path="external/mdnsresponder" remote="caf" revision="dd17df3f6775c4366a5c1d21865370d60a3b1295"/>
- <project name="platform/external/mksh" path="external/mksh" revision="f8c396c4d446a038358106a301b329607a04633d"/>
- <project name="platform/external/netcat" path="external/netcat" revision="444644cfa9a2f3002863caa168fb2d6b34dfd1e8"/>
- <project name="platform/external/openssl" path="external/openssl" revision="bb8428f762b3632f493572c4f73957e1281ade79"/>
- <project name="platform/external/protobuf" path="external/protobuf" revision="48ee66d295979372ed0234cefda42385daae8312"/>
- <project name="platform/external/safe-iop" path="external/safe-iop" revision="aa0725fb1da35e47676b6da30009322eb5ed59be"/>
- <project name="platform/external/scrypt" path="external/scrypt" revision="eb05b73c3bba21fff55529813109de4bad5ddbd1"/>
- <project name="platform/external/sepolicy" path="external/sepolicy" revision="6f50b84072d4920ce331226837ba794be72ea2b1"/>
- <project name="platform/external/sfntly" path="external/sfntly" revision="30d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cd"/>
- <project name="platform/external/skia" path="external/skia" revision="84a7058ba19c80ababd8c7c9eb379bf0babcc9ce"/>
- <project name="platform/external/sonivox" path="external/sonivox" revision="9fb2c53165b1512aa57db0bf1c757e3215e28eb8"/>
- <project name="platform/external/speex" path="external/speex" revision="fb7db5853ffb841a4d32fea8b5c3a43e6b875cae"/>
- <project name="platform/external/sqlite" path="external/sqlite" revision="ac0e0d5f866fbce0ebf00d0ddd615464849aa83b"/>
- <project name="platform/external/stlport" path="external/stlport" revision="628e14d37c5b239839a466e81c74bf66255b770b"/>
- <project name="platform/external/strace" path="external/strace" revision="1a4e05d53dec658a061acb9869cb1eb1342cd09d"/>
- <project name="platform/external/svox" path="external/svox" revision="b3c3bf3c1be35f3d455671de9f6d7b9bca3ce73a"/>
- <project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
- <project name="platform/external/tcpdump" path="external/tcpdump" revision="841663c88f0692202d57def239267e28cf832cdc"/>
- <project name="platform/external/tinyalsa" path="external/tinyalsa" revision="c1b682efcd3b3eac3101408231b58ea92c668756"/>
- <project name="platform/external/tinycompress" path="external/tinycompress" revision="a85e245a09c028d36cbf04f233be10bc583691f5"/>
- <project name="platform/external/tinyxml" path="external/tinyxml" revision="494e448824844d866e805831d1d5f5acb654065c"/>
- <project name="platform/external/tinyxml2" path="external/tinyxml2" revision="ead7a211773b9366466c6512cf945bc9dd1490a5"/>
- <project name="platform/external/tremolo" path="external/tremolo" revision="78772d5dde5a06eefae281b0dde224fcac46c4ff"/>
- <project name="platform/external/webp" path="external/webp" revision="513e97bd307573e2adc776eb5368bd129aceaa4a"/>
- <project name="platform/external/webrtc" path="external/webrtc" revision="446452f84e9cc4c75d8e80f6f05e24793397a19d"/>
- <project name="platform/external/yaffs2" path="external/yaffs2" revision="a2cff2275e1b501ff478b03757d6e4f05fddc2db"/>
- <project name="platform/external/zlib" path="external/zlib" revision="6eb3570ff8fa71bd83bb375b4bf09804c6089fed"/>
- <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="dbbe673145107e99883f62bafd70c5f43f11065c"/>
- <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="f0c3b4edf597c40aae4ea311575f39c8bcf203df"/>
- <project name="platform/libcore" path="libcore" revision="baf7d8068dd501cfa338d3a8b1b87216d6ce0571"/>
- <project name="platform/libnativehelper" path="libnativehelper" revision="50c4430e32849530ced32680fd6ee98963b3f7ac"/>
- <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
- <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="c739cffa6394c06e099ea48879a20341b6163338"/>
- <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
- <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
- <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
- <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="0a5aa7225129b792c19e91be88eac97a89c089b6"/>
- <project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
- <project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
- <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
- <project name="platform/system/vold" path="system/vold" revision="42fa2a0f14f965970a4b629a176bbd2666edf017"/>
- <project name="platform/external/curl" path="external/curl" revision="e68addd988448959ea8157c5de637346b4180c33"/>
- <project name="platform/external/icu4c" path="external/icu4c" revision="d3ec7428eb276db43b7ed0544e09344a6014806c"/>
- <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="76c4bf4bc430a1b8317f2f21ef735867733e50cc"/>
- <project name="platform/system/media" path="system/media" revision="c1332c21c608f4932a6d7e83450411cde53315ef"/>
- <default remote="caf" revision="LNX.LA.3.5.2.1.1" sync-j="4"/>
- <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a"/>
- <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="d9735fc81434f2af2c44d86ca57740c673c8d9bc"/>
- <!-- Platform common things -->
- <project name="device-shinano-common" path="device/sony/shinano-common" remote="b2g" revision="53dcf88a4314c05dae3464f7647138ad420398e6"/>
- <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
- <project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/>
- <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="559bc18796a7b97b7619ebf30042a09c3ae0398f"/>
- <project name="init_sh" path="external/init_sh" remote="b2g" revision="feb58d2b397e45ead9b904d5c4d9255df408db56"/>
- <project name="platform_bionic" path="bionic" remote="b2g" revision="3e85c4683c121530c1c3a48c696a569bf5f587e2"/>
- <project name="platform_external_bluetooth_bluedroid" path="external/bluetooth/bluedroid" remote="b2g" revision="70f536bd97d901b96b94669ae1aa2fd0fb54b258"/>
- <project name="platform_external_libnfc-nci" path="external/libnfc-nci" remote="b2g" revision="2a52bd77d2ca0cefbf02acc6863492d16b6ccfec"/>
- <project name="platform_external_libnfc-pn547" path="external/libnfc-pn547" remote="b2g" revision="5bb999b84b8adc14f6bea004d523ba258dea8188"/>
- <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="5b71e40213f650459e95d35b6f14af7e88d8ab62"/>
- <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="5d5bcc83d6c32874701f0df78ed1119e006bd10a"/>
- <project name="platform/frameworks/base" path="frameworks/base" revision="da8e6bc53c8bc669da0bb627904d08aa293f2497"/>
- <project name="platform/frameworks/native" path="frameworks/native" revision="a46a9f1ac0ed5662d614c277cbb14eb3f332f365"/>
- <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="7196881a0e9dd7bfbbcf0af64c8064e70f0fa094"/>
- <project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="15a9b66de9b7d84c7ea63df3a834f095bca9e493"/>
- <project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="8d7676dfb68ee0cd069affedd5d1e97316a184ba"/>
- <project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="2a1ded216a91bf62a72b1640cf01ab4998f37028"/>
- <project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="4a83e04c3fecffbcab75cd59bad2ae5f342778b7"/>
- <project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="9883ea57b0668d8f60dba025d4522dfa69a1fbfa"/>
- <project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="a558dc844bf5144fc38603fd8f4df8d9557052a5"/>
- <project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="57ee1320ed7b4a1a1274d8f3f6c177cd6b9becb2"/>
- <project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
- <project name="timekeep" path="hardware/sony/timekeep" remote="b2g" revision="460869402e019b122c4e5ffce19bfbbad026c0fe"/>
- <project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
- <project name="platform/system/core" path="system/core" revision="42839aedcf70bf6bc92a3b7ea4a5cc9bf9aef3f9"/>
- <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/>
- <project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
- <project name="platform/vendor/qcom/copper" path="device/qcom/msm8974" revision="ec7bc1a26610922156d7d412b4d3de6b4adb93da"/>
- <project name="vendor_broadcom_wlan" path="vendor/broadcom/wlan" remote="b2g" revision="114b9491a8a919687da4e22fbd89fab511d6d8d7"/>
- <project name="nginx" path="external/nginx" remote="b2g" revision="584bf310e21510e56af7e9dccd779eb7671118ef"/>
- <!-- Shinano specific things -->
- <project name="device-shinano" path="device/sony/leo" remote="b2g" revision="653f7e1f093b948e40262fcb3c665c2b4976df74"/>
- <!-- Aries specific things -->
- <project name="device-aries" path="device/sony/aries" remote="b2g" revision="791b8af16ec5f65366aa7a05aa0068c65018e882"/>
-</manifest>
diff --git a/b2g/config/desktop/config.json b/b2g/config/desktop/config.json
deleted file mode 100644
index ced2efa33..000000000
--- a/b2g/config/desktop/config.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "gaia": {
- "l10n": {
- "vcs": "hg",
- "root": "https://hg.mozilla.org/gaia-l10n"
- }
- }
-}
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
deleted file mode 100644
index 23934073b..000000000
--- a/b2g/config/gaia.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "git": {
- "git_revision": "60655051c0ae65a93da194ccffa7bd7a66800a60",
- "remote": "https://github.com/mozilla-b2g/gaia.git",
- "branch": "master"
- }
-}
diff --git a/b2g/config/mozconfigs/common b/b2g/config/mozconfigs/common
deleted file mode 100644
index 0ef93ae11..000000000
--- a/b2g/config/mozconfigs/common
+++ /dev/null
@@ -1,24 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# This file is included at the top of all b2g mozconfigs
-
-. "$topsrcdir/build/mozconfig.common"
-
-# Normally, we'd set this unconditionally, but this file is also used
-# for local builds and there is no other mozconfig in this tree that
-# is included on device builds.
-if test -d $topsrcdir/gcc/bin; then
- HOST_CC="$topsrcdir/gcc/bin/gcc"
- HOST_CXX="$topsrcdir/gcc/bin/g++"
- . "$topsrcdir/build/unix/mozconfig.stdcxx"
-fi
-
-# Allow overriding this from the environment, and don't
-# try to set it if it doesn't exist. As per above, this file is also
-# used for local builds, and we may need to override this for builds in
-# other environments.
-if test -z "$SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE" -a -f /builds/crash-stats-api.token; then
- export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
-fi
diff --git a/b2g/config/mozconfigs/common.override b/b2g/config/mozconfigs/common.override
deleted file mode 100644
index abe73b460..000000000
--- a/b2g/config/mozconfigs/common.override
+++ /dev/null
@@ -1,8 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# This file is included at the bottom of all b2g mozconfigs
-
-. "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
diff --git a/b2g/config/mozconfigs/ics_armv7a_gecko/debug b/b2g/config/mozconfigs/ics_armv7a_gecko/debug
deleted file mode 100644
index 1cacb8a75..000000000
--- a/b2g/config/mozconfigs/ics_armv7a_gecko/debug
+++ /dev/null
@@ -1,20 +0,0 @@
-. "$topsrcdir/b2g/config/mozconfigs/common"
-
-mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-b2g
-
-ac_add_options --enable-application=b2g
-ac_add_options --enable-b2g-camera
-
-ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-gonk="$topsrcdir/gonk-toolchain"
-export TOOLCHAIN_HOST=linux-x86
-export GONK_PRODUCT=generic
-ac_add_options --with-gonk-toolchain-prefix="$topsrcdir/gonk-toolchain/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-"
-ac_add_options --enable-debug-symbols
-ac_add_options --enable-debug
-ENABLE_MARIONETTE=1
-
-# Enable dump() from JS.
-export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/ics_armv7a_gecko/nightly b/b2g/config/mozconfigs/ics_armv7a_gecko/nightly
deleted file mode 100644
index c2f1ae0fa..000000000
--- a/b2g/config/mozconfigs/ics_armv7a_gecko/nightly
+++ /dev/null
@@ -1,21 +0,0 @@
-. "$topsrcdir/b2g/config/mozconfigs/common"
-
-mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-b2g
-
-ac_add_options --enable-application=b2g
-ac_add_options --enable-b2g-camera
-ac_add_options --enable-updater
-
-ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-gonk="$topsrcdir/gonk-toolchain"
-export TOOLCHAIN_HOST=linux-x86
-export GONK_PRODUCT=generic
-ac_add_options --with-gonk-toolchain-prefix="$topsrcdir/gonk-toolchain/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-"
-ac_add_options --enable-debug-symbols
-# ac_add_options --enable-profiling
-ENABLE_MARIONETTE=1
-
-# Enable dump() from JS.
-export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/linux32_gecko/debug b/b2g/config/mozconfigs/linux32_gecko/debug
deleted file mode 100644
index 7ecbda356..000000000
--- a/b2g/config/mozconfigs/linux32_gecko/debug
+++ /dev/null
@@ -1,34 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux32"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-ac_add_options --enable-debug
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-# Use sccache
-no_sccache=
-
-#B2G options
-ac_add_options --enable-application=b2g
-ENABLE_MARIONETTE=1
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/linux32_gecko/nightly b/b2g/config/mozconfigs/linux32_gecko/nightly
deleted file mode 100644
index 4cc78ca0e..000000000
--- a/b2g/config/mozconfigs/linux32_gecko/nightly
+++ /dev/null
@@ -1,36 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux32"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-# Use sccache
-no_sccache=
-
-#B2G options
-ac_add_options --enable-application=b2g
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-# Build simulator xpi and phone tweaks for b2g-desktop
-FXOS_SIMULATOR=1
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/linux64_gecko/nightly b/b2g/config/mozconfigs/linux64_gecko/nightly
deleted file mode 100644
index 67e7cea4f..000000000
--- a/b2g/config/mozconfigs/linux64_gecko/nightly
+++ /dev/null
@@ -1,36 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-# Use sccache
-no_sccache=
-
-#B2G options
-ac_add_options --enable-application=b2g
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-# Build simulator xpi and phone tweaks for b2g-desktop
-FXOS_SIMULATOR=1
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/macosx64_gecko/debug b/b2g/config/mozconfigs/macosx64_gecko/debug
deleted file mode 100644
index 1577e1f2e..000000000
--- a/b2g/config/mozconfigs/macosx64_gecko/debug
+++ /dev/null
@@ -1,33 +0,0 @@
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-
-# Use sccache
-no_sccache=
-
-. $topsrcdir/build/macosx/mozconfig.common
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-#ac_add_options --with-macbundlename-prefix=Firefox
-
-# B2G Stuff
-ac_add_options --enable-application=b2g
-ac_add_options --enable-debug-symbols
-ac_add_options --enable-debug
-ENABLE_MARIONETTE=1
-
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/macosx64_gecko/nightly b/b2g/config/mozconfigs/macosx64_gecko/nightly
deleted file mode 100644
index 2c9c01d67..000000000
--- a/b2g/config/mozconfigs/macosx64_gecko/nightly
+++ /dev/null
@@ -1,34 +0,0 @@
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-
-# Use sccache
-no_sccache=
-
-. $topsrcdir/build/macosx/mozconfig.common
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-#ac_add_options --with-macbundlename-prefix=Firefox
-
-# B2G Stuff
-ac_add_options --enable-application=b2g
-ac_add_options --enable-debug-symbols
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-# Build simulator xpi and phone tweaks for b2g-desktop
-FXOS_SIMULATOR=1
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/win32_gecko/debug b/b2g/config/mozconfigs/win32_gecko/debug
deleted file mode 100644
index ab34aa1f7..000000000
--- a/b2g/config/mozconfigs/win32_gecko/debug
+++ /dev/null
@@ -1,29 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-jemalloc
-ac_add_options --enable-signmar
-ac_add_options --enable-debug
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-. $topsrcdir/build/win32/mozconfig.vs-latest
-
-# B2G Options
-ac_add_options --enable-application=b2g
-ENABLE_MARIONETTE=1
-
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/mozconfigs/win32_gecko/nightly b/b2g/config/mozconfigs/win32_gecko/nightly
deleted file mode 100644
index 7e4486368..000000000
--- a/b2g/config/mozconfigs/win32_gecko/nightly
+++ /dev/null
@@ -1,30 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/b2g/config/mozconfigs/common"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-jemalloc
-ac_add_options --enable-signmar
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-export MOZ_TELEMETRY_REPORTING=1
-
-. $topsrcdir/build/win32/mozconfig.vs-latest
-
-# B2G Options
-ac_add_options --enable-application=b2g
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-GAIADIR=$topsrcdir/gaia
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-# Build simulator xpi and phone tweaks for b2g-desktop
-FXOS_SIMULATOR=1
-
-. "$topsrcdir/b2g/config/mozconfigs/common.override"
diff --git a/b2g/config/nexus-5-l/config.json b/b2g/config/nexus-5-l/config.json
deleted file mode 100644
index 7b8bada40..000000000
--- a/b2g/config/nexus-5-l/config.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "config_version": 2,
- "tooltool_manifest": "releng-nexus5.manifest",
- "mock_target": "mozilla-centos6-x86_64",
- "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
- "mock_files": [
- ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
- ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
- ],
- "build_targets": ["", "blobfree"],
- "upload_files": [
- "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
- "{objdir}/dist/b2g-*.tar.gz",
- "{workdir}/sources.xml",
- "{workdir}/out/target/product/nexus-5-l/fota-*-update-*.mar"
- ],
- "public_upload_files": [
- "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
- "{objdir}/dist/b2g-*.tar.gz",
- "{workdir}/sources.xml",
- "{objdir}/dist/b2g-update/*.mar",
- "{workdir}/hammerhead.zip",
- "{workdir}/out/target/product/nexus-5-l/fota-*-update.mar"
- ],
- "zip_files": [
- ["{workdir}/out/target/product/hammerhead/*.img", "out/target/product/hammerhead/"],
- ["{workdir}/boot.img", "out/target/product/hammerhead/"],
- "{workdir}/flash.sh",
- "{workdir}/gecko/b2g/installer/flash.bat",
- "{workdir}/prebuilts/misc/windows/win_flash_tools/*",
- "{workdir}/load-config.sh",
- "{workdir}/.config",
- "{workdir}/sources.xml",
- "{workdir}/profile.sh",
- ["{workdir}/gecko/tools/profiler/merge-profiles.py", "gecko/tools/profiler/"],
- ["{workdir}/scripts/profile-symbolicate.py", "scripts/"],
- ["{workdir}/gecko/tools/rb/fix_stack_using_bpsyms.py", "gecko/tools/rb/"]
- ],
- "env": {
- "VARIANT": "userdebug",
- "MOZILLA_OFFICIAL": "1",
- "MOZ_TELEMETRY_REPORTING": "1",
- "B2G_UPDATE_CHANNEL": "nightly"
- },
- "b2g_manifest": "nexus-5-l.xml",
- "b2g_manifest_intree": true,
- "additional_source_tarballs": [],
- "gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
- "gaia": {
- "l10n": {
- "vcs": "hg",
- "root": "https://hg.mozilla.org/gaia-l10n"
- }
- }
-}
diff --git a/b2g/config/nexus-5-l/releng-nexus5.manifest b/b2g/config/nexus-5-l/releng-nexus5.manifest
deleted file mode 100644
index f7851b4e3..000000000
--- a/b2g/config/nexus-5-l/releng-nexus5.manifest
+++ /dev/null
@@ -1,19 +0,0 @@
-[
-{
-"version": "Android NDK r11b for B2G",
-"algorithm": "sha512",
-"visibility": "internal",
-"filename": "android-ndk-b2g.tar.xz",
-"unpack": true,
-"digest": "bc37c6b2e38f4ff19e3326786312d8f893600e155d35dfba45163bd909e022db852b9c6920863cb498bbe7da8b86a6a387fa024bc9444ce3a8d1715cf2c24b21",
-"size": 292442020
-},
-{
-"version": "gcc 4.8.5 + PR64905",
-"size": 80160264,
-"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
-"algorithm": "sha512",
-"filename": "gcc.tar.xz",
-"unpack": "True"
-}
-]
diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml
deleted file mode 100644
index 0419408a3..000000000
--- a/b2g/config/nexus-5-l/sources.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" ?><manifest>
- <!--
- Remotes
- -->
- <remote fetch="git://github.com/apitrace/" name="apitrace"/>
- <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
- <remote fetch="git://codeaurora.org/" name="caf"/>
- <!--
- B2G repositories for all targets
- -->
- <project name="gaia" path="gaia" remote="b2g" revision="f5d355dfeb559e11fad48901b0bea287ec33b874"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
- <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
- <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
- <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
- <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="f1a61fa8f97cc0a1ac4eca160acc222981b21d90"/>
- <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3618678c472320de386f5ddc27897992d0e148a8"/>
- <!-- B2G specific things. -->
- <project name="platform_build" path="build" remote="b2g" revision="63ae12cb8ca32cbbd7ef8292582f2ac2a1587a0b">
- <copyfile dest="Makefile" src="core/root.mk"/>
- </project>
- <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
- <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
- <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
- <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c5a77c651bcde37005e6b6e209747edcc6c9361"/>
- <!-- Stock Android things -->
- <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
- <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
- <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
- <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
- <project depth="1" groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" remote="caf" revision="c09e1b3a55153d1ba142d5bf548c90487ea71f9e"/>
- <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
- <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
- <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
- <project depth="1" groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" remote="caf" revision="c33513f9de95fcdf4ec832db5e3ebd612382f541"/>
- <project groups="linux" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="ab14644af0429dfb6744e9709f9ef46fb7bf73e4"/>
- <project name="device/common" path="device/common" revision="05f67c8cf7b9669da6f37f74b3388b594e319b84"/>
- <project name="device/sample" path="device/sample" revision="298675b60a633253434c4829339534c08292dc92"/>
- <project name="platform/abi/cpp" path="abi/cpp" revision="39fd88f57cec1dd6e9c70f85ab0c76587f7ba766"/>
- <project name="platform/bionic" path="bionic" revision="7741d30da4f0f0c15e6622ca75ad396e78eab7dd"/>
- <project name="platform/bootable/recovery" path="bootable/recovery" revision="c9ef7996198ad29e706b352cbb773a7dad5bdc5c"/>
- <project name="platform/external/aac" path="external/aac" revision="78fdf0627dd31f77fe71fde289512f749032a787"/>
- <project name="platform/external/bison" path="external/bison" revision="4efa7909d921823fbfcf85f5c64ad3578803e2ee"/>
- <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="cdae70948d67a920e8847ad0323ff11f51dbcaf9"/>
- <project name="platform/external/bsdiff" path="external/bsdiff" revision="d7a2c5578467c3b8375943bee09c20a692d8d2a0"/>
- <project name="platform/external/bzip2" path="external/bzip2" revision="c41fb467156106c6274c12e1279fbd5340757667"/>
- <project name="platform/external/checkpolicy" path="external/checkpolicy" revision="a1d60ce948816137de49ea0737d9a9d6b54adab7"/>
- <project name="platform/external/clang" path="external/clang" revision="6c6bfc254506351c5753de7e2fe3eab6bca40d2b"/>
- <project name="platform/external/compiler-rt" path="external/compiler-rt" revision="3b8d597882284a3694b9bca7500ee9d9a4f02683"/>
- <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="72519f06fc08fe450607e040544267cd0befdee3"/>
- <project name="platform/external/dnsmasq" path="external/dnsmasq" revision="6e8e5151469e8da0eadb894813201f5e87e7ad66"/>
- <project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="566faf84e682b1e8233ed9853c9a0a4dd8c3bc37"/>
- <project name="platform/external/elfutils" path="external/elfutils" revision="5084a43adc8ae0de74888842a47d33d66f3fd2ca"/>
- <project name="platform/external/expat" path="external/expat" revision="47e857874d4a893bc90288f98f392448151cf741"/>
- <project name="platform/external/f2fs-tools" path="external/f2fs-tools" revision="fc24ac8347630a14d62ffafa93a27ec3b81cc44b"/>
- <project name="platform/external/fdlibm" path="external/fdlibm" revision="f24510089e8b5cb533c0406fd2e9c5a8eb1b201b"/>
- <project name="platform/external/flac" path="external/flac" revision="ae2004f637dd0eb68d763f441d3ff1cf285d42b4"/>
- <project name="platform/external/freetype" path="external/freetype" revision="a177e10e69985dc9640b89f615e1c0b61fb4f0f4"/>
- <project name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="9d1a7f107acea987ed2440c0a310a6c42f667bd7"/>
- <project name="platform/external/genext2fs" path="external/genext2fs" revision="c7e3aae061a272caa34e5a465edd9927cde42ac8"/>
- <project name="platform/external/giflib" path="external/giflib" revision="f0f278e928db903456cbbc2dfff2a678c31a9d27"/>
- <project name="platform/external/gtest" path="external/gtest" revision="5d13a30f9978eb09254ebc83ae51d6a730eec215"/>
- <project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="647fa898029679d4fac6958332c88c5f3f169439"/>
- <project name="platform/external/icu" path="external/icu" revision="a41b209dc1f9836733c59a30e862784e8895ac7c"/>
- <project name="platform/external/iproute2" path="external/iproute2" revision="acf444b6a524b4bce5b7cfe81b29e2839ff6e508"/>
- <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="bf460d6fcb58d7f8e95f5d3ab9ffa2e7e16c2957"/>
- <project name="platform/external/iptables" path="external/iptables" revision="11beff4f1ad782fd1d8e5c1857f2c2088abb42f6"/>
- <project name="platform/external/jack" path="external/jack" revision="cd80e83b301ac9c5a845d8d01dc73084891cd19d"/>
- <project name="platform/external/jemalloc" path="external/jemalloc" revision="a6a05e48b628346ec4342f8b6d1c3d0a5987236e"/>
- <project name="platform/external/jhead" path="external/jhead" revision="3b6bb83af87698537d150ee004ba27720af50f54"/>
- <project name="platform/external/jpeg" path="external/jpeg" revision="b5c22f7648e1b03241abb05733aec47e2bf66462"/>
- <project name="platform/external/jsmn" path="external/jsmn" revision="646c4a36fd8cdb1ecd2080963bd26d9e245473c5"/>
- <project name="platform/external/jsoncpp" path="external/jsoncpp" revision="d9d8c51470b0cd2b95219c6b596ef90ae7915b8e"/>
- <project name="platform/external/junit" path="external/junit" revision="a9d933b7f8f42007de21bc674a61d491e14b48df"/>
- <project name="platform/external/libcxxabi" path="external/libcxxabi" revision="31349d4fd0a2ee4744d1cade9fa774dd2213be80"/>
- <project name="platform/external/libcxx" path="external/libcxx" revision="7cff60f9e680dc58c9a913eddc049946e3616265"/>
- <project name="platform/external/libgsm" path="external/libgsm" revision="7f76ac798f682fed4662c789010050789eabee89"/>
- <project name="platform/external/liblzf" path="external/liblzf" revision="0e6384fa203d8c7499fe64c9e93930df8e50cc99"/>
- <project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="13c47f6dfcd78c59243e997b5df30c5155949d59"/>
- <project name="platform/external/libnl" path="external/libnl" revision="b1e000e9a7b0048a5e8335a32125b405bd77c53b"/>
- <project name="platform/external/libogg" path="external/libogg" revision="9a2354608fdae6e105b28d4456a94146e41616c7"/>
- <project name="platform/external/libopus" path="external/libopus" revision="46be742257e102568f59c3ce18e322cf0b258799"/>
- <project name="platform/external/libpcap" path="external/libpcap" revision="03c8b18ba58ac3347c18875779e162c75c652715"/>
- <project name="platform/external/libpng" path="external/libpng" revision="8eac982ec2415fbc83e5a61899e0ca7eba4fe96d"/>
- <project name="platform/external/libselinux" path="external/libselinux" revision="317bc4b75ea40dfb5988c12f607505a86c6c2823"/>
- <project name="platform/external/libsepol" path="external/libsepol" revision="24b924ffd20dbf7359a9e15a10a8d1cfd6309597"/>
- <project name="platform/external/libunwind" path="external/libunwind" revision="e3fa64fe20e4eaf13c2231727158bd5fac4e53ec"/>
- <project name="platform/external/libvpx" path="external/libvpx" revision="652843c7218cdfcd42c98a839b72941d0e4696ba"/>
- <project name="platform/external/llvm" path="external/llvm" revision="63e3c6329893697af239dae0ddab843a3e1623a3"/>
- <project name="platform/external/mdnsresponder" path="external/mdnsresponder" revision="32a5f67c10e0b87cf95bbbaad489b8e3f098eb01"/>
- <project name="platform/external/mksh" path="external/mksh" revision="c452c566cd6face953c9e33d01c4df652d39fdf6"/>
- <project name="platform/external/netcat" path="external/netcat" revision="00d9d6b1aa7772c96878db17d556f29150705be8"/>
- <project name="platform/external/openssl" path="external/openssl" revision="bf4112b16f0ede8128ba7ff3c17a0056834b7c75"/>
- <project name="platform/external/pcre" path="external/pcre" revision="89b3b9780dbdd7c682b9bf2efd0f476a1ebc5d33"/>
- <project name="platform/external/protobuf" path="external/protobuf" revision="cdb14929d7c934944079ce070f5eb2f9459f824c"/>
- <project name="platform/external/safe-iop" path="external/safe-iop" revision="33d0429591d345687755c25f23ea2e46df5cd293"/>
- <project name="platform/external/scrypt" path="external/scrypt" revision="d809e38af0d89747cde00970271fb64d42333302"/>
- <project name="platform/external/sfntly" path="external/sfntly" revision="d2bab207acad60e098d0652b5ed7348c96a249f3"/>
- <project name="platform/external/skia" path="external/skia" revision="b0fe7c355d4d95ff89b8e9e459285fe2b98e366d"/>
- <project name="platform/external/sonivox" path="external/sonivox" revision="3d04f03d824d5ea8835e577785b51022820ae763"/>
- <project name="platform/external/speex" path="external/speex" revision="9d73341cd881c415e6fce726ea4918654cd03145"/>
- <project name="platform/external/sqlite" path="external/sqlite" revision="2394fd03445b9496025558d4e48a54c09180e132"/>
- <project name="platform/external/stlport" path="external/stlport" revision="49f98215d1dea7f96f7560528bc8528570e2e05b"/>
- <project name="platform/external/strace" path="external/strace" revision="a093fa84778892c96159ccee02dc8d6c4378a124"/>
- <project name="platform/external/svox" path="external/svox" revision="7543f63ace85c9812dfc5263d63ed190eebb7f1c"/>
- <project name="platform/external/tagsoup" path="external/tagsoup" revision="5ad81cc518df943dbff3a566f3db5a3aae4b3098"/>
- <project name="platform/external/tcpdump" path="external/tcpdump" revision="f28770c517d9ca78bf25779d833da2d8a3aa1c61"/>
- <project name="platform/external/tinyalsa" path="external/tinyalsa" revision="73444308ffa76f7df107c9b5c8eb657d2a212017"/>
- <project name="platform/external/tinycompress" path="external/tinycompress" revision="d65aa7ba2e7548452906d3d61ee03c94cc64f25d"/>
- <project name="platform/external/tinyxml2" path="external/tinyxml2" revision="ea87469657dd498dd76ea01b35daab9d48503a3c"/>
- <project name="platform/external/tinyxml" path="external/tinyxml" revision="d09b587fe9bd7f1524d434c15941a5483c2d7046"/>
- <project name="platform/external/tremolo" path="external/tremolo" revision="7954026e4cbeeaa4bb7d7e2c82a6556ea34c58ab"/>
- <project name="platform/external/webp" path="external/webp" revision="5df3d5cb644f301e4a0c78b939e411b061a36558"/>
- <project name="platform/external/webrtc" path="external/webrtc" revision="de40077759a01a02a3e21b30ea0755f2d6fc4e09"/>
- <project name="platform/external/yaffs2" path="external/yaffs2" revision="b2aadfdf9482777530efac1fb13a25ff401e78ee"/>
- <project name="platform/external/zlib" path="external/zlib" revision="a9dc8ffc4b43f0ff455d52fc5a889e92794962a4"/>
- <project name="platform/external/zopfli" path="external/zopfli" revision="8b994159cf3fc74a58e42fca72bc6849e6027912"/>
- <project name="platform_frameworks_native" path="frameworks/native" remote="b2g" revision="77c23f8067bca84476f96d663efaae636817edd5"/>
- <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="2293192ed15b88ebe962fb5377dd197200e6472b"/>
- <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="f5feb2aa2047fbaf13be448fe8d06bff3ccf7b84"/>
- <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="8d075b4d5e9e032b18fbc8b5def63827d1b4a30d"/>
- <project name="platform/libcore" path="libcore" revision="bdec7d684c083760bef7bc4ba2429cceccaaf7d0"/>
- <project name="platform/libnativehelper" path="libnativehelper" revision="27bcc086236cedd31c056303e255c6d0ea3d4a50"/>
- <project name="platform/ndk" path="ndk" revision="42e85f81cc6c74af145056ee80b06e520cccb9a7"/>
- <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="25b96077aeae7bd0e3a5e7c284fb636664337013"/>
- <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="1d080491f26dfdfd76d5bbc3e6b40c660e8565af"/>
- <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="61a10cbd19d6b7fc052a8cb92dfa1b37b93754f3"/>
- <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="9e892a67a01671f312c76b0880dedaa6ba478148"/>
- <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="0a5aa7225129b792c19e91be88eac97a89c089b6"/>
- <project name="platform/system/extras" path="system/extras" revision="47fa016e2248b80aebd5928402c7409f8e0ca64e"/>
- <project name="platform/system/media" path="system/media" revision="70bfebc66d9c6a4c614a8c7efde90e8e7e1d8641"/>
- <project name="platform/system/netd" path="system/netd" revision="d113f0ceefa9ce29eb3c86e2d23c7417a70b4048"/>
- <project name="platform/system/security" path="system/security" revision="94e1617f6f2bc2286d005e79cffa6bf0721b06b3"/>
- <project name="platform/system/vold" path="system/vold" revision="c065e301e38ea0c241164e2a373e1ecefbeaf2ec"/>
- <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="479a404164986b3e95212eecdae7e67da4fba9ed"/>
- <project name="platform_frameworks_base" path="frameworks/base" remote="b2g" revision="396b731dbccc62f272f1fdb8228109c3fbd83c25"/>
- <project name="platform_frameworks_wilhelm" path="frameworks/wilhelm" remote="b2g" revision="174bb44bb9af7583e6337e1e1b6cc18d0217ae82"/>
- <project name="platform_system_core" path="system/core" remote="b2g" revision="1b8322b228f717ff2a4d48fa8b44240d8e3f62bc"/>
- <project name="platform_external_sepolicy" path="external/sepolicy" remote="b2g" revision="246c603d9fe181fa8893af7293dbc63e870fe5e0"/>
- <default remote="caf" revision="refs/tags/android-5.1.0_r1" sync-j="4"/>
- <!-- Nexus 5 specific things -->
- <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="fe7df1bc8dd0fd71571505d7be1c31a4ad1e40fb"/>
- <project name="device-hammerhead" path="device/lge/hammerhead" remote="b2g" revision="acbb7a8914059426180c9059fc9419e57668a478"/>
- <project name="device_lge_hammerhead-kernel" path="device/lge/hammerhead-kernel" remote="b2g" revision="8b3ffcfdd3d3852eca5488628f8bb2a08acbffa7"/>
- <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="5d0ae53d9588c3d70c005aec9be94af9a534de16"/>
- <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="c15b6e266136cd0cdd9b94d0bbed1962d9dd6672"/>
- <project name="platform/hardware/broadcom/libbt" path="hardware/broadcom/libbt" revision="399fe3d3c8f38c599a56becddc456133e62a5d70"/>
- <project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="3f3134d5cb19d5ace48d36d0100467a545d430eb"/>
- <project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="810c3dd29d009822a71eba9910e429a9ad114533"/>
- <project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="7b5967bbd90cb193b489d8f8668bc945384bd9b1"/>
- <project name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="eaede9f8bc206736a889bc57817047c31e205589"/>
- <project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="12364db20d6710f0003a4f00962c9790ad3c13e3"/>
- <project name="platform/hardware/qcom/msm8x74" path="hardware/qcom/msm8x74" revision="f09920b2b488cf68bcbe9f7bbbde84a509a1d7a5"/>
- <project name="platform/hardware/qcom/power" path="hardware/qcom/power" revision="29e9aeaf278b16fea4cb1ab4d05b8b8c9083c15b"/>
- <project name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="fde83fdf67e9b919f8a49008725bd595221bf33f"/>
- <project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="6417804bea95f6e46094a01a06025a86e28c5b0d"/>
- <project name="platform/hardware/ril" path="hardware/ril" revision="e00d716e7e3d31729f75399855b6921e90cb0b66"/>
- <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/>
-</manifest>
diff --git a/b2g/config/tooltool-manifests/linux32/releng.manifest b/b2g/config/tooltool-manifests/linux32/releng.manifest
deleted file mode 100644
index c1fd5eac1..000000000
--- a/b2g/config/tooltool-manifests/linux32/releng.manifest
+++ /dev/null
@@ -1,32 +0,0 @@
-[
-{
-"version": "gcc 4.8.5 + PR64905",
-"size": 80160264,
-"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
-"algorithm": "sha512",
-"filename": "gcc.tar.xz",
-"unpack": true
-},
-{
-"size": 11189216,
-"digest": "18bc52b0599b1308b667e282abb45f47597bfc98a5140cfcab8da71dacf89dd76d0dee22a04ce26fe7ad1f04e2d6596991f9e5b01fd2aaaab5542965f596b0e6",
-"algorithm": "sha512",
-"filename": "gtk3.tar.xz",
-"setup": "setup.sh",
-"unpack": true
-},
-{
-"size": 167175,
-"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"algorithm": "sha512",
-"filename": "sccache.tar.bz2",
-"unpack": true
-},
-{
-"size": 31078810,
-"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"algorithm": "sha512",
-"filename": "moz-tt.tar.bz2",
-"unpack": true
-}
-]
diff --git a/b2g/config/tooltool-manifests/macosx64/releng.manifest b/b2g/config/tooltool-manifests/macosx64/releng.manifest
deleted file mode 100644
index 33158d8dc..000000000
--- a/b2g/config/tooltool-manifests/macosx64/releng.manifest
+++ /dev/null
@@ -1,24 +0,0 @@
-[
-{
-"version": "clang 3.8.0",
-"size": 133060926,
-"digest": "aff5ad3ac2d41db19d1ba0df5f97b189a7d7e1b6af8c56e22c2b0cced84d75fa98394ded6a4ba5713652e6684a0a46f47aeccf87991f9e849bf8d7d82e564f6f",
-"algorithm": "sha512",
-"filename": "clang.tar.bz2",
-"unpack": true
-},
-{
-"size": 167175,
-"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"algorithm": "sha512",
-"filename": "sccache.tar.bz2",
-"unpack": true
-},
-{
-"size": 31078810,
-"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"algorithm": "sha512",
-"filename": "moz-tt.tar.bz2",
-"unpack": true
-}
-]
diff --git a/b2g/config/tooltool-manifests/win32/releng.manifest b/b2g/config/tooltool-manifests/win32/releng.manifest
deleted file mode 100644
index f0592ee14..000000000
--- a/b2g/config/tooltool-manifests/win32/releng.manifest
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-{
-"size": 266240,
-"digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
-"algorithm": "sha512",
-"filename": "mozmake.exe"
-},
-{
-"size": 31078810,
-"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"algorithm": "sha512",
-"filename": "moz-tt.tar.bz2",
-"unpack": true
-},
-{
-"size": 167175,
-"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"algorithm": "sha512",
-"filename": "sccache.tar.bz2",
-"unpack": true
-}
-]
diff --git a/b2g/confvars.sh b/b2g/confvars.sh
deleted file mode 100644
index 64c42caf6..000000000
--- a/b2g/confvars.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOZ_APP_BASENAME=B2G
-MOZ_APP_VENDOR=Mozilla
-
-MOZ_APP_VERSION=$FIREFOX_VERSION
-MOZ_APP_UA_NAME=Firefox
-
-MOZ_UA_OS_AGNOSTIC=1
-
-MOZ_B2G_VERSION=2.6.0.0-prerelease
-MOZ_B2G_OS_NAME=Boot2Gecko
-
-MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
-MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
-# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
-
-MOZ_NO_SMART_CARDS=1
-MOZ_APP_STATIC_INI=1
-
-if test "$OS_TARGET" = "Android"; then
-MOZ_CAPTURE=1
-MOZ_RAW=1
-MOZ_AUDIO_CHANNEL_MANAGER=1
-fi
-
-# use custom widget for html:select
-MOZ_USE_NATIVE_POPUP_WINDOWS=1
-
-MOZ_XULRUNNER=
-
-MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
-
-MOZ_TIME_MANAGER=1
-
-MOZ_TOOLKIT_SEARCH=
-MOZ_B2G=1
-
-MOZ_JSDOWNLOADS=1
-
-MOZ_BUNDLED_FONTS=1
-
-export JS_GC_SMALL_CHUNK_SIZE=1
diff --git a/b2g/dev/app.mozbuild b/b2g/dev/app.mozbuild
deleted file mode 100644
index 041991547..000000000
--- a/b2g/dev/app.mozbuild
+++ /dev/null
@@ -1,21 +0,0 @@
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include('/toolkit/toolkit.mozbuild')
-
-if CONFIG['MOZ_EXTENSIONS']:
- DIRS += ['/extensions']
-
-DIRS += ['/%s' % CONFIG['MOZ_BRANDING_DIRECTORY']]
-
-DIRS += [
- '/b2g/chrome',
- '/b2g/components',
- '/b2g/dev/app',
-
- # Never add dirs after browser because they apparently won't get
- # packaged properly on Mac.
- '/browser',
-]
diff --git a/b2g/dev/app/moz.build b/b2g/dev/app/moz.build
deleted file mode 100644
index 2f162d7e9..000000000
--- a/b2g/dev/app/moz.build
+++ /dev/null
@@ -1,15 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIST_SUBDIR = 'browser'
-export('DIST_SUBDIR')
-
-JS_PREFERENCE_PP_FILES += [
- '../../app/b2g.js',
-]
-
-JS_PREFERENCE_FILES += [
- 'mulet.js',
-]
-
diff --git a/b2g/dev/app/mulet.js b/b2g/dev/app/mulet.js
deleted file mode 100644
index 7be519855..000000000
--- a/b2g/dev/app/mulet.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Automatically open b2g in a tab
-pref("browser.startup.homepage", "chrome://b2g/content/shell.html");
-
-// Disable some painful behavior of fx
-pref("startup.homepage_welcome_url", "");
-pref("browser.shell.checkDefaultBrowser", "");
-pref("browser.sessionstore.max_tabs_undo", 0);
-pref("browser.sessionstore.max_windows_undo", 0);
-pref("browser.sessionstore.restore_on_demand", false);
-pref("browser.sessionstore.resume_from_crash", false);
-
-// Display the devtools on the right of the phone
-pref("devtools.toolbox.host", "side");
-pref("devtools.toolbox.sidebar.width", 800);
-
-// Disable e10s as we don't want to run shell.html,
-// nor the system app OOP, but only inner apps
-pref("browser.tabs.remote.autostart", false);
-pref("browser.tabs.remote.autostart.1", false);
-pref("browser.tabs.remote.autostart.2", false);
diff --git a/b2g/dev/build.mk b/b2g/dev/build.mk
deleted file mode 100644
index daa4e7ac2..000000000
--- a/b2g/dev/build.mk
+++ /dev/null
@@ -1,6 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/browser/build.mk
-
diff --git a/b2g/dev/config/mozconfigs/linux64/mulet b/b2g/dev/config/mozconfigs/linux64/mulet
deleted file mode 100644
index 4aaa6b78d..000000000
--- a/b2g/dev/config/mozconfigs/linux64/mulet
+++ /dev/null
@@ -1,10 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
-
-ac_add_options --enable-application=b2g/dev
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
diff --git a/b2g/dev/config/mozconfigs/linux64/mulet-hazards b/b2g/dev/config/mozconfigs/linux64/mulet-hazards
deleted file mode 100644
index 2c3609c99..000000000
--- a/b2g/dev/config/mozconfigs/linux64/mulet-hazards
+++ /dev/null
@@ -1,13 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
-
-ac_add_options --enable-application=b2g/dev
-ac_add_options --with-compiler-wrapper=$TOOLTOOL_DIR/sixgill/usr/libexec/sixgill/scripts/wrap_gcc/basecc
-ac_add_options --without-ccache
-ac_add_options --disable-warnings-as-errors
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
diff --git a/b2g/dev/config/mozconfigs/linux64/mulet_dbg b/b2g/dev/config/mozconfigs/linux64/mulet_dbg
deleted file mode 100644
index 08baad0e9..000000000
--- a/b2g/dev/config/mozconfigs/linux64/mulet_dbg
+++ /dev/null
@@ -1,14 +0,0 @@
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
-
-ac_add_options --enable-application=b2g/dev
-ac_add_options --enable-debug
-MOZ_DEMANGLE_SYMBOLS=1
-MOZ_DEBUG=1
-MOZ_DEBUG_SYMBOLS=1
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
diff --git a/b2g/dev/config/mozconfigs/macosx64/mulet b/b2g/dev/config/mozconfigs/macosx64/mulet
deleted file mode 100644
index b6f1338ca..000000000
--- a/b2g/dev/config/mozconfigs/macosx64/mulet
+++ /dev/null
@@ -1,27 +0,0 @@
-MOZ_AUTOMATION_BUILD_SYMBOLS=0
-MOZ_AUTOMATION_PACKAGE_TESTS=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. $topsrcdir/build/macosx/mozconfig.common
-
-ac_add_options --enable-application=b2g/dev
-ac_add_options --disable-install-strip
-ac_add_options --enable-signmar
-ac_add_options --enable-profiling
-ac_add_options --enable-instruments
-ac_add_options --enable-dtrace
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-ac_add_options --with-macbundlename-prefix=Firefox
-
-# Package js shell.
-export MOZ_PACKAGE_JSSHELL=1
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
-
-. "$topsrcdir/build/mozconfig.common.override"
-. "$topsrcdir/build/mozconfig.cache"
diff --git a/b2g/dev/config/mozconfigs/win32/mulet b/b2g/dev/config/mozconfigs/win32/mulet
deleted file mode 100644
index f5a43bd6a..000000000
--- a/b2g/dev/config/mozconfigs/win32/mulet
+++ /dev/null
@@ -1,13 +0,0 @@
-MOZ_AUTOMATION_BUILD_SYMBOLS=0
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_PACKAGE_TESTS=0
-MOZ_AUTOMATION_INSTALLER=0
-MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
-MOZ_AUTOMATION_UPDATE_PACKAGING=0
-MOZ_AUTOMATION_SDK=0
-. "$topsrcdir/browser/config/mozconfigs/win32/nightly"
-
-ac_add_options --enable-application=b2g/dev
-
-# Include Firefox OS fonts.
-MOZTTDIR=$topsrcdir/moz-tt
diff --git a/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest b/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
deleted file mode 100644
index 10a722c43..000000000
--- a/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
+++ /dev/null
@@ -1,48 +0,0 @@
-[
-{
-"size" : 102421980,
-"digest" : "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
-"version" : "gcc 4.9.3",
-"unpack" : true,
-"filename" : "gcc.tar.xz",
-"algorithm" : "sha512"
-},
-{
-"unpack" : true,
-"algorithm" : "sha512",
-"filename" : "sixgill.tar.xz",
-"hg_id" : "8cb9c3fb039a+ tip",
-"digest" : "36dc644e24c0aa824975ad8f5c15714445d5cb064d823000c3cb637e885199414d7df551e6b99233f0656dcf5760918192ef04113c486af37f3c489bb93ad029",
-"size" : 2631908
-},
-{
-"algorithm" : "sha512",
-"filename" : "gtk3.tar.xz",
-"setup" : "setup.sh",
-"unpack" : true,
-"digest" : "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
-"size" : 12072532
-},
-{
-"version": "rustc 1.13.0 (2c6933acc 2016-11-07) repack",
-"size": 68921028,
-"digest": "9a9ceccc02d4be445ffa64617683419a4f47990b1f2689980ac8db13d6369435ef4af1a3714d77377fb7b3b0ec213856ab7144ff22cbe0881d49aed44d82c0fc",
-"algorithm": "sha512",
-"filename": "rustc.tar.xz",
-"unpack": true
-},
-{
-"algorithm" : "sha512",
-"filename" : "sccache.tar.bz2",
-"unpack" : true,
-"digest" : "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"size" : 167175
-},
-{
-"filename" : "moz-tt.tar.bz2",
-"algorithm" : "sha512",
-"unpack" : true,
-"digest" : "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"size" : 31078810
-}
-]
diff --git a/b2g/dev/config/tooltool-manifests/linux64/releng.manifest b/b2g/dev/config/tooltool-manifests/linux64/releng.manifest
deleted file mode 100644
index d356dbaa3..000000000
--- a/b2g/dev/config/tooltool-manifests/linux64/releng.manifest
+++ /dev/null
@@ -1,48 +0,0 @@
-[
-{
-"version": "gcc 4.9.3",
-"size": 102421980,
-"digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
-"algorithm": "sha512",
-"filename": "gcc.tar.xz",
-"unpack": true
-},
-{
-"size": 12072532,
-"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
-"algorithm": "sha512",
-"filename": "gtk3.tar.xz",
-"setup": "setup.sh",
-"unpack": true
-},
-{
-"version": "rustc 1.13.0 (2c6933acc 2016-11-07) repack",
-"size": 68921028,
-"digest": "9a9ceccc02d4be445ffa64617683419a4f47990b1f2689980ac8db13d6369435ef4af1a3714d77377fb7b3b0ec213856ab7144ff22cbe0881d49aed44d82c0fc",
-"algorithm": "sha512",
-"filename": "rustc.tar.xz",
-"unpack": true
-},
-{
-"version": "cargo 0.13.0-nightly (eca9e15 2016-11-01) repack",
-"size": 3027932,
-"digest": "a5c99eeb12b3b9b49632c259c762e34ec13cf72dadf90a0608b8ab1dc66b36cb114c5b45f71d326e12d31d9e88a41b029e6a728ca64cef392c0a8d211c2fe191",
-"algorithm": "sha512",
-"filename": "cargo.tar.xz",
-"unpack": true
-},
-{
-"size": 167175,
-"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"algorithm": "sha512",
-"filename": "sccache.tar.bz2",
-"unpack": true
-},
-{
-"size": 31078810,
-"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"algorithm": "sha512",
-"filename": "moz-tt.tar.bz2",
-"unpack": true
-}
-]
diff --git a/b2g/dev/config/tooltool-manifests/macosx64/releng.manifest b/b2g/dev/config/tooltool-manifests/macosx64/releng.manifest
deleted file mode 100644
index 33158d8dc..000000000
--- a/b2g/dev/config/tooltool-manifests/macosx64/releng.manifest
+++ /dev/null
@@ -1,24 +0,0 @@
-[
-{
-"version": "clang 3.8.0",
-"size": 133060926,
-"digest": "aff5ad3ac2d41db19d1ba0df5f97b189a7d7e1b6af8c56e22c2b0cced84d75fa98394ded6a4ba5713652e6684a0a46f47aeccf87991f9e849bf8d7d82e564f6f",
-"algorithm": "sha512",
-"filename": "clang.tar.bz2",
-"unpack": true
-},
-{
-"size": 167175,
-"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"algorithm": "sha512",
-"filename": "sccache.tar.bz2",
-"unpack": true
-},
-{
-"size": 31078810,
-"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"algorithm": "sha512",
-"filename": "moz-tt.tar.bz2",
-"unpack": true
-}
-]
diff --git a/b2g/dev/config/tooltool-manifests/win32/releng.manifest b/b2g/dev/config/tooltool-manifests/win32/releng.manifest
deleted file mode 100644
index a5f5e436a..000000000
--- a/b2g/dev/config/tooltool-manifests/win32/releng.manifest
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-{
-"size": 266240,
-"digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869",
-"algorithm": "sha512",
-"filename": "mozmake.exe"
-},
-{
-"size": 167175,
-"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"algorithm": "sha512",
-"filename": "sccache.tar.bz2",
-"unpack": true
-},
-{
-"size": 31078810,
-"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"algorithm": "sha512",
-"filename": "moz-tt.tar.bz2",
-"unpack": true
-}
-]
diff --git a/b2g/dev/confvars.sh b/b2g/dev/confvars.sh
deleted file mode 100644
index 4fb0b58a1..000000000
--- a/b2g/dev/confvars.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#! /bin/sh
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOZ_B2G=1
-MOZ_MULET=1
-
-. ${srcdir}/browser/confvars.sh
-
-MOZ_BUNDLED_FONTS=1
-MOZ_UA_OS_AGNOSTIC=1
diff --git a/b2g/dev/moz.configure b/b2g/dev/moz.configure
deleted file mode 100644
index d1b944eb5..000000000
--- a/b2g/dev/moz.configure
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-imply_option('MOZ_SERVICES_SYNC', True)
-
-include('../common.configure')
diff --git a/b2g/gaia/Makefile.in b/b2g/gaia/Makefile.in
deleted file mode 100644
index 0820b16a4..000000000
--- a/b2g/gaia/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-GAIA_PATH := gaia/profile
-
-GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
-
-include $(topsrcdir)/config/rules.mk
-
-libs::
- +$(MAKE) -j1 -C $(GAIADIR) clean
- +$(MAKE) -j1 -C $(GAIADIR) profile
- (cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(ABS_DIST)/bin/$(GAIA_PATH) && tar -xf -)
diff --git a/b2g/gaia/moz.build b/b2g/gaia/moz.build
deleted file mode 100644
index ab98fd151..000000000
--- a/b2g/gaia/moz.build
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-Program(CONFIG['MOZ_APP_NAME'])
-
-if CONFIG['OS_ARCH'] == 'WINNT':
- SOURCES += [
- 'run-b2g.cpp',
- ]
- DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
- DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
-else:
- SOURCES += [
- 'run-b2g.c',
- ]
- DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
- DEFINES['GAIA_PATH'] = '"gaia/profile"'
diff --git a/b2g/gaia/run-b2g.c b/b2g/gaia/run-b2g.c
deleted file mode 100644
index 184fa3400..000000000
--- a/b2g/gaia/run-b2g.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <libgen.h>
-
-#ifndef B2G_NAME
-#define B2G_NAME "b2g-bin"
-#endif
-#ifndef GAIA_PATH
-#define GAIA_PATH "gaia/profile"
-#endif
-#define NOMEM "Could not allocate enough memory"
-
-void error(char* msg){
- fprintf(stderr, "ERROR: %s\n", msg);
-}
-
-int main(int argc, char* argv[], char* envp[]){
- char* cwd = NULL;
- char* full_path = NULL;
- char* full_profile_path = NULL;
- printf("Starting %s\n", B2G_NAME);
- cwd = realpath(dirname(argv[0]), NULL);
- full_path = (char*) malloc(strlen(cwd) + strlen(B2G_NAME) + 2);
- if (!full_path) {
- error(NOMEM);
- return -2;
- }
- full_profile_path = (char*) malloc(strlen(cwd) + strlen(GAIA_PATH) + 2);
- if (!full_profile_path) {
- free(full_path);
- error(NOMEM);
- return -2;
- }
- sprintf(full_path, "%s/%s", cwd, B2G_NAME);
- sprintf(full_profile_path, "%s/%s", cwd, GAIA_PATH);
- free(cwd);
- printf("Running: %s --profile %s\n", full_path, full_profile_path);
- fflush(stdout);
- fflush(stderr);
- // XXX: yes, the printf above says --profile and this execle uses -profile.
- // Bug 1088430 will change the execle to use --profile.
- execle(full_path, full_path, "-profile", full_profile_path, NULL, envp);
- error("unable to start");
- perror(argv[0]);
- free(full_path);
- free(full_profile_path);
- return -1;
-}
diff --git a/b2g/gaia/run-b2g.cpp b/b2g/gaia/run-b2g.cpp
deleted file mode 100644
index 26fce08a2..000000000
--- a/b2g/gaia/run-b2g.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <Windows.h>
-#include <Shlwapi.h>
-#include <strsafe.h>
-
-// Linker options
-#pragma comment(lib, "User32.lib")
-#pragma comment(lib, "shlwapi.lib")
-#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup")
-
-#define NUM_MAX_PATH_BYTES sizeof(wchar_t) * MAX_PATH + 1
-#define PROFILE_ARG L" -profile "
-
-// Options that can be overridden at build time with -D
-#ifndef B2G_NAME
-#define B2G_NAME L"b2g.exe"
-#endif
-#ifndef GAIA_PATH
-#define GAIA_PATH L"gaia\\profile"
-#endif
-
-void error(wchar_t* msg){
- MessageBoxW(nullptr, msg, L"Error starting program", MB_OK | MB_ICONERROR);
-}
-
-/* This function takes a string which represents a windows path, orig.
- * The file portion of the path is stripped off and replaced with the
- * path component, file. This function returns a string which represents
- * a windows path with the modifications requested and needs to be freed
- * explicitly by the calling function.
- */
-wchar_t* make_path_with_leaf_file_name(wchar_t* orig, wchar_t* file){
- wchar_t* buffer = (wchar_t*) malloc(NUM_MAX_PATH_BYTES);
- if (!buffer) {
- return nullptr;
- }
- if (FAILED(StringCchCopyW(buffer, NUM_MAX_PATH_BYTES, orig))) {
- error(L"Error copying string");
- free(buffer);
- buffer = nullptr;
- }
- PathRemoveFileSpecW(buffer);
- if (!PathAppendW(buffer, file)) {
- error(L"Unable to append file to directory");
- free(buffer);
- buffer = nullptr;
- }
- return buffer;
-}
-
-BOOL execute(wchar_t* binary_path, wchar_t* args, int cp_flags) {
- STARTUPINFOW si;
- PROCESS_INFORMATION pi;
-
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- ZeroMemory(&pi, sizeof(pi));
-
- if (!CreateProcessW(
- binary_path,
- args,
- nullptr,
- nullptr,
- FALSE,
- cp_flags,
- nullptr,
- nullptr,
- &si,
- &pi)){
- error(L"Could not execute program");
- return FALSE;
- }
-
- WaitForInputIdle(pi.hProcess, 0);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- return true;
-}
-
-int wmain(int argc, wchar_t *argv[], wchar_t *envp[]){
- int cp_flags;
- wchar_t* b2g_path = make_path_with_leaf_file_name(argv[0], B2G_NAME);
- wchar_t* profile_path = make_path_with_leaf_file_name(argv[0], GAIA_PATH);
- // 10 chars for the ' -profile ' portion of the argument
- wchar_t* args = (wchar_t*) malloc(2 * NUM_MAX_PATH_BYTES + wcslen(PROFILE_ARG));
- if (FAILED(StringCchPrintfW(args, NUM_MAX_PATH_BYTES, L"\"%ws\"%ws\"%ws\"", b2g_path, PROFILE_ARG, profile_path))) {
- error(L"Could not create argument string");
- ExitProcess(1);
- }
-#ifdef SHOW_CONSOLE
- cp_flags = 0;
-#else
- cp_flags = DETACHED_PROCESS;
-#endif
- if (!execute(b2g_path, args, cp_flags)) {
- error(L"Failed to launch program");
- }
- free(profile_path);
- free(b2g_path);
- free(args);
- profile_path = b2g_path = args = nullptr;
-
-}
diff --git a/b2g/graphene/app.mozbuild b/b2g/graphene/app.mozbuild
deleted file mode 100644
index fc3037c06..000000000
--- a/b2g/graphene/app.mozbuild
+++ /dev/null
@@ -1,17 +0,0 @@
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include('/toolkit/toolkit.mozbuild')
-
-if CONFIG['MOZ_EXTENSIONS']:
- DIRS += ['/extensions']
-
-DIRS += [
- '/%s' % CONFIG['MOZ_BRANDING_DIRECTORY'],
- '/b2g',
-]
-
-# Add the defaults settings.
-FINAL_TARGET_FILES.defaults += [ 'settings.json' ]
diff --git a/b2g/graphene/build.mk b/b2g/graphene/build.mk
deleted file mode 100644
index 5a3623e5a..000000000
--- a/b2g/graphene/build.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/b2g/build.mk
diff --git a/b2g/graphene/config/horizon-mozconfigs/common b/b2g/graphene/config/horizon-mozconfigs/common
deleted file mode 100644
index 9277d299f..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/common
+++ /dev/null
@@ -1,24 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Disable the l10n-check target, which isn't relevant to b2g builds at all.
-# This needs to be set prior to the next include for it to take effect.
-MOZ_AUTOMATION_PACKAGE_TESTS=0
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_SDK=0
-
-. "$topsrcdir/build/mozconfig.common"
-
-# Normally, we'd set this unconditionally, but this file is also used
-# for local builds and there is no other mozconfig in this tree that
-# is included on device builds.
-if test -d $topsrcdir/../gcc/bin; then
- HOST_CC="$topsrcdir/../gcc/bin/gcc"
- HOST_CXX="$topsrcdir/../gcc/bin/g++"
- . "$topsrcdir/build/unix/mozconfig.stdcxx"
-fi
-
-MOZ_HORIZON=1
-ac_add_options --with-branding=b2g/branding/horizon
-ac_add_options --enable-application=b2g/graphene
diff --git a/b2g/graphene/config/horizon-mozconfigs/common.override b/b2g/graphene/config/horizon-mozconfigs/common.override
deleted file mode 100644
index f17dadfe6..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/common.override
+++ /dev/null
@@ -1,5 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-. "$topsrcdir/build/mozconfig.common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/linux32/debug b/b2g/graphene/config/horizon-mozconfigs/linux32/debug
deleted file mode 100644
index 9758e72e4..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/linux32/debug
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux32"
-
-ac_add_options --enable-debug
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-ENABLE_MARIONETTE=1
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/linux32/nightly b/b2g/graphene/config/horizon-mozconfigs/linux32/nightly
deleted file mode 100644
index ad36ce038..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/linux32/nightly
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux32"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/linux64/debug b/b2g/graphene/config/horizon-mozconfigs/linux64/debug
deleted file mode 100644
index c29fe6ebc..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/linux64/debug
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux"
-
-ac_add_options --enable-debug
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-ENABLE_MARIONETTE=1
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/linux64/nightly b/b2g/graphene/config/horizon-mozconfigs/linux64/nightly
deleted file mode 100644
index 0a695b081..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/linux64/nightly
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/macosx64/debug b/b2g/graphene/config/horizon-mozconfigs/macosx64/debug
deleted file mode 100644
index b973fd24c..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/macosx64/debug
+++ /dev/null
@@ -1,23 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-
-# Use sccache
-no_sccache=
-
-. $topsrcdir/build/macosx/mozconfig.common
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-#ac_add_options --with-macbundlename-prefix=Firefox
-
-# graphene Stuff
-ac_add_options --enable-debug-symbols
-ac_add_options --enable-debug
-ENABLE_MARIONETTE=1
-
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/macosx64/nightly b/b2g/graphene/config/horizon-mozconfigs/macosx64/nightly
deleted file mode 100644
index 5125bb8f1..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/macosx64/nightly
+++ /dev/null
@@ -1,23 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-
-# Use sccache
-no_sccache=
-
-. $topsrcdir/build/macosx/mozconfig.common
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-#ac_add_options --with-macbundlename-prefix=Firefox
-
-# graphene Stuff
-ac_add_options --enable-debug-symbols
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/win32/debug b/b2g/graphene/config/horizon-mozconfigs/win32/debug
deleted file mode 100644
index 89bcb7a5f..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/win32/debug
+++ /dev/null
@@ -1,19 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-
-ac_add_options --enable-jemalloc
-ac_add_options --enable-debug
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-. $topsrcdir/build/win32/mozconfig.vs-latest
-
-# graphene Options
-ENABLE_MARIONETTE=1
-
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/win32/nightly b/b2g/graphene/config/horizon-mozconfigs/win32/nightly
deleted file mode 100644
index b9ab618e5..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/win32/nightly
+++ /dev/null
@@ -1,18 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-jemalloc
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-. $topsrcdir/build/win32/mozconfig.vs-latest
-
-# graphene Options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/win64/debug b/b2g/graphene/config/horizon-mozconfigs/win64/debug
deleted file mode 100644
index 3ab8e7820..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/win64/debug
+++ /dev/null
@@ -1,23 +0,0 @@
-. "$topsrcdir/build/mozconfig.win-common"
-MOZ_AUTOMATION_L10N_CHECK=0
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-
-ac_add_options --target=x86_64-pc-mingw32
-ac_add_options --host=x86_64-pc-mingw32
-
-ac_add_options --enable-debug
-ac_add_options --enable-dmd
-ac_add_options --enable-profiling # needed for --enable-dmd to work on Windows
-ac_add_options --enable-signmar
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Package js shell.
-export MOZ_PACKAGE_JSSHELL=1
-
-. $topsrcdir/build/win64/mozconfig.vs-latest
-
-. "$topsrcdir/build/mozconfig.cache"
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/horizon-mozconfigs/win64/nightly b/b2g/graphene/config/horizon-mozconfigs/win64/nightly
deleted file mode 100644
index f8cbb69e7..000000000
--- a/b2g/graphene/config/horizon-mozconfigs/win64/nightly
+++ /dev/null
@@ -1,26 +0,0 @@
-if [ "x$IS_NIGHTLY" = "xyes" ]; then
- MOZ_AUTOMATION_UPLOAD_SYMBOLS=1
- MOZ_AUTOMATION_UPDATE_PACKAGING=1
-fi
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common"
-
-ac_add_options --target=x86_64-pc-mingw32
-ac_add_options --host=x86_64-pc-mingw32
-
-. $topsrcdir/build/win64/mozconfig.vs-latest
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-jemalloc
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# graphene Options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/common b/b2g/graphene/config/mozconfigs/common
deleted file mode 100644
index 807d5d958..000000000
--- a/b2g/graphene/config/mozconfigs/common
+++ /dev/null
@@ -1,24 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Disable the l10n-check target, which isn't relevant to b2g builds at all.
-# This needs to be set prior to the next include for it to take effect.
-MOZ_AUTOMATION_PACKAGE_TESTS=0
-MOZ_AUTOMATION_L10N_CHECK=0
-MOZ_AUTOMATION_SDK=0
-
-. "$topsrcdir/build/mozconfig.common"
-
-# Normally, we'd set this unconditionally, but this file is also used
-# for local builds and there is no other mozconfig in this tree that
-# is included on device builds.
-if test -d $topsrcdir/../gcc/bin; then
- HOST_CC="$topsrcdir/../gcc/bin/gcc"
- HOST_CXX="$topsrcdir/../gcc/bin/g++"
- . "$topsrcdir/build/unix/mozconfig.stdcxx"
-fi
-
-ac_add_options --with-branding=b2g/branding/browserhtml
-ac_add_options --enable-application=b2g/graphene
-
diff --git a/b2g/graphene/config/mozconfigs/common.override b/b2g/graphene/config/mozconfigs/common.override
deleted file mode 100644
index f17dadfe6..000000000
--- a/b2g/graphene/config/mozconfigs/common.override
+++ /dev/null
@@ -1,5 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-. "$topsrcdir/build/mozconfig.common.override"
diff --git a/b2g/graphene/config/mozconfigs/linux32/debug b/b2g/graphene/config/mozconfigs/linux32/debug
deleted file mode 100644
index 4be8bc478..000000000
--- a/b2g/graphene/config/mozconfigs/linux32/debug
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux32"
-
-ac_add_options --enable-debug
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-ENABLE_MARIONETTE=1
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/linux32/nightly b/b2g/graphene/config/mozconfigs/linux32/nightly
deleted file mode 100644
index 0bbd85ac2..000000000
--- a/b2g/graphene/config/mozconfigs/linux32/nightly
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux32"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/linux64/debug b/b2g/graphene/config/mozconfigs/linux64/debug
deleted file mode 100644
index ab1eece0b..000000000
--- a/b2g/graphene/config/mozconfigs/linux64/debug
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux"
-
-ac_add_options --enable-debug
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-ENABLE_MARIONETTE=1
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/linux64/nightly b/b2g/graphene/config/mozconfigs/linux64/nightly
deleted file mode 100644
index 543ab8a4e..000000000
--- a/b2g/graphene/config/mozconfigs/linux64/nightly
+++ /dev/null
@@ -1,25 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-. "$topsrcdir/build/unix/mozconfig.linux"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-#ac_add_options --enable-js-diagnostics
-
-# This will overwrite the default of stripping everything and keep the symbol table.
-# This is useful for profiling and debugging and only increases the package size
-# by 2 MBs.
-STRIP_FLAGS="--strip-debug"
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Use sccache
-no_sccache=
-. "$topsrcdir/build/mozconfig.cache"
-
-# graphene options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/macosx64/debug b/b2g/graphene/config/mozconfigs/macosx64/debug
deleted file mode 100644
index 027632e1d..000000000
--- a/b2g/graphene/config/mozconfigs/macosx64/debug
+++ /dev/null
@@ -1,23 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-
-# Use sccache
-no_sccache=
-
-. $topsrcdir/build/macosx/mozconfig.common
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-#ac_add_options --with-macbundlename-prefix=Firefox
-
-# graphene Stuff
-ac_add_options --enable-debug-symbols
-ac_add_options --enable-debug
-ENABLE_MARIONETTE=1
-
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/macosx64/nightly b/b2g/graphene/config/mozconfigs/macosx64/nightly
deleted file mode 100644
index 002fdeaf9..000000000
--- a/b2g/graphene/config/mozconfigs/macosx64/nightly
+++ /dev/null
@@ -1,23 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-
-# Use sccache
-no_sccache=
-
-. $topsrcdir/build/macosx/mozconfig.common
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-#ac_add_options --with-macbundlename-prefix=Firefox
-
-# graphene Stuff
-ac_add_options --enable-debug-symbols
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/win32/debug b/b2g/graphene/config/mozconfigs/win32/debug
deleted file mode 100644
index 246b82399..000000000
--- a/b2g/graphene/config/mozconfigs/win32/debug
+++ /dev/null
@@ -1,19 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-
-ac_add_options --enable-jemalloc
-ac_add_options --enable-debug
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-. $topsrcdir/build/win32/mozconfig.vs-latest
-
-# graphene Options
-ENABLE_MARIONETTE=1
-
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/grapheneconfig/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/win32/nightly b/b2g/graphene/config/mozconfigs/win32/nightly
deleted file mode 100644
index ed7668b64..000000000
--- a/b2g/graphene/config/mozconfigs/win32/nightly
+++ /dev/null
@@ -1,18 +0,0 @@
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-jemalloc
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-. $topsrcdir/build/win32/mozconfig.vs-latest
-
-# graphene Options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/win64/debug b/b2g/graphene/config/mozconfigs/win64/debug
deleted file mode 100644
index 455ec1762..000000000
--- a/b2g/graphene/config/mozconfigs/win64/debug
+++ /dev/null
@@ -1,23 +0,0 @@
-. "$topsrcdir/build/mozconfig.win-common"
-MOZ_AUTOMATION_L10N_CHECK=0
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-
-ac_add_options --target=x86_64-pc-mingw32
-ac_add_options --host=x86_64-pc-mingw32
-
-ac_add_options --enable-debug
-ac_add_options --enable-dmd
-ac_add_options --enable-profiling # needed for --enable-dmd to work on Windows
-ac_add_options --enable-signmar
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# Package js shell.
-export MOZ_PACKAGE_JSSHELL=1
-
-. $topsrcdir/build/win64/mozconfig.vs-latest
-
-. "$topsrcdir/build/mozconfig.cache"
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/config/mozconfigs/win64/nightly b/b2g/graphene/config/mozconfigs/win64/nightly
deleted file mode 100644
index 73db616cc..000000000
--- a/b2g/graphene/config/mozconfigs/win64/nightly
+++ /dev/null
@@ -1,26 +0,0 @@
-if [ "x$IS_NIGHTLY" = "xyes" ]; then
- MOZ_AUTOMATION_UPLOAD_SYMBOLS=1
- MOZ_AUTOMATION_UPDATE_PACKAGING=1
-fi
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common"
-
-ac_add_options --target=x86_64-pc-mingw32
-ac_add_options --host=x86_64-pc-mingw32
-
-. $topsrcdir/build/win64/mozconfig.vs-latest
-
-ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
-ac_add_options --enable-jemalloc
-ac_add_options --enable-signmar
-
-# Nightlies only since this has a cost in performance
-ac_add_options --enable-js-diagnostics
-
-# Needed to enable breakpad in application.ini
-export MOZILLA_OFFICIAL=1
-
-# graphene Options
-export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
-
-. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
diff --git a/b2g/graphene/confvars.sh b/b2g/graphene/confvars.sh
deleted file mode 100644
index 7db9a7ee6..000000000
--- a/b2g/graphene/confvars.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-if test "$MOZ_HORIZON"; then
-MOZ_APP_BASENAME=Horizon
-else
-MOZ_APP_BASENAME=Graphene
-fi
-
-MOZ_APP_VENDOR=Mozilla
-MOZ_UPDATER=1
-
-MOZ_B2G=1
-MOZ_GRAPHENE=1
-
-MOZ_APP_VERSION=$FIREFOX_VERSION
-MOZ_APP_UA_NAME=Firefox
-
-MOZ_B2G_VERSION=2.6.0.0-prerelease
-MOZ_B2G_OS_NAME=Boot2Gecko
-
-MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
-MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
-# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
-
-MOZ_CAPTIVEDETECT=1
-
-MOZ_NO_SMART_CARDS=1
-MOZ_APP_STATIC_INI=1
-NSS_NO_LIBPKIX=1
-
-if test "$OS_TARGET" = "Android"; then
-MOZ_CAPTURE=1
-MOZ_RAW=1
-MOZ_AUDIO_CHANNEL_MANAGER=1
-fi
-
-MOZ_APP_ID={d1bfe7d9-c01e-4237-998b-7b5f960a4314}
-MOZ_TIME_MANAGER=1
-
-MOZ_TOOLKIT_SEARCH=
-MOZ_PLACES=
-MOZ_B2G=1
-
-MOZ_JSDOWNLOADS=1
-
-MOZ_BUNDLED_FONTS=1
-
-export JS_GC_SMALL_CHUNK_SIZE=1
-
-# Include the DevTools client, not just the server (which is the default)
-MOZ_DEVTOOLS=all
diff --git a/b2g/graphene/graphene.js b/b2g/graphene/graphene.js
deleted file mode 100644
index 0c8abf42f..000000000
--- a/b2g/graphene/graphene.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// See http://dxr.mozilla.org/mozilla-central/source/dom/webidl/KeyEvent.webidl
-// for keyCode values.
-// Default value is F5
-pref("b2g.reload_key", '{ "key": 116, "shift": false, "ctrl": false, "alt": false, "meta": false }');
-
-#ifdef MOZ_HORIZON
-pref("b2g.default.start_manifest_url", "https://mozvr.github.io/horizon/web/manifest.webapp");
-pref("dom.vr.enabled", true);
-pref("dom.ipc.tabs.disabled", true);
-#else
-pref("b2g.default.start_manifest_url", "https://mozilla.github.io/browser.html/manifest.webapp");
-pref("dom.ipc.tabs.disabled", false);
-#endif
-
-pref("javascript.options.discardSystemSource", false);
-pref("browser.dom.window.dump.enabled", true);
-pref("browser.ignoreNativeFrameTextSelection", false);
-pref("dom.meta-viewport.enabled", false);
-pref("full-screen-api.ignore-widgets", false);
-pref("image.high_quality_downscaling.enabled", true);
-pref("dom.w3c_touch_events.enabled", 0);
-pref("font.size.inflation.minTwips", 0);
-pref("browser.enable_click_image_resizing", true);
-pref("layout.css.scroll-snap.enabled", true);
-pref("dom.mozInputMethod.enabled", false);
-pref("browser.autofocus", true);
-pref("layers.async-pan-zoom.enabled", false);
-pref("network.predictor.enabled", true);
-
-// No AccessibleCaret
-pref("layout.accessiblecaret.enabled", false);
-
-// To be removed once bug 942756 is fixed.
-pref("devtools.debugger.unix-domain-socket", "6000");
-
-pref("devtools.debugger.forbid-certified-apps", false);
-pref("devtools.debugger.prompt-connection", false);
-
-// Update url.
-pref("app.update.url", "https://aus4.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
-
-pref("b2g.nativeWindowGeometry.width", 700);
-pref("b2g.nativeWindowGeometry.height", 600);
-pref("b2g.nativeWindowGeometry.screenX", -1); // center
-pref("b2g.nativeWindowGeometry.screenY", -1); // center
-pref("b2g.nativeWindowGeometry.fullscreen", false);
-
-pref("media.useAudioChannelService", false);
-
-#ifdef ENABLE_MARIONETTE
-pref("b2g.is_mulet", true);
-#endif
-
-// Most DevTools prefs are set from the shared file
-// devtools/client/preferences/devtools.js, but this one is currently set
-// per-app or per-channel.
-// Number of usages of the web console or scratchpad. If this is less than 5,
-// then pasting code into the web console or scratchpad is disabled
-pref("devtools.selfxss.count", 5);
diff --git a/b2g/graphene/moz.configure b/b2g/graphene/moz.configure
deleted file mode 100644
index e9533bbda..000000000
--- a/b2g/graphene/moz.configure
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include('../common.configure')
diff --git a/b2g/graphene/settings.json b/b2g/graphene/settings.json
deleted file mode 100644
index 75bd243a4..000000000
--- a/b2g/graphene/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "apz.overscroll.enabled": false
-}
diff --git a/b2g/installer/Makefile.in b/b2g/installer/Makefile.in
deleted file mode 100644
index 63d8f37e4..000000000
--- a/b2g/installer/Makefile.in
+++ /dev/null
@@ -1,135 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-STANDALONE_MAKEFILE := 1
-
-include $(topsrcdir)/config/rules.mk
-
-MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in
-
-MOZ_PKG_MANIFEST = $(srcdir)/package-manifest.in
-
-ifdef MOZ_CHROME_MULTILOCALE
-MOZ_PKG_MANIFEST_DEPS = locale-manifest.in
-
-DEFINES += -DPKG_LOCALE_MANIFEST=$(CURDIR)/locale-manifest.in
-endif
-
-DEFINES += \
- -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
- -DPREF_DIR=$(PREF_DIR) \
- $(NULL)
-
-DEFINES += -DJAREXT=
-
-DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
-
-# Set MSVC dlls version to package, if any.
-ifdef MOZ_NO_DEBUG_RTL
-ifdef WIN32_REDIST_DIR
-DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
-DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
-DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
-endif
-ifdef WIN_UCRT_REDIST_DIR
-DEFINES += -DMOZ_PACKAGE_WIN_UCRT_DLLS=1
-endif
-endif
-
-ifdef MOZ_DEBUG
-DEFINES += -DMOZ_DEBUG=1
-endif
-
-ifdef ENABLE_MARIONETTE
-DEFINES += -DENABLE_MARIONETTE=1
-endif
-
-MOZ_PACKAGER_MINIFY=1
-
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-ifndef _APPNAME
-_APPNAME = $(MOZ_MACBUNDLE_NAME)
-endif
-ifndef _BINPATH
-_BINPATH = /$(_APPNAME)/Contents/MacOS
-endif
-ifndef _RESPATH
-_RESPATH = /$(_APPNAME)/Contents/Resources
-endif
-endif
-
-include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
-
-# Note that JS_BINARY can be defined in packager.mk, so this test must come after
-# including that file. MOZ_PACKAGER_MINIFY_JS is used in packager.mk, but since
-# recipe evaluation is deferred, we can set it here after the inclusion.
-ifneq (,$(JS_BINARY))
-ifndef MOZ_DEBUG
-MOZ_PACKAGER_MINIFY_JS=1
-endif
-endif
-
-ifeq (bundle, $(MOZ_FS_LAYOUT))
-BINPATH = $(_BINPATH)
-RESPATH = $(_RESPATH)
-DEFINES += -DAPPNAME=$(_APPNAME)
-else
-# Every other platform just winds up in dist/bin
-BINPATH = bin
-RESPATH = bin
-endif
-DEFINES += -DBINPATH=$(BINPATH)
-DEFINES += -DRESPATH=$(RESPATH)
-
-LPROJ_ROOT = $(firstword $(subst -, ,$(AB_CD)))
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-ifeq (zh-TW,$(AB_CD))
-LPROJ_ROOT := $(subst -,_,$(AB_CD))
-endif
-endif
-DEFINES += -DLPROJ_ROOT=$(LPROJ_ROOT)
-
-ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET)))
-DEFINES += -DMOZ_SHARED_MOZGLUE=1
-endif
-
-DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
-ifdef MOZ_SYSTEM_ICU
-DEFINES += -DMOZ_SYSTEM_ICU
-endif
-DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
-DEFINES += -DICU_DATA_FILE=$(ICU_DATA_FILE)
-
-ifneq (,$(filter gtk%,$(MOZ_WIDGET_TOOLKIT)))
-DEFINES += -DMOZ_GTK=1
-ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3)
-DEFINES += -DMOZ_GTK3=1
-endif
-endif
-
-ifdef MOZ_CHROME_MULTILOCALE
-locale-manifest.in: $(GLOBAL_DEPS) FORCE
- printf '\n[multilocale]\n' > $@
- for LOCALE in $(MOZ_CHROME_MULTILOCALE) ;\
- do \
- printf '$(BINPATH)/chrome/'"$$LOCALE"'$(JAREXT)\n' >> $@; \
- printf '$(BINPATH)/chrome/'"$$LOCALE"'.manifest\n' >> $@; \
- done
-
-GARBAGE += locale-manifest.in
-endif
-
-ifdef FXOS_SIMULATOR
-export MAKE
-
-.PHONY: simulator
-simulator: make-package
- @echo 'Building simulator addon...'
- $(PYTHON) $(topsrcdir)/b2g/simulator/build_xpi.py $(MOZ_PKG_PLATFORM)
-
-libs:: simulator
-
-# Ensure copying Simulator xpi to ftp
-UPLOAD_EXTRA_FILES += fxos-simulator-*-*.xpi
-endif
diff --git a/b2g/installer/flash.bat b/b2g/installer/flash.bat
deleted file mode 100755
index 9b5093677..000000000
--- a/b2g/installer/flash.bat
+++ /dev/null
@@ -1,73 +0,0 @@
-@ECHO OFF
-
-REM read config file
-setlocal ENABLEDELAYEDEXPANSION
-set loop=0
-for /F "tokens=*" %%A in (.config) do (
- SET /A loop=!loop! + 1
- set %%A
-)
-
-set DEVICE_FOUND=0
-
-REM nexus has device instead of product name
-IF [%PRODUCT_NAME%]==[] (
- set PRODUCT_NAME=%DEVICE%
-)
-
-REM if nexus 4 assume you are in fastboot mode, can't seem to find drivers
-IF [%DEVICE%]==[mako] (
-call :flash
-)
-
-REM push device from adb to fastboot mode
-win_adb kill-server
-win_adb devices
-win_adb get-state > devicestate.txt
-set /p DEVICE_STATE= < devicestate.txt
-
-IF NOT "%DEVICE_STATE%"=="device" (
- ECHO Please check :
- ECHO 1. to make sure that only one device is connected to the computer
- ECHO 2. the device is turned on with the screen showing
- ECHO 3. the device is set to debugging via USB : ADB Only or ADB and Devtools
- ECHO 4. the device drivers are installed on the computer.
- Del devicestate.txt
- PAUSE
- EXIT /b
-)
-
-Del devicestate.txt
-win_adb reboot bootloader
-
-TIMEOUT 5
-
-:flash
-win_fastboot devices 2> fastboot_state.txt
-set /p FASTBOOT_STATE= < fastboot_state.txt
-
-IF NOT [%FASTBOOT_STATE%]==[] (
- ECHO Please check :
- ECHO 1. to make sure that only one device is connected to the computer
- ECHO 2. the device is turned on with an indication that the device is in fastboot mode
- ECHO 3. the fastboot drivers are installed on the computer.
- Del fastboot_state.txt
- PAUSE
- EXIT /b
-)
-
-Del fastboot_state.txt
-
-ECHO "Flashing build. If nothing mentions that it flashed anything and it looks stuck, make sure you have the drivers installed."
-win_fastboot flash boot out/target/product/%PRODUCT_NAME%/boot.img
-win_fastboot flash system out/target/product/%PRODUCT_NAME%/system.img
-win_fastboot flash persist out/target/product/%PRODUCT_NAME%/persist.img
-win_fastboot flash recovery out/target/product/%PRODUCT_NAME%/recovery.img
-win_fastboot flash cache out/target/product/%PRODUCT_NAME%/cache.img
-win_fastboot flash userdata out/target/product/%PRODUCT_NAME%/userdata.img
-
-ECHO "Done..."
-
-win_fastboot reboot
-echo "Just close the windows as you wish."
-TIMEOUT 5
diff --git a/b2g/installer/moz.build b/b2g/installer/moz.build
deleted file mode 100644
index 28919c271..000000000
--- a/b2g/installer/moz.build
+++ /dev/null
@@ -1,6 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in
deleted file mode 100644
index a5b886c42..000000000
--- a/b2g/installer/package-manifest.in
+++ /dev/null
@@ -1,845 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-; Package file for the B2G build.
-;
-; File format:
-;
-; [] designates a toplevel component. Example: [xpcom]
-; - in front of a file specifies it to be removed from the destination
-; * wildcard support to recursively copy the entire directory
-; ; file comment
-;
-
-#filter substitution
-
-#ifdef XP_MACOSX
-; Mac bundle stuff
-@APPNAME@/Contents/Info.plist
-@APPNAME@/Contents/PkgInfo
-@APPNAME@/Contents/Plug-Ins/
-@RESPATH@/@MOZ_APP_NAME@.icns
-@RESPATH@/@LPROJ_ROOT@.lproj/*
-#endif
-
-[@AB_CD@]
-@RESPATH@/chrome/@AB_CD@@JAREXT@
-@RESPATH@/chrome/@AB_CD@.manifest
-@RESPATH@/@PREF_DIR@/b2g-l10n.js
-@RESPATH@/searchplugins/*
-#ifdef MOZ_UPDATER
-@RESPATH@/update.locale
-@RESPATH@/updater.ini
-#endif
-@RESPATH@/dictionaries/*
-@RESPATH@/hyphenation/*
-#ifdef XP_WIN32
-@BINPATH@/uninstall/helper.exe
-#endif
-
-[xpcom]
-@RESPATH@/dependentlibs.list
-#ifndef MOZ_STATIC_JS
-@BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
-#endif
-#ifndef MOZ_FOLD_LIBS
-@BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
-@BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
-@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
-#endif
-#ifdef MOZ_DMD
-@BINPATH@/@DLL_PREFIX@dmd@DLL_SUFFIX@
-#endif
-#ifdef XP_MACOSX
-@BINPATH@/XUL
-#else
-@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
-#endif
-#ifdef XP_MACOSX
-@BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
-#else
-@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
-#endif
-#ifdef XP_WIN32
-#if MOZ_PACKAGE_MSVC_DLLS
-@BINPATH@/@MSVC_C_RUNTIME_DLL@
-@BINPATH@/@MSVC_CXX_RUNTIME_DLL@
-#endif
-#if MOZ_PACKAGE_WIN_UCRT_DLLS
-@BINPATH@/api-ms-win-*.dll
-@BINPATH@/ucrtbase.dll
-#endif
-#endif
-#ifndef MOZ_SYSTEM_ICU
-@RESPATH@/@ICU_DATA_FILE@
-#endif
-#ifdef MOZ_SHARED_MOZGLUE
-@BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
-#endif
-#ifdef ANDROID
-@RESPATH@/AndroidManifest.xml
-@RESPATH@/resources.arsc
-@RESPATH@/classes.dex
-@RESPATH@/res/drawable
-@RESPATH@/res/drawable-hdpi
-@RESPATH@/res/layout
-#endif
-#ifdef MOZ_GTK3
-@BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
-@BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
-#endif
-
-[browser]
-; [Base Browser Files]
-#ifndef XP_UNIX
-@BINPATH@/@MOZ_APP_NAME@.exe
-#else
-@BINPATH@/@MOZ_APP_NAME@-bin
-@BINPATH@/@MOZ_APP_NAME@
-#endif
-@RESPATH@/application.ini
-@RESPATH@/platform.ini
-#ifndef MOZ_FOLD_LIBS
-@BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
-#endif
-@BINPATH@/@DLL_PREFIX@lgpllibs@DLL_SUFFIX@
-@RESPATH@/blocklist.xml
-@RESPATH@/ua-update.json
-@RESPATH@/defaults/settings.json
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-@RESPATH@/run-mozilla.sh
-#endif
-#endif
-#ifdef MOZ_WEBSPEECH_MODELS
-@RESPATH@/models/
-#endif
-
-; [Components]
-@RESPATH@/components/components.manifest
-@RESPATH@/components/alerts.xpt
-#ifdef ACCESSIBILITY
-#ifdef XP_WIN32
-@BINPATH@/AccessibleMarshal.dll
-#endif
-@RESPATH@/components/accessibility.xpt
-#endif
-@RESPATH@/components/appshell.xpt
-@RESPATH@/components/appstartup.xpt
-@RESPATH@/components/autocomplete.xpt
-@RESPATH@/components/autoconfig.xpt
-@RESPATH@/components/browsercompsbase.xpt
-@RESPATH@/components/browser-element.xpt
-@RESPATH@/components/browser-feeds.xpt
-@RESPATH@/components/caps.xpt
-@RESPATH@/components/chardet.xpt
-@RESPATH@/components/chrome.xpt
-@RESPATH@/components/commandhandler.xpt
-@RESPATH@/components/commandlines.xpt
-@RESPATH@/components/composer.xpt
-@RESPATH@/components/content_events.xpt
-@RESPATH@/components/content_geckomediaplugins.xpt
-@RESPATH@/components/content_html.xpt
-@RESPATH@/components/content_xslt.xpt
-@RESPATH@/components/cookie.xpt
-@RESPATH@/components/directory.xpt
-@RESPATH@/components/diskspacewatcher.xpt
-@RESPATH@/components/docshell.xpt
-@RESPATH@/components/dom.xpt
-@RESPATH@/components/dom_activities.xpt
-@RESPATH@/components/dom_apps.xpt
-@RESPATH@/components/dom_audiochannel.xpt
-@RESPATH@/components/dom_base.xpt
-@RESPATH@/components/dom_system.xpt
-@RESPATH@/components/dom_workers.xpt
-#ifdef MOZ_WIDGET_GONK
-@RESPATH@/components/dom_wifi.xpt
-@RESPATH@/components/dom_system_gonk.xpt
-#endif
-@RESPATH@/components/dom_canvas.xpt
-@RESPATH@/components/dom_core.xpt
-@RESPATH@/components/dom_css.xpt
-@RESPATH@/components/dom_events.xpt
-@RESPATH@/components/dom_geolocation.xpt
-@RESPATH@/components/dom_media.xpt
-@RESPATH@/components/dom_network.xpt
-#ifdef MOZ_SECUREELEMENT
-@RESPATH@/components/dom_secureelement.xpt
-#endif
-@RESPATH@/components/dom_notification.xpt
-@RESPATH@/components/dom_html.xpt
-@RESPATH@/components/dom_offline.xpt
-@RESPATH@/components/dom_json.xpt
-@RESPATH@/components/dom_messages.xpt
-@RESPATH@/components/dom_power.xpt
-@RESPATH@/components/dom_push.xpt
-@RESPATH@/components/dom_quota.xpt
-@RESPATH@/components/dom_range.xpt
-@RESPATH@/components/dom_security.xpt
-@RESPATH@/components/dom_settings.xpt
-@RESPATH@/components/dom_permissionsettings.xpt
-@RESPATH@/components/dom_sidebar.xpt
-@RESPATH@/components/dom_cellbroadcast.xpt
-@RESPATH@/components/dom_icc.xpt
-@RESPATH@/components/dom_mobilemessage.xpt
-@RESPATH@/components/dom_storage.xpt
-@RESPATH@/components/dom_stylesheets.xpt
-@RESPATH@/components/dom_threads.xpt
-@RESPATH@/components/dom_traversal.xpt
-@RESPATH@/components/dom_tv.xpt
-@RESPATH@/components/dom_inputport.xpt
-@RESPATH@/components/dom_views.xpt
-#ifdef MOZ_WEBSPEECH
-@RESPATH@/components/dom_webspeechrecognition.xpt
-#endif
-@RESPATH@/components/dom_xbl.xpt
-@RESPATH@/components/dom_xhr.xpt
-@RESPATH@/components/dom_xpath.xpt
-@RESPATH@/components/dom_xul.xpt
-@RESPATH@/components/dom_time.xpt
-@RESPATH@/components/dom_presentation.xpt
-@RESPATH@/components/downloads.xpt
-@RESPATH@/components/editor.xpt
-@RESPATH@/components/embed_base.xpt
-@RESPATH@/components/extensions.xpt
-@RESPATH@/components/exthandler.xpt
-@RESPATH@/components/exthelper.xpt
-@RESPATH@/components/fastfind.xpt
-@RESPATH@/components/feeds.xpt
-#ifdef MOZ_GTK
-@RESPATH@/components/filepicker.xpt
-#endif
-@RESPATH@/components/find.xpt
-@RESPATH@/components/gfx.xpt
-@RESPATH@/components/gaia_chrome.xpt
-@RESPATH@/components/hal.xpt
-@RESPATH@/components/html5.xpt
-@RESPATH@/components/htmlparser.xpt
-@RESPATH@/components/identity.xpt
-@RESPATH@/components/imglib2.xpt
-@RESPATH@/components/inspector.xpt
-@RESPATH@/components/intl.xpt
-@RESPATH@/components/jar.xpt
-@RESPATH@/components/jsdebugger.xpt
-@RESPATH@/components/jsdownloads.xpt
-@RESPATH@/components/jsinspector.xpt
-@RESPATH@/components/layout_base.xpt
-#ifdef NS_PRINTING
-@RESPATH@/components/layout_printing.xpt
-#endif
-@RESPATH@/components/layout_xul_tree.xpt
-@RESPATH@/components/layout_xul.xpt
-@RESPATH@/components/locale.xpt
-@RESPATH@/components/lwbrk.xpt
-#ifdef MOZ_ENABLE_PROFILER_SPS
-@RESPATH@/components/memory_profiler.xpt
-#endif
-@RESPATH@/components/migration.xpt
-@RESPATH@/components/mimetype.xpt
-@RESPATH@/components/mozfind.xpt
-@RESPATH@/components/necko_about.xpt
-@RESPATH@/components/necko_cache.xpt
-@RESPATH@/components/necko_cache2.xpt
-@RESPATH@/components/necko_cookie.xpt
-@RESPATH@/components/necko_dns.xpt
-@RESPATH@/components/necko_file.xpt
-@RESPATH@/components/necko_ftp.xpt
-@RESPATH@/components/necko_http.xpt
-@RESPATH@/components/necko_mdns.xpt
-@RESPATH@/components/necko_res.xpt
-@RESPATH@/components/necko_socket.xpt
-@RESPATH@/components/necko_strconv.xpt
-@RESPATH@/components/necko_viewsource.xpt
-@RESPATH@/components/necko_websocket.xpt
-@RESPATH@/components/necko_wifi.xpt
-@RESPATH@/components/necko_wyciwyg.xpt
-@RESPATH@/components/necko.xpt
-@RESPATH@/components/loginmgr.xpt
-@RESPATH@/components/parentalcontrols.xpt
-#ifdef MOZ_WEBRTC
-@RESPATH@/components/peerconnection.xpt
-#endif
-@RESPATH@/components/places.xpt
-@RESPATH@/components/plugin.xpt
-@RESPATH@/components/pref.xpt
-@RESPATH@/components/prefetch.xpt
-#ifdef MOZ_ENABLE_PROFILER_SPS
-@RESPATH@/components/profiler.xpt
-#endif
-@RESPATH@/components/proxyObject.xpt
-@RESPATH@/components/rdf.xpt
-@RESPATH@/components/satchel.xpt
-@RESPATH@/components/saxparser.xpt
-@RESPATH@/components/sessionstore.xpt
-@RESPATH@/components/services-crypto-component.xpt
-@RESPATH@/components/captivedetect.xpt
-@RESPATH@/components/shellservice.xpt
-@RESPATH@/components/shistory.xpt
-@RESPATH@/components/spellchecker.xpt
-@RESPATH@/components/storage.xpt
-@RESPATH@/components/telemetry.xpt
-@RESPATH@/components/toolkit_asyncshutdown.xpt
-@RESPATH@/components/toolkit_filewatcher.xpt
-@RESPATH@/components/toolkit_finalizationwitness.xpt
-@RESPATH@/components/toolkit_formautofill.xpt
-@RESPATH@/components/toolkit_osfile.xpt
-@RESPATH@/components/toolkit_securityreporter.xpt
-@RESPATH@/components/toolkit_perfmonitoring.xpt
-@RESPATH@/components/toolkit_xulstore.xpt
-@RESPATH@/components/toolkitprofile.xpt
-#ifdef MOZ_ENABLE_XREMOTE
-@RESPATH@/components/toolkitremote.xpt
-#endif
-@RESPATH@/components/txtsvc.xpt
-@RESPATH@/components/txmgr.xpt
-#ifdef MOZ_USE_NATIVE_UCONV
-@RESPATH@/components/ucnative.xpt
-#endif
-@RESPATH@/components/uconv.xpt
-@RESPATH@/components/unicharutil.xpt
-@RESPATH@/components/update.xpt
-@RESPATH@/components/uriloader.xpt
-@RESPATH@/components/urlformatter.xpt
-@RESPATH@/components/webBrowser_core.xpt
-@RESPATH@/components/webbrowserpersist.xpt
-@RESPATH@/components/webshell_idls.xpt
-@RESPATH@/components/widget.xpt
-#ifdef XP_MACOSX
-@RESPATH@/components/widget_cocoa.xpt
-#endif
-#ifdef ANDROID
-@RESPATH@/components/widget_android.xpt
-#endif
-@RESPATH@/components/windowds.xpt
-@RESPATH@/components/windowwatcher.xpt
-@RESPATH@/components/xpcom_base.xpt
-@RESPATH@/components/xpcom_system.xpt
-@RESPATH@/components/xpcom_components.xpt
-@RESPATH@/components/xpcom_ds.xpt
-@RESPATH@/components/xpcom_io.xpt
-@RESPATH@/components/xpcom_threads.xpt
-@RESPATH@/components/xpcom_xpti.xpt
-@RESPATH@/components/xpconnect.xpt
-@RESPATH@/components/xulapp.xpt
-@RESPATH@/components/xul.xpt
-@RESPATH@/components/xultmpl.xpt
-@RESPATH@/components/zipwriter.xpt
-
-; JavaScript components
-@RESPATH@/components/ConsoleAPI.manifest
-@RESPATH@/components/ConsoleAPIStorage.js
-@RESPATH@/components/BrowserElementParent.manifest
-@RESPATH@/components/BrowserElementParent.js
-@RESPATH@/components/BrowserElementProxy.manifest
-@RESPATH@/components/BrowserElementProxy.js
-@RESPATH@/components/PhoneNumberService.js
-@RESPATH@/components/PhoneNumberService.manifest
-@RESPATH@/components/NotificationStorage.js
-@RESPATH@/components/NotificationStorage.manifest
-@RESPATH@/components/PermissionSettings.js
-@RESPATH@/components/PermissionSettings.manifest
-@RESPATH@/components/PermissionPromptService.js
-@RESPATH@/components/PermissionPromptService.manifest
-@RESPATH@/components/FeedProcessor.manifest
-@RESPATH@/components/FeedProcessor.js
-@RESPATH@/components/BrowserFeeds.manifest
-@RESPATH@/components/FeedConverter.js
-@RESPATH@/components/FeedWriter.js
-@RESPATH@/components/WebContentConverter.js
-@RESPATH@/components/BrowserComponents.manifest
-@RESPATH@/components/nsBrowserContentHandler.js
-@RESPATH@/components/nsBrowserGlue.js
-@RESPATH@/components/nsSetDefaultBrowser.manifest
-@RESPATH@/components/nsSetDefaultBrowser.js
-@RESPATH@/components/toolkitsearch.manifest
-@RESPATH@/components/nsTryToClose.manifest
-@RESPATH@/components/nsTryToClose.js
-@RESPATH@/components/passwordmgr.manifest
-@RESPATH@/components/nsLoginInfo.js
-@RESPATH@/components/nsLoginManager.js
-@RESPATH@/components/nsLoginManagerPrompter.js
-@RESPATH@/components/TooltipTextProvider.js
-@RESPATH@/components/TooltipTextProvider.manifest
-@RESPATH@/components/NetworkGeolocationProvider.manifest
-@RESPATH@/components/NetworkGeolocationProvider.js
-@RESPATH@/components/TVSimulatorService.js
-@RESPATH@/components/TVSimulatorService.manifest
-#ifdef MOZ_WEBRTC
-@RESPATH@/components/PeerConnection.js
-@RESPATH@/components/PeerConnection.manifest
-#endif
-@RESPATH@/components/SiteSpecificUserAgent.js
-@RESPATH@/components/SiteSpecificUserAgent.manifest
-@RESPATH@/components/storage-json.js
-@RESPATH@/components/crypto-SDR.js
-@RESPATH@/components/Downloads.manifest
-@RESPATH@/components/DownloadLegacy.js
-@RESPATH@/components/nsSidebar.manifest
-@RESPATH@/components/nsSidebar.js
-@RESPATH@/components/nsAsyncShutdown.manifest
-@RESPATH@/components/nsAsyncShutdown.js
-@RESPATH@/components/htmlMenuBuilder.js
-@RESPATH@/components/htmlMenuBuilder.manifest
-@RESPATH@/components/PresentationDeviceInfoManager.manifest
-@RESPATH@/components/PresentationDeviceInfoManager.js
-@RESPATH@/components/BuiltinProviders.manifest
-@RESPATH@/components/PresentationControlService.js
-@RESPATH@/components/PresentationDataChannelSessionTransport.js
-@RESPATH@/components/PresentationDataChannelSessionTransport.manifest
-
-#ifdef MOZ_SECUREELEMENT
-@RESPATH@/components/ACEService.js
-@RESPATH@/components/ACEService.manifest
-@RESPATH@/components/GPAccessRulesManager.js
-@RESPATH@/components/GPAccessRulesManager.manifest
-@RESPATH@/components/SecureElement.js
-@RESPATH@/components/SecureElement.manifest
-@RESPATH@/components/UiccConnector.js
-@RESPATH@/components/UiccConnector.manifest
-#endif
-
-; WiFi, NetworkManager, NetworkStats
-#ifdef MOZ_WIDGET_GONK
-@RESPATH@/components/DOMWifiManager.js
-@RESPATH@/components/DOMWifiManager.manifest
-@RESPATH@/components/DOMWifiP2pManager.js
-@RESPATH@/components/DOMWifiP2pManager.manifest
-@RESPATH@/components/EthernetManager.js
-@RESPATH@/components/EthernetManager.manifest
-@RESPATH@/components/NetworkInterfaceListService.js
-@RESPATH@/components/NetworkInterfaceListService.manifest
-@RESPATH@/components/NetworkManager.js
-@RESPATH@/components/NetworkManager.manifest
-@RESPATH@/components/NetworkService.js
-@RESPATH@/components/NetworkService.manifest
-@RESPATH@/components/NetworkStatsManager.js
-@RESPATH@/components/NetworkStatsManager.manifest
-@RESPATH@/components/NetworkStatsServiceProxy.js
-@RESPATH@/components/NetworkStatsServiceProxy.manifest
-@RESPATH@/components/TetheringService.js
-@RESPATH@/components/TetheringService.manifest
-@RESPATH@/components/WifiWorker.js
-@RESPATH@/components/WifiWorker.manifest
-#endif // MOZ_WIDGET_GONK
-
-; Tethering
-#ifdef MOZ_WIDGET_GONK
-@RESPATH@/components/TetheringManager.js
-@RESPATH@/components/TetheringManager.manifest
-#endif
-
-; RIL
-#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-@RESPATH@/components/CellBroadcastService.js
-@RESPATH@/components/CellBroadcastService.manifest
-@RESPATH@/components/DataCallManager.js
-@RESPATH@/components/DataCallManager.manifest
-@RESPATH@/components/IccService.js
-@RESPATH@/components/IccService.manifest
-@RESPATH@/components/MmsService.js
-@RESPATH@/components/MmsService.manifest
-@RESPATH@/components/MobileMessageDatabaseService.js
-@RESPATH@/components/MobileMessageDatabaseService.manifest
-#ifndef DISABLE_MOZ_RIL_GEOLOC
-@RESPATH@/components/DataCallInterfaceService.js
-@RESPATH@/components/DataCallInterfaceService.manifest
-@RESPATH@/components/RadioInterfaceLayer.js
-@RESPATH@/components/RadioInterfaceLayer.manifest
-@RESPATH@/components/SmsService.js
-@RESPATH@/components/SmsService.manifest
-#endif
-@RESPATH@/components/StkCmdFactory.js
-@RESPATH@/components/StkCmdFactory.manifest
-@RESPATH@/components/RILSystemMessengerHelper.js
-@RESPATH@/components/RILSystemMessengerHelper.manifest
-#ifndef DISABLE_MOZ_RIL_GEOLOC
-#endif
-#endif // MOZ_WIDGET_GONK && MOZ_B2G_RIL
-
-#ifndef MOZ_WIDGET_GONK
-@RESPATH@/components/addonManager.js
-@RESPATH@/components/amContentHandler.js
-@RESPATH@/components/amInstallTrigger.js
-@RESPATH@/components/amWebInstallListener.js
-
-@RESPATH@/components/OopCommandLine.js
-@RESPATH@/components/CommandLine.js
-#endif
-@RESPATH@/components/extensions.manifest
-@RESPATH@/components/nsBlocklistService.js
-@RESPATH@/components/BootstrapCommandLine.js
-
-#ifdef MOZ_UPDATER
-@RESPATH@/components/nsUpdateService.manifest
-@RESPATH@/components/nsUpdateService.js
-@RESPATH@/components/nsUpdateServiceStub.js
-#endif
-@RESPATH@/components/nsUpdateTimerManager.manifest
-@RESPATH@/components/nsUpdateTimerManager.js
-@RESPATH@/components/pluginGlue.manifest
-@RESPATH@/components/nsSessionStore.manifest
-@RESPATH@/components/nsSessionStartup.js
-@RESPATH@/components/nsSessionStore.js
-@RESPATH@/components/nsURLFormatter.manifest
-@RESPATH@/components/nsURLFormatter.js
-@RESPATH@/components/@DLL_PREFIX@browsercomps@DLL_SUFFIX@
-@RESPATH@/components/txEXSLTRegExFunctions.manifest
-@RESPATH@/components/txEXSLTRegExFunctions.js
-@RESPATH@/components/toolkitplaces.manifest
-@RESPATH@/components/nsLivemarkService.js
-@RESPATH@/components/nsTaggingService.js
-@RESPATH@/components/nsPlacesDBFlush.js
-@RESPATH@/components/UnifiedComplete.js
-@RESPATH@/components/nsPlacesExpiration.js
-@RESPATH@/components/PlacesCategoriesStarter.js
-@RESPATH@/components/nsDefaultCLH.manifest
-@RESPATH@/components/nsDefaultCLH.js
-@RESPATH@/components/nsContentPrefService.manifest
-@RESPATH@/components/nsContentPrefService.js
-@RESPATH@/components/nsContentDispatchChooser.manifest
-@RESPATH@/components/nsContentDispatchChooser.js
-@RESPATH@/components/nsHandlerService.manifest
-@RESPATH@/components/nsHandlerService.js
-@RESPATH@/components/nsWebHandlerApp.manifest
-@RESPATH@/components/nsWebHandlerApp.js
-@RESPATH@/components/satchel.manifest
-@RESPATH@/components/nsFormAutoComplete.js
-@RESPATH@/components/nsFormHistory.js
-@RESPATH@/components/FormHistoryStartup.js
-@RESPATH@/components/nsInputListAutoComplete.js
-@RESPATH@/components/formautofill.manifest
-@RESPATH@/components/FormAutofillContentService.js
-@RESPATH@/components/FormAutofillStartup.js
-@RESPATH@/components/CSSUnprefixingService.js
-@RESPATH@/components/CSSUnprefixingService.manifest
-@RESPATH@/components/contentAreaDropListener.manifest
-@RESPATH@/components/contentAreaDropListener.js
-@RESPATH@/components/messageWakeupService.js
-@RESPATH@/components/messageWakeupService.manifest
-@RESPATH@/components/SettingsManager.js
-@RESPATH@/components/SettingsManager.manifest
-@RESPATH@/components/SettingsService.js
-@RESPATH@/components/SettingsService.manifest
-@RESPATH@/components/webvtt.xpt
-@RESPATH@/components/WebVTT.manifest
-@RESPATH@/components/WebVTTParserWrapper.js
-#ifdef MOZ_SECUREELEMENT
-@RESPATH@/components/DOMSecureElement.manifest
-@RESPATH@/components/DOMSecureElement.js
-#endif
-@RESPATH@/components/nsINIProcessor.manifest
-@RESPATH@/components/nsINIProcessor.js
-@RESPATH@/components/nsPrompter.manifest
-@RESPATH@/components/nsPrompter.js
-@RESPATH@/components/servicesComponents.manifest
-@RESPATH@/components/cryptoComponents.manifest
-@RESPATH@/components/CaptivePortalDetectComponents.manifest
-@RESPATH@/components/captivedetect.js
-@RESPATH@/components/TelemetryStartup.js
-@RESPATH@/components/TelemetryStartup.manifest
-@RESPATH@/components/XULStore.js
-@RESPATH@/components/XULStore.manifest
-@RESPATH@/components/AppsService.js
-@RESPATH@/components/AppsService.manifest
-@RESPATH@/components/Push.js
-@RESPATH@/components/Push.manifest
-@RESPATH@/components/PushComponents.js
-
-@RESPATH@/components/nsDOMIdentity.js
-@RESPATH@/components/nsIDService.js
-@RESPATH@/components/Identity.manifest
-
-@RESPATH@/components/SystemMessageInternal.js
-@RESPATH@/components/SystemMessageManager.js
-@RESPATH@/components/SystemMessageCache.js
-@RESPATH@/components/SystemMessageManager.manifest
-@RESPATH@/components/HCIEventTransactionSystemMessage.manifest
-@RESPATH@/components/HCIEventTransactionSystemMessageConfigurator.js
-
-@RESPATH@/components/ActivityProxy.js
-@RESPATH@/components/ActivityRequestHandler.js
-@RESPATH@/components/ActivityWrapper.js
-@RESPATH@/components/ActivityMessageConfigurator.js
-
-@RESPATH@/components/DownloadsAPI.js
-@RESPATH@/components/DownloadsAPI.manifest
-
-; InputMethod API
-@RESPATH@/components/MozKeyboard.js
-@RESPATH@/components/InputMethod.manifest
-#ifdef MOZ_B2G
-@RESPATH@/components/inputmethod.xpt
-#endif
-
-@RESPATH@/components/SystemUpdate.manifest
-@RESPATH@/components/SystemUpdateManager.js
-
-#if defined(ENABLE_TESTS) && defined(MOZ_DEBUG)
-@RESPATH@/components/TestInterfaceJS.js
-@RESPATH@/components/TestInterfaceJS.manifest
-@RESPATH@/components/TestInterfaceJSMaplike.js
-#endif
-
-; Modules
-@RESPATH@/modules/*
-
-; Safe Browsing
-@RESPATH@/components/nsURLClassifier.manifest
-@RESPATH@/components/nsUrlClassifierHashCompleter.js
-@RESPATH@/components/nsUrlClassifierListManager.js
-@RESPATH@/components/nsUrlClassifierLib.js
-@RESPATH@/components/url-classifier.xpt
-
-; Private Browsing
-@RESPATH@/components/privatebrowsing.xpt
-@RESPATH@/components/PrivateBrowsing.manifest
-@RESPATH@/components/PrivateBrowsingTrackingProtectionWhitelist.js
-
-; Security Reports
-@RESPATH@/components/SecurityReporter.manifest
-@RESPATH@/components/SecurityReporter.js
-
-; ANGLE on Win32
-#ifdef XP_WIN32
-#ifndef HAVE_64BIT_BUILD
-@BINPATH@/libEGL.dll
-@BINPATH@/libGLESv2.dll
-#endif
-#endif
-
-; [Browser Chrome Files]
-@RESPATH@/chrome/browser@JAREXT@
-@RESPATH@/chrome/browser.manifest
-@RESPATH@/chrome/toolkit@JAREXT@
-@RESPATH@/chrome/toolkit.manifest
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-@RESPATH@/chrome/icons/default/default16.png
-@RESPATH@/chrome/icons/default/default32.png
-@RESPATH@/chrome/icons/default/default48.png
-#endif
-#endif
-
-; DevTools
-@RESPATH@/chrome/devtools@JAREXT@
-@RESPATH@/chrome/devtools.manifest
-#ifdef MOZ_GRAPHENE
-@RESPATH@/@PREF_DIR@/devtools.js
-#endif
-
-; shell icons
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-@RESPATH@/icons/*.xpm
-@RESPATH@/icons/*.png
-#endif
-#endif
-
-; [Default Preferences]
-; All the pref files must be part of base to prevent migration bugs
-#ifdef MOZ_MULET
-@RESPATH@/browser/@PREF_DIR@/b2g.js
-#else
-@RESPATH@/@PREF_DIR@/b2g.js
-#endif
-@RESPATH@/@PREF_DIR@/channel-prefs.js
-@RESPATH@/greprefs.js
-@RESPATH@/defaults/autoconfig/prefcalls.js
-
-; [Layout Engine Resources]
-; Style Sheets, Graphics and other Resources used by the layout engine.
-@RESPATH@/res/EditorOverride.css
-@RESPATH@/res/contenteditable.css
-@RESPATH@/res/designmode.css
-@RESPATH@/res/ImageDocument.css
-@RESPATH@/res/TopLevelImageDocument.css
-@RESPATH@/res/TopLevelVideoDocument.css
-@RESPATH@/res/table-add-column-after-active.gif
-@RESPATH@/res/table-add-column-after-hover.gif
-@RESPATH@/res/table-add-column-after.gif
-@RESPATH@/res/table-add-column-before-active.gif
-@RESPATH@/res/table-add-column-before-hover.gif
-@RESPATH@/res/table-add-column-before.gif
-@RESPATH@/res/table-add-row-after-active.gif
-@RESPATH@/res/table-add-row-after-hover.gif
-@RESPATH@/res/table-add-row-after.gif
-@RESPATH@/res/table-add-row-before-active.gif
-@RESPATH@/res/table-add-row-before-hover.gif
-@RESPATH@/res/table-add-row-before.gif
-@RESPATH@/res/table-remove-column-active.gif
-@RESPATH@/res/table-remove-column-hover.gif
-@RESPATH@/res/table-remove-column.gif
-@RESPATH@/res/table-remove-row-active.gif
-@RESPATH@/res/table-remove-row-hover.gif
-@RESPATH@/res/table-remove-row.gif
-@RESPATH@/res/grabber.gif
-#ifdef XP_MACOSX
-@RESPATH@/res/cursors/*
-#endif
-@RESPATH@/res/fonts/*
-@RESPATH@/res/dtd/*
-@RESPATH@/res/html/*
-@RESPATH@/res/language.properties
-@RESPATH@/res/entityTables/*
-#ifdef XP_MACOSX
-@RESPATH@/res/MainMenu.nib/
-#endif
-
-; svg
-@RESPATH@/res/svg.css
-@RESPATH@/components/dom_svg.xpt
-@RESPATH@/components/dom_smil.xpt
-
-; [Personal Security Manager]
-;
-@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
-@RESPATH@/components/pipnss.xpt
-@RESPATH@/components/pippki.xpt
-@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
-#ifndef MOZ_FOLD_LIBS
-@BINPATH@/@DLL_PREFIX@nssutil3@DLL_SUFFIX@
-@BINPATH@/@DLL_PREFIX@smime3@DLL_SUFFIX@
-@BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
-#endif
-@BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
-#if defined(XP_LINUX) && !defined(ANDROID)
-@BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@
-#else
-@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
-#endif
-#ifndef CROSS_COMPILE
-@BINPATH@/@DLL_PREFIX@freebl3.chk
-@BINPATH@/@DLL_PREFIX@softokn3.chk
-#endif
-#ifndef NSS_DISABLE_DBM
-@BINPATH@/@DLL_PREFIX@nssdbm3@DLL_SUFFIX@
-#ifndef CROSS_COMPILE
-@BINPATH@/@DLL_PREFIX@nssdbm3.chk
-#endif
-#endif
-@RESPATH@/chrome/pippki@JAREXT@
-@RESPATH@/chrome/pippki.manifest
-
-; For process sandboxing
-#if defined(MOZ_SANDBOX)
-#if defined(XP_WIN)
-@BINPATH@/@DLL_PREFIX@sandboxbroker@DLL_SUFFIX@
-#elif defined(XP_LINUX)
-@BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
-#endif
-#endif
-
-; for Solaris SPARC
-#ifdef SOLARIS
-bin/libfreebl_32fpu_3.chk
-bin/libfreebl_32fpu_3.so
-bin/libfreebl_32int_3.chk
-bin/libfreebl_32int_3.so
-bin/libfreebl_32int64_3.chk
-bin/libfreebl_32int64_3.so
-#endif
-
-; [Updater]
-;
-#ifdef MOZ_UPDATER
-#ifdef XP_MACOSX
-@BINPATH@/updater.app/
-#else
-@BINPATH@/updater@BIN_SUFFIX@
-#endif
-#endif
-
-; [Crash Reporter]
-;
-#ifdef MOZ_CRASHREPORTER
-#ifdef XP_MACOSX
-@BINPATH@/crashreporter.app/
-#else
-@BINPATH@/crashreporter@BIN_SUFFIX@
-@RESPATH@/crashreporter.crt
-@RESPATH@/crashreporter.ini
-#ifdef XP_UNIX
-@RESPATH@/Throbber-small.gif
-#endif
-#endif
-@RESPATH@/crashreporter-override.ini
-#endif
-
-[b2g]
-#ifndef MOZ_WIDGET_GONK
-#ifdef XP_WIN32
-@BINPATH@/xpcshell.exe
-@BINPATH@/ssltunnel.exe
-#else
-@BINPATH@/xpcshell
-@BINPATH@/ssltunnel
-#endif
-#endif
-@RESPATH@/chrome/icons/
-@RESPATH@/chrome/chrome@JAREXT@
-@RESPATH@/chrome/chrome.manifest
-@RESPATH@/components/B2GComponents.manifest
-@BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@
-#if defined(ENABLE_MARIONETTE) || !defined(MOZ_WIDGET_GONK)
-@RESPATH@/chrome/marionette@JAREXT@
-@RESPATH@/chrome/marionette.manifest
-@RESPATH@/components/marionette.manifest
-@RESPATH@/components/marionette.js
-#endif
-@RESPATH@/components/AlertsService.js
-@RESPATH@/components/ContentPermissionPrompt.js
-#ifdef MOZ_UPDATER
-@RESPATH@/components/UpdatePrompt.js
-#endif
-@RESPATH@/components/DirectoryProvider.js
-@RESPATH@/components/ProcessGlobal.js
-@RESPATH@/components/OMAContentHandler.js
-@RESPATH@/components/RecoveryService.js
-@RESPATH@/components/MailtoProtocolHandler.js
-@RESPATH@/components/SmsProtocolHandler.js
-@RESPATH@/components/TelProtocolHandler.js
-@RESPATH@/components/B2GAboutRedirector.js
-@RESPATH@/components/FilePicker.js
-@RESPATH@/components/HelperAppDialog.js
-@RESPATH@/components/DownloadsUI.js
-@RESPATH@/components/SystemMessageGlue.js
-@RESPATH@/components/B2GAppMigrator.js
-@RESPATH@/components/B2GPresentationDevicePrompt.js
-@RESPATH@/components/PresentationRequestUIGlue.js
-
-#ifndef MOZ_WIDGET_GONK
-@RESPATH@/components/SimulatorScreen.js
-#endif
-
-@RESPATH@/components/FxAccountsUIGlue.js
-@RESPATH@/components/services_fxaccounts.xpt
-
-#ifdef MOZ_WEBSPEECH
-@RESPATH@/components/dom_webspeechsynth.xpt
-#endif
-
-#ifdef XP_MACOSX
-@BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
-#endif
-
-#ifdef PACKAGE_GAIA
-[gaia]
-@RESPATH@/gaia/*
-@BINPATH@/b2g-bin@BIN_SUFFIX@
-#endif
-
-#ifdef PACKAGE_MOZTT
-@RESPATH@/fonts/*
-#endif
-
-; media
-@RESPATH@/gmp-clearkey/0.1/@DLL_PREFIX@clearkey@DLL_SUFFIX@
-@RESPATH@/gmp-clearkey/0.1/clearkey.info
-
-#ifdef PKG_LOCALE_MANIFEST
-#include @PKG_LOCALE_MANIFEST@
-#endif
-
-@RESPATH@/components/simpleServices.js
-@RESPATH@/components/utils.manifest
diff --git a/b2g/installer/removed-files.in b/b2g/installer/removed-files.in
deleted file mode 100644
index 557a379da..000000000
--- a/b2g/installer/removed-files.in
+++ /dev/null
@@ -1,45 +0,0 @@
-# Due to Apple Mac OS X packaging requirements files that are in the same
-# directory on other platforms must be located in different directories on
-# Mac OS X. The following defines allow specifying the Mac OS X bundle
-# location which also work on other platforms.
-#
-# @DIR_MACOS@
-# Equals Contents/MacOS/ on Mac OS X and is an empty string on other platforms.
-#
-# @DIR_RESOURCES@
-# Equals Contents/Resources/ on Mac OS X and is an empty string on other
-# platforms.
-
-# Mac OS X v2 signing removals
-#ifdef XP_MACOSX
- @DIR_MACOS@active-update.xml
- @DIR_MACOS@update-settings.ini
- @DIR_MACOS@updates.xml
- @DIR_MACOS@defaults/*
- @DIR_MACOS@updates/*
-#endif
-
-@DIR_MACOS@README.txt
-@DIR_MACOS@@DLL_PREFIX@mozutils@DLL_SUFFIX@
-@DIR_MACOS@jssubloader/
-#ifdef XP_MACOSX
-@DIR_MACOS@run-mozilla.sh
-#endif
-#ifdef XP_WIN
- mozcrt19.dll
- mozcpp19.dll
-#endif
-@DIR_MACOS@defaults/preferences/services-sync.js
-@DIR_MACOS@defaults/preferences/healthreport-prefs.js
-@DIR_MACOS@components/dom_sms.xpt
-@DIR_MACOS@components/dom_webspeech.xpt
-#ifdef MOZ_FOLD_LIBS
-@DIR_MACOS@@DLL_PREFIX@nspr4@DLL_SUFFIX@
-@DIR_MACOS@@DLL_PREFIX@plds4@DLL_SUFFIX@
-@DIR_MACOS@@DLL_PREFIX@plc4@DLL_SUFFIX@
-@DIR_MACOS@@DLL_PREFIX@ssl3@DLL_SUFFIX@
-@DIR_MACOS@@DLL_PREFIX@smime3@DLL_SUFFIX@
-@DIR_MACOS@@DLL_PREFIX@nssutil3@DLL_SUFFIX@
-@DIR_MACOS@@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
-#endif
-@DIR_MACOS@@DLL_PREFIX@xpcom@DLL_SUFFIX@
diff --git a/b2g/locales/Makefile.in b/b2g/locales/Makefile.in
deleted file mode 100644
index c626e557c..000000000
--- a/b2g/locales/Makefile.in
+++ /dev/null
@@ -1,149 +0,0 @@
-# vim:set ts=8 sw=8 sts=8 noet:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/config/config.mk
-
-SUBMAKEFILES += \
- $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \
- $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales/Makefile \
- $(NULL)
-
-# This makefile uses variable overrides from the libs-% target to
-# build non-default locales to non-default dist/ locations. Be aware!
-
-PWD := $(CURDIR)
-
-# These are defaulted to be compatible with the files the wget-en-US target
-# pulls. You may override them if you provide your own files. You _must_
-# override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not
-# work in that case.
-ZIP_IN ?= $(ABS_DIST)/$(PACKAGE)
-WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
-RETRIEVE_WINDOWS_INSTALLER = 1
-
-MOZ_LANGPACK_EID=langpack-$(AB_CD)@b2g.mozilla.org
-
-L10N_PREF_JS_EXPORTS = $(call MERGE_FILE,b2g-l10n.js)
-L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
-L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
-PP_TARGETS += L10N_PREF_JS_EXPORTS
-
-ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
-MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore
-MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png
-MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns
-MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ '
-endif
-
-ifeq (WINNT,$(OS_ARCH))
-UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \
- $(NSINSTALL) -D $(STAGEDIST)/uninstall; \
- cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \
- $(RM) $(ABS_DIST)/l10n-stage/setup.exe; \
- cp ../installer/windows/l10ngen/setup.exe $(ABS_DIST)/l10n-stage; \
- $(NULL)
-endif
-
-include $(topsrcdir)/config/rules.mk
-
-include $(topsrcdir)/toolkit/locales/l10n.mk
-
-$(STAGEDIST): $(DIST)/branding
-
-$(DIST)/branding:
- $(NSINSTALL) -D $@
-
-libs::
- @if test -f '$(LOCALE_SRCDIR)/existing-profile-defaults.js'; then \
- $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) \
- $(LOCALE_SRCDIR)/existing-profile-defaults.js -o $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
- fi
-
-NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
-
-libs-%:
- $(NSINSTALL) -D $(DIST)/install
- @$(MAKE) -C ../../toolkit/locales libs-$*
- @$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$*
- @$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
- @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$*
-
-# Tailored target to just add the chrome processing for multi-locale builds
-chrome-%:
- @$(MAKE) chrome AB_CD=$*
- @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
-
-repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
-repackage-win32-installer: $(call ESCAPE_SPACE,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD)
- @echo 'Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT).'
- $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export
- $(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen l10ngen/setup.exe l10ngen/7zSD.sfx
- $(MAKE) repackage-zip \
- AB_CD=$(AB_CD) \
- MOZ_PKG_FORMAT=SFX7Z \
- ZIP_IN='$(WIN32_INSTALLER_IN)' \
- ZIP_OUT='$(WIN32_INSTALLER_OUT)' \
- SFX_HEADER='$(PWD)/../installer/windows/l10ngen/7zSD.sfx \
- $(topsrcdir)/b2g/installer/windows/app.tag'
-
-ifeq (WINNT,$(OS_ARCH))
-repackage-win32-installer-%:
- @$(MAKE) repackage-win32-installer AB_CD=$* WIN32_INSTALLER_IN='$(WIN32_INSTALLER_IN)'
-else
-repackage-win32-installer-%: ;
-endif
-
-
-clobber-zip:
- $(RM) $(STAGEDIST)/chrome/$(AB_CD).jar \
- $(STAGEDIST)/chrome/$(AB_CD).manifest \
- $(STAGEDIST)/defaults/pref/b2g-l10n.js
- $(STAGEDIST)/dictionaries \
- $(STAGEDIST)/defaults/profile \
- $(STAGEDIST)/chrome/$(AB_CD)
-
-
-langpack: langpack-$(AB_CD)
-
-# This is a generic target that will make a langpack, repack ZIP (+tarball)
-# builds, and repack an installer if applicable. It is called from the
-# tinderbox scripts. Alter it with caution.
-
-installers-%: clobber-% langpack-% repackage-win32-installer-% repackage-zip-%
- @echo 'repackaging done'
-
-# When we unpack b2g on MacOS X the platform.ini and application.ini are in slightly
-# different locations that on all other platforms
-ifeq (Darwin, $(OS_ARCH))
-GECKO_PLATFORM_INI_PATH='$(STAGEDIST)/platform.ini'
-B2G_APPLICATION_INI_PATH='$(STAGEDIST)/application.ini'
-else
-GECKO_PLATFORM_INI_PATH='$(STAGEDIST)/platform.ini'
-B2G_APPLICATION_INI_PATH='$(STAGEDIST)/application.ini'
-endif
-
-
-ident:
- @printf 'gecko_revision '
- @$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(GECKO_PLATFORM_INI_PATH) Build SourceStamp
- @printf 'b2g_revision '
- @$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(B2G_APPLICATION_INI_PATH) App SourceStamp
- @printf 'buildid '
- @$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(B2G_APPLICATION_INI_PATH) App BuildID
-
-merge-%:
-ifdef LOCALE_MERGEDIR
- $(RM) -rf $(LOCALE_MERGEDIR)
- $(topsrcdir)/mach compare-locales --merge-dir $(LOCALE_MERGEDIR) $*
-endif
- @echo
-
-# test target, depends on make package
-# try to repack x-test, with just toolkit/defines.inc being there
-l10n-check::
- $(RM) -rf x-test
- $(NSINSTALL) -D x-test/toolkit
- echo '#define MOZ_LANG_TITLE Just testing' > x-test/toolkit/defines.inc
- $(MAKE) installers-x-test L10NBASEDIR='$(PWD)' LOCALE_MERGEDIR='$(PWD)/mergedir'
diff --git a/b2g/locales/all-locales b/b2g/locales/all-locales
deleted file mode 100644
index 44317e1ee..000000000
--- a/b2g/locales/all-locales
+++ /dev/null
@@ -1,3 +0,0 @@
-es-ES
-pl
-pt-BR
diff --git a/b2g/locales/en-US/b2g-l10n.js b/b2g/locales/en-US/b2g-l10n.js
deleted file mode 100644
index d502f0ae5..000000000
--- a/b2g/locales/en-US/b2g-l10n.js
+++ /dev/null
@@ -1,12 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#filter substitution
-
-pref("general.useragent.locale", "@AB_CD@");
-
-// Enable sparse localization by setting a few package locale overrides
-pref("chrome.override_package.global", "b2g-l10n");
-pref("chrome.override_package.mozapps", "b2g-l10n");
-pref("chrome.override_package.passwordmgr", "b2g-l10n");
diff --git a/b2g/locales/en-US/chrome/graphene.properties b/b2g/locales/en-US/chrome/graphene.properties
deleted file mode 100644
index be5f0b5c5..000000000
--- a/b2g/locales/en-US/chrome/graphene.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-installing=Installing…
diff --git a/b2g/locales/en-US/chrome/overrides/aboutCertError.dtd b/b2g/locales/en-US/chrome/overrides/aboutCertError.dtd
deleted file mode 100644
index cd6c6ba63..000000000
--- a/b2g/locales/en-US/chrome/overrides/aboutCertError.dtd
+++ /dev/null
@@ -1,38 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!ENTITY % brandDTD
- SYSTEM "chrome://branding/locale/brand.dtd">
- %brandDTD;
-
-<!-- These strings are used by Firefox's custom about:certerror page,
-a replacement for the standard security certificate errors produced
-by NSS/PSM via netError.xhtml. -->
-
-<!ENTITY certerror.pagetitle "Untrusted Connection">
-<!ENTITY certerror.longpagetitle "This Connection is Untrusted">
-
-<!-- Localization note (certerror.introPara1) - The string "#1" will
-be replaced at runtime with the name of the server to which the user
-was trying to connect. -->
-<!ENTITY certerror.introPara1 "You have asked &brandShortName; to connect
-securely to <b>#1</b>, but we can't confirm that your connection is secure.">
-
-<!ENTITY certerror.whatShouldIDo.heading "What Should I Do?">
-<!ENTITY certerror.whatShouldIDo.content "If you usually connect to
-this site without problems, this error could mean that someone is
-trying to impersonate the site, and you shouldn't continue.">
-<!ENTITY certerror.getMeOutOfHere.label "Get me out of here!">
-
-<!ENTITY certerror.expert.heading "I Understand the Risks">
-<!ENTITY certerror.expert.content "If you understand what's going on, you
-can tell &brandShortName; to start trusting this site's identification.
-<b>Even if you trust the site, this error could mean that someone is
-tampering with your connection.</b>">
-<!ENTITY certerror.expert.contentPara2 "Don't add an exception unless
-you know there's a good reason why this site doesn't use trusted identification.">
-<!ENTITY certerror.addTemporaryException.label "Visit site">
-<!ENTITY certerror.addPermanentException.label "Add permanent exception">
-
-<!ENTITY certerror.technical.heading "Technical Details">
diff --git a/b2g/locales/en-US/chrome/overrides/appstrings.properties b/b2g/locales/en-US/chrome/overrides/appstrings.properties
deleted file mode 100644
index ecc9e0a04..000000000
--- a/b2g/locales/en-US/chrome/overrides/appstrings.properties
+++ /dev/null
@@ -1,39 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-malformedURI=The URL is not valid and cannot be loaded.
-fileNotFound=Firefox can't find the file at %S.
-dnsNotFound=Firefox can't find the server at %S.
-unknownProtocolFound=Firefox doesn't know how to open this address, because one of the following protocols (%S) isn't associated with any program or is not allowed in this context.
-connectionFailure=Firefox can't establish a connection to the server at %S.
-netInterrupt=The connection to %S was interrupted while the page was loading.
-netTimeout=The server at %S is taking too long to respond.
-redirectLoop=Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
-## LOCALIZATION NOTE (confirmRepostPrompt): In this item, don't translate "%S"
-confirmRepostPrompt=To display this page, %S must send information that will repeat any action (such as a search or order confirmation) that was performed earlier.
-resendButton.label=Resend
-unknownSocketType=Firefox doesn't know how to communicate with the server.
-netReset=The connection to the server was reset while the page was loading.
-notCached=This document is no longer available.
-netOffline=Firefox is currently in offline mode and can't browse the Web.
-isprinting=The document cannot change while Printing or in Print Preview.
-deniedPortAccess=This address uses a network port which is normally used for purposes other than Web browsing. Firefox has canceled the request for your protection.
-proxyResolveFailure=Firefox is configured to use a proxy server that can't be found.
-proxyConnectFailure=Firefox is configured to use a proxy server that is refusing connections.
-contentEncodingError=The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.
-unsafeContentType=The page you are trying to view cannot be shown because it is contained in a file type that may not be safe to open. Please contact the website owners to inform them of this problem.
-externalProtocolTitle=External Protocol Request
-externalProtocolPrompt=An external application must be launched to handle %1$S: links.\n\n\nRequested link:\n\n%2$S\n\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n
-#LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined
-externalProtocolUnknown=<Unknown>
-externalProtocolChkMsg=Remember my choice for all links of this type.
-externalProtocolLaunchBtn=Launch application
-malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
-unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
-deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
-cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
-corruptedContentErrorv2=The site at %S has experienced a network protocol violation that cannot be repaired.
-remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
-sslv3Used=Firefox cannot guarantee the safety of your data on %S because it uses SSLv3, a broken security protocol.
-weakCryptoUsed=The owner of %S has configured their website improperly. To protect your information from being stolen, Firefox has not connected to this website.
diff --git a/b2g/locales/en-US/defines.inc b/b2g/locales/en-US/defines.inc
deleted file mode 100644
index 24f45813a..000000000
--- a/b2g/locales/en-US/defines.inc
+++ /dev/null
@@ -1,9 +0,0 @@
-#filter emptyLines
-
-#define MOZ_LANGPACK_CREATOR mozilla.org
-
-# If non-English locales wish to credit multiple contributors, uncomment this
-# variable definition and use the format specified.
-# #define MOZ_LANGPACK_CONTRIBUTORS <em:contributor>Joe Solon</em:contributor> <em:contributor>Suzy Solon</em:contributor>
-
-#unfilter emptyLines
diff --git a/b2g/locales/filter.py b/b2g/locales/filter.py
deleted file mode 100644
index d49507adc..000000000
--- a/b2g/locales/filter.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-def test(mod, path, entity = None):
- import re
- # ignore anything but b2g and specific overloads from dom and toolkit
- if mod not in ("netwerk", "dom", "toolkit", "security/manager",
- "devtools/shared",
- "mobile",
- "b2g"):
- return "ignore"
-
- return "error"
diff --git a/b2g/locales/jar.mn b/b2g/locales/jar.mn
deleted file mode 100644
index 970261dbe..000000000
--- a/b2g/locales/jar.mn
+++ /dev/null
@@ -1,75 +0,0 @@
-#filter substitution
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-@AB_CD@.jar:
-% locale b2g-l10n @AB_CD@ %locale/@AB_CD@/b2g-l10n/
-
-% override chrome://global/locale/aboutCertError.dtd chrome://b2g-l10n/locale/aboutCertError.dtd
-% override chrome://global/locale/appstrings.properties chrome://b2g-l10n/locale/appstrings.properties
- locale/@AB_CD@/b2g-l10n/aboutCertError.dtd (%chrome/overrides/aboutCertError.dtd)
- locale/@AB_CD@/b2g-l10n/appstrings.properties (%chrome/overrides/appstrings.properties)
-#ifdef MOZ_GRAPHENE
- locale/@AB_CD@/b2g-l10n/graphene.properties (%chrome/graphene.properties)
-#endif
-
-
-# overrides for toolkit l10n, also for en-US
-relativesrcdir toolkit/locales:
- locale/@AB_CD@/b2g-l10n/overrides/about.dtd (%chrome/global/about.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/aboutAbout.dtd (%chrome/global/aboutAbout.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/aboutRights.dtd (%chrome/global/aboutRights.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/commonDialogs.properties (%chrome/global/commonDialogs.properties)
- locale/@AB_CD@/b2g-l10n/overrides/handling/handling.properties (%chrome/mozapps/handling/handling.properties)
- locale/@AB_CD@/b2g-l10n/overrides/intl.properties (%chrome/global/intl.properties)
- locale/@AB_CD@/b2g-l10n/overrides/intl.css (%chrome/global/intl.css)
- locale/@AB_CD@/b2g-l10n/overrides/passwordmgr.properties (%chrome/passwordmgr/passwordmgr.properties)
- locale/@AB_CD@/b2g-l10n/overrides/search/search.properties (%chrome/search/search.properties)
- locale/@AB_CD@/b2g-l10n/overrides/update/updates.properties (%chrome/mozapps/update/updates.properties)
-# about:support
- locale/@AB_CD@/b2g-l10n/overrides/global/aboutSupport.dtd (%chrome/global/aboutSupport.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/global/aboutSupport.properties (%chrome/global/aboutSupport.properties)
-#about:crashes
- locale/@AB_CD@/b2g-l10n/overrides/crashreporter/crashes.dtd (%crashreporter/crashes.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/crashreporter/crashes.properties (%crashreporter/crashes.properties)
-#about:mozilla
- locale/@AB_CD@/b2g-l10n/overrides/global/mozilla.dtd (%chrome/global/mozilla.dtd)
-#about:telemetry
- locale/@AB_CD@/b2g-l10n/overrides/global/aboutTelemetry.dtd (%chrome/global/aboutTelemetry.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/global/aboutTelemetry.properties (%chrome/global/aboutTelemetry.properties)
-#about:webrtc
- locale/@AB_CD@/b2g-l10n/overrides/global/aboutWebrtc.properties (%chrome/global/aboutWebrtc.properties)
-
-% override chrome://global/locale/about.dtd chrome://b2g-l10n/locale/overrides/about.dtd
-% override chrome://global/locale/aboutAbout.dtd chrome://b2g-l10n/locale/overrides/aboutAbout.dtd
-% override chrome://global/locale/aboutRights.dtd chrome://b2g-l10n/locale/overrides/aboutRights.dtd
-% override chrome://global/locale/commonDialogs.properties chrome://b2g-l10n/locale/overrides/commonDialogs.properties
-% override chrome://mozapps/locale/handling/handling.properties chrome://b2g-l10n/locale/overrides/handling/handling.properties
-% override chrome://global/locale/intl.properties chrome://b2g-l10n/locale/overrides/intl.properties
-% override chrome://global/locale/intl.css chrome://b2g-l10n/locale/overrides/intl.css
-% override chrome://passwordmgr/locale/passwordmgr.properties chrome://b2g-l10n/locale/overrides/passwordmgr/passwordmgr.properties
-% override chrome://global/locale/search/search.properties chrome://b2g-l10n/locale/overrides/search/search.properties
-% override chrome://mozapps/locale/update/updates.properties chrome://b2g-l10n/locale/overrides/update/updates.properties
-% override chrome://global/locale/aboutSupport.dtd chrome://b2g-l10n/locale/overrides/global/aboutSupport.dtd
-% override chrome://global/locale/aboutSupport.properties chrome://b2g-l10n/locale/overrides/global/aboutSupport.properties
-% override chrome://global/locale/crashes.dtd chrome://b2g-l10n/locale/overrides/crashreporter/crashes.dtd
-% override chrome://global/locale/crashes.properties chrome://b2g-l10n/locale/overrides/crashreporter/crashes.properties
-% override chrome://global/locale/mozilla.dtd chrome://b2g-l10n/locale/overrides/global/mozilla.dtd
-% override chrome://global/locale/aboutTelemetry.dtd chrome://b2g-l10n/locale/overrides/global/aboutTelemetry.dtd
-% override chrome://global/locale/aboutTelemetry.properties chrome://b2g-l10n/locale/overrides/global/aboutTelemetry.properties
-% override chrome://global/locale/aboutWebrtc.properties chrome://b2g-l10n/locale/overrides/global/aboutWebrtc.properties
-
-# overrides for dom l10n, also for en-US
-relativesrcdir dom/locales:
- locale/@AB_CD@/b2g-l10n/overrides/global.dtd (%chrome/global.dtd)
- locale/@AB_CD@/b2g-l10n/overrides/AccessFu.properties (%chrome/accessibility/AccessFu.properties)
- locale/@AB_CD@/b2g-l10n/overrides/dom/dom.properties (%chrome/dom/dom.properties)
-#about:plugins
- locale/@AB_CD@/b2g-l10n/overrides/plugins.properties (%chrome/plugins.properties)
-
-% override chrome://global/locale/global.dtd chrome://b2g-l10n/locale/overrides/global.dtd
-% override chrome://global/locale/AccessFu.properties chrome://b2g-l10n/locale/overrides/AccessFu.properties
-% override chrome://global/locale/dom/dom.properties chrome://b2g-l10n/locale/overrides/dom/dom.properties
-% override chrome://global/locale/plugins.properties chrome://b2g-l10n/locale/overrides/plugins.properties
diff --git a/b2g/locales/l10n.ini b/b2g/locales/l10n.ini
deleted file mode 100644
index b40159dfd..000000000
--- a/b2g/locales/l10n.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-[general]
-depth = ../..
-all = b2g/locales/all-locales
-
-[compare]
-dirs = b2g
-
-[includes]
-toolkit = toolkit/locales/l10n.ini
diff --git a/b2g/locales/moz.build b/b2g/locales/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/b2g/locales/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/b2g/moz.build b/b2g/moz.build
deleted file mode 100644
index c5aec07c9..000000000
--- a/b2g/moz.build
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CONFIGURE_SUBST_FILES += ['installer/Makefile']
-
-DIRS += ['chrome', 'components', 'locales']
-
-if CONFIG['GAIADIR']:
- DIRS += ['gaia']
-
-DIRS += ['app']
diff --git a/b2g/moz.configure b/b2g/moz.configure
deleted file mode 100644
index b98e5e61f..000000000
--- a/b2g/moz.configure
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-option('--with-gonk', nargs=1, help='Path to the gonk base directory')
-
-@depends_if('--with-gonk', '--help')
-def gonkdir(value, _):
- return value[0]
-
-add_old_configure_assignment('gonkdir', gonkdir)
-
-@depends_if('--with-gonk')
-def gonk_toolkit(_):
- return 'cairo-gonk'
-
-imply_option('--enable-default-toolkit', gonk_toolkit)
-
-
-option('--with-gonk-toolchain-prefix', nargs=1,
- help='Prefix to gonk toolchain commands')
-
-@depends_if('--with-gonk-toolchain-prefix')
-def gonk_toolchain_prefix(value):
- return value
-
-imply_option('--with-toolchain-prefix', gonk_toolchain_prefix)
-
-
-include('common.configure')
diff --git a/b2g/simulator/bootstrap.js b/b2g/simulator/bootstrap.js
deleted file mode 100644
index b728caa3d..000000000
--- a/b2g/simulator/bootstrap.js
+++ /dev/null
@@ -1,4 +0,0 @@
-function startup(data, reason) {}
-function shutdown(data, reason) {}
-function install(data, reason) {}
-function uninstall(data, reason) {}
diff --git a/b2g/simulator/build_xpi.py b/b2g/simulator/build_xpi.py
deleted file mode 100644
index 392be09b2..000000000
--- a/b2g/simulator/build_xpi.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Generate xpi for the simulator addon by:
-# - building a special gaia profile for it, as we need:
-# * more languages, and,
-# * less apps
-# than b2g desktop's one
-# - retrieve usefull app version metadata from the build system
-# - finally, use addon sdk's cfx tool to build the addon xpi
-# that ships:
-# * b2g desktop runtime
-# * gaia profile
-
-import sys, os, re, subprocess
-from mozbuild.preprocessor import Preprocessor
-from mozbuild.base import MozbuildObject
-from mozbuild.util import ensureParentDir
-from mozpack.mozjar import JarWriter
-from zipfile import ZipFile
-from distutils.version import LooseVersion
-
-ftp_root_path = "/pub/mozilla.org/labs/fxos-simulator"
-UPDATE_URL = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/update.rdf"
-XPI_NAME = "fxos-simulator-%(version)s-%(platform)s.xpi"
-
-class GaiaBuilder(object):
- def __init__(self, build, gaia_path):
- self.build = build
- self.gaia_path = gaia_path
-
- def clean(self):
- self.build._run_make(target="clean", directory=self.gaia_path)
-
- def profile(self, env):
- self.build._run_make(target="profile", directory=self.gaia_path, num_jobs=1, silent=False, append_env=env)
-
- def override_prefs(self, srcfile):
- # Note that each time we call `make profile` in gaia, a fresh new pref file is created
- # cat srcfile >> profile/user.js
- with open(os.path.join(self.gaia_path, "profile", "user.js"), "a") as userJs:
- userJs.write(open(srcfile).read())
-
-def preprocess_file(src, dst, version, app_buildid, update_url):
- ensureParentDir(dst)
-
- defines = {
- "ADDON_ID": "fxos_" + version.replace(".", "_") + "_simulator@mozilla.org",
- # (reduce the app build id to only the build date
- # as addon manager doesn't handle big ints in addon versions)
- "ADDON_VERSION": ("%s.%s" % (version, app_buildid[:8])),
- "ADDON_NAME": "Firefox OS " + version + " Simulator",
- "ADDON_DESCRIPTION": "a Firefox OS " + version + " simulator",
- "ADDON_UPDATE_URL": update_url
- }
- pp = Preprocessor(defines=defines)
- pp.do_filter("substitution")
- with open(dst, "w") as output:
- with open(src, "r") as input:
- pp.processFile(input=input, output=output)
-
-def add_dir_to_zip(jar, top, pathInZip, blacklist=()):
- for dirpath, subdirs, files in os.walk(top):
- dir_relpath = os.path.relpath(dirpath, top)
- if dir_relpath.startswith(blacklist):
- continue
- for filename in files:
- relpath = os.path.join(dir_relpath, filename)
- if relpath in blacklist:
- continue
- path = os.path.normpath(os.path.join(pathInZip, relpath))
- file = open(os.path.join(dirpath, filename), "rb")
- mode = os.stat(os.path.join(dirpath, filename)).st_mode
- jar.add(path.encode("ascii"), file, mode=mode)
-
-def add_file_to_zip(jar, path, pathInZip):
- file = open(path, "rb")
- mode = os.stat(path).st_mode
- jar.add(pathInZip.encode("ascii"), file, mode=mode)
-
-def main(platform):
- build = MozbuildObject.from_environment()
- topsrcdir = build.topsrcdir
- distdir = build.distdir
-
- srcdir = os.path.join(topsrcdir, "b2g", "simulator")
-
- app_buildid = open(os.path.join(build.topobjdir, "config", "buildid")).read().strip()
-
- # The simulator uses a shorter version string,
- # it only keeps the major version digits A.B
- # whereas MOZ_B2G_VERSION is A.B.C.D
- b2g_version = build.config_environment.defines["MOZ_B2G_VERSION"].replace('"', '')
- version = ".".join(str(n) for n in LooseVersion(b2g_version).version[0:2])
-
- # Build a gaia profile specific to the simulator in order to:
- # - disable the FTU
- # - set custom prefs to enable devtools debugger server
- # - set custom settings to disable lockscreen and screen timeout
- # - only ship production apps
- gaia_path = build.config_environment.substs["GAIADIR"]
- builder = GaiaBuilder(build, gaia_path)
- builder.clean()
- env = {
- "NOFTU": "1",
- "GAIA_APP_TARGET": "production",
- "SETTINGS_PATH": os.path.join(srcdir, "custom-settings.json")
- }
- builder.profile(env)
- builder.override_prefs(os.path.join(srcdir, "custom-prefs.js"))
-
- # Build the simulator addon xpi
- xpi_name = XPI_NAME % {"version": version, "platform": platform}
- xpi_path = os.path.join(distdir, xpi_name)
-
- update_path = "%s/%s" % (version, platform)
- update_url = UPDATE_URL % {"update_path": update_path}
-
- # Preprocess some files...
- manifest = os.path.join(build.topobjdir, "b2g", "simulator", "install.rdf")
- preprocess_file(os.path.join(srcdir, "install.rdf.in"),
- manifest,
- version,
- app_buildid,
- update_url)
-
- with JarWriter(xpi_path, optimize=False) as zip:
- # Ship addon files into the .xpi
- add_file_to_zip(zip, manifest, "install.rdf")
- add_file_to_zip(zip, os.path.join(srcdir, "bootstrap.js"), "bootstrap.js")
- add_file_to_zip(zip, os.path.join(srcdir, "icon.png"), "icon.png")
- add_file_to_zip(zip, os.path.join(srcdir, "icon64.png"), "icon64.png")
-
- # Ship b2g-desktop, but prevent its gaia profile to be shipped in the xpi
- add_dir_to_zip(zip, os.path.join(distdir, "b2g"), "b2g",
- ("gaia", "B2G.app/Contents/MacOS/gaia",
- "B2G.app/Contents/Resources/gaia"))
- # Then ship our own gaia profile
- add_dir_to_zip(zip, os.path.join(gaia_path, "profile"), "profile")
-
-if __name__ == '__main__':
- if 2 != len(sys.argv):
- print("""Usage:
- python {0} MOZ_PKG_PLATFORM
-""".format(sys.argv[0]))
- sys.exit(1)
- main(*sys.argv[1:])
diff --git a/b2g/simulator/custom-prefs.js b/b2g/simulator/custom-prefs.js
deleted file mode 100644
index 634a9cebe..000000000
--- a/b2g/simulator/custom-prefs.js
+++ /dev/null
@@ -1,8 +0,0 @@
-user_pref("devtools.debugger.prompt-connection", false);
-user_pref("devtools.debugger.forbid-certified-apps", false);
-user_pref("devtools.apps.forbidden-permissions", "");
-user_pref("b2g.software-buttons", true);
-
-// Required for Mulet in order to run the debugger server from the command line
-user_pref("devtools.debugger.remote-enabled", true);
-user_pref("devtools.chrome.enabled", true);
diff --git a/b2g/simulator/custom-settings.json b/b2g/simulator/custom-settings.json
deleted file mode 100644
index ea0264d9a..000000000
--- a/b2g/simulator/custom-settings.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "debugger.remote-mode": "adb-devtools",
- "screen.timeout": 0,
- "lockscreen.enabled": false,
- "lockscreen.locked": false
-}
diff --git a/b2g/simulator/icon.png b/b2g/simulator/icon.png
deleted file mode 100644
index c4307fc84..000000000
--- a/b2g/simulator/icon.png
+++ /dev/null
Binary files differ
diff --git a/b2g/simulator/icon64.png b/b2g/simulator/icon64.png
deleted file mode 100644
index 275cd04a5..000000000
--- a/b2g/simulator/icon64.png
+++ /dev/null
Binary files differ
diff --git a/b2g/simulator/install.rdf.in b/b2g/simulator/install.rdf.in
deleted file mode 100644
index e9827d084..000000000
--- a/b2g/simulator/install.rdf.in
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
- <Description about="urn:mozilla:install-manifest">
- <em:id>@ADDON_ID@</em:id>
- <em:version>@ADDON_VERSION@</em:version>
- <em:type>2</em:type>
- <em:bootstrap>true</em:bootstrap>
- <em:unpack>true</em:unpack>
-
- <!-- Firefox -->
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>44.0a1</em:minVersion>
- <em:maxVersion>45.0</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Front End MetaData -->
- <em:name>@ADDON_NAME@</em:name>
- <em:description>@ADDON_DESCRIPTION@</em:description>
- <em:creator>Myk Melez (https://github.com/mykmelez)</em:creator>
-
- <em:optionsType>2</em:optionsType>
-
- <em:updateURL>@ADDON_UPDATE_URL@</em:updateURL>
-
- <em:contributor>Alexandre Poirot (https://github.com/ochameau)</em:contributor>
- <em:contributor>Anant Narayanan (https://github.com/anantn)</em:contributor>
- <em:contributor>Brandon Kase (https://github.com/bkase)</em:contributor>
- <em:contributor>Breck Yunits (https://github.com/breck7)</em:contributor>
- <em:contributor>César Carruitero (https://github.com/ccarruitero)</em:contributor>
- <em:contributor>David Gomes (https://github.com/davidgomes)</em:contributor>
- <em:contributor>Fabrice Desré (https://github.com/fabricedesre)</em:contributor>
- <em:contributor>Fraser Tweedale (https://github.com/frasertweedale)</em:contributor>
- <em:contributor>Harald Kirschner (https://github.com/digitarald)</em:contributor>
- <em:contributor>Jérémie Patonnier (https://github.com/JeremiePat)</em:contributor>
- <em:contributor>J. Ryan Stinnett (https://github.com/jryans)</em:contributor>
- <em:contributor>Kan-Ru Chen (陳侃如) (https://github.com/kanru)</em:contributor>
- <em:contributor>Louis Stowasser (https://github.com/louisstow)</em:contributor>
- <em:contributor>Luca Greco (https://github.com/rpl)</em:contributor>
- <em:contributor>Matthew Claypotch (https://github.com/potch)</em:contributor>
- <em:contributor>Matthew Riley MacPherson (https://github.com/tofumatt)</em:contributor>
- <em:contributor>Nick Desaulniers (https://github.com/nickdesaulniers)</em:contributor>
- <em:contributor>Soumen Ganguly (https://github.com/SoumenG)</em:contributor>
- <em:contributor>Sudheesh Singanamalla (https://github.com/sudheesh001)</em:contributor>
- <em:contributor>Victor Bjelkholm (https://github.com/VictorBjelkholm)</em:contributor>
- </Description>
-</RDF>
diff --git a/b2g/test/b2g-unittest-requirements.txt b/b2g/test/b2g-unittest-requirements.txt
deleted file mode 100644
index 46bbccc7b..000000000
--- a/b2g/test/b2g-unittest-requirements.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-manifestparser==0.5.7
-mozprocess==0.9
-mozprofile==0.6
-mozrunner==5.15
-mozdevice==0.21
-mozcrash==0.5
-mozfile==0.3
-mozlog==1.1
diff --git a/b2g/test/emulator.manifest b/b2g/test/emulator.manifest
deleted file mode 100644
index 5d9ed8a8d..000000000
--- a/b2g/test/emulator.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-[{
-"size": 746441603,
-"digest": "199236aefecc1657cdc1b791ec38c8184557ab9249aff9c63a74abf73edc1dc0ea36b19b558f34ca3b14f8a511b10bcf37408b19701929522b4dc22dbaddcbe9",
-"algorithm": "sha512",
-"filename": "emulator.zip"
-}]
diff --git a/browser/app/firefox.exe.manifest b/browser/app/firefox.exe.manifest
index b23c2a4c0..8b8db4b7b 100644
--- a/browser/app/firefox.exe.manifest
+++ b/browser/app/firefox.exe.manifest
@@ -37,7 +37,6 @@
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
- <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>
diff --git a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in b/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
index 3e803af5b..a2cb9754d 100644
--- a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
+++ b/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
@@ -11,15 +11,15 @@
<Description about="urn:mozilla:install-manifest">
<em:id>{972ce4c6-7e08-4474-a285-3208198ce6fd}</em:id>
- <em:version>@FIREFOX_VERSION@</em:version>
+ <em:version>@MOZ_APP_VERSION@</em:version>
<!-- Target Application this theme can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>@FIREFOX_VERSION@</em:minVersion>
- <em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
+ <em:id>@MOZ_APP_ID@</em:id>
+ <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
+ <em:maxVersion>@MOZ_APP_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>
diff --git a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build b/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
index 20a4c1cbe..f8c2a5c4b 100644
--- a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
+++ b/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
@@ -4,6 +4,9 @@
# 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/.
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+DEFINES['MOZ_APP_ID'] = CONFIG['MOZ_APP_ID']
+
FINAL_TARGET = 'dist/bin/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}'
FINAL_TARGET_PP_FILES += [
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index 82f8e45a5..465b5349f 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -40,7 +40,7 @@ pref("extensions.checkCompatibility.temporaryThemeOverride_minAppVersion", "29.0
pref("xpinstall.customConfirmationUI", true);
// Preferences for AMO integration
-pref("extensions.getAddons.cache.enabled", true);
+pref("extensions.getAddons.cache.enabled", false);
pref("extensions.getAddons.maxResults", 15);
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%");
pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
@@ -1249,11 +1249,7 @@ pref("plain_text.wrap_long_lines", true);
pref("dom.debug.propagate_gesture_events_through_content", false);
// The request URL of the GeoLocation backend.
-#ifdef RELEASE_OR_BETA
-pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
-#else
-pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
-#endif
+pref("geo.wifi.uri", "http://ip-api.com/json/?fields=lat,lon,status,message");
#ifdef XP_MACOSX
#ifdef RELEASE_OR_BETA
diff --git a/browser/base/content/test/alerts/.eslintrc.js b/browser/base/content/test/alerts/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/alerts/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/alerts/browser.ini b/browser/base/content/test/alerts/browser.ini
deleted file mode 100644
index 07fcf5253..000000000
--- a/browser/base/content/test/alerts/browser.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
- file_dom_notifications.html
-
-[browser_notification_close.js]
-[browser_notification_do_not_disturb.js]
-[browser_notification_open_settings.js]
-[browser_notification_remove_permission.js]
-[browser_notification_permission_migration.js]
-[browser_notification_replace.js]
-[browser_notification_tab_switching.js]
diff --git a/browser/base/content/test/alerts/browser_notification_close.js b/browser/base/content/test/alerts/browser_notification_close.js
deleted file mode 100644
index bbd444212..000000000
--- a/browser/base/content/test/alerts/browser_notification_close.js
+++ /dev/null
@@ -1,71 +0,0 @@
-"use strict";
-
-const {PlacesTestUtils} =
- Cu.import("resource://testing-common/PlacesTestUtils.jsm", {});
-
-let notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-let oldShowFavicons;
-
-add_task(function* test_notificationClose() {
- let pm = Services.perms;
- let notificationURI = makeURI(notificationURL);
- pm.add(notificationURI, "desktop-notification", pm.ALLOW_ACTION);
-
- oldShowFavicons = Services.prefs.getBoolPref("alerts.showFavicons");
- Services.prefs.setBoolPref("alerts.showFavicons", true);
-
- yield PlacesTestUtils.addVisits(notificationURI);
- let faviconURI = yield new Promise(resolve => {
- let faviconURI = makeURI("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC");
- PlacesUtils.favicons.setAndFetchFaviconForPage(notificationURI, faviconURI,
- true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- (faviconURI, iconSize, iconData, mimeType) => resolve(faviconURI),
- Services.scriptSecurityManager.getSystemPrincipal());
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: notificationURL
- }, function* dummyTabTask(aBrowser) {
- yield openNotification(aBrowser, "showNotification2");
-
- info("Notification alert showing");
-
- let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- if (!alertWindow) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
- yield closeNotification(aBrowser);
- return;
- }
-
- let alertTitleLabel = alertWindow.document.getElementById("alertTitleLabel");
- is(alertTitleLabel.value, "Test title", "Title text of notification should be present");
- let alertTextLabel = alertWindow.document.getElementById("alertTextLabel");
- is(alertTextLabel.textContent, "Test body 2", "Body text of notification should be present");
- let alertIcon = alertWindow.document.getElementById("alertIcon");
- is(alertIcon.src, faviconURI.spec, "Icon of notification should be present");
-
- let alertCloseButton = alertWindow.document.querySelector(".alertCloseButton");
- is(alertCloseButton.localName, "toolbarbutton", "close button found");
- let promiseBeforeUnloadEvent =
- BrowserTestUtils.waitForEvent(alertWindow, "beforeunload");
- let closedTime = alertWindow.Date.now();
- alertCloseButton.click();
- info("Clicked on close button");
- yield promiseBeforeUnloadEvent;
-
- ok(true, "Alert should close when the close button is clicked");
- let currentTime = alertWindow.Date.now();
- // The notification will self-close at 12 seconds, so this checks
- // that the notification closed before the timeout.
- ok(currentTime - closedTime < 5000,
- "Close requested at " + closedTime + ", actually closed at " + currentTime);
- });
-});
-
-add_task(function* cleanup() {
- Services.perms.remove(makeURI(notificationURL), "desktop-notification");
- if (typeof oldShowFavicons == "boolean") {
- Services.prefs.setBoolPref("alerts.showFavicons", oldShowFavicons);
- }
-});
diff --git a/browser/base/content/test/alerts/browser_notification_do_not_disturb.js b/browser/base/content/test/alerts/browser_notification_do_not_disturb.js
deleted file mode 100644
index 92c689fd2..000000000
--- a/browser/base/content/test/alerts/browser_notification_do_not_disturb.js
+++ /dev/null
@@ -1,80 +0,0 @@
-"use strict";
-
-var tab;
-var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-
-const ALERT_SERVICE = Cc["@mozilla.org/alerts-service;1"]
- .getService(Ci.nsIAlertsService)
- .QueryInterface(Ci.nsIAlertsDoNotDisturb);
-
-function test () {
- waitForExplicitFinish();
-
- try {
- // Only run the test if the do-not-disturb
- // interface has been implemented.
- ALERT_SERVICE.manualDoNotDisturb;
- ok(true, "Alert service implements do-not-disturb interface");
- } catch (e) {
- ok(true, "Alert service doesn't implement do-not-disturb interface, exiting test");
- finish();
- return;
- }
-
- let pm = Services.perms;
- registerCleanupFunction(function() {
- ALERT_SERVICE.manualDoNotDisturb = false;
- pm.remove(makeURI(notificationURL), "desktop-notification");
- gBrowser.removeTab(tab);
- window.restore();
- });
-
- pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
-
- // Make sure that do-not-disturb is not enabled.
- ok(!ALERT_SERVICE.manualDoNotDisturb, "Alert service should not be disabled when test starts");
- ALERT_SERVICE.manualDoNotDisturb = false;
-
- tab = gBrowser.addTab(notificationURL);
- gBrowser.selectedTab = tab;
- tab.linkedBrowser.addEventListener("load", onLoad, true);
-}
-
-function onLoad() {
- tab.linkedBrowser.removeEventListener("load", onLoad, true);
- openNotification(tab.linkedBrowser, "showNotification2").then(onAlertShowing);
-}
-
-function onAlertShowing() {
- info("Notification alert showing");
-
- let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- if (!alertWindow) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
- closeNotification(tab.linkedBrowser).then(finish);
- return;
- }
- let doNotDisturbMenuItem = alertWindow.document.getElementById("doNotDisturbMenuItem");
- is(doNotDisturbMenuItem.localName, "menuitem", "menuitem found");
- alertWindow.addEventListener("beforeunload", onAlertClosing);
- doNotDisturbMenuItem.click();
- info("Clicked on do-not-disturb menuitem");
-}
-
-function onAlertClosing(event) {
- event.target.removeEventListener("beforeunload", onAlertClosing);
-
- ok(ALERT_SERVICE.manualDoNotDisturb, "Alert service should be disabled after clicking menuitem");
-
- // The notification should not appear, but there is
- // no way from the client-side to know that it was
- // blocked, except for waiting some time and realizing
- // that the "onshow" event never fired.
- openNotification(tab.linkedBrowser, "showNotification2", 2000)
- .then(onAlert2Showing, finish);
-}
-
-function onAlert2Showing() {
- ok(false, "the second alert should not have been shown");
- closeNotification(tab.linkedBrowser).then(finish);
-}
diff --git a/browser/base/content/test/alerts/browser_notification_open_settings.js b/browser/base/content/test/alerts/browser_notification_open_settings.js
deleted file mode 100644
index 5306fd90a..000000000
--- a/browser/base/content/test/alerts/browser_notification_open_settings.js
+++ /dev/null
@@ -1,58 +0,0 @@
-"use strict";
-
-var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-
-add_task(function* test_settingsOpen_observer() {
- info("Opening a dummy tab so openPreferences=>switchToTabHavingURI doesn't use the blank tab.");
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:robots"
- }, function* dummyTabTask(aBrowser) {
- let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#content");
- info("simulate a notifications-open-settings notification");
- let uri = NetUtil.newURI("https://example.com");
- let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
- Services.obs.notifyObservers(principal, "notifications-open-settings", null);
- let tab = yield tabPromise;
- ok(tab, "The notification settings tab opened");
- yield BrowserTestUtils.removeTab(tab);
- });
-});
-
-add_task(function* test_settingsOpen_button() {
- let pm = Services.perms;
- info("Adding notification permission");
- pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
-
- try {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: notificationURL
- }, function* tabTask(aBrowser) {
- info("Waiting for notification");
- yield openNotification(aBrowser, "showNotification2");
-
- let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- if (!alertWindow) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
- yield closeNotification(aBrowser);
- return;
- }
-
- let closePromise = promiseWindowClosed(alertWindow);
- let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#content");
- let openSettingsMenuItem = alertWindow.document.getElementById("openSettingsMenuItem");
- openSettingsMenuItem.click();
-
- info("Waiting for notification settings tab");
- let tab = yield tabPromise;
- ok(tab, "The notification settings tab opened");
-
- yield closePromise;
- yield BrowserTestUtils.removeTab(tab);
- });
- } finally {
- info("Removing notification permission");
- pm.remove(makeURI(notificationURL), "desktop-notification");
- }
-});
diff --git a/browser/base/content/test/alerts/browser_notification_permission_migration.js b/browser/base/content/test/alerts/browser_notification_permission_migration.js
deleted file mode 100644
index b015e59a7..000000000
--- a/browser/base/content/test/alerts/browser_notification_permission_migration.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const UI_VERSION = 32;
-
-var gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"]
- .getService(Ci.nsIObserver);
-var notificationURI = makeURI("http://example.org");
-var pm = Services.perms;
-var currentUIVersion;
-
-add_task(function* setup() {
- currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
- Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
- pm.add(notificationURI, "desktop-notification", pm.ALLOW_ACTION);
-});
-
-add_task(function* test_permissionMigration() {
- if ("@mozilla.org/system-alerts-service;1" in Cc) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
- return;
- }
-
- info("Waiting for migration notification");
- let alertWindowPromise = promiseAlertWindow();
- gBrowserGlue.observe(null, "browser-glue-test", "force-ui-migration");
- let alertWindow = yield alertWindowPromise;
-
- info("Clicking on notification");
- let url =
- Services.urlFormatter.formatURLPref("app.support.baseURL") +
- "push#w_upgraded-notifications";
- let closePromise = promiseWindowClosed(alertWindow);
- let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, url);
- EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"), {}, alertWindow);
-
- info("Waiting for migration info tab");
- let tab = yield tabPromise;
- ok(tab, "The migration info tab opened");
-
- yield closePromise;
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* cleanup() {
- Services.prefs.setIntPref("browser.migration.version", currentUIVersion);
- pm.remove(notificationURI, "desktop-notification");
-});
diff --git a/browser/base/content/test/alerts/browser_notification_remove_permission.js b/browser/base/content/test/alerts/browser_notification_remove_permission.js
deleted file mode 100644
index bd36faeae..000000000
--- a/browser/base/content/test/alerts/browser_notification_remove_permission.js
+++ /dev/null
@@ -1,72 +0,0 @@
-"use strict";
-
-var tab;
-var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-var alertWindowClosed = false;
-var permRemoved = false;
-
-function test () {
- waitForExplicitFinish();
-
- let pm = Services.perms;
- registerCleanupFunction(function() {
- pm.remove(makeURI(notificationURL), "desktop-notification");
- gBrowser.removeTab(tab);
- window.restore();
- });
-
- pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
-
- tab = gBrowser.addTab(notificationURL);
- gBrowser.selectedTab = tab;
- tab.linkedBrowser.addEventListener("load", onLoad, true);
-}
-
-function onLoad() {
- tab.linkedBrowser.removeEventListener("load", onLoad, true);
- openNotification(tab.linkedBrowser, "showNotification2").then(onAlertShowing);
-}
-
-function onAlertShowing() {
- info("Notification alert showing");
-
- let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- if (!alertWindow) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
- closeNotification(tab.linkedBrowser).then(finish);
- return;
- }
- ok(Services.perms.testExactPermission(makeURI(notificationURL), "desktop-notification"),
- "Permission should exist prior to removal");
- let disableForOriginMenuItem = alertWindow.document.getElementById("disableForOriginMenuItem");
- is(disableForOriginMenuItem.localName, "menuitem", "menuitem found");
- Services.obs.addObserver(permObserver, "perm-changed", false);
- alertWindow.addEventListener("beforeunload", onAlertClosing);
- disableForOriginMenuItem.click();
- info("Clicked on disable-for-origin menuitem")
-}
-
-function permObserver(subject, topic, data) {
- if (topic != "perm-changed") {
- return;
- }
-
- let permission = subject.QueryInterface(Ci.nsIPermission);
- is(permission.type, "desktop-notification", "desktop-notification permission changed");
- is(data, "deleted", "desktop-notification permission deleted");
-
- Services.obs.removeObserver(permObserver, "perm-changed");
- permRemoved = true;
- if (alertWindowClosed) {
- finish();
- }
-}
-
-function onAlertClosing(event) {
- event.target.removeEventListener("beforeunload", onAlertClosing);
-
- alertWindowClosed = true;
- if (permRemoved) {
- finish();
- }
-}
diff --git a/browser/base/content/test/alerts/browser_notification_replace.js b/browser/base/content/test/alerts/browser_notification_replace.js
deleted file mode 100644
index e678dc438..000000000
--- a/browser/base/content/test/alerts/browser_notification_replace.js
+++ /dev/null
@@ -1,38 +0,0 @@
-"use strict";
-
-let notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-
-add_task(function* test_notificationReplace() {
- let pm = Services.perms;
- pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: notificationURL
- }, function* dummyTabTask(aBrowser) {
- yield ContentTask.spawn(aBrowser, {}, function* () {
- let win = content.window.wrappedJSObject;
- let notification = win.showNotification1();
- let promiseCloseEvent = ContentTaskUtils.waitForEvent(notification, "close");
-
- let showEvent = yield ContentTaskUtils.waitForEvent(notification, "show");
- Assert.equal(showEvent.target.body, "Test body 1", "Showed tagged notification");
-
- let newNotification = win.showNotification2();
- let newShowEvent = yield ContentTaskUtils.waitForEvent(newNotification, "show");
- Assert.equal(newShowEvent.target.body, "Test body 2", "Showed new notification with same tag");
-
- let closeEvent = yield promiseCloseEvent;
- Assert.equal(closeEvent.target.body, "Test body 1", "Closed previous tagged notification");
-
- let promiseNewCloseEvent = ContentTaskUtils.waitForEvent(newNotification, "close");
- newNotification.close();
- let newCloseEvent = yield promiseNewCloseEvent;
- Assert.equal(newCloseEvent.target.body, "Test body 2", "Closed new notification");
- });
- });
-});
-
-add_task(function* cleanup() {
- Services.perms.remove(makeURI(notificationURL), "desktop-notification");
-});
diff --git a/browser/base/content/test/alerts/browser_notification_tab_switching.js b/browser/base/content/test/alerts/browser_notification_tab_switching.js
deleted file mode 100644
index 7e46c0722..000000000
--- a/browser/base/content/test/alerts/browser_notification_tab_switching.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-"use strict";
-
-var tab;
-var notification;
-var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-var newWindowOpenedFromTab;
-
-add_task(function* test_notificationPreventDefaultAndSwitchTabs() {
- let pm = Services.perms;
- pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
-
- let originalTab = gBrowser.selectedTab;
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: notificationURL
- }, function* dummyTabTask(aBrowser) {
- // Put new tab in background so it is obvious when it is re-focused.
- yield BrowserTestUtils.switchTab(gBrowser, originalTab);
- isnot(gBrowser.selectedBrowser, aBrowser, "Notification page loaded as a background tab");
-
- // First, show a notification that will be have the tab-switching prevented.
- function promiseNotificationEvent(evt) {
- return ContentTask.spawn(aBrowser, evt, function* (evt) {
- return yield new Promise(resolve => {
- let notification = content.wrappedJSObject._notification;
- notification.addEventListener(evt, function l(event) {
- notification.removeEventListener(evt, l);
- resolve({ defaultPrevented: event.defaultPrevented });
- });
- });
- });
- }
- yield openNotification(aBrowser, "showNotification1");
- info("Notification alert showing");
- let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- if (!alertWindow) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
- yield closeNotification(aBrowser);
- return;
- }
- info("Clicking on notification");
- let promiseClickEvent = promiseNotificationEvent("click");
-
- // NB: This executeSoon is needed to allow the non-e10s runs of this test
- // a chance to set the event listener on the page. Otherwise, we
- // synchronously fire the click event before we listen for the event.
- executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"),
- {}, alertWindow);
- });
- let clickEvent = yield promiseClickEvent;
- ok(clickEvent.defaultPrevented, "The event handler for the first notification cancels the event");
- isnot(gBrowser.selectedBrowser, aBrowser, "Notification page still a background tab");
- let notificationClosed = promiseNotificationEvent("close");
- yield closeNotification(aBrowser);
- yield notificationClosed;
-
- // Second, show a notification that will cause the tab to get switched.
- yield openNotification(aBrowser, "showNotification2");
- alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- let promiseTabSelect = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabSelect");
- EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"),
- {},
- alertWindow);
- yield promiseTabSelect;
- is(gBrowser.selectedBrowser.currentURI.spec, notificationURL,
- "Clicking on the second notification should select its originating tab");
- notificationClosed = promiseNotificationEvent("close");
- yield closeNotification(aBrowser);
- yield notificationClosed;
- });
-});
-
-add_task(function* cleanup() {
- Services.perms.remove(makeURI(notificationURL), "desktop-notification");
-});
diff --git a/browser/base/content/test/alerts/file_dom_notifications.html b/browser/base/content/test/alerts/file_dom_notifications.html
deleted file mode 100644
index 6deede8fc..000000000
--- a/browser/base/content/test/alerts/file_dom_notifications.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<html>
-<head>
-<meta charset="utf-8">
-<script>
-"use strict";
-
-function showNotification1() {
- var options = {
- dir: undefined,
- lang: undefined,
- body: "Test body 1",
- tag: "Test tag",
- icon: undefined,
- };
- var n = new Notification("Test title", options);
- n.addEventListener("click", function(event) {
- event.preventDefault();
- });
- return n;
-}
-
-function showNotification2() {
- var options = {
- dir: undefined,
- lang: undefined,
- body: "Test body 2",
- tag: "Test tag",
- icon: undefined,
- };
- return new Notification("Test title", options);
-}
-</script>
-</head>
-<body>
-<form id="notificationForm" onsubmit="showNotification();">
- <input type="submit" value="Show notification" id="submit"/>
-</form>
-</body>
-</html>
diff --git a/browser/base/content/test/alerts/head.js b/browser/base/content/test/alerts/head.js
deleted file mode 100644
index 21257de31..000000000
--- a/browser/base/content/test/alerts/head.js
+++ /dev/null
@@ -1,71 +0,0 @@
-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);
- let windowType = alertWindow.document.documentElement.getAttribute("windowtype");
- if (windowType != "alert:alert") {
- return;
- }
- Services.wm.removeListener(listener);
- resolve(alertWindow);
- });
- },
- };
- Services.wm.addListener(listener);
- });
-}
-
-/**
- * Similar to `BrowserTestUtils.closeWindow`, but
- * doesn't call `window.close()`.
- */
-function promiseWindowClosed(window) {
- return new Promise(function(resolve) {
- Services.ww.registerNotification(function observer(subject, topic, data) {
- if (topic == "domwindowclosed" && subject == window) {
- Services.ww.unregisterNotification(observer);
- resolve();
- }
- });
- });
-}
-
-/**
- * These two functions work with file_dom_notifications.html to open the
- * notification and close it.
- *
- * |fn| can be showNotification1 or showNotification2.
- * if |timeout| is passed, then the promise returned from this function is
- * rejected after the requested number of miliseconds.
- */
-function openNotification(aBrowser, fn, timeout) {
- return ContentTask.spawn(aBrowser, { fn, timeout }, function* ({ fn, timeout }) {
- let win = content.wrappedJSObject;
- let notification = win[fn]();
- win._notification = notification;
- yield new Promise((resolve, reject) => {
- function listener() {
- notification.removeEventListener("show", listener);
- resolve();
- }
-
- notification.addEventListener("show", listener);
-
- if (timeout) {
- content.setTimeout(() => {
- notification.removeEventListener("show", listener);
- reject("timed out");
- }, timeout);
- }
- });
- });
-}
-
-function closeNotification(aBrowser) {
- return ContentTask.spawn(aBrowser, null, function() {
- content.wrappedJSObject._notification.close();
- });
-}
diff --git a/browser/base/content/test/captivePortal/browser.ini b/browser/base/content/test/captivePortal/browser.ini
deleted file mode 100644
index cfdbc5c2f..000000000
--- a/browser/base/content/test/captivePortal/browser.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
-
-[browser_CaptivePortalWatcher.js]
-skip-if = os == "win" # Bug 1313894
-[browser_CaptivePortalWatcher_1.js]
-skip-if = os == "win" # Bug 1313894
-[browser_captivePortal_certErrorUI.js]
diff --git a/browser/base/content/test/captivePortal/browser_CaptivePortalWatcher.js b/browser/base/content/test/captivePortal/browser_CaptivePortalWatcher.js
deleted file mode 100644
index e9c0fad6d..000000000
--- a/browser/base/content/test/captivePortal/browser_CaptivePortalWatcher.js
+++ /dev/null
@@ -1,119 +0,0 @@
-"use strict";
-
-add_task(setupPrefsAndRecentWindowBehavior);
-
-// Each of the test cases below is run twice: once for login-success and once
-// for login-abort (aSuccess set to true and false respectively).
-let testCasesForBothSuccessAndAbort = [
- /**
- * A portal is detected when there's no browser window, then a browser
- * window is opened, then the portal is freed.
- * The portal tab should be added and focused when the window is
- * opened, and closed automatically when the success event is fired.
- * The captive portal notification should be shown when the window is
- * opened, and closed automatically when the success event is fired.
- */
- function* test_detectedWithNoBrowserWindow_Open(aSuccess) {
- yield portalDetected();
- let win = yield focusWindowAndWaitForPortalUI();
- yield freePortal(aSuccess);
- ensureNoPortalTab(win);
- ensureNoPortalNotification(win);
- yield closeWindowAndWaitForXulWindowVisible(win);
- },
-
- /**
- * A portal is detected when multiple browser windows are open but none
- * have focus. A brower window is focused, then the portal is freed.
- * The portal tab should be added and focused when the window is
- * focused, and closed automatically when the success event is fired.
- * The captive portal notification should be shown in all windows upon
- * detection, and closed automatically when the success event is fired.
- */
- function* test_detectedWithNoBrowserWindow_Focused(aSuccess) {
- let win1 = yield openWindowAndWaitForFocus();
- let win2 = yield openWindowAndWaitForFocus();
- // Defocus both windows.
- yield SimpleTest.promiseFocus(window);
-
- yield portalDetected();
-
- // Notification should be shown in both windows.
- ensurePortalNotification(win1);
- ensureNoPortalTab(win1);
- ensurePortalNotification(win2);
- ensureNoPortalTab(win2);
-
- yield focusWindowAndWaitForPortalUI(false, win2);
-
- yield freePortal(aSuccess);
-
- ensureNoPortalNotification(win1);
- ensureNoPortalTab(win2);
- ensureNoPortalNotification(win2);
-
- yield closeWindowAndWaitForXulWindowVisible(win2);
- // No need to wait for xul-window-visible: after win2 is closed, focus
- // is restored to the default window and win1 remains in the background.
- yield BrowserTestUtils.closeWindow(win1);
- },
-
- /**
- * A portal is detected when there's no browser window, then a browser
- * window is opened, then the portal is freed.
- * The recheck triggered when the browser window is opened takes a
- * long time. No portal tab should be added.
- * The captive portal notification should be shown when the window is
- * opened, and closed automatically when the success event is fired.
- */
- function* test_detectedWithNoBrowserWindow_LongRecheck(aSuccess) {
- yield portalDetected();
- let win = yield focusWindowAndWaitForPortalUI(true);
- yield freePortal(aSuccess);
- ensureNoPortalTab(win);
- ensureNoPortalNotification(win);
- yield closeWindowAndWaitForXulWindowVisible(win);
- },
-
- /**
- * A portal is detected when there's no browser window, and the
- * portal is freed before a browser window is opened. No portal
- * UI should be shown when a browser window is opened.
- */
- function* test_detectedWithNoBrowserWindow_GoneBeforeOpen(aSuccess) {
- yield portalDetected();
- yield freePortal(aSuccess);
- let win = yield openWindowAndWaitForFocus();
- // Wait for a while to make sure no UI is shown.
- yield new Promise(resolve => {
- setTimeout(resolve, 1000);
- });
- ensureNoPortalTab(win);
- ensureNoPortalNotification(win);
- yield closeWindowAndWaitForXulWindowVisible(win);
- },
-
- /**
- * A portal is detected when a browser window has focus. No portal tab should
- * be opened. A notification bar should be displayed in all browser windows.
- */
- function* test_detectedWithFocus(aSuccess) {
- let win1 = yield openWindowAndWaitForFocus();
- let win2 = yield openWindowAndWaitForFocus();
- yield portalDetected();
- ensureNoPortalTab(win1);
- ensureNoPortalTab(win2);
- ensurePortalNotification(win1);
- ensurePortalNotification(win2);
- yield freePortal(aSuccess);
- ensureNoPortalNotification(win1);
- ensureNoPortalNotification(win2);
- yield closeWindowAndWaitForXulWindowVisible(win2);
- yield closeWindowAndWaitForXulWindowVisible(win1);
- },
-];
-
-for (let testcase of testCasesForBothSuccessAndAbort) {
- add_task(testcase.bind(null, true));
- add_task(testcase.bind(null, false));
-}
diff --git a/browser/base/content/test/captivePortal/browser_CaptivePortalWatcher_1.js b/browser/base/content/test/captivePortal/browser_CaptivePortalWatcher_1.js
deleted file mode 100644
index 71b12c32a..000000000
--- a/browser/base/content/test/captivePortal/browser_CaptivePortalWatcher_1.js
+++ /dev/null
@@ -1,91 +0,0 @@
-"use strict";
-
-add_task(setupPrefsAndRecentWindowBehavior);
-
-let testcases = [
- /**
- * A portal is detected when there's no browser window,
- * then a browser window is opened, and the portal is logged into
- * and redirects to a different page. The portal tab should be added
- * and focused when the window is opened, and left open after login
- * since it redirected.
- */
- function* test_detectedWithNoBrowserWindow_Redirect() {
- yield portalDetected();
- let win = yield focusWindowAndWaitForPortalUI();
- let browser = win.gBrowser.selectedTab.linkedBrowser;
- let loadPromise =
- BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
- BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
- yield loadPromise;
- yield freePortal(true);
- ensurePortalTab(win);
- ensureNoPortalNotification(win);
- yield closeWindowAndWaitForXulWindowVisible(win);
- },
-
- /**
- * Test the various expected behaviors of the "Show Login Page" button
- * in the captive portal notification. The button should be visible for
- * all tabs except the captive portal tab, and when clicked, should
- * ensure a captive portal tab is open and select it.
- */
- function* test_showLoginPageButton() {
- let win = yield openWindowAndWaitForFocus();
- yield portalDetected();
- let notification = ensurePortalNotification(win);
- testShowLoginPageButtonVisibility(notification, "visible");
-
- function testPortalTabSelectedAndButtonNotVisible() {
- is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
- testShowLoginPageButtonVisibility(notification, "hidden");
- }
-
- let button = notification.querySelector("button.notification-button");
- function* clickButtonAndExpectNewPortalTab() {
- let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
- button.click();
- let tab = yield p;
- is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
- return tab;
- }
-
- // Simulate clicking the button. The portal tab should be opened and
- // selected and the button should hide.
- let tab = yield clickButtonAndExpectNewPortalTab();
- testPortalTabSelectedAndButtonNotVisible();
-
- // Close the tab. The button should become visible.
- yield BrowserTestUtils.removeTab(tab);
- ensureNoPortalTab(win);
- testShowLoginPageButtonVisibility(notification, "visible");
-
- // When the button is clicked, a new portal tab should be opened and
- // selected.
- tab = yield clickButtonAndExpectNewPortalTab();
-
- // Open another arbitrary tab. The button should become visible. When it's clicked,
- // the portal tab should be selected.
- let anotherTab = yield BrowserTestUtils.openNewForegroundTab(win.gBrowser);
- testShowLoginPageButtonVisibility(notification, "visible");
- button.click();
- is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
-
- // Close the portal tab and select the arbitrary tab. The button should become
- // visible and when it's clicked, a new portal tab should be opened.
- yield BrowserTestUtils.removeTab(tab);
- win.gBrowser.selectedTab = anotherTab;
- testShowLoginPageButtonVisibility(notification, "visible");
- tab = yield clickButtonAndExpectNewPortalTab();
-
- yield BrowserTestUtils.removeTab(anotherTab);
- yield freePortal(true);
- ensureNoPortalTab(win);
- ensureNoPortalNotification(win);
- yield closeWindowAndWaitForXulWindowVisible(win);
- },
-];
-
-for (let testcase of testcases) {
- add_task(testcase);
-}
diff --git a/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js b/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
deleted file mode 100644
index 6b97e19a3..000000000
--- a/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const BAD_CERT_PAGE = "https://expired.example.com/";
-
-// This tests the alternate cert error UI when we are behind a captive portal.
-
-add_task(function* checkCaptivePortalCertErrorUI() {
- yield SpecialPowers.pushPrefEnv({
- set: [["captivedetect.canonicalURL", CANONICAL_URL],
- ["captivedetect.canonicalContent", CANONICAL_CONTENT]],
- });
-
- let captivePortalStatePropagated = TestUtils.topicObserved("ipc:network:captive-portal-set-state");
-
- info("Checking that the alternate about:certerror UI is shown when we are behind a captive portal.");
- Services.obs.notifyObservers(null, "captive-portal-login", null);
-
- info("Waiting for captive portal state to be propagated to the content process.");
- yield captivePortalStatePropagated;
-
- // Open a page with a cert error.
- let browser;
- let certErrorLoaded;
- let errorTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- let tab = gBrowser.addTab(BAD_CERT_PAGE);
- gBrowser.selectedTab = tab;
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = waitForCertErrorLoad(browser);
- return tab;
- }, false);
-
- info("Waiting for cert error page to load.")
- yield certErrorLoaded;
-
- let portalTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, CANONICAL_URL);
-
- yield ContentTask.spawn(browser, null, () => {
- let doc = content.document;
- ok(doc.body.classList.contains("captiveportal"),
- "Captive portal error page UI is visible.");
-
- info("Clicking the Open Login Page button.");
- let loginButton = doc.getElementById("openPortalLoginPageButton");
- is(loginButton.getAttribute("autofocus"), "true", "openPortalLoginPageButton has autofocus");
- loginButton.click();
- });
-
- let portalTab = yield portalTabPromise;
- is(gBrowser.selectedTab, portalTab, "Login page should be open in a new foreground tab.");
-
- // Make sure clicking the "Open Login Page" button again focuses the existing portal tab.
- yield BrowserTestUtils.switchTab(gBrowser, errorTab);
- // Passing an empty function to BrowserTestUtils.switchTab lets us wait for an arbitrary
- // tab switch.
- portalTabPromise = BrowserTestUtils.switchTab(gBrowser, () => {});
- yield ContentTask.spawn(browser, null, () => {
- info("Clicking the Open Login Page button.");
- content.document.getElementById("openPortalLoginPageButton").click();
- });
-
- let portalTab2 = yield portalTabPromise;
- is(portalTab2, portalTab, "The existing portal tab should be focused.");
-
- let portalTabRemoved = BrowserTestUtils.removeTab(portalTab, {dontRemove: true});
- let errorTabReloaded = waitForCertErrorLoad(browser);
-
- Services.obs.notifyObservers(null, "captive-portal-login-success", null);
- yield portalTabRemoved;
-
- info("Waiting for error tab to be reloaded after the captive portal was freed.");
- yield errorTabReloaded;
- yield ContentTask.spawn(browser, null, () => {
- let doc = content.document;
- ok(!doc.body.classList.contains("captiveportal"),
- "Captive portal error page UI is not visible.");
- });
-
- yield BrowserTestUtils.removeTab(errorTab);
-});
diff --git a/browser/base/content/test/captivePortal/head.js b/browser/base/content/test/captivePortal/head.js
deleted file mode 100644
index e40b5a325..000000000
--- a/browser/base/content/test/captivePortal/head.js
+++ /dev/null
@@ -1,181 +0,0 @@
-Components.utils.import("resource:///modules/RecentWindow.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "CaptivePortalWatcher",
- "resource:///modules/CaptivePortalWatcher.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cps",
- "@mozilla.org/network/captive-portal-service;1",
- "nsICaptivePortalService");
-
-const CANONICAL_CONTENT = "success";
-const CANONICAL_URL = "data:text/plain;charset=utf-8," + CANONICAL_CONTENT;
-const CANONICAL_URL_REDIRECTED = "data:text/plain;charset=utf-8,redirected";
-const PORTAL_NOTIFICATION_VALUE = "captive-portal-detected";
-
-function* setupPrefsAndRecentWindowBehavior() {
- yield SpecialPowers.pushPrefEnv({
- set: [["captivedetect.canonicalURL", CANONICAL_URL],
- ["captivedetect.canonicalContent", CANONICAL_CONTENT]],
- });
- // We need to test behavior when a portal is detected when there is no browser
- // window, but we can't close the default window opened by the test harness.
- // Instead, we deactivate CaptivePortalWatcher in the default window and
- // exclude it from RecentWindow.getMostRecentBrowserWindow in an attempt to
- // mask its presence.
- window.CaptivePortalWatcher.uninit();
- let getMostRecentBrowserWindowCopy = RecentWindow.getMostRecentBrowserWindow;
- let defaultWindow = window;
- RecentWindow.getMostRecentBrowserWindow = () => {
- let win = getMostRecentBrowserWindowCopy();
- if (win == defaultWindow) {
- return null;
- }
- return win;
- };
-
- registerCleanupFunction(function* cleanUp() {
- RecentWindow.getMostRecentBrowserWindow = getMostRecentBrowserWindowCopy;
- window.CaptivePortalWatcher.init();
- });
-}
-
-function* portalDetected() {
- Services.obs.notifyObservers(null, "captive-portal-login", null);
- yield BrowserTestUtils.waitForCondition(() => {
- return cps.state == cps.LOCKED_PORTAL;
- }, "Waiting for Captive Portal Service to update state after portal detected.");
-}
-
-function* freePortal(aSuccess) {
- Services.obs.notifyObservers(null,
- "captive-portal-login-" + (aSuccess ? "success" : "abort"), null);
- yield BrowserTestUtils.waitForCondition(() => {
- return cps.state != cps.LOCKED_PORTAL;
- }, "Waiting for Captive Portal Service to update state after portal freed.");
-}
-
-// If a window is provided, it will be focused. Otherwise, a new window
-// will be opened and focused.
-function* focusWindowAndWaitForPortalUI(aLongRecheck, win) {
- // CaptivePortalWatcher triggers a recheck when a window gains focus. If
- // the time taken for the check to complete is under PORTAL_RECHECK_DELAY_MS,
- // a tab with the login page is opened and selected. If it took longer,
- // no tab is opened. It's not reliable to time things in an async test,
- // so use a delay threshold of -1 to simulate a long recheck (so that any
- // amount of time is considered excessive), and a very large threshold to
- // simulate a short recheck.
- Preferences.set("captivedetect.portalRecheckDelayMS", aLongRecheck ? -1 : 1000000);
-
- if (!win) {
- win = yield BrowserTestUtils.openNewBrowserWindow();
- }
- yield SimpleTest.promiseFocus(win);
-
- // After a new window is opened, CaptivePortalWatcher asks for a recheck, and
- // waits for it to complete. We need to manually tell it a recheck completed.
- yield BrowserTestUtils.waitForCondition(() => {
- return win.CaptivePortalWatcher._waitingForRecheck;
- }, "Waiting for CaptivePortalWatcher to trigger a recheck.");
- Services.obs.notifyObservers(null, "captive-portal-check-complete", null);
-
- let notification = ensurePortalNotification(win);
-
- if (aLongRecheck) {
- ensureNoPortalTab(win);
- testShowLoginPageButtonVisibility(notification, "visible");
- return win;
- }
-
- let tab = win.gBrowser.tabs[1];
- if (tab.linkedBrowser.currentURI.spec != CANONICAL_URL) {
- // The tab should load the canonical URL, wait for it.
- yield BrowserTestUtils.waitForLocationChange(win.gBrowser, CANONICAL_URL);
- }
- is(win.gBrowser.selectedTab, tab,
- "The captive portal tab should be open and selected in the new window.");
- testShowLoginPageButtonVisibility(notification, "hidden");
- return win;
-}
-
-function ensurePortalTab(win) {
- // For the tests that call this function, it's enough to ensure there
- // are two tabs in the window - the default tab and the portal tab.
- is(win.gBrowser.tabs.length, 2,
- "There should be a captive portal tab in the window.");
-}
-
-function ensurePortalNotification(win) {
- let notificationBox =
- win.document.getElementById("high-priority-global-notificationbox");
- let notification = notificationBox.getNotificationWithValue(PORTAL_NOTIFICATION_VALUE)
- isnot(notification, null,
- "There should be a captive portal notification in the window.");
- return notification;
-}
-
-// Helper to test whether the "Show Login Page" is visible in the captive portal
-// notification (it should be hidden when the portal tab is selected).
-function testShowLoginPageButtonVisibility(notification, visibility) {
- let showLoginPageButton = notification.querySelector("button.notification-button");
- // If the visibility property was never changed from default, it will be
- // an empty string, so we pretend it's "visible" (effectively the same).
- is(showLoginPageButton.style.visibility || "visible", visibility,
- "The \"Show Login Page\" button should be " + visibility + ".");
-}
-
-function ensureNoPortalTab(win) {
- is(win.gBrowser.tabs.length, 1,
- "There should be no captive portal tab in the window.");
-}
-
-function ensureNoPortalNotification(win) {
- let notificationBox =
- win.document.getElementById("high-priority-global-notificationbox");
- is(notificationBox.getNotificationWithValue(PORTAL_NOTIFICATION_VALUE), null,
- "There should be no captive portal notification in the window.");
-}
-
-/**
- * Some tests open a new window and close it later. When the window is closed,
- * the original window opened by mochitest gains focus, generating a
- * xul-window-visible notification. If the next test also opens a new window
- * before this notification has a chance to fire, CaptivePortalWatcher picks
- * up the first one instead of the one from the new window. To avoid this
- * unfortunate intermittent timing issue, we wait for the notification from
- * the original window every time we close a window that we opened.
- */
-function waitForXulWindowVisible() {
- return new Promise(resolve => {
- Services.obs.addObserver(function observe() {
- Services.obs.removeObserver(observe, "xul-window-visible");
- resolve();
- }, "xul-window-visible", false);
- });
-}
-
-function* closeWindowAndWaitForXulWindowVisible(win) {
- let p = waitForXulWindowVisible();
- yield BrowserTestUtils.closeWindow(win);
- yield p;
-}
-
-/**
- * BrowserTestUtils.openNewBrowserWindow() does not guarantee the newly
- * opened window has received focus when the promise resolves, so we
- * have to manually wait every time.
- */
-function* openWindowAndWaitForFocus() {
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield SimpleTest.promiseFocus(win);
- return win;
-}
-
-function waitForCertErrorLoad(browser) {
- return new Promise(resolve => {
- info("Waiting for DOMContentLoaded event");
- browser.addEventListener("DOMContentLoaded", function load() {
- browser.removeEventListener("DOMContentLoaded", load, false, true);
- resolve();
- }, false, true);
- });
-}
diff --git a/browser/base/content/test/chrome/.eslintrc.js b/browser/base/content/test/chrome/.eslintrc.js
deleted file mode 100644
index 8c0f4f574..000000000
--- a/browser/base/content/test/chrome/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/chrome.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/chrome/chrome.ini b/browser/base/content/test/chrome/chrome.ini
deleted file mode 100644
index 15035fc0c..000000000
--- a/browser/base/content/test/chrome/chrome.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[DEFAULT]
-
-[test_aboutCrashed.xul]
diff --git a/browser/base/content/test/chrome/test_aboutCrashed.xul b/browser/base/content/test/chrome/test_aboutCrashed.xul
deleted file mode 100644
index 7a68076f1..000000000
--- a/browser/base/content/test/chrome/test_aboutCrashed.xul
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <iframe type="content" id="frame1"/>
- <iframe type="content" id="frame2" onload="doTest()"/>
- <script type="application/javascript"><![CDATA[
- const Ci = Components.interfaces;
- const Cu = Components.utils;
-
- Cu.import("resource://gre/modules/Services.jsm");
- Cu.import("resource://gre/modules/Task.jsm");
- Cu.import("resource://gre/modules/Promise.jsm");
- Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
- SimpleTest.waitForExplicitFinish();
-
- // Load error pages do not fire "load" events, so let's use a progressListener.
- function waitForErrorPage(frame) {
- let errorPageDeferred = Promise.defer();
-
- let progressListener = {
- onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
- if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
- frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebProgress)
- .removeProgressListener(progressListener,
- Ci.nsIWebProgress.NOTIFY_LOCATION);
-
- errorPageDeferred.resolve();
- }
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference])
- };
-
- frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebProgress)
- .addProgressListener(progressListener,
- Ci.nsIWebProgress.NOTIFY_LOCATION);
-
- return errorPageDeferred.promise;
- }
-
- function doTest() {
- Task.spawn(function test_aboutCrashed() {
- let frame1 = document.getElementById("frame1");
- let frame2 = document.getElementById("frame2");
- let uri1 = Services.io.newURI("http://www.example.com/1", null, null);
- let uri2 = Services.io.newURI("http://www.example.com/2", null, null);
-
- let errorPageReady = waitForErrorPage(frame1);
- frame1.docShell.chromeEventHandler.setAttribute("crashedPageTitle", "pageTitle");
- frame1.docShell.displayLoadError(Components.results.NS_ERROR_CONTENT_CRASHED, uri1, null);
-
- yield errorPageReady;
- frame1.docShell.chromeEventHandler.removeAttribute("crashedPageTitle");
-
- SimpleTest.is(frame1.contentDocument.documentURI,
- "about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/1&c=UTF-8&f=regular&d=pageTitle",
- "Correct about:tabcrashed displayed for page with title.");
-
- errorPageReady = waitForErrorPage(frame2);
- frame2.docShell.displayLoadError(Components.results.NS_ERROR_CONTENT_CRASHED, uri2, null);
-
- yield errorPageReady;
-
- SimpleTest.is(frame2.contentDocument.documentURI,
- "about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/2&c=UTF-8&f=regular&d=%20",
- "Correct about:tabcrashed displayed for page with no title.");
-
- SimpleTest.finish();
- });
- }
- ]]></script>
-
- <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;" />
-</window>
diff --git a/browser/base/content/test/general/.eslintrc.js b/browser/base/content/test/general/.eslintrc.js
deleted file mode 100644
index 11abd6140..000000000
--- a/browser/base/content/test/general/.eslintrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js",
- "../../../../../testing/mochitest/mochitest.eslintrc.js",
- ]
-};
diff --git a/browser/base/content/test/general/POSTSearchEngine.xml b/browser/base/content/test/general/POSTSearchEngine.xml
deleted file mode 100644
index 30567d92f..000000000
--- a/browser/base/content/test/general/POSTSearchEngine.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
- <ShortName>POST Search</ShortName>
- <Url type="text/html" method="POST" template="http://mochi.test:8888/browser/browser/base/content/test/general/print_postdata.sjs">
- <Param name="searchterms" value="{searchTerms}"/>
- </Url>
-</OpenSearchDescription>
diff --git a/browser/base/content/test/general/aboutHome_content_script.js b/browser/base/content/test/general/aboutHome_content_script.js
deleted file mode 100644
index 28d0e617e..000000000
--- a/browser/base/content/test/general/aboutHome_content_script.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-addMessageListener("AboutHome:SearchTriggered", function (msg) {
- sendAsyncMessage("AboutHomeTest:CheckRecordedSearch", msg.data);
-});
diff --git a/browser/base/content/test/general/accounts_testRemoteCommands.html b/browser/base/content/test/general/accounts_testRemoteCommands.html
deleted file mode 100644
index 517317aff..000000000
--- a/browser/base/content/test/general/accounts_testRemoteCommands.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<html>
- <head>
- <meta charset="utf-8">
-
-<script type="text/javascript;version=1.8">
-
-function init() {
- window.addEventListener("message", function process(e) {doTest(e)}, false);
- // unless we relinquish the eventloop,
- // tests will run before the chrome event handlers are ready
- setTimeout(doTest, 0);
-}
-
-function checkStatusValue(payload, expectedValue) {
- return payload.status == expectedValue;
-}
-
-let tests = [
-{
- info: "Check account log in",
- event: "login",
- data: {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- assertion: "foobar",
- sessionToken: "dead",
- kA: "beef",
- kB: "cafe",
- verified: true
- },
- payloadType: "message",
- validateResponse: function(payload) {
- return checkStatusValue(payload, "login");
- },
-},
-];
-
-let currentTest = -1;
-function doTest(evt) {
- if (evt) {
- if (currentTest < 0 || !evt.data.content)
- return; // not yet testing
-
- let test = tests[currentTest];
- if (evt.data.type != test.payloadType)
- return; // skip unrequested events
-
- let error = JSON.stringify(evt.data.content);
- let pass = false;
- try {
- pass = test.validateResponse(evt.data.content)
- } catch (e) {}
- reportResult(test.info, pass, error);
- }
- // start the next test if there are any left
- if (tests[++currentTest])
- sendToBrowser(tests[currentTest].event, tests[currentTest].data);
- else
- reportFinished();
-}
-
-function reportResult(info, pass, error) {
- let data = {type: "testResult", info: info, pass: pass, error: error};
- let event = new CustomEvent("FirefoxAccountsTestResponse", {detail: {data: data}, bubbles: true});
- document.dispatchEvent(event);
-}
-
-function reportFinished(cmd) {
- let data = {type: "testsComplete", count: tests.length};
- let event = new CustomEvent("FirefoxAccountsTestResponse", {detail: {data: data}, bubbles: true});
- document.dispatchEvent(event);
-}
-
-function sendToBrowser(type, data) {
- let event = new CustomEvent("FirefoxAccountsCommand", {detail: {command: type, data: data}, bubbles: true});
- document.dispatchEvent(event);
-}
-
-</script>
- </head>
- <body onload="init()">
- </body>
-</html>
diff --git a/browser/base/content/test/general/alltabslistener.html b/browser/base/content/test/general/alltabslistener.html
deleted file mode 100644
index 166c31037..000000000
--- a/browser/base/content/test/general/alltabslistener.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
-<title>Test page for bug 463387</title>
-</head>
-<body>
-<p>Test page for bug 463387</p>
-</body>
-</html>
diff --git a/browser/base/content/test/general/app_bug575561.html b/browser/base/content/test/general/app_bug575561.html
deleted file mode 100644
index a60c7c87e..000000000
--- a/browser/base/content/test/general/app_bug575561.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=575561
--->
- <head>
- <title>Test for links in app tabs</title>
- </head>
- <body>
- <a href="http://example.com/browser/browser/base/content/test/general/dummy_page.html">same domain</a>
- <a href="http://test1.example.com/browser/browser/base/content/test/general/dummy_page.html">same domain (different subdomain)</a>
- <a href="http://example.org/browser/browser/base/content/test/general/dummy_page.html">different domain</a>
- <a href="http://example.org/browser/browser/base/content/test/general/dummy_page.html" target="foo">different domain (with target)</a>
- <a href="http://www.example.com/browser/browser/base/content/test/general/dummy_page.html">same domain (www prefix)</a>
- <a href="data:text/html,<!DOCTYPE html><html><body>Another Page</body></html>">data: URI</a>
- <iframe src="app_subframe_bug575561.html"></iframe>
- </body>
-</html>
diff --git a/browser/base/content/test/general/app_subframe_bug575561.html b/browser/base/content/test/general/app_subframe_bug575561.html
deleted file mode 100644
index 8690497ff..000000000
--- a/browser/base/content/test/general/app_subframe_bug575561.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=575561
--->
- <head>
- <title>Test for links in app tab subframes</title>
- </head>
- <body>
- <a href="http://example.org/browser/browser/base/content/test/general/dummy_page.html">different domain</a>
- </body>
-</html>
diff --git a/browser/base/content/test/general/audio.ogg b/browser/base/content/test/general/audio.ogg
deleted file mode 100644
index 477544875..000000000
--- a/browser/base/content/test/general/audio.ogg
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/benignPage.html b/browser/base/content/test/general/benignPage.html
deleted file mode 100644
index 8e9429acd..000000000
--- a/browser/base/content/test/general/benignPage.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<html dir="ltr" xml:lang="en-US" lang="en-US">
- <head>
- <meta charset="utf8">
- </head>
- <body>
- <iframe src="http://not-tracking.example.com/"></iframe>
- </body>
-</html>
diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini
deleted file mode 100644
index 96e591ffe..000000000
--- a/browser/base/content/test/general/browser.ini
+++ /dev/null
@@ -1,494 +0,0 @@
-[DEFAULT]
-support-files =
- POSTSearchEngine.xml
- accounts_testRemoteCommands.html
- alltabslistener.html
- app_bug575561.html
- app_subframe_bug575561.html
- aboutHome_content_script.js
- audio.ogg
- browser_bug479408_sample.html
- browser_bug678392-1.html
- browser_bug678392-2.html
- browser_bug970746.xhtml
- browser_fxa_oauth.html
- browser_fxa_oauth_with_keys.html
- browser_fxa_web_channel.html
- browser_registerProtocolHandler_notification.html
- browser_star_hsts.sjs
- browser_tab_dragdrop2_frame1.xul
- browser_web_channel.html
- browser_web_channel_iframe.html
- bug1262648_string_with_newlines.dtd
- bug592338.html
- bug792517-2.html
- bug792517.html
- bug792517.sjs
- bug839103.css
- clipboard_pastefile.html
- contextmenu_common.js
- ctxmenu-image.png
- discovery.html
- download_page.html
- dummy_page.html
- feed_tab.html
- file_generic_favicon.ico
- file_with_favicon.html
- file_bug822367_1.html
- file_bug822367_1.js
- file_bug822367_2.html
- file_bug822367_3.html
- file_bug822367_4.html
- file_bug822367_4.js
- file_bug822367_4B.html
- file_bug822367_5.html
- file_bug822367_6.html
- file_bug902156.js
- file_bug902156_1.html
- file_bug902156_2.html
- file_bug902156_3.html
- file_bug906190_1.html
- file_bug906190_2.html
- file_bug906190_3_4.html
- file_bug906190_redirected.html
- file_bug906190.js
- file_bug906190.sjs
- file_mediaPlayback.html
- file_mixedContentFromOnunload.html
- file_mixedContentFromOnunload_test1.html
- file_mixedContentFromOnunload_test2.html
- file_mixedContentFramesOnHttp.html
- file_mixedPassiveContent.html
- file_bug970276_popup1.html
- file_bug970276_popup2.html
- file_bug970276_favicon1.ico
- file_bug970276_favicon2.ico
- file_documentnavigation_frameset.html
- file_double_close_tab.html
- file_favicon_change.html
- file_favicon_change_not_in_document.html
- file_fullscreen-window-open.html
- head.js
- healthreport_pingData.js
- healthreport_testRemoteCommands.html
- moz.png
- navigating_window_with_download.html
- offlineQuotaNotification.cacheManifest
- offlineQuotaNotification.html
- page_style_sample.html
- parsingTestHelpers.jsm
- pinning_headers.sjs
- ssl_error_reports.sjs
- print_postdata.sjs
- searchSuggestionEngine.sjs
- searchSuggestionEngine.xml
- searchSuggestionEngine2.xml
- subtst_contextmenu.html
- subtst_contextmenu_input.html
- subtst_contextmenu_xul.xul
- test-mixedcontent-securityerrors.html
- test_bug435035.html
- test_bug462673.html
- test_bug628179.html
- test_bug839103.html
- test_bug959531.html
- test_process_flags_chrome.html
- title_test.svg
- unknownContentType_file.pif
- unknownContentType_file.pif^headers^
- video.ogg
- web_video.html
- web_video1.ogv
- web_video1.ogv^headers^
- zoom_test.html
- test_no_mcb_on_http_site_img.html
- test_no_mcb_on_http_site_img.css
- test_no_mcb_on_http_site_font.html
- test_no_mcb_on_http_site_font.css
- test_no_mcb_on_http_site_font2.html
- test_no_mcb_on_http_site_font2.css
- test_mcb_redirect.html
- test_mcb_redirect_image.html
- test_mcb_double_redirect_image.html
- test_mcb_redirect.js
- test_mcb_redirect.sjs
- file_bug1045809_1.html
- file_bug1045809_2.html
- file_csp_block_all_mixedcontent.html
- file_csp_block_all_mixedcontent.js
- !/image/test/mochitest/blue.png
- !/toolkit/components/passwordmgr/test/browser/form_basic.html
- !/toolkit/components/passwordmgr/test/browser/insecure_test.html
- !/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html
- !/toolkit/content/tests/browser/common/mockTransfer.js
- !/toolkit/modules/tests/browser/metadata_*.html
- !/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi
- !/toolkit/mozapps/extensions/test/xpinstall/corrupt.xpi
- !/toolkit/mozapps/extensions/test/xpinstall/incompatible.xpi
- !/toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
- !/toolkit/mozapps/extensions/test/xpinstall/redirect.sjs
- !/toolkit/mozapps/extensions/test/xpinstall/restartless-unsigned.xpi
- !/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi
- !/toolkit/mozapps/extensions/test/xpinstall/theme.xpi
- !/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs
-
-[browser_aboutAccounts.js]
-skip-if = os == "linux" # Bug 958026
-support-files =
- content_aboutAccounts.js
-[browser_aboutCertError.js]
-[browser_aboutNetError.js]
-[browser_aboutSupport_newtab_security_state.js]
-[browser_aboutHealthReport.js]
-skip-if = os == "linux" # Bug 924307
-[browser_aboutHome.js]
-[browser_aboutHome_wrapsCorrectly.js]
-[browser_addKeywordSearch.js]
-[browser_alltabslistener.js]
-[browser_audioTabIcon.js]
-tags = audiochannel
-[browser_backButtonFitts.js]
-skip-if = os == "mac" # The Fitt's Law back button is not supported on OS X
-[browser_beforeunload_duplicate_dialogs.js]
-[browser_blob-channelname.js]
-[browser_bookmark_popup.js]
-skip-if = (os == "linux" && debug) # mouseover not reliable on linux debug builds
-[browser_bookmark_titles.js]
-skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341)
-[browser_bug321000.js]
-subsuite = clipboard
-skip-if = true # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
-[browser_bug356571.js]
-[browser_bug380960.js]
-[browser_bug386835.js]
-[browser_bug406216.js]
-[browser_bug408415.js]
-[browser_bug409481.js]
-[browser_bug409624.js]
-[browser_bug413915.js]
-[browser_bug416661.js]
-[browser_bug417483.js]
-[browser_bug419612.js]
-[browser_bug422590.js]
-[browser_bug423833.js]
-skip-if = true # bug 428712
-[browser_bug424101.js]
-[browser_bug427559.js]
-[browser_bug431826.js]
-[browser_bug432599.js]
-[browser_bug435035.js]
-[browser_bug435325.js]
-[browser_bug441778.js]
-[browser_bug455852.js]
-[browser_bug460146.js]
-[browser_bug462289.js]
-skip-if = toolkit == "cocoa"
-[browser_bug462673.js]
-[browser_bug477014.js]
-[browser_bug479408.js]
-[browser_bug481560.js]
-[browser_bug484315.js]
-[browser_bug491431.js]
-[browser_bug495058.js]
-[browser_bug517902.js]
-skip-if = (os == 'linux' && e10s) # bug 1161699
-[browser_bug519216.js]
-[browser_bug520538.js]
-[browser_bug521216.js]
-[browser_bug533232.js]
-[browser_bug537013.js]
-subsuite = clipboard
-skip-if = e10s # Bug 1134458 - Find bar doesn't work correctly in a detached tab
-[browser_bug537474.js]
-[browser_bug550565.js]
-[browser_bug553455.js]
-[browser_bug555224.js]
-[browser_bug555767.js]
-[browser_bug559991.js]
-[browser_bug561636.js]
-skip-if = true # bug 1057615
-[browser_bug563588.js]
-[browser_bug565575.js]
-[browser_bug567306.js]
-subsuite = clipboard
-[browser_bug1261299.js]
-subsuite = clipboard
-skip-if = toolkit != "cocoa" # Because of tests for supporting Service Menu of macOS, bug 1261299
-[browser_bug1297539.js]
-skip-if = toolkit != "cocoa" # Because of tests for supporting pasting from Service Menu of macOS, bug 1297539
-[browser_bug575561.js]
-[browser_bug575830.js]
-[browser_bug577121.js]
-[browser_bug578534.js]
-[browser_bug579872.js]
-[browser_bug580638.js]
-[browser_bug580956.js]
-[browser_bug581242.js]
-[browser_bug581253.js]
-[browser_bug585558.js]
-[browser_bug585785.js]
-[browser_bug585830.js]
-[browser_bug590206.js]
-[browser_bug592338.js]
-[browser_bug594131.js]
-[browser_bug595507.js]
-skip-if = true # bug 1057615
-[browser_bug596687.js]
-[browser_bug597218.js]
-[browser_bug609700.js]
-[browser_bug623893.js]
-[browser_bug624734.js]
-[browser_bug633691.js]
-[browser_bug647886.js]
-[browser_bug655584.js]
-[browser_bug664672.js]
-[browser_bug676619.js]
-skip-if = os == "mac" # mac: Intermittent failures, bug 925225
-[browser_bug678392.js]
-skip-if = os == "mac" # Bug 1102331 - does focus things on the content window which break in e10s mode (still causes orange on Mac 10.10)
-[browser_bug710878.js]
-[browser_bug719271.js]
-[browser_bug724239.js]
-[browser_bug734076.js]
-[browser_bug735471.js]
-[browser_bug749738.js]
-[browser_bug763468_perwindowpb.js]
-[browser_bug767836_perwindowpb.js]
-[browser_bug817947.js]
-[browser_bug822367.js]
-tags = mcb
-[browser_bug832435.js]
-[browser_bug839103.js]
-[browser_bug882977.js]
-[browser_bug902156.js]
-tags = mcb
-[browser_bug906190.js]
-tags = mcb
-[browser_mixedContentFromOnunload.js]
-tags = mcb
-[browser_mixedContentFramesOnHttp.js]
-tags = mcb
-[browser_bug970746.js]
-[browser_bug1015721.js]
-skip-if = os == 'win'
-[browser_bug1064280_changeUrlInPinnedTab.js]
-[browser_accesskeys.js]
-[browser_clipboard.js]
-subsuite = clipboard
-[browser_clipboard_pastefile.js]
-skip-if = true # Disabled due to the clipboard not supporting real file types yet (bug 1288773)
-[browser_contentAreaClick.js]
-skip-if = e10s # Clicks in content don't go through contentAreaClick with e10s.
-[browser_contentAltClick.js]
-[browser_contextmenu.js]
-subsuite = clipboard
-tags = fullscreen
-skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug 513558
-[browser_contextmenu_input.js]
-skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug 513558
-[browser_ctrlTab.js]
-[browser_datachoices_notification.js]
-skip-if = !datareporting
-[browser_decoderDoctor.js]
-skip-if = os == "mac" # decoder doctor isn't implemented on osx
-[browser_devedition.js]
-[browser_discovery.js]
-[browser_double_close_tab.js]
-[browser_documentnavigation.js]
-[browser_duplicateIDs.js]
-[browser_drag.js]
-skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
-[browser_favicon_change.js]
-[browser_favicon_change_not_in_document.js]
-[browser_findbarClose.js]
-[browser_focusonkeydown.js]
-[browser_fullscreen-window-open.js]
-tags = fullscreen
-skip-if = os == "linux" # Linux: Intermittent failures - bug 941575.
-[browser_fxaccounts.js]
-support-files = fxa_profile_handler.sjs
-[browser_fxa_migrate.js]
-[browser_fxa_oauth.js]
-[browser_fxa_web_channel.js]
-[browser_gestureSupport.js]
-skip-if = e10s # Bug 863514 - no gesture support.
-[browser_getshortcutoruri.js]
-[browser_hide_removing.js]
-[browser_homeDrop.js]
-[browser_identity_UI.js]
-[browser_insecureLoginForms.js]
-support-files = insecure_opener.html
-[browser_invalid_uri_back_forward_manipulation.js]
-[browser_keywordBookmarklets.js]
-[browser_keywordSearch.js]
-[browser_keywordSearch_postData.js]
-[browser_lastAccessedTab.js]
-skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bug 969405)
-[browser_menuButtonFitts.js]
-skip-if = os != "win" # The Fitts Law menu button is only supported on Windows (bug 969376)
-[browser_middleMouse_noJSPaste.js]
-subsuite = clipboard
-[browser_minimize.js]
-[browser_misused_characters_in_strings.js]
-[browser_mixed_content_cert_override.js]
-[browser_mixedcontent_securityflags.js]
-tags = mcb
-[browser_modifiedclick_inherit_principal.js]
-[browser_offlineQuotaNotification.js]
-skip-if = os == "linux" && !debug # bug 1304273
-[browser_feed_discovery.js]
-support-files = feed_discovery.html
-[browser_gZipOfflineChild.js]
-support-files = test_offline_gzip.html gZipOfflineChild.cacheManifest gZipOfflineChild.cacheManifest^headers^ gZipOfflineChild.html gZipOfflineChild.html^headers^
-[browser_overflowScroll.js]
-[browser_pageInfo.js]
-[browser_pageinfo_svg_image.js]
-support-files =
- svg_image.html
-[browser_page_style_menu.js]
-[browser_page_style_menu_update.js]
-[browser_parsable_css.js]
-skip-if = (debug || asan) # no point in running on both opt and debug, and will likely intermittently timeout on debug
-[browser_parsable_script.js]
-skip-if = asan || (os == 'linux' && !debug && (bits == 32)) # disabled on asan because of timeouts, and bug 1172468 for the linux 32-bit pgo issue.
-[browser_permissions.js]
-support-files =
- permissions.html
-[browser_pinnedTabs.js]
-[browser_plainTextLinks.js]
-[browser_printpreview.js]
-[browser_private_browsing_window.js]
-[browser_private_no_prompt.js]
-[browser_purgehistory_clears_sh.js]
-[browser_PageMetaData_pushstate.js]
-[browser_refreshBlocker.js]
-support-files =
- refresh_header.sjs
- refresh_meta.sjs
-[browser_relatedTabs.js]
-[browser_remoteTroubleshoot.js]
-support-files =
- test_remoteTroubleshoot.html
-[browser_remoteWebNavigation_postdata.js]
-[browser_removeTabsToTheEnd.js]
-[browser_restore_isAppTab.js]
-[browser_sanitize-passwordDisabledHosts.js]
-[browser_sanitize-sitepermissions.js]
-[browser_sanitize-timespans.js]
-[browser_sanitizeDialog.js]
-[browser_save_link-perwindowpb.js]
-skip-if = e10s && debug && os == "win" # Bug 1280505
-[browser_save_private_link_perwindowpb.js]
-[browser_save_link_when_window_navigates.js]
-[browser_save_video.js]
-[browser_save_video_frame.js]
-[browser_scope.js]
-[browser_contentSearchUI.js]
-support-files =
- contentSearchUI.html
- contentSearchUI.js
-[browser_selectpopup.js]
-run-if = e10s
-[browser_selectTabAtIndex.js]
-[browser_ssl_error_reports.js]
-[browser_star_hsts.js]
-[browser_subframe_favicons_not_used.js]
-[browser_syncui.js]
-[browser_tab_close_dependent_window.js]
-[browser_tabDrop.js]
-[browser_tabReorder.js]
-[browser_tab_detach_restore.js]
-[browser_tab_drag_drop_perwindow.js]
-[browser_tab_dragdrop.js]
-skip-if = buildapp == 'mulet' || (e10s && (debug || os == 'linux')) # Bug 1312436
-[browser_tab_dragdrop2.js]
-[browser_tabbar_big_widgets.js]
-skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
- # Disabled on OS X because of bug 967917
-[browser_tabfocus.js]
-[browser_tabkeynavigation.js]
-skip-if = (os == "mac" && !e10s) # Bug 1237713 - OSX eats keypresses for some reason
-[browser_tabopen_reflows.js]
-[browser_tabs_close_beforeunload.js]
-support-files =
- close_beforeunload_opens_second_tab.html
- close_beforeunload.html
-[browser_tabs_isActive.js]
-[browser_tabs_owner.js]
-[browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js]
-run-if = e10s
-[browser_trackingUI_1.js]
-tags = trackingprotection
-support-files =
- trackingPage.html
- benignPage.html
-[browser_trackingUI_2.js]
-tags = trackingprotection
-support-files =
- trackingPage.html
- benignPage.html
-[browser_trackingUI_3.js]
-tags = trackingprotection
-[browser_trackingUI_4.js]
-tags = trackingprotection
-support-files =
- trackingPage.html
- benignPage.html
-[browser_trackingUI_5.js]
-tags = trackingprotection
-support-files =
- trackingPage.html
-[browser_trackingUI_6.js]
-tags = trackingprotection
-support-files =
- file_trackingUI_6.html
- file_trackingUI_6.js
- file_trackingUI_6.js^headers^
-[browser_trackingUI_telemetry.js]
-tags = trackingprotection
-support-files =
- trackingPage.html
-[browser_typeAheadFind.js]
-[browser_unknownContentType_title.js]
-[browser_unloaddialogs.js]
-[browser_utilityOverlay.js]
-[browser_viewSourceInTabOnViewSource.js]
-[browser_visibleFindSelection.js]
-[browser_visibleTabs.js]
-[browser_visibleTabs_bookmarkAllPages.js]
-skip-if = true # Bug 1005420 - fails intermittently. also with e10s enabled: bizarre problem with hidden tab having _mouseenter called, via _setPositionalAttributes, and tab not being found resulting in 'candidate is undefined'
-[browser_visibleTabs_bookmarkAllTabs.js]
-[browser_visibleTabs_contextMenu.js]
-[browser_visibleTabs_tabPreview.js]
-skip-if = (os == "win" && !debug)
-[browser_web_channel.js]
-[browser_windowopen_reflows.js]
-[browser_zbug569342.js]
-skip-if = e10s || debug # Bug 1094240 - has findbar-related failures
-[browser_registerProtocolHandler_notification.js]
-[browser_no_mcb_on_http_site.js]
-tags = mcb
-[browser_addCertException.js]
-[browser_bug1045809.js]
-tags = mcb
-[browser_e10s_switchbrowser.js]
-[browser_e10s_about_process.js]
-[browser_e10s_chrome_process.js]
-[browser_e10s_javascript.js]
-[browser_blockHPKP.js]
-tags = psm
-[browser_mcb_redirect.js]
-tags = mcb
-[browser_windowactivation.js]
-[browser_contextmenu_childprocess.js]
-[browser_bug963945.js]
-[browser_domFullscreen_fullscreenMode.js]
-tags = fullscreen
-[browser_menuButtonBadgeManager.js]
-[browser_newTabDrop.js]
-[browser_newWindowDrop.js]
-[browser_csp_block_all_mixedcontent.js]
-tags = mcb
-[browser_newwindow_focus.js]
-skip-if = (os == "linux" && !e10s) # Bug 1263254 - Perma fails on Linux without e10s for some reason.
-[browser_bug1299667.js]
diff --git a/browser/base/content/test/general/browser_PageMetaData_pushstate.js b/browser/base/content/test/general/browser_PageMetaData_pushstate.js
deleted file mode 100644
index 6f71c57a3..000000000
--- a/browser/base/content/test/general/browser_PageMetaData_pushstate.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-add_task(function* () {
- let rooturi = "https://example.com/browser/toolkit/modules/tests/browser/";
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, rooturi + "metadata_simple.html");
- yield ContentTask.spawn(gBrowser.selectedBrowser, { rooturi }, function* (args) {
- let result = PageMetadata.getData(content.document);
- // Result should have description.
- Assert.equal(result.url, args.rooturi + "metadata_simple.html", "metadata url is correct");
- Assert.equal(result.title, "Test Title", "metadata title is correct");
- Assert.equal(result.description, "A very simple test page", "description is correct");
-
- content.history.pushState({}, "2", "2.html");
- result = PageMetadata.getData(content.document);
- // Result should not have description.
- Assert.equal(result.url, args.rooturi + "2.html", "metadata url is correct");
- Assert.equal(result.title, "Test Title", "metadata title is correct");
- Assert.ok(!result.description, "description is undefined");
-
- Assert.equal(content.document.documentURI, args.rooturi + "2.html",
- "content.document has correct url");
- });
-
- is(gBrowser.currentURI.spec, rooturi + "2.html", "gBrowser has correct url");
-
- gBrowser.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/general/browser_aboutAccounts.js b/browser/base/content/test/general/browser_aboutAccounts.js
deleted file mode 100644
index fd72a1608..000000000
--- a/browser/base/content/test/general/browser_aboutAccounts.js
+++ /dev/null
@@ -1,499 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: window.location is null");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
- "resource://gre/modules/FxAccounts.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm");
-
-const CHROME_BASE = "chrome://mochitests/content/browser/browser/base/content/test/general/";
-// Preference helpers.
-var changedPrefs = new Set();
-
-function setPref(name, value) {
- changedPrefs.add(name);
- Services.prefs.setCharPref(name, value);
-}
-
-registerCleanupFunction(function() {
- // Ensure we don't pollute prefs for next tests.
- for (let name of changedPrefs) {
- Services.prefs.clearUserPref(name);
- }
-});
-
-var gTests = [
-{
- desc: "Test the remote commands",
- teardown: function* () {
- gBrowser.removeCurrentTab();
- yield signOut();
- },
- run: function* ()
- {
- setPref("identity.fxaccounts.remote.signup.uri",
- "https://example.com/browser/browser/base/content/test/general/accounts_testRemoteCommands.html");
- let tab = yield promiseNewTabLoadEvent("about:accounts");
- let mm = tab.linkedBrowser.messageManager;
-
- let deferred = Promise.defer();
-
- // We'll get a message when openPrefs() is called, which this test should
- // arrange.
- let promisePrefsOpened = promiseOneMessage(tab, "test:openPrefsCalled");
- let results = 0;
- try {
- mm.addMessageListener("test:response", function responseHandler(msg) {
- let data = msg.data.data;
- if (data.type == "testResult") {
- ok(data.pass, data.info);
- results++;
- } else if (data.type == "testsComplete") {
- is(results, data.count, "Checking number of results received matches the number of tests that should have run");
- mm.removeMessageListener("test:response", responseHandler);
- deferred.resolve();
- }
- });
- } catch (e) {
- ok(false, "Failed to get all commands");
- deferred.reject();
- }
- yield deferred.promise;
- yield promisePrefsOpened;
- }
-},
-{
- desc: "Test action=signin - no user logged in",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* ()
- {
- // When this loads with no user logged-in, we expect the "normal" URL
- const expected_url = "https://example.com/?is_sign_in";
- setPref("identity.fxaccounts.remote.signin.uri", expected_url);
- let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin");
- is(url, expected_url, "action=signin got the expected URL");
- // we expect the remote iframe to be shown.
- yield checkVisibilities(tab, {
- stage: false, // parent of 'manage' and 'intro'
- manage: false,
- intro: false, // this is "get started"
- remote: true,
- networkError: false
- });
- }
-},
-{
- desc: "Test action=signin - user logged in",
- teardown: function* () {
- gBrowser.removeCurrentTab();
- yield signOut();
- },
- run: function* ()
- {
- // When this loads with a user logged-in, we expect the normal URL to
- // have been ignored and the "manage" page to be shown.
- const expected_url = "https://example.com/?is_sign_in";
- setPref("identity.fxaccounts.remote.signin.uri", expected_url);
- yield setSignedInUser();
- let tab = yield promiseNewTabLoadEvent("about:accounts?action=signin");
- // about:accounts initializes after fetching the current user from Fxa -
- // so we also request it - by the time we get it we know it should have
- // done its thing.
- yield fxAccounts.getSignedInUser();
- // we expect "manage" to be shown.
- yield checkVisibilities(tab, {
- stage: true, // parent of 'manage' and 'intro'
- manage: true,
- intro: false, // this is "get started"
- remote: false,
- networkError: false
- });
- }
-},
-{
- desc: "Test action=signin - captive portal",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* ()
- {
- const signinUrl = "https://redirproxy.example.com/test";
- setPref("identity.fxaccounts.remote.signin.uri", signinUrl);
- let [tab, ] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin");
- yield checkVisibilities(tab, {
- stage: true, // parent of 'manage' and 'intro'
- manage: false,
- intro: false, // this is "get started"
- remote: false,
- networkError: true
- });
- }
-},
-{
- desc: "Test action=signin - offline",
- teardown: () => {
- gBrowser.removeCurrentTab();
- BrowserOffline.toggleOfflineStatus();
- },
- run: function* ()
- {
- BrowserOffline.toggleOfflineStatus();
- Services.cache2.clear();
-
- const signinUrl = "https://unknowndomain.cow";
- setPref("identity.fxaccounts.remote.signin.uri", signinUrl);
- let [tab, ] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin");
- yield checkVisibilities(tab, {
- stage: true, // parent of 'manage' and 'intro'
- manage: false,
- intro: false, // this is "get started"
- remote: false,
- networkError: true
- });
- }
-},
-{
- desc: "Test action=signup - no user logged in",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* ()
- {
- const expected_url = "https://example.com/?is_sign_up";
- setPref("identity.fxaccounts.remote.signup.uri", expected_url);
- let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signup");
- is(url, expected_url, "action=signup got the expected URL");
- // we expect the remote iframe to be shown.
- yield checkVisibilities(tab, {
- stage: false, // parent of 'manage' and 'intro'
- manage: false,
- intro: false, // this is "get started"
- remote: true,
- networkError: false
- });
- },
-},
-{
- desc: "Test action=signup - user logged in",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* ()
- {
- const expected_url = "https://example.com/?is_sign_up";
- setPref("identity.fxaccounts.remote.signup.uri", expected_url);
- yield setSignedInUser();
- let tab = yield promiseNewTabLoadEvent("about:accounts?action=signup");
- yield fxAccounts.getSignedInUser();
- // we expect "manage" to be shown.
- yield checkVisibilities(tab, {
- stage: true, // parent of 'manage' and 'intro'
- manage: true,
- intro: false, // this is "get started"
- remote: false,
- networkError: false
- });
- },
-},
-{
- desc: "Test action=reauth",
- teardown: function* () {
- gBrowser.removeCurrentTab();
- yield signOut();
- },
- run: function* ()
- {
- const expected_url = "https://example.com/?is_force_auth";
- setPref("identity.fxaccounts.remote.force_auth.uri", expected_url);
-
- yield setSignedInUser();
- let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=reauth");
- // The current user will be appended to the url
- let expected = expected_url + "&email=foo%40example.com";
- is(url, expected, "action=reauth got the expected URL");
- },
-},
-{
- desc: "Test with migrateToDevEdition enabled (success)",
- teardown: function* () {
- gBrowser.removeCurrentTab();
- yield signOut();
- },
- run: function* ()
- {
- let fxAccountsCommon = {};
- Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
- const pref = "identity.fxaccounts.migrateToDevEdition";
- changedPrefs.add(pref);
- Services.prefs.setBoolPref(pref, true);
-
- // Create the signedInUser.json file that will be used as the source of
- // migrated user data.
- let signedInUser = {
- version: 1,
- accountData: {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- sessionToken: "dead",
- verified: true
- }
- };
- // We use a sub-dir of the real profile dir as the "pretend" profile dir
- // for this test.
- let profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
- let mockDir = profD.clone();
- mockDir.append("about-accounts-mock-profd");
- mockDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
- let fxAccountsStorage = OS.Path.join(mockDir.path, fxAccountsCommon.DEFAULT_STORAGE_FILENAME);
- yield OS.File.writeAtomic(fxAccountsStorage, JSON.stringify(signedInUser));
- info("Wrote file " + fxAccountsStorage);
-
- // this is a little subtle - we load about:robots so we get a non-remote
- // tab, then we send a message which does both (a) load the URL we want and
- // (b) mocks the default profile path used by about:accounts.
- let tab = yield promiseNewTabLoadEvent("about:robots");
- let readyPromise = promiseOneMessage(tab, "test:load-with-mocked-profile-path-response");
-
- let mm = tab.linkedBrowser.messageManager;
- mm.sendAsyncMessage("test:load-with-mocked-profile-path", {
- url: "about:accounts",
- profilePath: mockDir.path,
- });
-
- let response = yield readyPromise;
- // We are expecting the iframe to be on the "force reauth" URL
- let expected = yield fxAccounts.promiseAccountsForceSigninURI();
- is(response.data.url, expected);
-
- let userData = yield fxAccounts.getSignedInUser();
- SimpleTest.isDeeply(userData, signedInUser.accountData, "All account data were migrated");
- // The migration pref will have been switched off by now.
- is(Services.prefs.getBoolPref(pref), false, pref + " got the expected value");
-
- yield OS.File.remove(fxAccountsStorage);
- yield OS.File.removeEmptyDir(mockDir.path);
- },
-},
-{
- desc: "Test with migrateToDevEdition enabled (no user to migrate)",
- teardown: function* () {
- gBrowser.removeCurrentTab();
- yield signOut();
- },
- run: function* ()
- {
- const pref = "identity.fxaccounts.migrateToDevEdition";
- changedPrefs.add(pref);
- Services.prefs.setBoolPref(pref, true);
-
- let profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
- let mockDir = profD.clone();
- mockDir.append("about-accounts-mock-profd");
- mockDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
- // but leave it empty, so we don't think a user is logged in.
-
- let tab = yield promiseNewTabLoadEvent("about:robots");
- let readyPromise = promiseOneMessage(tab, "test:load-with-mocked-profile-path-response");
-
- let mm = tab.linkedBrowser.messageManager;
- mm.sendAsyncMessage("test:load-with-mocked-profile-path", {
- url: "about:accounts",
- profilePath: mockDir.path,
- });
-
- let response = yield readyPromise;
- // We are expecting the iframe to be on the "signup" URL
- let expected = yield fxAccounts.promiseAccountsSignUpURI();
- is(response.data.url, expected);
-
- // and expect no signed in user.
- let userData = yield fxAccounts.getSignedInUser();
- is(userData, null);
- // The migration pref should have still been switched off.
- is(Services.prefs.getBoolPref(pref), false, pref + " got the expected value");
- yield OS.File.removeEmptyDir(mockDir.path);
- },
-},
-{
- desc: "Test observers about:accounts",
- teardown: function() {
- gBrowser.removeCurrentTab();
- },
- run: function* () {
- setPref("identity.fxaccounts.remote.signup.uri", "https://example.com/");
- yield setSignedInUser();
- let tab = yield promiseNewTabLoadEvent("about:accounts");
- // sign the user out - the tab should have action=signin
- yield signOut();
- // wait for the new load.
- yield promiseOneMessage(tab, "test:document:load");
- is(tab.linkedBrowser.contentDocument.location.href, "about:accounts?action=signin");
- }
-},
-{
- desc: "Test entrypoint query string, no action, no user logged in",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* () {
- // When this loads with no user logged-in, we expect the "normal" URL
- setPref("identity.fxaccounts.remote.signup.uri", "https://example.com/");
- let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?entrypoint=abouthome");
- is(url, "https://example.com/?entrypoint=abouthome", "entrypoint=abouthome got the expected URL");
- },
-},
-{
- desc: "Test entrypoint query string for signin",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* () {
- // When this loads with no user logged-in, we expect the "normal" URL
- const expected_url = "https://example.com/?is_sign_in";
- setPref("identity.fxaccounts.remote.signin.uri", expected_url);
- let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin&entrypoint=abouthome");
- is(url, expected_url + "&entrypoint=abouthome", "entrypoint=abouthome got the expected URL");
- },
-},
-{
- desc: "Test entrypoint query string for signup",
- teardown: () => gBrowser.removeCurrentTab(),
- run: function* () {
- // When this loads with no user logged-in, we expect the "normal" URL
- const sign_up_url = "https://example.com/?is_sign_up";
- setPref("identity.fxaccounts.remote.signup.uri", sign_up_url);
- let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?entrypoint=abouthome&action=signup");
- is(url, sign_up_url + "&entrypoint=abouthome", "entrypoint=abouthome got the expected URL");
- },
-},
-{
- desc: "about:accounts URL params should be copied to remote URL params " +
- "when remote URL has no URL params, except for 'action'",
- teardown() {
- gBrowser.removeCurrentTab();
- },
- run: function* () {
- let signupURL = "https://example.com/";
- setPref("identity.fxaccounts.remote.signup.uri", signupURL);
- let queryStr = "email=foo%40example.com&foo=bar&baz=quux";
- let [, url] =
- yield promiseNewTabWithIframeLoadEvent("about:accounts?" + queryStr +
- "&action=action");
- is(url, signupURL + "?" + queryStr, "URL params are copied to signup URL");
- },
-},
-{
- desc: "about:accounts URL params should be copied to remote URL params " +
- "when remote URL already has some URL params, except for 'action'",
- teardown() {
- gBrowser.removeCurrentTab();
- },
- run: function* () {
- let signupURL = "https://example.com/?param";
- setPref("identity.fxaccounts.remote.signup.uri", signupURL);
- let queryStr = "email=foo%40example.com&foo=bar&baz=quux";
- let [, url] =
- yield promiseNewTabWithIframeLoadEvent("about:accounts?" + queryStr +
- "&action=action");
- is(url, signupURL + "&" + queryStr, "URL params are copied to signup URL");
- },
-},
-]; // gTests
-
-function test()
-{
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- for (let testCase of gTests) {
- info(testCase.desc);
- try {
- yield testCase.run();
- } finally {
- yield testCase.teardown();
- }
- }
-
- finish();
- });
-}
-
-function promiseOneMessage(tab, messageName) {
- let mm = tab.linkedBrowser.messageManager;
- let deferred = Promise.defer();
- mm.addMessageListener(messageName, function onmessage(message) {
- mm.removeMessageListener(messageName, onmessage);
- deferred.resolve(message);
- });
- return deferred.promise;
-}
-
-function promiseNewTabLoadEvent(aUrl)
-{
- let tab = gBrowser.selectedTab = gBrowser.addTab(aUrl);
- let browser = tab.linkedBrowser;
- let mm = browser.messageManager;
-
- // give it an e10s-friendly content script to help with our tests.
- mm.loadFrameScript(CHROME_BASE + "content_aboutAccounts.js", true);
- // and wait for it to tell us about the load.
- return promiseOneMessage(tab, "test:document:load").then(
- () => tab
- );
-}
-
-// Returns a promise which is resolved with the iframe's URL after a new
-// tab is created and the iframe in that tab loads.
-function promiseNewTabWithIframeLoadEvent(aUrl) {
- let deferred = Promise.defer();
- let tab = gBrowser.selectedTab = gBrowser.addTab(aUrl);
- let browser = tab.linkedBrowser;
- let mm = browser.messageManager;
-
- // give it an e10s-friendly content script to help with our tests.
- mm.loadFrameScript(CHROME_BASE + "content_aboutAccounts.js", true);
- // and wait for it to tell us about the iframe load.
- mm.addMessageListener("test:iframe:load", function onFrameLoad(message) {
- mm.removeMessageListener("test:iframe:load", onFrameLoad);
- deferred.resolve([tab, message.data.url]);
- });
- return deferred.promise;
-}
-
-function checkVisibilities(tab, data) {
- let ids = Object.keys(data);
- let mm = tab.linkedBrowser.messageManager;
- let deferred = Promise.defer();
- mm.addMessageListener("test:check-visibilities-response", function onResponse(message) {
- mm.removeMessageListener("test:check-visibilities-response", onResponse);
- for (let id of ids) {
- is(message.data[id], data[id], "Element '" + id + "' has correct visibility");
- }
- deferred.resolve();
- });
- mm.sendAsyncMessage("test:check-visibilities", {ids: ids});
- return deferred.promise;
-}
-
-// watch out - these will fire observers which if you aren't careful, may
-// interfere with the tests.
-function setSignedInUser(data) {
- if (!data) {
- data = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- assertion: "foobar",
- sessionToken: "dead",
- kA: "beef",
- kB: "cafe",
- verified: true
- }
- }
- return fxAccounts.setSignedInUser(data);
-}
-
-function signOut() {
- // we always want a "localOnly" signout here...
- return fxAccounts.signOut(true);
-}
diff --git a/browser/base/content/test/general/browser_aboutCertError.js b/browser/base/content/test/general/browser_aboutCertError.js
deleted file mode 100644
index 0e335066c..000000000
--- a/browser/base/content/test/general/browser_aboutCertError.js
+++ /dev/null
@@ -1,409 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// This is testing the aboutCertError page (Bug 1207107).
-
-const GOOD_PAGE = "https://example.com/";
-const BAD_CERT = "https://expired.example.com/";
-const UNKNOWN_ISSUER = "https://self-signed.example.com ";
-const BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443";
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-
-add_task(function* checkReturnToAboutHome() {
- info("Loading a bad cert page directly and making sure 'return to previous page' goes to about:home");
- let browser;
- let certErrorLoaded;
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = gBrowser.addTab(BAD_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = waitForCertErrorLoad(browser);
- }, false);
-
- info("Loading and waiting for the cert error");
- yield certErrorLoaded;
-
- is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
-
- // Populate the shistory entries manually, since it happens asynchronously
- // and the following tests will be too soon otherwise.
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is one shistory entry");
-
- info("Clicking the go back button on about:certerror");
- yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let returnButton = doc.getElementById("returnButton");
- is(returnButton.getAttribute("autofocus"), "true", "returnButton has autofocus");
- returnButton.click();
-
- yield ContentTaskUtils.waitForEvent(this, "pageshow", true);
- });
-
- is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
- is(gBrowser.currentURI.spec, "about:home", "Went back");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_task(function* checkReturnToPreviousPage() {
- info("Loading a bad cert page and making sure 'return to previous page' goes back");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
- let browser = gBrowser.selectedBrowser;
-
- info("Loading and waiting for the cert error");
- let certErrorLoaded = waitForCertErrorLoad(browser);
- BrowserTestUtils.loadURI(browser, BAD_CERT);
- yield certErrorLoaded;
-
- is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
-
- // Populate the shistory entries manually, since it happens asynchronously
- // and the following tests will be too soon otherwise.
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 2, "there are two shistory entries");
-
- info("Clicking the go back button on about:certerror");
- yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let returnButton = doc.getElementById("returnButton");
- returnButton.click();
-
- yield ContentTaskUtils.waitForEvent(this, "pageshow", true);
- });
-
- is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
- is(browser.webNavigation.canGoForward, true, "webNavigation.canGoForward");
- is(gBrowser.currentURI.spec, GOOD_PAGE, "Went back");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_task(function* checkBadStsCert() {
- info("Loading a badStsCert and making sure exception button doesn't show up");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE);
- let browser = gBrowser.selectedBrowser;
-
- info("Loading and waiting for the cert error");
- let certErrorLoaded = waitForCertErrorLoad(browser);
- BrowserTestUtils.loadURI(browser, BAD_STS_CERT);
- yield certErrorLoaded;
-
- let exceptionButtonHidden = yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let exceptionButton = doc.getElementById("exceptionDialogButton");
- return exceptionButton.hidden;
- });
- ok(exceptionButtonHidden, "Exception button is hidden");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-const PREF_BLOCKLIST_CLOCK_SKEW_SECONDS = "services.blocklist.clock_skew_seconds";
-
-add_task(function* checkWrongSystemTimeWarning() {
- function* setUpPage() {
- let browser;
- let certErrorLoaded;
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = gBrowser.addTab(BAD_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = waitForCertErrorLoad(browser);
- }, false);
-
- info("Loading and waiting for the cert error");
- yield certErrorLoaded;
-
- return yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let div = doc.getElementById("wrongSystemTimePanel");
- let systemDateDiv = doc.getElementById("wrongSystemTime_systemDate");
- let actualDateDiv = doc.getElementById("wrongSystemTime_actualDate");
- let learnMoreLink = doc.getElementById("learnMoreLink");
-
- return {
- divDisplay: content.getComputedStyle(div).display,
- text: div.textContent,
- systemDate: systemDateDiv.textContent,
- actualDate: actualDateDiv.textContent,
- learnMoreLink: learnMoreLink.href
- };
- });
- }
-
- let formatter = new Intl.DateTimeFormat();
-
- // pretend we have a positively skewed (ahead) system time
- let serverDate = new Date("2015/10/27");
- let serverDateFmt = formatter.format(serverDate);
- let localDateFmt = formatter.format(new Date());
-
- let skew = Math.floor((Date.now() - serverDate.getTime()) / 1000);
- yield new Promise(r => SpecialPowers.pushPrefEnv({set:
- [[PREF_BLOCKLIST_CLOCK_SKEW_SECONDS, skew]]}, r));
-
- info("Loading a bad cert page with a skewed clock");
- let message = yield Task.spawn(setUpPage);
-
- isnot(message.divDisplay, "none", "Wrong time message information is visible");
- ok(message.text.includes("because your clock appears to show the wrong time"),
- "Correct error message found");
- ok(message.text.includes("expired.example.com"), "URL found in error message");
- ok(message.systemDate.includes(localDateFmt), "correct local date displayed");
- ok(message.actualDate.includes(serverDateFmt), "correct server date displayed");
- ok(message.learnMoreLink.includes("time-errors"), "time-errors in the Learn More URL");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- // pretend we have a negatively skewed (behind) system time
- serverDate = new Date();
- serverDate.setYear(serverDate.getFullYear() + 1);
- serverDateFmt = formatter.format(serverDate);
-
- skew = Math.floor((Date.now() - serverDate.getTime()) / 1000);
- yield new Promise(r => SpecialPowers.pushPrefEnv({set:
- [[PREF_BLOCKLIST_CLOCK_SKEW_SECONDS, skew]]}, r));
-
- info("Loading a bad cert page with a skewed clock");
- message = yield Task.spawn(setUpPage);
-
- isnot(message.divDisplay, "none", "Wrong time message information is visible");
- ok(message.text.includes("because your clock appears to show the wrong time"),
- "Correct error message found");
- ok(message.text.includes("expired.example.com"), "URL found in error message");
- ok(message.systemDate.includes(localDateFmt), "correct local date displayed");
- ok(message.actualDate.includes(serverDateFmt), "correct server date displayed");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- // pretend we only have a slightly skewed system time, four hours
- skew = 60 * 60 * 4;
- yield new Promise(r => SpecialPowers.pushPrefEnv({set:
- [[PREF_BLOCKLIST_CLOCK_SKEW_SECONDS, skew]]}, r));
-
- info("Loading a bad cert page with an only slightly skewed clock");
- message = yield Task.spawn(setUpPage);
-
- is(message.divDisplay, "none", "Wrong time message information is not visible");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- // now pretend we have no skewed system time
- skew = 0;
- yield new Promise(r => SpecialPowers.pushPrefEnv({set:
- [[PREF_BLOCKLIST_CLOCK_SKEW_SECONDS, skew]]}, r));
-
- info("Loading a bad cert page with no skewed clock");
- message = yield Task.spawn(setUpPage);
-
- is(message.divDisplay, "none", "Wrong time message information is not visible");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_task(function* checkAdvancedDetails() {
- info("Loading a bad cert page and verifying the main error and advanced details section");
- let browser;
- let certErrorLoaded;
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = gBrowser.addTab(BAD_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = waitForCertErrorLoad(browser);
- }, false);
-
- info("Loading and waiting for the cert error");
- yield certErrorLoaded;
-
- let message = yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let shortDescText = doc.getElementById("errorShortDescText");
- info("Main error text: " + shortDescText.textContent);
- ok(shortDescText.textContent.includes("expired.example.com"),
- "Should list hostname in error message.");
-
- let advancedButton = doc.getElementById("advancedButton");
- advancedButton.click();
- let el = doc.getElementById("errorCode");
- return { textContent: el.textContent, tagName: el.tagName };
- });
- is(message.textContent, "SEC_ERROR_EXPIRED_CERTIFICATE",
- "Correct error message found");
- is(message.tagName, "a", "Error message is a link");
-
- message = yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let errorCode = doc.getElementById("errorCode");
- errorCode.click();
- let div = doc.getElementById("certificateErrorDebugInformation");
- let text = doc.getElementById("certificateErrorText");
-
- let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
- .getService(Ci.nsISerializationHelper);
- let serializable = docShell.failedChannel.securityInfo
- .QueryInterface(Ci.nsITransportSecurityInfo)
- .QueryInterface(Ci.nsISerializable);
- let serializedSecurityInfo = serhelper.serializeToString(serializable);
- return {
- divDisplay: content.getComputedStyle(div).display,
- text: text.textContent,
- securityInfoAsString: serializedSecurityInfo
- };
- });
- isnot(message.divDisplay, "none", "Debug information is visible");
- ok(message.text.includes(BAD_CERT), "Correct URL found");
- ok(message.text.includes("Certificate has expired"),
- "Correct error message found");
- ok(message.text.includes("HTTP Strict Transport Security: false"),
- "Correct HSTS value found");
- ok(message.text.includes("HTTP Public Key Pinning: false"),
- "Correct HPKP value found");
- let certChain = getCertChain(message.securityInfoAsString);
- ok(message.text.includes(certChain), "Found certificate chain");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_task(function* checkAdvancedDetailsForHSTS() {
- info("Loading a bad STS cert page and verifying the advanced details section");
- let browser;
- let certErrorLoaded;
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = gBrowser.addTab(BAD_STS_CERT);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = waitForCertErrorLoad(browser);
- }, false);
-
- info("Loading and waiting for the cert error");
- yield certErrorLoaded;
-
- let message = yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let advancedButton = doc.getElementById("advancedButton");
- advancedButton.click();
- let ec = doc.getElementById("errorCode");
- let cdl = doc.getElementById("cert_domain_link");
- return {
- ecTextContent: ec.textContent,
- ecTagName: ec.tagName,
- cdlTextContent: cdl.textContent,
- cdlTagName: cdl.tagName
- };
- });
-
- const badStsUri = Services.io.newURI(BAD_STS_CERT, null, null);
- is(message.ecTextContent, "SSL_ERROR_BAD_CERT_DOMAIN",
- "Correct error message found");
- is(message.ecTagName, "a", "Error message is a link");
- const url = badStsUri.prePath.slice(badStsUri.prePath.indexOf(".") + 1);
- is(message.cdlTextContent, url,
- "Correct cert_domain_link contents found");
- is(message.cdlTagName, "a", "cert_domain_link is a link");
-
- message = yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let errorCode = doc.getElementById("errorCode");
- errorCode.click();
- let div = doc.getElementById("certificateErrorDebugInformation");
- let text = doc.getElementById("certificateErrorText");
-
- let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
- .getService(Ci.nsISerializationHelper);
- let serializable = docShell.failedChannel.securityInfo
- .QueryInterface(Ci.nsITransportSecurityInfo)
- .QueryInterface(Ci.nsISerializable);
- let serializedSecurityInfo = serhelper.serializeToString(serializable);
- return {
- divDisplay: content.getComputedStyle(div).display,
- text: text.textContent,
- securityInfoAsString: serializedSecurityInfo
- };
- });
- isnot(message.divDisplay, "none", "Debug information is visible");
- ok(message.text.includes(badStsUri.spec), "Correct URL found");
- ok(message.text.includes("requested domain name does not match the server\u2019s certificate"),
- "Correct error message found");
- ok(message.text.includes("HTTP Strict Transport Security: false"),
- "Correct HSTS value found");
- ok(message.text.includes("HTTP Public Key Pinning: true"),
- "Correct HPKP value found");
- let certChain = getCertChain(message.securityInfoAsString);
- ok(message.text.includes(certChain), "Found certificate chain");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_task(function* checkUnknownIssuerLearnMoreLink() {
- info("Loading a cert error for self-signed pages and checking the correct link is shown");
- let browser;
- let certErrorLoaded;
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = gBrowser.addTab(UNKNOWN_ISSUER);
- browser = gBrowser.selectedBrowser;
- certErrorLoaded = waitForCertErrorLoad(browser);
- }, false);
-
- info("Loading and waiting for the cert error");
- yield certErrorLoaded;
-
- let href = yield ContentTask.spawn(browser, null, function* () {
- let learnMoreLink = content.document.getElementById("learnMoreLink");
- return learnMoreLink.href;
- });
- ok(href.endsWith("security-error"), "security-error in the Learn More URL");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-function waitForCertErrorLoad(browser) {
- return new Promise(resolve => {
- info("Waiting for DOMContentLoaded event");
- browser.addEventListener("DOMContentLoaded", function load() {
- browser.removeEventListener("DOMContentLoaded", load, false, true);
- resolve();
- }, false, true);
- });
-}
-
-function getCertChain(securityInfoAsString) {
- let certChain = "";
- const serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
- .getService(Ci.nsISerializationHelper);
- let securityInfo = serhelper.deserializeObject(securityInfoAsString);
- securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
- let certs = securityInfo.failedCertChain.getEnumerator();
- while (certs.hasMoreElements()) {
- let cert = certs.getNext();
- cert.QueryInterface(Ci.nsIX509Cert);
- certChain += getPEMString(cert);
- }
- return certChain;
-}
-
-function getDERString(cert)
-{
- var length = {};
- var derArray = cert.getRawDER(length);
- var derString = '';
- for (var i = 0; i < derArray.length; i++) {
- derString += String.fromCharCode(derArray[i]);
- }
- return derString;
-}
-
-function getPEMString(cert)
-{
- var derb64 = btoa(getDERString(cert));
- // Wrap the Base64 string into lines of 64 characters,
- // with CRLF line breaks (as specified in RFC 1421).
- var wrapped = derb64.replace(/(\S{64}(?!$))/g, "$1\r\n");
- return "-----BEGIN CERTIFICATE-----\r\n"
- + wrapped
- + "\r\n-----END CERTIFICATE-----\r\n";
-}
diff --git a/browser/base/content/test/general/browser_aboutHealthReport.js b/browser/base/content/test/general/browser_aboutHealthReport.js
deleted file mode 100644
index 0be184fb8..000000000
--- a/browser/base/content/test/general/browser_aboutHealthReport.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-
-const CHROME_BASE = "chrome://mochitests/content/browser/browser/base/content/test/general/";
-const HTTPS_BASE = "https://example.com/browser/browser/base/content/test/general/";
-
-const TELEMETRY_LOG_PREF = "toolkit.telemetry.log.level";
-const telemetryOriginalLogPref = Preferences.get(TELEMETRY_LOG_PREF, null);
-
-const originalReportUrl = Services.prefs.getCharPref("datareporting.healthreport.about.reportUrl");
-
-registerCleanupFunction(function() {
- // Ensure we don't pollute prefs for next tests.
- if (telemetryOriginalLogPref) {
- Preferences.set(TELEMETRY_LOG_PREF, telemetryOriginalLogPref);
- } else {
- Preferences.reset(TELEMETRY_LOG_PREF);
- }
-
- try {
- Services.prefs.setCharPref("datareporting.healthreport.about.reportUrl", originalReportUrl);
- Services.prefs.setBoolPref("datareporting.healthreport.uploadEnabled", true);
- } catch (ex) {}
-});
-
-function fakeTelemetryNow(...args) {
- let date = new Date(...args);
- let scope = {};
- const modules = [
- Cu.import("resource://gre/modules/TelemetrySession.jsm", scope),
- Cu.import("resource://gre/modules/TelemetryEnvironment.jsm", scope),
- Cu.import("resource://gre/modules/TelemetryController.jsm", scope),
- ];
-
- for (let m of modules) {
- m.Policy.now = () => new Date(date);
- }
-
- return date;
-}
-
-function* setupPingArchive() {
- let scope = {};
- Cu.import("resource://gre/modules/TelemetryController.jsm", scope);
- Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript(CHROME_BASE + "healthreport_pingData.js", scope);
-
- for (let p of scope.TEST_PINGS) {
- fakeTelemetryNow(p.date);
- p.id = yield scope.TelemetryController.submitExternalPing(p.type, p.payload);
- }
-}
-
-var gTests = [
-
-{
- desc: "Test the remote commands",
- setup: Task.async(function*()
- {
- Preferences.set(TELEMETRY_LOG_PREF, "Trace");
- yield setupPingArchive();
- Preferences.set("datareporting.healthreport.about.reportUrl",
- HTTPS_BASE + "healthreport_testRemoteCommands.html");
- }),
- run: function (iframe)
- {
- let deferred = Promise.defer();
- let results = 0;
- try {
- iframe.contentWindow.addEventListener("FirefoxHealthReportTestResponse", function evtHandler(event) {
- let data = event.detail.data;
- if (data.type == "testResult") {
- ok(data.pass, data.info);
- results++;
- }
- else if (data.type == "testsComplete") {
- is(results, data.count, "Checking number of results received matches the number of tests that should have run");
- iframe.contentWindow.removeEventListener("FirefoxHealthReportTestResponse", evtHandler, true);
- deferred.resolve();
- }
- }, true);
-
- } catch (e) {
- ok(false, "Failed to get all commands");
- deferred.reject();
- }
- return deferred.promise;
- }
-},
-
-]; // gTests
-
-function test()
-{
- waitForExplicitFinish();
-
- // xxxmpc leaving this here until we resolve bug 854038 and bug 854060
- requestLongerTimeout(10);
-
- Task.spawn(function* () {
- for (let testCase of gTests) {
- info(testCase.desc);
- yield testCase.setup();
-
- let iframe = yield promiseNewTabLoadEvent("about:healthreport");
-
- yield testCase.run(iframe);
-
- gBrowser.removeCurrentTab();
- }
-
- finish();
- });
-}
-
-function promiseNewTabLoadEvent(aUrl, aEventType="load")
-{
- let deferred = Promise.defer();
- let tab = gBrowser.selectedTab = gBrowser.addTab(aUrl);
- tab.linkedBrowser.addEventListener(aEventType, function load(event) {
- tab.linkedBrowser.removeEventListener(aEventType, load, true);
- let iframe = tab.linkedBrowser.contentDocument.getElementById("remote-report");
- iframe.addEventListener("load", function frameLoad(e) {
- if (iframe.contentWindow.location.href == "about:blank" ||
- e.target != iframe) {
- return;
- }
- iframe.removeEventListener("load", frameLoad, false);
- deferred.resolve(iframe);
- }, false);
- }, true);
- return deferred.promise;
-}
diff --git a/browser/base/content/test/general/browser_aboutHome.js b/browser/base/content/test/general/browser_aboutHome.js
deleted file mode 100644
index f0e19e852..000000000
--- a/browser/base/content/test/general/browser_aboutHome.js
+++ /dev/null
@@ -1,668 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// This test needs to be split up. See bug 1258717.
-requestLongerTimeout(4);
-ignoreAllUncaughtExceptions();
-
-XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
- "resource:///modules/AboutHome.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
- "resource://gre/modules/AppConstants.jsm");
-
-const TEST_CONTENT_HELPER = "chrome://mochitests/content/browser/browser/base/" +
- "content/test/general/aboutHome_content_script.js";
-var gRightsVersion = Services.prefs.getIntPref("browser.rights.version");
-
-registerCleanupFunction(function() {
- // Ensure we don't pollute prefs for next tests.
- Services.prefs.clearUserPref("network.cookies.cookieBehavior");
- Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
- Services.prefs.clearUserPref("browser.rights.override");
- Services.prefs.clearUserPref("browser.rights." + gRightsVersion + ".shown");
-});
-
-add_task(function* () {
- info("Check that clearing cookies does not clear storage");
-
- yield withSnippetsMap(
- () => {
- Cc["@mozilla.org/observer-service;1"]
- .getService(Ci.nsIObserverService)
- .notifyObservers(null, "cookie-changed", "cleared");
- },
- function* () {
- isnot(content.gSnippetsMap.get("snippets-last-update"), null,
- "snippets-last-update should have a value");
- });
-});
-
-add_task(function* () {
- info("Check default snippets are shown");
-
- yield withSnippetsMap(null, function* () {
- let doc = content.document;
- let snippetsElt = doc.getElementById("snippets");
- ok(snippetsElt, "Found snippets element")
- is(snippetsElt.getElementsByTagName("span").length, 1,
- "A default snippet is present.");
- });
-});
-
-add_task(function* () {
- info("Check default snippets are shown if snippets are invalid xml");
-
- yield withSnippetsMap(
- // This must set some incorrect xhtml code.
- snippetsMap => snippetsMap.set("snippets", "<p><b></p></b>"),
- function* () {
- let doc = content.document;
- let snippetsElt = doc.getElementById("snippets");
- ok(snippetsElt, "Found snippets element");
- is(snippetsElt.getElementsByTagName("span").length, 1,
- "A default snippet is present.");
-
- content.gSnippetsMap.delete("snippets");
- });
-});
-
-add_task(function* () {
- info("Check that performing a search fires a search event and records to Telemetry.");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- let currEngine = Services.search.currentEngine;
- let engine = yield promiseNewEngine("searchSuggestionEngine.xml");
- // Make this actually work in healthreport by giving it an ID:
- Object.defineProperty(engine.wrappedJSObject, "identifier",
- { value: "org.mozilla.testsearchsuggestions" });
-
- let p = promiseContentSearchChange(browser, engine.name);
- Services.search.currentEngine = engine;
- yield p;
-
- yield ContentTask.spawn(browser, { expectedName: engine.name }, function* (args) {
- let engineName = content.wrappedJSObject.gContentSearchController.defaultEngine.name;
- is(engineName, args.expectedName, "Engine name in DOM should match engine we just added");
- });
-
- let numSearchesBefore = 0;
- // Get the current number of recorded searches.
- let histogramKey = engine.identifier + ".abouthome";
- try {
- let hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
- if (histogramKey in hs) {
- numSearchesBefore = hs[histogramKey].sum;
- }
- } catch (ex) {
- // No searches performed yet, not a problem, |numSearchesBefore| is 0.
- }
-
- let searchStr = "a search";
-
- let expectedURL = Services.search.currentEngine
- .getSubmission(searchStr, null, "homepage").uri.spec;
- let promise = waitForDocLoadAndStopIt(expectedURL, browser);
-
- // Perform a search to increase the SEARCH_COUNT histogram.
- yield ContentTask.spawn(browser, { searchStr }, function* (args) {
- let doc = content.document;
- info("Perform a search.");
- doc.getElementById("searchText").value = args.searchStr;
- doc.getElementById("searchSubmit").click();
- });
-
- yield promise;
-
- // Make sure the SEARCH_COUNTS histogram has the right key and count.
- let hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
- Assert.ok(histogramKey in hs, "histogram with key should be recorded");
- Assert.equal(hs[histogramKey].sum, numSearchesBefore + 1,
- "histogram sum should be incremented");
-
- Services.search.currentEngine = currEngine;
- try {
- Services.search.removeEngine(engine);
- } catch (ex) {}
- });
-});
-
-add_task(function* () {
- info("Check snippets map is cleared if cached version is old");
-
- yield withSnippetsMap(
- snippetsMap => {
- snippetsMap.set("snippets", "test");
- snippetsMap.set("snippets-cached-version", 0);
- },
- function* () {
- let snippetsMap = content.gSnippetsMap;
- ok(!snippetsMap.has("snippets"), "snippets have been properly cleared");
- ok(!snippetsMap.has("snippets-cached-version"),
- "cached-version has been properly cleared");
- });
-});
-
-add_task(function* () {
- info("Check cached snippets are shown if cached version is current");
-
- yield withSnippetsMap(
- snippetsMap => snippetsMap.set("snippets", "test"),
- function* (args) {
- let doc = content.document;
- let snippetsMap = content.gSnippetsMap
-
- let snippetsElt = doc.getElementById("snippets");
- ok(snippetsElt, "Found snippets element");
- is(snippetsElt.innerHTML, "test", "Cached snippet is present.");
-
- is(snippetsMap.get("snippets"), "test", "snippets still cached");
- is(snippetsMap.get("snippets-cached-version"),
- args.expectedVersion,
- "cached-version is correct");
- ok(snippetsMap.has("snippets-last-update"), "last-update still exists");
- }, { expectedVersion: AboutHomeUtils.snippetsVersion });
-});
-
-add_task(function* () {
- info("Check if the 'Know Your Rights' default snippet is shown when " +
- "'browser.rights.override' pref is set and that its link works");
-
- Services.prefs.setBoolPref("browser.rights.override", false);
-
- ok(AboutHomeUtils.showKnowYourRights, "AboutHomeUtils.showKnowYourRights should be TRUE");
-
- yield withSnippetsMap(null, function* () {
- let doc = content.document;
- let snippetsElt = doc.getElementById("snippets");
- ok(snippetsElt, "Found snippets element");
- let linkEl = snippetsElt.querySelector("a");
- is(linkEl.href, "about:rights", "Snippet link is present.");
- }, null, function* () {
- let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, "about:rights");
- yield BrowserTestUtils.synthesizeMouseAtCenter("a[href='about:rights']", {
- button: 0
- }, gBrowser.selectedBrowser);
- yield loadPromise;
- is(gBrowser.currentURI.spec, "about:rights", "about:rights should have opened.");
- });
-
-
- Services.prefs.clearUserPref("browser.rights.override");
-});
-
-add_task(function* () {
- info("Check if the 'Know Your Rights' default snippet is NOT shown when " +
- "'browser.rights.override' pref is NOT set");
-
- Services.prefs.setBoolPref("browser.rights.override", true);
-
- let rightsData = AboutHomeUtils.knowYourRightsData;
- ok(!rightsData, "AboutHomeUtils.knowYourRightsData should be FALSE");
-
- yield withSnippetsMap(null, function*() {
- let doc = content.document;
- let snippetsElt = doc.getElementById("snippets");
- ok(snippetsElt, "Found snippets element");
- ok(snippetsElt.getElementsByTagName("a")[0].href != "about:rights",
- "Snippet link should not point to about:rights.");
- });
-
- Services.prefs.clearUserPref("browser.rights.override");
-});
-
-add_task(function* () {
- info("Check POST search engine support");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- return new Promise(resolve => {
- let searchObserver = Task.async(function* search_observer(subject, topic, data) {
- let currEngine = Services.search.defaultEngine;
- let engine = subject.QueryInterface(Ci.nsISearchEngine);
- info("Observer: " + data + " for " + engine.name);
-
- if (data != "engine-added")
- return;
-
- if (engine.name != "POST Search")
- return;
-
- Services.obs.removeObserver(searchObserver, "browser-search-engine-modified");
-
- // Ready to execute the tests!
- let needle = "Search for something awesome.";
-
- let p = promiseContentSearchChange(browser, engine.name);
- Services.search.defaultEngine = engine;
- yield p;
-
- let promise = BrowserTestUtils.browserLoaded(browser);
-
- yield ContentTask.spawn(browser, { needle }, function* (args) {
- let doc = content.document;
- doc.getElementById("searchText").value = args.needle;
- doc.getElementById("searchSubmit").click();
- });
-
- yield promise;
-
- // When the search results load, check them for correctness.
- yield ContentTask.spawn(browser, { needle }, function* (args) {
- let loadedText = content.document.body.textContent;
- ok(loadedText, "search page loaded");
- is(loadedText, "searchterms=" + escape(args.needle.replace(/\s/g, "+")),
- "Search text should arrive correctly");
- });
-
- Services.search.defaultEngine = currEngine;
- try {
- Services.search.removeEngine(engine);
- } catch (ex) {}
- resolve();
- });
- Services.obs.addObserver(searchObserver, "browser-search-engine-modified", false);
- Services.search.addEngine("http://test:80/browser/browser/base/content/test/general/POSTSearchEngine.xml",
- null, null, false);
- });
- });
-});
-
-add_task(function* () {
- info("Make sure that a page can't imitate about:home");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- let promise = BrowserTestUtils.browserLoaded(browser);
- browser.loadURI("https://example.com/browser/browser/base/content/test/general/test_bug959531.html");
- yield promise;
-
- yield ContentTask.spawn(browser, null, function* () {
- let button = content.document.getElementById("settings");
- ok(button, "Found settings button in test page");
- button.click();
- });
-
- yield new Promise(resolve => {
- // It may take a few turns of the event loop before the window
- // is displayed, so we wait.
- function check(n) {
- let win = Services.wm.getMostRecentWindow("Browser:Preferences");
- ok(!win, "Preferences window not showing");
- if (win) {
- win.close();
- }
-
- if (n > 0) {
- executeSoon(() => check(n-1));
- } else {
- resolve();
- }
- }
-
- check(5);
- });
- });
-});
-
-add_task(function* () {
- // See browser_contentSearchUI.js for comprehensive content search UI tests.
- info("Search suggestion smoke test");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- // Add a test engine that provides suggestions and switch to it.
- let currEngine = Services.search.currentEngine;
- let engine = yield promiseNewEngine("searchSuggestionEngine.xml");
- let p = promiseContentSearchChange(browser, engine.name);
- Services.search.currentEngine = engine;
- yield p;
-
- yield ContentTask.spawn(browser, null, function* () {
- // Avoid intermittent failures.
- content.wrappedJSObject.gContentSearchController.remoteTimeout = 5000;
-
- // Type an X in the search input.
- let input = content.document.getElementById("searchText");
- input.focus();
- });
-
- yield BrowserTestUtils.synthesizeKey("x", {}, browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- // Wait for the search suggestions to become visible.
- let table = content.document.getElementById("searchSuggestionTable");
- let input = content.document.getElementById("searchText");
-
- yield new Promise(resolve => {
- let observer = new content.MutationObserver(() => {
- if (input.getAttribute("aria-expanded") == "true") {
- observer.disconnect();
- ok(!table.hidden, "Search suggestion table unhidden");
- resolve();
- }
- });
- observer.observe(input, {
- attributes: true,
- attributeFilter: ["aria-expanded"],
- });
- });
- });
-
- // Empty the search input, causing the suggestions to be hidden.
- yield BrowserTestUtils.synthesizeKey("a", { accelKey: true }, browser);
- yield BrowserTestUtils.synthesizeKey("VK_DELETE", {}, browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- let table = content.document.getElementById("searchSuggestionTable");
- yield ContentTaskUtils.waitForCondition(() => table.hidden,
- "Search suggestion table hidden");
- });
-
- Services.search.currentEngine = currEngine;
- try {
- Services.search.removeEngine(engine);
- } catch (ex) { }
- });
-});
-
-add_task(function* () {
- info("Clicking suggestion list while composing");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- // Add a test engine that provides suggestions and switch to it.
- let currEngine = Services.search.currentEngine;
- let engine = yield promiseNewEngine("searchSuggestionEngine.xml");
- let p = promiseContentSearchChange(browser, engine.name);
- Services.search.currentEngine = engine;
- yield p;
-
- yield ContentTask.spawn(browser, null, function* () {
- // Start composition and type "x"
- let input = content.document.getElementById("searchText");
- input.focus();
- });
-
- yield BrowserTestUtils.synthesizeComposition({
- type: "compositionstart",
- data: ""
- }, browser);
- yield BrowserTestUtils.synthesizeCompositionChange({
- composition: {
- string: "x",
- clauses: [
- { length: 1, attr: Ci.nsITextInputProcessor.ATTR_RAW_CLAUSE }
- ]
- },
- caret: { start: 1, length: 0 }
- }, browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- let searchController = content.wrappedJSObject.gContentSearchController;
-
- // Wait for the search suggestions to become visible.
- let table = searchController._suggestionsList;
- let input = content.document.getElementById("searchText");
-
- yield new Promise(resolve => {
- let observer = new content.MutationObserver(() => {
- if (input.getAttribute("aria-expanded") == "true") {
- observer.disconnect();
- ok(!table.hidden, "Search suggestion table unhidden");
- resolve();
- }
- });
- observer.observe(input, {
- attributes: true,
- attributeFilter: ["aria-expanded"],
- });
- });
-
- let row = table.children[1];
- row.setAttribute("id", "TEMPID");
-
- // ContentSearchUIController looks at the current selectedIndex when
- // performing a search. Synthesizing the mouse event on the suggestion
- // doesn't actually mouseover the suggestion and trigger it to be flagged
- // as selected, so we manually select it first.
- searchController.selectedIndex = 1;
- });
-
- // Click the second suggestion.
- let expectedURL = Services.search.currentEngine
- .getSubmission("xbar", null, "homepage").uri.spec;
- let loadPromise = waitForDocLoadAndStopIt(expectedURL);
- yield BrowserTestUtils.synthesizeMouseAtCenter("#TEMPID", {
- button: 0
- }, browser);
- yield loadPromise;
-
- yield ContentTask.spawn(browser, null, function* () {
- let input = content.document.getElementById("searchText");
- ok(input.value == "x", "Input value did not change");
-
- let row = content.document.getElementById("TEMPID");
- if (row) {
- row.removeAttribute("id");
- }
- });
-
- Services.search.currentEngine = currEngine;
- try {
- Services.search.removeEngine(engine);
- } catch (ex) { }
- });
-});
-
-add_task(function* () {
- info("Pressing any key should focus the search box in the page, and send the key to it");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- yield BrowserTestUtils.synthesizeMouseAtCenter("#brandLogo", {}, browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- isnot(doc.getElementById("searchText"), doc.activeElement,
- "Search input should not be the active element.");
- });
-
- yield BrowserTestUtils.synthesizeKey("a", {}, browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- let doc = content.document;
- let searchInput = doc.getElementById("searchText");
- yield ContentTaskUtils.waitForCondition(() => doc.activeElement === searchInput,
- "Search input should be the active element.");
- is(searchInput.value, "a", "Search input should be 'a'.");
- });
- });
-});
-
-add_task(function* () {
- info("Cmd+k should focus the search box in the toolbar when it's present");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- yield BrowserTestUtils.synthesizeMouseAtCenter("#brandLogo", {}, browser);
-
- let doc = window.document;
- let searchInput = doc.getElementById("searchbar").textbox.inputField;
- isnot(searchInput, doc.activeElement, "Search bar should not be the active element.");
-
- EventUtils.synthesizeKey("k", { accelKey: true });
- yield promiseWaitForCondition(() => doc.activeElement === searchInput);
- is(searchInput, doc.activeElement, "Search bar should be the active element.");
- });
-});
-
-add_task(function* () {
- info("Sync button should open about:preferences#sync");
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- let oldOpenPrefs = window.openPreferences;
- let openPrefsPromise = new Promise(resolve => {
- window.openPreferences = function (pane, params) {
- resolve({ pane: pane, params: params });
- };
- });
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#sync", {}, browser);
-
- let result = yield openPrefsPromise;
- window.openPreferences = oldOpenPrefs;
-
- is(result.pane, "paneSync", "openPreferences should be called with paneSync");
- is(result.params.urlParams.entrypoint, "abouthome",
- "openPreferences should be called with abouthome entrypoint");
- });
-});
-
-add_task(function* () {
- info("Pressing Space while the Addons button is focused should activate it");
-
- // Skip this test on Mac, because Space doesn't activate the button there.
- if (AppConstants.platform == "macosx") {
- return;
- }
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:home" }, function* (browser) {
- info("Waiting for about:addons tab to open...");
- let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
-
- yield ContentTask.spawn(browser, null, function* () {
- let addOnsButton = content.document.getElementById("addons");
- addOnsButton.focus();
- });
- yield BrowserTestUtils.synthesizeKey(" ", {}, browser);
-
- let tab = yield promiseTabOpened;
- is(tab.linkedBrowser.currentURI.spec, "about:addons",
- "Should have seen the about:addons tab");
- yield BrowserTestUtils.removeTab(tab);
- });
-});
-
-/**
- * Cleans up snippets and ensures that by default we don't try to check for
- * remote snippets since that may cause network bustage or slowness.
- *
- * @param aSetupFn
- * The setup function to be run.
- * @param testFn
- * the content task to run
- * @param testArgs (optional)
- * the parameters to pass to the content task
- * @param parentFn (optional)
- * the function to run in the parent after the content task has completed.
- * @return {Promise} resolved when the snippets are ready. Gets the snippets map.
- */
-function* withSnippetsMap(setupFn, testFn, testArgs = null, parentFn = null) {
- let setupFnSource;
- if (setupFn) {
- setupFnSource = setupFn.toSource();
- }
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
- let promiseAfterLocationChange = () => {
- 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);
-
- let updateSnippets;
- if (args.setupFnSource) {
- updateSnippets = eval(`(() => (${args.setupFnSource}))()`);
- }
-
- content.wrappedJSObject.ensureSnippetsMapThen(snippetsMap => {
- snippetsMap = Cu.waiveXrays(snippetsMap);
- info("Got snippets map: " +
- "{ last-update: " + snippetsMap.get("snippets-last-update") +
- ", cached-version: " + snippetsMap.get("snippets-cached-version") +
- " }");
- // Don't try to update.
- snippetsMap.set("snippets-last-update", Date.now());
- snippetsMap.set("snippets-cached-version", args.version);
- // Clear snippets.
- snippetsMap.delete("snippets");
-
- if (updateSnippets) {
- updateSnippets(snippetsMap);
- }
-
- // Tack it to the global object
- content.gSnippetsMap = snippetsMap;
-
- resolve();
- });
- });
- });
- });
- };
-
- // 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 = {
- onLocationChange() {
- gBrowser.removeProgressListener(wpl);
- // Phase 2: retrieving the snippets map is the next promise on our agenda.
- promiseAfterLocationChange().then(resolve);
- },
- onProgressChange() {},
- onStatusChange() {},
- onSecurityChange() {}
- };
- gBrowser.addProgressListener(wpl);
- });
-
- // Set the URL to 'about:home' here to allow capturing the 'AboutHomeLoadSnippets'
- // event.
- browser.loadURI("about:home");
- // Wait for LocationChange.
- yield promise;
-
- yield ContentTask.spawn(browser, testArgs, testFn);
- if (parentFn) {
- yield parentFn();
- }
- });
-}
-
-function promiseContentSearchChange(browser, newEngineName) {
- return ContentTask.spawn(browser, { newEngineName }, function* (args) {
- return new Promise(resolve => {
- content.addEventListener("ContentSearchService", function listener(aEvent) {
- if (aEvent.detail.type == "CurrentState" &&
- content.wrappedJSObject.gContentSearchController.defaultEngine.name == args.newEngineName) {
- content.removeEventListener("ContentSearchService", listener);
- resolve();
- }
- });
- });
- });
-}
-
-function promiseNewEngine(basename) {
- info("Waiting for engine to be added: " + basename);
- return new Promise((resolve, reject) => {
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- registerCleanupFunction(() => {
- try {
- Services.search.removeEngine(engine);
- } catch (ex) { /* Can't remove the engine more than once */ }
- });
- resolve(engine);
- },
- onError: function (errCode) {
- ok(false, "addEngine failed with error code " + errCode);
- reject();
- },
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_aboutHome_wrapsCorrectly.js b/browser/base/content/test/general/browser_aboutHome_wrapsCorrectly.js
deleted file mode 100644
index bfe0fe9c8..000000000
--- a/browser/base/content/test/general/browser_aboutHome_wrapsCorrectly.js
+++ /dev/null
@@ -1,28 +0,0 @@
-add_task(function* () {
- let newWindow = yield BrowserTestUtils.openNewBrowserWindow();
-
- let resizedPromise = BrowserTestUtils.waitForEvent(newWindow, "resize");
- newWindow.resizeTo(300, 300);
- yield resizedPromise;
-
- yield BrowserTestUtils.openNewForegroundTab(newWindow.gBrowser, "about:home");
-
- yield ContentTask.spawn(newWindow.gBrowser.selectedBrowser, {}, function* () {
- Assert.equal(content.document.body.getAttribute("narrow"), "true", "narrow mode");
- });
-
- resizedPromise = BrowserTestUtils.waitForContentEvent(newWindow.gBrowser.selectedBrowser, "resize");
-
-
- yield ContentTask.spawn(newWindow.gBrowser.selectedBrowser, {}, function* () {
- content.window.resizeTo(800, 800);
- });
-
- yield resizedPromise;
-
- yield ContentTask.spawn(newWindow.gBrowser.selectedBrowser, {}, function* () {
- Assert.equal(content.document.body.hasAttribute("narrow"), false, "non-narrow mode");
- });
-
- yield BrowserTestUtils.closeWindow(newWindow);
-});
diff --git a/browser/base/content/test/general/browser_aboutNetError.js b/browser/base/content/test/general/browser_aboutNetError.js
deleted file mode 100644
index 5185cbcaa..000000000
--- a/browser/base/content/test/general/browser_aboutNetError.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Set ourselves up for TLS error
-Services.prefs.setIntPref("security.tls.version.max", 3);
-Services.prefs.setIntPref("security.tls.version.min", 3);
-
-const LOW_TLS_VERSION = "https://tls1.example.com/";
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-
-add_task(function* checkReturnToPreviousPage() {
- info("Loading a TLS page that isn't supported, ensure we have a fix button and clicking it then loads the page");
- let browser;
- let pageLoaded;
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- gBrowser.selectedTab = gBrowser.addTab(LOW_TLS_VERSION);
- browser = gBrowser.selectedBrowser;
- pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
- }, false);
-
- info("Loading and waiting for the net error");
- yield pageLoaded;
-
- // NB: This code assumes that the error page and the test page load in the
- // same process. If this test starts to fail, it could be because they load
- // in different processes.
- yield ContentTask.spawn(browser, LOW_TLS_VERSION, function* (LOW_TLS_VERSION_) {
- ok(content.document.getElementById("prefResetButton").getBoundingClientRect().left >= 0,
- "Should have a visible button");
-
- ok(content.document.documentURI.startsWith("about:neterror"), "Should be showing error page");
-
- let doc = content.document;
- let prefResetButton = doc.getElementById("prefResetButton");
- is(prefResetButton.getAttribute("autofocus"), "true", "prefResetButton has autofocus");
- prefResetButton.click();
-
- yield ContentTaskUtils.waitForEvent(this, "pageshow", true);
-
- is(content.document.documentURI, LOW_TLS_VERSION_, "Should not be showing page");
- });
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/general/browser_aboutSupport_newtab_security_state.js b/browser/base/content/test/general/browser_aboutSupport_newtab_security_state.js
deleted file mode 100644
index e574ba978..000000000
--- a/browser/base/content/test/general/browser_aboutSupport_newtab_security_state.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: window.location is null");
-
-
-add_task(function* checkIdentityOfAboutSupport() {
- let tab = gBrowser.loadOneTab("about:support", {
- referrerURI: null,
- inBackground: false,
- allowThirdPartyFixup: false,
- relatedToCurrent: false,
- skipAnimation: true,
- allowMixedContent: false
- });
-
- yield promiseTabLoaded(tab);
- let identityBox = document.getElementById("identity-box");
- is(identityBox.className, "chromeUI", "Should know that we're chrome.");
- gBrowser.removeTab(tab);
-});
-
diff --git a/browser/base/content/test/general/browser_accesskeys.js b/browser/base/content/test/general/browser_accesskeys.js
deleted file mode 100644
index 56fe3995f..000000000
--- a/browser/base/content/test/general/browser_accesskeys.js
+++ /dev/null
@@ -1,82 +0,0 @@
-add_task(function *() {
- yield pushPrefs(["ui.key.contentAccess", 5], ["ui.key.chromeAccess", 5]);
-
- const gPageURL1 = "data:text/html,<body><p>" +
- "<button id='button' accesskey='y'>Button</button>" +
- "<input id='checkbox' type='checkbox' accesskey='z'>Checkbox" +
- "</p></body>";
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gPageURL1);
- tab1.linkedBrowser.messageManager.loadFrameScript("data:,(" + childHandleFocus.toString() + ")();", false);
-
- Services.focus.clearFocus(window);
-
- // Press an accesskey in the child document while the chrome is focused.
- let focusedId = yield performAccessKey("y");
- is(focusedId, "button", "button accesskey");
-
- // Press an accesskey in the child document while the content document is focused.
- focusedId = yield performAccessKey("z");
- is(focusedId, "checkbox", "checkbox accesskey");
-
- // Add an element with an accesskey to the chrome and press its accesskey while the chrome is focused.
- let newButton = document.createElement("button");
- newButton.id = "chromebutton";
- newButton.setAttribute("accesskey", "z");
- document.documentElement.appendChild(newButton);
-
- Services.focus.clearFocus(window);
-
- focusedId = yield performAccessKeyForChrome("z");
- is(focusedId, "chromebutton", "chromebutton accesskey");
-
- // Add a second tab and ensure that accesskey from the first tab is not used.
- const gPageURL2 = "data:text/html,<body>" +
- "<button id='tab2button' accesskey='y'>Button in Tab 2</button>" +
- "</body>";
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gPageURL2);
- tab2.linkedBrowser.messageManager.loadFrameScript("data:,(" + childHandleFocus.toString() + ")();", false);
-
- Services.focus.clearFocus(window);
-
- focusedId = yield performAccessKey("y");
- is(focusedId, "tab2button", "button accesskey in tab2");
-
- // Press the accesskey for the chrome element while the content document is focused.
- focusedId = yield performAccessKeyForChrome("z");
- is(focusedId, "chromebutton", "chromebutton accesskey");
-
- newButton.parentNode.removeChild(newButton);
-
- gBrowser.removeTab(tab1);
- gBrowser.removeTab(tab2);
-});
-
-function childHandleFocus() {
- content.document.body.firstChild.addEventListener("focus", function focused(event) {
- let focusedElement = content.document.activeElement;
- focusedElement.blur();
- sendAsyncMessage("Test:FocusFromAccessKey", { focus: focusedElement.id })
- }, true);
-}
-
-function performAccessKey(key)
-{
- return new Promise(resolve => {
- let mm = gBrowser.selectedBrowser.messageManager;
- mm.addMessageListener("Test:FocusFromAccessKey", function listenForFocus(msg) {
- mm.removeMessageListener("Test:FocusFromAccessKey", listenForFocus);
- resolve(msg.data.focus);
- });
-
- EventUtils.synthesizeKey(key, { altKey: true, shiftKey: true });
- });
-}
-
-// This version is used when a chrome elemnt is expected to be found for an accesskey.
-function* performAccessKeyForChrome(key, inChild)
-{
- let waitFocusChangePromise = BrowserTestUtils.waitForEvent(document, "focus", true);
- EventUtils.synthesizeKey(key, { altKey: true, shiftKey: true });
- yield waitFocusChangePromise;
- return document.activeElement.id;
-}
diff --git a/browser/base/content/test/general/browser_addCertException.js b/browser/base/content/test/general/browser_addCertException.js
deleted file mode 100644
index e2cf34b47..000000000
--- a/browser/base/content/test/general/browser_addCertException.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test adding a certificate exception by attempting to browse to a site with
-// a bad certificate, being redirected to the internal about:certerror page,
-// using the button contained therein to load the certificate exception
-// dialog, using that to add an exception, and finally successfully visiting
-// the site, including showing the right identity box and control center icons.
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- yield loadBadCertPage("https://expired.example.com");
- checkControlPanelIcons();
- let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
- .getService(Ci.nsICertOverrideService);
- certOverrideService.clearValidityOverride("expired.example.com", -1);
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// Check for the correct icons in the identity box and control center.
-function checkControlPanelIcons() {
- let { gIdentityHandler } = gBrowser.ownerGlobal;
- gIdentityHandler._identityBox.click();
- document.getElementById("identity-popup-security-expander").click();
-
- is_element_visible(document.getElementById("connection-icon"), "Should see connection icon");
- let connectionIconImage = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("connection-icon"), "")
- .getPropertyValue("list-style-image");
- let securityViewBG = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("identity-popup-securityView"), "")
- .getPropertyValue("background-image");
- let securityContentBG = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("identity-popup-security-content"), "")
- .getPropertyValue("background-image");
- is(connectionIconImage,
- "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
- "Using expected icon image in the identity block");
- is(securityViewBG,
- "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
- "Using expected icon image in the Control Center main view");
- is(securityContentBG,
- "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
- "Using expected icon image in the Control Center subview");
-
- gIdentityHandler._identityPopup.hidden = true;
-}
-
diff --git a/browser/base/content/test/general/browser_addKeywordSearch.js b/browser/base/content/test/general/browser_addKeywordSearch.js
deleted file mode 100644
index f38050b43..000000000
--- a/browser/base/content/test/general/browser_addKeywordSearch.js
+++ /dev/null
@@ -1,81 +0,0 @@
-var testData = [
- { desc: "No path",
- action: "http://example.com/",
- param: "q",
- },
- { desc: "With path",
- action: "http://example.com/new-path-here/",
- param: "q",
- },
- { desc: "No action",
- action: "",
- param: "q",
- },
- { desc: "With Query String",
- action: "http://example.com/search?oe=utf-8",
- param: "q",
- },
-];
-
-add_task(function*() {
- const TEST_URL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
-
- let count = 0;
- for (let method of ["GET", "POST"]) {
- for (let {desc, action, param } of testData) {
- info(`Running ${method} keyword test '${desc}'`);
- let id = `keyword-form-${count++}`;
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let contextMenuPromise =
- BrowserTestUtils.waitForEvent(contextMenu, "popupshown")
- .then(() => gContextMenuContentData.popupNode);
-
- yield ContentTask.spawn(tab.linkedBrowser,
- { action, param, method, id }, function* (args) {
- let doc = content.document;
- let form = doc.createElement("form");
- form.id = args.id;
- form.method = args.method;
- form.action = args.action;
- let element = doc.createElement("input");
- element.setAttribute("type", "text");
- element.setAttribute("name", args.param);
- form.appendChild(element);
- doc.body.appendChild(form);
- });
-
- yield BrowserTestUtils.synthesizeMouseAtCenter(`#${id} > input`,
- { type : "contextmenu", button : 2 },
- tab.linkedBrowser);
- let target = yield contextMenuPromise;
-
- yield new Promise(resolve => {
- let url = action || tab.linkedBrowser.currentURI.spec;
- let mm = tab.linkedBrowser.messageManager;
- let onMessage = (message) => {
- mm.removeMessageListener("ContextMenu:SearchFieldBookmarkData:Result", onMessage);
- if (method == "GET") {
- ok(message.data.spec.endsWith(`${param}=%s`),
- `Check expected url for field named ${param} and action ${action}`);
- } else {
- is(message.data.spec, url,
- `Check expected url for field named ${param} and action ${action}`);
- is(message.data.postData, `${param}%3D%25s`,
- `Check expected POST data for field named ${param} and action ${action}`);
- }
- resolve();
- };
- mm.addMessageListener("ContextMenu:SearchFieldBookmarkData:Result", onMessage);
-
- mm.sendAsyncMessage("ContextMenu:SearchFieldBookmarkData", null, { target });
- });
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- contextMenu.hidePopup();
- yield popupHiddenPromise;
- }
- }
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_alltabslistener.js b/browser/base/content/test/general/browser_alltabslistener.js
deleted file mode 100644
index a56473ec9..000000000
--- a/browser/base/content/test/general/browser_alltabslistener.js
+++ /dev/null
@@ -1,206 +0,0 @@
-var Ci = Components.interfaces;
-
-const gCompleteState = Ci.nsIWebProgressListener.STATE_STOP +
- Ci.nsIWebProgressListener.STATE_IS_NETWORK;
-
-var gFrontProgressListener = {
- onProgressChange: function (aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress) {
- },
-
- onStateChange: function (aWebProgress, aRequest, aStateFlags, aStatus) {
- var state = "onStateChange";
- info("FrontProgress: " + state + " 0x" + aStateFlags.toString(16));
- ok(gFrontNotificationsPos < gFrontNotifications.length, "Got an expected notification for the front notifications listener");
- is(state, gFrontNotifications[gFrontNotificationsPos], "Got a notification for the front notifications listener");
- gFrontNotificationsPos++;
- },
-
- onLocationChange: function (aWebProgress, aRequest, aLocationURI, aFlags) {
- var state = "onLocationChange";
- info("FrontProgress: " + state + " " + aLocationURI.spec);
- ok(gFrontNotificationsPos < gFrontNotifications.length, "Got an expected notification for the front notifications listener");
- is(state, gFrontNotifications[gFrontNotificationsPos], "Got a notification for the front notifications listener");
- gFrontNotificationsPos++;
- },
-
- onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
- },
-
- onSecurityChange: function (aWebProgress, aRequest, aState) {
- var state = "onSecurityChange";
- info("FrontProgress: " + state + " 0x" + aState.toString(16));
- ok(gFrontNotificationsPos < gFrontNotifications.length, "Got an expected notification for the front notifications listener");
- is(state, gFrontNotifications[gFrontNotificationsPos], "Got a notification for the front notifications listener");
- gFrontNotificationsPos++;
- }
-}
-
-var gAllProgressListener = {
- onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
- var state = "onStateChange";
- info("AllProgress: " + state + " 0x" + aStateFlags.toString(16));
- ok(aBrowser == gTestBrowser, state + " notification came from the correct browser");
- ok(gAllNotificationsPos < gAllNotifications.length, "Got an expected notification for the all notifications listener");
- is(state, gAllNotifications[gAllNotificationsPos], "Got a notification for the all notifications listener");
- gAllNotificationsPos++;
-
- if ((aStateFlags & gCompleteState) == gCompleteState) {
- ok(gAllNotificationsPos == gAllNotifications.length, "Saw the expected number of notifications");
- ok(gFrontNotificationsPos == gFrontNotifications.length, "Saw the expected number of frontnotifications");
- executeSoon(gNextTest);
- }
- },
-
- onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI,
- aFlags) {
- var state = "onLocationChange";
- info("AllProgress: " + state + " " + aLocationURI.spec);
- ok(aBrowser == gTestBrowser, state + " notification came from the correct browser");
- ok(gAllNotificationsPos < gAllNotifications.length, "Got an expected notification for the all notifications listener");
- is(state, gAllNotifications[gAllNotificationsPos], "Got a notification for the all notifications listener");
- gAllNotificationsPos++;
- },
-
- onStatusChange: function (aBrowser, aWebProgress, aRequest, aStatus, aMessage) {
- var state = "onStatusChange";
- ok(aBrowser == gTestBrowser, state + " notification came from the correct browser");
- },
-
- onSecurityChange: function (aBrowser, aWebProgress, aRequest, aState) {
- var state = "onSecurityChange";
- info("AllProgress: " + state + " 0x" + aState.toString(16));
- ok(aBrowser == gTestBrowser, state + " notification came from the correct browser");
- ok(gAllNotificationsPos < gAllNotifications.length, "Got an expected notification for the all notifications listener");
- is(state, gAllNotifications[gAllNotificationsPos], "Got a notification for the all notifications listener");
- gAllNotificationsPos++;
- }
-}
-
-var gFrontNotifications, gAllNotifications, gFrontNotificationsPos, gAllNotificationsPos;
-var gBackgroundTab, gForegroundTab, gBackgroundBrowser, gForegroundBrowser, gTestBrowser;
-var gTestPage = "/browser/browser/base/content/test/general/alltabslistener.html";
-const kBasePage = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-var gNextTest;
-
-function test() {
- waitForExplicitFinish();
-
- gBackgroundTab = gBrowser.addTab();
- gForegroundTab = gBrowser.addTab();
- gBackgroundBrowser = gBrowser.getBrowserForTab(gBackgroundTab);
- gForegroundBrowser = gBrowser.getBrowserForTab(gForegroundTab);
- gBrowser.selectedTab = gForegroundTab;
-
- // We must wait until a page has completed loading before
- // starting tests or we get notifications from that
- let promises = [
- waitForDocLoadComplete(gBackgroundBrowser),
- waitForDocLoadComplete(gForegroundBrowser)
- ];
- gBackgroundBrowser.loadURI(kBasePage);
- gForegroundBrowser.loadURI(kBasePage);
- Promise.all(promises).then(startTest1);
-}
-
-function runTest(browser, url, next) {
- gFrontNotificationsPos = 0;
- gAllNotificationsPos = 0;
- gNextTest = next;
- gTestBrowser = browser;
- browser.loadURI(url);
-}
-
-function startTest1() {
- info("\nTest 1");
- gBrowser.addProgressListener(gFrontProgressListener);
- gBrowser.addTabsProgressListener(gAllProgressListener);
-
- gAllNotifications = [
- "onStateChange",
- "onLocationChange",
- "onSecurityChange",
- "onStateChange"
- ];
- gFrontNotifications = gAllNotifications;
- runTest(gForegroundBrowser, "http://example.org" + gTestPage, startTest2);
-}
-
-function startTest2() {
- info("\nTest 2");
- gAllNotifications = [
- "onStateChange",
- "onLocationChange",
- "onSecurityChange",
- "onSecurityChange",
- "onStateChange"
- ];
- gFrontNotifications = gAllNotifications;
- runTest(gForegroundBrowser, "https://example.com" + gTestPage, startTest3);
-}
-
-function startTest3() {
- info("\nTest 3");
- gAllNotifications = [
- "onStateChange",
- "onLocationChange",
- "onSecurityChange",
- "onStateChange"
- ];
- gFrontNotifications = [];
- runTest(gBackgroundBrowser, "http://example.org" + gTestPage, startTest4);
-}
-
-function startTest4() {
- info("\nTest 4");
- gAllNotifications = [
- "onStateChange",
- "onLocationChange",
- "onSecurityChange",
- "onSecurityChange",
- "onStateChange"
- ];
- gFrontNotifications = [];
- runTest(gBackgroundBrowser, "https://example.com" + gTestPage, startTest5);
-}
-
-function startTest5() {
- info("\nTest 5");
- // Switch the foreground browser
- [gForegroundBrowser, gBackgroundBrowser] = [gBackgroundBrowser, gForegroundBrowser];
- [gForegroundTab, gBackgroundTab] = [gBackgroundTab, gForegroundTab];
- // Avoid the onLocationChange this will fire
- gBrowser.removeProgressListener(gFrontProgressListener);
- gBrowser.selectedTab = gForegroundTab;
- gBrowser.addProgressListener(gFrontProgressListener);
-
- gAllNotifications = [
- "onStateChange",
- "onLocationChange",
- "onSecurityChange",
- "onStateChange"
- ];
- gFrontNotifications = gAllNotifications;
- runTest(gForegroundBrowser, "http://example.org" + gTestPage, startTest6);
-}
-
-function startTest6() {
- info("\nTest 6");
- gAllNotifications = [
- "onStateChange",
- "onLocationChange",
- "onSecurityChange",
- "onStateChange"
- ];
- gFrontNotifications = [];
- runTest(gBackgroundBrowser, "http://example.org" + gTestPage, finishTest);
-}
-
-function finishTest() {
- gBrowser.removeProgressListener(gFrontProgressListener);
- gBrowser.removeTabsProgressListener(gAllProgressListener);
- gBrowser.removeTab(gBackgroundTab);
- gBrowser.removeTab(gForegroundTab);
- finish();
-}
diff --git a/browser/base/content/test/general/browser_audioTabIcon.js b/browser/base/content/test/general/browser_audioTabIcon.js
deleted file mode 100644
index 4d7a7bbd8..000000000
--- a/browser/base/content/test/general/browser_audioTabIcon.js
+++ /dev/null
@@ -1,504 +0,0 @@
-const PAGE = "https://example.com/browser/browser/base/content/test/general/file_mediaPlayback.html";
-const TABATTR_REMOVAL_PREFNAME = "browser.tabs.delayHidingAudioPlayingIconMS";
-const INITIAL_TABATTR_REMOVAL_DELAY_MS = Services.prefs.getIntPref(TABATTR_REMOVAL_PREFNAME);
-
-function* wait_for_tab_playing_event(tab, expectPlaying) {
- if (tab.soundPlaying == expectPlaying) {
- ok(true, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
- return true;
- }
- return yield BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false, (event) => {
- if (event.detail.changed.includes("soundplaying")) {
- is(tab.hasAttribute("soundplaying"), expectPlaying, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
- is(tab.soundPlaying, expectPlaying, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
- return true;
- }
- return false;
- });
-}
-
-function* play(tab) {
- let browser = tab.linkedBrowser;
- yield ContentTask.spawn(browser, {}, function* () {
- let audio = content.document.querySelector("audio");
- audio.play();
- });
-
- yield wait_for_tab_playing_event(tab, true);
-}
-
-function* pause(tab, options) {
- ok(tab.hasAttribute("soundplaying"), "The tab should have the soundplaying attribute when pause() is called");
-
- let extendedDelay = options && options.extendedDelay;
- if (extendedDelay) {
- // Use 10s to remove possibility of race condition with attr removal.
- Services.prefs.setIntPref(TABATTR_REMOVAL_PREFNAME, 10000);
- }
-
- try {
- let browser = tab.linkedBrowser;
- let awaitDOMAudioPlaybackStopped =
- BrowserTestUtils.waitForEvent(browser, "DOMAudioPlaybackStopped", "DOMAudioPlaybackStopped event should get fired after pause");
- let awaitTabPausedAttrModified =
- wait_for_tab_playing_event(tab, false);
- yield ContentTask.spawn(browser, {}, function* () {
- let audio = content.document.querySelector("audio");
- audio.pause();
- });
-
- if (extendedDelay) {
- ok(tab.hasAttribute("soundplaying"), "The tab should still have the soundplaying attribute immediately after pausing");
-
- yield awaitDOMAudioPlaybackStopped;
- ok(tab.hasAttribute("soundplaying"), "The tab should still have the soundplaying attribute immediately after DOMAudioPlaybackStopped");
- }
-
- yield awaitTabPausedAttrModified;
- ok(!tab.hasAttribute("soundplaying"), "The tab should not have the soundplaying attribute after the timeout has resolved");
- } finally {
- // Make sure other tests don't timeout if an exception gets thrown above.
- // Need to use setIntPref instead of clearUserPref because prefs_general.js
- // overrides the default value to help this and other tests run faster.
- Services.prefs.setIntPref(TABATTR_REMOVAL_PREFNAME, INITIAL_TABATTR_REMOVAL_DELAY_MS);
- }
-}
-
-function disable_non_test_mouse(disable) {
- let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- utils.disableNonTestMouseEvents(disable);
-}
-
-function* hover_icon(icon, tooltip) {
- disable_non_test_mouse(true);
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(tooltip, "popupshown");
- EventUtils.synthesizeMouse(icon, 1, 1, {type: "mouseover"});
- EventUtils.synthesizeMouse(icon, 2, 2, {type: "mousemove"});
- EventUtils.synthesizeMouse(icon, 3, 3, {type: "mousemove"});
- EventUtils.synthesizeMouse(icon, 4, 4, {type: "mousemove"});
- return popupShownPromise;
-}
-
-function leave_icon(icon) {
- EventUtils.synthesizeMouse(icon, 0, 0, {type: "mouseout"});
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
-
- disable_non_test_mouse(false);
-}
-
-function* test_tooltip(icon, expectedTooltip, isActiveTab) {
- let tooltip = document.getElementById("tabbrowser-tab-tooltip");
-
- yield hover_icon(icon, tooltip);
- if (isActiveTab) {
- // The active tab should have the keybinding shortcut in the tooltip.
- // We check this by ensuring that the strings are not equal but the expected
- // message appears in the beginning.
- isnot(tooltip.getAttribute("label"), expectedTooltip, "Tooltips should not be equal");
- is(tooltip.getAttribute("label").indexOf(expectedTooltip), 0, "Correct tooltip expected");
- } else {
- is(tooltip.getAttribute("label"), expectedTooltip, "Tooltips should not be equal");
- }
- leave_icon(icon);
-}
-
-// The set of tabs which have ever had their mute state changed.
-// Used to determine whether the tab should have a muteReason value.
-let everMutedTabs = new WeakSet();
-
-function get_wait_for_mute_promise(tab, expectMuted) {
- return BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false, event => {
- if (event.detail.changed.includes("muted")) {
- is(tab.hasAttribute("muted"), expectMuted, "The tab should " + (expectMuted ? "" : "not ") + "be muted");
- is(tab.muted, expectMuted, "The tab muted property " + (expectMuted ? "" : "not ") + "be true");
-
- if (expectMuted || everMutedTabs.has(tab)) {
- everMutedTabs.add(tab);
- is(tab.muteReason, null, "The tab should have a null muteReason value");
- } else {
- is(tab.muteReason, undefined, "The tab should have an undefined muteReason value");
- }
- return true;
- }
- return false;
- });
-}
-
-function* test_mute_tab(tab, icon, expectMuted) {
- let mutedPromise = test_mute_keybinding(tab, expectMuted);
-
- let activeTab = gBrowser.selectedTab;
-
- let tooltip = document.getElementById("tabbrowser-tab-tooltip");
-
- yield hover_icon(icon, tooltip);
- EventUtils.synthesizeMouseAtCenter(icon, {button: 0});
- leave_icon(icon);
-
- is(gBrowser.selectedTab, activeTab, "Clicking on mute should not change the currently selected tab");
-
- return mutedPromise;
-}
-
-function get_tab_state(tab) {
- const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
- return JSON.parse(ss.getTabState(tab));
-}
-
-function* test_muting_using_menu(tab, expectMuted) {
- // Show the popup menu
- let contextMenu = document.getElementById("tabContextMenu");
- let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- EventUtils.synthesizeMouseAtCenter(tab, {type: "contextmenu", button: 2});
- yield popupShownPromise;
-
- // Check the menu
- let expectedLabel = expectMuted ? "Unmute Tab" : "Mute Tab";
- let toggleMute = document.getElementById("context_toggleMuteTab");
- is(toggleMute.label, expectedLabel, "Correct label expected");
- is(toggleMute.accessKey, "M", "Correct accessKey expected");
-
- is(toggleMute.hasAttribute("muted"), expectMuted, "Should have the correct state for the muted attribute");
- ok(!toggleMute.hasAttribute("soundplaying"), "Should not have the soundplaying attribute");
-
- yield play(tab);
-
- is(toggleMute.hasAttribute("muted"), expectMuted, "Should have the correct state for the muted attribute");
- ok(toggleMute.hasAttribute("soundplaying"), "Should have the soundplaying attribute");
-
- yield pause(tab);
-
- is(toggleMute.hasAttribute("muted"), expectMuted, "Should have the correct state for the muted attribute");
- ok(!toggleMute.hasAttribute("soundplaying"), "Should not have the soundplaying attribute");
-
- // Click on the menu and wait for the tab to be muted.
- let mutedPromise = get_wait_for_mute_promise(tab, !expectMuted);
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- EventUtils.synthesizeMouseAtCenter(toggleMute, {});
- yield popupHiddenPromise;
- yield mutedPromise;
-}
-
-function* test_playing_icon_on_tab(tab, browser, isPinned) {
- let icon = document.getAnonymousElementByAttribute(tab, "anonid",
- isPinned ? "overlay-icon" : "soundplaying-icon");
- let isActiveTab = tab === gBrowser.selectedTab;
-
- yield play(tab);
-
- yield test_tooltip(icon, "Mute tab", isActiveTab);
-
- ok(!("muted" in get_tab_state(tab)), "No muted attribute should be persisted");
- ok(!("muteReason" in get_tab_state(tab)), "No muteReason property should be persisted");
-
- yield test_mute_tab(tab, icon, true);
-
- ok("muted" in get_tab_state(tab), "Muted attribute should be persisted");
- ok("muteReason" in get_tab_state(tab), "muteReason property should be persisted");
-
- yield test_tooltip(icon, "Unmute tab", isActiveTab);
-
- yield test_mute_tab(tab, icon, false);
-
- ok(!("muted" in get_tab_state(tab)), "No muted attribute should be persisted");
- ok(!("muteReason" in get_tab_state(tab)), "No muteReason property should be persisted");
-
- yield test_tooltip(icon, "Mute tab", isActiveTab);
-
- yield test_mute_tab(tab, icon, true);
-
- yield pause(tab);
-
- ok(tab.hasAttribute("muted") &&
- !tab.hasAttribute("soundplaying"), "Tab should still be muted but not playing");
- ok(tab.muted && !tab.soundPlaying, "Tab should still be muted but not playing");
-
- yield test_tooltip(icon, "Unmute tab", isActiveTab);
-
- yield test_mute_tab(tab, icon, false);
-
- ok(!tab.hasAttribute("muted") &&
- !tab.hasAttribute("soundplaying"), "Tab should not be be muted or playing");
- ok(!tab.muted && !tab.soundPlaying, "Tab should not be be muted or playing");
-
- // Make sure it's possible to mute using the context menu.
- yield test_muting_using_menu(tab, false);
-
- // Make sure it's possible to unmute using the context menu.
- yield test_muting_using_menu(tab, true);
-}
-
-function* test_swapped_browser_while_playing(oldTab, newBrowser) {
- ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab");
- is(oldTab.muteReason, null, "Expected the correct muteReason attribute on the old tab");
- ok(oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab");
-
- let newTab = gBrowser.getTabForBrowser(newBrowser);
- let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
- return event.detail.changed.includes("soundplaying") &&
- event.detail.changed.includes("muted");
- });
-
- gBrowser.swapBrowsersAndCloseOther(newTab, oldTab);
- yield AttrChangePromise;
-
- ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
- is(newTab.muteReason, null, "Expected the correct muteReason property on the new tab");
- ok(newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
-
- let icon = document.getAnonymousElementByAttribute(newTab, "anonid",
- "soundplaying-icon");
- yield test_tooltip(icon, "Unmute tab", true);
-}
-
-function* test_swapped_browser_while_not_playing(oldTab, newBrowser) {
- ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab");
- is(oldTab.muteReason, null, "Expected the correct muteReason property on the old tab");
- ok(!oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab");
-
- let newTab = gBrowser.getTabForBrowser(newBrowser);
- let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => {
- return event.detail.changed.includes("muted");
- });
-
- let AudioPlaybackPromise = new Promise(resolve => {
- let observer = (subject, topic, data) => {
- ok(false, "Should not see an audio-playback notification");
- };
- Services.obs.addObserver(observer, "audiochannel-activity-normal", false);
- setTimeout(() => {
- Services.obs.removeObserver(observer, "audiochannel-activity-normal");
- resolve();
- }, 100);
- });
-
- gBrowser.swapBrowsersAndCloseOther(newTab, oldTab);
- yield AttrChangePromise;
-
- ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
- is(newTab.muteReason, null, "Expected the correct muteReason property on the new tab");
- ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
-
- // Wait to see if an audio-playback event is dispatched.
- yield AudioPlaybackPromise;
-
- ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
- is(newTab.muteReason, null, "Expected the correct muteReason property on the new tab");
- ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab");
-
- let icon = document.getAnonymousElementByAttribute(newTab, "anonid",
- "soundplaying-icon");
- yield test_tooltip(icon, "Unmute tab", true);
-}
-
-function* test_browser_swapping(tab, browser) {
- // First, test swapping with a playing but muted tab.
- yield play(tab);
-
- let icon = document.getAnonymousElementByAttribute(tab, "anonid",
- "soundplaying-icon");
- yield test_mute_tab(tab, icon, true);
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:blank",
- }, function*(newBrowser) {
- yield test_swapped_browser_while_playing(tab, newBrowser)
-
- // Now, test swapping with a muted but not playing tab.
- // Note that the tab remains muted, so we only need to pause playback.
- tab = gBrowser.getTabForBrowser(newBrowser);
- yield pause(tab);
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:blank",
- }, secondAboutBlankBrowser => test_swapped_browser_while_not_playing(tab, secondAboutBlankBrowser));
- });
-}
-
-function* test_click_on_pinned_tab_after_mute() {
- function* taskFn(browser) {
- let tab = gBrowser.getTabForBrowser(browser);
-
- gBrowser.selectedTab = originallySelectedTab;
- isnot(tab, gBrowser.selectedTab, "Sanity check, the tab should not be selected!");
-
- // Steps to reproduce the bug:
- // Pin the tab.
- gBrowser.pinTab(tab);
-
- // Start playback and wait for it to finish.
- yield play(tab);
-
- // Mute the tab.
- let icon = document.getAnonymousElementByAttribute(tab, "anonid", "overlay-icon");
- yield test_mute_tab(tab, icon, true);
-
- // Pause playback and wait for it to finish.
- yield pause(tab);
-
- // Unmute tab.
- yield test_mute_tab(tab, icon, false);
-
- // Now click on the tab.
- let image = document.getAnonymousElementByAttribute(tab, "anonid", "tab-icon-image");
- EventUtils.synthesizeMouseAtCenter(image, {button: 0});
-
- is(tab, gBrowser.selectedTab, "Tab switch should be successful");
-
- // Cleanup.
- gBrowser.unpinTab(tab);
- gBrowser.selectedTab = originallySelectedTab;
- }
-
- let originallySelectedTab = gBrowser.selectedTab;
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE
- }, taskFn);
-}
-
-// This test only does something useful in e10s!
-function* test_cross_process_load() {
- function* taskFn(browser) {
- let tab = gBrowser.getTabForBrowser(browser);
-
- // Start playback and wait for it to finish.
- yield play(tab);
-
- let soundPlayingStoppedPromise = BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false,
- event => event.detail.changed.includes("soundplaying")
- );
-
- // Go to a different process.
- browser.loadURI("about:");
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield soundPlayingStoppedPromise;
-
- ok(!tab.hasAttribute("soundplaying"), "Tab should not be playing sound any more");
- ok(!tab.soundPlaying, "Tab should not be playing sound any more");
- }
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE
- }, taskFn);
-}
-
-function* test_mute_keybinding() {
- function* test_muting_using_keyboard(tab) {
- let mutedPromise = get_wait_for_mute_promise(tab, true);
- EventUtils.synthesizeKey("m", {ctrlKey: true});
- yield mutedPromise;
- mutedPromise = get_wait_for_mute_promise(tab, false);
- EventUtils.synthesizeKey("m", {ctrlKey: true});
- yield mutedPromise;
- }
- function* taskFn(browser) {
- let tab = gBrowser.getTabForBrowser(browser);
-
- // Make sure it's possible to mute before the tab is playing.
- yield test_muting_using_keyboard(tab);
-
- // Start playback and wait for it to finish.
- yield play(tab);
-
- // Make sure it's possible to mute after the tab is playing.
- yield test_muting_using_keyboard(tab);
-
- // Pause playback and wait for it to finish.
- yield pause(tab);
-
- // Make sure things work if the tab is pinned.
- gBrowser.pinTab(tab);
-
- // Make sure it's possible to mute before the tab is playing.
- yield test_muting_using_keyboard(tab);
-
- // Start playback and wait for it to finish.
- yield play(tab);
-
- // Make sure it's possible to mute after the tab is playing.
- yield test_muting_using_keyboard(tab);
-
- gBrowser.unpinTab(tab);
- }
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE
- }, taskFn);
-}
-
-function* test_on_browser(browser) {
- let tab = gBrowser.getTabForBrowser(browser);
-
- // Test the icon in a normal tab.
- yield test_playing_icon_on_tab(tab, browser, false);
-
- gBrowser.pinTab(tab);
-
- // Test the icon in a pinned tab.
- yield test_playing_icon_on_tab(tab, browser, true);
-
- gBrowser.unpinTab(tab);
-
- // Retest with another browser in the foreground tab
- if (gBrowser.selectedBrowser.currentURI.spec == PAGE) {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "data:text/html,test"
- }, () => test_on_browser(browser));
- } else {
- yield test_browser_swapping(tab, browser);
- }
-}
-
-function* test_delayed_tabattr_removal() {
- function* taskFn(browser) {
- let tab = gBrowser.getTabForBrowser(browser);
- yield play(tab);
-
- // Extend the delay to guarantee the soundplaying attribute
- // is not removed from the tab when audio is stopped. Without
- // the extended delay the attribute could be removed in the
- // same tick and the test wouldn't catch that this broke.
- yield pause(tab, {extendedDelay: true});
- }
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE
- }, taskFn);
-}
-
-add_task(function*() {
- yield new Promise((resolve) => {
- SpecialPowers.pushPrefEnv({"set": [
- ["browser.tabs.showAudioPlayingIcon", true],
- ]}, resolve);
- });
-});
-
-requestLongerTimeout(2);
-add_task(function* test_page() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE
- }, test_on_browser);
-});
-
-add_task(test_click_on_pinned_tab_after_mute);
-
-add_task(test_cross_process_load);
-
-add_task(test_mute_keybinding);
-
-add_task(test_delayed_tabattr_removal);
diff --git a/browser/base/content/test/general/browser_backButtonFitts.js b/browser/base/content/test/general/browser_backButtonFitts.js
deleted file mode 100644
index 0e8aeeaee..000000000
--- a/browser/base/content/test/general/browser_backButtonFitts.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-add_task(function* () {
- let firstLocation = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
- 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, false);
- sendAsyncMessage("Test:PopStateOccurred", { location: content.document.location.href });
- }, false);
- });
-
- 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);
- var xPixel = 0; // Use the first pixel of the screen since it is maximized.
-
- let resultLocation = yield new Promise(resolve => {
- messageManager.addMessageListener("Test:PopStateOccurred", function statePopped(message) {
- messageManager.removeMessageListener("Test:PopStateOccurred", statePopped);
- resolve(message.data.location);
- });
-
- EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window);
- });
-
- is(resultLocation, firstLocation, "Clicking the first pixel should have navigated back.");
- window.restore();
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js b/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
deleted file mode 100644
index 91a4a7e9c..000000000
--- a/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
+++ /dev/null
@@ -1,76 +0,0 @@
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/base/content/test/general/file_double_close_tab.html";
-
-var expectingDialog = false;
-var wantToClose = true;
-var resolveDialogPromise;
-function onTabModalDialogLoaded(node) {
- ok(expectingDialog, "Should be expecting this dialog.");
- expectingDialog = false;
- if (wantToClose) {
- // This accepts the dialog, closing it
- node.Dialog.ui.button0.click();
- } else {
- // This keeps the page open
- node.Dialog.ui.button1.click();
- }
- if (resolveDialogPromise) {
- resolveDialogPromise();
- }
-}
-
-SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
-
-// Listen for the dialog being created
-Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false);
-registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.tabs.warnOnClose");
- Services.obs.removeObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded");
-});
-
-add_task(function* closeLastTabInWindow() {
- let newWin = yield promiseOpenAndLoadWindow({}, true);
- let firstTab = newWin.gBrowser.selectedTab;
- yield promiseTabLoadEvent(firstTab, TEST_PAGE);
- let windowClosedPromise = promiseWindowWillBeClosed(newWin);
- expectingDialog = true;
- // close tab:
- document.getAnonymousElementByAttribute(firstTab, "anonid", "close-button").click();
- yield windowClosedPromise;
- ok(!expectingDialog, "There should have been a dialog.");
- ok(newWin.closed, "Window should be closed.");
-});
-
-add_task(function* closeWindowWithMultipleTabsIncludingOneBeforeUnload() {
- Services.prefs.setBoolPref("browser.tabs.warnOnClose", false);
- let newWin = yield promiseOpenAndLoadWindow({}, true);
- let firstTab = newWin.gBrowser.selectedTab;
- yield promiseTabLoadEvent(firstTab, TEST_PAGE);
- yield promiseTabLoadEvent(newWin.gBrowser.addTab(), "http://example.com/");
- let windowClosedPromise = promiseWindowWillBeClosed(newWin);
- expectingDialog = true;
- newWin.BrowserTryToCloseWindow();
- yield windowClosedPromise;
- ok(!expectingDialog, "There should have been a dialog.");
- ok(newWin.closed, "Window should be closed.");
- Services.prefs.clearUserPref("browser.tabs.warnOnClose");
-});
-
-add_task(function* closeWindoWithSingleTabTwice() {
- let newWin = yield promiseOpenAndLoadWindow({}, true);
- let firstTab = newWin.gBrowser.selectedTab;
- yield promiseTabLoadEvent(firstTab, TEST_PAGE);
- let windowClosedPromise = promiseWindowWillBeClosed(newWin);
- expectingDialog = true;
- wantToClose = false;
- let firstDialogShownPromise = new Promise((resolve, reject) => { resolveDialogPromise = resolve; });
- document.getAnonymousElementByAttribute(firstTab, "anonid", "close-button").click();
- yield firstDialogShownPromise;
- info("Got initial dialog, now trying again");
- expectingDialog = true;
- wantToClose = true;
- resolveDialogPromise = null;
- document.getAnonymousElementByAttribute(firstTab, "anonid", "close-button").click();
- yield windowClosedPromise;
- ok(!expectingDialog, "There should have been a dialog.");
- ok(newWin.closed, "Window should be closed.");
-});
diff --git a/browser/base/content/test/general/browser_blob-channelname.js b/browser/base/content/test/general/browser_blob-channelname.js
deleted file mode 100644
index d87e4a896..000000000
--- a/browser/base/content/test/general/browser_blob-channelname.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-function test() {
- var file = new File([new Blob(['test'], {type: 'text/plain'})], "test-name");
- var url = URL.createObjectURL(file);
- var channel = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
-
- is(channel.contentDispositionFilename, 'test-name', "filename matches");
-}
diff --git a/browser/base/content/test/general/browser_blockHPKP.js b/browser/base/content/test/general/browser_blockHPKP.js
deleted file mode 100644
index c0d1233ab..000000000
--- a/browser/base/content/test/general/browser_blockHPKP.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test that visiting a site pinned with HPKP headers does not succeed when it
-// uses a certificate with a key not in the pinset. This should result in an
-// about:neterror page
-// Also verify that removal of the HPKP headers succeeds (via HPKP headers)
-// and that after removal the visit to the site with the previously
-// unauthorized pins succeeds.
-//
-// This test required three certs to be created in build/pgo/certs:
-// 1. A new trusted root:
-// a. certutil -S -s "Alternate trusted authority" -s "CN=Alternate Trusted Authority" -t "C,," -x -m 1 -v 120 -n "alternateTrustedAuthority" -Z SHA256 -g 2048 -2 -d .
-// b. (export) certutil -L -d . -n "alternateTrustedAuthority" -a -o alternateroot.ca
-// (files ended in .ca are added as trusted roots by the mochitest harness)
-// 2. A good pinning server cert (signed by the pgo root):
-// certutil -S -n "dynamicPinningGood" -s "CN=dynamic-pinning.example.com" -c "pgo temporary ca" -t "P,," -k rsa -g 2048 -Z SHA256 -m 8939454 -v 120 -8 "*.include-subdomains.pinning-dynamic.example.com,*.pinning-dynamic.example.com" -d .
-// 3. A certificate with a different issuer, so as to cause a key pinning violation."
-// certutil -S -n "dynamicPinningBad" -s "CN=bad.include-subdomains.pinning-dynamic.example.com" -c "alternateTrustedAuthority" -t "P,," -k rsa -g 2048 -Z SHA256 -m 893945439 -v 120 -8 "bad.include-subdomains.pinning-dynamic.example.com" -d .
-
-const gSSService = Cc["@mozilla.org/ssservice;1"]
- .getService(Ci.nsISiteSecurityService);
-const gIOService = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService);
-
-const kPinningDomain = "include-subdomains.pinning-dynamic.example.com";
-const khpkpPinninEnablePref = "security.cert_pinning.process_headers_from_non_builtin_roots";
-const kpkpEnforcementPref = "security.cert_pinning.enforcement_level";
-const kBadPinningDomain = "bad.include-subdomains.pinning-dynamic.example.com";
-const kURLPath = "/browser/browser/base/content/test/general/pinning_headers.sjs?";
-
-function test() {
- waitForExplicitFinish();
- // Enable enforcing strict pinning and processing headers from
- // non-builtin roots.
- Services.prefs.setIntPref(kpkpEnforcementPref, 2);
- Services.prefs.setBoolPref(khpkpPinninEnablePref, true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(kpkpEnforcementPref);
- Services.prefs.clearUserPref(khpkpPinninEnablePref);
- let uri = gIOService.newURI("https://" + kPinningDomain, null, null);
- gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
- });
- whenNewTabLoaded(window, loadPinningPage);
-}
-
-// Start by making a successful connection to a domain that will pin a site
-function loadPinningPage() {
-
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kPinningDomain + kURLPath + "valid").then(function() {
- gBrowser.selectedBrowser.addEventListener("load",
- successfulPinningPageListener,
- true);
- });
-}
-
-// After the site is pinned try to load with a subdomain site that should
-// fail to validate
-var successfulPinningPageListener = {
- handleEvent: function() {
- gBrowser.selectedBrowser.removeEventListener("load", this, true);
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kBadPinningDomain).then(function() {
- return promiseErrorPageLoaded(gBrowser.selectedBrowser);
- }).then(errorPageLoaded);
- }
-};
-
-// The browser should load about:neterror, when this happens, proceed
-// to load the pinning domain again, this time removing the pinning information
-function errorPageLoaded() {
- ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let textElement = content.document.getElementById("errorShortDescText");
- let text = textElement.innerHTML;
- ok(text.indexOf("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE") > 0,
- "Got a pinning error page");
- }).then(function() {
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kPinningDomain + kURLPath + "zeromaxagevalid").then(function() {
- return BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- }).then(pinningRemovalLoaded);
- });
-}
-
-// After the pinning information has been removed (successful load) proceed
-// to load again with the invalid pin domain.
-function pinningRemovalLoaded() {
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kBadPinningDomain).then(function() {
- return BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- }).then(badPinningPageLoaded);
-}
-
-// Finally, we should successfully load
-// https://bad.include-subdomains.pinning-dynamic.example.com.
-function badPinningPageLoaded() {
- BrowserTestUtils.removeTab(gBrowser.selectedTab).then(function() {
- ok(true, "load complete");
- finish();
- });
-}
diff --git a/browser/base/content/test/general/browser_bookmark_popup.js b/browser/base/content/test/general/browser_bookmark_popup.js
deleted file mode 100644
index c1ddd725e..000000000
--- a/browser/base/content/test/general/browser_bookmark_popup.js
+++ /dev/null
@@ -1,431 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * Test opening and closing the bookmarks panel.
- */
-
-let bookmarkPanel = document.getElementById("editBookmarkPanel");
-let bookmarkStar = document.getElementById("bookmarks-menu-button");
-let bookmarkPanelTitle = document.getElementById("editBookmarkPanelTitle");
-let editBookmarkPanelRemoveButtonRect;
-
-StarUI._closePanelQuickForTesting = true;
-
-function* test_bookmarks_popup({isNewBookmark, popupShowFn, popupEditFn,
- shouldAutoClose, popupHideFn, isBookmarkRemoved}) {
- yield BrowserTestUtils.withNewTab({gBrowser, url: "about:home"}, function*(browser) {
- try {
- if (!isNewBookmark) {
- yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "about:home",
- title: "Home Page"
- });
- }
-
- info(`BookmarkingUI.status is ${BookmarkingUI.status}`);
- yield BrowserTestUtils.waitForCondition(
- () => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING,
- "BookmarkingUI should not be updating");
-
- is(bookmarkStar.hasAttribute("starred"), !isNewBookmark,
- "Page should only be starred prior to popupshown if editing bookmark");
- is(bookmarkPanel.state, "closed", "Panel should be 'closed' to start test");
- let shownPromise = promisePopupShown(bookmarkPanel);
- yield popupShowFn(browser);
- yield shownPromise;
- is(bookmarkPanel.state, "open", "Panel should be 'open' after shownPromise is resolved");
-
- editBookmarkPanelRemoveButtonRect =
- document.getElementById("editBookmarkPanelRemoveButton").getBoundingClientRect();
-
- if (popupEditFn) {
- yield popupEditFn();
- }
- let bookmarks = [];
- yield PlacesUtils.bookmarks.fetch({url: "about:home"}, bm => bookmarks.push(bm));
- is(bookmarks.length, 1, "Only one bookmark should exist");
- is(bookmarkStar.getAttribute("starred"), "true", "Page is starred");
- is(bookmarkPanelTitle.value,
- isNewBookmark ?
- gNavigatorBundle.getString("editBookmarkPanel.pageBookmarkedTitle") :
- gNavigatorBundle.getString("editBookmarkPanel.editBookmarkTitle"),
- "title should match isEditingBookmark state");
-
- if (!shouldAutoClose) {
- yield new Promise(resolve => setTimeout(resolve, 400));
- is(bookmarkPanel.state, "open", "Panel should still be 'open' for non-autoclose");
- }
-
- let hiddenPromise = promisePopupHidden(bookmarkPanel);
- if (popupHideFn) {
- yield popupHideFn();
- }
- yield hiddenPromise;
- is(bookmarkStar.hasAttribute("starred"), !isBookmarkRemoved,
- "Page is starred after closing");
- } finally {
- let bookmark = yield PlacesUtils.bookmarks.fetch({url: "about:home"});
- is(!!bookmark, !isBookmarkRemoved,
- "bookmark should not be present if a panel action should've removed it");
- if (bookmark) {
- yield PlacesUtils.bookmarks.remove(bookmark);
- }
- }
- });
-}
-
-add_task(function* panel_shown_for_new_bookmarks_and_autocloses() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- bookmarkStar.click();
- },
- shouldAutoClose: true,
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_once_for_doubleclick_on_new_bookmark_star_and_autocloses() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- EventUtils.synthesizeMouse(bookmarkStar, 10, 10, { clickCount: 2 },
- window);
- },
- shouldAutoClose: true,
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_once_for_slow_doubleclick_on_new_bookmark_star_and_autocloses() {
- todo(false, "bug 1250267, may need to add some tracking state to " +
- "browser-places.js for this.");
- return;
-
- /*
- yield test_bookmarks_popup({
- isNewBookmark: true,
- *popupShowFn() {
- EventUtils.synthesizeMouse(bookmarkStar, 10, 10, window);
- yield new Promise(resolve => setTimeout(resolve, 300));
- EventUtils.synthesizeMouse(bookmarkStar, 10, 10, window);
- },
- shouldAutoClose: true,
- isBookmarkRemoved: false,
- });
- */
-});
-
-add_task(function* panel_shown_for_keyboardshortcut_on_new_bookmark_star_and_autocloses() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- EventUtils.synthesizeKey("D", {accelKey: true}, window);
- },
- shouldAutoClose: true,
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_for_new_bookmarks_mousemove_mouseout() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- bookmarkStar.click();
- },
- *popupEditFn() {
- let mouseMovePromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mousemove");
- EventUtils.synthesizeMouseAtCenter(bookmarkPanel, {type: "mousemove"});
- info("Waiting for mousemove event");
- yield mouseMovePromise;
- info("Got mousemove event");
-
- yield new Promise(resolve => setTimeout(resolve, 400));
- is(bookmarkPanel.state, "open", "Panel should still be open on mousemove");
- },
- *popupHideFn() {
- let mouseOutPromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mouseout");
- EventUtils.synthesizeMouse(bookmarkPanel, 0, 0, {type: "mouseout"});
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
- info("Waiting for mouseout event");
- yield mouseOutPromise;
- info("Got mouseout event, should autoclose now");
- },
- shouldAutoClose: false,
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_for_new_bookmark_no_autoclose_close_with_ESC() {
- yield test_bookmarks_popup({
- isNewBookmark: false,
- popupShowFn() {
- bookmarkStar.click();
- },
- shouldAutoClose: false,
- popupHideFn() {
- EventUtils.synthesizeKey("VK_ESCAPE", {accelKey: true}, window);
- },
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_for_editing_no_autoclose_close_with_ESC() {
- yield test_bookmarks_popup({
- isNewBookmark: false,
- popupShowFn() {
- bookmarkStar.click();
- },
- shouldAutoClose: false,
- popupHideFn() {
- EventUtils.synthesizeKey("VK_ESCAPE", {accelKey: true}, window);
- },
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_for_new_bookmark_keypress_no_autoclose() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- bookmarkStar.click();
- },
- popupEditFn() {
- EventUtils.sendChar("VK_TAB", window);
- },
- shouldAutoClose: false,
- popupHideFn() {
- bookmarkPanel.hidePopup();
- },
- isBookmarkRemoved: false,
- });
-});
-
-
-add_task(function* panel_shown_for_new_bookmark_compositionstart_no_autoclose() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- bookmarkStar.click();
- },
- *popupEditFn() {
- let compositionStartPromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "compositionstart");
- EventUtils.synthesizeComposition({ type: "compositionstart" }, window);
- info("Waiting for compositionstart event");
- yield compositionStartPromise;
- info("Got compositionstart event");
- },
- shouldAutoClose: false,
- popupHideFn() {
- EventUtils.synthesizeComposition({ type: "compositioncommitasis" });
- bookmarkPanel.hidePopup();
- },
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_for_new_bookmark_compositionstart_mouseout_no_autoclose() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- bookmarkStar.click();
- },
- *popupEditFn() {
- let mouseMovePromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mousemove");
- EventUtils.synthesizeMouseAtCenter(bookmarkPanel, {type: "mousemove"});
- info("Waiting for mousemove event");
- yield mouseMovePromise;
- info("Got mousemove event");
-
- let compositionStartPromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "compositionstart");
- EventUtils.synthesizeComposition({ type: "compositionstart" }, window);
- info("Waiting for compositionstart event");
- yield compositionStartPromise;
- info("Got compositionstart event");
-
- let mouseOutPromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mouseout");
- EventUtils.synthesizeMouse(bookmarkPanel, 0, 0, {type: "mouseout"});
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
- info("Waiting for mouseout event");
- yield mouseOutPromise;
- info("Got mouseout event, but shouldn't run autoclose");
- },
- shouldAutoClose: false,
- popupHideFn() {
- EventUtils.synthesizeComposition({ type: "compositioncommitasis" });
- bookmarkPanel.hidePopup();
- },
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* panel_shown_for_new_bookmark_compositionend_no_autoclose() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn() {
- bookmarkStar.click();
- },
- *popupEditFn() {
- let mouseMovePromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mousemove");
- EventUtils.synthesizeMouseAtCenter(bookmarkPanel, {type: "mousemove"});
- info("Waiting for mousemove event");
- yield mouseMovePromise;
- info("Got mousemove event");
-
- EventUtils.synthesizeComposition({ type: "compositioncommit", data: "committed text" });
- },
- popupHideFn() {
- bookmarkPanel.hidePopup();
- },
- shouldAutoClose: false,
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* contextmenu_new_bookmark_keypress_no_autoclose() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- *popupShowFn(browser) {
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu,
- "popupshown");
- let awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu,
- "popuphidden");
- yield BrowserTestUtils.synthesizeMouseAtCenter("body", {
- type: "contextmenu",
- button: 2
- }, browser);
- yield awaitPopupShown;
- document.getElementById("context-bookmarkpage").click();
- contextMenu.hidePopup();
- yield awaitPopupHidden;
- },
- popupEditFn() {
- EventUtils.sendChar("VK_TAB", window);
- },
- shouldAutoClose: false,
- popupHideFn() {
- bookmarkPanel.hidePopup();
- },
- isBookmarkRemoved: false,
- });
-});
-
-add_task(function* bookmarks_menu_new_bookmark_remove_bookmark() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn(browser) {
- document.getElementById("menu_bookmarkThisPage").doCommand();
- },
- shouldAutoClose: true,
- popupHideFn() {
- document.getElementById("editBookmarkPanelRemoveButton").click();
- },
- isBookmarkRemoved: true,
- });
-});
-
-add_task(function* ctrl_d_edit_bookmark_remove_bookmark() {
- yield test_bookmarks_popup({
- isNewBookmark: false,
- popupShowFn(browser) {
- EventUtils.synthesizeKey("D", {accelKey: true}, window);
- },
- shouldAutoClose: true,
- popupHideFn() {
- document.getElementById("editBookmarkPanelRemoveButton").click();
- },
- isBookmarkRemoved: true,
- });
-});
-
-add_task(function* enter_on_remove_bookmark_should_remove_bookmark() {
- if (AppConstants.platform == "macosx") {
- // "Full Keyboard Access" is disabled by default, and thus doesn't allow
- // keyboard navigation to the "Remove Bookmarks" button by default.
- return;
- }
-
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn(browser) {
- EventUtils.synthesizeKey("D", {accelKey: true}, window);
- },
- shouldAutoClose: true,
- popupHideFn() {
- while (!document.activeElement ||
- document.activeElement.id != "editBookmarkPanelRemoveButton") {
- EventUtils.sendChar("VK_TAB", window);
- }
- EventUtils.sendChar("VK_RETURN", window);
- },
- isBookmarkRemoved: true,
- });
-});
-
-add_task(function* ctrl_d_new_bookmark_mousedown_mouseout_no_autoclose() {
- yield test_bookmarks_popup({
- isNewBookmark: true,
- popupShowFn(browser) {
- EventUtils.synthesizeKey("D", {accelKey: true}, window);
- },
- *popupEditFn() {
- let mouseMovePromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mousemove");
- EventUtils.synthesizeMouseAtCenter(bookmarkPanel, {type: "mousemove"});
- info("Waiting for mousemove event");
- yield mouseMovePromise;
- info("Got mousemove event");
-
- yield new Promise(resolve => setTimeout(resolve, 400));
- is(bookmarkPanel.state, "open", "Panel should still be open on mousemove");
-
- EventUtils.synthesizeMouseAtCenter(bookmarkPanelTitle, {button: 1, type: "mousedown"});
-
- let mouseOutPromise = BrowserTestUtils.waitForEvent(bookmarkPanel, "mouseout");
- EventUtils.synthesizeMouse(bookmarkPanel, 0, 0, {type: "mouseout"});
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
- info("Waiting for mouseout event");
- yield mouseOutPromise;
- },
- shouldAutoClose: false,
- popupHideFn() {
- document.getElementById("editBookmarkPanelRemoveButton").click();
- },
- isBookmarkRemoved: true,
- });
-});
-
-add_task(function* mouse_hovering_panel_should_prevent_autoclose() {
- if (AppConstants.platform != "win") {
- // This test requires synthesizing native mouse movement which is
- // best supported on Windows.
- return;
- }
- yield test_bookmarks_popup({
- isNewBookmark: true,
- *popupShowFn(browser) {
- yield new Promise(resolve => {
- EventUtils.synthesizeNativeMouseMove(
- document.documentElement,
- editBookmarkPanelRemoveButtonRect.left,
- editBookmarkPanelRemoveButtonRect.top,
- resolve);
- });
- EventUtils.synthesizeKey("D", {accelKey: true}, window);
- },
- shouldAutoClose: false,
- popupHideFn() {
- document.getElementById("editBookmarkPanelRemoveButton").click();
- },
- isBookmarkRemoved: true,
- });
-});
-
-registerCleanupFunction(function() {
- delete StarUI._closePanelQuickForTesting;
-});
diff --git a/browser/base/content/test/general/browser_bookmark_titles.js b/browser/base/content/test/general/browser_bookmark_titles.js
deleted file mode 100644
index 1f7082396..000000000
--- a/browser/base/content/test/general/browser_bookmark_titles.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This file is tests for the default titles that new bookmarks get.
-
-var tests = [
- // Common page.
- ['http://example.com/browser/browser/base/content/test/general/dummy_page.html',
- 'Dummy test page'],
- // Data URI.
- ['data:text/html;charset=utf-8,<title>test%20data:%20url</title>',
- 'test data: url'],
- // about:neterror
- ['data:application/vnd.mozilla.xul+xml,',
- 'data:application/vnd.mozilla.xul+xml,'],
- // about:certerror
- ['https://untrusted.example.com/somepage.html',
- 'https://untrusted.example.com/somepage.html']
-];
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
- let browser = gBrowser.selectedBrowser;
- browser.stop(); // stop the about:blank load.
-
- // Test that a bookmark of each URI gets the corresponding default title.
- for (let i = 0; i < tests.length; ++i) {
- let [uri, title] = tests[i];
-
- let promiseLoaded = promisePageLoaded(browser);
- BrowserTestUtils.loadURI(browser, uri);
- yield promiseLoaded;
- yield checkBookmark(uri, title);
- }
-
- // Network failure test: now that dummy_page.html is in history, bookmarking
- // it should give the last known page title as the default bookmark title.
-
- // Simulate a network outage with offline mode. (Localhost is still
- // accessible in offline mode, so disable the test proxy as well.)
- BrowserOffline.toggleOfflineStatus();
- let proxy = Services.prefs.getIntPref('network.proxy.type');
- Services.prefs.setIntPref('network.proxy.type', 0);
- registerCleanupFunction(function () {
- BrowserOffline.toggleOfflineStatus();
- Services.prefs.setIntPref('network.proxy.type', proxy);
- });
-
- // LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
- Services.cache2.clear();
-
- let [uri, title] = tests[0];
-
- let promiseLoaded = promisePageLoaded(browser);
- BrowserTestUtils.loadURI(browser, uri);
- yield promiseLoaded;
-
- // The offline mode test is only good if the page failed to load.
- yield ContentTask.spawn(browser, null, function() {
- is(content.document.documentURI.substring(0, 14), 'about:neterror',
- "Offline mode successfully simulated network outage.");
- });
- yield checkBookmark(uri, title);
-
- gBrowser.removeCurrentTab();
-});
-
-// Bookmark the current page and confirm that the new bookmark has the expected
-// title. (Then delete the bookmark.)
-function* checkBookmark(uri, expected_title) {
- is(gBrowser.selectedBrowser.currentURI.spec, uri,
- "Trying to bookmark the expected uri");
-
- let promiseBookmark = promiseOnBookmarkItemAdded(gBrowser.selectedBrowser.currentURI);
- PlacesCommandHook.bookmarkCurrentPage(false);
- yield promiseBookmark;
-
- let id = PlacesUtils.getMostRecentBookmarkForURI(PlacesUtils._uri(uri));
- ok(id > 0, "Found the expected bookmark");
- let title = PlacesUtils.bookmarks.getItemTitle(id);
- is(title, expected_title, "Bookmark got a good default title.");
-
- PlacesUtils.bookmarks.removeItem(id);
-}
-
-// BrowserTestUtils.browserLoaded doesn't work for the about pages, so use a
-// custom page load listener.
-function promisePageLoaded(browser)
-{
- return ContentTask.spawn(browser, null, function* () {
- yield ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", true,
- (event) => {
- return event.originalTarget === content.document &&
- event.target.location.href !== "about:blank"
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_bug1015721.js b/browser/base/content/test/general/browser_bug1015721.js
deleted file mode 100644
index e3e715396..000000000
--- a/browser/base/content/test/general/browser_bug1015721.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const TEST_PAGE = "http://example.org/browser/browser/base/content/test/general/zoom_test.html";
-
-var gTab1, gTab2, gLevel1;
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- gTab1 = gBrowser.addTab();
- gTab2 = gBrowser.addTab();
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- yield FullZoomHelper.load(gTab1, TEST_PAGE);
- yield FullZoomHelper.load(gTab2, TEST_PAGE);
- }).then(zoomTab1, FullZoomHelper.failAndContinue(finish));
-}
-
-function zoomTab1() {
- Task.spawn(function* () {
- is(gBrowser.selectedTab, gTab1, "Tab 1 is selected");
- FullZoomHelper.zoomTest(gTab1, 1, "Initial zoom of tab 1 should be 1");
- FullZoomHelper.zoomTest(gTab2, 1, "Initial zoom of tab 2 should be 1");
-
- let browser1 = gBrowser.getBrowserForTab(gTab1);
- yield BrowserTestUtils.synthesizeMouse(null, 10, 10, {
- wheel: true, ctrlKey: true, deltaY: -1, deltaMode: WheelEvent.DOM_DELTA_LINE
- }, browser1);
-
- info("Waiting for tab 1 to be zoomed");
- yield promiseWaitForCondition(() => {
- gLevel1 = ZoomManager.getZoomForBrowser(browser1);
- return gLevel1 > 1;
- });
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab2);
- FullZoomHelper.zoomTest(gTab2, gLevel1, "Tab 2 should have zoomed along with tab 1");
- }).then(finishTest, FullZoomHelper.failAndContinue(finish));
-}
-
-function finishTest() {
- Task.spawn(function* () {
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab1);
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab2);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab2);
- }).then(finish, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug1045809.js b/browser/base/content/test/general/browser_bug1045809.js
deleted file mode 100644
index 63b6b06d5..000000000
--- a/browser/base/content/test/general/browser_bug1045809.js
+++ /dev/null
@@ -1,68 +0,0 @@
-// Test that the Mixed Content Doorhanger Action to re-enable protection works
-
-const PREF_ACTIVE = "security.mixed_content.block_active_content";
-
-var origBlockActive;
-
-add_task(function* () {
- registerCleanupFunction(function() {
- Services.prefs.setBoolPref(PREF_ACTIVE, origBlockActive);
- gBrowser.removeCurrentTab();
- });
-
- // Store original preferences so we can restore settings after testing
- origBlockActive = Services.prefs.getBoolPref(PREF_ACTIVE);
-
- // Make sure mixed content blocking is on
- Services.prefs.setBoolPref(PREF_ACTIVE, true);
-
- var url =
- "https://test1.example.com/browser/browser/base/content/test/general/" +
- "file_bug1045809_1.html";
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- // Test 1: mixed content must be blocked
- yield promiseTabLoadEvent(tab, url);
- yield* test1(gBrowser.getBrowserForTab(tab));
-
- yield promiseTabLoadEvent(tab);
- // Test 2: mixed content must NOT be blocked
- yield* test2(gBrowser.getBrowserForTab(tab));
-
- // Test 3: mixed content must be blocked again
- yield promiseTabLoadEvent(tab);
- yield* test3(gBrowser.getBrowserForTab(tab));
-});
-
-function* test1(gTestBrowser) {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- var x = content.document.getElementsByTagName("iframe")[0].contentDocument.getElementById("mixedContentContainer");
- is(x, null, "Mixed Content is NOT to be found in Test1");
- });
-
- // Disable Mixed Content Protection for the page (and reload)
- gIdentityHandler.disableMixedContentProtection();
-}
-
-function* test2(gTestBrowser) {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: false});
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- var x = content.document.getElementsByTagName("iframe")[0].contentDocument.getElementById("mixedContentContainer");
- isnot(x, null, "Mixed Content is to be found in Test2");
- });
-
- // Re-enable Mixed Content Protection for the page (and reload)
- gIdentityHandler.enableMixedContentProtection();
-}
-
-function* test3(gTestBrowser) {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- var x = content.document.getElementsByTagName("iframe")[0].contentDocument.getElementById("mixedContentContainer");
- is(x, null, "Mixed Content is NOT to be found in Test3");
- });
-}
diff --git a/browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js b/browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js
deleted file mode 100644
index 98e0e74db..000000000
--- a/browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-add_task(function* () {
- // Test that changing the URL in a pinned tab works correctly
-
- let TEST_LINK_INITIAL = "about:";
- let TEST_LINK_CHANGED = "about:support";
-
- let appTab = gBrowser.addTab(TEST_LINK_INITIAL);
- let browser = appTab.linkedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- gBrowser.pinTab(appTab);
- is(appTab.pinned, true, "Tab was successfully pinned");
-
- let initialTabsNo = gBrowser.tabs.length;
-
- let goButton = document.getElementById("urlbar-go-button");
- gBrowser.selectedTab = appTab;
- gURLBar.focus();
- gURLBar.value = TEST_LINK_CHANGED;
-
- goButton.click();
- yield BrowserTestUtils.browserLoaded(browser);
-
- is(appTab.linkedBrowser.currentURI.spec, TEST_LINK_CHANGED,
- "New page loaded in the app tab");
- is(gBrowser.tabs.length, initialTabsNo, "No additional tabs were opened");
-});
-
-registerCleanupFunction(function () {
- gBrowser.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/general/browser_bug1261299.js b/browser/base/content/test/general/browser_bug1261299.js
deleted file mode 100644
index 673ef2a0a..000000000
--- a/browser/base/content/test/general/browser_bug1261299.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests for Bug 1261299
- * Test that the service menu code path is called properly and the
- * current selection (transferable) is cached properly on the parent process.
- */
-
-add_task(function* test_content_and_chrome_selection()
-{
- let testPage =
- 'data:text/html,' +
- '<textarea id="textarea">Write something here</textarea>';
- let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
- let selectedText;
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage);
- yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, gBrowser.selectedBrowser);
- yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
- {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
- selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
- is(selectedText, "Write something here", "The macOS services got the selected content text");
-
- gURLBar.value = "test.mozilla.org";
- yield gURLBar.focus();
- yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
- {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
- selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
- is(selectedText, "test.mozilla.org", "The macOS services got the selected chrome text");
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-// Test switching active selection.
-// Each tab has a content selection and when you switch to that tab, its selection becomes
-// active aka the current selection.
-// Expect: The active selection is what is being sent to OSX service menu.
-
-add_task(function* test_active_selection_switches_properly()
-{
- let testPage1 =
- 'data:text/html,' +
- '<textarea id="textarea">Write something here</textarea>';
- let testPage2 =
- 'data:text/html,' +
- '<textarea id="textarea">Nothing available</textarea>';
- let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
- let selectedText;
-
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage1);
- yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, gBrowser.selectedBrowser);
- yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
- {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
-
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2);
- yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, gBrowser.selectedBrowser);
- yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
- {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
-
- yield BrowserTestUtils.switchTab(gBrowser, tab1);
- selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
- is(selectedText, "Write something here", "The macOS services got the selected content text");
-
- yield BrowserTestUtils.switchTab(gBrowser, tab2);
- selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
- is(selectedText, "Nothing available", "The macOS services got the selected content text");
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/base/content/test/general/browser_bug1297539.js b/browser/base/content/test/general/browser_bug1297539.js
deleted file mode 100644
index d7e675437..000000000
--- a/browser/base/content/test/general/browser_bug1297539.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Test for Bug 1297539
- * Test that the content event "pasteTransferable"
- * (mozilla::EventMessage::eContentCommandPasteTransferable)
- * is handled correctly for plain text and html in the remote case.
- *
- * Original test test_bug525389.html for command content event
- * "pasteTransferable" runs only in the content process.
- * This doesn't test the remote case.
- *
- */
-
-"use strict";
-
-function getLoadContext() {
- return window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsILoadContext);
-}
-
-function getTransferableFromClipboard(asHTML) {
- let trans = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- trans.init(getLoadContext());
- if (asHTML) {
- trans.addDataFlavor("text/html");
- } else {
- trans.addDataFlavor("text/unicode");
- }
- let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
- clip.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
- return trans;
-}
-
-function* cutCurrentSelection(elementQueryString, property, browser) {
- // Cut the current selection.
- yield BrowserTestUtils.synthesizeKey("x", {accelKey: true}, browser);
-
- // The editor should be empty after cut.
- yield ContentTask.spawn(browser, [elementQueryString, property],
- function* ([contentElementQueryString, contentProperty]) {
- let element = content.document.querySelector(contentElementQueryString);
- is(element[contentProperty], "",
- `${contentElementQueryString} should be empty after cut (superkey + x)`);
- });
-}
-
-// Test that you are able to pasteTransferable for plain text
-// which is handled by TextEditor::PasteTransferable to paste into the editor.
-add_task(function* test_paste_transferable_plain_text()
-{
- let testPage =
- 'data:text/html,' +
- '<textarea id="textarea">Write something here</textarea>';
-
- yield BrowserTestUtils.withNewTab(testPage, function* (browser) {
- // Select all the content in your editor element.
- yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, browser);
- yield BrowserTestUtils.synthesizeKey("a", {accelKey: true}, browser);
-
- yield* cutCurrentSelection("#textarea", "value", browser);
-
- let trans = getTransferableFromClipboard(false);
- let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
- DOMWindowUtils.sendContentCommandEvent("pasteTransferable", trans);
-
- yield ContentTask.spawn(browser, null, function* () {
- let textArea = content.document.querySelector('#textarea');
- is(textArea.value, "Write something here",
- "Send content command pasteTransferable successful");
- });
- });
-});
-
-// Test that you are able to pasteTransferable for html
-// which is handled by HTMLEditor::PasteTransferable to paste into the editor.
-//
-// On Linux,
-// BrowserTestUtils.synthesizeKey("a", {accelKey: true}, browser);
-// doesn't seem to trigger for contenteditable which is why we use
-// Selection to select the contenteditable contents.
-add_task(function* test_paste_transferable_html()
-{
- let testPage =
- 'data:text/html,' +
- '<div contenteditable="true"><b>Bold Text</b><i>italics</i></div>';
-
- yield BrowserTestUtils.withNewTab(testPage, function* (browser) {
- // Select all the content in your editor element.
- yield BrowserTestUtils.synthesizeMouse("div", 0, 0, {}, browser);
- yield ContentTask.spawn(browser, {}, function* () {
- let element = content.document.querySelector("div");
- let selection = content.window.getSelection();
- selection.selectAllChildren(element);
- });
-
- yield* cutCurrentSelection("div", "textContent", browser);
-
- let trans = getTransferableFromClipboard(true);
- let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
- DOMWindowUtils.sendContentCommandEvent("pasteTransferable", trans);
-
- yield ContentTask.spawn(browser, null, function* () {
- let textArea = content.document.querySelector('div');
- is(textArea.innerHTML, "<b>Bold Text</b><i>italics</i>",
- "Send content command pasteTransferable successful");
- });
- });
-});
diff --git a/browser/base/content/test/general/browser_bug1299667.js b/browser/base/content/test/general/browser_bug1299667.js
deleted file mode 100644
index 084c8d49f..000000000
--- a/browser/base/content/test/general/browser_bug1299667.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const { addObserver, removeObserver } = Cc["@mozilla.org/observer-service;1"].
- getService(Ci.nsIObserverService);
-
-function receive(topic) {
- return new Promise((resolve, reject) => {
- let timeout = setTimeout(() => {
- reject(new Error("Timeout"));
- }, 90000);
-
- const observer = {
- observe: subject => {
- removeObserver(observer, topic);
- clearTimeout(timeout);
- resolve(subject);
- }
- };
- addObserver(observer, topic, false);
- });
-}
-
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- content.history.pushState({}, "2", "2.html");
- });
-
- yield receive("sessionstore-state-write-complete");
-
- // Wait for the session data to be flushed before continuing the test
- yield new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
-
- let backButton = document.getElementById("back-button");
- let contextMenu = document.getElementById("backForwardMenu");
-
- info("waiting for the history menu to open");
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- EventUtils.synthesizeMouseAtCenter(backButton, {type: "contextmenu", button: 2});
- let event = yield popupShownPromise;
-
- ok(true, "history menu opened");
-
- // Wait for the session data to be flushed before continuing the test
- yield new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
-
- is(event.target.children.length, 2, "Two history items");
-
- let node = event.target.firstChild;
- is(node.getAttribute("uri"), "http://example.com/2.html", "first item uri");
- is(node.getAttribute("index"), "1", "first item index");
- is(node.getAttribute("historyindex"), "0", "first item historyindex");
-
- node = event.target.lastChild;
- is(node.getAttribute("uri"), "http://example.com/", "second item uri");
- is(node.getAttribute("index"), "0", "second item index");
- is(node.getAttribute("historyindex"), "-1", "second item historyindex");
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- event.target.hidePopup();
- yield popupHiddenPromise;
- info("Hidden popup");
-
- let onClose = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield onClose;
- info("Tab closed");
-});
diff --git a/browser/base/content/test/general/browser_bug321000.js b/browser/base/content/test/general/browser_bug321000.js
deleted file mode 100644
index b30b7101d..000000000
--- a/browser/base/content/test/general/browser_bug321000.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const kTestString = " hello hello \n world\nworld ";
-
-var gTests = [
-
- { desc: "Urlbar strips newlines and surrounding whitespace",
- element: gURLBar,
- expected: kTestString.replace(/\s*\n\s*/g, '')
- },
-
- { desc: "Searchbar replaces newlines with spaces",
- element: document.getElementById('searchbar'),
- expected: kTestString.replace(/\n/g, ' ')
- },
-
-];
-
-// Test for bug 23485 and bug 321000.
-// Urlbar should strip newlines,
-// search bar should replace newlines with spaces.
-function test() {
- waitForExplicitFinish();
-
- let cbHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
- getService(Ci.nsIClipboardHelper);
-
- // Put a multi-line string in the clipboard.
- // Setting the clipboard value is an async OS operation, so we need to poll
- // the clipboard for valid data before going on.
- waitForClipboard(kTestString, function() { cbHelper.copyString(kTestString); },
- next_test, finish);
-}
-
-function next_test() {
- if (gTests.length)
- test_paste(gTests.shift());
- else
- finish();
-}
-
-function test_paste(aCurrentTest) {
- var element = aCurrentTest.element;
-
- // Register input listener.
- var inputListener = {
- test: aCurrentTest,
- handleEvent: function(event) {
- element.removeEventListener(event.type, this, false);
-
- is(element.value, this.test.expected, this.test.desc);
-
- // Clear the field and go to next test.
- element.value = "";
- setTimeout(next_test, 0);
- }
- }
- element.addEventListener("input", inputListener, false);
-
- // 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, false);
- 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 });
- });
- }, false);
- element.focus();
-}
diff --git a/browser/base/content/test/general/browser_bug356571.js b/browser/base/content/test/general/browser_bug356571.js
deleted file mode 100644
index ab689d0f8..000000000
--- a/browser/base/content/test/general/browser_bug356571.js
+++ /dev/null
@@ -1,93 +0,0 @@
-// Bug 356571 - loadOneOrMoreURIs gives up if one of the URLs has an unknown protocol
-
-var Cr = Components.results;
-var Cm = Components.manager;
-
-// Set to true when docShell alerts for unknown protocol error
-var didFail = false;
-
-// Override Alert to avoid blocking the test due to unknown protocol error
-const kPromptServiceUUID = "{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}";
-const kPromptServiceContractID = "@mozilla.org/embedcomp/prompt-service;1";
-
-// Save original prompt service factory
-const kPromptServiceFactory = Cm.getClassObject(Cc[kPromptServiceContractID],
- Ci.nsIFactory);
-
-var fakePromptServiceFactory = {
- createInstance: function(aOuter, aIid) {
- if (aOuter != null)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return promptService.QueryInterface(aIid);
- }
-};
-
-var promptService = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPromptService]),
- alert: function() {
- didFail = true;
- }
-};
-
-/* FIXME
-Cm.QueryInterface(Ci.nsIComponentRegistrar)
- .registerFactory(Components.ID(kPromptServiceUUID), "Prompt Service",
- kPromptServiceContractID, fakePromptServiceFactory);
-*/
-
-const kCompleteState = Ci.nsIWebProgressListener.STATE_STOP +
- Ci.nsIWebProgressListener.STATE_IS_NETWORK;
-
-const kDummyPage = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-const kURIs = [
- "bad://www.mozilla.org/",
- kDummyPage,
- kDummyPage,
-];
-
-var gProgressListener = {
- _runCount: 0,
- onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
- if ((aStateFlags & kCompleteState) == kCompleteState) {
- if (++this._runCount != kURIs.length)
- return;
- // Check we failed on unknown protocol (received an alert from docShell)
- ok(didFail, "Correctly failed on unknown protocol");
- // Check we opened all tabs
- ok(gBrowser.tabs.length == kURIs.length, "Correctly opened all expected tabs");
- finishTest();
- }
- }
-}
-
-function test() {
- todo(false, "temp. disabled");
- return; /* FIXME */
- /*
- waitForExplicitFinish();
- // Wait for all tabs to finish loading
- gBrowser.addTabsProgressListener(gProgressListener);
- loadOneOrMoreURIs(kURIs.join("|"));
- */
-}
-
-function finishTest() {
- // Unregister the factory so we do not leak
- Cm.QueryInterface(Ci.nsIComponentRegistrar)
- .unregisterFactory(Components.ID(kPromptServiceUUID),
- fakePromptServiceFactory);
-
- // Restore the original factory
- Cm.QueryInterface(Ci.nsIComponentRegistrar)
- .registerFactory(Components.ID(kPromptServiceUUID), "Prompt Service",
- kPromptServiceContractID, kPromptServiceFactory);
-
- // Remove the listener
- gBrowser.removeTabsProgressListener(gProgressListener);
-
- // Close opened tabs
- for (var i = gBrowser.tabs.length-1; i > 0; i--)
- gBrowser.removeTab(gBrowser.tabs[i]);
-
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug380960.js b/browser/base/content/test/general/browser_bug380960.js
deleted file mode 100644
index d6b64543b..000000000
--- a/browser/base/content/test/general/browser_bug380960.js
+++ /dev/null
@@ -1,11 +0,0 @@
-function test() {
- var tab = gBrowser.addTab("about:blank", { skipAnimation: true });
- gBrowser.removeTab(tab);
- is(tab.parentNode, null, "tab removed immediately");
-
- tab = gBrowser.addTab("about:blank", { skipAnimation: true });
- gBrowser.removeTab(tab, { animate: true });
- gBrowser.removeTab(tab);
- is(tab.parentNode, null, "tab removed immediately when calling removeTab again after the animation was kicked off");
-}
-
diff --git a/browser/base/content/test/general/browser_bug386835.js b/browser/base/content/test/general/browser_bug386835.js
deleted file mode 100644
index 1c3ba99c5..000000000
--- a/browser/base/content/test/general/browser_bug386835.js
+++ /dev/null
@@ -1,89 +0,0 @@
-var gTestPage = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-var gTestImage = "http://example.org/browser/browser/base/content/test/general/moz.png";
-var gTab1, gTab2, gTab3;
-var gLevel;
-const BACK = 0;
-const FORWARD = 1;
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- gTab1 = gBrowser.addTab(gTestPage);
- gTab2 = gBrowser.addTab();
- gTab3 = gBrowser.addTab();
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- yield FullZoomHelper.load(gTab1, gTestPage);
- yield FullZoomHelper.load(gTab2, gTestPage);
- }).then(secondPageLoaded, FullZoomHelper.failAndContinue(finish));
-}
-
-function secondPageLoaded() {
- Task.spawn(function* () {
- FullZoomHelper.zoomTest(gTab1, 1, "Initial zoom of tab 1 should be 1");
- FullZoomHelper.zoomTest(gTab2, 1, "Initial zoom of tab 2 should be 1");
- FullZoomHelper.zoomTest(gTab3, 1, "Initial zoom of tab 3 should be 1");
-
- // Now have three tabs, two with the test page, one blank. Tab 1 is selected
- // Zoom tab 1
- FullZoom.enlarge();
- gLevel = ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1));
-
- ok(gLevel > 1, "New zoom for tab 1 should be greater than 1");
- FullZoomHelper.zoomTest(gTab2, 1, "Zooming tab 1 should not affect tab 2");
- FullZoomHelper.zoomTest(gTab3, 1, "Zooming tab 1 should not affect tab 3");
-
- yield FullZoomHelper.load(gTab3, gTestPage);
- }).then(thirdPageLoaded, FullZoomHelper.failAndContinue(finish));
-}
-
-function thirdPageLoaded() {
- Task.spawn(function* () {
- FullZoomHelper.zoomTest(gTab1, gLevel, "Tab 1 should still be zoomed");
- FullZoomHelper.zoomTest(gTab2, 1, "Tab 2 should still not be affected");
- FullZoomHelper.zoomTest(gTab3, gLevel, "Tab 3 should have zoomed as it was loading in the background");
-
- // Switching to tab 2 should update its zoom setting.
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab2);
- FullZoomHelper.zoomTest(gTab1, gLevel, "Tab 1 should still be zoomed");
- FullZoomHelper.zoomTest(gTab2, gLevel, "Tab 2 should be zoomed now");
- FullZoomHelper.zoomTest(gTab3, gLevel, "Tab 3 should still be zoomed");
-
- yield FullZoomHelper.load(gTab1, gTestImage);
- }).then(imageLoaded, FullZoomHelper.failAndContinue(finish));
-}
-
-function imageLoaded() {
- Task.spawn(function* () {
- FullZoomHelper.zoomTest(gTab1, 1, "Zoom should be 1 when image was loaded in the background");
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- FullZoomHelper.zoomTest(gTab1, 1, "Zoom should still be 1 when tab with image is selected");
- }).then(imageZoomSwitch, FullZoomHelper.failAndContinue(finish));
-}
-
-function imageZoomSwitch() {
- Task.spawn(function* () {
- yield FullZoomHelper.navigate(BACK);
- yield FullZoomHelper.navigate(FORWARD);
- FullZoomHelper.zoomTest(gTab1, 1, "Tab 1 should not be zoomed when an image loads");
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab2);
- FullZoomHelper.zoomTest(gTab1, 1, "Tab 1 should still not be zoomed when deselected");
- }).then(finishTest, FullZoomHelper.failAndContinue(finish));
-}
-
-var finishTestStarted = false;
-function finishTest() {
- Task.spawn(function* () {
- ok(!finishTestStarted, "finishTest called more than once");
- finishTestStarted = true;
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab1);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab2);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab3);
- }).then(finish, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug406216.js b/browser/base/content/test/general/browser_bug406216.js
deleted file mode 100644
index e1bd38395..000000000
--- a/browser/base/content/test/general/browser_bug406216.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * "TabClose" event is possibly used for closing related tabs of the current.
- * "removeTab" method should work correctly even if the number of tabs are
- * changed while "TabClose" event.
- */
-
-var count = 0;
-const URIS = ["about:config",
- "about:plugins",
- "about:buildconfig",
- "data:text/html,<title>OK</title>"];
-
-function test() {
- waitForExplicitFinish();
- URIS.forEach(addTab);
-}
-
-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);
-}
-
-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);
-
- 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();
-}
diff --git a/browser/base/content/test/general/browser_bug408415.js b/browser/base/content/test/general/browser_bug408415.js
deleted file mode 100644
index d8f80f8be..000000000
--- a/browser/base/content/test/general/browser_bug408415.js
+++ /dev/null
@@ -1,45 +0,0 @@
-add_task(function* test() {
- let testPath = getRootDirectory(gTestPath);
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (tabBrowser) {
- const URI = testPath + "file_with_favicon.html";
- const expectedIcon = testPath + "file_generic_favicon.ico";
-
- let got_favicon = Promise.defer();
- let listener = {
- onLinkIconAvailable(browser, iconURI) {
- if (got_favicon && iconURI && browser === tabBrowser) {
- got_favicon.resolve(iconURI);
- got_favicon = null;
- }
- }
- };
- gBrowser.addTabsProgressListener(listener);
-
- BrowserTestUtils.loadURI(tabBrowser, URI);
-
- let iconURI = yield got_favicon.promise;
- is(iconURI, expectedIcon, "Correct icon before pushState.");
-
- got_favicon = Promise.defer();
- got_favicon.promise.then(() => { ok(false, "shouldn't be called"); }, (e) => e);
- yield ContentTask.spawn(tabBrowser, null, function() {
- content.location.href += "#foo";
- });
-
- // We've navigated and shouldn't get a call to onLinkIconAvailable.
- TestUtils.executeSoon(() => {
- got_favicon.reject(gBrowser.getIcon(gBrowser.getTabForBrowser(tabBrowser)));
- });
- try {
- yield got_favicon.promise;
- } catch (e) {
- iconURI = e;
- }
- is(iconURI, expectedIcon, "Correct icon after pushState.");
-
- gBrowser.removeTabsProgressListener(listener);
- });
-});
-
diff --git a/browser/base/content/test/general/browser_bug409481.js b/browser/base/content/test/general/browser_bug409481.js
deleted file mode 100644
index 395ad93d4..000000000
--- a/browser/base/content/test/general/browser_bug409481.js
+++ /dev/null
@@ -1,83 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- // XXX This looks a bit odd, but is needed to avoid throwing when removing the
- // event listeners below. See bug 310955.
- document.getElementById("sidebar").addEventListener("load", delayedOpenUrl, true);
- SidebarUI.show("viewWebPanelsSidebar");
-}
-
-function delayedOpenUrl() {
- ok(true, "Ran delayedOpenUrl");
- setTimeout(openPanelUrl, 100);
-}
-
-function openPanelUrl(event) {
- ok(!document.getElementById("sidebar-box").hidden, "Sidebar showing");
-
- var sidebar = document.getElementById("sidebar");
- var root = sidebar.contentDocument.documentElement;
- ok(root.nodeName != "parsererror", "Sidebar is well formed");
-
- sidebar.removeEventListener("load", delayedOpenUrl, true);
- // XXX See comment above
- sidebar.contentDocument.addEventListener("load", delayedRunTest, true);
- var url = 'data:text/html,<div%20id="test_bug409481">Content!</div><a id="link" href="http://www.example.com/ctest">Link</a><input id="textbox">';
- sidebar.contentWindow.loadWebPanel(url);
-}
-
-function delayedRunTest() {
- ok(true, "Ran delayedRunTest");
- setTimeout(runTest, 100);
-}
-
-function runTest(event) {
- var sidebar = document.getElementById("sidebar");
- sidebar.contentDocument.removeEventListener("load", delayedRunTest, true);
-
- var browser = sidebar.contentDocument.getElementById("web-panels-browser");
- var div = browser && browser.contentDocument.getElementById("test_bug409481");
- ok(div && div.textContent == "Content!", "Sidebar content loaded");
-
- var link = browser && browser.contentDocument.getElementById("link");
- sidebar.contentDocument.addEventListener("popupshown", contextMenuOpened, false);
-
- EventUtils.synthesizeMouseAtCenter(link, { type: "contextmenu", button: 2 }, browser.contentWindow);
-}
-
-function contextMenuOpened()
-{
- var sidebar = document.getElementById("sidebar");
- sidebar.contentDocument.removeEventListener("popupshown", contextMenuOpened, false);
-
- var copyLinkCommand = sidebar.contentDocument.getElementById("context-copylink");
- copyLinkCommand.addEventListener("command", copyLinkCommandExecuted, false);
- copyLinkCommand.doCommand();
-}
-
-function copyLinkCommandExecuted(event)
-{
- event.target.removeEventListener("command", copyLinkCommandExecuted, false);
-
- var sidebar = document.getElementById("sidebar");
- var browser = sidebar.contentDocument.getElementById("web-panels-browser");
- var textbox = browser && browser.contentDocument.getElementById("textbox");
- textbox.focus();
- document.commandDispatcher.getControllerForCommand("cmd_paste").doCommand("cmd_paste");
- is(textbox.value, "http://www.example.com/ctest", "copy link command");
-
- sidebar.contentDocument.addEventListener("popuphidden", contextMenuClosed, false);
- event.target.parentNode.hidePopup();
-}
-
-function contextMenuClosed()
-{
- var sidebar = document.getElementById("sidebar");
- sidebar.contentDocument.removeEventListener("popuphidden", contextMenuClosed, false);
-
- SidebarUI.hide();
-
- ok(document.getElementById("sidebar-box").hidden, "Sidebar successfully hidden");
-
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug409624.js b/browser/base/content/test/general/browser_bug409624.js
deleted file mode 100644
index 8e46ec0c2..000000000
--- a/browser/base/content/test/general/browser_bug409624.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
- "resource://gre/modules/FormHistory.jsm");
-
-add_task(function* test() {
- // This test relies on the form history being empty to start with delete
- // all the items first.
- yield new Promise((resolve, reject) => {
- FormHistory.update({ op: "remove" },
- { handleError(error) {
- reject(error);
- },
- handleCompletion(reason) {
- if (!reason) {
- resolve();
- } else {
- reject();
- }
- },
- });
- });
-
- let prefService = Cc["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
-
- let tempScope = {};
- Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
- let Sanitizer = tempScope.Sanitizer;
- let s = new Sanitizer();
- s.prefDomain = "privacy.cpd.";
- let prefBranch = prefService.getBranch(s.prefDomain);
-
- prefBranch.setBoolPref("cache", false);
- prefBranch.setBoolPref("cookies", false);
- prefBranch.setBoolPref("downloads", false);
- prefBranch.setBoolPref("formdata", true);
- prefBranch.setBoolPref("history", false);
- prefBranch.setBoolPref("offlineApps", false);
- prefBranch.setBoolPref("passwords", false);
- prefBranch.setBoolPref("sessions", false);
- prefBranch.setBoolPref("siteSettings", false);
-
- // Sanitize now so we can test the baseline point.
- yield s.sanitize();
- ok(!gFindBar.hasTransactions, "pre-test baseline for sanitizer");
-
- gFindBar.getElement("findbar-textbox").value = "m";
- ok(gFindBar.hasTransactions, "formdata can be cleared after input");
-
- yield s.sanitize();
- is(gFindBar.getElement("findbar-textbox").value, "", "findBar textbox should be empty after sanitize");
- ok(!gFindBar.hasTransactions, "No transactions after sanitize");
-});
diff --git a/browser/base/content/test/general/browser_bug413915.js b/browser/base/content/test/general/browser_bug413915.js
deleted file mode 100644
index 86c94c427..000000000
--- a/browser/base/content/test/general/browser_bug413915.js
+++ /dev/null
@@ -1,62 +0,0 @@
-XPCOMUtils.defineLazyModuleGetter(this, "Feeds",
- "resource:///modules/Feeds.jsm");
-
-function test() {
- var exampleUri = makeURI("http://example.com/");
- var secman = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
- var principal = secman.createCodebasePrincipal(exampleUri, {});
-
- function testIsFeed(aTitle, aHref, aType, aKnown) {
- var link = { title: aTitle, href: aHref, type: aType };
- return Feeds.isValidFeed(link, principal, aKnown);
- }
-
- var href = "http://example.com/feed/";
- var atomType = "application/atom+xml";
- var funkyAtomType = " aPPLICAtion/Atom+XML ";
- var rssType = "application/rss+xml";
- var funkyRssType = " Application/RSS+XML ";
- var rdfType = "application/rdf+xml";
- var texmlType = "text/xml";
- var appxmlType = "application/xml";
- var noRss = "Foo";
- var rss = "RSS";
-
- // things that should be valid
- ok(testIsFeed(noRss, href, atomType, false) == atomType,
- "detect Atom feed");
- ok(testIsFeed(noRss, href, funkyAtomType, false) == atomType,
- "clean up and detect Atom feed");
- ok(testIsFeed(noRss, href, rssType, false) == rssType,
- "detect RSS feed");
- ok(testIsFeed(noRss, href, funkyRssType, false) == rssType,
- "clean up and detect RSS feed");
-
- // things that should not be feeds
- ok(testIsFeed(noRss, href, rdfType, false) == null,
- "should not detect RDF non-feed");
- ok(testIsFeed(rss, href, rdfType, false) == null,
- "should not detect RDF feed from type and title");
- ok(testIsFeed(noRss, href, texmlType, false) == null,
- "should not detect text/xml non-feed");
- ok(testIsFeed(rss, href, texmlType, false) == null,
- "should not detect text/xml feed from type and title");
- ok(testIsFeed(noRss, href, appxmlType, false) == null,
- "should not detect application/xml non-feed");
- ok(testIsFeed(rss, href, appxmlType, false) == null,
- "should not detect application/xml feed from type and title");
-
- // security check only, returns cleaned up type or "application/rss+xml"
- ok(testIsFeed(noRss, href, atomType, true) == atomType,
- "feed security check should return Atom type");
- ok(testIsFeed(noRss, href, funkyAtomType, true) == atomType,
- "feed security check should return cleaned up Atom type");
- ok(testIsFeed(noRss, href, rssType, true) == rssType,
- "feed security check should return RSS type");
- ok(testIsFeed(noRss, href, funkyRssType, true) == rssType,
- "feed security check should return cleaned up RSS type");
- ok(testIsFeed(noRss, href, "", true) == rssType,
- "feed security check without type should return RSS type");
- ok(testIsFeed(noRss, href, "garbage", true) == "garbage",
- "feed security check with garbage type should return garbage");
-}
diff --git a/browser/base/content/test/general/browser_bug416661.js b/browser/base/content/test/general/browser_bug416661.js
deleted file mode 100644
index a37971a34..000000000
--- a/browser/base/content/test/general/browser_bug416661.js
+++ /dev/null
@@ -1,43 +0,0 @@
-var tabElm, zoomLevel;
-function start_test_prefNotSet() {
- Task.spawn(function* () {
- is(ZoomManager.zoom, 1, "initial zoom level should be 1");
- FullZoom.enlarge();
-
- // capture the zoom level to test later
- zoomLevel = ZoomManager.zoom;
- isnot(zoomLevel, 1, "zoom level should have changed");
-
- yield FullZoomHelper.load(gBrowser.selectedTab, "http://mochi.test:8888/browser/browser/base/content/test/general/moz.png");
- }).then(continue_test_prefNotSet, FullZoomHelper.failAndContinue(finish));
-}
-
-function continue_test_prefNotSet () {
- Task.spawn(function* () {
- is(ZoomManager.zoom, 1, "zoom level pref should not apply to an image");
- yield FullZoom.reset();
-
- yield FullZoomHelper.load(gBrowser.selectedTab, "http://mochi.test:8888/browser/browser/base/content/test/general/zoom_test.html");
- }).then(end_test_prefNotSet, FullZoomHelper.failAndContinue(finish));
-}
-
-function end_test_prefNotSet() {
- Task.spawn(function* () {
- is(ZoomManager.zoom, zoomLevel, "the zoom level should have persisted");
-
- // Reset the zoom so that other tests have a fresh zoom level
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange();
- finish();
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- tabElm = gBrowser.addTab();
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tabElm);
- yield FullZoomHelper.load(tabElm, "http://mochi.test:8888/browser/browser/base/content/test/general/zoom_test.html");
- }).then(start_test_prefNotSet, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug417483.js b/browser/base/content/test/general/browser_bug417483.js
deleted file mode 100644
index 43ff7b917..000000000
--- a/browser/base/content/test/general/browser_bug417483.js
+++ /dev/null
@@ -1,30 +0,0 @@
-add_task(function* () {
- let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, true);
- const htmlContent = "data:text/html, <iframe src='data:text/html,text text'></iframe>";
- gBrowser.loadURI(htmlContent);
- yield loadedPromise;
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
- let frame = content.frames[0];
- let sel = frame.getSelection();
- let range = frame.document.createRange();
- let tn = frame.document.body.childNodes[0];
- range.setStart(tn, 4);
- range.setEnd(tn, 5);
- sel.addRange(range);
- frame.focus();
- });
-
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouse("frame", 5, 5,
- { type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
- yield popupShownPromise;
-
- ok(document.getElementById("frame-sep").hidden, "'frame-sep' should be hidden if the selection contains only spaces");
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- contentAreaContextMenu.hidePopup();
- yield popupHiddenPromise;
-});
diff --git a/browser/base/content/test/general/browser_bug419612.js b/browser/base/content/test/general/browser_bug419612.js
deleted file mode 100644
index 8c34b2d39..000000000
--- a/browser/base/content/test/general/browser_bug419612.js
+++ /dev/null
@@ -1,32 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- let testPage = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
- let tab1 = gBrowser.addTab();
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab1);
- yield FullZoomHelper.load(tab1, testPage);
-
- let tab2 = gBrowser.addTab();
- yield FullZoomHelper.load(tab2, testPage);
-
- FullZoom.enlarge();
- let tab1Zoom = ZoomManager.getZoomForBrowser(tab1.linkedBrowser);
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab2);
- let tab2Zoom = ZoomManager.getZoomForBrowser(tab2.linkedBrowser);
- is(tab2Zoom, tab1Zoom, "Zoom should affect background tabs");
-
- gPrefService.setBoolPref("browser.zoom.updateBackgroundTabs", false);
- yield FullZoom.reset();
- gBrowser.selectedTab = tab1;
- tab1Zoom = ZoomManager.getZoomForBrowser(tab1.linkedBrowser);
- tab2Zoom = ZoomManager.getZoomForBrowser(tab2.linkedBrowser);
- isnot(tab1Zoom, tab2Zoom, "Zoom should not affect background tabs");
-
- if (gPrefService.prefHasUserValue("browser.zoom.updateBackgroundTabs"))
- gPrefService.clearUserPref("browser.zoom.updateBackgroundTabs");
- yield FullZoomHelper.removeTabAndWaitForLocationChange(tab1);
- yield FullZoomHelper.removeTabAndWaitForLocationChange(tab2);
- }).then(finish, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug422590.js b/browser/base/content/test/general/browser_bug422590.js
deleted file mode 100644
index f26919cc5..000000000
--- a/browser/base/content/test/general/browser_bug422590.js
+++ /dev/null
@@ -1,50 +0,0 @@
-function test() {
- waitForExplicitFinish();
- // test the main (normal) browser window
- testCustomize(window, testChromeless);
-}
-
-function testChromeless() {
- // test a chromeless window
- var newWin = openDialog(getBrowserURL(), "_blank",
- "chrome,dialog=no,location=yes,toolbar=no", "about:blank");
- ok(newWin, "got new window");
-
- whenDelayedStartupFinished(newWin, function () {
- // Check that the search bar is hidden
- var searchBar = newWin.BrowserSearch.searchBar;
- ok(searchBar, "got search bar");
-
- var searchBarBO = searchBar.boxObject;
- is(searchBarBO.width, 0, "search bar hidden");
- is(searchBarBO.height, 0, "search bar hidden");
-
- testCustomize(newWin, function () {
- newWin.close();
- finish();
- });
- });
-}
-
-function testCustomize(aWindow, aCallback) {
- var fileMenu = aWindow.document.getElementById("file-menu");
- ok(fileMenu, "got file menu");
- is(fileMenu.disabled, false, "file menu initially enabled");
-
- openToolbarCustomizationUI(function () {
- // Can't use the property, since the binding may have since been removed
- // if the element is hidden (see bug 422590)
- is(fileMenu.getAttribute("disabled"), "true",
- "file menu is disabled during toolbar customization");
-
- closeToolbarCustomizationUI(onClose, aWindow);
- }, aWindow);
-
- function onClose() {
- is(fileMenu.getAttribute("disabled"), "false",
- "file menu is enabled after toolbar customization");
-
- if (aCallback)
- aCallback();
- }
-}
diff --git a/browser/base/content/test/general/browser_bug423833.js b/browser/base/content/test/general/browser_bug423833.js
deleted file mode 100644
index d4069338b..000000000
--- a/browser/base/content/test/general/browser_bug423833.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Tests for proper behaviour of "Show this frame" context menu options */
-
-// Two frames, one with text content, the other an error page
-var invalidPage = 'http://127.0.0.1:55555/';
-var validPage = 'http://example.com/';
-var testPage = 'data:text/html,<frameset cols="400,400"><frame src="' + validPage + '"><frame src="' + invalidPage + '"></frameset>';
-
-// Store the tab and window created in tests 2 and 3 respectively
-var test2tab;
-var test3window;
-
-// We use setInterval instead of setTimeout to avoid race conditions on error doc loads
-var intervalID;
-
-function test() {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.selectedBrowser.addEventListener("load", test1Setup, true);
- content.location = testPage;
-}
-
-function test1Setup() {
- if (content.frames.length < 2 ||
- content.frames[1].location != invalidPage)
- // The error frame hasn't loaded yet
- return;
-
- gBrowser.selectedBrowser.removeEventListener("load", test1Setup, true);
-
- var badFrame = content.frames[1];
- document.popupNode = badFrame.document.firstChild;
-
- var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- var contextMenu = new nsContextMenu(contentAreaContextMenu);
-
- // We'd like to use another load listener here, but error pages don't fire load events
- contextMenu.showOnlyThisFrame();
- intervalID = setInterval(testShowOnlyThisFrame, 3000);
-}
-
-function testShowOnlyThisFrame() {
- if (content.location.href == testPage)
- // This is a stale event from the original page loading
- return;
-
- // We should now have loaded the error page frame content directly
- // in the tab, make sure the URL is right.
- clearInterval(intervalID);
-
- is(content.location.href, invalidPage, "Should navigate to page url, not about:neterror");
-
- // Go back to the frames page
- gBrowser.addEventListener("load", test2Setup, true);
- content.location = testPage;
-}
-
-function test2Setup() {
- if (content.frames.length < 2 ||
- content.frames[1].location != invalidPage)
- // The error frame hasn't loaded yet
- return;
-
- gBrowser.removeEventListener("load", test2Setup, true);
-
- // Now let's do the whole thing again, but this time for "Open frame in new tab"
- var badFrame = content.frames[1];
-
- document.popupNode = badFrame.document.firstChild;
-
- var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- var contextMenu = new nsContextMenu(contentAreaContextMenu);
-
- gBrowser.tabContainer.addEventListener("TabOpen", function (event) {
- test2tab = event.target;
- gBrowser.tabContainer.removeEventListener("TabOpen", arguments.callee, false);
- }, false);
- contextMenu.openFrameInTab();
- ok(test2tab, "openFrameInTab() opened a tab");
-
- gBrowser.selectedTab = test2tab;
-
- intervalID = setInterval(testOpenFrameInTab, 3000);
-}
-
-function testOpenFrameInTab() {
- if (gBrowser.contentDocument.location.href == "about:blank")
- // Wait another cycle
- return;
-
- clearInterval(intervalID);
-
- // We should now have the error page in a new, active tab.
- is(gBrowser.contentDocument.location.href, invalidPage, "New tab should have page url, not about:neterror");
-
- // Clear up the new tab, and punt to test 3
- gBrowser.removeCurrentTab();
-
- test3Setup();
-}
-
-function test3Setup() {
- // One more time, for "Open frame in new window"
- var badFrame = content.frames[1];
- document.popupNode = badFrame.document.firstChild;
-
- var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- var contextMenu = new nsContextMenu(contentAreaContextMenu);
-
- Services.ww.registerNotification(function (aSubject, aTopic, aData) {
- if (aTopic == "domwindowopened")
- test3window = aSubject;
- Services.ww.unregisterNotification(arguments.callee);
- });
-
- contextMenu.openFrame();
-
- intervalID = setInterval(testOpenFrame, 3000);
-}
-
-function testOpenFrame() {
- if (!test3window || test3window.content.location.href == "about:blank") {
- info("testOpenFrame: Wait another cycle");
- return;
- }
-
- clearInterval(intervalID);
-
- is(test3window.content.location.href, invalidPage, "New window should have page url, not about:neterror");
-
- test3window.close();
- cleanup();
-}
-
-function cleanup() {
- gBrowser.removeCurrentTab();
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug424101.js b/browser/base/content/test/general/browser_bug424101.js
deleted file mode 100644
index 8000d2ae9..000000000
--- a/browser/base/content/test/general/browser_bug424101.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Make sure that the context menu appears on form elements */
-
-add_task(function *() {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/html,test");
-
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
-
- let tests = [
- { element: "input", type: "text" },
- { element: "input", type: "password" },
- { element: "input", type: "image" },
- { element: "input", type: "button" },
- { element: "input", type: "submit" },
- { element: "input", type: "reset" },
- { element: "input", type: "checkbox" },
- { element: "input", type: "radio" },
- { element: "button" },
- { element: "select" },
- { element: "option" },
- { element: "optgroup" }
- ];
-
- for (let index = 0; index < tests.length; index++) {
- let test = tests[index];
-
- yield ContentTask.spawn(gBrowser.selectedBrowser,
- { element: test.element, type: test.type, index: index },
- function* (arg) {
- let element = content.document.createElement(arg.element);
- element.id = "element" + arg.index;
- if (arg.type) {
- element.setAttribute("type", arg.type);
- }
- content.document.body.appendChild(element);
- });
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouseAtCenter("#element" + index,
- { type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
- yield popupShownPromise;
-
- let typeAttr = test.type ? "type=" + test.type + " " : "";
- is(gContextMenu.shouldDisplay, true,
- "context menu behavior for <" + test.element + " " + typeAttr + "> is wrong");
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- contentAreaContextMenu.hidePopup();
- yield popupHiddenPromise;
- }
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug427559.js b/browser/base/content/test/general/browser_bug427559.js
deleted file mode 100644
index 78cecdefa..000000000
--- a/browser/base/content/test/general/browser_bug427559.js
+++ /dev/null
@@ -1,38 +0,0 @@
-"use strict";
-
-/*
- * Test bug 427559 to make sure focused elements that are no longer on the page
- * will have focus transferred to the window when changing tabs back to that
- * tab with the now-gone element.
- */
-
-// Default focus on a button and have it kill itself on blur.
-const URL = 'data:text/html;charset=utf-8,' +
- '<body><button onblur="this.remove()">' +
- '<script>document.body.firstChild.focus()</script></body>';
-
-function getFocusedLocalName(browser) {
- return ContentTask.spawn(browser, null, function* () {
- return content.document.activeElement.localName;
- });
-}
-
-add_task(function* () {
- let testTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
-
- let browser = testTab.linkedBrowser;
-
- is((yield getFocusedLocalName(browser)), "button", "button is focused");
-
- let blankTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- yield BrowserTestUtils.switchTab(gBrowser, testTab);
-
- // Make sure focus is given to the window because the element is now gone.
- is((yield getFocusedLocalName(browser)), "body", "body is focused");
-
- // Cleanup.
- gBrowser.removeTab(blankTab);
- gBrowser.removeCurrentTab();
-
-});
diff --git a/browser/base/content/test/general/browser_bug431826.js b/browser/base/content/test/general/browser_bug431826.js
deleted file mode 100644
index 592ea9cef..000000000
--- a/browser/base/content/test/general/browser_bug431826.js
+++ /dev/null
@@ -1,50 +0,0 @@
-function remote(task) {
- return ContentTask.spawn(gBrowser.selectedBrowser, null, task);
-}
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
-
- let promise = remote(function () {
- return ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", true, event => {
- return content.document.documentURI != "about:blank";
- }).then(() => 0); // don't want to send the event to the chrome process
- });
- gBrowser.loadURI("https://nocert.example.com/");
- yield promise;
-
- yield remote(() => {
- // Confirm that we are displaying the contributed error page, not the default
- let uri = content.document.documentURI;
- Assert.ok(uri.startsWith("about:certerror"), "Broken page should go to about:certerror, not about:neterror");
- });
-
- yield remote(() => {
- let div = content.document.getElementById("badCertAdvancedPanel");
- // Confirm that the expert section is collapsed
- Assert.ok(div, "Advanced content div should exist");
- Assert.equal(div.ownerGlobal.getComputedStyle(div).display,
- "none", "Advanced content should not be visible by default");
- });
-
- // Tweak the expert mode pref
- gPrefService.setBoolPref("browser.xul.error_pages.expert_bad_cert", true);
-
- promise = remote(function () {
- return ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", true);
- });
- gBrowser.reload();
- yield promise;
-
- yield remote(() => {
- let div = content.document.getElementById("badCertAdvancedPanel");
- Assert.ok(div, "Advanced content div should exist");
- Assert.equal(div.ownerGlobal.getComputedStyle(div).display,
- "block", "Advanced content should be visible by default");
- });
-
- // Clean up
- gBrowser.removeCurrentTab();
- if (gPrefService.prefHasUserValue("browser.xul.error_pages.expert_bad_cert"))
- gPrefService.clearUserPref("browser.xul.error_pages.expert_bad_cert");
-});
diff --git a/browser/base/content/test/general/browser_bug432599.js b/browser/base/content/test/general/browser_bug432599.js
deleted file mode 100644
index a5f7c0b5e..000000000
--- a/browser/base/content/test/general/browser_bug432599.js
+++ /dev/null
@@ -1,127 +0,0 @@
-function invokeUsingCtrlD(phase) {
- switch (phase) {
- case 1:
- EventUtils.synthesizeKey("d", { accelKey: true });
- break;
- case 2:
- case 4:
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- break;
- case 3:
- EventUtils.synthesizeKey("d", { accelKey: true });
- EventUtils.synthesizeKey("d", { accelKey: true });
- break;
- }
-}
-
-function invokeUsingStarButton(phase) {
- switch (phase) {
- case 1:
- EventUtils.synthesizeMouseAtCenter(BookmarkingUI.star, {});
- break;
- case 2:
- case 4:
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- break;
- case 3:
- EventUtils.synthesizeMouseAtCenter(BookmarkingUI.star,
- { clickCount: 2 });
- break;
- }
-}
-
-var testURL = "data:text/plain,Content";
-var bookmarkId;
-
-function add_bookmark(aURI, aTitle) {
- return PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- aURI, PlacesUtils.bookmarks.DEFAULT_INDEX,
- aTitle);
-}
-
-// test bug 432599
-function test() {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
- gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
- waitForStarChange(false, initTest);
- }, true);
-
- content.location = testURL;
-}
-
-function initTest() {
- // First, bookmark the page.
- bookmarkId = add_bookmark(makeURI(testURL), "Bug 432599 Test");
-
- checkBookmarksPanel(invokers[currentInvoker], 1);
-}
-
-function waitForStarChange(aValue, aCallback) {
- let expectedStatus = aValue ? BookmarkingUI.STATUS_STARRED
- : BookmarkingUI.STATUS_UNSTARRED;
- if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING ||
- BookmarkingUI.status != expectedStatus) {
- info("Waiting for star button change.");
- setTimeout(waitForStarChange, 50, aValue, aCallback);
- return;
- }
- aCallback();
-}
-
-var invokers = [invokeUsingStarButton, invokeUsingCtrlD];
-var currentInvoker = 0;
-
-var initialValue;
-var initialRemoveHidden;
-
-var popupElement = document.getElementById("editBookmarkPanel");
-var titleElement = document.getElementById("editBookmarkPanelTitle");
-var removeElement = document.getElementById("editBookmarkPanelRemoveButton");
-
-function checkBookmarksPanel(invoker, phase)
-{
- let onPopupShown = function(aEvent) {
- if (aEvent.originalTarget == popupElement) {
- popupElement.removeEventListener("popupshown", arguments.callee, false);
- checkBookmarksPanel(invoker, phase + 1);
- }
- };
- let onPopupHidden = function(aEvent) {
- if (aEvent.originalTarget == popupElement) {
- popupElement.removeEventListener("popuphidden", arguments.callee, false);
- if (phase < 4) {
- checkBookmarksPanel(invoker, phase + 1);
- } else {
- ++currentInvoker;
- if (currentInvoker < invokers.length) {
- checkBookmarksPanel(invokers[currentInvoker], 1);
- } else {
- gBrowser.removeTab(gBrowser.selectedTab, {skipPermitUnload: true});
- PlacesUtils.bookmarks.removeItem(bookmarkId);
- executeSoon(finish);
- }
- }
- }
- };
-
- switch (phase) {
- case 1:
- case 3:
- popupElement.addEventListener("popupshown", onPopupShown, false);
- break;
- case 2:
- popupElement.addEventListener("popuphidden", onPopupHidden, false);
- initialValue = titleElement.value;
- initialRemoveHidden = removeElement.hidden;
- break;
- case 4:
- popupElement.addEventListener("popuphidden", onPopupHidden, false);
- is(titleElement.value, initialValue, "The bookmark panel's title should be the same");
- is(removeElement.hidden, initialRemoveHidden, "The bookmark panel's visibility should not change");
- break;
- }
- invoker(phase);
-}
diff --git a/browser/base/content/test/general/browser_bug435035.js b/browser/base/content/test/general/browser_bug435035.js
deleted file mode 100644
index 7570ef0d7..000000000
--- a/browser/base/content/test/general/browser_bug435035.js
+++ /dev/null
@@ -1,17 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab();
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
- is(document.getElementById("identity-box").className,
- "unknownIdentity mixedDisplayContent",
- "identity box has class name for mixed content");
-
- gBrowser.removeCurrentTab();
- finish();
- });
-
- gBrowser.loadURI(
- "https://example.com/browser/browser/base/content/test/general/test_bug435035.html"
- );
-}
diff --git a/browser/base/content/test/general/browser_bug435325.js b/browser/base/content/test/general/browser_bug435325.js
deleted file mode 100644
index 2ae15deff..000000000
--- a/browser/base/content/test/general/browser_bug435325.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* Ensure that clicking the button in the Offline mode neterror page makes the browser go online. See bug 435325. */
-
-var proxyPrefValue;
-
-function test() {
- waitForExplicitFinish();
-
- // Go offline and disable the proxy and cache, then try to load the test URL.
- Services.io.offline = true;
-
- // Tests always connect to localhost, and per bug 87717, localhost is now
- // reachable in offline mode. To avoid this, disable any proxy.
- proxyPrefValue = Services.prefs.getIntPref("network.proxy.type");
- Services.prefs.setIntPref("network.proxy.type", 0);
-
- Services.prefs.setBoolPref("browser.cache.disk.enable", false);
- Services.prefs.setBoolPref("browser.cache.memory.enable", false);
-
- gBrowser.selectedTab = gBrowser.addTab("http://example.com/");
-
- let contentScript = `
- let listener = function () {
- removeEventListener("DOMContentLoaded", listener);
- sendAsyncMessage("Test:DOMContentLoaded", { uri: content.document.documentURI });
- };
- addEventListener("DOMContentLoaded", listener);
- `;
-
- function pageloaded({ data }) {
- mm.removeMessageListener("Test:DOMContentLoaded", pageloaded);
- checkPage(data);
- }
-
- let mm = gBrowser.selectedBrowser.messageManager;
- mm.addMessageListener("Test:DOMContentLoaded", pageloaded);
- mm.loadFrameScript("data:," + contentScript, true);
-}
-
-function checkPage(data) {
- ok(Services.io.offline, "Setting Services.io.offline to true.");
-
- is(data.uri.substring(0, 27),
- "about:neterror?e=netOffline", "Loading the Offline mode neterror page.");
-
- // Re-enable the proxy so example.com is resolved to localhost, rather than
- // the actual example.com.
- Services.prefs.setIntPref("network.proxy.type", proxyPrefValue);
-
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- ok(!Services.io.offline, "After clicking the Try Again button, we're back " +
- "online.");
- Services.obs.removeObserver(observer, "network:offline-status-changed", false);
- finish();
- }, "network:offline-status-changed", false);
-
- ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- content.document.getElementById("errorTryAgain").click();
- });
-}
-
-registerCleanupFunction(function() {
- Services.prefs.setBoolPref("browser.cache.disk.enable", true);
- Services.prefs.setBoolPref("browser.cache.memory.enable", true);
- Services.io.offline = false;
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug441778.js b/browser/base/content/test/general/browser_bug441778.js
deleted file mode 100644
index fa938541f..000000000
--- a/browser/base/content/test/general/browser_bug441778.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Test the fix for bug 441778 to ensure site-specific page zoom doesn't get
- * modified by sub-document loads of content from a different domain.
- */
-
-function test() {
- waitForExplicitFinish();
-
- const TEST_PAGE_URL = 'data:text/html,<body><iframe src=""></iframe></body>';
- const TEST_IFRAME_URL = "http://test2.example.org/";
-
- Task.spawn(function* () {
- // Prepare the test tab
- let tab = gBrowser.addTab();
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab);
-
- let testBrowser = tab.linkedBrowser;
-
- yield FullZoomHelper.load(tab, TEST_PAGE_URL);
-
- // Change the zoom level and then save it so we can compare it to the level
- // after loading the sub-document.
- FullZoom.enlarge();
- var zoomLevel = ZoomManager.zoom;
-
- // Start the sub-document load.
- let deferred = Promise.defer();
- executeSoon(function () {
- BrowserTestUtils.browserLoaded(testBrowser, true).then(url => {
- is(url, TEST_IFRAME_URL, "got the load event for the iframe");
- is(ZoomManager.zoom, zoomLevel, "zoom is retained after sub-document load");
-
- FullZoomHelper.removeTabAndWaitForLocationChange().
- then(() => deferred.resolve());
- });
- ContentTask.spawn(testBrowser, TEST_IFRAME_URL, url => {
- content.document.querySelector("iframe").src = url;
- });
- });
- yield deferred.promise;
- }).then(finish, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug455852.js b/browser/base/content/test/general/browser_bug455852.js
deleted file mode 100644
index ce883b581..000000000
--- a/browser/base/content/test/general/browser_bug455852.js
+++ /dev/null
@@ -1,20 +0,0 @@
-add_task(function*() {
- is(gBrowser.tabs.length, 1, "one tab is open");
-
- gBrowser.selectedBrowser.focus();
- isnot(document.activeElement, gURLBar.inputField, "location bar is not focused");
-
- var tab = gBrowser.selectedTab;
- gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
-
- let tabClosedPromise = BrowserTestUtils.removeTab(tab, {dontRemove: true});
- EventUtils.synthesizeKey("w", { accelKey: true });
- yield tabClosedPromise;
-
- is(tab.parentNode, null, "ctrl+w removes the tab");
- is(gBrowser.tabs.length, 1, "a new tab has been opened");
- is(document.activeElement, gURLBar.inputField, "location bar is focused for the new tab");
-
- if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
- gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
-});
diff --git a/browser/base/content/test/general/browser_bug460146.js b/browser/base/content/test/general/browser_bug460146.js
deleted file mode 100644
index 1fdf0921c..000000000
--- a/browser/base/content/test/general/browser_bug460146.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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);
-
- content.location =
- "data:text/html," +
- "<html>" +
- " <head>" +
- " <title>Test for media tab</title>" +
- " <link rel='shortcut icon' href='file:///dummy_icon.ico'>" + // Icon
- " </head>" +
- " <body style='background-image:url(about:logo?a);'>" + // Background
- " <img src='file:///dummy_image.gif'>" + // Image
- " <ul>" +
- " <li style='list-style:url(about:logo?b);'>List Item 1</li>" + // Bullet
- " </ul> " +
- " <div style='-moz-border-image: url(about:logo?c) 20 20 20 20;'>test</div>" + // Border
- " <a href='' style='cursor: url(about:logo?d),default;'>test link</a>" + // Cursor
- " <object type='image/svg+xml' width=20 height=20 data='file:///dummy_object.svg'></object>" + // Object
- " </body>" +
- "</html>";
-}
diff --git a/browser/base/content/test/general/browser_bug462289.js b/browser/base/content/test/general/browser_bug462289.js
deleted file mode 100644
index 1ce79f07e..000000000
--- a/browser/base/content/test/general/browser_bug462289.js
+++ /dev/null
@@ -1,81 +0,0 @@
-var tab1, tab2;
-
-function focus_in_navbar()
-{
- var parent = document.activeElement.parentNode;
- while (parent && parent.id != "nav-bar")
- parent = parent.parentNode;
-
- return parent != null;
-}
-
-function test()
-{
- waitForExplicitFinish();
-
- tab1 = gBrowser.addTab("about:blank", {skipAnimation: true});
- tab2 = gBrowser.addTab("about:blank", {skipAnimation: true});
-
- EventUtils.synthesizeMouseAtCenter(tab1, {});
- executeSoon(step2);
-}
-
-function step2()
-{
- is(gBrowser.selectedTab, tab1, "1st click on tab1 selects tab");
- isnot(document.activeElement, tab1, "1st click on tab1 does not activate tab");
-
- EventUtils.synthesizeMouseAtCenter(tab1, {});
- executeSoon(step3);
-}
-
-function step3()
-{
- is(gBrowser.selectedTab, tab1, "2nd click on selected tab1 keeps tab selected");
- isnot(document.activeElement, tab1, "2nd click on selected tab1 does not activate tab");
-
- ok(true, "focusing URLBar then sending 1 Shift+Tab.");
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
- is(gBrowser.selectedTab, tab1, "tab key to selected tab1 keeps tab selected");
- is(document.activeElement, tab1, "tab key to selected tab1 activates tab");
-
- EventUtils.synthesizeMouseAtCenter(tab1, {});
- executeSoon(step4);
-}
-
-function step4()
-{
- is(gBrowser.selectedTab, tab1, "3rd click on activated tab1 keeps tab selected");
- is(document.activeElement, tab1, "3rd click on activated tab1 keeps tab activated");
-
- gBrowser.addEventListener("TabSwitchDone", step5);
- EventUtils.synthesizeMouseAtCenter(tab2, {});
-}
-
-function step5()
-{
- gBrowser.removeEventListener("TabSwitchDone", step5);
-
- // The tabbox selects a tab within a setTimeout in a bubbling mousedown event
- // listener, and focuses the current tab if another tab previously had focus.
- is(gBrowser.selectedTab, tab2, "click on tab2 while tab1 is activated selects tab");
- is(document.activeElement, tab2, "click on tab2 while tab1 is activated activates tab");
-
- info("focusing content then sending middle-button mousedown to tab2.");
- gBrowser.selectedBrowser.focus();
-
- EventUtils.synthesizeMouseAtCenter(tab2, {button: 1, type: "mousedown"});
- executeSoon(step6);
-}
-
-function step6()
-{
- is(gBrowser.selectedTab, tab2, "middle-button mousedown on selected tab2 keeps tab selected");
- isnot(document.activeElement, tab2, "middle-button mousedown on selected tab2 does not activate tab");
-
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab1);
-
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug462673.js b/browser/base/content/test/general/browser_bug462673.js
deleted file mode 100644
index f5b090917..000000000
--- a/browser/base/content/test/general/browser_bug462673.js
+++ /dev/null
@@ -1,36 +0,0 @@
-add_task(function* () {
- var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
- yield SimpleTest.promiseFocus(win);
-
- let tab = win.gBrowser.tabContainer.firstChild;
- yield promiseTabLoadEvent(tab, getRootDirectory(gTestPath) + "test_bug462673.html");
-
- is(win.gBrowser.browsers.length, 2, "test_bug462673.html has opened a second tab");
- is(win.gBrowser.selectedTab, tab.nextSibling, "dependent tab is selected");
- win.gBrowser.removeTab(tab);
-
- // Closing a tab will also close its parent chrome window, but async
- yield promiseWindowWillBeClosed(win);
-});
-
-add_task(function* () {
- var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
- yield SimpleTest.promiseFocus(win);
-
- let tab = win.gBrowser.tabContainer.firstChild;
- yield promiseTabLoadEvent(tab, getRootDirectory(gTestPath) + "test_bug462673.html");
-
- var newTab = win.gBrowser.addTab();
- var newBrowser = newTab.linkedBrowser;
- win.gBrowser.removeTab(tab);
- ok(!win.closed, "Window stays open");
- if (!win.closed) {
- is(win.gBrowser.tabContainer.childElementCount, 1, "Window has one tab");
- is(win.gBrowser.browsers.length, 1, "Window has one browser");
- is(win.gBrowser.selectedTab, newTab, "Remaining tab is selected");
- is(win.gBrowser.selectedBrowser, newBrowser, "Browser for remaining tab is selected");
- is(win.gBrowser.mTabBox.selectedPanel, newBrowser.parentNode.parentNode.parentNode.parentNode, "Panel for remaining tab is selected");
- }
-
- yield promiseWindowClosed(win);
-});
diff --git a/browser/base/content/test/general/browser_bug477014.js b/browser/base/content/test/general/browser_bug477014.js
deleted file mode 100644
index 8a0fac6d8..000000000
--- a/browser/base/content/test/general/browser_bug477014.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// That's a gecko!
-const iconURLSpec = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
-var testPage="data:text/plain,test bug 477014";
-
-add_task(function*() {
- let tabToDetach = gBrowser.addTab(testPage);
- yield waitForDocLoadComplete(tabToDetach.linkedBrowser);
-
- gBrowser.setIcon(tabToDetach, iconURLSpec,
- Services.scriptSecurityManager.getSystemPrincipal());
- tabToDetach.setAttribute("busy", "true");
-
- // detach and set the listener on the new window
- let newWindow = gBrowser.replaceTabWithWindow(tabToDetach);
- yield promiseWaitForEvent(tabToDetach.linkedBrowser, "SwapDocShells");
-
- is(newWindow.gBrowser.selectedTab.hasAttribute("busy"), true, "Busy attribute should be correct");
- is(newWindow.gBrowser.getIcon(), iconURLSpec, "Icon should be correct");
-
- newWindow.close();
-});
diff --git a/browser/base/content/test/general/browser_bug479408.js b/browser/base/content/test/general/browser_bug479408.js
deleted file mode 100644
index 0dfa96f2e..000000000
--- a/browser/base/content/test/general/browser_bug479408.js
+++ /dev/null
@@ -1,17 +0,0 @@
-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);
-}
diff --git a/browser/base/content/test/general/browser_bug479408_sample.html b/browser/base/content/test/general/browser_bug479408_sample.html
deleted file mode 100644
index f83f02bb9..000000000
--- a/browser/base/content/test/general/browser_bug479408_sample.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE html>
-<title>Testcase for bug 479408</title>
-
-<iframe src='data:text/html,<link%20rel="search"%20type="application/opensearchdescription+xml"%20title="Search%20bug%20479408"%20href="http://example.com/search.xml">'>
diff --git a/browser/base/content/test/general/browser_bug481560.js b/browser/base/content/test/general/browser_bug481560.js
deleted file mode 100644
index bb9249e75..000000000
--- a/browser/base/content/test/general/browser_bug481560.js
+++ /dev/null
@@ -1,21 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- whenNewWindowLoaded(null, function (win) {
- waitForFocus(function () {
- function onTabClose() {
- ok(false, "shouldn't have gotten the TabClose event for the last tab");
- }
- var tab = win.gBrowser.selectedTab;
- tab.addEventListener("TabClose", onTabClose, false);
-
- EventUtils.synthesizeKey("w", { accelKey: true }, win);
-
- ok(win.closed, "accel+w closed the window immediately");
-
- tab.removeEventListener("TabClose", onTabClose, false);
-
- finish();
- }, win);
- });
-}
diff --git a/browser/base/content/test/general/browser_bug484315.js b/browser/base/content/test/general/browser_bug484315.js
deleted file mode 100644
index fb23ae33a..000000000
--- a/browser/base/content/test/general/browser_bug484315.js
+++ /dev/null
@@ -1,23 +0,0 @@
-function test() {
- var contentWin = window.open("about:blank", "", "width=100,height=100");
- var enumerator = Services.wm.getEnumerator("navigator:browser");
-
- while (enumerator.hasMoreElements()) {
- let win = enumerator.getNext();
- if (win.content == contentWin) {
- gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
- win.gBrowser.removeCurrentTab();
- ok(win.closed, "popup is closed");
-
- // clean up
- if (!win.closed)
- win.close();
- if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
- gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
-
- return;
- }
- }
-
- throw "couldn't find the content window";
-}
diff --git a/browser/base/content/test/general/browser_bug491431.js b/browser/base/content/test/general/browser_bug491431.js
deleted file mode 100644
index d270e912e..000000000
--- a/browser/base/content/test/general/browser_bug491431.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var testPage = "data:text/plain,test bug 491431 Page";
-
-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);
- newWin = gBrowser.replaceTabWithWindow(tabB);
- }, true);
- gBrowser.removeTab(tabA);
-}
-
diff --git a/browser/base/content/test/general/browser_bug495058.js b/browser/base/content/test/general/browser_bug495058.js
deleted file mode 100644
index a82c6c931..000000000
--- a/browser/base/content/test/general/browser_bug495058.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Tests that the right elements of a tab are focused when it is
- * torn out into its own window.
- */
-
-const URIS = [
- "about:blank",
- "about:sessionrestore",
- "about:privatebrowsing",
-];
-
-add_task(function*() {
- for (let uri of URIS) {
- let tab = gBrowser.addTab();
- yield BrowserTestUtils.loadURI(tab.linkedBrowser, uri);
-
- let win = gBrowser.replaceTabWithWindow(tab);
- yield TestUtils.topicObserved("browser-delayed-startup-finished",
- subject => subject == win);
- tab = win.gBrowser.selectedTab;
-
- // BrowserTestUtils doesn't get the add-on shims, which means that
- // MozAfterPaint won't get shimmed over if we add an event handler
- // for it in the parent.
- if (tab.linkedBrowser.isRemoteBrowser) {
- yield BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "MozAfterPaint");
- } else {
- yield BrowserTestUtils.waitForEvent(tab.linkedBrowser, "MozAfterPaint");
- }
-
- Assert.equal(win.gBrowser.currentURI.spec, uri, uri + ": uri loaded in detached tab");
- Assert.equal(win.document.activeElement, win.gBrowser.selectedBrowser, uri + ": browser is focused");
- Assert.equal(win.gURLBar.value, "", uri + ": urlbar is empty");
- Assert.ok(win.gURLBar.placeholder, uri + ": placeholder text is present");
-
- yield BrowserTestUtils.closeWindow(win);
- }
-});
diff --git a/browser/base/content/test/general/browser_bug517902.js b/browser/base/content/test/general/browser_bug517902.js
deleted file mode 100644
index bc1d16f4b..000000000
--- a/browser/base/content/test/general/browser_bug517902.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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);
-
- 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>" +
- "<img src='about:logo?b' height=100 width=150 alt=2 id='test-image'>";
-}
diff --git a/browser/base/content/test/general/browser_bug519216.js b/browser/base/content/test/general/browser_bug519216.js
deleted file mode 100644
index d3a517086..000000000
--- a/browser/base/content/test/general/browser_bug519216.js
+++ /dev/null
@@ -1,45 +0,0 @@
-function test() {
- waitForExplicitFinish();
- gBrowser.addProgressListener(progressListener1);
- gBrowser.addProgressListener(progressListener2);
- gBrowser.addProgressListener(progressListener3);
- gBrowser.loadURI("data:text/plain,bug519216");
-}
-
-var calledListener1 = false;
-var progressListener1 = {
- onLocationChange: function onLocationChange() {
- calledListener1 = true;
- gBrowser.removeProgressListener(this);
- }
-};
-
-var calledListener2 = false;
-var progressListener2 = {
- onLocationChange: function onLocationChange() {
- ok(calledListener1, "called progressListener1 before progressListener2");
- calledListener2 = true;
- gBrowser.removeProgressListener(this);
- }
-};
-
-var progressListener3 = {
- onLocationChange: function onLocationChange() {
- ok(calledListener2, "called progressListener2 before progressListener3");
- gBrowser.removeProgressListener(this);
- gBrowser.addProgressListener(progressListener4);
- executeSoon(function () {
- expectListener4 = true;
- gBrowser.reload();
- });
- }
-};
-
-var expectListener4 = false;
-var progressListener4 = {
- onLocationChange: function onLocationChange() {
- ok(expectListener4, "didn't call progressListener4 for the first location change");
- gBrowser.removeProgressListener(this);
- executeSoon(finish);
- }
-};
diff --git a/browser/base/content/test/general/browser_bug520538.js b/browser/base/content/test/general/browser_bug520538.js
deleted file mode 100644
index e0b64db9d..000000000
--- a/browser/base/content/test/general/browser_bug520538.js
+++ /dev/null
@@ -1,15 +0,0 @@
-function test() {
- var tabCount = gBrowser.tabs.length;
- gBrowser.selectedBrowser.focus();
- browserDOMWindow.openURI(makeURI("about:blank"),
- null,
- Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
- Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
- is(gBrowser.tabs.length, tabCount + 1,
- "'--new-tab about:blank' opens a new tab");
- is(gBrowser.selectedTab, gBrowser.tabs[tabCount],
- "'--new-tab about:blank' selects the new tab");
- is(document.activeElement, gURLBar.inputField,
- "'--new-tab about:blank' focuses the location bar");
- gBrowser.removeCurrentTab();
-}
diff --git a/browser/base/content/test/general/browser_bug521216.js b/browser/base/content/test/general/browser_bug521216.js
deleted file mode 100644
index 735ae92f6..000000000
--- a/browser/base/content/test/general/browser_bug521216.js
+++ /dev/null
@@ -1,50 +0,0 @@
-var expected = ["TabOpen", "onStateChange", "onLocationChange", "onLinkIconAvailable"];
-var actual = [];
-var tabIndex = -1;
-this.__defineGetter__("tab", () => gBrowser.tabs[tabIndex]);
-
-function test() {
- waitForExplicitFinish();
- tabIndex = gBrowser.tabs.length;
- gBrowser.addTabsProgressListener(progressListener);
- gBrowser.tabContainer.addEventListener("TabOpen", TabOpen, false);
- gBrowser.addTab("data:text/html,<html><head><link href='about:logo' rel='shortcut icon'>");
-}
-
-function record(aName) {
- info("got " + aName);
- if (actual.indexOf(aName) == -1)
- actual.push(aName);
- if (actual.length == expected.length) {
- is(actual.toString(), expected.toString(),
- "got events and progress notifications in expected order");
-
- executeSoon(function(tab) {
- gBrowser.removeTab(tab);
- gBrowser.removeTabsProgressListener(progressListener);
- gBrowser.tabContainer.removeEventListener("TabOpen", TabOpen, false);
- finish();
- }.bind(null, tab));
- }
-}
-
-function TabOpen(aEvent) {
- if (aEvent.target == tab)
- record(arguments.callee.name);
-}
-
-var progressListener = {
- onLocationChange: function onLocationChange(aBrowser) {
- if (aBrowser == tab.linkedBrowser)
- record(arguments.callee.name);
- },
- onStateChange: function onStateChange(aBrowser) {
- if (aBrowser == tab.linkedBrowser)
- record(arguments.callee.name);
- },
- onLinkIconAvailable: function onLinkIconAvailable(aBrowser, aIconURL) {
- if (aBrowser == tab.linkedBrowser &&
- aIconURL == "about:logo")
- record(arguments.callee.name);
- }
-};
diff --git a/browser/base/content/test/general/browser_bug533232.js b/browser/base/content/test/general/browser_bug533232.js
deleted file mode 100644
index 6c7a0e51f..000000000
--- a/browser/base/content/test/general/browser_bug533232.js
+++ /dev/null
@@ -1,36 +0,0 @@
-function test() {
- var tab1 = gBrowser.selectedTab;
- var tab2 = gBrowser.addTab();
- var childTab1;
- var childTab2;
-
- childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
- gBrowser.selectedTab = childTab1;
- gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
- is(idx(gBrowser.selectedTab), idx(tab1),
- "closing a tab next to its parent selects the parent");
-
- childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
- gBrowser.selectedTab = tab2;
- gBrowser.selectedTab = childTab1;
- gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
- is(idx(gBrowser.selectedTab), idx(tab2),
- "closing a tab next to its parent doesn't select the parent if another tab had been selected ad interim");
-
- gBrowser.selectedTab = tab1;
- childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
- childTab2 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
- gBrowser.selectedTab = childTab1;
- gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
- is(idx(gBrowser.selectedTab), idx(childTab2),
- "closing a tab next to its parent selects the next tab with the same parent");
- gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
- is(idx(gBrowser.selectedTab), idx(tab2),
- "closing the last tab in a set of child tabs doesn't go back to the parent");
-
- gBrowser.removeTab(tab2, { skipPermitUnload: true });
-}
-
-function idx(tab) {
- return Array.indexOf(gBrowser.tabs, tab);
-}
diff --git a/browser/base/content/test/general/browser_bug537013.js b/browser/base/content/test/general/browser_bug537013.js
deleted file mode 100644
index 5ae1586ea..000000000
--- a/browser/base/content/test/general/browser_bug537013.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* Tests for bug 537013 to ensure proper tab-sequestration of find bar. */
-
-var tabs = [];
-var texts = [
- "This side up.",
- "The world is coming to an end. Please log off.",
- "Klein bottle for sale. Inquire within.",
- "To err is human; to forgive is not company policy."
-];
-
-var Clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
-var HasFindClipboard = Clipboard.supportsFindClipboard();
-
-function addTabWithText(aText, aCallback) {
- let newTab = gBrowser.addTab("data:text/html;charset=utf-8,<h1 id='h1'>" +
- aText + "</h1>");
- tabs.push(newTab);
- gBrowser.selectedTab = newTab;
-}
-
-function setFindString(aString) {
- gFindBar.open();
- gFindBar._findField.focus();
- gFindBar._findField.select();
- EventUtils.sendString(aString);
- is(gFindBar._findField.value, aString, "Set the field correctly!");
-}
-
-var newWindow;
-
-function test() {
- waitForExplicitFinish();
- registerCleanupFunction(function () {
- while (tabs.length) {
- gBrowser.removeTab(tabs.pop());
- }
- });
- texts.forEach(aText => addTabWithText(aText));
-
- // Set up the first tab
- gBrowser.selectedTab = tabs[0];
-
- setFindString(texts[0]);
- // Turn on highlight for testing bug 891638
- gFindBar.toggleHighlight(true);
-
- // Make sure the second tab is correct, then set it up
- gBrowser.selectedTab = tabs[1];
- gBrowser.selectedTab.addEventListener("TabFindInitialized", continueTests1);
- // Initialize the findbar
- gFindBar;
-}
-function continueTests1() {
- gBrowser.selectedTab.removeEventListener("TabFindInitialized",
- continueTests1);
- ok(true, "'TabFindInitialized' event properly dispatched!");
- ok(gFindBar.hidden, "Second tab doesn't show find bar!");
- gFindBar.open();
- is(gFindBar._findField.value, texts[0],
- "Second tab kept old find value for new initialization!");
- setFindString(texts[1]);
-
- // Confirm the first tab is still correct, ensure re-hiding works as expected
- gBrowser.selectedTab = tabs[0];
- ok(!gFindBar.hidden, "First tab shows find bar!");
- // When the Find Clipboard is supported, this test not relevant.
- if (!HasFindClipboard)
- is(gFindBar._findField.value, texts[0], "First tab persists find value!");
- ok(gFindBar.getElement("highlight").checked,
- "Highlight button state persists!");
-
- // While we're here, let's test the backout of bug 253793.
- gBrowser.reload();
- gBrowser.addEventListener("DOMContentLoaded", continueTests2, true);
-}
-
-function continueTests2() {
- gBrowser.removeEventListener("DOMContentLoaded", continueTests2, true);
- ok(gFindBar.getElement("highlight").checked, "Highlight never reset!");
- continueTests3();
-}
-
-function continueTests3() {
- ok(gFindBar.getElement("highlight").checked, "Highlight button reset!");
- gFindBar.close();
- ok(gFindBar.hidden, "First tab doesn't show find bar!");
- gBrowser.selectedTab = tabs[1];
- ok(!gFindBar.hidden, "Second tab shows find bar!");
- // Test for bug 892384
- is(gFindBar._findField.getAttribute("focused"), "true",
- "Open findbar refocused on tab change!");
- gURLBar.focus();
- gBrowser.selectedTab = tabs[0];
- ok(gFindBar.hidden, "First tab doesn't show find bar!");
-
- // Set up a third tab, no tests here
- gBrowser.selectedTab = tabs[2];
- setFindString(texts[2]);
-
- // Now we jump to the second, then first, and then fourth
- gBrowser.selectedTab = tabs[1];
- // Test for bug 892384
- ok(!gFindBar._findField.hasAttribute("focused"),
- "Open findbar not refocused on tab change!");
- gBrowser.selectedTab = tabs[0];
- gBrowser.selectedTab = tabs[3];
- ok(gFindBar.hidden, "Fourth tab doesn't show find bar!");
- is(gFindBar, gBrowser.getFindBar(), "Find bar is right one!");
- gFindBar.open();
- // Disabled the following assertion due to intermittent failure on OSX 10.6 Debug.
- if (!HasFindClipboard) {
- is(gFindBar._findField.value, texts[1],
- "Fourth tab has second tab's find value!");
- }
-
- newWindow = gBrowser.replaceTabWithWindow(tabs.pop());
- whenDelayedStartupFinished(newWindow, checkNewWindow);
-}
-
-// Test that findbar gets restored when a tab is moved to a new window.
-function checkNewWindow() {
- ok(!newWindow.gFindBar.hidden, "New window shows find bar!");
- // Disabled the following assertion due to intermittent failure on OSX 10.6 Debug.
- if (!HasFindClipboard) {
- is(newWindow.gFindBar._findField.value, texts[1],
- "New window find bar has correct find value!");
- }
- ok(!newWindow.gFindBar.getElement("find-next").disabled,
- "New window findbar has enabled buttons!");
- newWindow.close();
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug537474.js b/browser/base/content/test/general/browser_bug537474.js
deleted file mode 100644
index f1139f235..000000000
--- a/browser/base/content/test/general/browser_bug537474.js
+++ /dev/null
@@ -1,8 +0,0 @@
-add_task(function *() {
- let browserLoadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- browserDOMWindow.openURI(makeURI("about:"), null,
- Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW, null)
- yield browserLoadedPromise;
- is(gBrowser.currentURI.spec, "about:", "page loads in the current content window");
-});
-
diff --git a/browser/base/content/test/general/browser_bug550565.js b/browser/base/content/test/general/browser_bug550565.js
deleted file mode 100644
index b0e094e07..000000000
--- a/browser/base/content/test/general/browser_bug550565.js
+++ /dev/null
@@ -1,44 +0,0 @@
-add_task(function* test() {
- let testPath = getRootDirectory(gTestPath);
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (tabBrowser) {
- const URI = testPath + "file_with_favicon.html";
- const expectedIcon = testPath + "file_generic_favicon.ico";
-
- let got_favicon = Promise.defer();
- let listener = {
- onLinkIconAvailable(browser, iconURI) {
- if (got_favicon && iconURI && browser === tabBrowser) {
- got_favicon.resolve(iconURI);
- got_favicon = null;
- }
- }
- };
- gBrowser.addTabsProgressListener(listener);
-
- BrowserTestUtils.loadURI(tabBrowser, URI);
-
- let iconURI = yield got_favicon.promise;
- is(iconURI, expectedIcon, "Correct icon before pushState.");
-
- got_favicon = Promise.defer();
- got_favicon.promise.then(() => { ok(false, "shouldn't be called"); }, (e) => e);
- yield ContentTask.spawn(tabBrowser, null, function() {
- content.history.pushState("page2", "page2", "page2");
- });
-
- // We've navigated and shouldn't get a call to onLinkIconAvailable.
- TestUtils.executeSoon(() => {
- got_favicon.reject(gBrowser.getIcon(gBrowser.getTabForBrowser(tabBrowser)));
- });
- try {
- yield got_favicon.promise;
- } catch (e) {
- iconURI = e;
- }
- is(iconURI, expectedIcon, "Correct icon after pushState.");
-
- gBrowser.removeTabsProgressListener(listener);
- });
-});
diff --git a/browser/base/content/test/general/browser_bug553455.js b/browser/base/content/test/general/browser_bug553455.js
deleted file mode 100644
index c29a810de..000000000
--- a/browser/base/content/test/general/browser_bug553455.js
+++ /dev/null
@@ -1,1200 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const TESTROOT = "http://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
-const TESTROOT2 = "http://example.org/browser/toolkit/mozapps/extensions/test/xpinstall/";
-const SECUREROOT = "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
-const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
-const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
-const PROGRESS_NOTIFICATION = "addon-progress";
-
-const { REQUIRE_SIGNING } = Cu.import("resource://gre/modules/addons/AddonConstants.jsm", {});
-const { Task } = Cu.import("resource://gre/modules/Task.jsm");
-
-var rootDir = getRootDirectory(gTestPath);
-var rootPath = rootDir.split('/');
-var chromeName = rootPath[0] + '//' + rootPath[2];
-var croot = chromeName + "/content/browser/toolkit/mozapps/extensions/test/xpinstall/";
-var jar = getJar(croot);
-if (jar) {
- var tmpdir = extractJarToTmp(jar);
- croot = 'file://' + tmpdir.path + '/';
-}
-const CHROMEROOT = croot;
-
-var gApp = document.getElementById("bundle_brand").getString("brandShortName");
-var gVersion = Services.appinfo.version;
-
-function getObserverTopic(aNotificationId) {
- let topic = aNotificationId;
- if (topic == "xpinstall-disabled")
- topic = "addon-install-disabled";
- else if (topic == "addon-progress")
- topic = "addon-install-started";
- else if (topic == "addon-install-restart")
- topic = "addon-install-complete";
- return topic;
-}
-
-function waitForProgressNotification(aPanelOpen = false, aExpectedCount = 1) {
- return Task.spawn(function* () {
- let notificationId = PROGRESS_NOTIFICATION;
- info("Waiting for " + notificationId + " notification");
-
- let topic = getObserverTopic(notificationId);
-
- let observerPromise = new Promise(resolve => {
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
- // Ignore the progress notification unless that is the notification we want
- if (notificationId != PROGRESS_NOTIFICATION &&
- aTopic == getObserverTopic(PROGRESS_NOTIFICATION)) {
- return;
- }
- Services.obs.removeObserver(observer, topic);
- resolve();
- }, 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);
- resolve();
- });
- });
- }
-
- yield observerPromise;
- yield panelEventPromise;
-
- info("Saw a notification");
- ok(PopupNotifications.isPanelOpen, "Panel should be open");
- is(PopupNotifications.panel.childNodes.length, aExpectedCount, "Should be the right number of notifications");
- if (PopupNotifications.panel.childNodes.length) {
- let nodes = Array.from(PopupNotifications.panel.childNodes);
- let notification = nodes.find(n => n.id == notificationId + "-notification");
- ok(notification, `Should have seen the right notification`);
- }
-
- return PopupNotifications.panel;
- });
-}
-
-function waitForNotification(aId, aExpectedCount = 1) {
- return Task.spawn(function* () {
- info("Waiting for " + aId + " notification");
-
- let topic = getObserverTopic(aId);
-
- let observerPromise = new Promise(resolve => {
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
- // Ignore the progress notification unless that is the notification we want
- if (aId != PROGRESS_NOTIFICATION &&
- aTopic == getObserverTopic(PROGRESS_NOTIFICATION)) {
- return;
- }
- Services.obs.removeObserver(observer, topic);
- resolve();
- }, topic, false);
- });
-
- let panelEventPromise = new Promise(resolve => {
- PopupNotifications.panel.addEventListener("PanelUpdated", function eventListener(e) {
- // Skip notifications that are not the one that we are supposed to be looking for
- if (e.detail.indexOf(aId) == -1) {
- return;
- }
- PopupNotifications.panel.removeEventListener("PanelUpdated", eventListener);
- resolve();
- });
- });
-
- yield observerPromise;
- yield panelEventPromise;
-
- info("Saw a notification");
- ok(PopupNotifications.isPanelOpen, "Panel should be open");
- is(PopupNotifications.panel.childNodes.length, aExpectedCount, "Should be the right number of notifications");
- if (PopupNotifications.panel.childNodes.length) {
- let nodes = Array.from(PopupNotifications.panel.childNodes);
- let notification = nodes.find(n => n.id == aId + "-notification");
- ok(notification, `Should have seen the right notification`);
- }
-
- 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, false);
- resolve();
- }, false);
- });
-}
-
-function waitForInstallDialog() {
- return Task.spawn(function* () {
- if (Preferences.get("xpinstall.customConfirmationUI", false)) {
- yield waitForNotification("addon-install-confirmation");
- return;
- }
-
- info("Waiting for install dialog");
-
- let window = yield new Promise(resolve => {
- Services.wm.addListener({
- onOpenWindow: function(aXULWindow) {
- Services.wm.removeListener(this);
- resolve(aXULWindow);
- },
- onCloseWindow: function(aXULWindow) {
- },
- onWindowTitleChange: function(aXULWindow, aNewTitle) {
- }
- });
- });
- info("Install dialog opened, waiting for focus");
-
- let domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- yield new Promise(resolve => {
- waitForFocus(function() {
- resolve();
- }, domwindow);
- });
- info("Saw install dialog");
- is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
-
- // Override the countdown timer on the accept button
- let button = domwindow.document.documentElement.getButton("accept");
- button.disabled = false;
-
- return;
- });
-}
-
-function removeTab() {
- return Promise.all([
- waitForNotificationClose(),
- BrowserTestUtils.removeTab(gBrowser.selectedTab)
- ]);
-}
-
-function acceptInstallDialog() {
- if (Preferences.get("xpinstall.customConfirmationUI", false)) {
- document.getElementById("addon-install-confirmation-accept").click();
- } else {
- let win = Services.wm.getMostRecentWindow("Addons:Install");
- win.document.documentElement.acceptDialog();
- }
-}
-
-function cancelInstallDialog() {
- if (Preferences.get("xpinstall.customConfirmationUI", false)) {
- document.getElementById("addon-install-confirmation-cancel").click();
- } else {
- let win = Services.wm.getMostRecentWindow("Addons:Install");
- win.document.documentElement.cancelDialog();
- }
-}
-
-function waitForSingleNotification(aCallback) {
- return Task.spawn(function* () {
- while (PopupNotifications.panel.childNodes.length == 2) {
- yield new Promise(resolve => executeSoon(resolve));
-
- info("Waiting for single notification");
- // Notification should never close while we wait
- ok(PopupNotifications.isPanelOpen, "Notification should still be open");
- }
- });
-}
-
-function setupRedirect(aSettings) {
- var url = "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/redirect.sjs?mode=setup";
- for (var name in aSettings) {
- url += "&" + name + "=" + aSettings[name];
- }
-
- var req = new XMLHttpRequest();
- req.open("GET", url, false);
- req.send(null);
-}
-
-function getInstalls() {
- return new Promise(resolve => {
- AddonManager.getAllInstalls(installs => resolve(installs));
- });
-}
-
-var TESTS = [
-function test_disabledInstall() {
- return Task.spawn(function* () {
- Services.prefs.setBoolPref("xpinstall.enabled", false);
-
- let notificationPromise = waitForNotification("xpinstall-disabled");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Enable", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "Software installation is currently disabled. Click Enable and try again.");
-
- let closePromise = waitForNotificationClose();
- // Click on Enable
- EventUtils.synthesizeMouseAtCenter(notification.button, {});
- yield closePromise;
-
- try {
- ok(Services.prefs.getBoolPref("xpinstall.enabled"), "Installation should be enabled");
- }
- catch (e) {
- ok(false, "xpinstall.enabled should be set");
- }
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- let installs = yield getInstalls();
- is(installs.length, 0, "Shouldn't be any pending installs");
- });
-},
-
-function test_blockedInstall() {
- return Task.spawn(function* () {
- let notificationPromise = waitForNotification("addon-install-blocked");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Allow", "Should have seen the right button");
- is(notification.getAttribute("origin"), "example.com",
- "Should have seen the right origin host");
- is(notification.getAttribute("label"),
- gApp + " prevented this site from asking you to install software on your computer.",
- "Should have seen the right message");
-
- let dialogPromise = waitForInstallDialog();
- // Click on Allow
- EventUtils.synthesizeMouse(notification.button, 20, 10, {});
- // Notification should have changed to progress notification
- ok(PopupNotifications.isPanelOpen, "Notification should still be open");
- notification = panel.childNodes[0];
- is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
- yield dialogPromise;
-
- notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- panel = yield notificationPromise;
-
- notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "XPI Test will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
- installs[0].cancel();
- yield removeTab();
- });
-},
-
-function test_whitelistedInstall() {
- return Task.spawn(function* () {
- let originalTab = gBrowser.selectedTab;
- let tab;
- gBrowser.selectedTab = originalTab;
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?"
- + triggers).then(newTab => tab = newTab);
- yield progressPromise;
- yield dialogPromise;
- yield BrowserTestUtils.waitForCondition(() => !!tab, "tab should be present");
-
- is(gBrowser.selectedTab, tab,
- "tab selected in response to the addon-install-confirmation notification");
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "XPI Test will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
- installs[0].cancel();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_failedDownload() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let failPromise = waitForNotification("addon-install-failed");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "missing.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- let panel = yield failPromise;
-
- let notification = panel.childNodes[0];
- is(notification.getAttribute("label"),
- "The add-on could not be downloaded because of a connection failure.",
- "Should have seen the right message");
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_corruptFile() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let failPromise = waitForNotification("addon-install-failed");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "corrupt.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- let panel = yield failPromise;
-
- let notification = panel.childNodes[0];
- is(notification.getAttribute("label"),
- "The add-on downloaded from this site could not be installed " +
- "because it appears to be corrupt.",
- "Should have seen the right message");
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_incompatible() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let failPromise = waitForNotification("addon-install-failed");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "incompatible.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- let panel = yield failPromise;
-
- let notification = panel.childNodes[0];
- is(notification.getAttribute("label"),
- "XPI Test could not be installed because it is not compatible with " +
- gApp + " " + gVersion + ".",
- "Should have seen the right message");
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_restartless() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "restartless.xpi"
- }));
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- let notificationPromise = waitForNotification("addon-install-complete");
- acceptInstallDialog();
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.getAttribute("label"),
- "XPI Test has been installed successfully.",
- "Should have seen the right message");
-
- let installs = yield getInstalls();
- is(installs.length, 0, "Should be no pending installs");
-
- let addon = yield new Promise(resolve => {
- AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", result => {
- resolve(result);
- });
- });
- addon.uninstall();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
-
- let closePromise = waitForNotificationClose();
- gBrowser.removeTab(gBrowser.selectedTab);
- yield closePromise;
- });
-},
-
-function test_multiple() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Unsigned XPI": "amosigned.xpi",
- "Restartless XPI": "restartless.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- let panel = yield progressPromise;
- yield dialogPromise;
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "2 add-ons will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
- installs[0].cancel();
-
- let addon = yield new Promise(resolve => {
- AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function (result) {
- resolve(result);
- });
- });
- addon.uninstall();
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_sequential() {
- return Task.spawn(function* () {
- // This test is only relevant if using the new doorhanger UI
- if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
- return;
- }
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Restartless XPI": "restartless.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- // Should see the right add-on
- let container = document.getElementById("addon-install-confirmation-content");
- is(container.childNodes.length, 1, "Should be one item listed");
- is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
-
- progressPromise = waitForProgressNotification(true, 2);
- triggers = encodeURIComponent(JSON.stringify({
- "Theme XPI": "theme.xpi"
- }));
- gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
-
- // Should still have the right add-on in the confirmation notification
- is(container.childNodes.length, 1, "Should be one item listed");
- is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
-
- // Wait for the install to complete, we won't see a new confirmation
- // notification
- yield new Promise(resolve => {
- Services.obs.addObserver(function observer() {
- Services.obs.removeObserver(observer, "addon-install-confirmation");
- resolve();
- }, "addon-install-confirmation", false);
- });
-
- // Make sure browser-addons.js executes first
- yield new Promise(resolve => executeSoon(resolve));
-
- // Should have dropped the progress notification
- is(PopupNotifications.panel.childNodes.length, 1, "Should be the right number of notifications");
- is(PopupNotifications.panel.childNodes[0].id, "addon-install-confirmation-notification",
- "Should only be showing one install confirmation");
-
- // Should still have the right add-on in the confirmation notification
- is(container.childNodes.length, 1, "Should be one item listed");
- is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
-
- cancelInstallDialog();
-
- ok(PopupNotifications.isPanelOpen, "Panel should still be open");
- is(PopupNotifications.panel.childNodes.length, 1, "Should be the right number of notifications");
- is(PopupNotifications.panel.childNodes[0].id, "addon-install-confirmation-notification",
- "Should still have an install confirmation open");
-
- // Should have the next add-on's confirmation dialog
- is(container.childNodes.length, 1, "Should be one item listed");
- is(container.childNodes[0].firstChild.getAttribute("value"), "Theme Test", "Should have the right add-on");
-
- Services.perms.remove(makeURI("http://example.com"), "install");
- let closePromise = waitForNotificationClose();
- cancelInstallDialog();
- yield closePromise;
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- });
-},
-
-function test_someUnverified() {
- return Task.spawn(function* () {
- // This test is only relevant if using the new doorhanger UI and allowing
- // unsigned add-ons
- if (!Preferences.get("xpinstall.customConfirmationUI", false) ||
- Preferences.get("xpinstall.signatures.required", true) ||
- REQUIRE_SIGNING) {
- return;
- }
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Extension XPI": "restartless-unsigned.xpi",
- "Theme XPI": "theme.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- let notification = document.getElementById("addon-install-confirmation-notification");
- let message = notification.getAttribute("label");
- is(message, "Caution: This site would like to install 2 add-ons in " + gApp +
- ", some of which are unverified. Proceed at your own risk.",
- "Should see the right message");
-
- let container = document.getElementById("addon-install-confirmation-content");
- is(container.childNodes.length, 2, "Should be two items listed");
- is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
- is(container.childNodes[0].lastChild.getAttribute("class"),
- "addon-install-confirmation-unsigned", "Should have the unverified marker");
- is(container.childNodes[1].firstChild.getAttribute("value"), "Theme Test", "Should have the right add-on");
- is(container.childNodes[1].childNodes.length, 1, "Shouldn't have the unverified marker");
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- yield notificationPromise;
-
- let [addon, theme] = yield new Promise(resolve => {
- AddonManager.getAddonsByIDs(["restartless-xpi@tests.mozilla.org",
- "theme-xpi@tests.mozilla.org"],
- function(addons) {
- resolve(addons);
- });
- });
- addon.uninstall();
- // Installing a new theme tries to switch to it, switch back to the
- // default theme.
- theme.userDisabled = true;
- theme.uninstall();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_allUnverified() {
- return Task.spawn(function* () {
- // This test is only relevant if using the new doorhanger UI and allowing
- // unsigned add-ons
- if (!Preferences.get("xpinstall.customConfirmationUI", false) ||
- Preferences.get("xpinstall.signatures.required", true) ||
- REQUIRE_SIGNING) {
- return;
- }
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Extension XPI": "restartless-unsigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- let notification = document.getElementById("addon-install-confirmation-notification");
- let message = notification.getAttribute("label");
- is(message, "Caution: This site would like to install an unverified add-on in " + gApp + ". Proceed at your own risk.");
-
- let container = document.getElementById("addon-install-confirmation-content");
- is(container.childNodes.length, 1, "Should be one item listed");
- is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
- is(container.childNodes[0].childNodes.length, 1, "Shouldn't have the unverified marker");
-
- let notificationPromise = waitForNotification("addon-install-complete");
- acceptInstallDialog();
- yield notificationPromise;
-
- let addon = yield new Promise(resolve => {
- AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(result) {
- resolve(result);
- });
- });
- addon.uninstall();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_url() {
- return Task.spawn(function* () {
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.loadURI(TESTROOT + "amosigned.xpi");
- yield progressPromise;
- yield dialogPromise;
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "XPI Test will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
- installs[0].cancel();
-
- yield removeTab();
- });
-},
-
-function test_localFile() {
- return Task.spawn(function* () {
- let cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Components.interfaces.nsIChromeRegistry);
- let path;
- try {
- path = cr.convertChromeURL(makeURI(CHROMEROOT + "corrupt.xpi")).spec;
- } catch (ex) {
- path = CHROMEROOT + "corrupt.xpi";
- }
-
- let failPromise = new Promise(resolve => {
- Services.obs.addObserver(function observer() {
- Services.obs.removeObserver(observer, "addon-install-failed");
- resolve();
- }, "addon-install-failed", false);
- });
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.loadURI(path);
- yield failPromise;
-
- // Wait for the browser code to add the failure notification
- yield waitForSingleNotification();
-
- let notification = PopupNotifications.panel.childNodes[0];
- is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
- is(notification.getAttribute("label"),
- "This add-on could not be installed because it appears to be corrupt.",
- "Should have seen the right message");
-
- yield removeTab();
- });
-},
-
-function test_tabClose() {
- return Task.spawn(function* () {
- if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
- runNextTest();
- return;
- }
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.loadURI(TESTROOT + "amosigned.xpi");
- yield progressPromise;
- yield dialogPromise;
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
-
- let closePromise = waitForNotificationClose();
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield closePromise;
-
- installs = yield getInstalls();
- is(installs.length, 0, "Should be no pending install since the tab is closed");
- });
-},
-
-// Add-ons should be cancelled and the install notification destroyed when
-// navigating to a new origin
-function test_tabNavigate() {
- return Task.spawn(function* () {
- if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
- return;
- }
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Extension XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- let closePromise = waitForNotificationClose();
- let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.loadURI("about:blank");
- yield closePromise;
-
- let installs = yield getInstalls();
- is(installs.length, 0, "Should be no pending install");
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield loadPromise;
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- });
-},
-
-function test_urlBar() {
- return Task.spawn(function* () {
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
-
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gURLBar.value = TESTROOT + "amosigned.xpi";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
-
- yield progressPromise;
- let installDialog = yield dialogPromise;
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog(installDialog);
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "XPI Test will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
- installs[0].cancel();
-
- yield removeTab();
- });
-},
-
-function test_wrongHost() {
- return Task.spawn(function* () {
- let requestedUrl = TESTROOT2 + "enabled.html";
- gBrowser.selectedTab = gBrowser.addTab();
-
- let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, requestedUrl);
- gBrowser.loadURI(TESTROOT2 + "enabled.html");
- yield loadedPromise;
-
- let progressPromise = waitForProgressNotification();
- let notificationPromise = waitForNotification("addon-install-failed");
- gBrowser.loadURI(TESTROOT + "corrupt.xpi");
- yield progressPromise;
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.getAttribute("label"),
- "The add-on downloaded from this site could not be installed " +
- "because it appears to be corrupt.",
- "Should have seen the right message");
-
- yield removeTab();
- });
-},
-
-function test_reload() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Unsigned XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "XPI Test will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- function testFail() {
- ok(false, "Reloading should not have hidden the notification");
- }
- PopupNotifications.panel.addEventListener("popuphiding", testFail, false);
- let requestedUrl = TESTROOT2 + "enabled.html";
- let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, requestedUrl);
- gBrowser.loadURI(TESTROOT2 + "enabled.html");
- yield loadedPromise;
- PopupNotifications.panel.removeEventListener("popuphiding", testFail, false);
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending install");
- installs[0].cancel();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_theme() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "Theme XPI": "theme.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
- is(notification.getAttribute("label"),
- "Theme Test will be installed after you restart " + gApp + ".",
- "Should have seen the right message");
-
- let addon = yield new Promise(resolve => {
- AddonManager.getAddonByID("{972ce4c6-7e08-4474-a285-3208198ce6fd}", function(result) {
- resolve(result);
- });
- });
- ok(addon.userDisabled, "Should be switching away from the default theme.");
- // Undo the pending theme switch
- addon.userDisabled = false;
-
- addon = yield new Promise(resolve => {
- AddonManager.getAddonByID("theme-xpi@tests.mozilla.org", function(result) {
- resolve(result);
- });
- });
- isnot(addon, null, "Test theme will have been installed");
- addon.uninstall();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_renotifyBlocked() {
- return Task.spawn(function* () {
- let notificationPromise = waitForNotification("addon-install-blocked");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- let panel = yield notificationPromise;
-
- let closePromise = waitForNotificationClose();
- // hide the panel (this simulates the user dismissing it)
- panel.hidePopup();
- yield closePromise;
-
- info("Timeouts after this probably mean bug 589954 regressed");
-
- yield new Promise(resolve => executeSoon(resolve));
-
- notificationPromise = waitForNotification("addon-install-blocked");
- gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
- yield notificationPromise;
-
- let installs = yield getInstalls();
- is(installs.length, 2, "Should be two pending installs");
-
- closePromise = waitForNotificationClose();
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield closePromise;
-
- installs = yield getInstalls();
- is(installs.length, 0, "Should have cancelled the installs");
- });
-},
-
-function test_renotifyInstalled() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let progressPromise = waitForProgressNotification();
- let dialogPromise = waitForInstallDialog();
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- // Wait for the complete notification
- let notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- let panel = yield notificationPromise;
-
- let closePromise = waitForNotificationClose();
- // hide the panel (this simulates the user dismissing it)
- panel.hidePopup();
- yield closePromise;
-
- // Install another
- yield new Promise(resolve => executeSoon(resolve));
-
- progressPromise = waitForProgressNotification();
- dialogPromise = waitForInstallDialog();
- gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
- yield progressPromise;
- yield dialogPromise;
-
- info("Timeouts after this probably mean bug 589954 regressed");
-
- // Wait for the complete notification
- notificationPromise = waitForNotification("addon-install-restart");
- acceptInstallDialog();
- yield notificationPromise;
-
- let installs = yield getInstalls();
- is(installs.length, 1, "Should be one pending installs");
- installs[0].cancel();
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield removeTab();
- });
-},
-
-function test_cancel() {
- return Task.spawn(function* () {
- let pm = Services.perms;
- pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
-
- let notificationPromise = waitForNotification(PROGRESS_NOTIFICATION);
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "slowinstall.sjs?file=amosigned.xpi"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- // Close the notification
- let anchor = document.getElementById("addons-notification-icon");
- anchor.click();
- // Reopen the notification
- anchor.click();
-
- ok(PopupNotifications.isPanelOpen, "Notification should still be open");
- is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
- notification = panel.childNodes[0];
- is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
- let button = document.getElementById("addon-progress-cancel");
-
- // Cancel the download
- let install = notification.notification.options.installs[0];
- let cancelledPromise = new Promise(resolve => {
- install.addListener({
- onDownloadCancelled: function() {
- install.removeListener(this);
- resolve();
- }
- });
- });
- EventUtils.synthesizeMouseAtCenter(button, {});
- yield cancelledPromise;
-
- yield new Promise(resolve => executeSoon(resolve));
-
- ok(!PopupNotifications.isPanelOpen, "Notification should be closed");
-
- let installs = yield getInstalls();
- is(installs.length, 0, "Should be no pending install");
-
- Services.perms.remove(makeURI("http://example.com/"), "install");
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- });
-},
-
-function test_failedSecurity() {
- return Task.spawn(function* () {
- Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false);
- setupRedirect({
- "Location": TESTROOT + "amosigned.xpi"
- });
-
- let notificationPromise = waitForNotification("addon-install-blocked");
- let triggers = encodeURIComponent(JSON.stringify({
- "XPI": "redirect.sjs?mode=redirect"
- }));
- BrowserTestUtils.openNewForegroundTab(gBrowser, SECUREROOT + "installtrigger.html?" + triggers);
- let panel = yield notificationPromise;
-
- let notification = panel.childNodes[0];
- // Click on Allow
- EventUtils.synthesizeMouse(notification.button, 20, 10, {});
-
- // Notification should have changed to progress notification
- ok(PopupNotifications.isPanelOpen, "Notification should still be open");
- is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
- notification = panel.childNodes[0];
- is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
-
- // Wait for it to fail
- yield new Promise(resolve => {
- Services.obs.addObserver(function observer() {
- Services.obs.removeObserver(observer, "addon-install-failed");
- resolve();
- }, "addon-install-failed", false);
- });
-
- // Allow the browser code to add the failure notification and then wait
- // for the progress notification to dismiss itself
- yield waitForSingleNotification();
- is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
- notification = panel.childNodes[0];
- is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
-
- Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, true);
- yield removeTab();
- });
-}
-];
-
-var gTestStart = null;
-
-var XPInstallObserver = {
- observe: function (aSubject, aTopic, aData) {
- var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
- info("Observed " + aTopic + " for " + installInfo.installs.length + " installs");
- installInfo.installs.forEach(function(aInstall) {
- info("Install of " + aInstall.sourceURI.spec + " was in state " + aInstall.state);
- });
- }
-};
-
-add_task(function* () {
- requestLongerTimeout(4);
-
- Services.prefs.setBoolPref("extensions.logging.enabled", true);
- Services.prefs.setBoolPref("extensions.strictCompatibility", true);
- Services.prefs.setBoolPref("extensions.install.requireSecureOrigin", false);
- Services.prefs.setIntPref("security.dialog_enable_delay", 0);
-
- Services.obs.addObserver(XPInstallObserver, "addon-install-started", false);
- Services.obs.addObserver(XPInstallObserver, "addon-install-blocked", false);
- Services.obs.addObserver(XPInstallObserver, "addon-install-failed", false);
- Services.obs.addObserver(XPInstallObserver, "addon-install-complete", false);
-
- registerCleanupFunction(function() {
- // Make sure no more test parts run in case we were timed out
- TESTS = [];
-
- AddonManager.getAllInstalls(function(aInstalls) {
- aInstalls.forEach(function(aInstall) {
- aInstall.cancel();
- });
- });
-
- Services.prefs.clearUserPref("extensions.logging.enabled");
- Services.prefs.clearUserPref("extensions.strictCompatibility");
- Services.prefs.clearUserPref("extensions.install.requireSecureOrigin");
- Services.prefs.clearUserPref("security.dialog_enable_delay");
-
- Services.obs.removeObserver(XPInstallObserver, "addon-install-started");
- Services.obs.removeObserver(XPInstallObserver, "addon-install-blocked");
- Services.obs.removeObserver(XPInstallObserver, "addon-install-failed");
- Services.obs.removeObserver(XPInstallObserver, "addon-install-complete");
- });
-
- for (let i = 0; i < TESTS.length; ++i) {
- if (gTestStart)
- info("Test part took " + (Date.now() - gTestStart) + "ms");
-
- ok(!PopupNotifications.isPanelOpen, "Notification should be closed");
-
- let installs = yield new Promise(resolve => {
- AddonManager.getAllInstalls(function(aInstalls) {
- resolve(aInstalls);
- });
- });
-
- is(installs.length, 0, "Should be no active installs");
- info("Running " + TESTS[i].name);
- gTestStart = Date.now();
- yield TESTS[i]();
- }
-});
diff --git a/browser/base/content/test/general/browser_bug555224.js b/browser/base/content/test/general/browser_bug555224.js
deleted file mode 100644
index d27bf0040..000000000
--- a/browser/base/content/test/general/browser_bug555224.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const TEST_PAGE = "/browser/browser/base/content/test/general/dummy_page.html";
-var gTestTab, gBgTab, gTestZoom;
-
-function testBackgroundLoad() {
- Task.spawn(function* () {
- is(ZoomManager.zoom, gTestZoom, "opening a background tab should not change foreground zoom");
-
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gBgTab);
-
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTestTab);
- finish();
- });
-}
-
-function testInitialZoom() {
- Task.spawn(function* () {
- is(ZoomManager.zoom, 1, "initial zoom level should be 1");
- FullZoom.enlarge();
-
- gTestZoom = ZoomManager.zoom;
- isnot(gTestZoom, 1, "zoom level should have changed");
-
- gBgTab = gBrowser.addTab();
- yield FullZoomHelper.load(gBgTab, "http://mochi.test:8888" + TEST_PAGE);
- }).then(testBackgroundLoad, FullZoomHelper.failAndContinue(finish));
-}
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- gTestTab = gBrowser.addTab();
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTestTab);
- yield FullZoomHelper.load(gTestTab, "http://example.org" + TEST_PAGE);
- }).then(testInitialZoom, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug555767.js b/browser/base/content/test/general/browser_bug555767.js
deleted file mode 100644
index bc774f7dc..000000000
--- a/browser/base/content/test/general/browser_bug555767.js
+++ /dev/null
@@ -1,54 +0,0 @@
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
- add_task(function* () {
- let testURL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
- let tabSelected = false;
-
- // Open the base tab
- let baseTab = gBrowser.addTab(testURL);
-
- // Wait for the tab to be fully loaded so matching happens correctly
- yield promiseTabLoaded(baseTab);
- if (baseTab.linkedBrowser.currentURI.spec == "about:blank")
- return;
- baseTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
- let testTab = gBrowser.addTab();
-
- // Select the testTab
- gBrowser.selectedTab = testTab;
-
- // Set the urlbar to include the moz-action
- gURLBar.value = "moz-action:switchtab," + JSON.stringify({url: testURL});
- // Focus the urlbar so we can press enter
- gURLBar.focus();
-
- // Functions for TabClose and TabSelect
- function onTabClose(aEvent) {
- gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, false);
- // Make sure we get the TabClose event for testTab
- is(aEvent.originalTarget, testTab, "Got the TabClose event for the right tab");
- // Confirm that we did select the tab
- ok(tabSelected, "Confirming that the tab was selected");
- gBrowser.removeTab(baseTab);
- finish();
- }
- function onTabSelect(aEvent) {
- gBrowser.tabContainer.removeEventListener("TabSelect", onTabSelect, false);
- // Make sure we got the TabSelect event for baseTab
- is(aEvent.originalTarget, baseTab, "Got the TabSelect event for the right tab");
- // Confirm that the selected tab is in fact base tab
- is(gBrowser.selectedTab, baseTab, "We've switched to the correct tab");
- tabSelected = true;
- }
-
- // Add the TabClose, TabSelect event listeners before we press enter
- gBrowser.tabContainer.addEventListener("TabClose", onTabClose, false);
- gBrowser.tabContainer.addEventListener("TabSelect", onTabSelect, false);
-
- // Press enter!
- EventUtils.synthesizeKey("VK_RETURN", {});
- });
-
diff --git a/browser/base/content/test/general/browser_bug559991.js b/browser/base/content/test/general/browser_bug559991.js
deleted file mode 100644
index b1516a8b4..000000000
--- a/browser/base/content/test/general/browser_bug559991.js
+++ /dev/null
@@ -1,42 +0,0 @@
-var tab;
-
-function test() {
-
- // ----------
- // Test setup
-
- waitForExplicitFinish();
-
- gPrefService.setBoolPref("browser.zoom.updateBackgroundTabs", true);
- gPrefService.setBoolPref("browser.zoom.siteSpecific", true);
-
- let uri = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-
- Task.spawn(function* () {
- tab = gBrowser.addTab();
- yield FullZoomHelper.load(tab, uri);
-
- // -------------------------------------------------------------------
- // Test - Trigger a tab switch that should update the zoom level
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab);
- ok(true, "applyPrefToSetting was called");
- }).then(endTest, FullZoomHelper.failAndContinue(endTest));
-}
-
-// -------------
-// Test clean-up
-function endTest() {
- Task.spawn(function* () {
- yield FullZoomHelper.removeTabAndWaitForLocationChange(tab);
-
- tab = null;
-
- if (gPrefService.prefHasUserValue("browser.zoom.updateBackgroundTabs"))
- gPrefService.clearUserPref("browser.zoom.updateBackgroundTabs");
-
- if (gPrefService.prefHasUserValue("browser.zoom.siteSpecific"))
- gPrefService.clearUserPref("browser.zoom.siteSpecific");
-
- finish();
- });
-}
diff --git a/browser/base/content/test/general/browser_bug561636.js b/browser/base/content/test/general/browser_bug561636.js
deleted file mode 100644
index 69bc475c3..000000000
--- a/browser/base/content/test/general/browser_bug561636.js
+++ /dev/null
@@ -1,370 +0,0 @@
-var gInvalidFormPopup = document.getElementById('invalid-form-popup');
-ok(gInvalidFormPopup,
- "The browser should have a popup to show when a form is invalid");
-
-function checkPopupShow()
-{
- ok(gInvalidFormPopup.state == 'showing' || gInvalidFormPopup.state == 'open',
- "[Test " + testId + "] The invalid form popup should be shown");
-}
-
-function checkPopupHide()
-{
- ok(gInvalidFormPopup.state != 'showing' && gInvalidFormPopup.state != 'open',
- "[Test " + testId + "] The invalid form popup should not be shown");
-}
-
-var gObserver = {
- QueryInterface : XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver]),
-
- notifyInvalidSubmit : function (aFormElement, aInvalidElements)
- {
- }
-};
-
-var testId = 0;
-
-function incrementTest()
-{
- testId++;
- info("Starting next part of test");
-}
-
-function getDocHeader()
-{
- return "<html><head><meta charset='utf-8'></head><body>" + getEmptyFrame();
-}
-
-function getDocFooter()
-{
- return "</body></html>";
-}
-
-function getEmptyFrame()
-{
- return "<iframe style='width:100px; height:30px; margin:3px; border:1px solid lightgray;' " +
- "name='t' srcdoc=\"<html><head><meta charset='utf-8'></head><body>form target</body></html>\"></iframe>";
-}
-
-function* openNewTab(uri, background)
-{
- let tab = gBrowser.addTab();
- let browser = gBrowser.getBrowserForTab(tab);
- if (!background) {
- gBrowser.selectedTab = tab;
- }
- yield promiseTabLoadEvent(tab, "data:text/html," + escape(uri));
- return browser;
-}
-
-function* clickChildElement(browser)
-{
- yield ContentTask.spawn(browser, {}, function* () {
- content.document.getElementById('s').click();
- });
-}
-
-function* blurChildElement(browser)
-{
- yield ContentTask.spawn(browser, {}, function* () {
- content.document.getElementById('i').blur();
- });
-}
-
-function* checkChildFocus(browser, message)
-{
- yield ContentTask.spawn(browser, [message, testId], function* (args) {
- let [msg, id] = args;
- var focused = content.document.activeElement == content.document.getElementById('i');
-
- var validMsg = true;
- if (msg) {
- validMsg = (msg == content.document.getElementById('i').validationMessage);
- }
-
- Assert.equal(focused, true, "Test " + id + " First invalid element should be focused");
- Assert.equal(validMsg, true, "Test " + id + " The panel should show the message from validationMessage");
- });
-}
-
-/**
- * In this test, we check that no popup appears if the form is valid.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- yield clickChildElement(browser);
-
- yield new Promise((resolve, reject) => {
- // XXXndeakin This isn't really going to work when the content is another process
- executeSoon(function() {
- checkPopupHide();
- resolve();
- });
- });
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that, when an invalid form is submitted,
- * the invalid element is focused and a popup appears.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input required id='i'><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that, when an invalid form is submitted,
- * the first invalid element is focused and a popup appears.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input><input id='i' required><input required><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that, we hide the popup by interacting with the
- * invalid element if the element becomes valid.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- let popupHiddenPromise = promiseWaitForEvent(gInvalidFormPopup, "popuphidden");
- EventUtils.synthesizeKey("a", {});
- yield popupHiddenPromise;
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that, we don't hide the popup by interacting with the
- * invalid element if the element is still invalid.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input type='email' id='i' required><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- yield new Promise((resolve, reject) => {
- EventUtils.synthesizeKey("a", {});
- executeSoon(function() {
- checkPopupShow();
- resolve();
- })
- });
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that we can hide the popup by blurring the invalid
- * element.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- let popupHiddenPromise = promiseWaitForEvent(gInvalidFormPopup, "popuphidden");
- yield blurChildElement(browser);
- yield popupHiddenPromise;
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that we can hide the popup by pressing TAB.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- let popupHiddenPromise = promiseWaitForEvent(gInvalidFormPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_TAB", {});
- yield popupHiddenPromise;
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that the popup will hide if we move to another tab.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>" + getDocFooter();
- let browser1 = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser1);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser1, gInvalidFormPopup.firstChild.textContent);
-
- let popupHiddenPromise = promiseWaitForEvent(gInvalidFormPopup, "popuphidden");
-
- let browser2 = yield openNewTab("data:text/html,<html></html>");
- yield popupHiddenPromise;
-
- gBrowser.removeTab(gBrowser.getTabForBrowser(browser1));
- gBrowser.removeTab(gBrowser.getTabForBrowser(browser2));
-});
-
-/**
- * In this test, we check that nothing happen if the invalid form is
- * submitted in a background tab.
- */
-add_task(function* ()
-{
- // Observers don't propagate currently across processes. We may add support for this in the
- // future via the addon compat layer.
- if (gMultiProcessBrowser) {
- return;
- }
-
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri, true);
- isnot(gBrowser.selectedBrowser, browser, "This tab should have been loaded in background");
-
- let notifierPromise = new Promise((resolve, reject) => {
- gObserver.notifyInvalidSubmit = function() {
- executeSoon(function() {
- checkPopupHide();
-
- // Clean-up
- Services.obs.removeObserver(gObserver, "invalidformsubmit");
- gObserver.notifyInvalidSubmit = function () {};
- resolve();
- });
- };
-
- Services.obs.addObserver(gObserver, "invalidformsubmit", false);
-
- executeSoon(function () {
- browser.contentDocument.getElementById('s').click();
- });
- });
-
- yield notifierPromise;
-
- gBrowser.removeTab(gBrowser.getTabForBrowser(browser));
-});
-
-/**
- * In this test, we check that the author defined error message is shown.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input x-moz-errormessage='foo' required id='i'><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- is(gInvalidFormPopup.firstChild.textContent, "foo",
- "The panel should show the author defined error message");
-
- gBrowser.removeCurrentTab();
-});
-
-/**
- * In this test, we check that the message is correctly updated when it changes.
- */
-add_task(function* ()
-{
- incrementTest();
- let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input type='email' required id='i'><input id='s' type='submit'></form>" + getDocFooter();
- let browser = yield openNewTab(uri);
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
- yield clickChildElement(browser);
- yield popupShownPromise;
-
- checkPopupShow();
- yield checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
-
- let inputPromise = promiseWaitForEvent(gBrowser.contentDocument.getElementById('i'), "input");
- EventUtils.synthesizeKey('f', {});
- yield inputPromise;
-
- // Now, the element suffers from another error, the message should have
- // been updated.
- yield new Promise((resolve, reject) => {
- // XXXndeakin This isn't really going to work when the content is another process
- executeSoon(function() {
- checkChildFocus(browser, gInvalidFormPopup.firstChild.textContent);
- resolve();
- });
- });
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug563588.js b/browser/base/content/test/general/browser_bug563588.js
deleted file mode 100644
index a1774fb7e..000000000
--- a/browser/base/content/test/general/browser_bug563588.js
+++ /dev/null
@@ -1,30 +0,0 @@
-function press(key, expectedPos) {
- var originalSelectedTab = gBrowser.selectedTab;
- EventUtils.synthesizeKey("VK_" + key.toUpperCase(), { accelKey: true });
- is(gBrowser.selectedTab, originalSelectedTab,
- "accel+" + key + " doesn't change which tab is selected");
- is(gBrowser.tabContainer.selectedIndex, expectedPos,
- "accel+" + key + " moves the tab to the expected position");
- is(document.activeElement, gBrowser.selectedTab,
- "accel+" + key + " leaves the selected tab focused");
-}
-
-function test() {
- gBrowser.addTab();
- gBrowser.addTab();
- is(gBrowser.tabs.length, 3, "got three tabs");
- is(gBrowser.tabs[0], gBrowser.selectedTab, "first tab is selected");
-
- gBrowser.selectedTab.focus();
- is(document.activeElement, gBrowser.selectedTab, "selected tab is focused");
-
- press("right", 1);
- press("down", 2);
- press("left", 1);
- press("up", 0);
- press("end", 2);
- press("home", 0);
-
- gBrowser.removeCurrentTab();
- gBrowser.removeCurrentTab();
-}
diff --git a/browser/base/content/test/general/browser_bug565575.js b/browser/base/content/test/general/browser_bug565575.js
deleted file mode 100644
index 3555a2e7f..000000000
--- a/browser/base/content/test/general/browser_bug565575.js
+++ /dev/null
@@ -1,14 +0,0 @@
-add_task(function* () {
- gBrowser.selectedBrowser.focus();
-
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => BrowserOpenTab(), false);
- ok(gURLBar.focused, "location bar is focused for a new tab");
-
- yield BrowserTestUtils.switchTab(gBrowser, gBrowser.tabs[0]);
- ok(!gURLBar.focused, "location bar isn't focused for the previously selected tab");
-
- yield BrowserTestUtils.switchTab(gBrowser, gBrowser.tabs[1]);
- ok(gURLBar.focused, "location bar is re-focused when selecting the new tab");
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug567306.js b/browser/base/content/test/general/browser_bug567306.js
deleted file mode 100644
index 742ff6726..000000000
--- a/browser/base/content/test/general/browser_bug567306.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var {Ci: interfaces, Cc: classes} = Components;
-
-var Clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
-var HasFindClipboard = Clipboard.supportsFindClipboard();
-
-add_task(function* () {
- let newwindow = yield BrowserTestUtils.openNewBrowserWindow();
-
- let selectedBrowser = newwindow.gBrowser.selectedBrowser;
- yield new Promise((resolve, reject) => {
- selectedBrowser.addEventListener("pageshow", function pageshowListener() {
- if (selectedBrowser.currentURI.spec == "about:blank")
- return;
-
- selectedBrowser.removeEventListener("pageshow", pageshowListener, true);
- ok(true, "pageshow listener called: " + newwindow.content.location);
- resolve();
- }, true);
- selectedBrowser.loadURI("data:text/html,<h1 id='h1'>Select Me</h1>");
- });
-
- yield SimpleTest.promiseFocus(newwindow);
-
- ok(!newwindow.gFindBarInitialized, "find bar is not yet initialized");
- let findBar = newwindow.gFindBar;
-
- yield ContentTask.spawn(selectedBrowser, { }, function* () {
- let elt = content.document.getElementById("h1");
- let selection = content.getSelection();
- let range = content.document.createRange();
- range.setStart(elt, 0);
- range.setEnd(elt, 1);
- selection.removeAllRanges();
- selection.addRange(range);
- });
-
- yield findBar.onFindCommand();
-
- // When the OS supports the Find Clipboard (OSX), the find field value is
- // persisted across Fx sessions, thus not useful to test.
- if (!HasFindClipboard)
- is(findBar._findField.value, "Select Me", "Findbar is initialized with selection");
- findBar.close();
- yield promiseWindowClosed(newwindow);
-});
-
diff --git a/browser/base/content/test/general/browser_bug575561.js b/browser/base/content/test/general/browser_bug575561.js
deleted file mode 100644
index b6d17a447..000000000
--- a/browser/base/content/test/general/browser_bug575561.js
+++ /dev/null
@@ -1,97 +0,0 @@
-requestLongerTimeout(2);
-
-const TEST_URL = "http://example.com/browser/browser/base/content/test/general/app_bug575561.html";
-
-add_task(function*() {
- SimpleTest.requestCompleteLog();
-
- // Pinned: Link to the same domain should not open a new tab
- // Tests link to http://example.com/browser/browser/base/content/test/general/dummy_page.html
- yield testLink(0, true, false);
- // Pinned: Link to a different subdomain should open a new tab
- // Tests link to http://test1.example.com/browser/browser/base/content/test/general/dummy_page.html
- yield testLink(1, true, true);
-
- // Pinned: Link to a different domain should open a new tab
- // Tests link to http://example.org/browser/browser/base/content/test/general/dummy_page.html
- yield testLink(2, true, true);
-
- // Not Pinned: Link to a different domain should not open a new tab
- // Tests link to http://example.org/browser/browser/base/content/test/general/dummy_page.html
- yield testLink(2, false, false);
-
- // Pinned: Targetted link should open a new tab
- // Tests link to http://example.org/browser/browser/base/content/test/general/dummy_page.html with target="foo"
- yield testLink(3, true, true);
-
- // Pinned: Link in a subframe should not open a new tab
- // Tests link to http://example.org/browser/browser/base/content/test/general/dummy_page.html in subframe
- yield testLink(0, true, false, true);
-
- // Pinned: Link to the same domain (with www prefix) should not open a new tab
- // Tests link to http://www.example.com/browser/browser/base/content/test/general/dummy_page.html
- yield testLink(4, true, false);
-
- // Pinned: Link to a data: URI should not open a new tab
- // Tests link to data:text/html,<!DOCTYPE html><html><body>Another Page</body></html>
- yield testLink(5, true, false);
-
- // Pinned: Link to an about: URI should not open a new tab
- // Tests link to about:logo
- yield testLink(function(doc) {
- let link = doc.createElement("a");
- link.textContent = "Link to Mozilla";
- link.href = "about:logo";
- doc.body.appendChild(link);
- return link;
- }, true, false, false, "about:robots");
-});
-
-var waitForPageLoad = Task.async(function*(browser, linkLocation) {
- yield waitForDocLoadComplete();
-
- is(browser.contentDocument.location.href, linkLocation, "Link should not open in a new tab");
-});
-
-var waitForTabOpen = Task.async(function*() {
- let event = yield promiseWaitForEvent(gBrowser.tabContainer, "TabOpen", true);
- ok(true, "Link should open a new tab");
-
- yield waitForDocLoadComplete(event.target.linkedBrowser);
- yield Promise.resolve();
-
- gBrowser.removeCurrentTab();
-});
-
-var testLink = Task.async(function*(aLinkIndexOrFunction, pinTab, expectNewTab, testSubFrame, aURL = TEST_URL) {
- let appTab = gBrowser.addTab(aURL, {skipAnimation: true});
- if (pinTab)
- gBrowser.pinTab(appTab);
- gBrowser.selectedTab = appTab;
-
- yield waitForDocLoadComplete();
-
- let browser = appTab.linkedBrowser;
- if (testSubFrame)
- browser = browser.contentDocument.querySelector("iframe");
-
- let link;
- if (typeof aLinkIndexOrFunction == "function") {
- link = aLinkIndexOrFunction(browser.contentDocument);
- } else {
- link = browser.contentDocument.querySelectorAll("a")[aLinkIndexOrFunction];
- }
-
- let promise;
- if (expectNewTab)
- promise = waitForTabOpen();
- else
- promise = waitForPageLoad(browser, link.href);
-
- info("Clicking " + link.textContent);
- link.click();
-
- yield promise;
-
- gBrowser.removeTab(appTab);
-});
diff --git a/browser/base/content/test/general/browser_bug575830.js b/browser/base/content/test/general/browser_bug575830.js
deleted file mode 100644
index 5393c08d7..000000000
--- a/browser/base/content/test/general/browser_bug575830.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-function test() {
- let tab1, tab2;
- const TEST_IMAGE = "http://example.org/browser/browser/base/content/test/general/moz.png";
-
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- tab1 = gBrowser.addTab();
- tab2 = gBrowser.addTab();
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab1);
- yield FullZoomHelper.load(tab1, TEST_IMAGE);
-
- is(ZoomManager.zoom, 1, "initial zoom level for first should be 1");
-
- FullZoom.enlarge();
- let zoom = ZoomManager.zoom;
- isnot(zoom, 1, "zoom level should have changed");
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab2);
- is(ZoomManager.zoom, 1, "initial zoom level for second tab should be 1");
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(tab1);
- is(ZoomManager.zoom, zoom, "zoom level for first tab should not have changed");
-
- yield FullZoomHelper.removeTabAndWaitForLocationChange(tab1);
- yield FullZoomHelper.removeTabAndWaitForLocationChange(tab2);
- }).then(finish, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug577121.js b/browser/base/content/test/general/browser_bug577121.js
deleted file mode 100644
index 5ebfdc115..000000000
--- a/browser/base/content/test/general/browser_bug577121.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- Services.prefs.setBoolPref("browser.tabs.animate", false);
- registerCleanupFunction(function() {
- Services.prefs.clearUserPref("browser.tabs.animate");
- });
-
- // Open 2 other tabs, and pin the second one. Like that, the initial tab
- // should get closed.
- let testTab1 = gBrowser.addTab();
- let testTab2 = gBrowser.addTab();
- gBrowser.pinTab(testTab2);
-
- // Now execute "Close other Tabs" on the first manually opened tab (tab1).
- // -> tab2 ist pinned, tab1 should remain open and the initial tab should
- // get closed.
- gBrowser.removeAllTabsBut(testTab1);
-
- is(gBrowser.tabs.length, 2, "there are two remaining tabs open");
- is(gBrowser.tabs[0], testTab2, "pinned tab2 stayed open");
- is(gBrowser.tabs[1], testTab1, "tab1 stayed open");
-
- // Cleanup. Close only one tab because we need an opened tab at the end of
- // the test.
- gBrowser.removeTab(testTab2);
-}
diff --git a/browser/base/content/test/general/browser_bug578534.js b/browser/base/content/test/general/browser_bug578534.js
deleted file mode 100644
index 0d61cca76..000000000
--- a/browser/base/content/test/general/browser_bug578534.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test() {
- let uriString = "http://example.com/";
- let cookieBehavior = "network.cookie.cookieBehavior";
- let uriObj = Services.io.newURI(uriString, null, null)
- let cp = Components.classes["@mozilla.org/cookie/permission;1"]
- .getService(Components.interfaces.nsICookiePermission);
-
- yield SpecialPowers.pushPrefEnv({ set: [[ cookieBehavior, 2 ]] });
- cp.setAccess(uriObj, cp.ACCESS_ALLOW);
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: uriString }, function* (browser) {
- yield ContentTask.spawn(browser, null, function() {
- is(content.navigator.cookieEnabled, true,
- "navigator.cookieEnabled should be true");
- });
- });
-
- cp.setAccess(uriObj, cp.ACCESS_DEFAULT);
-});
diff --git a/browser/base/content/test/general/browser_bug579872.js b/browser/base/content/test/general/browser_bug579872.js
deleted file mode 100644
index bc10ca0c8..000000000
--- a/browser/base/content/test/general/browser_bug579872.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- let newTab = gBrowser.addTab();
- waitForExplicitFinish();
- BrowserTestUtils.browserLoaded(newTab.linkedBrowser).then(mainPart);
-
- function mainPart() {
- gBrowser.pinTab(newTab);
- gBrowser.selectedTab = newTab;
-
- openUILinkIn("javascript:var x=0;", "current");
- is(gBrowser.tabs.length, 2, "Should open in current tab");
-
- openUILinkIn("http://example.com/1", "current");
- is(gBrowser.tabs.length, 2, "Should open in current tab");
-
- openUILinkIn("http://example.org/", "current");
- is(gBrowser.tabs.length, 3, "Should open in new tab");
-
- gBrowser.removeTab(newTab);
- gBrowser.removeTab(gBrowser.tabs[1]); // example.org tab
- finish();
- }
- newTab.linkedBrowser.loadURI("http://example.com");
-}
diff --git a/browser/base/content/test/general/browser_bug580638.js b/browser/base/content/test/general/browser_bug580638.js
deleted file mode 100644
index 66defafe3..000000000
--- a/browser/base/content/test/general/browser_bug580638.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- function testState(aPinned) {
- function elemAttr(id, attr) {
- return document.getElementById(id).getAttribute(attr);
- }
-
- if (aPinned) {
- is(elemAttr("key_close", "disabled"), "true",
- "key_close should be disabled when a pinned-tab is selected");
- is(elemAttr("menu_close", "key"), "",
- "menu_close shouldn't have a key set when a pinned is selected");
- }
- else {
- is(elemAttr("key_close", "disabled"), "",
- "key_closed shouldn't have disabled state set when a non-pinned tab is selected");
- is(elemAttr("menu_close", "key"), "key_close",
- "menu_close should have key_close set as its key when a non-pinned tab is selected");
- }
- }
-
- let lastSelectedTab = gBrowser.selectedTab;
- ok(!lastSelectedTab.pinned, "We should have started with a regular tab selected");
-
- testState(false);
-
- let pinnedTab = gBrowser.addTab("about:blank");
- gBrowser.pinTab(pinnedTab);
-
- // Just pinning the tab shouldn't change the key state.
- testState(false);
-
- // Test updating key state after selecting a tab.
- gBrowser.selectedTab = pinnedTab;
- testState(true);
-
- gBrowser.selectedTab = lastSelectedTab;
- testState(false);
-
- gBrowser.selectedTab = pinnedTab;
- testState(true);
-
- // Test updating the key state after un/pinning the tab.
- gBrowser.unpinTab(pinnedTab);
- testState(false);
-
- gBrowser.pinTab(pinnedTab);
- testState(true);
-
- // Test updating the key state after removing the tab.
- gBrowser.removeTab(pinnedTab);
- testState(false);
-
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug580956.js b/browser/base/content/test/general/browser_bug580956.js
deleted file mode 100644
index b8e7bc20b..000000000
--- a/browser/base/content/test/general/browser_bug580956.js
+++ /dev/null
@@ -1,26 +0,0 @@
-function numClosedTabs() {
- return SessionStore.getClosedTabCount(window);
-}
-
-function isUndoCloseEnabled() {
- updateTabContextMenu();
- return !document.getElementById("context_undoCloseTab").disabled;
-}
-
-function test() {
- waitForExplicitFinish();
-
- gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", 0);
- gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
- is(numClosedTabs(), 0, "There should be 0 closed tabs.");
- ok(!isUndoCloseEnabled(), "Undo Close Tab should be disabled.");
-
- var tab = gBrowser.addTab("http://mochi.test:8888/");
- var browser = gBrowser.getBrowserForTab(tab);
- BrowserTestUtils.browserLoaded(browser).then(() => {
- BrowserTestUtils.removeTab(tab).then(() => {
- ok(isUndoCloseEnabled(), "Undo Close Tab should be enabled.");
- finish();
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_bug581242.js b/browser/base/content/test/general/browser_bug581242.js
deleted file mode 100644
index 668c0cd41..000000000
--- a/browser/base/content/test/general/browser_bug581242.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- // Create a new tab and load about:addons
- 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);
-}
diff --git a/browser/base/content/test/general/browser_bug581253.js b/browser/base/content/test/general/browser_bug581253.js
deleted file mode 100644
index 0c537c3d3..000000000
--- a/browser/base/content/test/general/browser_bug581253.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var testURL = "data:text/plain,nothing but plain text";
-var testTag = "581253_tag";
-var timerID = -1;
-
-function test() {
- registerCleanupFunction(function() {
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- 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);
-
- content.location = testURL;
-}
-
-function waitForStarChange(aValue, aCallback) {
- let expectedStatus = aValue ? BookmarkingUI.STATUS_STARRED
- : BookmarkingUI.STATUS_UNSTARRED;
- if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING ||
- BookmarkingUI.status != expectedStatus) {
- info("Waiting for star button change.");
- setTimeout(waitForStarChange, 50, aValue, aCallback);
- return;
- }
- aCallback();
-}
-
-function onStarred() {
- is(BookmarkingUI.status, BookmarkingUI.STATUS_STARRED,
- "star button indicates that the page is bookmarked");
-
- let uri = makeURI(testURL);
- let tagTxn = new PlacesTagURITransaction(uri, [testTag]);
- PlacesUtils.transactionManager.doTransaction(tagTxn);
-
- StarUI.panel.addEventListener("popupshown", onPanelShown, false);
- BookmarkingUI.star.click();
-}
-
-function onPanelShown(aEvent) {
- if (aEvent.target == StarUI.panel) {
- StarUI.panel.removeEventListener("popupshown", arguments.callee, false);
- let tagsField = document.getElementById("editBMPanel_tagsField");
- ok(tagsField.value == testTag, "tags field value was set");
- tagsField.focus();
-
- StarUI.panel.addEventListener("popuphidden", onPanelHidden, false);
- let removeButton = document.getElementById("editBookmarkPanelRemoveButton");
- removeButton.click();
- }
-}
-
-function onPanelHidden(aEvent) {
- if (aEvent.target == StarUI.panel) {
- StarUI.panel.removeEventListener("popuphidden", arguments.callee, false);
-
- executeSoon(function() {
- ok(!PlacesUtils.bookmarks.isBookmarked(makeURI(testURL)),
- "the bookmark for the test url has been removed");
- is(BookmarkingUI.status, BookmarkingUI.STATUS_UNSTARRED,
- "star button indicates that the bookmark has been removed");
- gBrowser.removeCurrentTab();
- PlacesTestUtils.clearHistory().then(finish);
- });
- }
-}
diff --git a/browser/base/content/test/general/browser_bug585558.js b/browser/base/content/test/general/browser_bug585558.js
deleted file mode 100644
index bae832b4d..000000000
--- a/browser/base/content/test/general/browser_bug585558.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var tabs = [];
-
-function addTab(aURL) {
- tabs.push(gBrowser.addTab(aURL, {skipAnimation: true}));
-}
-
-function testAttrib(elem, attrib, attribValue, msg) {
- is(elem.hasAttribute(attrib), attribValue, msg);
-}
-
-function test() {
- waitForExplicitFinish();
-
- is(gBrowser.tabs.length, 1, "one tab is open initially");
-
- // Add several new tabs in sequence, hiding some, to ensure that the
- // correct attributes get set
-
- addTab("http://mochi.test:8888/#0");
- addTab("http://mochi.test:8888/#1");
- addTab("http://mochi.test:8888/#2");
- addTab("http://mochi.test:8888/#3");
-
- gBrowser.selectedTab = gBrowser.tabs[0];
- testAttrib(gBrowser.tabs[0], "first-visible-tab", true,
- "First tab marked first-visible-tab!");
- testAttrib(gBrowser.tabs[4], "last-visible-tab", true,
- "Fifth tab marked last-visible-tab!");
- testAttrib(gBrowser.tabs[0], "selected", true, "First tab marked selected!");
- testAttrib(gBrowser.tabs[0], "afterselected-visible", false,
- "First tab not marked afterselected-visible!");
- testAttrib(gBrowser.tabs[1], "afterselected-visible", true,
- "Second tab marked afterselected-visible!");
- gBrowser.hideTab(gBrowser.tabs[1]);
- executeSoon(test_hideSecond);
-}
-
-function test_hideSecond() {
- testAttrib(gBrowser.tabs[2], "afterselected-visible", true,
- "Third tab marked afterselected-visible!");
- gBrowser.showTab(gBrowser.tabs[1])
- executeSoon(test_showSecond);
-}
-
-function test_showSecond() {
- testAttrib(gBrowser.tabs[1], "afterselected-visible", true,
- "Second tab marked afterselected-visible!");
- testAttrib(gBrowser.tabs[2], "afterselected-visible", false,
- "Third tab not marked as afterselected-visible!");
- gBrowser.selectedTab = gBrowser.tabs[1];
- gBrowser.hideTab(gBrowser.tabs[0]);
- executeSoon(test_hideFirst);
-}
-
-function test_hideFirst() {
- testAttrib(gBrowser.tabs[0], "first-visible-tab", false,
- "Hidden first tab not marked first-visible-tab!");
- testAttrib(gBrowser.tabs[1], "first-visible-tab", true,
- "Second tab marked first-visible-tab!");
- gBrowser.showTab(gBrowser.tabs[0]);
- executeSoon(test_showFirst);
-}
-
-function test_showFirst() {
- testAttrib(gBrowser.tabs[0], "first-visible-tab", true,
- "First tab marked first-visible-tab!");
- gBrowser.selectedTab = gBrowser.tabs[2];
- testAttrib(gBrowser.tabs[3], "afterselected-visible", true,
- "Fourth tab marked afterselected-visible!");
-
- gBrowser.moveTabTo(gBrowser.selectedTab, 1);
- executeSoon(test_movedLower);
-}
-
-function test_movedLower() {
- testAttrib(gBrowser.tabs[2], "afterselected-visible", true,
- "Third tab marked afterselected-visible!");
- test_hoverOne();
-}
-
-function test_hoverOne() {
- EventUtils.synthesizeMouseAtCenter(gBrowser.tabs[4], { type: "mousemove" });
- testAttrib(gBrowser.tabs[3], "beforehovered", true, "Fourth tab marked beforehovered");
- EventUtils.synthesizeMouseAtCenter(gBrowser.tabs[3], { type: "mousemove" });
- testAttrib(gBrowser.tabs[2], "beforehovered", true, "Third tab marked beforehovered!");
- testAttrib(gBrowser.tabs[2], "afterhovered", false, "Third tab not marked afterhovered!");
- testAttrib(gBrowser.tabs[4], "afterhovered", true, "Fifth tab marked afterhovered!");
- testAttrib(gBrowser.tabs[4], "beforehovered", false, "Fifth tab not marked beforehovered!");
- testAttrib(gBrowser.tabs[0], "beforehovered", false, "First tab not marked beforehovered!");
- testAttrib(gBrowser.tabs[0], "afterhovered", false, "First tab not marked afterhovered!");
- testAttrib(gBrowser.tabs[1], "beforehovered", false, "Second tab not marked beforehovered!");
- testAttrib(gBrowser.tabs[1], "afterhovered", false, "Second tab not marked afterhovered!");
- testAttrib(gBrowser.tabs[3], "beforehovered", false, "Fourth tab not marked beforehovered!");
- testAttrib(gBrowser.tabs[3], "afterhovered", false, "Fourth tab not marked afterhovered!");
- gBrowser.removeTab(tabs.pop());
- executeSoon(test_hoverStatePersistence);
-}
-
-function test_hoverStatePersistence() {
- // Test that the afterhovered and beforehovered attributes are still there when
- // a tab is selected and then unselected again. See bug 856107.
-
- function assertState() {
- testAttrib(gBrowser.tabs[0], "beforehovered", true, "First tab still marked beforehovered!");
- testAttrib(gBrowser.tabs[0], "afterhovered", false, "First tab not marked afterhovered!");
- testAttrib(gBrowser.tabs[2], "afterhovered", true, "Third tab still marked afterhovered!");
- testAttrib(gBrowser.tabs[2], "beforehovered", false, "Third tab not marked afterhovered!");
- testAttrib(gBrowser.tabs[1], "beforehovered", false, "Second tab not marked beforehovered!");
- testAttrib(gBrowser.tabs[1], "afterhovered", false, "Second tab not marked afterhovered!");
- testAttrib(gBrowser.tabs[3], "beforehovered", false, "Fourth tab not marked beforehovered!");
- testAttrib(gBrowser.tabs[3], "afterhovered", false, "Fourth tab not marked afterhovered!");
- }
-
- gBrowser.selectedTab = gBrowser.tabs[3];
- EventUtils.synthesizeMouseAtCenter(gBrowser.tabs[1], { type: "mousemove" });
- assertState();
- gBrowser.selectedTab = gBrowser.tabs[1];
- assertState();
- gBrowser.selectedTab = gBrowser.tabs[3];
- assertState();
- executeSoon(test_pinning);
-}
-
-function test_pinning() {
- gBrowser.selectedTab = gBrowser.tabs[3];
- testAttrib(gBrowser.tabs[3], "last-visible-tab", true,
- "Fourth tab marked last-visible-tab!");
- testAttrib(gBrowser.tabs[3], "selected", true, "Fourth tab marked selected!");
- testAttrib(gBrowser.tabs[3], "afterselected-visible", false,
- "Fourth tab not marked afterselected-visible!");
- // Causes gBrowser.tabs to change indices
- gBrowser.pinTab(gBrowser.tabs[3]);
- testAttrib(gBrowser.tabs[3], "last-visible-tab", true,
- "Fourth tab marked last-visible-tab!");
- testAttrib(gBrowser.tabs[1], "afterselected-visible", true,
- "Second tab marked afterselected-visible!");
- testAttrib(gBrowser.tabs[0], "first-visible-tab", true,
- "First tab marked first-visible-tab!");
- testAttrib(gBrowser.tabs[0], "selected", true, "First tab marked selected!");
- gBrowser.selectedTab = gBrowser.tabs[1];
- testAttrib(gBrowser.tabs[2], "afterselected-visible", true,
- "Third tab marked afterselected-visible!");
- test_cleanUp();
-}
-
-function test_cleanUp() {
- tabs.forEach(gBrowser.removeTab, gBrowser);
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug585785.js b/browser/base/content/test/general/browser_bug585785.js
deleted file mode 100644
index 4f9045231..000000000
--- a/browser/base/content/test/general/browser_bug585785.js
+++ /dev/null
@@ -1,35 +0,0 @@
-var tab;
-
-function test() {
- waitForExplicitFinish();
-
- tab = gBrowser.addTab();
- isnot(tab.getAttribute("fadein"), "true", "newly opened tab is yet to fade in");
-
- // Try to remove the tab right before the opening animation's first frame
- window.requestAnimationFrame(checkAnimationState);
-}
-
-function checkAnimationState() {
- is(tab.getAttribute("fadein"), "true", "tab opening animation initiated");
-
- info(window.getComputedStyle(tab).maxWidth);
- gBrowser.removeTab(tab, { animate: true });
- if (!tab.parentNode) {
- ok(true, "tab removed synchronously since the opening animation hasn't moved yet");
- finish();
- return;
- }
-
- info("tab didn't close immediately, so the tab opening animation must have started moving");
- info("waiting for the tab to close asynchronously");
- tab.addEventListener("transitionend", function (event) {
- if (event.propertyName == "max-width") {
- tab.removeEventListener("transitionend", arguments.callee, false);
- executeSoon(function () {
- ok(!tab.parentNode, "tab removed asynchronously");
- finish();
- });
- }
- }, false);
-}
diff --git a/browser/base/content/test/general/browser_bug585830.js b/browser/base/content/test/general/browser_bug585830.js
deleted file mode 100644
index 6d3adf198..000000000
--- a/browser/base/content/test/general/browser_bug585830.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- let tab1 = gBrowser.selectedTab;
- let tab2 = gBrowser.addTab("about:blank", {skipAnimation: true});
- gBrowser.addTab();
- gBrowser.selectedTab = tab2;
-
- gBrowser.removeCurrentTab({animate: true});
- gBrowser.tabContainer.advanceSelectedTab(-1, true);
- is(gBrowser.selectedTab, tab1, "First tab should be selected");
- gBrowser.removeTab(tab2);
-
- // test for "null has no properties" fix. See Bug 585830 Comment 13
- gBrowser.removeCurrentTab({animate: true});
- try {
- gBrowser.tabContainer.advanceSelectedTab(-1, false);
- } catch (err) {
- ok(false, "Shouldn't throw");
- }
-
- gBrowser.removeTab(tab1);
-}
diff --git a/browser/base/content/test/general/browser_bug590206.js b/browser/base/content/test/general/browser_bug590206.js
deleted file mode 100644
index f73d144e9..000000000
--- a/browser/base/content/test/general/browser_bug590206.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Test the identity mode UI for a variety of page types
- */
-
-"use strict";
-
-const DUMMY = "browser/browser/base/content/test/general/dummy_page.html";
-
-function loadNewTab(url) {
- return BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-}
-
-function getIdentityMode() {
- return document.getElementById("identity-box").className;
-}
-
-function getConnectionState() {
- gIdentityHandler.refreshIdentityPopup();
- return document.getElementById("identity-popup").getAttribute("connection");
-}
-
-// This test is slow on Linux debug e10s
-requestLongerTimeout(2);
-
-add_task(function* test_webpage() {
- let oldTab = gBrowser.selectedTab;
-
- let newTab = yield loadNewTab("http://example.com/" + DUMMY);
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_blank() {
- let oldTab = gBrowser.selectedTab;
-
- let newTab = yield loadNewTab("about:blank");
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_chrome() {
- let oldTab = gBrowser.selectedTab;
-
- let newTab = yield loadNewTab("chrome://mozapps/content/extensions/extensions.xul");
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_https() {
- let oldTab = gBrowser.selectedTab;
-
- let newTab = yield loadNewTab("https://example.com/" + DUMMY);
- is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_addons() {
- let oldTab = gBrowser.selectedTab;
-
- let newTab = yield loadNewTab("about:addons");
- is(getIdentityMode(), "chromeUI", "Identity should be chrome");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "chromeUI", "Identity should be chrome");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_file() {
- let oldTab = gBrowser.selectedTab;
- let fileURI = getTestFilePath("");
-
- let newTab = yield loadNewTab(fileURI);
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_resource_uri() {
- let oldTab = gBrowser.selectedTab;
- let dataURI = "resource://gre/modules/Services.jsm";
-
- let newTab = yield loadNewTab(dataURI);
-
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_data_uri() {
- let oldTab = gBrowser.selectedTab;
- let dataURI = "data:text/html,hi"
-
- let newTab = yield loadNewTab(dataURI);
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* test_about_uri() {
- let oldTab = gBrowser.selectedTab;
- let aboutURI = "about:robots"
-
- let newTab = yield loadNewTab(aboutURI);
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.selectedTab = oldTab;
- is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
-
- gBrowser.selectedTab = newTab;
- is(getConnectionState(), "file", "Connection should be file");
-
- gBrowser.removeTab(newTab);
-});
diff --git a/browser/base/content/test/general/browser_bug592338.js b/browser/base/content/test/general/browser_bug592338.js
deleted file mode 100644
index ca9cc361a..000000000
--- a/browser/base/content/test/general/browser_bug592338.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-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, false);
- aCallback(PopupNotifications.panel);
- }, false);
-}
-
-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);
-
- gBrowser.selectedTab = gBrowser.addTab("http://example.org/browser/browser/base/content/test/general/bug592338.html");
- gBrowser.selectedBrowser.addEventListener("pageshow", function() {
- if (gBrowser.contentDocument.location.href == "about:blank")
- return;
-
- gBrowser.selectedBrowser.removeEventListener("pageshow", arguments.callee, false);
-
- executeSoon(function() {
- BrowserTestUtils.synthesizeMouse("#theme-install", 2, 2, {}, gBrowser.selectedBrowser);
-
- is(LightweightThemeManager.currentTheme, null, "Should not have installed the test theme");
-
- gBrowser.removeTab(gBrowser.selectedTab);
-
- pm.remove(makeURI("http://example.org/"), "install");
-
- runNextTest();
- });
- }, false);
-},
-
-function test_install_lwtheme() {
- is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected");
-
- var pm = Services.perms;
- pm.add(makeURI("https://example.com/"), "install", pm.ALLOW_ACTION);
-
- gBrowser.selectedTab = gBrowser.addTab("https://example.com/browser/browser/base/content/test/general/bug592338.html");
- gBrowser.selectedBrowser.addEventListener("pageshow", function() {
- if (gBrowser.contentDocument.location.href == "about:blank")
- return;
-
- gBrowser.selectedBrowser.removeEventListener("pageshow", arguments.callee, false);
-
- BrowserTestUtils.synthesizeMouse("#theme-install", 2, 2, {}, gBrowser.selectedBrowser);
- let notificationBox = gBrowser.getNotificationBox(gBrowser.selectedBrowser);
- waitForCondition(
- () => notificationBox.getNotificationWithValue("lwtheme-install-notification"),
- () => {
- is(LightweightThemeManager.currentTheme.id, "test", "Should have installed the test theme");
-
- LightweightThemeManager.currentTheme = null;
- gBrowser.removeTab(gBrowser.selectedTab);
- Services.perms.remove(makeURI("http://example.com/"), "install");
-
- runNextTest();
- }
- );
- }, false);
-},
-
-function test_lwtheme_switch_theme() {
- is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected");
-
- AddonManager.getAddonByID("theme-xpi@tests.mozilla.org", function(aAddon) {
- aAddon.userDisabled = false;
- ok(aAddon.isActive, "Theme should have immediately enabled");
- Services.prefs.setBoolPref("extensions.dss.enabled", false);
-
- var pm = Services.perms;
- pm.add(makeURI("https://example.com/"), "install", pm.ALLOW_ACTION);
-
- gBrowser.selectedTab = gBrowser.addTab("https://example.com/browser/browser/base/content/test/general/bug592338.html");
- gBrowser.selectedBrowser.addEventListener("pageshow", function() {
- if (gBrowser.contentDocument.location.href == "about:blank")
- return;
-
- gBrowser.selectedBrowser.removeEventListener("pageshow", arguments.callee, false);
-
- executeSoon(function() {
- wait_for_notification(function(aPanel) {
- is(LightweightThemeManager.currentTheme, null, "Should not have installed the test lwtheme");
- ok(aAddon.isActive, "Test theme should still be active");
-
- let notification = aPanel.childNodes[0];
- is(notification.button.label, "Restart Now", "Should have seen the right button");
-
- ok(aAddon.userDisabled, "Should be waiting to disable the test theme");
- aAddon.userDisabled = false;
- Services.prefs.setBoolPref("extensions.dss.enabled", true);
-
- gBrowser.removeTab(gBrowser.selectedTab);
-
- Services.perms.remove(makeURI("http://example.com"), "install");
-
- runNextTest();
- });
- BrowserTestUtils.synthesizeMouse("#theme-install", 2, 2, {}, gBrowser.selectedBrowser);
- });
- }, false);
- });
-}
-];
-
-function runNextTest() {
- AddonManager.getAllInstalls(function(aInstalls) {
- is(aInstalls.length, 0, "Should be no active installs");
-
- if (TESTS.length == 0) {
- AddonManager.getAddonByID("theme-xpi@tests.mozilla.org", function(aAddon) {
- aAddon.uninstall();
-
- Services.prefs.setBoolPref("extensions.logging.enabled", false);
- Services.prefs.setBoolPref("extensions.dss.enabled", false);
-
- finish();
- });
- return;
- }
-
- info("Running " + TESTS[0].name);
- TESTS.shift()();
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref("extensions.logging.enabled", true);
-
- AddonManager.getInstallForURL(TESTROOT + "theme.xpi", function(aInstall) {
- aInstall.addListener({
- onInstallEnded: function() {
- AddonManager.getAddonByID("theme-xpi@tests.mozilla.org", function(aAddon) {
- isnot(aAddon, null, "Should have installed the test theme.");
-
- // In order to switch themes while the test is running we turn on dynamic
- // theme switching. This means the test isn't exactly correct but should
- // do some good
- Services.prefs.setBoolPref("extensions.dss.enabled", true);
-
- runNextTest();
- });
- }
- });
-
- aInstall.install();
- }, "application/x-xpinstall");
-}
diff --git a/browser/base/content/test/general/browser_bug594131.js b/browser/base/content/test/general/browser_bug594131.js
deleted file mode 100644
index ce09026ac..000000000
--- a/browser/base/content/test/general/browser_bug594131.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- let newTab = gBrowser.addTab("http://example.com");
- waitForExplicitFinish();
- BrowserTestUtils.browserLoaded(newTab.linkedBrowser).then(mainPart);
-
- function mainPart() {
- gBrowser.pinTab(newTab);
- gBrowser.selectedTab = newTab;
-
- openUILinkIn("http://example.org/", "current", { inBackground: true });
- isnot(gBrowser.selectedTab, newTab, "shouldn't load in background");
-
- gBrowser.removeTab(newTab);
- gBrowser.removeTab(gBrowser.tabs[1]); // example.org tab
- finish();
- }
-}
diff --git a/browser/base/content/test/general/browser_bug595507.js b/browser/base/content/test/general/browser_bug595507.js
deleted file mode 100644
index 54ae42346..000000000
--- a/browser/base/content/test/general/browser_bug595507.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Make sure that the form validation error message shows even if the form is in an iframe.
- */
-add_task(function* () {
- let uri = "<iframe src=\"data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input required id='i'><input id='s' type='submit'></form>\"</iframe>";
-
- var gInvalidFormPopup = document.getElementById('invalid-form-popup');
- ok(gInvalidFormPopup,
- "The browser should have a popup to show when a form is invalid");
-
- let tab = gBrowser.addTab();
- let browser = gBrowser.getBrowserForTab(tab);
- gBrowser.selectedTab = tab;
-
- yield promiseTabLoadEvent(tab, "data:text/html," + escape(uri));
-
- let popupShownPromise = promiseWaitForEvent(gInvalidFormPopup, "popupshown");
-
- yield ContentTask.spawn(browser, {}, function* () {
- content.document.getElementsByTagName('iframe')[0]
- .contentDocument.getElementById('s').click();
- });
- yield popupShownPromise;
-
- yield ContentTask.spawn(browser, {}, function* () {
- let childdoc = content.document.getElementsByTagName('iframe')[0].contentDocument;
- Assert.equal(childdoc.activeElement, childdoc.getElementById("i"),
- "First invalid element should be focused");
- });
-
- ok(gInvalidFormPopup.state == 'showing' || gInvalidFormPopup.state == 'open',
- "The invalid form popup should be shown");
-
- gBrowser.removeCurrentTab();
-});
-
diff --git a/browser/base/content/test/general/browser_bug596687.js b/browser/base/content/test/general/browser_bug596687.js
deleted file mode 100644
index 5c2b4fbfe..000000000
--- a/browser/base/content/test/general/browser_bug596687.js
+++ /dev/null
@@ -1,25 +0,0 @@
-add_task(function* test() {
- var tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
-
- var gotTabAttrModified = false;
- var gotTabClose = false;
-
- function onTabClose() {
- gotTabClose = true;
- tab.addEventListener("TabAttrModified", onTabAttrModified, false);
- }
-
- function onTabAttrModified() {
- gotTabAttrModified = true;
- }
-
- tab.addEventListener("TabClose", onTabClose, false);
-
- yield BrowserTestUtils.removeTab(tab);
-
- ok(gotTabClose, "should have got the TabClose event");
- ok(!gotTabAttrModified, "shouldn't have got the TabAttrModified event after TabClose");
-
- tab.removeEventListener("TabClose", onTabClose, false);
- tab.removeEventListener("TabAttrModified", onTabAttrModified, false);
-});
diff --git a/browser/base/content/test/general/browser_bug597218.js b/browser/base/content/test/general/browser_bug597218.js
deleted file mode 100644
index 5f4ededc3..000000000
--- a/browser/base/content/test/general/browser_bug597218.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- // establish initial state
- is(gBrowser.tabs.length, 1, "we start with one tab");
-
- // create a tab
- let tab = gBrowser.loadOneTab("about:blank");
- ok(!tab.hidden, "tab starts out not hidden");
- is(gBrowser.tabs.length, 2, "we now have two tabs");
-
- // make sure .hidden is read-only
- tab.hidden = true;
- ok(!tab.hidden, "can't set .hidden directly");
-
- // hide the tab
- gBrowser.hideTab(tab);
- ok(tab.hidden, "tab is hidden");
-
- // now pin it and make sure it gets unhidden
- gBrowser.pinTab(tab);
- ok(tab.pinned, "tab was pinned");
- ok(!tab.hidden, "tab was unhidden");
-
- // try hiding it now that it's pinned; shouldn't be able to
- gBrowser.hideTab(tab);
- ok(!tab.hidden, "tab did not hide");
-
- // clean up
- gBrowser.removeTab(tab);
- is(gBrowser.tabs.length, 1, "we finish with one tab");
-
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug609700.js b/browser/base/content/test/general/browser_bug609700.js
deleted file mode 100644
index 8b4f1ea91..000000000
--- a/browser/base/content/test/general/browser_bug609700.js
+++ /dev/null
@@ -1,20 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- Services.ww.registerNotification(function (aSubject, aTopic, aData) {
- if (aTopic == "domwindowopened") {
- Services.ww.unregisterNotification(arguments.callee);
-
- ok(true, "duplicateTabIn opened a new window");
-
- whenDelayedStartupFinished(aSubject, function () {
- executeSoon(function () {
- aSubject.close();
- finish();
- });
- }, false);
- }
- });
-
- duplicateTabIn(gBrowser.selectedTab, "window");
-}
diff --git a/browser/base/content/test/general/browser_bug623893.js b/browser/base/content/test/general/browser_bug623893.js
deleted file mode 100644
index fa6da1b22..000000000
--- a/browser/base/content/test/general/browser_bug623893.js
+++ /dev/null
@@ -1,37 +0,0 @@
-add_task(function* test() {
- yield BrowserTestUtils.withNewTab("data:text/plain;charset=utf-8,1", function* (browser) {
- BrowserTestUtils.loadURI(browser, "data:text/plain;charset=utf-8,2");
- yield BrowserTestUtils.browserLoaded(browser);
-
- BrowserTestUtils.loadURI(browser, "data:text/plain;charset=utf-8,3");
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield duplicate(0, "maintained the original index");
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- yield duplicate(-1, "went back");
- yield duplicate(1, "went forward");
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- });
-});
-
-function promiseGetIndex(browser) {
- return ContentTask.spawn(browser, null, function() {
- let shistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISHistory);
- return shistory.index;
- });
-}
-
-let duplicate = Task.async(function* (delta, msg, cb) {
- var startIndex = yield promiseGetIndex(gBrowser.selectedBrowser);
-
- duplicateTabIn(gBrowser.selectedTab, "tab", delta);
-
- let tab = gBrowser.selectedTab;
- yield BrowserTestUtils.waitForEvent(tab, "SSTabRestored");
-
- let endIndex = yield promiseGetIndex(gBrowser.selectedBrowser);
- is(endIndex, startIndex + delta, msg);
-});
diff --git a/browser/base/content/test/general/browser_bug624734.js b/browser/base/content/test/general/browser_bug624734.js
deleted file mode 100644
index d6fc7acbc..000000000
--- a/browser/base/content/test/general/browser_bug624734.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Bug 624734 - Star UI has no tooltip until bookmarked page is visited
-
-function finishTest() {
- is(BookmarkingUI.button.getAttribute("buttontooltiptext"),
- BookmarkingUI._unstarredTooltip,
- "Star icon should have the unstarred tooltip text");
-
- gBrowser.removeCurrentTab();
- finish();
-}
-
-function test() {
- waitForExplicitFinish();
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
- if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING) {
- waitForCondition(() => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING, finishTest, "BookmarkingUI was updating for too long");
- } else {
- finishTest();
- }
- });
-
- tab.linkedBrowser.loadURI("http://example.com/browser/browser/base/content/test/general/dummy_page.html");
-}
diff --git a/browser/base/content/test/general/browser_bug633691.js b/browser/base/content/test/general/browser_bug633691.js
deleted file mode 100644
index 28a8440ff..000000000
--- a/browser/base/content/test/general/browser_bug633691.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-add_task(function* test() {
- const URL = "data:text/html,<iframe width='700' height='700'></iframe>";
- yield BrowserTestUtils.withNewTab({ gBrowser, url: URL }, function* (browser) {
- yield ContentTask.spawn(browser,
- { is_element_hidden_: is_element_hidden.toSource(),
- is_hidden_: is_hidden.toSource() },
- function* ({ is_element_hidden_, is_hidden_ }) {
- let loadError =
- ContentTaskUtils.waitForEvent(this, "AboutNetErrorLoad", false, null, true);
- let iframe = content.document.querySelector("iframe");
- iframe.src = "https://expired.example.com/";
-
- yield loadError;
-
- let is_hidden = eval(`(() => ${is_hidden_})()`);
- let is_element_hidden = eval(`(() => ${is_element_hidden_})()`);
- let doc = content.document.getElementsByTagName("iframe")[0].contentDocument;
- let aP = doc.getElementById("badCertAdvancedPanel");
- ok(aP, "Advanced content should exist");
- void is_hidden; // Quiet eslint warnings (actual use under is_element_hidden)
- is_element_hidden(aP, "Advanced content should not be visible by default")
- });
- });
-});
diff --git a/browser/base/content/test/general/browser_bug647886.js b/browser/base/content/test/general/browser_bug647886.js
deleted file mode 100644
index 6c28c465c..000000000
--- a/browser/base/content/test/general/browser_bug647886.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- content.history.pushState({}, "2", "2.html");
- });
-
- var backButton = document.getElementById("back-button");
- var rect = backButton.getBoundingClientRect();
-
- info("waiting for the history menu to open");
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(backButton, "popupshown");
- EventUtils.synthesizeMouseAtCenter(backButton, {type: "mousedown"});
- EventUtils.synthesizeMouse(backButton, rect.width / 2, rect.height, {type: "mouseup"});
- let event = yield popupShownPromise;
-
- ok(true, "history menu opened");
-
- // Wait for the session data to be flushed before continuing the test
- yield new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
-
- is(event.target.children.length, 2, "Two history items");
-
- let node = event.target.firstChild;
- is(node.getAttribute("uri"), "http://example.com/2.html", "first item uri");
- is(node.getAttribute("index"), "1", "first item index");
- is(node.getAttribute("historyindex"), "0", "first item historyindex");
-
- node = event.target.lastChild;
- is(node.getAttribute("uri"), "http://example.com/", "second item uri");
- is(node.getAttribute("index"), "0", "second item index");
- is(node.getAttribute("historyindex"), "-1", "second item historyindex");
-
- event.target.hidePopup();
- gBrowser.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/general/browser_bug655584.js b/browser/base/content/test/general/browser_bug655584.js
deleted file mode 100644
index b836e3173..000000000
--- a/browser/base/content/test/general/browser_bug655584.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Bug 655584 - awesomebar suggestions don't update after tab is closed
-
-add_task(function* () {
- var tab1 = gBrowser.addTab();
- var tab2 = gBrowser.addTab();
-
- // When urlbar in a new tab is focused, and a tab switch occurs,
- // the urlbar popup should be closed
- yield BrowserTestUtils.switchTab(gBrowser, tab2);
- gURLBar.focus(); // focus the urlbar in the tab we will switch to
- yield BrowserTestUtils.switchTab(gBrowser, tab1);
- gURLBar.openPopup();
- yield BrowserTestUtils.switchTab(gBrowser, tab2);
- ok(!gURLBar.popupOpen, "urlbar focused in tab to switch to, close popup");
-
- // cleanup
- gBrowser.removeCurrentTab();
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug664672.js b/browser/base/content/test/general/browser_bug664672.js
deleted file mode 100644
index 2064f77d0..000000000
--- a/browser/base/content/test/general/browser_bug664672.js
+++ /dev/null
@@ -1,19 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- var tab = gBrowser.addTab();
-
- tab.addEventListener("TabClose", function () {
- tab.removeEventListener("TabClose", arguments.callee, false);
-
- 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();
- });
- }, false);
-
- gBrowser.removeTab(tab);
-}
diff --git a/browser/base/content/test/general/browser_bug676619.js b/browser/base/content/test/general/browser_bug676619.js
deleted file mode 100644
index 6b596481d..000000000
--- a/browser/base/content/test/general/browser_bug676619.js
+++ /dev/null
@@ -1,124 +0,0 @@
-function test () {
- requestLongerTimeout(3);
- waitForExplicitFinish();
-
- var isHTTPS = false;
-
- function loadListener() {
- function testLocation(link, url, next) {
- new TabOpenListener(url, function () {
- gBrowser.removeTab(this.tab);
- }, function () {
- next();
- });
-
- ContentTask.spawn(gBrowser.selectedBrowser, link, contentLink => {
- content.document.getElementById(contentLink).click();
- });
- }
-
- function testLink(link, name, next) {
- addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function (win) {
- ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
- Assert.equal(content.document.getElementById("unload-flag").textContent,
- "Okay", "beforeunload shouldn't have fired");
- }).then(() => {
- is(win.document.getElementById("location").value, name, "file name should match");
- win.close();
- next();
- });
- });
-
- ContentTask.spawn(gBrowser.selectedBrowser, link, contentLink => {
- content.document.getElementById(contentLink).click();
- });
- }
-
- testLink("link1", "test.txt",
- testLink.bind(null, "link2", "video.ogg",
- testLink.bind(null, "link3", "just some video",
- testLink.bind(null, "link4", "with-target.txt",
- testLink.bind(null, "link5", "javascript.txt",
- testLink.bind(null, "link6", "test.blob",
- testLocation.bind(null, "link7", "http://example.com/",
- function () {
- if (isHTTPS) {
- finish();
- } else {
- // same test again with https:
- isHTTPS = true;
- gBrowser.loadURI("https://example.com:443/browser/browser/base/content/test/general/download_page.html");
- }
- })))))));
-
- }
-
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
- loadListener();
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(loadListener);
- });
-
- gBrowser.loadURI("http://mochi.test:8888/browser/browser/base/content/test/general/download_page.html");
-}
-
-
-function addWindowListener(aURL, aCallback) {
- Services.wm.addListener({
- onOpenWindow: function(aXULWindow) {
- info("window opened, waiting for focus");
- Services.wm.removeListener(this);
-
- var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- waitForFocus(function() {
- is(domwindow.document.location.href, aURL, "should have seen the right window open");
- aCallback(domwindow);
- }, domwindow);
- },
- onCloseWindow: function(aXULWindow) { },
- onWindowTitleChange: function(aXULWindow, aNewTitle) { }
- });
-}
-
-// This listens for the next opened tab and checks it is of the right url.
-// opencallback is called when the new tab is fully loaded
-// closecallback is called when the tab is closed
-function TabOpenListener(url, opencallback, closecallback) {
- this.url = url;
- this.opencallback = opencallback;
- this.closecallback = closecallback;
-
- gBrowser.tabContainer.addEventListener("TabOpen", this, false);
-}
-
-TabOpenListener.prototype = {
- url: null,
- opencallback: null,
- closecallback: null,
- tab: null,
- browser: null,
-
- handleEvent: function(event) {
- if (event.type == "TabOpen") {
- gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
- this.tab = event.originalTarget;
- this.browser = this.tab.linkedBrowser;
- BrowserTestUtils.browserLoaded(this.browser, false, this.url).then(() => {
- this.tab.addEventListener("TabClose", this, false);
- var url = this.browser.currentURI.spec;
- is(url, this.url, "Should have opened the correct tab");
- this.opencallback();
- });
- } else if (event.type == "TabClose") {
- if (event.originalTarget != this.tab)
- return;
- this.tab.removeEventListener("TabClose", this, false);
- this.opencallback = null;
- this.tab = null;
- this.browser = null;
- // Let the window close complete
- executeSoon(this.closecallback);
- this.closecallback = null;
- }
- }
-};
diff --git a/browser/base/content/test/general/browser_bug678392-1.html b/browser/base/content/test/general/browser_bug678392-1.html
deleted file mode 100644
index c3b235dd0..000000000
--- a/browser/base/content/test/general/browser_bug678392-1.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
- <head>
- <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
- <meta content="utf-8" http-equiv="encoding">
- <title>bug678392 - 1</title>
- </head>
- <body>
-bug 678392 test page 1
- </body>
-</html> \ No newline at end of file
diff --git a/browser/base/content/test/general/browser_bug678392-2.html b/browser/base/content/test/general/browser_bug678392-2.html
deleted file mode 100644
index 9b18efcf7..000000000
--- a/browser/base/content/test/general/browser_bug678392-2.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
- <head>
- <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
- <meta content="utf-8" http-equiv="encoding">
- <title>bug678392 - 2</title>
- </head>
- <body>
-bug 678392 test page 2
- </body>
-</html> \ No newline at end of file
diff --git a/browser/base/content/test/general/browser_bug678392.js b/browser/base/content/test/general/browser_bug678392.js
deleted file mode 100644
index 6aedeefdf..000000000
--- a/browser/base/content/test/general/browser_bug678392.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var HTTPROOT = "http://example.com/browser/browser/base/content/test/general/";
-
-function maxSnapshotOverride() {
- return 5;
-}
-
-function test() {
- waitForExplicitFinish();
-
- BrowserOpenTab();
- let tab = gBrowser.selectedTab;
- registerCleanupFunction(function () { gBrowser.removeTab(tab); });
-
- ok(gHistorySwipeAnimation, "gHistorySwipeAnimation exists.");
-
- if (!gHistorySwipeAnimation._isSupported()) {
- is(gHistorySwipeAnimation.active, false, "History swipe animation is not " +
- "active when not supported by the platform.");
- finish();
- return;
- }
-
- gHistorySwipeAnimation._getMaxSnapshots = maxSnapshotOverride;
- gHistorySwipeAnimation.init();
-
- 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);
- waitForFocus(aCallback, content);
- }, 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);
- }
-}
-
-function testArrayCleanup() {
- // Test cleanup of array of tracked snapshots.
- let arr = gHistorySwipeAnimation._trackedSnapshots;
- is(arr.length, 0, "Snapshots were removed correctly from the array of " +
- "tracked snapshots.");
-}
-
-function test0() {
- // Test growing of array of tracked snapshots.
- let tab = gBrowser.selectedTab;
-
- load(tab, HTTPROOT + "browser_bug678392-1.html", function() {
- ok(gHistorySwipeAnimation._trackedSnapshots, "Array for snapshot " +
- "tracking is initialized.");
- is(gHistorySwipeAnimation._trackedSnapshots.length, 1, "Snapshot array " +
- "has correct length of 1 after loading one page.");
- load(tab, HTTPROOT + "browser_bug678392-2.html", function() {
- is(gHistorySwipeAnimation._trackedSnapshots.length, 2, "Snapshot array " +
- " has correct length of 2 after loading two pages.");
- load(tab, HTTPROOT + "browser_bug678392-1.html", function() {
- is(gHistorySwipeAnimation._trackedSnapshots.length, 3, "Snapshot " +
- "array has correct length of 3 after loading three pages.");
- load(tab, HTTPROOT + "browser_bug678392-2.html", function() {
- is(gHistorySwipeAnimation._trackedSnapshots.length, 4, "Snapshot " +
- "array has correct length of 4 after loading four pages.");
- cleanupArray();
- testArrayCleanup();
- test1();
- });
- });
- });
- });
-}
-
-function verifyRefRemoved(aIndex, aBrowser) {
- let wasFound = false;
- let arr = gHistorySwipeAnimation._trackedSnapshots;
- for (let i = 0; i < arr.length; i++) {
- if (arr[i].index == aIndex && arr[i].browser == aBrowser)
- wasFound = true;
- }
- is(wasFound, false, "The reference that was previously removed was " +
- "still found in the array of tracked snapshots.");
-}
-
-function test1() {
- // Test presence of snpashots in per-tab array of snapshots and removal of
- // individual snapshots (and corresponding references in the array of
- // tracked snapshots).
- let tab = gBrowser.selectedTab;
-
- load(tab, HTTPROOT + "browser_bug678392-1.html", function() {
- var historyIndex = gBrowser.webNavigation.sessionHistory.index - 1;
- load(tab, HTTPROOT + "browser_bug678392-2.html", function() {
- load(tab, HTTPROOT + "browser_bug678392-1.html", function() {
- load(tab, HTTPROOT + "browser_bug678392-2.html", function() {
- let browser = gBrowser.selectedBrowser;
- ok(browser.snapshots, "Array of snapshots exists in browser.");
- ok(browser.snapshots[historyIndex], "First page exists in snapshot " +
- "array.");
- ok(browser.snapshots[historyIndex + 1], "Second page exists in " +
- "snapshot array.");
- ok(browser.snapshots[historyIndex + 2], "Third page exists in " +
- "snapshot array.");
- ok(browser.snapshots[historyIndex + 3], "Fourth page exists in " +
- "snapshot array.");
- is(gHistorySwipeAnimation._trackedSnapshots.length, 4, "Length of " +
- "array of tracked snapshots is equal to 4 after loading four " +
- "pages.");
-
- // Test removal of reference in the middle of the array.
- gHistorySwipeAnimation._removeTrackedSnapshot(historyIndex + 1,
- browser);
- verifyRefRemoved(historyIndex + 1, browser);
- is(gHistorySwipeAnimation._trackedSnapshots.length, 3, "Length of " +
- "array of tracked snapshots is equal to 3 after removing one" +
- "reference from the array with length 4.");
-
- // Test removal of reference at end of array.
- gHistorySwipeAnimation._removeTrackedSnapshot(historyIndex + 3,
- browser);
- verifyRefRemoved(historyIndex + 3, browser);
- is(gHistorySwipeAnimation._trackedSnapshots.length, 2, "Length of " +
- "array of tracked snapshots is equal to 2 after removing two" +
- "references from the array with length 4.");
-
- // Test removal of reference at head of array.
- gHistorySwipeAnimation._removeTrackedSnapshot(historyIndex,
- browser);
- verifyRefRemoved(historyIndex, browser);
- is(gHistorySwipeAnimation._trackedSnapshots.length, 1, "Length of " +
- "array of tracked snapshots is equal to 1 after removing three" +
- "references from the array with length 4.");
-
- cleanupArray();
- test2();
- });
- });
- });
- });
-}
-
-function test2() {
- // Test growing of snapshot array across tabs.
- let tab = gBrowser.selectedTab;
-
- load(tab, HTTPROOT + "browser_bug678392-1.html", function() {
- load(tab, HTTPROOT + "browser_bug678392-2.html", function() {
- is(gHistorySwipeAnimation._trackedSnapshots.length, 2, "Length of " +
- "snapshot array is equal to 2 after loading two pages");
- let prevTab = tab;
- tab = gBrowser.addTab("about:newtab");
- gBrowser.selectedTab = tab;
- load(tab, HTTPROOT + "browser_bug678392-2.html" /* initial page */,
- function() {
- load(tab, HTTPROOT + "browser_bug678392-1.html", function() {
- load(tab, HTTPROOT + "browser_bug678392-2.html", function() {
- is(gHistorySwipeAnimation._trackedSnapshots.length, 4, "Length " +
- "of snapshot array is equal to 4 after loading two pages in " +
- "two tabs each.");
- gBrowser.removeCurrentTab();
- gBrowser.selectedTab = prevTab;
- cleanupArray();
- test3();
- });
- });
- });
- });
- });
-}
-
-function test3() {
- // Test uninit of gHistorySwipeAnimation.
- // This test MUST be the last one to execute.
- gHistorySwipeAnimation.uninit();
- is(gHistorySwipeAnimation.active, false, "History swipe animation support " +
- "was successfully uninitialized");
- finish();
-}
diff --git a/browser/base/content/test/general/browser_bug710878.js b/browser/base/content/test/general/browser_bug710878.js
deleted file mode 100644
index dd99d67cf..000000000
--- a/browser/base/content/test/general/browser_bug710878.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const PAGE = "data:text/html;charset=utf-8,<a href='%23xxx'><span>word1 <span> word2 </span></span><span> word3</span></a>";
-
-/**
- * Tests that we correctly compute the text for context menu
- * selection of some content.
- */
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu,
- "popupshown");
- let awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu,
- "popuphidden");
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("a", {
- type: "contextmenu",
- button: 2,
- }, browser);
-
- yield awaitPopupShown;
-
- is(gContextMenu.linkTextStr, "word1 word2 word3",
- "Text under link is correctly computed.");
-
- contextMenu.hidePopup();
- yield awaitPopupHidden;
- });
-});
diff --git a/browser/base/content/test/general/browser_bug719271.js b/browser/base/content/test/general/browser_bug719271.js
deleted file mode 100644
index c3bb9cd26..000000000
--- a/browser/base/content/test/general/browser_bug719271.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const TEST_PAGE = "http://example.org/browser/browser/base/content/test/general/zoom_test.html";
-const TEST_VIDEO = "http://example.org/browser/browser/base/content/test/general/video.ogg";
-
-var gTab1, gTab2, gLevel1;
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- gTab1 = gBrowser.addTab();
- gTab2 = gBrowser.addTab();
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- yield FullZoomHelper.load(gTab1, TEST_PAGE);
- yield FullZoomHelper.load(gTab2, TEST_VIDEO);
- }).then(zoomTab1, FullZoomHelper.failAndContinue(finish));
-}
-
-function zoomTab1() {
- Task.spawn(function* () {
- is(gBrowser.selectedTab, gTab1, "Tab 1 is selected");
-
- // Reset zoom level if we run this test > 1 time in same browser session.
- var level1 = ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1));
- if (level1 > 1)
- FullZoom.reduce();
-
- FullZoomHelper.zoomTest(gTab1, 1, "Initial zoom of tab 1 should be 1");
- FullZoomHelper.zoomTest(gTab2, 1, "Initial zoom of tab 2 should be 1");
-
- FullZoom.enlarge();
- gLevel1 = ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1));
-
- ok(gLevel1 > 1, "New zoom for tab 1 should be greater than 1");
- FullZoomHelper.zoomTest(gTab2, 1, "Zooming tab 1 should not affect tab 2");
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab2);
- FullZoomHelper.zoomTest(gTab2, 1, "Tab 2 is still unzoomed after it is selected");
- FullZoomHelper.zoomTest(gTab1, gLevel1, "Tab 1 is still zoomed");
- }).then(zoomTab2, FullZoomHelper.failAndContinue(finish));
-}
-
-function zoomTab2() {
- Task.spawn(function* () {
- is(gBrowser.selectedTab, gTab2, "Tab 2 is selected");
-
- FullZoom.reduce();
- let level2 = ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab2));
-
- ok(level2 < 1, "New zoom for tab 2 should be less than 1");
- FullZoomHelper.zoomTest(gTab1, gLevel1, "Zooming tab 2 should not affect tab 1");
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- FullZoomHelper.zoomTest(gTab1, gLevel1, "Tab 1 should have the same zoom after it's selected");
- }).then(testNavigation, FullZoomHelper.failAndContinue(finish));
-}
-
-function testNavigation() {
- Task.spawn(function* () {
- yield FullZoomHelper.load(gTab1, TEST_VIDEO);
- FullZoomHelper.zoomTest(gTab1, 1, "Zoom should be 1 when a video was loaded");
- yield waitForNextTurn(); // trying to fix orange bug 806046
- yield FullZoomHelper.navigate(FullZoomHelper.BACK);
- FullZoomHelper.zoomTest(gTab1, gLevel1, "Zoom should be restored when a page is loaded");
- yield waitForNextTurn(); // trying to fix orange bug 806046
- yield FullZoomHelper.navigate(FullZoomHelper.FORWARD);
- FullZoomHelper.zoomTest(gTab1, 1, "Zoom should be 1 again when navigating back to a video");
- }).then(finishTest, FullZoomHelper.failAndContinue(finish));
-}
-
-function waitForNextTurn() {
- let deferred = Promise.defer();
- setTimeout(() => deferred.resolve(), 0);
- return deferred.promise;
-}
-
-var finishTestStarted = false;
-function finishTest() {
- Task.spawn(function* () {
- ok(!finishTestStarted, "finishTest called more than once");
- finishTestStarted = true;
-
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab1);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab1);
- yield FullZoomHelper.selectTabAndWaitForLocationChange(gTab2);
- yield FullZoom.reset();
- yield FullZoomHelper.removeTabAndWaitForLocationChange(gTab2);
- }).then(finish, FullZoomHelper.failAndContinue(finish));
-}
diff --git a/browser/base/content/test/general/browser_bug724239.js b/browser/base/content/test/general/browser_bug724239.js
deleted file mode 100644
index 430751b91..000000000
--- a/browser/base/content/test/general/browser_bug724239.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* test() {
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (browser) {
- BrowserTestUtils.loadURI(browser, "http://example.com");
- yield BrowserTestUtils.browserLoaded(browser);
- ok(!gBrowser.canGoBack, "about:newtab wasn't added to the session history");
- });
-});
diff --git a/browser/base/content/test/general/browser_bug734076.js b/browser/base/content/test/general/browser_bug734076.js
deleted file mode 100644
index 9de7d913f..000000000
--- a/browser/base/content/test/general/browser_bug734076.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* ()
-{
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, null, false);
-
- let browser = tab.linkedBrowser;
- browser.stop(); // stop the about:blank load
-
- let writeDomainURL = encodeURI("data:text/html,<script>document.write(document.domain);</script>");
-
- let tests = [
- {
- name: "view background image",
- url: "http://mochi.test:8888/",
- element: "body",
- go: function () {
- return ContentTask.spawn(gBrowser.selectedBrowser, { writeDomainURL: writeDomainURL }, function* (arg) {
- let contentBody = content.document.body;
- contentBody.style.backgroundImage = "url('" + arg.writeDomainURL + "')";
-
- return "context-viewbgimage";
- });
- },
- verify: function () {
- return ContentTask.spawn(gBrowser.selectedBrowser, null, function* (arg) {
- Assert.ok(!content.document.body.textContent,
- "no domain was inherited for view background image");
- });
- }
- },
- {
- name: "view image",
- url: "http://mochi.test:8888/",
- element: "img",
- go: function () {
- return ContentTask.spawn(gBrowser.selectedBrowser, { writeDomainURL: writeDomainURL }, function* (arg) {
- let doc = content.document;
- let img = doc.createElement("img");
- img.height = 100;
- img.width = 100;
- img.setAttribute("src", arg.writeDomainURL);
- doc.body.insertBefore(img, doc.body.firstChild);
-
- return "context-viewimage";
- });
- },
- verify: function () {
- return ContentTask.spawn(gBrowser.selectedBrowser, null, function* (arg) {
- Assert.ok(!content.document.body.textContent,
- "no domain was inherited for view image");
- });
- }
- },
- {
- name: "show only this frame",
- url: "http://mochi.test:8888/",
- element: "iframe",
- go: function () {
- return ContentTask.spawn(gBrowser.selectedBrowser, { writeDomainURL: 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);
- resolve("context-showonlythisframe");
- }, true);
- });
- });
- },
- verify: function () {
- return ContentTask.spawn(gBrowser.selectedBrowser, null, function* (arg) {
- Assert.ok(!content.document.body.textContent,
- "no domain was inherited for 'show only this frame'");
- });
- }
- }
- ];
-
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
-
- for (let test of tests) {
- let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.loadURI(test.url);
- yield loadedPromise;
-
- info("Run subtest " + test.name);
- let commandToRun = yield test.go();
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouse(test.element, 3, 3,
- { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
- yield popupShownPromise;
- info("onImage: " + gContextMenu.onImage);
- info("target: " + gContextMenu.target.tagName);
-
- let loadedAfterCommandPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- document.getElementById(commandToRun).click();
- yield loadedAfterCommandPromise;
-
- yield test.verify();
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- contentAreaContextMenu.hidePopup();
- yield popupHiddenPromise;
- }
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug735471.js b/browser/base/content/test/general/browser_bug735471.js
deleted file mode 100644
index 9afb52c4b..000000000
--- a/browser/base/content/test/general/browser_bug735471.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-
-function test() {
- waitForExplicitFinish();
- // Open a new tab.
- whenNewTabLoaded(window, testPreferences);
-}
-
-function testPreferences() {
- whenTabLoaded(gBrowser.selectedTab, function () {
- is(content.location.href, "about:preferences", "Checking if the preferences tab was opened");
-
- gBrowser.removeCurrentTab();
- finish();
- });
-
- openPreferences();
-}
diff --git a/browser/base/content/test/general/browser_bug749738.js b/browser/base/content/test/general/browser_bug749738.js
deleted file mode 100644
index 7e805b799..000000000
--- a/browser/base/content/test/general/browser_bug749738.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const DUMMY_PAGE = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-
-function test() {
- waitForExplicitFinish();
-
- let tab = gBrowser.addTab();
- gBrowser.selectedTab = tab;
-
- BrowserTestUtils.loadURI(tab.linkedBrowser, DUMMY_PAGE);
- BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
- gFindBar.onFindCommand();
- EventUtils.sendString("Dummy");
- gBrowser.removeTab(tab);
-
- try {
- gFindBar.close();
- ok(true, "findbar.close should not throw an exception");
- } catch (e) {
- ok(false, "findbar.close threw exception: " + e);
- }
- finish();
- });
-}
diff --git a/browser/base/content/test/general/browser_bug763468_perwindowpb.js b/browser/base/content/test/general/browser_bug763468_perwindowpb.js
deleted file mode 100644
index 23cb14b8c..000000000
--- a/browser/base/content/test/general/browser_bug763468_perwindowpb.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-/* globals
- waitForExplicitFinish, whenNewWindowLoaded, whenNewTabLoaded,
- executeSoon, registerCleanupFunction, finish, is
-*/
-/* exported test */
-
-// This test makes sure that opening a new tab in private browsing mode opens about:privatebrowsing
-function test() {
- // initialization
- waitForExplicitFinish();
-
- let windowsToClose = [];
- let newTabURL;
- let mode;
-
- function doTest(aIsPrivateMode, aWindow, aCallback) {
- whenNewTabLoaded(aWindow, function() {
- if (aIsPrivateMode) {
- mode = "per window private browsing";
- newTabURL = "about:privatebrowsing";
- } else {
- mode = "normal";
- newTabURL = "about:newtab";
- }
-
- is(aWindow.gBrowser.currentURI.spec, newTabURL,
- "URL of NewTab should be " + newTabURL + " in " + mode + " mode");
-
- aWindow.gBrowser.removeTab(aWindow.gBrowser.selectedTab);
- aCallback();
- });
- }
-
- function testOnWindow(aOptions, aCallback) {
- whenNewWindowLoaded(aOptions, function(aWin) {
- windowsToClose.push(aWin);
- // execute should only be called when need, like when you are opening
- // web pages on the test. If calling executeSoon() is not necesary, then
- // call whenNewWindowLoaded() instead of testOnWindow() on your test.
- executeSoon(() => aCallback(aWin));
- });
- }
-
- // this function is called after calling finish() on the test.
- registerCleanupFunction(function() {
- windowsToClose.forEach(function(aWin) {
- aWin.close();
- });
- });
-
- // test first when not on private mode
- testOnWindow({}, function(aWin) {
- doTest(false, aWin, function() {
- // then test when on private mode
- testOnWindow({private: true}, function(aWin2) {
- doTest(true, aWin2, function() {
- // then test again when not on private mode
- testOnWindow({}, function(aWin3) {
- doTest(false, aWin3, finish);
- });
- });
- });
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_bug767836_perwindowpb.js b/browser/base/content/test/general/browser_bug767836_perwindowpb.js
deleted file mode 100644
index 7f5d15e76..000000000
--- a/browser/base/content/test/general/browser_bug767836_perwindowpb.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-/* globals waitForExplicitFinish, executeSoon, finish, whenNewWindowLoaded, ok */
-/* globals is */
-/* exported test */
-
-function test() {
- // initialization
- waitForExplicitFinish();
-
- let aboutNewTabService = Components.classes["@mozilla.org/browser/aboutnewtab-service;1"]
- .getService(Components.interfaces.nsIAboutNewTabService);
- let newTabURL;
- let testURL = "http://example.com/";
- let defaultURL = aboutNewTabService.newTabURL;
- let mode;
-
- function doTest(aIsPrivateMode, aWindow, aCallback) {
- openNewTab(aWindow, function() {
- if (aIsPrivateMode) {
- mode = "per window private browsing";
- newTabURL = "about:privatebrowsing";
- } else {
- mode = "normal";
- newTabURL = "about:newtab";
- }
-
- // Check the new tab opened while in normal/private mode
- is(aWindow.gBrowser.selectedBrowser.currentURI.spec, newTabURL,
- "URL of NewTab should be " + newTabURL + " in " + mode + " mode");
- // Set the custom newtab url
- aboutNewTabService.newTabURL = testURL;
- is(aboutNewTabService.newTabURL, testURL, "Custom newtab url is set");
-
- // Open a newtab after setting the custom newtab url
- openNewTab(aWindow, function() {
- is(aWindow.gBrowser.selectedBrowser.currentURI.spec, testURL,
- "URL of NewTab should be the custom url");
-
- // Clear the custom url.
- aboutNewTabService.resetNewTabURL();
- is(aboutNewTabService.newTabURL, defaultURL, "No custom newtab url is set");
-
- aWindow.gBrowser.removeTab(aWindow.gBrowser.selectedTab);
- aWindow.gBrowser.removeTab(aWindow.gBrowser.selectedTab);
- aWindow.close();
- aCallback();
- });
- });
- }
-
- function testOnWindow(aIsPrivate, aCallback) {
- whenNewWindowLoaded({private: aIsPrivate}, function(win) {
- executeSoon(() => aCallback(win));
- });
- }
-
- // check whether any custom new tab url has been configured
- ok(!aboutNewTabService.overridden, "No custom newtab url is set");
-
- // test normal mode
- testOnWindow(false, function(aWindow) {
- doTest(false, aWindow, function() {
- // test private mode
- testOnWindow(true, function(aWindow2) {
- doTest(true, aWindow2, function() {
- finish();
- });
- });
- });
- });
-}
-
-function openNewTab(aWindow, aCallback) {
- // Open a new tab
- 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);
- executeSoon(aCallback);
- }, true);
-}
diff --git a/browser/base/content/test/general/browser_bug817947.js b/browser/base/content/test/general/browser_bug817947.js
deleted file mode 100644
index 3a76e36d3..000000000
--- a/browser/base/content/test/general/browser_bug817947.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-const URL = "http://mochi.test:8888/browser/";
-const PREF = "browser.sessionstore.restore_on_demand";
-
-function test() {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref(PREF, true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF);
- });
-
- preparePendingTab(function (aTab) {
- let win = gBrowser.replaceTabWithWindow(aTab);
-
- whenDelayedStartupFinished(win, function () {
- let [tab] = win.gBrowser.tabs;
-
- whenLoaded(tab.linkedBrowser, function () {
- is(tab.linkedBrowser.currentURI.spec, URL, "correct url should be loaded");
- ok(!tab.hasAttribute("pending"), "tab should not be pending");
-
- win.close();
- finish();
- });
- });
- });
-}
-
-function preparePendingTab(aCallback) {
- let tab = gBrowser.addTab(URL);
-
- whenLoaded(tab.linkedBrowser, function () {
- BrowserTestUtils.removeTab(tab).then(() => {
- let [{state}] = JSON.parse(SessionStore.getClosedTabData(window));
-
- tab = gBrowser.addTab("about:blank");
- whenLoaded(tab.linkedBrowser, function () {
- SessionStore.setTabState(tab, JSON.stringify(state));
- ok(tab.hasAttribute("pending"), "tab should be pending");
- aCallback(tab);
- });
- });
- });
-}
-
-function whenLoaded(aElement, aCallback) {
- aElement.addEventListener("load", function onLoad() {
- aElement.removeEventListener("load", onLoad, true);
- executeSoon(aCallback);
- }, true);
-}
diff --git a/browser/base/content/test/general/browser_bug822367.js b/browser/base/content/test/general/browser_bug822367.js
deleted file mode 100644
index 0d60c05cd..000000000
--- a/browser/base/content/test/general/browser_bug822367.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * User Override Mixed Content Block - Tests for Bug 822367
- */
-
-
-const PREF_DISPLAY = "security.mixed_content.block_display_content";
-const PREF_ACTIVE = "security.mixed_content.block_active_content";
-
-// We alternate for even and odd test cases to simulate different hosts
-const gHttpTestRoot = "https://example.com/browser/browser/base/content/test/general/";
-const gHttpTestRoot2 = "https://test1.example.com/browser/browser/base/content/test/general/";
-
-var gTestBrowser = null;
-
-add_task(function* test() {
- yield SpecialPowers.pushPrefEnv({ set: [[ PREF_DISPLAY, true ],
- [ PREF_ACTIVE, true ]] });
-
- var newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
- newTab.linkedBrowser.stop()
-
- // Mixed Script Test
- var url = gHttpTestRoot + "file_bug822367_1.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-// Mixed Script Test
-add_task(function* MixedTest1A() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest1B() {
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("p1").innerHTML == "hello",
- "Waited too long for mixed script to run in Test 1");
- });
-});
-
-// Mixed Display Test - Doorhanger should not appear
-add_task(function* MixedTest2() {
- var url = gHttpTestRoot2 + "file_bug822367_2.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
-});
-
-// Mixed Script and Display Test - User Override should cause both the script and the image to load.
-add_task(function* MixedTest3() {
- var url = gHttpTestRoot + "file_bug822367_3.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest3A() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest3B() {
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let p1 = ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("p1").innerHTML == "hello",
- "Waited too long for mixed script to run in Test 3");
- let p2 = ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("p2").innerHTML == "bye",
- "Waited too long for mixed image to load in Test 3");
- yield Promise.all([ p1, p2 ]);
- });
-
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: true});
-});
-
-// Location change - User override on one page doesn't propogate to another page after location change.
-add_task(function* MixedTest4() {
- var url = gHttpTestRoot2 + "file_bug822367_4.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest4A() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest4B() {
- let url = gHttpTestRoot + "file_bug822367_4B.html";
- yield ContentTask.spawn(gTestBrowser, url, function* (wantedUrl) {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.location == wantedUrl,
- "Waited too long for mixed script to run in Test 4");
- });
-});
-
-add_task(function* MixedTest4C() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("p1").innerHTML == "",
- "Mixed script loaded in test 4 after location change!");
- });
-});
-
-// Mixed script attempts to load in a document.open()
-add_task(function* MixedTest5() {
- var url = gHttpTestRoot + "file_bug822367_5.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest5A() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest5B() {
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("p1").innerHTML == "hello",
- "Waited too long for mixed script to run in Test 5");
- });
-});
-
-// Mixed script attempts to load in a document.open() that is within an iframe.
-add_task(function* MixedTest6() {
- var url = gHttpTestRoot2 + "file_bug822367_6.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest6A() {
- gTestBrowser.removeEventListener("load", MixedTest6A, true);
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
-
- yield BrowserTestUtils.waitForCondition(
- () => gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
- "Waited too long for control center to get mixed active blocked state");
-});
-
-add_task(function* MixedTest6B() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
-
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* MixedTest6C() {
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- function test() {
- try {
- return content.document.getElementById("f1").contentDocument.getElementById("p1").innerHTML == "hello";
- } catch (e) {
- return false;
- }
- }
-
- yield ContentTaskUtils.waitForCondition(test, "Waited too long for mixed script to run in Test 6");
- });
-});
-
-add_task(function* MixedTest6D() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: false});
-});
-
-add_task(function* cleanup() {
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug832435.js b/browser/base/content/test/general/browser_bug832435.js
deleted file mode 100644
index 6be2604cd..000000000
--- a/browser/base/content/test/general/browser_bug832435.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
- ok(true, "Starting up");
-
- gBrowser.selectedBrowser.focus();
- gURLBar.addEventListener("focus", function onFocus() {
- gURLBar.removeEventListener("focus", onFocus);
- 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();
- });
- });
- gURLBar.inputField.value = "javascript: var foo = '11111111'; ";
- gURLBar.focus();
-}
diff --git a/browser/base/content/test/general/browser_bug839103.js b/browser/base/content/test/general/browser_bug839103.js
deleted file mode 100644
index 5240c92ed..000000000
--- a/browser/base/content/test/general/browser_bug839103.js
+++ /dev/null
@@ -1,120 +0,0 @@
-const gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-
-add_task(function* test() {
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (browser) {
- yield ContentTask.spawn(browser, gTestRoot, testBody);
- });
-});
-
-// This function runs entirely in the content process. It doesn't have access
-// any free variables in this file.
-function* testBody(testRoot) {
- const gStyleSheet = "bug839103.css";
-
- let loaded = ContentTaskUtils.waitForEvent(this, "load", true);
- content.location = testRoot + "test_bug839103.html";
-
- yield loaded;
- function unexpectedContentEvent(event) {
- ok(false, "Received a " + event.type + " event on content");
- }
-
- // We've seen the original stylesheet in the document.
- // Now add a stylesheet on the fly and make sure we see it.
- let doc = content.document;
- doc.styleSheetChangeEventsEnabled = true;
- doc.addEventListener("StyleSheetAdded", unexpectedContentEvent);
- doc.addEventListener("StyleSheetRemoved", unexpectedContentEvent);
- doc.addEventListener("StyleSheetApplicableStateChanged", unexpectedContentEvent);
- doc.defaultView.addEventListener("StyleSheetAdded", unexpectedContentEvent);
- doc.defaultView.addEventListener("StyleSheetRemoved", unexpectedContentEvent);
- doc.defaultView.addEventListener("StyleSheetApplicableStateChanged", unexpectedContentEvent);
-
- let link = doc.createElement("link");
- link.setAttribute("rel", "stylesheet");
- link.setAttribute("type", "text/css");
- link.setAttribute("href", testRoot + gStyleSheet);
-
- let sheetAdded =
- ContentTaskUtils.waitForEvent(this, "StyleSheetAdded", true);
- let stateChanged =
- ContentTaskUtils.waitForEvent(this, "StyleSheetApplicableStateChanged", true);
- doc.body.appendChild(link);
-
- let evt = yield sheetAdded;
- info("received dynamic style sheet event");
- is(evt.type, "StyleSheetAdded", "evt.type has expected value");
- is(evt.target, doc, "event targets correct document");
- ok(evt.stylesheet, "evt.stylesheet is defined");
- ok(evt.stylesheet.toString().includes("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
- ok(evt.documentSheet, "style sheet is a document sheet");
-
- evt = yield stateChanged;
- info("received dynamic style sheet applicable state change event");
- is(evt.type, "StyleSheetApplicableStateChanged", "evt.type has expected value");
- is(evt.target, doc, "event targets correct document");
- is(evt.stylesheet, link.sheet, "evt.stylesheet has the right value");
- is(evt.applicable, true, "evt.applicable has the right value");
-
- stateChanged =
- ContentTaskUtils.waitForEvent(this, "StyleSheetApplicableStateChanged", true);
- link.disabled = true;
-
- evt = yield stateChanged;
- is(evt.type, "StyleSheetApplicableStateChanged", "evt.type has expected value");
- info("received dynamic style sheet applicable state change event after media=\"\" changed");
- is(evt.target, doc, "event targets correct document");
- is(evt.stylesheet, link.sheet, "evt.stylesheet has the right value");
- is(evt.applicable, false, "evt.applicable has the right value");
-
- let sheetRemoved =
- ContentTaskUtils.waitForEvent(this, "StyleSheetRemoved", true);
- doc.body.removeChild(link);
-
- evt = yield sheetRemoved;
- info("received dynamic style sheet removal");
- is(evt.type, "StyleSheetRemoved", "evt.type has expected value");
- is(evt.target, doc, "event targets correct document");
- ok(evt.stylesheet, "evt.stylesheet is defined");
- ok(evt.stylesheet.toString().includes("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
- ok(evt.stylesheet.href.includes(gStyleSheet), "evt.stylesheet is the removed stylesheet");
-
- let ruleAdded =
- ContentTaskUtils.waitForEvent(this, "StyleRuleAdded", true);
- doc.querySelector("style").sheet.insertRule("*{color:black}", 0);
-
- evt = yield ruleAdded;
- info("received style rule added event");
- is(evt.type, "StyleRuleAdded", "evt.type has expected value");
- is(evt.target, doc, "event targets correct document");
- ok(evt.stylesheet, "evt.stylesheet is defined");
- ok(evt.stylesheet.toString().includes("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
- ok(evt.rule, "evt.rule is defined");
- is(evt.rule.cssText, "* { color: black; }", "evt.rule.cssText has expected value");
-
- let ruleChanged =
- ContentTaskUtils.waitForEvent(this, "StyleRuleChanged", true);
- evt.rule.style.cssText = "color:green";
-
- evt = yield ruleChanged;
- ok(true, "received style rule changed event");
- is(evt.type, "StyleRuleChanged", "evt.type has expected value");
- is(evt.target, doc, "event targets correct document");
- ok(evt.stylesheet, "evt.stylesheet is defined");
- ok(evt.stylesheet.toString().includes("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
- ok(evt.rule, "evt.rule is defined");
- is(evt.rule.cssText, "* { color: green; }", "evt.rule.cssText has expected value");
-
- let ruleRemoved =
- ContentTaskUtils.waitForEvent(this, "StyleRuleRemoved", true);
- evt.stylesheet.deleteRule(0);
-
- evt = yield ruleRemoved;
- info("received style rule removed event");
- is(evt.type, "StyleRuleRemoved", "evt.type has expected value");
- is(evt.target, doc, "event targets correct document");
- ok(evt.stylesheet, "evt.stylesheet is defined");
- ok(evt.stylesheet.toString().includes("CSSStyleSheet"), "evt.stylesheet is a stylesheet");
- ok(evt.rule, "evt.rule is defined");
-}
diff --git a/browser/base/content/test/general/browser_bug882977.js b/browser/base/content/test/general/browser_bug882977.js
deleted file mode 100644
index ed958e06b..000000000
--- a/browser/base/content/test/general/browser_bug882977.js
+++ /dev/null
@@ -1,29 +0,0 @@
-"use strict";
-
-/**
- * Tests that the identity-box shows the chromeUI styling
- * when viewing about:home in a new window.
- */
-add_task(function*() {
- let homepage = "about:home";
- yield SpecialPowers.pushPrefEnv({
- "set": [
- ["browser.startup.homepage", homepage],
- ["browser.startup.page", 1],
- ]
- });
-
- let win = OpenBrowserWindow();
- yield BrowserTestUtils.firstBrowserLoaded(win, false);
-
- let browser = win.gBrowser.selectedBrowser;
- is(browser.currentURI.spec, homepage, "Loaded the correct homepage");
- checkIdentityMode(win);
-
- yield BrowserTestUtils.closeWindow(win);
-});
-
-function checkIdentityMode(win) {
- let identityMode = win.document.getElementById("identity-box").className;
- is(identityMode, "chromeUI", "Identity state should be chromeUI for about:home in a new window");
-}
diff --git a/browser/base/content/test/general/browser_bug902156.js b/browser/base/content/test/general/browser_bug902156.js
deleted file mode 100644
index 74969ead4..000000000
--- a/browser/base/content/test/general/browser_bug902156.js
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Description of the Tests for
- * - Bug 902156: Persist "disable protection" option for Mixed Content Blocker
- *
- * 1. Navigate to the same domain via document.location
- * - Load a html page which has mixed content
- * - Control Center button to disable protection appears - we disable it
- * - Load a new page from the same origin using document.location
- * - Control Center button should not appear anymore!
- *
- * 2. Navigate to the same domain via simulateclick for a link on the page
- * - Load a html page which has mixed content
- * - Control Center button to disable protection appears - we disable it
- * - Load a new page from the same origin simulating a click
- * - Control Center button should not appear anymore!
- *
- * 3. Navigate to a differnet domain and show the content is still blocked
- * - Load a different html page which has mixed content
- * - Control Center button to disable protection should appear again because
- * we navigated away from html page where we disabled the protection.
- *
- * Note, for all tests we set gHttpTestRoot to use 'https'.
- */
-
-const PREF_ACTIVE = "security.mixed_content.block_active_content";
-
-// We alternate for even and odd test cases to simulate different hosts
-const gHttpTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
-const gHttpTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
-
-var origBlockActive;
-var gTestBrowser = null;
-
-registerCleanupFunction(function() {
- // Set preferences back to their original values
- Services.prefs.setBoolPref(PREF_ACTIVE, origBlockActive);
-});
-
-function cleanUpAfterTests() {
- gBrowser.removeCurrentTab();
- window.focus();
- finish();
-}
-
-// ------------------------ Test 1 ------------------------------
-
-function test1A() {
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test1B);
-
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- // Disable Mixed Content Protection for the page (and reload)
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
-}
-
-function test1B() {
- var expected = "Mixed Content Blocker disabled";
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test1C, "Error: Waited too long for mixed script to run in Test 1B");
-}
-
-function test1C() {
- var actual = content.document.getElementById('mctestdiv').innerHTML;
- is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1C");
-
- // The Script loaded after we disabled the page, now we are going to reload the
- // page and see if our decision is persistent
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test1D);
-
- var url = gHttpTestRoot1 + "file_bug902156_2.html";
- gTestBrowser.loadURI(url);
-}
-
-function test1D() {
- // The Control Center button should appear but isMixedContentBlocked should be NOT true,
- // because our decision of disabling the mixed content blocker is persistent.
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: false});
-
- var actual = content.document.getElementById('mctestdiv').innerHTML;
- is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1D");
-
- // move on to Test 2
- test2();
-}
-
-// ------------------------ Test 2 ------------------------------
-
-function test2() {
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test2A);
- var url = gHttpTestRoot2 + "file_bug902156_2.html";
- gTestBrowser.loadURI(url);
-}
-
-function test2A() {
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test2B);
-
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- // Disable Mixed Content Protection for the page (and reload)
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
-}
-
-function test2B() {
- var expected = "Mixed Content Blocker disabled";
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test2C, "Error: Waited too long for mixed script to run in Test 2B");
-}
-
-function test2C() {
- var actual = content.document.getElementById('mctestdiv').innerHTML;
- is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 2C");
-
- // The Script loaded after we disabled the page, now we are going to reload the
- // page and see if our decision is persistent
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test2D);
-
- // reload the page using the provided link in the html file
- var mctestlink = content.document.getElementById("mctestlink");
- mctestlink.click();
-}
-
-function test2D() {
- // The Control Center button should appear but isMixedContentBlocked should be NOT true,
- // because our decision of disabling the mixed content blocker is persistent.
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: false});
-
- var actual = content.document.getElementById('mctestdiv').innerHTML;
- is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 2D");
-
- // move on to Test 3
- test3();
-}
-
-// ------------------------ Test 3 ------------------------------
-
-function test3() {
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test3A);
- var url = gHttpTestRoot1 + "file_bug902156_3.html";
- gTestBrowser.loadURI(url);
-}
-
-function test3A() {
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- // We are done with tests, clean up
- cleanUpAfterTests();
-}
-
-// ------------------------------------------------------
-
-function test() {
- // Performing async calls, e.g. 'onload', we have to wait till all of them finished
- waitForExplicitFinish();
-
- // Store original preferences so we can restore settings after testing
- origBlockActive = Services.prefs.getBoolPref(PREF_ACTIVE);
-
- Services.prefs.setBoolPref(PREF_ACTIVE, true);
-
- // Not really sure what this is doing
- var newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
- newTab.linkedBrowser.stop()
-
- // Starting Test Number 1:
- BrowserTestUtils.browserLoaded(gTestBrowser).then(test1A);
- var url = gHttpTestRoot1 + "file_bug902156_1.html";
- gTestBrowser.loadURI(url);
-}
diff --git a/browser/base/content/test/general/browser_bug906190.js b/browser/base/content/test/general/browser_bug906190.js
deleted file mode 100644
index 613f50efd..000000000
--- a/browser/base/content/test/general/browser_bug906190.js
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Tests the persistence of the "disable protection" option for Mixed Content
- * Blocker in child tabs (bug 906190).
- */
-
-requestLongerTimeout(2);
-
-// We use the different urls for testing same origin checks before allowing
-// mixed content on child tabs.
-const gHttpTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
-const gHttpTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
-
-/**
- * For all tests, we load the pages over HTTPS and test both:
- * - |CTRL+CLICK|
- * - |RIGHT CLICK -> OPEN LINK IN TAB|
- */
-function* doTest(parentTabSpec, childTabSpec, testTaskFn, waitForMetaRefresh) {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: parentTabSpec,
- }, function* (browser) {
- // As a sanity check, test that active content has been blocked as expected.
- yield assertMixedContentBlockingState(gBrowser, {
- activeLoaded: false, activeBlocked: true, passiveLoaded: false,
- });
-
- // Disable the Mixed Content Blocker for the page, which reloads it.
- let promiseReloaded = BrowserTestUtils.browserLoaded(browser);
- gIdentityHandler.disableMixedContentProtection();
- yield promiseReloaded;
-
- // Wait for the script in the page to update the contents of the test div.
- let testDiv = content.document.getElementById('mctestdiv');
- yield promiseWaitForCondition(
- () => testDiv.innerHTML == "Mixed Content Blocker disabled");
-
- // Add the link for the child tab to the page.
- let mainDiv = content.document.createElement("div");
- mainDiv.innerHTML =
- '<p><a id="linkToOpenInNewTab" href="' + childTabSpec + '">Link</a></p>';
- content.document.body.appendChild(mainDiv);
-
- // Execute the test in the child tabs with the two methods to open it.
- for (let openFn of [simulateCtrlClick, simulateContextMenuOpenInTab]) {
- let promiseTabLoaded = waitForSomeTabToLoad();
- openFn(browser);
- yield promiseTabLoaded;
- gBrowser.selectTabAtIndex(2);
-
- if (waitForMetaRefresh) {
- yield waitForSomeTabToLoad();
- }
-
- yield testTaskFn();
-
- gBrowser.removeCurrentTab();
- }
- });
-}
-
-function simulateCtrlClick(browser) {
- BrowserTestUtils.synthesizeMouseAtCenter("#linkToOpenInNewTab",
- { ctrlKey: true, metaKey: true },
- browser);
-}
-
-function simulateContextMenuOpenInTab(browser) {
- BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
- // These are operations that must be executed synchronously with the event.
- document.getElementById("context-openlinkintab").doCommand();
- event.target.hidePopup();
- return true;
- });
- BrowserTestUtils.synthesizeMouseAtCenter("#linkToOpenInNewTab",
- { type: "contextmenu", button: 2 },
- browser);
-}
-
-// Waits for a load event somewhere in the browser but ignore events coming
-// from <xul:browser>s without a tab assigned. That are most likely browsers
-// that preload the new tab page.
-function waitForSomeTabToLoad() {
- return new Promise(resolve => {
- gBrowser.addEventListener("load", function onLoad(event) {
- let tab = gBrowser._getTabForContentWindow(event.target.defaultView.top);
- if (tab) {
- gBrowser.removeEventListener("load", onLoad, true);
- resolve();
- }
- }, true);
- });
-}
-
-/**
- * Ensure the Mixed Content Blocker is enabled.
- */
-add_task(function* test_initialize() {
- yield new Promise(resolve => SpecialPowers.pushPrefEnv({
- "set": [["security.mixed_content.block_active_content", true]],
- }, resolve));
-});
-
-/**
- * 1. - Load a html page which has mixed content
- * - Doorhanger to disable protection appears - we disable it
- * - Load a subpage from the same origin in a new tab simulating a click
- * - Doorhanger should >> NOT << appear anymore!
- */
-add_task(function* test_same_origin() {
- yield doTest(gHttpTestRoot1 + "file_bug906190_1.html",
- gHttpTestRoot1 + "file_bug906190_2.html", function* () {
- // The doorhanger should appear but activeBlocked should be >> NOT << true,
- // because our decision of disabling the mixed content blocker is persistent
- // across tabs.
- yield assertMixedContentBlockingState(gBrowser, {
- activeLoaded: true, activeBlocked: false, passiveLoaded: false,
- });
-
- is(content.document.getElementById('mctestdiv').innerHTML,
- "Mixed Content Blocker disabled", "OK: Executed mixed script");
- });
-});
-
-/**
- * 2. - Load a html page which has mixed content
- * - Doorhanger to disable protection appears - we disable it
- * - Load a new page from a different origin in a new tab simulating a click
- * - Doorhanger >> SHOULD << appear again!
- */
-add_task(function* test_different_origin() {
- yield doTest(gHttpTestRoot1 + "file_bug906190_2.html",
- gHttpTestRoot2 + "file_bug906190_2.html", function* () {
- // The doorhanger should appear and activeBlocked should be >> TRUE <<,
- // because our decision of disabling the mixed content blocker should only
- // persist if pages are from the same domain.
- yield assertMixedContentBlockingState(gBrowser, {
- activeLoaded: false, activeBlocked: true, passiveLoaded: false,
- });
-
- is(content.document.getElementById('mctestdiv').innerHTML,
- "Mixed Content Blocker enabled", "OK: Blocked mixed script");
- });
-});
-
-/**
- * 3. - Load a html page which has mixed content
- * - Doorhanger to disable protection appears - we disable it
- * - Load a new page from the same origin in a new tab simulating a click
- * - Redirect to another page from the same origin using meta-refresh
- * - Doorhanger should >> NOT << appear again!
- */
-add_task(function* test_same_origin_metarefresh_same_origin() {
- // file_bug906190_3_4.html redirects to page test1.example.com/* using meta-refresh
- yield doTest(gHttpTestRoot1 + "file_bug906190_1.html",
- gHttpTestRoot1 + "file_bug906190_3_4.html", function* () {
- // The doorhanger should appear but activeBlocked should be >> NOT << true!
- yield assertMixedContentBlockingState(gBrowser, {
- activeLoaded: true, activeBlocked: false, passiveLoaded: false,
- });
-
- is(content.document.getElementById('mctestdiv').innerHTML,
- "Mixed Content Blocker disabled", "OK: Executed mixed script");
- }, true);
-});
-
-/**
- * 4. - Load a html page which has mixed content
- * - Doorhanger to disable protection appears - we disable it
- * - Load a new page from the same origin in a new tab simulating a click
- * - Redirect to another page from a different origin using meta-refresh
- * - Doorhanger >> SHOULD << appear again!
- */
-add_task(function* test_same_origin_metarefresh_different_origin() {
- yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
- gHttpTestRoot2 + "file_bug906190_3_4.html", function* () {
- // The doorhanger should appear and activeBlocked should be >> TRUE <<.
- yield assertMixedContentBlockingState(gBrowser, {
- activeLoaded: false, activeBlocked: true, passiveLoaded: false,
- });
-
- is(content.document.getElementById('mctestdiv').innerHTML,
- "Mixed Content Blocker enabled", "OK: Blocked mixed script");
- }, true);
-});
-
-/**
- * 5. - Load a html page which has mixed content
- * - Doorhanger to disable protection appears - we disable it
- * - Load a new page from the same origin in a new tab simulating a click
- * - Redirect to another page from the same origin using 302 redirect
- */
-add_task(function* test_same_origin_302redirect_same_origin() {
- // the sjs files returns a 302 redirect- note, same origins
- yield doTest(gHttpTestRoot1 + "file_bug906190_1.html",
- gHttpTestRoot1 + "file_bug906190.sjs", function* () {
- // The doorhanger should appear but activeBlocked should be >> NOT << true.
- // Currently it is >> TRUE << - see follow up bug 914860
- ok(!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
- "OK: Mixed Content is NOT being blocked");
-
- is(content.document.getElementById('mctestdiv').innerHTML,
- "Mixed Content Blocker disabled", "OK: Executed mixed script");
- });
-});
-
-/**
- * 6. - Load a html page which has mixed content
- * - Doorhanger to disable protection appears - we disable it
- * - Load a new page from the same origin in a new tab simulating a click
- * - Redirect to another page from a different origin using 302 redirect
- */
-add_task(function* test_same_origin_302redirect_different_origin() {
- // the sjs files returns a 302 redirect - note, different origins
- yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
- gHttpTestRoot2 + "file_bug906190.sjs", function* () {
- // The doorhanger should appear and activeBlocked should be >> TRUE <<.
- yield assertMixedContentBlockingState(gBrowser, {
- activeLoaded: false, activeBlocked: true, passiveLoaded: false,
- });
-
- is(content.document.getElementById('mctestdiv').innerHTML,
- "Mixed Content Blocker enabled", "OK: Blocked mixed script");
- });
-});
-
-/**
- * 7. - Test memory leak issue on redirection error. See Bug 1269426.
- */
-add_task(function* test_bad_redirection() {
- // the sjs files returns a 302 redirect - note, different origins
- yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
- gHttpTestRoot2 + "file_bug906190.sjs?bad-redirection=1", function* () {
- // Nothing to do. Just see if memory leak is reported in the end.
- ok(true, "Nothing to do");
- });
-});
diff --git a/browser/base/content/test/general/browser_bug963945.js b/browser/base/content/test/general/browser_bug963945.js
deleted file mode 100644
index 4531964b0..000000000
--- a/browser/base/content/test/general/browser_bug963945.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This test ensures the about:addons tab is only
- * opened one time when in private browsing.
- */
-
-add_task(function* test() {
- let win = yield BrowserTestUtils.openNewBrowserWindow({private: true});
-
- let tab = win.gBrowser.selectedTab = win.gBrowser.addTab("about:addons");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield promiseWaitForFocus(win);
-
- EventUtils.synthesizeKey("a", { ctrlKey: true, shiftKey: true }, win);
-
- is(win.gBrowser.tabs.length, 2, "about:addons tab was re-focused.");
- is(win.gBrowser.currentURI.spec, "about:addons", "Addons tab was opened.");
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/base/content/test/general/browser_bug970746.js b/browser/base/content/test/general/browser_bug970746.js
deleted file mode 100644
index 623623e55..000000000
--- a/browser/base/content/test/general/browser_bug970746.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Make sure context menu includes option to search hyperlink text on search engine */
-
-add_task(function *() {
- const url = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_bug970746.xhtml";
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-
- const ellipsis = "\u2026";
-
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
-
- // Tests if the "Search <engine> for '<some terms>'" context menu item is shown for the
- // given query string of an element. Tests to make sure label includes the proper search terms.
- //
- // Each test:
- //
- // id: The id of the element to test.
- // isSelected: Flag to enable selecting (text highlight) the contents of the element
- // shouldBeShown: The display state of the menu item
- // expectedLabelContents: The menu item label should contain a portion of this string.
- // Will only be tested if shouldBeShown is true.
- let tests = [
- {
- id: "link",
- isSelected: true,
- shouldBeShown: true,
- expectedLabelContents: "I'm a link!",
- },
- {
- id: "link",
- isSelected: false,
- shouldBeShown: true,
- expectedLabelContents: "I'm a link!",
- },
- {
- id: "longLink",
- isSelected: true,
- shouldBeShown: true,
- expectedLabelContents: "I'm a really lo" + ellipsis,
- },
- {
- id: "longLink",
- isSelected: false,
- shouldBeShown: true,
- expectedLabelContents: "I'm a really lo" + ellipsis,
- },
- {
- id: "plainText",
- isSelected: true,
- shouldBeShown: true,
- expectedLabelContents: "Right clicking " + ellipsis,
- },
- {
- id: "plainText",
- isSelected: false,
- shouldBeShown: false,
- },
- {
- id: "mixedContent",
- isSelected: true,
- shouldBeShown: true,
- expectedLabelContents: "I'm some text, " + ellipsis,
- },
- {
- id: "mixedContent",
- isSelected: false,
- shouldBeShown: false,
- },
- {
- id: "partialLink",
- isSelected: true,
- shouldBeShown: true,
- expectedLabelContents: "link selection",
- },
- {
- id: "partialLink",
- isSelected: false,
- shouldBeShown: true,
- expectedLabelContents: "A partial link " + ellipsis,
- },
- {
- id: "surrogatePair",
- isSelected: true,
- shouldBeShown: true,
- expectedLabelContents: "This character\uD83D\uDD25" + ellipsis,
- }
- ];
-
- for (let test of tests) {
- yield ContentTask.spawn(gBrowser.selectedBrowser,
- { selectElement: test.isSelected ? test.id : null },
- function* (arg) {
- let selection = content.getSelection();
- selection.removeAllRanges();
-
- if (arg.selectElement) {
- selection.selectAllChildren(content.document.getElementById(arg.selectElement));
- }
- });
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouseAtCenter("#" + test.id,
- { type: "contextmenu", button: 2}, gBrowser.selectedBrowser);
- yield popupShownPromise;
-
- let menuItem = document.getElementById("context-searchselect");
- is(menuItem.hidden, !test.shouldBeShown,
- "search context menu item is shown for '#" + test.id + "' and selected is '" + test.isSelected + "'");
-
- if (test.shouldBeShown) {
- ok(menuItem.label.includes(test.expectedLabelContents),
- "Menu item text '" + menuItem.label + "' contains the correct search terms '" + test.expectedLabelContents + "'");
- }
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- contentAreaContextMenu.hidePopup();
- yield popupHiddenPromise;
- }
-
- // cleanup
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_bug970746.xhtml b/browser/base/content/test/general/browser_bug970746.xhtml
deleted file mode 100644
index 9d78d7147..000000000
--- a/browser/base/content/test/general/browser_bug970746.xhtml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<html xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <a href="http://mozilla.org" id="link">I'm a link!</a>
- <a href="http://mozilla.org" id="longLink">I'm a really long link and I should be truncated.</a>
-
- <span id="plainText">
- Right clicking me when I'm selected should show the menu item.
- </span>
- <span id="mixedContent">
- I'm some text, and <a href="http://mozilla.org">I'm a link!</a>
- </span>
-
- <a href="http://mozilla.org">A partial <span id="partialLink">link selection</span></a>
-
- <span id="surrogatePair">
- This character🔥 shouldn't be truncated.
- </span>
- </body>
-</html>
diff --git a/browser/base/content/test/general/browser_clipboard.js b/browser/base/content/test/general/browser_clipboard.js
deleted file mode 100644
index 33c6de52d..000000000
--- a/browser/base/content/test/general/browser_clipboard.js
+++ /dev/null
@@ -1,174 +0,0 @@
-// This test is used to check copy and paste in editable areas to ensure that non-text
-// types (html and images) are copied to and pasted from the clipboard properly.
-
-var testPage = "<body style='margin: 0'>" +
- " <img id='img' tabindex='1' src='http://example.org/browser/browser/base/content/test/general/moz.png'>" +
- " <div id='main' contenteditable='true'>Test <b>Bold</b> After Text</div>" +
- "</body>";
-
-add_task(function*() {
- let tab = gBrowser.addTab();
- let browser = gBrowser.getBrowserForTab(tab);
-
- gBrowser.selectedTab = tab;
-
- yield promiseTabLoadEvent(tab, "data:text/html," + escape(testPage));
- yield SimpleTest.promiseFocus(browser.contentWindowAsCPOW);
-
- const modifier = (navigator.platform.indexOf("Mac") >= 0) ?
- Components.interfaces.nsIDOMWindowUtils.MODIFIER_META :
- Components.interfaces.nsIDOMWindowUtils.MODIFIER_CONTROL;
-
- // On windows, HTML clipboard includes extra data.
- // The values are from widget/windows/nsDataObj.cpp.
- const htmlPrefix = (navigator.platform.indexOf("Win") >= 0) ? "<html><body>\n<!--StartFragment-->" : "";
- const htmlPostfix = (navigator.platform.indexOf("Win") >= 0) ? "<!--EndFragment-->\n</body>\n</html>" : "";
-
- yield ContentTask.spawn(browser, { modifier, htmlPrefix, htmlPostfix }, function* (arg) {
- var doc = content.document;
- var main = doc.getElementById("main");
- main.focus();
-
- const utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
-
- function sendKey(key) {
- if (utils.sendKeyEvent("keydown", key, 0, arg.modifier)) {
- utils.sendKeyEvent("keypress", key, key.charCodeAt(0), arg.modifier);
- }
- utils.sendKeyEvent("keyup", key, 0, arg.modifier);
- }
-
- // Select an area of the text.
- let selection = doc.getSelection();
- selection.modify("move", "left", "line");
- selection.modify("move", "right", "character");
- selection.modify("move", "right", "character");
- selection.modify("move", "right", "character");
- selection.modify("extend", "right", "word");
- selection.modify("extend", "right", "word");
-
- yield new Promise((resolve, reject) => {
- addEventListener("copy", function copyEvent(event) {
- removeEventListener("copy", copyEvent, true);
- // The data is empty as the selection is copied during the event default phase.
- Assert.equal(event.clipboardData.mozItemCount, 0, "Zero items on clipboard");
- resolve();
- }, true)
-
- sendKey("c");
- });
-
- selection.modify("move", "right", "line");
-
- yield new Promise((resolve, reject) => {
- addEventListener("paste", function copyEvent(event) {
- removeEventListener("paste", copyEvent, true);
- let clipboardData = event.clipboardData;
- Assert.equal(clipboardData.mozItemCount, 1, "One item on clipboard");
- Assert.equal(clipboardData.types.length, 2, "Two types on clipboard");
- Assert.equal(clipboardData.types[0], "text/html", "text/html on clipboard");
- Assert.equal(clipboardData.types[1], "text/plain", "text/plain on clipboard");
- Assert.equal(clipboardData.getData("text/html"), arg.htmlPrefix +
- "t <b>Bold</b>" + arg.htmlPostfix, "text/html value");
- Assert.equal(clipboardData.getData("text/plain"), "t Bold", "text/plain value");
- resolve();
- }, true)
- sendKey("v");
- });
-
- Assert.equal(main.innerHTML, "Test <b>Bold</b> After Textt <b>Bold</b>", "Copy and paste html");
-
- selection.modify("extend", "left", "word");
- selection.modify("extend", "left", "word");
- selection.modify("extend", "left", "character");
-
- yield new Promise((resolve, reject) => {
- addEventListener("cut", function copyEvent(event) {
- removeEventListener("cut", copyEvent, true);
- event.clipboardData.setData("text/plain", "Some text");
- event.clipboardData.setData("text/html", "<i>Italic</i> ");
- selection.deleteFromDocument();
- event.preventDefault();
- resolve();
- }, true)
- sendKey("x");
- });
-
- selection.modify("move", "left", "line");
-
- yield new Promise((resolve, reject) => {
- addEventListener("paste", function copyEvent(event) {
- removeEventListener("paste", copyEvent, true);
- let clipboardData = event.clipboardData;
- Assert.equal(clipboardData.mozItemCount, 1, "One item on clipboard 2");
- Assert.equal(clipboardData.types.length, 2, "Two types on clipboard 2");
- Assert.equal(clipboardData.types[0], "text/html", "text/html on clipboard 2");
- Assert.equal(clipboardData.types[1], "text/plain", "text/plain on clipboard 2");
- Assert.equal(clipboardData.getData("text/html"), arg.htmlPrefix +
- "<i>Italic</i> " + arg.htmlPostfix, "text/html value 2");
- Assert.equal(clipboardData.getData("text/plain"), "Some text", "text/plain value 2");
- resolve();
- }, true)
- sendKey("v");
- });
-
- Assert.equal(main.innerHTML, "<i>Italic</i> Test <b>Bold</b> After<b></b>",
- "Copy and paste html 2");
- });
-
- // Next, check that the Copy Image command works.
-
- // The context menu needs to be opened to properly initialize for the copy
- // image command to run.
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let contextMenuShown = promisePopupShown(contextMenu);
- BrowserTestUtils.synthesizeMouseAtCenter("#img", { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
- yield contextMenuShown;
-
- document.getElementById("context-copyimage-contents").doCommand();
-
- contextMenu.hidePopup();
- yield promisePopupHidden(contextMenu);
-
- // Focus the content again
- yield SimpleTest.promiseFocus(browser.contentWindowAsCPOW);
-
- yield ContentTask.spawn(browser, { modifier, htmlPrefix, htmlPostfix }, function* (arg) {
- var doc = content.document;
- var main = doc.getElementById("main");
- main.focus();
-
- yield new Promise((resolve, reject) => {
- addEventListener("paste", function copyEvent(event) {
- removeEventListener("paste", copyEvent, true);
- let clipboardData = event.clipboardData;
-
- // DataTransfer doesn't support the image types yet, so only text/html
- // will be present.
- if (clipboardData.getData("text/html") !== arg.htmlPrefix +
- '<img id="img" tabindex="1" src="http://example.org/browser/browser/base/content/test/general/moz.png">' +
- arg.htmlPostfix) {
- reject('Clipboard Data did not contain an image, was ' + clipboardData.getData("text/html"));
- }
- resolve();
- }, true)
-
- const utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
-
- if (utils.sendKeyEvent("keydown", "v", 0, arg.modifier)) {
- utils.sendKeyEvent("keypress", "v", "v".charCodeAt(0), arg.modifier);
- }
- utils.sendKeyEvent("keyup", "v", 0, arg.modifier);
- });
-
- // The new content should now include an image.
- Assert.equal(main.innerHTML, '<i>Italic</i> <img id="img" tabindex="1" ' +
- 'src="http://example.org/browser/browser/base/content/test/general/moz.png">' +
- 'Test <b>Bold</b> After<b></b>', "Paste after copy image");
- });
-
- gBrowser.removeCurrentTab();
-});
-
diff --git a/browser/base/content/test/general/browser_clipboard_pastefile.js b/browser/base/content/test/general/browser_clipboard_pastefile.js
deleted file mode 100644
index fe87284f3..000000000
--- a/browser/base/content/test/general/browser_clipboard_pastefile.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// This test is used to check that pasting files removes all non-file data from
-// event.clipboardData.
-
-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);
- 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)
-
- 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;
-
- yield ContentTask.spawn(browser, { }, function* (arg) {
- content.document.getElementById("input").focus();
- });
-
- yield BrowserTestUtils.synthesizeKey("v", { accelKey: true }, browser);
-
- 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);
-
- 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);
-
- EventUtils.synthesizeKey("v", { accelKey: true });
- });
-
- document.documentElement.removeChild(textbox);
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_contentAltClick.js b/browser/base/content/test/general/browser_contentAltClick.js
deleted file mode 100644
index 1a3b0fccc..000000000
--- a/browser/base/content/test/general/browser_contentAltClick.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Test for Bug 1109146.
- * The tests opens a new tab and alt + clicks to download files
- * and confirms those files are on the download list.
- *
- * The difference between this and the test "browser_contentAreaClick.js" is that
- * the code path in e10s uses ContentClick.jsm instead of browser.js::contentAreaClick() util.
- */
-"use strict";
-
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
- "resource://gre/modules/Downloads.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-function setup() {
- gPrefService.setBoolPref("browser.altClickSave", true);
-
- let testPage =
- 'data:text/html,' +
- '<p><a id="commonlink" href="http://mochi.test/moz/">Common link</a></p>' +
- '<p><math id="mathxlink" xmlns="http://www.w3.org/1998/Math/MathML" xlink:type="simple" xlink:href="http://mochi.test/moz/"><mtext>MathML XLink</mtext></math></p>' +
- '<p><svg id="svgxlink" xmlns="http://www.w3.org/2000/svg" width="100px" height="50px" version="1.1"><a xlink:type="simple" xlink:href="http://mochi.test/moz/"><text transform="translate(10, 25)">SVG XLink</text></a></svg></p>';
-
- return BrowserTestUtils.openNewForegroundTab(gBrowser, testPage);
-}
-
-function* clean_up() {
- // Remove downloads.
- let downloadList = yield Downloads.getList(Downloads.ALL);
- let downloads = yield downloadList.getAll();
- for (let download of downloads) {
- yield downloadList.remove(download);
- yield download.finalize(true);
- }
- // Remove download history.
- yield PlacesTestUtils.clearHistory();
-
- gPrefService.clearUserPref("browser.altClickSave");
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-}
-
-add_task(function* test_alt_click()
-{
- yield setup();
-
- let downloadList = yield Downloads.getList(Downloads.ALL);
- let downloads = [];
- let downloadView;
- // When 1 download has been attempted then resolve the promise.
- let finishedAllDownloads = new Promise( (resolve) => {
- downloadView = {
- onDownloadAdded: function (aDownload) {
- downloads.push(aDownload);
- resolve();
- },
- };
- });
- yield downloadList.addView(downloadView);
- yield BrowserTestUtils.synthesizeMouseAtCenter("#commonlink", {altKey: true}, gBrowser.selectedBrowser);
-
- // Wait for all downloads to be added to the download list.
- yield finishedAllDownloads;
- yield downloadList.removeView(downloadView);
-
- is(downloads.length, 1, "1 downloads");
- is(downloads[0].source.url, "http://mochi.test/moz/", "Downloaded #commonlink element");
-
- yield* clean_up();
-});
-
-add_task(function* test_alt_click_on_xlinks()
-{
- yield setup();
-
- let downloadList = yield Downloads.getList(Downloads.ALL);
- let downloads = [];
- let downloadView;
- // When all 2 downloads have been attempted then resolve the promise.
- let finishedAllDownloads = new Promise( (resolve) => {
- downloadView = {
- onDownloadAdded: function (aDownload) {
- downloads.push(aDownload);
- if (downloads.length == 2) {
- resolve();
- }
- },
- };
- });
- yield downloadList.addView(downloadView);
- yield BrowserTestUtils.synthesizeMouseAtCenter("#mathxlink", {altKey: true}, gBrowser.selectedBrowser);
- yield BrowserTestUtils.synthesizeMouseAtCenter("#svgxlink", {altKey: true}, gBrowser.selectedBrowser);
-
- // Wait for all downloads to be added to the download list.
- yield finishedAllDownloads;
- yield downloadList.removeView(downloadView);
-
- is(downloads.length, 2, "2 downloads");
- is(downloads[0].source.url, "http://mochi.test/moz/", "Downloaded #mathxlink element");
- is(downloads[1].source.url, "http://mochi.test/moz/", "Downloaded #svgxlink element");
-
- yield* clean_up();
-});
diff --git a/browser/base/content/test/general/browser_contentAreaClick.js b/browser/base/content/test/general/browser_contentAreaClick.js
deleted file mode 100644
index facdfb498..000000000
--- a/browser/base/content/test/general/browser_contentAreaClick.js
+++ /dev/null
@@ -1,307 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Test for bug 549340.
- * Test for browser.js::contentAreaClick() util.
- *
- * The test opens a new browser window, then replaces browser.js methods invoked
- * by contentAreaClick with a mock function that tracks which methods have been
- * called.
- * Each sub-test synthesizes a mouse click event on links injected in content,
- * the event is collected by a click handler that ensures that contentAreaClick
- * correctly prevent default events, and follows the correct code path.
- */
-
-var gTests = [
-
- {
- desc: "Simple left click",
- setup: function() {},
- clean: function() {},
- event: {},
- targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
- expectedInvokedMethods: [],
- preventDefault: false,
- },
-
- {
- desc: "Ctrl/Cmd left click",
- setup: function() {},
- clean: function() {},
- event: { ctrlKey: true,
- metaKey: true },
- targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
- expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
- preventDefault: true,
- },
-
- // The next test was once handling feedService.forcePreview(). Now it should
- // just be like Alt click.
- {
- desc: "Shift+Alt left click",
- setup: function() {
- gPrefService.setBoolPref("browser.altClickSave", true);
- },
- clean: function() {
- gPrefService.clearUserPref("browser.altClickSave");
- },
- event: { shiftKey: true,
- altKey: true },
- targets: [ "commonlink", "maplink" ],
- expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
- preventDefault: true,
- },
-
- {
- desc: "Shift+Alt left click on XLinks",
- setup: function() {
- gPrefService.setBoolPref("browser.altClickSave", true);
- },
- clean: function() {
- gPrefService.clearUserPref("browser.altClickSave");
- },
- event: { shiftKey: true,
- altKey: true },
- targets: [ "mathxlink", "svgxlink"],
- expectedInvokedMethods: [ "saveURL" ],
- preventDefault: true,
- },
-
- {
- desc: "Shift click",
- setup: function() {},
- clean: function() {},
- event: { shiftKey: true },
- targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
- expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
- preventDefault: true,
- },
-
- {
- desc: "Alt click",
- setup: function() {
- gPrefService.setBoolPref("browser.altClickSave", true);
- },
- clean: function() {
- gPrefService.clearUserPref("browser.altClickSave");
- },
- event: { altKey: true },
- targets: [ "commonlink", "maplink" ],
- expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
- preventDefault: true,
- },
-
- {
- desc: "Alt click on XLinks",
- setup: function() {
- gPrefService.setBoolPref("browser.altClickSave", true);
- },
- clean: function() {
- gPrefService.clearUserPref("browser.altClickSave");
- },
- event: { altKey: true },
- targets: [ "mathxlink", "svgxlink" ],
- expectedInvokedMethods: [ "saveURL" ],
- preventDefault: true,
- },
-
- {
- desc: "Panel click",
- setup: function() {},
- clean: function() {},
- event: {},
- targets: [ "panellink" ],
- expectedInvokedMethods: [ "urlSecurityCheck", "loadURI" ],
- preventDefault: true,
- },
-
- {
- desc: "Simple middle click opentab",
- setup: function() {},
- clean: function() {},
- event: { button: 1 },
- targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
- expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
- preventDefault: true,
- },
-
- {
- desc: "Simple middle click openwin",
- setup: function() {
- gPrefService.setBoolPref("browser.tabs.opentabfor.middleclick", false);
- },
- clean: function() {
- gPrefService.clearUserPref("browser.tabs.opentabfor.middleclick");
- },
- event: { button: 1 },
- targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
- expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
- preventDefault: true,
- },
-
- {
- desc: "Middle mouse paste",
- setup: function() {
- gPrefService.setBoolPref("middlemouse.contentLoadURL", true);
- gPrefService.setBoolPref("general.autoScroll", false);
- },
- clean: function() {
- gPrefService.clearUserPref("middlemouse.contentLoadURL");
- gPrefService.clearUserPref("general.autoScroll");
- },
- event: { button: 1 },
- targets: [ "emptylink" ],
- expectedInvokedMethods: [ "middleMousePaste" ],
- preventDefault: true,
- },
-
-];
-
-// Array of method names that will be replaced in the new window.
-var gReplacedMethods = [
- "middleMousePaste",
- "urlSecurityCheck",
- "loadURI",
- "gatherTextUnder",
- "saveURL",
- "openLinkIn",
- "getShortcutOrURIAndPostData",
-];
-
-// Reference to the new window.
-var gTestWin = null;
-
-// List of methods invoked by a specific call to contentAreaClick.
-var gInvokedMethods = [];
-
-// The test currently running.
-var gCurrentTest = null;
-
-function test() {
- waitForExplicitFinish();
-
- gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
- whenDelayedStartupFinished(gTestWin, function () {
- info("Browser window opened");
- waitForFocus(function() {
- info("Browser window focused");
- waitForFocus(function() {
- info("Setting up browser...");
- setupTestBrowserWindow();
- info("Running tests...");
- executeSoon(runNextTest);
- }, gTestWin.content, true);
- }, gTestWin);
- });
-}
-
-// Click handler used to steal click events.
-var gClickHandler = {
- handleEvent: function (event) {
- let linkId = event.target.id || event.target.localName;
- is(event.type, "click",
- gCurrentTest.desc + ":Handler received a click event on " + linkId);
-
- let isPanelClick = linkId == "panellink";
- gTestWin.contentAreaClick(event, isPanelClick);
- let prevent = event.defaultPrevented;
- is(prevent, gCurrentTest.preventDefault,
- gCurrentTest.desc + ": event.defaultPrevented is correct (" + prevent + ")")
-
- // Check that all required methods have been called.
- gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
- isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
- gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
- });
-
- if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
- ok(false, "Wrong number of invoked methods");
- gInvokedMethods.forEach(method => info(method + " was invoked"));
- }
-
- event.preventDefault();
- event.stopPropagation();
-
- executeSoon(runNextTest);
- }
-}
-
-// Wraps around the methods' replacement mock function.
-function wrapperMethod(aInvokedMethods, aMethodName) {
- return function () {
- aInvokedMethods.push(aMethodName);
- // At least getShortcutOrURIAndPostData requires to return url
- return (aMethodName == "getShortcutOrURIAndPostData") ? arguments.url : arguments[0];
- }
-}
-
-function setupTestBrowserWindow() {
- // Steal click events and don't propagate them.
- gTestWin.addEventListener("click", gClickHandler, true);
-
- // Replace methods.
- gReplacedMethods.forEach(function (aMethodName) {
- gTestWin["old_" + aMethodName] = gTestWin[aMethodName];
- gTestWin[aMethodName] = wrapperMethod(gInvokedMethods, aMethodName);
- });
-
- // Inject links in content.
- let doc = gTestWin.content.document;
- let mainDiv = doc.createElement("div");
- mainDiv.innerHTML =
- '<p><a id="commonlink" href="http://mochi.test/moz/">Common link</a></p>' +
- '<p><a id="panellink" href="http://mochi.test/moz/">Panel link</a></p>' +
- '<p><a id="emptylink">Empty link</a></p>' +
- '<p><math id="mathxlink" xmlns="http://www.w3.org/1998/Math/MathML" xlink:type="simple" xlink:href="http://mochi.test/moz/"><mtext>MathML XLink</mtext></math></p>' +
- '<p><svg id="svgxlink" xmlns="http://www.w3.org/2000/svg" width="100px" height="50px" version="1.1"><a xlink:type="simple" xlink:href="http://mochi.test/moz/"><text transform="translate(10, 25)">SVG XLink</text></a></svg></p>' +
- '<p><map name="map" id="map"><area href="http://mochi.test/moz/" shape="rect" coords="0,0,128,128" /></map><img id="maplink" usemap="#map" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAABGdBTUEAALGPC%2FxhBQAAAOtJREFUeF7t0IEAAAAAgKD9qRcphAoDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGBgwIAAAT0N51AAAAAASUVORK5CYII%3D"/></p>'
- doc.body.appendChild(mainDiv);
-}
-
-function runNextTest() {
- if (!gCurrentTest) {
- gCurrentTest = gTests.shift();
- gCurrentTest.setup();
- }
-
- if (gCurrentTest.targets.length == 0) {
- info(gCurrentTest.desc + ": cleaning up...")
- gCurrentTest.clean();
-
- if (gTests.length > 0) {
- gCurrentTest = gTests.shift();
- gCurrentTest.setup();
- }
- else {
- finishTest();
- return;
- }
- }
-
- // Move to next target.
- gInvokedMethods.length = 0;
- let target = gCurrentTest.targets.shift();
-
- info(gCurrentTest.desc + ": testing " + target);
-
- // Fire click event.
- let targetElt = gTestWin.content.document.getElementById(target);
- ok(targetElt, gCurrentTest.desc + ": target is valid (" + targetElt.id + ")");
- EventUtils.synthesizeMouseAtCenter(targetElt, gCurrentTest.event, gTestWin.content);
-}
-
-function finishTest() {
- info("Restoring browser...");
- gTestWin.removeEventListener("click", gClickHandler, true);
-
- // Restore original methods.
- gReplacedMethods.forEach(function (aMethodName) {
- gTestWin[aMethodName] = gTestWin["old_" + aMethodName];
- delete gTestWin["old_" + aMethodName];
- });
-
- gTestWin.close();
- finish();
-}
diff --git a/browser/base/content/test/general/browser_contentSearchUI.js b/browser/base/content/test/general/browser_contentSearchUI.js
deleted file mode 100644
index 003f80aff..000000000
--- a/browser/base/content/test/general/browser_contentSearchUI.js
+++ /dev/null
@@ -1,771 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const TEST_PAGE_BASENAME = "contentSearchUI.html";
-const TEST_CONTENT_SCRIPT_BASENAME = "contentSearchUI.js";
-const TEST_ENGINE_PREFIX = "browser_searchSuggestionEngine";
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-const TEST_ENGINE_2_BASENAME = "searchSuggestionEngine2.xml";
-
-const TEST_MSG = "ContentSearchUIControllerTest";
-
-requestLongerTimeout(2);
-
-add_task(function* emptyInput() {
- yield setUp();
-
- let state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("key", "VK_BACK_SPACE");
- checkState(state, "", [], -1);
-
- yield msg("reset");
-});
-
-add_task(function* blur() {
- yield setUp();
-
- let state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("blur");
- checkState(state, "x", [], -1);
-
- yield msg("reset");
-});
-
-add_task(function* upDownKeys() {
- yield setUp();
-
- let state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- // Cycle down the suggestions starting from no selection.
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoo", ["xfoo", "xbar"], 0);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xbar", ["xfoo", "xbar"], 1);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "x", ["xfoo", "xbar"], 2);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "x", ["xfoo", "xbar"], 3);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- // Cycle up starting from no selection.
- state = yield msg("key", "VK_UP");
- checkState(state, "x", ["xfoo", "xbar"], 3);
-
- state = yield msg("key", "VK_UP");
- checkState(state, "x", ["xfoo", "xbar"], 2);
-
- state = yield msg("key", "VK_UP");
- checkState(state, "xbar", ["xfoo", "xbar"], 1);
-
- state = yield msg("key", "VK_UP");
- checkState(state, "xfoo", ["xfoo", "xbar"], 0);
-
- state = yield msg("key", "VK_UP");
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- yield msg("reset");
-});
-
-add_task(function* rightLeftKeys() {
- yield setUp();
-
- let state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("key", "VK_LEFT");
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("key", "VK_LEFT");
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("key", "VK_RIGHT");
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("key", "VK_RIGHT");
- checkState(state, "x", [], -1);
-
- state = yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoo", ["xfoo", "xbar"], 0);
-
- // This should make the xfoo suggestion sticky. To make sure it sticks,
- // trigger suggestions again and cycle through them by pressing Down until
- // nothing is selected again.
- state = yield msg("key", "VK_RIGHT");
- checkState(state, "xfoo", [], -1);
-
- state = yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
- checkState(state, "xfoo", ["xfoofoo", "xfoobar"], -1);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoofoo", ["xfoofoo", "xfoobar"], 0);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoobar", ["xfoofoo", "xfoobar"], 1);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoo", ["xfoofoo", "xfoobar"], 2);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoo", ["xfoofoo", "xfoobar"], 3);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoo", ["xfoofoo", "xfoobar"], -1);
-
- yield msg("reset");
-});
-
-add_task(function* tabKey() {
- yield setUp();
- yield msg("key", { key: "x", waitForSuggestions: true });
-
- let state = yield msg("key", "VK_TAB");
- checkState(state, "x", ["xfoo", "xbar"], 2);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "x", ["xfoo", "xbar"], 3);
-
- state = yield msg("key", { key: "VK_TAB", modifiers: { shiftKey: true }});
- checkState(state, "x", ["xfoo", "xbar"], 2);
-
- state = yield msg("key", { key: "VK_TAB", modifiers: { shiftKey: true }});
- checkState(state, "x", [], -1);
-
- yield setUp();
-
- yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
-
- for (let i = 0; i < 3; ++i) {
- state = yield msg("key", "VK_TAB");
- }
- checkState(state, "x", [], -1);
-
- yield setUp();
-
- yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xfoo", ["xfoo", "xbar"], 0);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "xfoo", ["xfoo", "xbar"], 0, 0);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "xfoo", ["xfoo", "xbar"], 0, 1);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 1);
-
- state = yield msg("key", "VK_DOWN");
- checkState(state, "x", ["xfoo", "xbar"], 2);
-
- state = yield msg("key", "VK_UP");
- checkState(state, "xbar", ["xfoo", "xbar"], 1);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 0);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 1);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "xbar", [], -1);
-
- yield msg("reset");
-});
-
-add_task(function* cycleSuggestions() {
- yield setUp();
- yield msg("key", { key: "x", waitForSuggestions: true });
-
- let cycle = Task.async(function* (aSelectedButtonIndex) {
- let modifiers = {
- shiftKey: true,
- accelKey: true,
- };
-
- let state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xfoo", ["xfoo", "xbar"], 0, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "x", ["xfoo", "xbar"], -1, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xfoo", ["xfoo", "xbar"], 0, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "x", ["xfoo", "xbar"], -1, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "xfoo", ["xfoo", "xbar"], 0, aSelectedButtonIndex);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "x", ["xfoo", "xbar"], -1, aSelectedButtonIndex);
- });
-
- yield cycle();
-
- // Repeat with a one-off selected.
- let state = yield msg("key", "VK_TAB");
- checkState(state, "x", ["xfoo", "xbar"], 2);
- yield cycle(0);
-
- // Repeat with the settings button selected.
- state = yield msg("key", "VK_TAB");
- checkState(state, "x", ["xfoo", "xbar"], 3);
- yield cycle(1);
-
- yield msg("reset");
-});
-
-add_task(function* cycleOneOffs() {
- yield setUp();
- yield msg("key", { key: "x", waitForSuggestions: true });
-
- yield msg("addDuplicateOneOff");
-
- let state = yield msg("key", "VK_DOWN");
- state = yield msg("key", "VK_DOWN");
- checkState(state, "xbar", ["xfoo", "xbar"], 1);
-
- let modifiers = {
- altKey: true,
- };
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 0);
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 1);
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 1);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 0);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1);
-
- // If the settings button is selected, pressing alt+up/down should select the
- // last/first one-off respectively (and deselect the settings button).
- yield msg("key", "VK_TAB");
- yield msg("key", "VK_TAB");
- state = yield msg("key", "VK_TAB"); // Settings button selected.
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 2);
-
- state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 1);
-
- state = yield msg("key", "VK_TAB");
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 2);
-
- state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
- checkState(state, "xbar", ["xfoo", "xbar"], 1, 0);
-
- yield msg("removeLastOneOff");
- yield msg("reset");
-});
-
-add_task(function* mouse() {
- yield setUp();
-
- let state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("mousemove", 0);
- checkState(state, "x", ["xfoo", "xbar"], 0);
-
- state = yield msg("mousemove", 1);
- checkState(state, "x", ["xfoo", "xbar"], 1);
-
- state = yield msg("mousemove", 2);
- checkState(state, "x", ["xfoo", "xbar"], 1, 0);
-
- state = yield msg("mousemove", 3);
- checkState(state, "x", ["xfoo", "xbar"], 1, 1);
-
- state = yield msg("mousemove", -1);
- checkState(state, "x", ["xfoo", "xbar"], 1);
-
- yield msg("reset");
- yield setUp();
-
- state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- state = yield msg("mousemove", 0);
- checkState(state, "x", ["xfoo", "xbar"], 0);
-
- state = yield msg("mousemove", 2);
- checkState(state, "x", ["xfoo", "xbar"], 0, 0);
-
- state = yield msg("mousemove", -1);
- checkState(state, "x", ["xfoo", "xbar"], 0);
-
- yield msg("reset");
-});
-
-add_task(function* formHistory() {
- yield setUp();
-
- // Type an X and add it to form history.
- let state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
- // Wait for Satchel to say it's been added to form history.
- let deferred = Promise.defer();
- Services.obs.addObserver(function onAdd(subj, topic, data) {
- if (data == "formhistory-add") {
- Services.obs.removeObserver(onAdd, "satchel-storage-changed");
- executeSoon(() => deferred.resolve());
- }
- }, "satchel-storage-changed", false);
- yield Promise.all([msg("addInputValueToFormHistory"), deferred.promise]);
-
- // Reset the input.
- state = yield msg("reset");
- checkState(state, "", [], -1);
-
- // Type an X again. The form history entry should appear.
- state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", [{ str: "x", type: "formHistory" }, "xfoo", "xbar"],
- -1);
-
- // Select the form history entry and delete it.
- state = yield msg("key", "VK_DOWN");
- checkState(state, "x", [{ str: "x", type: "formHistory" }, "xfoo", "xbar"],
- 0);
-
- // Wait for Satchel.
- deferred = Promise.defer();
- Services.obs.addObserver(function onRemove(subj, topic, data) {
- if (data == "formhistory-remove") {
- Services.obs.removeObserver(onRemove, "satchel-storage-changed");
- executeSoon(() => deferred.resolve());
- }
- }, "satchel-storage-changed", false);
-
- state = yield msg("key", "VK_DELETE");
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- yield deferred.promise;
-
- // Reset the input.
- state = yield msg("reset");
- checkState(state, "", [], -1);
-
- // Type an X again. The form history entry should still be gone.
- state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- yield msg("reset");
-});
-
-add_task(function* cycleEngines() {
- yield setUp();
- yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
-
- let promiseEngineChange = function(newEngineName) {
- let deferred = Promise.defer();
- Services.obs.addObserver(function resolver(subj, topic, data) {
- if (data != "engine-current") {
- return;
- }
- SimpleTest.is(subj.name, newEngineName, "Engine cycled correctly");
- Services.obs.removeObserver(resolver, "browser-search-engine-modified");
- deferred.resolve();
- }, "browser-search-engine-modified", false);
- return deferred.promise;
- }
-
- let p = promiseEngineChange(TEST_ENGINE_PREFIX + " " + TEST_ENGINE_2_BASENAME);
- yield msg("key", { key: "VK_DOWN", modifiers: { accelKey: true }});
- yield p;
-
- p = promiseEngineChange(TEST_ENGINE_PREFIX + " " + TEST_ENGINE_BASENAME);
- yield msg("key", { key: "VK_UP", modifiers: { accelKey: true }});
- yield p;
-
- yield msg("reset");
-});
-
-add_task(function* search() {
- yield setUp();
-
- let modifiers = {};
- ["altKey", "ctrlKey", "metaKey", "shiftKey"].forEach(k => modifiers[k] = true);
-
- // Test typing a query and pressing enter.
- let p = msg("waitForSearch");
- yield msg("key", { key: "x", waitForSuggestions: true });
- yield msg("key", { key: "VK_RETURN", modifiers: modifiers });
- let mesg = yield p;
- let eventData = {
- engineName: TEST_ENGINE_PREFIX + " " + TEST_ENGINE_BASENAME,
- searchString: "x",
- healthReportKey: "test",
- searchPurpose: "test",
- originalEvent: modifiers,
- };
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test typing a query, then selecting a suggestion and pressing enter.
- p = msg("waitForSearch");
- yield msg("key", { key: "x", waitForSuggestions: true });
- yield msg("key", "VK_DOWN");
- yield msg("key", "VK_DOWN");
- yield msg("key", { key: "VK_RETURN", modifiers: modifiers });
- mesg = yield p;
- eventData.searchString = "xfoo";
- eventData.engineName = TEST_ENGINE_PREFIX + " " + TEST_ENGINE_BASENAME;
- eventData.selection = {
- index: 1,
- kind: "key",
- }
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test typing a query, then selecting a one-off button and pressing enter.
- p = msg("waitForSearch");
- yield msg("key", { key: "x", waitForSuggestions: true });
- yield msg("key", "VK_UP");
- yield msg("key", "VK_UP");
- yield msg("key", { key: "VK_RETURN", modifiers: modifiers });
- mesg = yield p;
- delete eventData.selection;
- eventData.searchString = "x";
- eventData.engineName = TEST_ENGINE_PREFIX + " " + TEST_ENGINE_2_BASENAME;
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test typing a query and clicking the search engine header.
- p = msg("waitForSearch");
- modifiers.button = 0;
- yield msg("key", { key: "x", waitForSuggestions: true });
- yield msg("mousemove", -1);
- yield msg("click", { eltIdx: -1, modifiers: modifiers });
- mesg = yield p;
- eventData.originalEvent = modifiers;
- eventData.engineName = TEST_ENGINE_PREFIX + " " + TEST_ENGINE_BASENAME;
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test typing a query and then clicking a suggestion.
- yield msg("key", { key: "x", waitForSuggestions: true });
- p = msg("waitForSearch");
- yield msg("mousemove", 1);
- yield msg("click", { eltIdx: 1, modifiers: modifiers });
- mesg = yield p;
- eventData.searchString = "xfoo";
- eventData.selection = {
- index: 1,
- kind: "mouse",
- };
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test typing a query and then clicking a one-off button.
- yield msg("key", { key: "x", waitForSuggestions: true });
- p = msg("waitForSearch");
- yield msg("mousemove", 3);
- yield msg("click", { eltIdx: 3, modifiers: modifiers });
- mesg = yield p;
- eventData.searchString = "x";
- eventData.engineName = TEST_ENGINE_PREFIX + " " + TEST_ENGINE_2_BASENAME;
- delete eventData.selection;
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test selecting a suggestion, then clicking a one-off without deselecting the
- // suggestion.
- yield msg("key", { key: "x", waitForSuggestions: true });
- p = msg("waitForSearch");
- yield msg("mousemove", 1);
- yield msg("mousemove", 3);
- yield msg("click", { eltIdx: 3, modifiers: modifiers });
- mesg = yield p;
- eventData.searchString = "xfoo"
- eventData.selection = {
- index: 1,
- kind: "mouse",
- };
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Same as above, but with the keyboard.
- delete modifiers.button;
- yield msg("key", { key: "x", waitForSuggestions: true });
- p = msg("waitForSearch");
- yield msg("key", "VK_DOWN");
- yield msg("key", "VK_DOWN");
- yield msg("key", "VK_TAB");
- yield msg("key", { key: "VK_RETURN", modifiers: modifiers });
- mesg = yield p;
- eventData.selection = {
- index: 1,
- kind: "key",
- };
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Test searching when using IME composition.
- let state = yield msg("startComposition", { data: "" });
- checkState(state, "", [], -1);
- state = yield msg("changeComposition", { data: "x", waitForSuggestions: true });
- checkState(state, "x", [{ str: "x", type: "formHistory" },
- { str: "xfoo", type: "formHistory" }, "xbar"], -1);
- yield msg("commitComposition");
- delete modifiers.button;
- p = msg("waitForSearch");
- yield msg("key", { key: "VK_RETURN", modifiers: modifiers });
- mesg = yield p;
- eventData.searchString = "x"
- eventData.originalEvent = modifiers;
- eventData.engineName = TEST_ENGINE_PREFIX + " " + TEST_ENGINE_BASENAME;
- delete eventData.selection;
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- state = yield msg("startComposition", { data: "" });
- checkState(state, "", [], -1);
- state = yield msg("changeComposition", { data: "x", waitForSuggestions: true });
- checkState(state, "x", [{ str: "x", type: "formHistory" },
- { str: "xfoo", type: "formHistory" }, "xbar"], -1);
-
- // Mouse over the first suggestion.
- state = yield msg("mousemove", 0);
- checkState(state, "x", [{ str: "x", type: "formHistory" },
- { str: "xfoo", type: "formHistory" }, "xbar"], 0);
-
- // Mouse over the second suggestion.
- state = yield msg("mousemove", 1);
- checkState(state, "x", [{ str: "x", type: "formHistory" },
- { str: "xfoo", type: "formHistory" }, "xbar"], 1);
-
- modifiers.button = 0;
- p = msg("waitForSearch");
- yield msg("click", { eltIdx: 1, modifiers: modifiers });
- mesg = yield p;
- eventData.searchString = "xfoo";
- eventData.originalEvent = modifiers;
- eventData.selection = {
- index: 1,
- kind: "mouse",
- };
- SimpleTest.isDeeply(eventData, mesg, "Search event data");
-
- yield promiseTab();
- yield setUp();
-
- // Remove form history entries.
- // Wait for Satchel.
- let deferred = Promise.defer();
- let historyCount = 2;
- Services.obs.addObserver(function onRemove(subj, topic, data) {
- if (data == "formhistory-remove") {
- if (--historyCount) {
- return;
- }
- Services.obs.removeObserver(onRemove, "satchel-storage-changed");
- executeSoon(() => deferred.resolve());
- }
- }, "satchel-storage-changed", false);
-
- yield msg("key", { key: "x", waitForSuggestions: true });
- yield msg("key", "VK_DOWN");
- yield msg("key", "VK_DOWN");
- yield msg("key", "VK_DELETE");
- yield msg("key", "VK_DOWN");
- yield msg("key", "VK_DELETE");
- yield deferred.promise;
-
- yield msg("reset");
- state = yield msg("key", { key: "x", waitForSuggestions: true });
- checkState(state, "x", ["xfoo", "xbar"], -1);
-
- yield promiseTab();
- yield setUp();
- yield msg("reset");
-});
-
-add_task(function* settings() {
- yield setUp();
- yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
- yield msg("key", "VK_UP");
- let p = msg("waitForSearchSettings");
- yield msg("key", "VK_RETURN");
- yield p;
-
- yield msg("reset");
-});
-
-var gDidInitialSetUp = false;
-
-function setUp(aNoEngine) {
- return Task.spawn(function* () {
- if (!gDidInitialSetUp) {
- Cu.import("resource:///modules/ContentSearch.jsm");
- let originalOnMessageSearch = ContentSearch._onMessageSearch;
- let originalOnMessageManageEngines = ContentSearch._onMessageManageEngines;
- ContentSearch._onMessageSearch = () => {};
- ContentSearch._onMessageManageEngines = () => {};
- registerCleanupFunction(() => {
- ContentSearch._onMessageSearch = originalOnMessageSearch;
- ContentSearch._onMessageManageEngines = originalOnMessageManageEngines;
- });
- yield setUpEngines();
- yield promiseTab();
- gDidInitialSetUp = true;
- }
- yield msg("focus");
- });
-}
-
-function msg(type, data=null) {
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: type,
- data: data,
- });
- let deferred = Promise.defer();
- gMsgMan.addMessageListener(TEST_MSG, function onMsg(msgObj) {
- if (msgObj.data.type != type) {
- return;
- }
- gMsgMan.removeMessageListener(TEST_MSG, onMsg);
- deferred.resolve(msgObj.data.data);
- });
- return deferred.promise;
-}
-
-function checkState(actualState, expectedInputVal, expectedSuggestions,
- expectedSelectedIdx, expectedSelectedButtonIdx) {
- expectedSuggestions = expectedSuggestions.map(sugg => {
- return typeof(sugg) == "object" ? sugg : {
- str: sugg,
- type: "remote",
- };
- });
-
- if (expectedSelectedIdx == -1 && expectedSelectedButtonIdx != undefined) {
- expectedSelectedIdx = expectedSuggestions.length + expectedSelectedButtonIdx;
- }
-
- let expectedState = {
- selectedIndex: expectedSelectedIdx,
- numSuggestions: expectedSuggestions.length,
- suggestionAtIndex: expectedSuggestions.map(s => s.str),
- isFormHistorySuggestionAtIndex:
- expectedSuggestions.map(s => s.type == "formHistory"),
-
- tableHidden: expectedSuggestions.length == 0,
-
- inputValue: expectedInputVal,
- ariaExpanded: expectedSuggestions.length == 0 ? "false" : "true",
- };
- if (expectedSelectedButtonIdx != undefined) {
- expectedState.selectedButtonIndex = expectedSelectedButtonIdx;
- }
- else if (expectedSelectedIdx < expectedSuggestions.length) {
- expectedState.selectedButtonIndex = -1;
- }
- else {
- expectedState.selectedButtonIndex = expectedSelectedIdx - expectedSuggestions.length;
- }
-
- SimpleTest.isDeeply(actualState, expectedState, "State");
-}
-
-var gMsgMan;
-
-function* promiseTab() {
- let deferred = Promise.defer();
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- registerCleanupFunction(() => BrowserTestUtils.removeTab(tab));
- let pageURL = getRootDirectory(gTestPath) + TEST_PAGE_BASENAME;
- tab.linkedBrowser.addEventListener("load", function onLoad(event) {
- tab.linkedBrowser.removeEventListener("load", onLoad, true);
- gMsgMan = tab.linkedBrowser.messageManager;
- gMsgMan.sendAsyncMessage("ContentSearch", {
- type: "AddToWhitelist",
- data: [pageURL],
- });
- promiseMsg("ContentSearch", "AddToWhitelistAck", gMsgMan).then(() => {
- let jsURL = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
- gMsgMan.loadFrameScript(jsURL, false);
- deferred.resolve(msg("init"));
- });
- }, true, true);
- openUILinkIn(pageURL, "current");
- return deferred.promise;
-}
-
-function promiseMsg(name, type, msgMan) {
- let deferred = Promise.defer();
- info("Waiting for " + name + " message " + type + "...");
- msgMan.addMessageListener(name, function onMsg(msgObj) {
- info("Received " + name + " message " + msgObj.data.type + "\n");
- if (msgObj.data.type == type) {
- msgMan.removeMessageListener(name, onMsg);
- deferred.resolve(msgObj);
- }
- });
- return deferred.promise;
-}
-
-function setUpEngines() {
- return Task.spawn(function* () {
- info("Removing default search engines");
- let currentEngineName = Services.search.currentEngine.name;
- let currentEngines = Services.search.getVisibleEngines();
- info("Adding test search engines");
- let engine1 = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
- yield promiseNewSearchEngine(TEST_ENGINE_2_BASENAME);
- Services.search.currentEngine = engine1;
- for (let engine of currentEngines) {
- Services.search.removeEngine(engine);
- }
- registerCleanupFunction(() => {
- Services.search.restoreDefaultEngines();
- Services.search.currentEngine = Services.search.getEngineByName(currentEngineName);
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_contextmenu.js b/browser/base/content/test/general/browser_contextmenu.js
deleted file mode 100644
index 3e0135848..000000000
--- a/browser/base/content/test/general/browser_contextmenu.js
+++ /dev/null
@@ -1,996 +0,0 @@
-"use strict";
-
-let contextMenu;
-let LOGIN_FILL_ITEMS = [
- "---", null,
- "fill-login", null,
- [
- "fill-login-no-logins", false,
- "---", null,
- "fill-login-saved-passwords", true
- ], null,
-];
-let hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
-let hasContainers = Services.prefs.getBoolPref("privacy.userContext.enabled");
-
-const example_base = "http://example.com/browser/browser/base/content/test/general/";
-const chrome_base = "chrome://mochitests/content/browser/browser/base/content/test/general/";
-
-Services.scriptloader.loadSubScript(chrome_base + "contextmenu_common.js", this);
-
-// Below are test cases for XUL element
-add_task(function* test_xul_text_link_label() {
- let url = chrome_base + "subtst_contextmenu_xul.xul";
-
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-
- yield test_contextmenu("#test-xul-text-link-label",
- ["context-openlinkintab", true,
- ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
- // We need a blank entry here because the containers submenu is
- // dynamically generated with no ids.
- ...(hasContainers ? ["", null] : []),
- "context-openlink", true,
- "context-openlinkprivate", true,
- "---", null,
- "context-bookmarklink", true,
- "context-savelink", true,
- ...(hasPocket ? ["context-savelinktopocket", true] : []),
- "context-copylink", true,
- "context-searchselect", true
- ]
- );
-
- // Clean up so won't affect HTML element test cases
- lastElementSelector = null;
- gBrowser.removeCurrentTab();
-});
-
-// Below are test cases for HTML element
-
-add_task(function* test_setup_html() {
- let url = example_base + "subtst_contextmenu.html";
-
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let videoIframe = doc.querySelector("#test-video-in-iframe");
- let video = videoIframe.contentDocument.querySelector("video");
- let awaitPause = ContentTaskUtils.waitForEvent(video, "pause");
- video.pause();
- yield awaitPause;
-
- let audioIframe = doc.querySelector("#test-audio-in-iframe");
- // media documents always use a <video> tag.
- let audio = audioIframe.contentDocument.querySelector("video");
- awaitPause = ContentTaskUtils.waitForEvent(audio, "pause");
- audio.pause();
- yield awaitPause;
- });
-});
-
-let plainTextItems;
-add_task(function* test_plaintext() {
- plainTextItems = ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ];
- yield test_contextmenu("#test-text", plainTextItems);
-});
-
-add_task(function* test_link() {
- yield test_contextmenu("#test-link",
- ["context-openlinkintab", true,
- ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
- // We need a blank entry here because the containers submenu is
- // dynamically generated with no ids.
- ...(hasContainers ? ["", null] : []),
- "context-openlink", true,
- "context-openlinkprivate", true,
- "---", null,
- "context-bookmarklink", true,
- "context-savelink", true,
- ...(hasPocket ? ["context-savelinktopocket", true] : []),
- "context-copylink", true,
- "context-searchselect", true
- ]
- );
-});
-
-add_task(function* test_mailto() {
- yield test_contextmenu("#test-mailto",
- ["context-copyemail", true,
- "context-searchselect", true
- ]
- );
-});
-
-add_task(function* test_image() {
- yield test_contextmenu("#test-image",
- ["context-viewimage", true,
- "context-copyimage-contents", true,
- "context-copyimage", true,
- "---", null,
- "context-saveimage", true,
- "context-sendimage", true,
- "context-setDesktopBackground", true,
- "context-viewimageinfo", true
- ]
- );
-});
-
-add_task(function* test_canvas() {
- yield test_contextmenu("#test-canvas",
- ["context-viewimage", true,
- "context-saveimage", true,
- "context-selectall", true
- ]
- );
-});
-
-add_task(function* test_video_ok() {
- yield test_contextmenu("#test-video-ok",
- ["context-media-play", true,
- "context-media-mute", true,
- "context-media-playbackrate", null,
- ["context-media-playbackrate-050x", true,
- "context-media-playbackrate-100x", true,
- "context-media-playbackrate-125x", true,
- "context-media-playbackrate-150x", true,
- "context-media-playbackrate-200x", true], null,
- "context-media-loop", true,
- "context-media-hidecontrols", true,
- "context-video-fullscreen", true,
- "---", null,
- "context-viewvideo", true,
- "context-copyvideourl", true,
- "---", null,
- "context-savevideo", true,
- "context-video-saveimage", true,
- "context-sendvideo", true,
- "context-castvideo", null,
- [], null
- ]
- );
-});
-
-add_task(function* test_audio_in_video() {
- yield test_contextmenu("#test-audio-in-video",
- ["context-media-play", true,
- "context-media-mute", true,
- "context-media-playbackrate", null,
- ["context-media-playbackrate-050x", true,
- "context-media-playbackrate-100x", true,
- "context-media-playbackrate-125x", true,
- "context-media-playbackrate-150x", true,
- "context-media-playbackrate-200x", true], null,
- "context-media-loop", true,
- "context-media-showcontrols", true,
- "---", null,
- "context-copyaudiourl", true,
- "---", null,
- "context-saveaudio", true,
- "context-sendaudio", true
- ]
- );
-});
-
-add_task(function* test_video_bad() {
- yield test_contextmenu("#test-video-bad",
- ["context-media-play", false,
- "context-media-mute", false,
- "context-media-playbackrate", null,
- ["context-media-playbackrate-050x", false,
- "context-media-playbackrate-100x", false,
- "context-media-playbackrate-125x", false,
- "context-media-playbackrate-150x", false,
- "context-media-playbackrate-200x", false], null,
- "context-media-loop", true,
- "context-media-hidecontrols", false,
- "context-video-fullscreen", false,
- "---", null,
- "context-viewvideo", true,
- "context-copyvideourl", true,
- "---", null,
- "context-savevideo", true,
- "context-video-saveimage", false,
- "context-sendvideo", true,
- "context-castvideo", null,
- [], null
- ]
- );
-});
-
-add_task(function* test_video_bad2() {
- yield test_contextmenu("#test-video-bad2",
- ["context-media-play", false,
- "context-media-mute", false,
- "context-media-playbackrate", null,
- ["context-media-playbackrate-050x", false,
- "context-media-playbackrate-100x", false,
- "context-media-playbackrate-125x", false,
- "context-media-playbackrate-150x", false,
- "context-media-playbackrate-200x", false], null,
- "context-media-loop", true,
- "context-media-hidecontrols", false,
- "context-video-fullscreen", false,
- "---", null,
- "context-viewvideo", false,
- "context-copyvideourl", false,
- "---", null,
- "context-savevideo", false,
- "context-video-saveimage", false,
- "context-sendvideo", false,
- "context-castvideo", null,
- [], null
- ]
- );
-});
-
-add_task(function* test_iframe() {
- yield test_contextmenu("#test-iframe",
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "frame", null,
- ["context-showonlythisframe", true,
- "context-openframeintab", true,
- "context-openframe", true,
- "---", null,
- "context-reloadframe", true,
- "---", null,
- "context-bookmarkframe", true,
- "context-saveframe", true,
- "---", null,
- "context-printframe", true,
- "---", null,
- "context-viewframesource", true,
- "context-viewframeinfo", true], null,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ]
- );
-});
-
-add_task(function* test_video_in_iframe() {
- yield test_contextmenu("#test-video-in-iframe",
- ["context-media-play", true,
- "context-media-mute", true,
- "context-media-playbackrate", null,
- ["context-media-playbackrate-050x", true,
- "context-media-playbackrate-100x", true,
- "context-media-playbackrate-125x", true,
- "context-media-playbackrate-150x", true,
- "context-media-playbackrate-200x", true], null,
- "context-media-loop", true,
- "context-media-hidecontrols", true,
- "context-video-fullscreen", true,
- "---", null,
- "context-viewvideo", true,
- "context-copyvideourl", true,
- "---", null,
- "context-savevideo", true,
- "context-video-saveimage", true,
- "context-sendvideo", true,
- "context-castvideo", null,
- [], null,
- "frame", null,
- ["context-showonlythisframe", true,
- "context-openframeintab", true,
- "context-openframe", true,
- "---", null,
- "context-reloadframe", true,
- "---", null,
- "context-bookmarkframe", true,
- "context-saveframe", true,
- "---", null,
- "context-printframe", true,
- "---", null,
- "context-viewframeinfo", true], null]
- );
-});
-
-add_task(function* test_audio_in_iframe() {
- yield test_contextmenu("#test-audio-in-iframe",
- ["context-media-play", true,
- "context-media-mute", true,
- "context-media-playbackrate", null,
- ["context-media-playbackrate-050x", true,
- "context-media-playbackrate-100x", true,
- "context-media-playbackrate-125x", true,
- "context-media-playbackrate-150x", true,
- "context-media-playbackrate-200x", true], null,
- "context-media-loop", true,
- "---", null,
- "context-copyaudiourl", true,
- "---", null,
- "context-saveaudio", true,
- "context-sendaudio", true,
- "frame", null,
- ["context-showonlythisframe", true,
- "context-openframeintab", true,
- "context-openframe", true,
- "---", null,
- "context-reloadframe", true,
- "---", null,
- "context-bookmarkframe", true,
- "context-saveframe", true,
- "---", null,
- "context-printframe", true,
- "---", null,
- "context-viewframeinfo", true], null]
- );
-});
-
-add_task(function* test_image_in_iframe() {
- yield test_contextmenu("#test-image-in-iframe",
- ["context-viewimage", true,
- "context-copyimage-contents", true,
- "context-copyimage", true,
- "---", null,
- "context-saveimage", true,
- "context-sendimage", true,
- "context-setDesktopBackground", true,
- "context-viewimageinfo", true,
- "frame", null,
- ["context-showonlythisframe", true,
- "context-openframeintab", true,
- "context-openframe", true,
- "---", null,
- "context-reloadframe", true,
- "---", null,
- "context-bookmarkframe", true,
- "context-saveframe", true,
- "---", null,
- "context-printframe", true,
- "---", null,
- "context-viewframeinfo", true], null]
- );
-});
-
-add_task(function* test_textarea() {
- // Disabled since this is seeing spell-check-enabled
- // instead of spell-add-dictionaries-main
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-textarea",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null,
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-add-dictionaries-main", true,
- ],
- {
- skipFocusChange: true,
- }
- );
- */
-});
-
-add_task(function* test_textarea_spellcheck() {
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-textarea",
- ["*chubbiness", true, // spelling suggestion
- "spell-add-to-dictionary", true,
- "---", null,
- "context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true,
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null
- ],
- {
- waitForSpellCheck: true,
- offsetX: 6,
- offsetY: 6,
- postCheckContextMenuFn() {
- document.getElementById("spell-add-to-dictionary").doCommand();
- }
- }
- );
- */
-});
-
-add_task(function* test_plaintext2() {
- yield test_contextmenu("#test-text", plainTextItems);
-});
-
-add_task(function* test_undo_add_to_dictionary() {
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-textarea",
- ["spell-undo-add-to-dictionary", true,
- "---", null,
- "context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true,
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null
- ],
- {
- waitForSpellCheck: true,
- postCheckContextMenuFn() {
- document.getElementById("spell-undo-add-to-dictionary")
- .doCommand();
- }
- }
- );
- */
-});
-
-add_task(function* test_contenteditable() {
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-contenteditable",
- ["spell-no-suggestions", false,
- "spell-add-to-dictionary", true,
- "---", null,
- "context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true,
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null
- ],
- {waitForSpellCheck: true}
- );
- */
-});
-
-add_task(function* test_copylinkcommand() {
- yield test_contextmenu("#test-link", null, {
- postCheckContextMenuFn: function*() {
- document.commandDispatcher
- .getControllerForCommand("cmd_copyLink")
- .doCommand("cmd_copyLink");
-
- // The easiest way to check the clipboard is to paste the contents
- // into a textbox.
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let input = doc.getElementById("test-input");
- input.focus();
- input.value = "";
- });
- document.commandDispatcher
- .getControllerForCommand("cmd_paste")
- .doCommand("cmd_paste");
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let input = doc.getElementById("test-input");
- Assert.equal(input.value, "http://mozilla.com/", "paste for command cmd_paste");
- });
- }
- });
-});
-
-add_task(function* test_pagemenu() {
- yield test_contextmenu("#test-pagemenu",
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "+Plain item", {type: "", icon: "", checked: false, disabled: false},
- "+Disabled item", {type: "", icon: "", checked: false, disabled: true},
- "+Item w/ textContent", {type: "", icon: "", checked: false, disabled: false},
- "---", null,
- "+Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false},
- "---", null,
- "+Radio1", {type: "checkbox", icon: "", checked: true, disabled: false},
- "+Radio2", {type: "checkbox", icon: "", checked: false, disabled: false},
- "+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
- "---", null,
- "+Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false},
- "+Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false},
- "---", null,
- "generated-submenu-1", true,
- ["+Radio1", {type: "checkbox", icon: "", checked: false, disabled: false},
- "+Radio2", {type: "checkbox", icon: "", checked: true, disabled: false},
- "+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
- "---", null,
- "+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ],
- {postCheckContextMenuFn: function*() {
- let item = contextMenu.getElementsByAttribute("generateditemid", "1")[0];
- ok(item, "Got generated XUL menu item");
- item.doCommand();
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let pagemenu = content.document.getElementById("test-pagemenu");
- Assert.ok(!pagemenu.hasAttribute("hopeless"), "attribute got removed");
- });
- }
- });
-});
-
-add_task(function* test_dom_full_screen() {
- yield test_contextmenu("#test-dom-full-screen",
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-leave-dom-fullscreen", true,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ],
- {
- shiftkey: true,
- *preCheckContextMenuFn() {
- yield pushPrefs(["full-screen-api.allow-trusted-requests-only", false],
- ["full-screen-api.transition-duration.enter", "0 0"],
- ["full-screen-api.transition-duration.leave", "0 0"])
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let win = doc.defaultView;
- let full_screen_element = doc.getElementById("test-dom-full-screen");
- let awaitFullScreenChange =
- ContentTaskUtils.waitForEvent(win, "fullscreenchange");
- full_screen_element.requestFullscreen();
- yield awaitFullScreenChange;
- });
- },
- *postCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let win = content.document.defaultView;
- let awaitFullScreenChange =
- ContentTaskUtils.waitForEvent(win, "fullscreenchange");
- content.document.exitFullscreen();
- yield awaitFullScreenChange;
- });
- }
- }
- );
-});
-
-add_task(function* test_pagemenu2() {
- yield test_contextmenu("#test-text",
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ],
- {shiftkey: true}
- );
-});
-
-add_task(function* test_select_text() {
- yield test_contextmenu("#test-select-text",
- ["context-copy", true,
- "context-selectall", true,
- "---", null,
- "context-searchselect", true,
- "context-viewpartialsource-selection", true
- ],
- {
- offsetX: 6,
- offsetY: 6,
- *preCheckContextMenuFn() {
- yield selectText("#test-select-text");
- }
- }
- );
-});
-
-add_task(function* test_select_text_link() {
- yield test_contextmenu("#test-select-text-link",
- ["context-openlinkincurrent", true,
- "context-openlinkintab", true,
- ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
- // We need a blank entry here because the containers submenu is
- // dynamically generated with no ids.
- ...(hasContainers ? ["", null] : []),
- "context-openlink", true,
- "context-openlinkprivate", true,
- "---", null,
- "context-bookmarklink", true,
- "context-savelink", true,
- "context-copy", true,
- "context-selectall", true,
- "---", null,
- "context-searchselect", true,
- "context-viewpartialsource-selection", true
- ],
- {
- offsetX: 6,
- offsetY: 6,
- *preCheckContextMenuFn() {
- yield selectText("#test-select-text-link");
- },
- *postCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let win = content.document.defaultView;
- win.getSelection().removeAllRanges();
- });
- }
- }
- );
-});
-
-add_task(function* test_imagelink() {
- yield test_contextmenu("#test-image-link",
- ["context-openlinkintab", true,
- ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
- // We need a blank entry here because the containers submenu is
- // dynamically generated with no ids.
- ...(hasContainers ? ["", null] : []),
- "context-openlink", true,
- "context-openlinkprivate", true,
- "---", null,
- "context-bookmarklink", true,
- "context-savelink", true,
- ...(hasPocket ? ["context-savelinktopocket", true] : []),
- "context-copylink", true,
- "---", null,
- "context-viewimage", true,
- "context-copyimage-contents", true,
- "context-copyimage", true,
- "---", null,
- "context-saveimage", true,
- "context-sendimage", true,
- "context-setDesktopBackground", true,
- "context-viewimageinfo", true
- ]
- );
-});
-
-add_task(function* test_select_input_text() {
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-select-input-text",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", true,
- "---", null,
- "context-selectall", true,
- "context-searchselect", true,
- "---", null,
- "spell-check-enabled", true
- ].concat(LOGIN_FILL_ITEMS),
- {
- *preCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let win = doc.defaultView;
- win.getSelection().removeAllRanges();
- let element = doc.querySelector("#test-select-input-text");
- element.select();
- });
- }
- }
- );
- */
-});
-
-add_task(function* test_select_input_text_password() {
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-select-input-text-type-password",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", true,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true,
- // spell checker is shown on input[type="password"] on this testcase
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null
- ].concat(LOGIN_FILL_ITEMS),
- {
- *preCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let win = doc.defaultView;
- win.getSelection().removeAllRanges();
- let element = doc.querySelector("#test-select-input-text-type-password");
- element.select();
- });
- },
- *postCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let win = content.document.defaultView;
- win.getSelection().removeAllRanges();
- });
- }
- }
- );
- */
-});
-
-add_task(function* test_click_to_play_blocked_plugin() {
- yield test_contextmenu("#test-plugin",
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-ctp-play", true,
- "context-ctp-hide", true,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ],
- {
- preCheckContextMenuFn: function*() {
- pushPrefs(["plugins.click_to_play", true]);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
- },
- postCheckContextMenuFn: function*() {
- getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
- }
- }
- );
-});
-
-add_task(function* test_longdesc() {
- yield test_contextmenu("#test-longdesc",
- ["context-viewimage", true,
- "context-copyimage-contents", true,
- "context-copyimage", true,
- "---", null,
- "context-saveimage", true,
- "context-sendimage", true,
- "context-setDesktopBackground", true,
- "context-viewimageinfo", true,
- "context-viewimagedesc", true
- ]
- );
-});
-
-add_task(function* test_srcdoc() {
- yield test_contextmenu("#test-srcdoc",
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "frame", null,
- ["context-reloadframe", true,
- "---", null,
- "context-saveframe", true,
- "---", null,
- "context-printframe", true,
- "---", null,
- "context-viewframesource", true,
- "context-viewframeinfo", true], null,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ]
- );
-});
-
-add_task(function* test_input_spell_false() {
- todo(false, "spell checker tests are failing, bug 1246296");
- return;
-
- /*
- yield test_contextmenu("#test-contenteditable-spellcheck-false",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- ]
- );
- */
-});
-
-const remoteClientsFixture = [ { id: 1, name: "Foo"}, { id: 2, name: "Bar"} ];
-
-add_task(function* test_plaintext_sendpagetodevice() {
- if (!gFxAccounts.sendTabToDeviceEnabled) {
- return;
- }
- const oldGetter = setupRemoteClientsFixture(remoteClientsFixture);
-
- let plainTextItemsWithSendPage =
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-sendpagetodevice", true,
- ["*Foo", true,
- "*Bar", true,
- "---", null,
- "*All Devices", true], null,
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", true,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true
- ];
- yield test_contextmenu("#test-text", plainTextItemsWithSendPage, {
- *onContextMenuShown() {
- yield openMenuItemSubmenu("context-sendpagetodevice");
- }
- });
-
- restoreRemoteClients(oldGetter);
-});
-
-add_task(function* test_link_sendlinktodevice() {
- if (!gFxAccounts.sendTabToDeviceEnabled) {
- return;
- }
- const oldGetter = setupRemoteClientsFixture(remoteClientsFixture);
-
- yield test_contextmenu("#test-link",
- ["context-openlinkintab", true,
- ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
- // We need a blank entry here because the containers submenu is
- // dynamically generated with no ids.
- ...(hasContainers ? ["", null] : []),
- "context-openlink", true,
- "context-openlinkprivate", true,
- "---", null,
- "context-bookmarklink", true,
- "context-savelink", true,
- ...(hasPocket ? ["context-savelinktopocket", true] : []),
- "context-copylink", true,
- "context-searchselect", true,
- "---", null,
- "context-sendlinktodevice", true,
- ["*Foo", true,
- "*Bar", true,
- "---", null,
- "*All Devices", true], null,
- ],
- {
- *onContextMenuShown() {
- yield openMenuItemSubmenu("context-sendlinktodevice");
- }
- });
-
- restoreRemoteClients(oldGetter);
-});
-
-add_task(function* test_cleanup_html() {
- gBrowser.removeCurrentTab();
-});
-
-/**
- * Selects the text of the element that matches the provided `selector`
- *
- * @param {String} selector
- * A selector passed to querySelector to find
- * the element that will be referenced.
- */
-function* selectText(selector) {
- yield ContentTask.spawn(gBrowser.selectedBrowser, selector, function*(contentSelector) {
- info(`Selecting text of ${contentSelector}`);
- let doc = content.document;
- let win = doc.defaultView;
- win.getSelection().removeAllRanges();
- let div = doc.createRange();
- let element = doc.querySelector(contentSelector);
- Assert.ok(element, "Found element to select text from");
- div.setStartBefore(element);
- div.setEndAfter(element);
- win.getSelection().addRange(div);
- });
-}
diff --git a/browser/base/content/test/general/browser_contextmenu_childprocess.js b/browser/base/content/test/general/browser_contextmenu_childprocess.js
deleted file mode 100644
index 3d52be9ab..000000000
--- a/browser/base/content/test/general/browser_contextmenu_childprocess.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const gBaseURL = "https://example.com/browser/browser/base/content/test/general/";
-
-add_task(function *() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gBaseURL + "subtst_contextmenu.html");
-
- let contextMenu = document.getElementById("contentAreaContextMenu");
-
- // Get the point of the element with the page menu (test-pagemenu) and
- // synthesize a right mouse click there.
- let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouse("#test-pagemenu", 5, 5, { type : "contextmenu", button : 2 }, tab.linkedBrowser);
- yield popupShownPromise;
-
- checkMenu(contextMenu);
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- contextMenu.hidePopup();
- yield popupHiddenPromise;
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-function checkItems(menuitem, arr)
-{
- for (let i = 0; i < arr.length; i += 2) {
- let str = arr[i];
- let details = arr[i + 1];
- if (str == "---") {
- is(menuitem.localName, "menuseparator", "menuseparator");
- }
- else if ("children" in details) {
- is(menuitem.localName, "menu", "submenu");
- is(menuitem.getAttribute("label"), str, str + " label");
- checkItems(menuitem.firstChild.firstChild, details.children);
- }
- else {
- is(menuitem.localName, "menuitem", str + " menuitem");
-
- is(menuitem.getAttribute("label"), str, str + " label");
- is(menuitem.getAttribute("type"), details.type, str + " type");
- is(menuitem.getAttribute("image"), details.icon ? gBaseURL + details.icon : "", str + " icon");
-
- if (details.checked)
- is(menuitem.getAttribute("checked"), "true", str + " checked");
- else
- ok(!menuitem.hasAttribute("checked"), str + " checked");
-
- if (details.disabled)
- is(menuitem.getAttribute("disabled"), "true", str + " disabled");
- else
- ok(!menuitem.hasAttribute("disabled"), str + " disabled");
- }
-
- menuitem = menuitem.nextSibling;
- }
-}
-
-function checkMenu(contextMenu)
-{
- let items = [ "Plain item", {type: "", icon: "", checked: false, disabled: false},
- "Disabled item", {type: "", icon: "", checked: false, disabled: true},
- "Item w/ textContent", {type: "", icon: "", checked: false, disabled: false},
- "---", null,
- "Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false},
- "---", null,
- "Radio1", {type: "checkbox", icon: "", checked: true, disabled: false},
- "Radio2", {type: "checkbox", icon: "", checked: false, disabled: false},
- "Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
- "---", null,
- "Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false},
- "Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false},
- "---", null,
- "Submenu", { children:
- ["Radio1", {type: "checkbox", icon: "", checked: false, disabled: false},
- "Radio2", {type: "checkbox", icon: "", checked: true, disabled: false},
- "Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
- "---", null,
- "Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}] }
- ];
- checkItems(contextMenu.childNodes[2], items);
-}
diff --git a/browser/base/content/test/general/browser_contextmenu_input.js b/browser/base/content/test/general/browser_contextmenu_input.js
deleted file mode 100644
index cfc7b7529..000000000
--- a/browser/base/content/test/general/browser_contextmenu_input.js
+++ /dev/null
@@ -1,243 +0,0 @@
-"use strict";
-
-let contextMenu;
-let hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
-
-add_task(function* test_setup() {
- const example_base = "http://example.com/browser/browser/base/content/test/general/";
- const url = example_base + "subtst_contextmenu_input.html";
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-
- const chrome_base = "chrome://mochitests/content/browser/browser/base/content/test/general/";
- const contextmenu_common = chrome_base + "contextmenu_common.js";
- Services.scriptloader.loadSubScript(contextmenu_common, this);
-});
-
-add_task(function* test_text_input() {
- yield test_contextmenu("#input_text",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", false,
- "---", null,
- "spell-check-enabled", true]);
-});
-
-add_task(function* test_text_input_spellcheck() {
- yield test_contextmenu("#input_spellcheck_no_value",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", false,
- "---", null,
- "spell-check-enabled", true,
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null],
- {
- waitForSpellCheck: true,
- // Need to dynamically add/remove the "password" type or LoginManager
- // will think that the form inputs on the page are part of a login
- // and will add fill-login context menu items.
- *preCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let input = doc.getElementById("input_spellcheck_no_value");
- input.setAttribute("spellcheck", "true");
- input.clientTop; // force layout flush
- });
- },
- }
- );
-});
-
-add_task(function* test_text_input_spellcheckwrong() {
- yield test_contextmenu("#input_spellcheck_incorrect",
- ["*prodigality", true, // spelling suggestion
- "spell-add-to-dictionary", true,
- "---", null,
- "context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true,
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null],
- {waitForSpellCheck: true}
- );
-});
-
-add_task(function* test_text_input_spellcheckcorrect() {
- yield test_contextmenu("#input_spellcheck_correct",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true,
- "spell-dictionaries", true,
- ["spell-check-dictionary-en-US", true,
- "---", null,
- "spell-add-dictionaries", true], null],
- {waitForSpellCheck: true}
- );
-});
-
-add_task(function* test_text_input_disabled() {
- yield test_contextmenu("#input_disabled",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", true,
- "---", null,
- "spell-check-enabled", true],
- {skipFocusChange: true}
- );
-});
-
-add_task(function* test_password_input() {
- todo(false, "context-selectall is enabled on osx-e10s, and windows when" +
- " it should be disabled");
- yield test_contextmenu("#input_password",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", null,
- "---", null,
- "fill-login", null,
- ["fill-login-no-logins", false,
- "---", null,
- "fill-login-saved-passwords", true], null],
- {
- skipFocusChange: true,
- // Need to dynamically add/remove the "password" type or LoginManager
- // will think that the form inputs on the page are part of a login
- // and will add fill-login context menu items.
- *preCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let input = doc.getElementById("input_password");
- input.type = "password";
- input.clientTop; // force layout flush
- });
- },
- *postCheckContextMenuFn() {
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- let doc = content.document;
- let input = doc.getElementById("input_password");
- input.type = "text";
- input.clientTop; // force layout flush
- });
- },
- }
- );
-});
-
-add_task(function* test_tel_email_url_number_input() {
- todo(false, "context-selectall is enabled on osx-e10s, and windows when" +
- " it should be disabled");
- for (let selector of ["#input_email", "#input_url", "#input_tel", "#input_number"]) {
- yield test_contextmenu(selector,
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", null],
- {skipFocusChange: true}
- );
- }
-});
-
-add_task(function* test_date_time_color_range_month_week_datetimelocal_input() {
- for (let selector of ["#input_date", "#input_time", "#input_color",
- "#input_range", "#input_month", "#input_week",
- "#input_datetime-local"]) {
- yield test_contextmenu(selector,
- ["context-navigation", null,
- ["context-back", false,
- "context-forward", false,
- "context-reload", true,
- "context-bookmarkpage", true], null,
- "---", null,
- "context-savepage", true,
- ...(hasPocket ? ["context-pocket", true] : []),
- "---", null,
- "context-viewbgimage", false,
- "context-selectall", null,
- "---", null,
- "context-viewsource", true,
- "context-viewinfo", true],
- {skipFocusChange: true}
- );
- }
-});
-
-add_task(function* test_search_input() {
- todo(false, "context-selectall is enabled on osx-e10s, and windows when" +
- " it should be disabled");
- yield test_contextmenu("#input_search",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", null,
- "---", null,
- "spell-check-enabled", true],
- {skipFocusChange: true}
- );
-});
-
-add_task(function* test_text_input_readonly() {
- todo(false, "context-selectall is enabled on osx-e10s, and windows when" +
- " it should be disabled");
- todo(false, "spell-check should not be enabled for input[readonly]. see bug 1246296");
- yield test_contextmenu("#input_readonly",
- ["context-undo", false,
- "---", null,
- "context-cut", true,
- "context-copy", true,
- "context-paste", null, // ignore clipboard state
- "context-delete", false,
- "---", null,
- "context-selectall", null],
- {skipFocusChange: true}
- );
-});
-
-add_task(function* test_cleanup() {
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/general/browser_csp_block_all_mixedcontent.js b/browser/base/content/test/general/browser_csp_block_all_mixedcontent.js
deleted file mode 100644
index 00a06f53e..000000000
--- a/browser/base/content/test/general/browser_csp_block_all_mixedcontent.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Description of the Test:
- * We load an https page which uses a CSP including block-all-mixed-content.
- * The page tries to load a script over http. We make sure the UI is not
- * influenced when blocking the mixed content. In particular the page
- * should still appear fully encrypted with a green lock.
- */
-
-const PRE_PATH = "https://example.com/browser/browser/base/content/test/general/";
-var gTestBrowser = null;
-
-// ------------------------------------------------------
-function cleanUpAfterTests() {
- gBrowser.removeCurrentTab();
- window.focus();
- finish();
-}
-
-// ------------------------------------------------------
-function verifyUInotDegraded() {
- // make sure that not mixed content is loaded and also not blocked
- assertMixedContentBlockingState(
- gTestBrowser,
- { activeLoaded: false,
- activeBlocked: false,
- passiveLoaded: false
- }
- );
- // clean up and finish test
- cleanUpAfterTests();
-}
-
-// ------------------------------------------------------
-function runTests() {
- var newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
- newTab.linkedBrowser.stop();
-
- // Starting the test
- BrowserTestUtils.browserLoaded(gTestBrowser).then(verifyUInotDegraded);
- var url = PRE_PATH + "file_csp_block_all_mixedcontent.html";
- gTestBrowser.loadURI(url);
-}
-
-// ------------------------------------------------------
-function test() {
- // Performing async calls, e.g. 'onload', we have to wait till all of them finished
- waitForExplicitFinish();
-
- SpecialPowers.pushPrefEnv(
- { 'set': [["security.mixed_content.block_active_content", true]] },
- function() { runTests(); }
- );
-}
diff --git a/browser/base/content/test/general/browser_ctrlTab.js b/browser/base/content/test/general/browser_ctrlTab.js
deleted file mode 100644
index d16aaeca4..000000000
--- a/browser/base/content/test/general/browser_ctrlTab.js
+++ /dev/null
@@ -1,185 +0,0 @@
-add_task(function* () {
- gPrefService.setBoolPref("browser.ctrlTab.previews", true);
-
- gBrowser.addTab();
- gBrowser.addTab();
- gBrowser.addTab();
-
- checkTabs(4);
-
- yield ctrlTabTest([2], 1, 0);
- yield ctrlTabTest([2, 3, 1], 2, 2);
- yield ctrlTabTest([], 4, 2);
-
- {
- let selectedIndex = gBrowser.tabContainer.selectedIndex;
- yield pressCtrlTab();
- yield pressCtrlTab(true);
- yield releaseCtrl();
- is(gBrowser.tabContainer.selectedIndex, selectedIndex,
- "Ctrl+Tab -> Ctrl+Shift+Tab keeps the selected tab");
- }
-
- { // test for bug 445369
- let tabs = gBrowser.tabs.length;
- yield pressCtrlTab();
- yield synthesizeCtrlW();
- is(gBrowser.tabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes one tab");
- yield releaseCtrl();
- }
-
- { // test for bug 667314
- let tabs = gBrowser.tabs.length;
- yield pressCtrlTab();
- yield pressCtrlTab(true);
- yield synthesizeCtrlW();
- is(gBrowser.tabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes the selected tab");
- yield releaseCtrl();
- }
-
- gBrowser.addTab();
- checkTabs(3);
- yield ctrlTabTest([2, 1, 0], 7, 1);
-
- { // test for bug 1292049
- let tabToClose = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:buildconfig");
- checkTabs(4);
- selectTabs([0, 1, 2, 3]);
-
- yield BrowserTestUtils.removeTab(tabToClose);
- checkTabs(3);
- undoCloseTab();
- checkTabs(4);
- is(gBrowser.tabContainer.selectedIndex, 3, "tab is selected after closing and restoring it");
-
- yield ctrlTabTest([], 1, 2);
- }
-
- { // test for bug 445369
- checkTabs(4);
- selectTabs([1, 2, 0]);
-
- let selectedTab = gBrowser.selectedTab;
- let tabToRemove = gBrowser.tabs[1];
-
- yield pressCtrlTab();
- yield pressCtrlTab();
- yield synthesizeCtrlW();
- ok(!tabToRemove.parentNode,
- "Ctrl+Tab*2 -> Ctrl+W removes the second most recently selected tab");
-
- yield pressCtrlTab(true);
- yield pressCtrlTab(true);
- yield releaseCtrl();
- ok(selectedTab.selected,
- "Ctrl+Tab*2 -> Ctrl+W -> Ctrl+Shift+Tab*2 keeps the selected tab");
- }
- gBrowser.removeTab(gBrowser.tabContainer.lastChild);
- checkTabs(2);
-
- yield ctrlTabTest([1], 1, 0);
-
- gBrowser.removeTab(gBrowser.tabContainer.lastChild);
- checkTabs(1);
-
- { // test for bug 445768
- let focusedWindow = document.commandDispatcher.focusedWindow;
- let eventConsumed = true;
- let detectKeyEvent = function (event) {
- eventConsumed = event.defaultPrevented;
- };
- document.addEventListener("keypress", detectKeyEvent, false);
- yield pressCtrlTab();
- document.removeEventListener("keypress", detectKeyEvent, false);
- ok(eventConsumed, "Ctrl+Tab consumed by the tabbed browser if one tab is open");
- is(focusedWindow, document.commandDispatcher.focusedWindow,
- "Ctrl+Tab doesn't change focus if one tab is open");
- }
-
- // cleanup
- if (gPrefService.prefHasUserValue("browser.ctrlTab.previews"))
- gPrefService.clearUserPref("browser.ctrlTab.previews");
-
- /* private utility functions */
-
- function* pressCtrlTab(aShiftKey) {
- let promise;
- if (!isOpen() && canOpen()) {
- promise = BrowserTestUtils.waitForEvent(ctrlTab.panel, "popupshown");
- } else {
- promise = BrowserTestUtils.waitForEvent(document, "keyup");
- }
- EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: !!aShiftKey });
- return promise;
- }
-
- function* releaseCtrl() {
- let promise;
- if (isOpen()) {
- promise = BrowserTestUtils.waitForEvent(ctrlTab.panel, "popuphidden");
- } else {
- promise = BrowserTestUtils.waitForEvent(document, "keyup");
- }
- EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" });
- return promise;
- }
-
- function* synthesizeCtrlW() {
- let promise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
- EventUtils.synthesizeKey("w", { ctrlKey: true });
- return promise;
- }
-
- function isOpen() {
- return ctrlTab.isOpen;
- }
-
- function canOpen() {
- return gPrefService.getBoolPref("browser.ctrlTab.previews") && gBrowser.tabs.length > 2;
- }
-
- function checkTabs(aTabs) {
- is(gBrowser.tabs.length, aTabs, "number of open tabs should be " + aTabs);
- }
-
- function selectTabs(tabs) {
- tabs.forEach(function (index) {
- gBrowser.selectedTab = gBrowser.tabs[index];
- });
- }
-
- function* ctrlTabTest(tabsToSelect, tabTimes, expectedIndex) {
- selectTabs(tabsToSelect);
-
- var indexStart = gBrowser.tabContainer.selectedIndex;
- var tabCount = gBrowser.tabs.length;
- var normalized = tabTimes % tabCount;
- var where = normalized == 1 ? "back to the previously selected tab" :
- normalized + " tabs back in most-recently-selected order";
-
- for (let i = 0; i < tabTimes; i++) {
- yield pressCtrlTab();
-
- if (tabCount > 2)
- is(gBrowser.tabContainer.selectedIndex, indexStart,
- "Selected tab doesn't change while tabbing");
- }
-
- if (tabCount > 2) {
- ok(isOpen(),
- "With " + tabCount + " tabs open, Ctrl+Tab opens the preview panel");
-
- yield releaseCtrl();
-
- ok(!isOpen(),
- "Releasing Ctrl closes the preview panel");
- } else {
- ok(!isOpen(),
- "With " + tabCount + " tabs open, Ctrl+Tab doesn't open the preview panel");
- }
-
- is(gBrowser.tabContainer.selectedIndex, expectedIndex,
- "With "+ tabCount +" tabs open and tab " + indexStart
- + " selected, Ctrl+Tab*" + tabTimes + " goes " + where);
- }
-});
diff --git a/browser/base/content/test/general/browser_datachoices_notification.js b/browser/base/content/test/general/browser_datachoices_notification.js
deleted file mode 100644
index 360728b4c..000000000
--- a/browser/base/content/test/general/browser_datachoices_notification.js
+++ /dev/null
@@ -1,221 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Pass an empty scope object to the import to prevent "leaked window property"
-// errors in tests.
-var Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
-var TelemetryReportingPolicy =
- Cu.import("resource://gre/modules/TelemetryReportingPolicy.jsm", {}).TelemetryReportingPolicy;
-
-const PREF_BRANCH = "datareporting.policy.";
-const PREF_BYPASS_NOTIFICATION = PREF_BRANCH + "dataSubmissionPolicyBypassNotification";
-const PREF_CURRENT_POLICY_VERSION = PREF_BRANCH + "currentPolicyVersion";
-const PREF_ACCEPTED_POLICY_VERSION = PREF_BRANCH + "dataSubmissionPolicyAcceptedVersion";
-const PREF_ACCEPTED_POLICY_DATE = PREF_BRANCH + "dataSubmissionPolicyNotifiedTime";
-
-const TEST_POLICY_VERSION = 37;
-
-function fakeShowPolicyTimeout(set, clear) {
- let reportingPolicy =
- Cu.import("resource://gre/modules/TelemetryReportingPolicy.jsm", {}).Policy;
- reportingPolicy.setShowInfobarTimeout = set;
- reportingPolicy.clearShowInfobarTimeout = clear;
-}
-
-function sendSessionRestoredNotification() {
- let reportingPolicyImpl =
- Cu.import("resource://gre/modules/TelemetryReportingPolicy.jsm", {}).TelemetryReportingPolicyImpl;
- reportingPolicyImpl.observe(null, "sessionstore-windows-restored", null);
-}
-
-/**
- * Wait for a tick.
- */
-function promiseNextTick() {
- return new Promise(resolve => executeSoon(resolve));
-}
-
-/**
- * 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);
- deferred.resolve();
- });
- return deferred.promise;
-}
-
-/**
- * Wait for a notification to be closed.
- * @param {Object} aNotification The notification.
- * @return {Promise} Resolved when the notification is closed.
- */
-function promiseWaitForNotificationClose(aNotification) {
- let deferred = PromiseUtils.defer();
- waitForNotificationClose(aNotification, deferred.resolve);
- return deferred.promise;
-}
-
-function triggerInfoBar(expectedTimeoutMs) {
- let showInfobarCallback = null;
- let timeoutMs = null;
- fakeShowPolicyTimeout((callback, timeout) => {
- showInfobarCallback = callback;
- timeoutMs = timeout;
- }, () => {});
- sendSessionRestoredNotification();
- Assert.ok(!!showInfobarCallback, "Must have a timer callback.");
- if (expectedTimeoutMs !== undefined) {
- Assert.equal(timeoutMs, expectedTimeoutMs, "Timeout should match");
- }
- showInfobarCallback();
-}
-
-var checkInfobarButton = Task.async(function* (aNotification) {
- // Check that the button on the data choices infobar does the right thing.
- let buttons = aNotification.getElementsByTagName("button");
- Assert.equal(buttons.length, 1, "There is 1 button in the data reporting notification.");
- let button = buttons[0];
-
- // Add an observer to ensure the "advanced" pane opened (but don't bother
- // closing it - we close the entire window when done.)
- let paneLoadedPromise = promiseTopicObserved("advanced-pane-loaded");
-
- // Click on the button.
- button.click();
-
- // Wait for the preferences panel to open.
- yield paneLoadedPromise;
- yield promiseNextTick();
-});
-
-add_task(function* setup() {
- const bypassNotification = Preferences.get(PREF_BYPASS_NOTIFICATION, true);
- const currentPolicyVersion = Preferences.get(PREF_CURRENT_POLICY_VERSION, 1);
-
- // Register a cleanup function to reset our preferences.
- registerCleanupFunction(() => {
- Preferences.set(PREF_BYPASS_NOTIFICATION, bypassNotification);
- Preferences.set(PREF_CURRENT_POLICY_VERSION, currentPolicyVersion);
-
- return closeAllNotifications();
- });
-
- // Don't skip the infobar visualisation.
- Preferences.set(PREF_BYPASS_NOTIFICATION, false);
- // Set the current policy version.
- Preferences.set(PREF_CURRENT_POLICY_VERSION, TEST_POLICY_VERSION);
-});
-
-function clearAcceptedPolicy() {
- // Reset the accepted policy.
- Preferences.reset(PREF_ACCEPTED_POLICY_VERSION);
- Preferences.reset(PREF_ACCEPTED_POLICY_DATE);
-}
-
-add_task(function* test_single_window() {
- clearAcceptedPolicy();
-
- // Close all the notifications, then try to trigger the data choices infobar.
- yield closeAllNotifications();
-
- let notificationBox = document.getElementById("global-notificationbox");
-
- // Make sure that we have a coherent initial state.
- Assert.equal(Preferences.get(PREF_ACCEPTED_POLICY_VERSION, 0), 0,
- "No version should be set on init.");
- Assert.equal(Preferences.get(PREF_ACCEPTED_POLICY_DATE, 0), 0,
- "No date should be set on init.");
- Assert.ok(!TelemetryReportingPolicy.testIsUserNotified(),
- "User not notified about datareporting policy.");
-
- let alertShownPromise = promiseWaitForAlertActive(notificationBox);
- Assert.ok(!TelemetryReportingPolicy.canUpload(),
- "User should not be allowed to upload.");
-
- // Wait for the infobar to be displayed.
- triggerInfoBar(10 * 1000);
- yield alertShownPromise;
-
- Assert.equal(notificationBox.allNotifications.length, 1, "Notification Displayed.");
- Assert.ok(TelemetryReportingPolicy.canUpload(), "User should be allowed to upload now.");
-
- yield promiseNextTick();
- let promiseClosed = promiseWaitForNotificationClose(notificationBox.currentNotification);
- yield checkInfobarButton(notificationBox.currentNotification);
- yield promiseClosed;
-
- Assert.equal(notificationBox.allNotifications.length, 0, "No notifications remain.");
-
- // Check that we are still clear to upload and that the policy data is saved.
- Assert.ok(TelemetryReportingPolicy.canUpload());
- Assert.equal(TelemetryReportingPolicy.testIsUserNotified(), true,
- "User notified about datareporting policy.");
- Assert.equal(Preferences.get(PREF_ACCEPTED_POLICY_VERSION, 0), TEST_POLICY_VERSION,
- "Version pref set.");
- Assert.greater(parseInt(Preferences.get(PREF_ACCEPTED_POLICY_DATE, null), 10), -1,
- "Date pref set.");
-});
-
-add_task(function* test_multiple_windows() {
- clearAcceptedPolicy();
-
- // Close all the notifications, then try to trigger the data choices infobar.
- yield closeAllNotifications();
-
- // Ensure we see the notification on all windows and that action on one window
- // results in dismiss on every window.
- let otherWindow = yield BrowserTestUtils.openNewBrowserWindow();
-
- // Get the notification box for both windows.
- let notificationBoxes = [
- document.getElementById("global-notificationbox"),
- otherWindow.document.getElementById("global-notificationbox")
- ];
-
- Assert.ok(notificationBoxes[1], "2nd window has a global notification box.");
-
- // Make sure that we have a coherent initial state.
- Assert.equal(Preferences.get(PREF_ACCEPTED_POLICY_VERSION, 0), 0, "No version should be set on init.");
- Assert.equal(Preferences.get(PREF_ACCEPTED_POLICY_DATE, 0), 0, "No date should be set on init.");
- Assert.ok(!TelemetryReportingPolicy.testIsUserNotified(), "User not notified about datareporting policy.");
-
- let showAlertPromises = [
- promiseWaitForAlertActive(notificationBoxes[0]),
- promiseWaitForAlertActive(notificationBoxes[1])
- ];
-
- Assert.ok(!TelemetryReportingPolicy.canUpload(),
- "User should not be allowed to upload.");
-
- // Wait for the infobars.
- triggerInfoBar(10 * 1000);
- yield Promise.all(showAlertPromises);
-
- // Both notification were displayed. Close one and check that both gets closed.
- let closeAlertPromises = [
- promiseWaitForNotificationClose(notificationBoxes[0].currentNotification),
- promiseWaitForNotificationClose(notificationBoxes[1].currentNotification)
- ];
- notificationBoxes[0].currentNotification.close();
- yield Promise.all(closeAlertPromises);
-
- // Close the second window we opened.
- yield BrowserTestUtils.closeWindow(otherWindow);
-
- // Check that we are clear to upload and that the policy data us saved.
- Assert.ok(TelemetryReportingPolicy.canUpload(), "User should be allowed to upload now.");
- Assert.equal(TelemetryReportingPolicy.testIsUserNotified(), true,
- "User notified about datareporting policy.");
- Assert.equal(Preferences.get(PREF_ACCEPTED_POLICY_VERSION, 0), TEST_POLICY_VERSION,
- "Version pref set.");
- Assert.greater(parseInt(Preferences.get(PREF_ACCEPTED_POLICY_DATE, null), 10), -1,
- "Date pref set.");
-});
diff --git a/browser/base/content/test/general/browser_decoderDoctor.js b/browser/base/content/test/general/browser_decoderDoctor.js
deleted file mode 100644
index a37972160..000000000
--- a/browser/base/content/test/general/browser_decoderDoctor.js
+++ /dev/null
@@ -1,122 +0,0 @@
-"use strict";
-
-function* test_decoder_doctor_notification(type, notificationMessage, options) {
- yield BrowserTestUtils.withNewTab({ gBrowser }, function*(browser) {
- let awaitNotificationBar =
- BrowserTestUtils.waitForNotificationBar(gBrowser, browser, "decoder-doctor-notification");
-
- yield ContentTask.spawn(browser, type, function*(aType) {
- Services.obs.notifyObservers(content.window,
- "decoder-doctor-notification",
- JSON.stringify({type: aType,
- isSolved: false,
- decoderDoctorReportId: "test",
- formats: "test"}));
- });
-
- let notification;
- try {
- notification = yield awaitNotificationBar;
- } catch (ex) {
- ok(false, ex);
- return;
- }
- ok(notification, "Got decoder-doctor-notification notification");
-
- is(notification.getAttribute("label"), notificationMessage,
- "notification message should match expectation");
- let button = notification.childNodes[0];
- if (options && options.noLearnMoreButton) {
- ok(!button, "There should not be a Learn More button");
- return;
- }
-
- is(button.getAttribute("label"), gNavigatorBundle.getString("decoder.noCodecs.button"),
- "notification button should be 'Learn more'");
- is(button.getAttribute("accesskey"), gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
- "notification button should have accesskey");
-
- let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
- let url = baseURL + ((options && options.sumo) ||
- "fix-video-audio-problems-firefox-windows");
- let awaitNewTab = BrowserTestUtils.waitForNewTab(gBrowser, url);
- button.click();
- let sumoTab = yield awaitNewTab;
- yield BrowserTestUtils.removeTab(sumoTab);
- });
-}
-
-add_task(function* test_adobe_cdm_not_found() {
- // This is only sent on Windows.
- if (AppConstants.platform != "win") {
- return;
- }
-
- let message;
- if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
- message = gNavigatorBundle.getFormattedString("emeNotifications.drmContentDisabled.message", [""]);
- } else {
- message = gNavigatorBundle.getString("decoder.noCodecs.message");
- }
-
- yield test_decoder_doctor_notification("adobe-cdm-not-found", message);
-});
-
-add_task(function* test_adobe_cdm_not_activated() {
- // This is only sent on Windows.
- if (AppConstants.platform != "win") {
- return;
- }
-
- let message;
- if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
- message = gNavigatorBundle.getString("decoder.noCodecsXP.message");
- } else {
- message = gNavigatorBundle.getString("decoder.noCodecs.message");
- }
-
- yield test_decoder_doctor_notification("adobe-cdm-not-activated", message);
-});
-
-add_task(function* test_platform_decoder_not_found() {
- // Not sent on Windows XP.
- if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
- return;
- }
-
- let message;
- let isLinux = AppConstants.platform == "linux";
- if (isLinux) {
- message = gNavigatorBundle.getString("decoder.noCodecsLinux.message");
- } else {
- message = gNavigatorBundle.getString("decoder.noHWAcceleration.message");
- }
-
- yield test_decoder_doctor_notification("platform-decoder-not-found",
- message,
- {noLearnMoreButton: isLinux});
-});
-
-add_task(function* test_cannot_initialize_pulseaudio() {
- // This is only sent on Linux.
- if (AppConstants.platform != "linux") {
- return;
- }
-
- let message = gNavigatorBundle.getString("decoder.noPulseAudio.message");
- yield test_decoder_doctor_notification("cannot-initialize-pulseaudio",
- message,
- {sumo: "fix-common-audio-and-video-issues"});
-});
-
-add_task(function* test_unsupported_libavcodec() {
- // This is only sent on Linux.
- if (AppConstants.platform != "linux") {
- return;
- }
-
- let message = gNavigatorBundle.getString("decoder.unsupportedLibavcodec.message");
- yield test_decoder_doctor_notification("unsupported-libavcodec",
- message,
- {noLearnMoreButton: true});
-});
diff --git a/browser/base/content/test/general/browser_devedition.js b/browser/base/content/test/general/browser_devedition.js
deleted file mode 100644
index 06ee42e7e..000000000
--- a/browser/base/content/test/general/browser_devedition.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Testing changes for Developer Edition theme.
- * A special stylesheet should be added to the browser.xul document
- * when the firefox-devedition@mozilla.org lightweight theme
- * is applied.
- */
-
-const PREF_LWTHEME_USED_THEMES = "lightweightThemes.usedThemes";
-const PREF_DEVTOOLS_THEME = "devtools.theme";
-const {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
-
-LightweightThemeManager.clearBuiltInThemes();
-LightweightThemeManager.addBuiltInTheme(dummyLightweightTheme("firefox-devedition@mozilla.org"));
-
-registerCleanupFunction(() => {
- // Set preferences back to their original values
- LightweightThemeManager.currentTheme = null;
- Services.prefs.clearUserPref(PREF_DEVTOOLS_THEME);
- Services.prefs.clearUserPref(PREF_LWTHEME_USED_THEMES);
-
- LightweightThemeManager.currentTheme = null;
- LightweightThemeManager.clearBuiltInThemes();
-});
-
-add_task(function* startTests() {
- Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
-
- info ("Setting the current theme to null");
- LightweightThemeManager.currentTheme = null;
- ok (!DevEdition.isStyleSheetEnabled, "There is no devedition style sheet when no lw theme is applied.");
-
- info ("Adding a lightweight theme.");
- LightweightThemeManager.currentTheme = dummyLightweightTheme("preview0");
- ok (!DevEdition.isStyleSheetEnabled, "The devedition stylesheet has been removed when a lightweight theme is applied.");
-
- info ("Applying the devedition lightweight theme.");
- let onAttributeAdded = waitForBrightTitlebarAttribute();
- LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org");
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet has been added when the devedition lightweight theme is applied");
- yield onAttributeAdded;
- is (document.documentElement.getAttribute("brighttitlebarforeground"), "true",
- "The brighttitlebarforeground attribute is set on the window.");
-
- info ("Unapplying all themes.");
- LightweightThemeManager.currentTheme = null;
- ok (!DevEdition.isStyleSheetEnabled, "There is no devedition style sheet when no lw theme is applied.");
-
- info ("Applying the devedition lightweight theme.");
- onAttributeAdded = waitForBrightTitlebarAttribute();
- LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org");
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet has been added when the devedition lightweight theme is applied");
- yield onAttributeAdded;
- ok (document.documentElement.hasAttribute("brighttitlebarforeground"),
- "The brighttitlebarforeground attribute is set on the window with dark devtools theme.");
-});
-
-add_task(function* testDevtoolsTheme() {
- info ("Checking stylesheet and :root attributes based on devtools theme.");
- Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
- is (document.documentElement.getAttribute("devtoolstheme"), "light",
- "The documentElement has an attribute based on devtools theme.");
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet is still there with the light devtools theme.");
- ok (!document.documentElement.hasAttribute("brighttitlebarforeground"),
- "The brighttitlebarforeground attribute is not set on the window with light devtools theme.");
-
- Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
- is (document.documentElement.getAttribute("devtoolstheme"), "dark",
- "The documentElement has an attribute based on devtools theme.");
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet is still there with the dark devtools theme.");
- is (document.documentElement.getAttribute("brighttitlebarforeground"), "true",
- "The brighttitlebarforeground attribute is set on the window with dark devtools theme.");
-
- Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "foobar");
- is (document.documentElement.getAttribute("devtoolstheme"), "light",
- "The documentElement has 'light' as a default for the devtoolstheme attribute");
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet is still there with the foobar devtools theme.");
- ok (!document.documentElement.hasAttribute("brighttitlebarforeground"),
- "The brighttitlebarforeground attribute is not set on the window with light devtools theme.");
-});
-
-function dummyLightweightTheme(id) {
- return {
- id: id,
- name: id,
- headerURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.header.png",
- iconURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.icon.png",
- textcolor: "red",
- accentcolor: "blue"
- };
-}
-
-add_task(function* testLightweightThemePreview() {
- info ("Setting devedition to current and the previewing others");
- LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org");
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet is enabled.");
- LightweightThemeManager.previewTheme(dummyLightweightTheme("preview0"));
- ok (!DevEdition.isStyleSheetEnabled, "The devedition stylesheet is not enabled after a lightweight theme preview.");
- LightweightThemeManager.resetPreview();
- LightweightThemeManager.previewTheme(dummyLightweightTheme("preview1"));
- ok (!DevEdition.isStyleSheetEnabled, "The devedition stylesheet is not enabled after a second lightweight theme preview.");
- LightweightThemeManager.resetPreview();
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet is enabled again after resetting the preview.");
- LightweightThemeManager.currentTheme = null;
- ok (!DevEdition.isStyleSheetEnabled, "The devedition stylesheet is gone after removing the current theme.");
-
- info ("Previewing the devedition theme");
- LightweightThemeManager.previewTheme(LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org"));
- ok (DevEdition.isStyleSheetEnabled, "The devedition stylesheet is enabled.");
- LightweightThemeManager.previewTheme(dummyLightweightTheme("preview2"));
- LightweightThemeManager.resetPreview();
- ok (!DevEdition.isStyleSheetEnabled, "The devedition stylesheet is now disabled after resetting the preview.");
-});
-
-// Use a mutation observer to wait for the brighttitlebarforeground
-// attribute to change. Using this instead of waiting for the load
-// event on the DevEdition styleSheet.
-function waitForBrightTitlebarAttribute() {
- return new Promise((resolve, reject) => {
- let mutationObserver = new MutationObserver(function (mutations) {
- for (let mutation of mutations) {
- if (mutation.attributeName == "brighttitlebarforeground") {
- mutationObserver.disconnect();
- resolve();
- }
- }
- });
- mutationObserver.observe(document.documentElement, { attributes: true });
- });
-}
diff --git a/browser/base/content/test/general/browser_discovery.js b/browser/base/content/test/general/browser_discovery.js
deleted file mode 100644
index 23d44c6a9..000000000
--- a/browser/base/content/test/general/browser_discovery.js
+++ /dev/null
@@ -1,162 +0,0 @@
-var browser;
-
-function doc() {
- return browser.contentDocument;
-}
-
-function setHandlerFunc(aResultFunc) {
- gBrowser.addEventListener("DOMLinkAdded", function (event) {
- gBrowser.removeEventListener("DOMLinkAdded", arguments.callee, false);
- executeSoon(aResultFunc);
- }, false);
-}
-
-function test() {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab();
- browser = gBrowser.selectedBrowser;
- browser.addEventListener("load", function (event) {
- event.currentTarget.removeEventListener("load", arguments.callee, true);
- iconDiscovery();
- }, 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" },
- { rel: "shortcut-icon", pass: false, text: "rel shortcut-icon not discovered" },
- { href: "moz.png", text: "relative href works" },
- { href: "notthere.png", text: "404'd icon is removed properly" },
- { href: "data:image/x-icon,%00", type: "image/x-icon", text: "data: URIs work" },
- { type: "image/png; charset=utf-8", text: "type may have optional parameters (RFC2046)" }
-];
-
-function runIconDiscoveryTest() {
- var testCase = iconDiscoveryTests[0];
- var head = doc().getElementById("linkparent");
- var hasSrc = gBrowser.getIcon() != null;
- if (testCase.pass)
- ok(hasSrc, testCase.text);
- else
- ok(!hasSrc, testCase.text);
-
- head.removeChild(head.getElementsByTagName('link')[0]);
- iconDiscoveryTests.shift();
- iconDiscovery(); // Run the next test.
-}
-
-function iconDiscovery() {
- if (iconDiscoveryTests.length) {
- setHandlerFunc(runIconDiscoveryTest);
- gBrowser.setIcon(gBrowser.selectedTab, null,
- Services.scriptSecurityManager.getSystemPrincipal());
-
- var testCase = iconDiscoveryTests[0];
- var head = doc().getElementById("linkparent");
- var link = doc().createElement("link");
-
- var rootDir = getRootDirectory(gTestPath);
- var rel = testCase.rel || "icon";
- var href = testCase.href || rootDir + "moz.png";
- var type = testCase.type || "image/png";
- if (testCase.pass == undefined)
- testCase.pass = true;
-
- link.rel = rel;
- link.href = href;
- link.type = type;
- head.appendChild(link);
- } else {
- searchDiscovery();
- }
-}
-
-var searchDiscoveryTests = [
- { text: "rel search discovered" },
- { rel: "SEARCH", text: "rel is case insensitive" },
- { rel: "-search-", pass: false, text: "rel -search- not discovered" },
- { rel: "foo bar baz search quux", text: "rel may contain additional rels separated by spaces" },
- { href: "https://not.mozilla.com", text: "HTTPS ok" },
- { href: "ftp://not.mozilla.com", text: "FTP ok" },
- { href: "data:text/foo,foo", pass: false, text: "data URI not permitted" },
- { href: "javascript:alert(0)", pass: false, text: "JS URI not permitted" },
- { type: "APPLICATION/OPENSEARCHDESCRIPTION+XML", text: "type is case insensitve" },
- { type: " application/opensearchdescription+xml ", text: "type may contain extra whitespace" },
- { type: "application/opensearchdescription+xml; charset=utf-8", text: "type may have optional parameters (RFC2046)" },
- { type: "aapplication/opensearchdescription+xml", pass: false, text: "type should not be loosely matched" },
- { rel: "search search search", count: 1, text: "only one engine should be added" }
-];
-
-function runSearchDiscoveryTest() {
- var testCase = searchDiscoveryTests[0];
- var title = testCase.title || searchDiscoveryTests.length;
- if (browser.engines) {
- var hasEngine = (testCase.count) ? (browser.engines[0].title == title &&
- browser.engines.length == testCase.count) :
- (browser.engines[0].title == title);
- ok(hasEngine, testCase.text);
- browser.engines = null;
- }
- else
- ok(!testCase.pass, testCase.text);
-
- searchDiscoveryTests.shift();
- searchDiscovery(); // Run the next test.
-}
-
-// This handler is called twice, once for each added link element.
-// Only want to check once the second link element has been added.
-var ranOnce = false;
-function runMultipleEnginesTestAndFinalize() {
- if (!ranOnce) {
- ranOnce = true;
- return;
- }
- ok(browser.engines, "has engines");
- is(browser.engines.length, 1, "only one engine");
- is(browser.engines[0].uri, "http://first.mozilla.com/search.xml", "first engine wins");
-
- gBrowser.removeCurrentTab();
- finish();
-}
-
-function searchDiscovery() {
- let head = doc().getElementById("linkparent");
-
- if (searchDiscoveryTests.length) {
- setHandlerFunc(runSearchDiscoveryTest);
- let testCase = searchDiscoveryTests[0];
- let link = doc().createElement("link");
-
- let rel = testCase.rel || "search";
- let href = testCase.href || "http://so.not.here.mozilla.com/search.xml";
- let type = testCase.type || "application/opensearchdescription+xml";
- let title = testCase.title || searchDiscoveryTests.length;
- if (testCase.pass == undefined)
- testCase.pass = true;
-
- link.rel = rel;
- link.href = href;
- link.type = type;
- link.title = title;
- head.appendChild(link);
- } else {
- setHandlerFunc(runMultipleEnginesTestAndFinalize);
- setHandlerFunc(runMultipleEnginesTestAndFinalize);
- // Test multiple engines with the same title
- let link = doc().createElement("link");
- link.rel = "search";
- link.href = "http://first.mozilla.com/search.xml";
- link.type = "application/opensearchdescription+xml";
- link.title = "Test Engine";
- let link2 = link.cloneNode(false);
- link2.href = "http://second.mozilla.com/search.xml";
-
- head.appendChild(link);
- head.appendChild(link2);
- }
-}
diff --git a/browser/base/content/test/general/browser_documentnavigation.js b/browser/base/content/test/general/browser_documentnavigation.js
deleted file mode 100644
index eb789d076..000000000
--- a/browser/base/content/test/general/browser_documentnavigation.js
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * This test checks that focus is adjusted properly in a browser when pressing F6 and Shift+F6.
- * There are additional tests in dom/tests/mochitest/chrome/test_focus_docnav.xul which test
- * non-browser cases.
- */
-
-var testPage1 = "data:text/html,<html id='html1'><body id='body1'><button id='button1'>Tab 1</button></body></html>";
-var testPage2 = "data:text/html,<html id='html2'><body id='body2'><button id='button2'>Tab 2</button></body></html>";
-var testPage3 = "data:text/html,<html id='html3'><body id='body3' contenteditable='true'><button id='button3'>Tab 3</button></body></html>";
-
-var fm = Services.focus;
-
-function* expectFocusOnF6(backward, expectedDocument, expectedElement, onContent, desc)
-{
- let focusChangedInChildResolver = null;
- let focusPromise = onContent ? new Promise(resolve => focusChangedInChildResolver = resolve) :
- BrowserTestUtils.waitForEvent(window, "focus", true);
-
- function focusChangedListener(msg) {
- let expected = expectedDocument;
- if (!expectedElement.startsWith("html")) {
- expected += "," + expectedElement;
- }
-
- is(msg.data.details, expected, desc + " child focus matches");
- focusChangedInChildResolver();
- }
-
- if (onContent) {
- messageManager.addMessageListener("BrowserTest:FocusChanged", focusChangedListener);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, { expectedElementId: expectedElement }, function* (arg) {
- let contentExpectedElement = content.document.getElementById(arg.expectedElementId);
- if (!contentExpectedElement) {
- // Element not found, so look in the child frames.
- for (let f = 0; f < content.frames.length; f++) {
- if (content.frames[f].document.getElementById(arg.expectedElementId)) {
- contentExpectedElement = content.frames[f].document;
- break;
- }
- }
- }
- else if (contentExpectedElement.localName == "html") {
- contentExpectedElement = contentExpectedElement.ownerDocument;
- }
-
- if (!contentExpectedElement) {
- sendSyncMessage("BrowserTest:FocusChanged",
- { details : "expected element " + arg.expectedElementId + " not found" });
- return;
- }
-
- contentExpectedElement.addEventListener("focus", function focusReceived() {
- contentExpectedElement.removeEventListener("focus", focusReceived, true);
-
- 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 : details });
- }, true);
- });
- }
-
- EventUtils.synthesizeKey("VK_F6", { shiftKey: backward });
- yield focusPromise;
-
- if (typeof expectedElement == "string") {
- expectedElement = fm.focusedWindow.document.getElementById(expectedElement);
- }
-
- if (gMultiProcessBrowser && onContent) {
- expectedDocument = "main-window";
- expectedElement = gBrowser.selectedBrowser;
- }
-
- is(fm.focusedWindow.document.documentElement.id, expectedDocument, desc + " document matches");
- is(fm.focusedElement, expectedElement, desc + " element matches");
-
- if (onContent) {
- messageManager.removeMessageListener("BrowserTest:FocusChanged", focusChangedListener);
- }
-}
-
-// Load a page and navigate between it and the chrome window.
-add_task(function* ()
-{
- let page1Promise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.selectedBrowser.loadURI(testPage1);
- yield page1Promise;
-
- // When the urlbar is focused, pressing F6 should focus the root of the content page.
- gURLBar.focus();
- yield* expectFocusOnF6(false, "html1", "html1",
- true, "basic focus content page");
-
- // When the content is focused, pressing F6 should focus the urlbar.
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "basic focus content page urlbar");
-
- // When a button in content is focused, pressing F6 should focus the urlbar.
- yield* expectFocusOnF6(false, "html1", "html1",
- true, "basic focus content page with button focused");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () {
- return content.document.getElementById("button1").focus();
- });
-
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "basic focus content page with button focused urlbar");
-
- // The document root should be focused, not the button
- yield* expectFocusOnF6(false, "html1", "html1",
- true, "basic focus again content page with button focused");
-
- // Check to ensure that the root element is focused
- yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () {
- Assert.ok(content.document.activeElement == content.document.documentElement,
- "basic focus again content page with button focused child root is focused");
- });
-});
-
-// Open a second tab. Document focus should skip the background tab.
-add_task(function* ()
-{
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2);
-
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "basic focus content page and second tab urlbar");
- yield* expectFocusOnF6(false, "html2", "html2",
- true, "basic focus content page with second tab");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// Shift+F6 should navigate backwards. There's only one document here so the effect
-// is the same.
-add_task(function* ()
-{
- gURLBar.focus();
- yield* expectFocusOnF6(true, "html1", "html1",
- true, "back focus content page");
- yield* expectFocusOnF6(true, "main-window", gURLBar.inputField,
- false, "back focus content page urlbar");
-});
-
-// Open the sidebar and navigate between the sidebar, content and top-level window
-add_task(function* ()
-{
- let sidebar = document.getElementById("sidebar");
-
- let loadPromise = BrowserTestUtils.waitForEvent(sidebar, "load", true);
- SidebarUI.toggle('viewBookmarksSidebar');
- yield loadPromise;
-
-
- gURLBar.focus();
- yield* expectFocusOnF6(false, "bookmarksPanel",
- sidebar.contentDocument.getElementById("search-box").inputField,
- false, "focus with sidebar open sidebar");
- yield* expectFocusOnF6(false, "html1", "html1",
- true, "focus with sidebar open content");
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "focus with sidebar urlbar");
-
- // Now go backwards
- yield* expectFocusOnF6(true, "html1", "html1",
- true, "back focus with sidebar open content");
- yield* expectFocusOnF6(true, "bookmarksPanel",
- sidebar.contentDocument.getElementById("search-box").inputField,
- false, "back focus with sidebar open sidebar");
- yield* expectFocusOnF6(true, "main-window", gURLBar.inputField,
- false, "back focus with sidebar urlbar");
-
- SidebarUI.toggle('viewBookmarksSidebar');
-});
-
-// Navigate when the downloads panel is open
-add_task(function* ()
-{
- yield pushPrefs(["accessibility.tabfocus", 7]);
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", true);
- EventUtils.synthesizeMouseAtCenter(document.getElementById("downloads-button"), { });
- yield popupShownPromise;
-
- gURLBar.focus();
- yield* expectFocusOnF6(false, "main-window", document.getElementById("downloadsHistory"),
- false, "focus with downloads panel open panel");
- yield* expectFocusOnF6(false, "html1", "html1",
- true, "focus with downloads panel open");
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "focus downloads panel open urlbar");
-
- // Now go backwards
- yield* expectFocusOnF6(true, "html1", "html1",
- true, "back focus with downloads panel open");
- yield* expectFocusOnF6(true, "main-window", document.getElementById("downloadsHistory"),
- false, "back focus with downloads panel open");
- yield* expectFocusOnF6(true, "main-window", gURLBar.inputField,
- false, "back focus downloads panel open urlbar");
-
- let downloadsPopup = document.getElementById("downloadsPanel");
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(downloadsPopup, "popuphidden", true);
- downloadsPopup.hidePopup();
- yield popupHiddenPromise;
-});
-
-// Navigation with a contenteditable body
-add_task(function* ()
-{
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage3);
-
- // The body should be focused when it is editable, not the root.
- gURLBar.focus();
- yield* expectFocusOnF6(false, "html3", "body3",
- true, "focus with contenteditable body");
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "focus with contenteditable body urlbar");
-
- // Now go backwards
-
- yield* expectFocusOnF6(false, "html3", "body3",
- true, "back focus with contenteditable body");
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "back focus with contenteditable body urlbar");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// Navigation with a frameset loaded
-add_task(function* ()
-{
- yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/base/content/test/general/file_documentnavigation_frameset.html");
-
- gURLBar.focus();
- yield* expectFocusOnF6(false, "htmlframe1", "htmlframe1",
- true, "focus on frameset frame 0");
- yield* expectFocusOnF6(false, "htmlframe2", "htmlframe2",
- true, "focus on frameset frame 1");
- yield* expectFocusOnF6(false, "htmlframe3", "htmlframe3",
- true, "focus on frameset frame 2");
- yield* expectFocusOnF6(false, "htmlframe4", "htmlframe4",
- true, "focus on frameset frame 3");
- yield* expectFocusOnF6(false, "main-window", gURLBar.inputField,
- false, "focus on frameset frame urlbar");
-
- yield* expectFocusOnF6(true, "htmlframe4", "htmlframe4",
- true, "back focus on frameset frame 3");
- yield* expectFocusOnF6(true, "htmlframe3", "htmlframe3",
- true, "back focus on frameset frame 2");
- yield* expectFocusOnF6(true, "htmlframe2", "htmlframe2",
- true, "back focus on frameset frame 1");
- yield* expectFocusOnF6(true, "htmlframe1", "htmlframe1",
- true, "back focus on frameset frame 0");
- yield* expectFocusOnF6(true, "main-window", gURLBar.inputField,
- false, "back focus on frameset frame urlbar");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// XXXndeakin add tests for browsers inside of panels
diff --git a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js
deleted file mode 100644
index 054fb3cc0..000000000
--- a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js
+++ /dev/null
@@ -1,221 +0,0 @@
-"use strict";
-
-var gMessageManager;
-
-function frameScript() {
- addMessageListener("Test:RequestFullscreen", () => {
- content.document.body.requestFullscreen();
- });
- addMessageListener("Test:ExitFullscreen", () => {
- content.document.exitFullscreen();
- });
- addMessageListener("Test:QueryFullscreenState", () => {
- sendAsyncMessage("Test:FullscreenState", {
- inDOMFullscreen: !!content.document.fullscreenElement,
- inFullscreen: content.fullScreen
- });
- });
- content.document.addEventListener("fullscreenchange", () => {
- sendAsyncMessage("Test:FullscreenChanged", {
- inDOMFullscreen: !!content.document.fullscreenElement,
- inFullscreen: content.fullScreen
- });
- });
- function waitUntilActive() {
- let doc = content.document;
- if (doc.docShell.isActive && doc.hasFocus()) {
- sendAsyncMessage("Test:Activated");
- } else {
- setTimeout(waitUntilActive, 10);
- }
- }
- waitUntilActive();
-}
-
-function listenOneMessage(aMsg, aListener) {
- function listener({ data }) {
- gMessageManager.removeMessageListener(aMsg, listener);
- aListener(data);
- }
- gMessageManager.addMessageListener(aMsg, listener);
-}
-
-function listenOneEvent(aEvent, aListener) {
- function listener(evt) {
- removeEventListener(aEvent, listener);
- aListener(evt);
- }
- addEventListener(aEvent, listener);
-}
-
-function queryFullscreenState() {
- return new Promise(resolve => {
- listenOneMessage("Test:FullscreenState", resolve);
- gMessageManager.sendAsyncMessage("Test:QueryFullscreenState");
- });
-}
-
-function captureUnexpectedFullscreenChange() {
- ok(false, "catched an unexpected fullscreen change");
-}
-
-const FS_CHANGE_DOM = 1 << 0;
-const FS_CHANGE_SIZE = 1 << 1;
-const FS_CHANGE_BOTH = FS_CHANGE_DOM | FS_CHANGE_SIZE;
-
-function waitForFullscreenChanges(aFlags) {
- return new Promise(resolve => {
- let fullscreenData = null;
- let sizemodeChanged = false;
- function tryResolve() {
- if ((!(aFlags & FS_CHANGE_DOM) || fullscreenData) &&
- (!(aFlags & FS_CHANGE_SIZE) || sizemodeChanged)) {
- if (!fullscreenData) {
- queryFullscreenState().then(resolve);
- } else {
- resolve(fullscreenData);
- }
- }
- }
- if (aFlags & FS_CHANGE_SIZE) {
- listenOneEvent("sizemodechange", () => {
- sizemodeChanged = true;
- tryResolve();
- });
- }
- if (aFlags & FS_CHANGE_DOM) {
- gMessageManager.removeMessageListener(
- "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
- listenOneMessage("Test:FullscreenChanged", data => {
- gMessageManager.addMessageListener(
- "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
- fullscreenData = data;
- tryResolve();
- });
- }
- });
-}
-
-var gTests = [
- {
- desc: "document method",
- affectsFullscreenMode: false,
- exitFunc: () => {
- gMessageManager.sendAsyncMessage("Test:ExitFullscreen");
- }
- },
- {
- desc: "escape key",
- affectsFullscreenMode: false,
- exitFunc: () => {
- executeSoon(() => EventUtils.synthesizeKey("VK_ESCAPE", {}));
- }
- },
- {
- desc: "F11 key",
- affectsFullscreenMode: true,
- exitFunc: function () {
- executeSoon(() => EventUtils.synthesizeKey("VK_F11", {}));
- }
- }
-];
-
-function checkState(expectedStates, contentStates) {
- is(contentStates.inDOMFullscreen, expectedStates.inDOMFullscreen,
- "The DOM fullscreen state of the content should match");
- // TODO window.fullScreen is not updated as soon as the fullscreen
- // state flips in child process, hence checking it could cause
- // anonying intermittent failure. As we just want to confirm the
- // fullscreen state of the browser window, we can just check the
- // that on the chrome window below.
- // is(contentStates.inFullscreen, expectedStates.inFullscreen,
- // "The fullscreen state of the content should match");
- is(!!document.fullscreenElement, expectedStates.inDOMFullscreen,
- "The DOM fullscreen state of the chrome should match");
- is(window.fullScreen, expectedStates.inFullscreen,
- "The fullscreen state of the chrome should match");
-}
-
-const kPage = "http://example.org/browser/browser/" +
- "base/content/test/general/dummy_page.html";
-
-add_task(function* () {
- yield pushPrefs(
- ["full-screen-api.transition-duration.enter", "0 0"],
- ["full-screen-api.transition-duration.leave", "0 0"]);
-
- let tab = gBrowser.addTab(kPage);
- let browser = tab.linkedBrowser;
- gBrowser.selectedTab = tab;
- yield waitForDocLoadComplete();
-
- registerCleanupFunction(() => {
- if (browser.contentWindow.fullScreen) {
- BrowserFullScreen();
- }
- gBrowser.removeTab(tab);
- });
-
- gMessageManager = browser.messageManager;
- gMessageManager.loadFrameScript(
- "data:,(" + frameScript.toString() + ")();", false);
- gMessageManager.addMessageListener(
- "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
-
- // Wait for the document being activated, so that
- // fullscreen request won't be denied.
- yield new Promise(resolve => listenOneMessage("Test:Activated", resolve));
-
- for (let test of gTests) {
- let contentStates;
- info("Testing exit DOM fullscreen via " + test.desc);
-
- contentStates = yield queryFullscreenState();
- checkState({inDOMFullscreen: false, inFullscreen: false}, contentStates);
-
- /* DOM fullscreen without fullscreen mode */
-
- info("> Enter DOM fullscreen");
- gMessageManager.sendAsyncMessage("Test:RequestFullscreen");
- contentStates = yield waitForFullscreenChanges(FS_CHANGE_BOTH);
- checkState({inDOMFullscreen: true, inFullscreen: true}, contentStates);
-
- info("> Exit DOM fullscreen");
- test.exitFunc();
- contentStates = yield waitForFullscreenChanges(FS_CHANGE_BOTH);
- checkState({inDOMFullscreen: false, inFullscreen: false}, contentStates);
-
- /* DOM fullscreen with fullscreen mode */
-
- info("> Enter fullscreen mode");
- // Need to be asynchronous because sizemodechange event could be
- // dispatched synchronously, which would cause the event listener
- // miss that event and wait infinitely.
- executeSoon(() => BrowserFullScreen());
- contentStates = yield waitForFullscreenChanges(FS_CHANGE_SIZE);
- checkState({inDOMFullscreen: false, inFullscreen: true}, contentStates);
-
- info("> Enter DOM fullscreen in fullscreen mode");
- gMessageManager.sendAsyncMessage("Test:RequestFullscreen");
- contentStates = yield waitForFullscreenChanges(FS_CHANGE_DOM);
- checkState({inDOMFullscreen: true, inFullscreen: true}, contentStates);
-
- info("> Exit DOM fullscreen in fullscreen mode");
- test.exitFunc();
- contentStates = yield waitForFullscreenChanges(
- test.affectsFullscreenMode ? FS_CHANGE_BOTH : FS_CHANGE_DOM);
- checkState({
- inDOMFullscreen: false,
- inFullscreen: !test.affectsFullscreenMode
- }, contentStates);
-
- /* Cleanup */
-
- // Exit fullscreen mode if we are still in
- if (window.fullScreen) {
- info("> Cleanup");
- executeSoon(() => BrowserFullScreen());
- yield waitForFullscreenChanges(FS_CHANGE_SIZE);
- }
- }
-});
diff --git a/browser/base/content/test/general/browser_double_close_tab.js b/browser/base/content/test/general/browser_double_close_tab.js
deleted file mode 100644
index 29242c3f9..000000000
--- a/browser/base/content/test/general/browser_double_close_tab.js
+++ /dev/null
@@ -1,80 +0,0 @@
-"use strict";
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/base/content/test/general/file_double_close_tab.html";
-var testTab;
-
-SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
-
-function waitForDialog(callback) {
- function onTabModalDialogLoaded(node) {
- Services.obs.removeObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded");
- callback(node);
- }
-
- // Listen for the dialog being created
- Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false);
-}
-
-function waitForDialogDestroyed(node, callback) {
- // Now listen for the dialog going away again...
- let observer = new MutationObserver(function(muts) {
- if (!node.parentNode) {
- ok(true, "Dialog is gone");
- done();
- }
- });
- observer.observe(node.parentNode, {childList: true});
- let failureTimeout = setTimeout(function() {
- ok(false, "Dialog should have been destroyed");
- done();
- }, 10000);
-
- function done() {
- clearTimeout(failureTimeout);
- observer.disconnect();
- observer = null;
- callback();
- }
-}
-
-add_task(function*() {
- testTab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(testTab, TEST_PAGE);
- // XXXgijs the reason this has nesting and callbacks rather than promises is
- // that DOM promises resolve on the next tick. So they're scheduled
- // in an event queue. So when we spin a new event queue for a modal dialog...
- // everything gets messed up and the promise's .then callbacks never get
- // called, despite resolve() being called just fine.
- yield new Promise(resolveOuter => {
- waitForDialog(dialogNode => {
- waitForDialogDestroyed(dialogNode, () => {
- let doCompletion = () => setTimeout(resolveOuter, 0);
- info("Now checking if dialog is destroyed");
- ok(!dialogNode.parentNode, "onbeforeunload dialog should be gone.");
- if (dialogNode.parentNode) {
- // Failed to remove onbeforeunload dialog, so do it ourselves:
- let leaveBtn = dialogNode.ui.button0;
- waitForDialogDestroyed(dialogNode, doCompletion);
- EventUtils.synthesizeMouseAtCenter(leaveBtn, {});
- return;
- }
- doCompletion();
- });
- // Click again:
- document.getAnonymousElementByAttribute(testTab, "anonid", "close-button").click();
- });
- // Click once:
- document.getAnonymousElementByAttribute(testTab, "anonid", "close-button").click();
- });
- yield promiseWaitForCondition(() => !testTab.parentNode);
- ok(!testTab.parentNode, "Tab should be closed completely");
-});
-
-registerCleanupFunction(function() {
- if (testTab.parentNode) {
- // Remove the handler, or closing this tab will prove tricky:
- try {
- testTab.linkedBrowser.contentWindow.onbeforeunload = null;
- } catch (ex) {}
- gBrowser.removeTab(testTab);
- }
-});
diff --git a/browser/base/content/test/general/browser_drag.js b/browser/base/content/test/general/browser_drag.js
deleted file mode 100644
index 64ad19bde..000000000
--- a/browser/base/content/test/general/browser_drag.js
+++ /dev/null
@@ -1,45 +0,0 @@
-function test()
-{
- waitForExplicitFinish();
-
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- // ---- Test dragging the proxy icon ---
- var value = content.location.href;
- var urlString = value + "\n" + content.document.title;
- var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
- var expected = [ [
- { type : "text/x-moz-url",
- data : urlString },
- { type : "text/uri-list",
- data : value },
- { type : "text/plain",
- data : value },
- { type : "text/html",
- data : htmlString }
- ] ];
- // set the valid attribute so dropping is allowed
- var oldstate = gURLBar.getAttribute("pageproxystate");
- gURLBar.setAttribute("pageproxystate", "valid");
- var dt = EventUtils.synthesizeDragStart(document.getElementById("identity-box"), expected);
- is(dt, null, "drag on proxy icon");
- gURLBar.setAttribute("pageproxystate", oldstate);
- // Now, the identity information panel is opened by the proxy icon click.
- // We need to close it for next tests.
- EventUtils.synthesizeKey("VK_ESCAPE", {}, window);
-
- // now test dragging onto a tab
- var tab = gBrowser.addTab("about:blank", {skipAnimation: true});
- var browser = gBrowser.getBrowserForTab(tab);
-
- browser.addEventListener("load", function () {
- is(browser.contentWindow.location, "http://mochi.test:8888/", "drop on tab");
- gBrowser.removeTab(tab);
- finish();
- }, true);
-
- EventUtils.synthesizeDrop(tab, tab, [[{type: "text/uri-list", data: "http://mochi.test:8888/"}]], "copy", window);
-}
diff --git a/browser/base/content/test/general/browser_duplicateIDs.js b/browser/base/content/test/general/browser_duplicateIDs.js
deleted file mode 100644
index 38fc17820..000000000
--- a/browser/base/content/test/general/browser_duplicateIDs.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function test() {
- var ids = {};
- Array.forEach(document.querySelectorAll("[id]"), function (node) {
- var id = node.id;
- ok(!(id in ids), id + " should be unique");
- ids[id] = null;
- });
-}
diff --git a/browser/base/content/test/general/browser_e10s_about_process.js b/browser/base/content/test/general/browser_e10s_about_process.js
deleted file mode 100644
index 2b4816754..000000000
--- a/browser/base/content/test/general/browser_e10s_about_process.js
+++ /dev/null
@@ -1,114 +0,0 @@
-const CHROME_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-const CONTENT_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
-
-const CHROME = {
- id: "cb34538a-d9da-40f3-b61a-069f0b2cb9fb",
- path: "test-chrome",
- flags: 0,
-}
-const CANREMOTE = {
- id: "2480d3e1-9ce4-4b84-8ae3-910b9a95cbb3",
- path: "test-allowremote",
- flags: Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD,
-}
-const MUSTREMOTE = {
- id: "f849cee5-e13e-44d2-981d-0fb3884aaead",
- path: "test-mustremote",
- flags: Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD,
-}
-
-const TEST_MODULES = [
- CHROME,
- CANREMOTE,
- MUSTREMOTE
-]
-
-function AboutModule() {
-}
-
-AboutModule.prototype = {
- newChannel: function(aURI, aLoadInfo) {
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- getURIFlags: function(aURI) {
- for (let module of TEST_MODULES) {
- if (aURI.path.startsWith(module.path)) {
- return module.flags;
- }
- }
-
- ok(false, "Called getURIFlags for an unknown page " + aURI.spec);
- return 0;
- },
-
- getIndexedDBOriginPostfix: function(aURI) {
- return null;
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule])
-};
-
-var AboutModuleFactory = {
- createInstance: function(aOuter, aIID) {
- if (aOuter)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
- return new AboutModule().QueryInterface(aIID);
- },
-
- lockFactory: function(aLock) {
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-};
-
-add_task(function* init() {
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- for (let module of TEST_MODULES) {
- registrar.registerFactory(Components.ID(module.id), "",
- "@mozilla.org/network/protocol/about;1?what=" + module.path,
- AboutModuleFactory);
- }
-});
-
-registerCleanupFunction(() => {
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- for (let module of TEST_MODULES) {
- registrar.unregisterFactory(Components.ID(module.id), AboutModuleFactory);
- }
-});
-
-function test_url(url, chromeResult, contentResult) {
- is(E10SUtils.canLoadURIInProcess(url, CHROME_PROCESS),
- chromeResult, "Check URL in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url, CONTENT_PROCESS),
- contentResult, "Check URL in content process.");
-
- is(E10SUtils.canLoadURIInProcess(url + "#foo", CHROME_PROCESS),
- chromeResult, "Check URL with ref in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url + "#foo", CONTENT_PROCESS),
- contentResult, "Check URL with ref in content process.");
-
- is(E10SUtils.canLoadURIInProcess(url + "?foo", CHROME_PROCESS),
- chromeResult, "Check URL with query in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url + "?foo", CONTENT_PROCESS),
- contentResult, "Check URL with query in content process.");
-
- is(E10SUtils.canLoadURIInProcess(url + "?foo#bar", CHROME_PROCESS),
- chromeResult, "Check URL with query and ref in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url + "?foo#bar", CONTENT_PROCESS),
- contentResult, "Check URL with query and ref in content process.");
-}
-
-add_task(function* test_chrome() {
- test_url("about:" + CHROME.path, true, false);
-});
-
-add_task(function* test_any() {
- test_url("about:" + CANREMOTE.path, true, true);
-});
-
-add_task(function* test_remote() {
- test_url("about:" + MUSTREMOTE.path, false, true);
-});
diff --git a/browser/base/content/test/general/browser_e10s_chrome_process.js b/browser/base/content/test/general/browser_e10s_chrome_process.js
deleted file mode 100644
index 0726447ce..000000000
--- a/browser/base/content/test/general/browser_e10s_chrome_process.js
+++ /dev/null
@@ -1,150 +0,0 @@
-// Returns a function suitable for add_task which loads startURL, runs
-// transitionTask and waits for endURL to load, checking that the URLs were
-// loaded in the correct process.
-function makeTest(name, startURL, startProcessIsRemote, endURL, endProcessIsRemote, transitionTask) {
- return function*() {
- info("Running test " + name + ", " + transitionTask.name);
- let browser = gBrowser.selectedBrowser;
-
- // In non-e10s nothing should be remote
- if (!gMultiProcessBrowser) {
- startProcessIsRemote = false;
- endProcessIsRemote = false;
- }
-
- // Load the initial URL and make sure we are in the right initial process
- info("Loading initial URL");
- browser.loadURI(startURL);
- yield waitForDocLoadComplete();
-
- is(browser.currentURI.spec, startURL, "Shouldn't have been redirected");
- is(browser.isRemoteBrowser, startProcessIsRemote, "Should be displayed in the right process");
-
- let docLoadedPromise = waitForDocLoadComplete();
- let asyncTask = Task.async(transitionTask);
- let expectSyncChange = yield asyncTask(browser, endURL);
- if (expectSyncChange) {
- is(browser.isRemoteBrowser, endProcessIsRemote, "Should have switched to the right process synchronously");
- }
- yield docLoadedPromise;
-
- is(browser.currentURI.spec, endURL, "Should have made it to the final URL");
- is(browser.isRemoteBrowser, endProcessIsRemote, "Should be displayed in the right process");
- }
-}
-
-const CHROME_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-const CONTENT_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
-const PATH = (getRootDirectory(gTestPath) + "test_process_flags_chrome.html").replace("chrome://mochitests", "");
-
-const CHROME = "chrome://mochitests" + PATH;
-const CANREMOTE = "chrome://mochitests-any" + PATH;
-const MUSTREMOTE = "chrome://mochitests-content" + PATH;
-
-add_task(function* init() {
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
-});
-
-registerCleanupFunction(() => {
- gBrowser.removeCurrentTab();
-});
-
-function test_url(url, chromeResult, contentResult) {
- is(E10SUtils.canLoadURIInProcess(url, CHROME_PROCESS),
- chromeResult, "Check URL in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url, CONTENT_PROCESS),
- contentResult, "Check URL in content process.");
-
- is(E10SUtils.canLoadURIInProcess(url + "#foo", CHROME_PROCESS),
- chromeResult, "Check URL with ref in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url + "#foo", CONTENT_PROCESS),
- contentResult, "Check URL with ref in content process.");
-
- is(E10SUtils.canLoadURIInProcess(url + "?foo", CHROME_PROCESS),
- chromeResult, "Check URL with query in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url + "?foo", CONTENT_PROCESS),
- contentResult, "Check URL with query in content process.");
-
- is(E10SUtils.canLoadURIInProcess(url + "?foo#bar", CHROME_PROCESS),
- chromeResult, "Check URL with query and ref in chrome process.");
- is(E10SUtils.canLoadURIInProcess(url + "?foo#bar", CONTENT_PROCESS),
- contentResult, "Check URL with query and ref in content process.");
-}
-
-add_task(function* test_chrome() {
- test_url(CHROME, true, false);
-});
-
-add_task(function* test_any() {
- test_url(CANREMOTE, true, true);
-});
-
-add_task(function* test_remote() {
- test_url(MUSTREMOTE, false, true);
-});
-
-// The set of page transitions
-var TESTS = [
- [
- "chrome -> chrome",
- CHROME, false,
- CHROME, false,
- ],
- [
- "chrome -> canremote",
- CHROME, false,
- CANREMOTE, false,
- ],
- [
- "chrome -> mustremote",
- CHROME, false,
- MUSTREMOTE, true,
- ],
- [
- "remote -> chrome",
- MUSTREMOTE, true,
- CHROME, false,
- ],
- [
- "remote -> canremote",
- MUSTREMOTE, true,
- CANREMOTE, true,
- ],
- [
- "remote -> mustremote",
- MUSTREMOTE, true,
- MUSTREMOTE, true,
- ],
-];
-
-// The different ways to transition from one page to another
-var TRANSITIONS = [
-// Loads the new page by calling browser.loadURI directly
-function* loadURI(browser, uri) {
- info("Calling browser.loadURI");
- yield BrowserTestUtils.loadURI(browser, uri);
- return true;
-},
-
-// Loads the new page by finding a link with the right href in the document and
-// clicking it
-function* clickLink(browser, uri) {
- info("Clicking link");
-
- function frame_script(frameUri) {
- let link = content.document.querySelector("a[href='" + frameUri + "']");
- link.click();
- }
-
- browser.messageManager.loadFrameScript("data:,(" + frame_script.toString() + ")(" + JSON.stringify(uri) + ");", false);
-
- return false;
-},
-];
-
-// Creates a set of test tasks, one for each combination of TESTS and TRANSITIONS.
-for (let test of TESTS) {
- for (let transition of TRANSITIONS) {
- add_task(makeTest(...test, transition));
- }
-}
diff --git a/browser/base/content/test/general/browser_e10s_javascript.js b/browser/base/content/test/general/browser_e10s_javascript.js
deleted file mode 100644
index 90e847b09..000000000
--- a/browser/base/content/test/general/browser_e10s_javascript.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const CHROME_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-const CONTENT_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
-
-add_task(function*() {
- let url = "javascript:dosomething()";
-
- ok(E10SUtils.canLoadURIInProcess(url, CHROME_PROCESS),
- "Check URL in chrome process.");
- ok(E10SUtils.canLoadURIInProcess(url, CONTENT_PROCESS),
- "Check URL in content process.");
-});
diff --git a/browser/base/content/test/general/browser_e10s_switchbrowser.js b/browser/base/content/test/general/browser_e10s_switchbrowser.js
deleted file mode 100644
index e6134f749..000000000
--- a/browser/base/content/test/general/browser_e10s_switchbrowser.js
+++ /dev/null
@@ -1,261 +0,0 @@
-requestLongerTimeout(2);
-
-const DUMMY_PATH = "browser/browser/base/content/test/general/dummy_page.html";
-
-const gExpectedHistory = {
- index: -1,
- entries: []
-};
-
-function get_remote_history(browser) {
- function frame_script() {
- let webNav = docShell.QueryInterface(Components.interfaces.nsIWebNavigation);
- let sessionHistory = webNav.sessionHistory;
- let result = {
- index: sessionHistory.index,
- entries: []
- };
-
- for (let i = 0; i < sessionHistory.count; i++) {
- let entry = sessionHistory.getEntryAtIndex(i, false);
- result.entries.push({
- uri: entry.URI.spec,
- title: entry.title
- });
- }
-
- sendAsyncMessage("Test:History", result);
- }
-
- return new Promise(resolve => {
- browser.messageManager.addMessageListener("Test:History", function listener({data}) {
- browser.messageManager.removeMessageListener("Test:History", listener);
- resolve(data);
- });
-
- browser.messageManager.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
- });
-}
-
-var check_history = Task.async(function*() {
- let sessionHistory = yield get_remote_history(gBrowser.selectedBrowser);
-
- let count = sessionHistory.entries.length;
- is(count, gExpectedHistory.entries.length, "Should have the right number of history entries");
- is(sessionHistory.index, gExpectedHistory.index, "Should have the right history index");
-
- for (let i = 0; i < count; i++) {
- let entry = sessionHistory.entries[i];
- is(entry.uri, gExpectedHistory.entries[i].uri, "Should have the right URI");
- is(entry.title, gExpectedHistory.entries[i].title, "Should have the right title");
- }
-});
-
-function clear_history() {
- gExpectedHistory.index = -1;
- gExpectedHistory.entries = [];
-}
-
-// Waits for a load and updates the known history
-var waitForLoad = Task.async(function*(uri) {
- info("Loading " + uri);
- // Longwinded but this ensures we don't just shortcut to LoadInNewProcess
- gBrowser.selectedBrowser.webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
-
- yield waitForDocLoadComplete();
- gExpectedHistory.index++;
- gExpectedHistory.entries.push({
- uri: gBrowser.currentURI.spec,
- title: gBrowser.contentTitle
- });
-});
-
-// Waits for a load and updates the known history
-var waitForLoadWithFlags = Task.async(function*(uri, flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE) {
- info("Loading " + uri + " flags = " + flags);
- gBrowser.selectedBrowser.loadURIWithFlags(uri, flags, null, null, null);
-
- yield waitForDocLoadComplete();
- if (!(flags & Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY)) {
-
- if (flags & Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY) {
- gExpectedHistory.entries.pop();
- }
- else {
- gExpectedHistory.index++;
- }
-
- gExpectedHistory.entries.push({
- uri: gBrowser.currentURI.spec,
- title: gBrowser.contentTitle
- });
- }
-});
-
-var back = Task.async(function*() {
- info("Going back");
- gBrowser.goBack();
- yield waitForDocLoadComplete();
- gExpectedHistory.index--;
-});
-
-var forward = Task.async(function*() {
- info("Going forward");
- gBrowser.goForward();
- yield waitForDocLoadComplete();
- gExpectedHistory.index++;
-});
-
-// Tests that navigating from a page that should be in the remote process and
-// a page that should be in the main process works and retains history
-add_task(function* test_navigation() {
- let expectedRemote = gMultiProcessBrowser;
-
- info("1");
- // Create a tab and load a remote page in it
- gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
- let {permanentKey} = gBrowser.selectedBrowser;
- yield waitForLoad("http://example.org/" + DUMMY_PATH);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
-
- info("2");
- // Load another page
- yield waitForLoad("http://example.com/" + DUMMY_PATH);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("3");
- // Load a non-remote page
- yield waitForLoad("about:robots");
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("4");
- // Load a remote page
- yield waitForLoad("http://example.org/" + DUMMY_PATH);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("5");
- yield back();
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("6");
- yield back();
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("7");
- yield forward();
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("8");
- yield forward();
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("9");
- yield back();
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("10");
- // Load a new remote page, this should replace the last history entry
- gExpectedHistory.entries.splice(gExpectedHistory.entries.length - 1, 1);
- yield waitForLoad("http://example.com/" + DUMMY_PATH);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
- yield check_history();
-
- info("11");
- gBrowser.removeCurrentTab();
- clear_history();
-});
-
-// Tests that calling gBrowser.loadURI or browser.loadURI to load a page in a
-// different process updates the browser synchronously
-add_task(function* test_synchronous() {
- let expectedRemote = gMultiProcessBrowser;
-
- info("1");
- // Create a tab and load a remote page in it
- gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
- let {permanentKey} = gBrowser.selectedBrowser;
- yield waitForLoad("http://example.org/" + DUMMY_PATH);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
-
- info("2");
- // Load another page
- info("Loading about:robots");
- yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
-
- yield waitForDocLoadComplete();
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
-
- info("3");
- // Load the remote page again
- info("Loading http://example.org/" + DUMMY_PATH);
- yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "http://example.org/" + DUMMY_PATH);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
-
- yield waitForDocLoadComplete();
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
-
- info("4");
- gBrowser.removeCurrentTab();
- clear_history();
-});
-
-// Tests that load flags are correctly passed through to the child process with
-// normal loads
-add_task(function* test_loadflags() {
- let expectedRemote = gMultiProcessBrowser;
-
- info("1");
- // Create a tab and load a remote page in it
- gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
- yield waitForLoadWithFlags("about:robots");
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- yield check_history();
-
- info("2");
- // Load a page in the remote process with some custom flags
- yield waitForLoadWithFlags("http://example.com/" + DUMMY_PATH, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- yield check_history();
-
- info("3");
- // Load a non-remote page
- yield waitForLoadWithFlags("about:robots");
- is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
- yield check_history();
-
- info("4");
- // Load another remote page
- yield waitForLoadWithFlags("http://example.org/" + DUMMY_PATH, Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY);
- is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
- yield check_history();
-
- is(gExpectedHistory.entries.length, 2, "Should end with the right number of history entries");
-
- info("5");
- gBrowser.removeCurrentTab();
- clear_history();
-});
diff --git a/browser/base/content/test/general/browser_favicon_change.js b/browser/base/content/test/general/browser_favicon_change.js
deleted file mode 100644
index f6b0a2a42..000000000
--- a/browser/base/content/test/general/browser_favicon_change.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const TEST_URL = "http://mochi.test:8888/browser/browser/base/content/test/general/file_favicon_change.html"
-
-add_task(function*() {
- let extraTab = gBrowser.selectedTab = gBrowser.addTab();
- extraTab.linkedBrowser.loadURI(TEST_URL);
- let tabLoaded = BrowserTestUtils.browserLoaded(extraTab.linkedBrowser);
- let expectedFavicon = "http://example.org/one-icon";
- let haveChanged = new Promise.defer();
- let observer = new MutationObserver(function(mutations) {
- for (let mut of mutations) {
- if (mut.attributeName != "image") {
- continue;
- }
- let imageVal = extraTab.getAttribute("image").replace(/#.*$/, "");
- if (!imageVal) {
- // The value gets removed because it doesn't load.
- continue;
- }
- is(imageVal, expectedFavicon, "Favicon image should correspond to expected image.");
- haveChanged.resolve();
- }
- });
- observer.observe(extraTab, {attributes: true});
- yield tabLoaded;
- yield haveChanged.promise;
- haveChanged = new Promise.defer();
- expectedFavicon = "http://example.org/other-icon";
- ContentTask.spawn(extraTab.linkedBrowser, null, function() {
- let ev = new content.CustomEvent("PleaseChangeFavicon", {});
- content.dispatchEvent(ev);
- });
- yield haveChanged.promise;
- observer.disconnect();
- gBrowser.removeTab(extraTab);
-});
-
diff --git a/browser/base/content/test/general/browser_favicon_change_not_in_document.js b/browser/base/content/test/general/browser_favicon_change_not_in_document.js
deleted file mode 100644
index d14a1da32..000000000
--- a/browser/base/content/test/general/browser_favicon_change_not_in_document.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-const TEST_URL = "http://mochi.test:8888/browser/browser/base/content/test/general/file_favicon_change_not_in_document.html"
-
-add_task(function*() {
- let extraTab = gBrowser.selectedTab = gBrowser.addTab();
- let tabLoaded = promiseTabLoaded(extraTab);
- extraTab.linkedBrowser.loadURI(TEST_URL);
- let expectedFavicon = "http://example.org/one-icon";
- let haveChanged = new Promise.defer();
- let observer = new MutationObserver(function(mutations) {
- for (let mut of mutations) {
- if (mut.attributeName != "image") {
- continue;
- }
- let imageVal = extraTab.getAttribute("image").replace(/#.*$/, "");
- if (!imageVal) {
- // The value gets removed because it doesn't load.
- continue;
- }
- is(imageVal, expectedFavicon, "Favicon image should correspond to expected image.");
- haveChanged.resolve();
- }
- });
- observer.observe(extraTab, {attributes: true});
- yield tabLoaded;
- expectedFavicon = "http://example.org/yet-another-icon";
- haveChanged = new Promise.defer();
- yield haveChanged.promise;
- observer.disconnect();
- gBrowser.removeTab(extraTab);
-});
-
-
diff --git a/browser/base/content/test/general/browser_feed_discovery.js b/browser/base/content/test/general/browser_feed_discovery.js
deleted file mode 100644
index 73dcef755..000000000
--- a/browser/base/content/test/general/browser_feed_discovery.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const URL = "http://mochi.test:8888/browser/browser/base/content/test/general/feed_discovery.html"
-
-/** Test for Bug 377611 **/
-
-add_task(function* () {
- // Open a new tab.
- gBrowser.selectedTab = gBrowser.addTab(URL);
- registerCleanupFunction(() => gBrowser.removeCurrentTab());
-
- let browser = gBrowser.selectedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- let discovered = browser.feeds;
- ok(discovered.length > 0, "some feeds should be discovered");
-
- let feeds = {};
- for (let aFeed of discovered) {
- feeds[aFeed.href] = true;
- }
-
- yield ContentTask.spawn(browser, feeds, function* (contentFeeds) {
- for (let aLink of content.document.getElementsByTagName("link")) {
- // ignore real stylesheets, and anything without an href property
- if (aLink.type != "text/css" && aLink.href) {
- if (/bogus/i.test(aLink.title)) {
- ok(!contentFeeds[aLink.href], "don't discover " + aLink.href);
- } else {
- ok(contentFeeds[aLink.href], "should discover " + aLink.href);
- }
- }
- }
- });
-})
diff --git a/browser/base/content/test/general/browser_findbarClose.js b/browser/base/content/test/general/browser_findbarClose.js
deleted file mode 100644
index 53503073c..000000000
--- a/browser/base/content/test/general/browser_findbarClose.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests find bar auto-close behavior
-
-var newTab;
-
-add_task(function* findbar_test() {
- waitForExplicitFinish();
- newTab = gBrowser.addTab("about:blank");
-
- let promise = ContentTask.spawn(newTab.linkedBrowser, null, function* () {
- yield ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", false);
- });
- newTab.linkedBrowser.loadURI("http://example.com/browser/" +
- "browser/base/content/test/general/test_bug628179.html");
- yield promise;
-
- gFindBar.open();
-
- yield new ContentTask.spawn(newTab.linkedBrowser, null, function* () {
- let iframe = content.document.getElementById("iframe");
- let awaitLoad = ContentTaskUtils.waitForEvent(iframe, "load", false);
- iframe.src = "http://example.org/";
- yield awaitLoad;
- });
-
- ok(!gFindBar.hidden, "the Find bar isn't hidden after the location of a " +
- "subdocument changes");
-
- gFindBar.close();
- gBrowser.removeTab(newTab);
- finish();
-});
-
diff --git a/browser/base/content/test/general/browser_focusonkeydown.js b/browser/base/content/test/general/browser_focusonkeydown.js
deleted file mode 100644
index 5b3337203..000000000
--- a/browser/base/content/test/general/browser_focusonkeydown.js
+++ /dev/null
@@ -1,26 +0,0 @@
-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);
- if (event.originalTarget == gURLBar.inputField) {
- keyUps++;
- }
- }, true);
-
- gURLBar.addEventListener("keydown", function redirectFocus(event) {
- gURLBar.removeEventListener("keydown", redirectFocus, true);
- gBrowser.selectedBrowser.focus();
- }, true);
-
- EventUtils.synthesizeKey("v", { });
-
- is(keyUps, 1, "Key up fired at url bar");
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_fullscreen-window-open.js b/browser/base/content/test/general/browser_fullscreen-window-open.js
deleted file mode 100644
index 2624b754a..000000000
--- a/browser/base/content/test/general/browser_fullscreen-window-open.js
+++ /dev/null
@@ -1,347 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-
-const PREF_DISABLE_OPEN_NEW_WINDOW = "browser.link.open_newwindow.disabled_in_fullscreen";
-const isOSX = (Services.appinfo.OS === "Darwin");
-
-const TEST_FILE = "file_fullscreen-window-open.html";
-const gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/",
- "http://127.0.0.1:8888/");
-
-function test () {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, true);
-
- let newTab = gBrowser.addTab(gHttpTestRoot + TEST_FILE);
- gBrowser.selectedTab = newTab;
-
- whenTabLoaded(newTab, function () {
- // Enter browser fullscreen mode.
- BrowserFullScreen();
-
- runNextTest();
- });
-}
-
-registerCleanupFunction(function() {
- // Exit browser fullscreen mode.
- BrowserFullScreen();
-
- gBrowser.removeCurrentTab();
-
- Services.prefs.clearUserPref(PREF_DISABLE_OPEN_NEW_WINDOW);
-});
-
-var gTests = [
- test_open,
- test_open_with_size,
- test_open_with_pos,
- test_open_with_outerSize,
- test_open_with_innerSize,
- test_open_with_dialog,
- test_open_when_open_new_window_by_pref,
- test_open_with_pref_to_disable_in_fullscreen,
- test_open_from_chrome,
-];
-
-function runNextTest () {
- let testCase = gTests.shift();
- if (testCase) {
- executeSoon(testCase);
- }
- else {
- finish();
- }
-}
-
-
-// Test for window.open() with no feature.
-function test_open() {
- waitForTabOpen({
- message: {
- title: "test_open",
- param: "",
- },
- finalizeFn: function () {},
- });
-}
-
-// Test for window.open() with width/height.
-function test_open_with_size() {
- waitForTabOpen({
- message: {
- title: "test_open_with_size",
- param: "width=400,height=400",
- },
- finalizeFn: function () {},
- });
-}
-
-// Test for window.open() with top/left.
-function test_open_with_pos() {
- waitForTabOpen({
- message: {
- title: "test_open_with_pos",
- param: "top=200,left=200",
- },
- finalizeFn: function () {},
- });
-}
-
-// Test for window.open() with outerWidth/Height.
-function test_open_with_outerSize() {
- let [outerWidth, outerHeight] = [window.outerWidth, window.outerHeight];
- waitForTabOpen({
- message: {
- title: "test_open_with_outerSize",
- param: "outerWidth=200,outerHeight=200",
- },
- successFn: function () {
- is(window.outerWidth, outerWidth, "Don't change window.outerWidth.");
- is(window.outerHeight, outerHeight, "Don't change window.outerHeight.");
- },
- finalizeFn: function () {},
- });
-}
-
-// Test for window.open() with innerWidth/Height.
-function test_open_with_innerSize() {
- let [innerWidth, innerHeight] = [window.innerWidth, window.innerHeight];
- waitForTabOpen({
- message: {
- title: "test_open_with_innerSize",
- param: "innerWidth=200,innerHeight=200",
- },
- successFn: function () {
- is(window.innerWidth, innerWidth, "Don't change window.innerWidth.");
- is(window.innerHeight, innerHeight, "Don't change window.innerHeight.");
- },
- finalizeFn: function () {},
- });
-}
-
-// Test for window.open() with dialog.
-function test_open_with_dialog() {
- waitForTabOpen({
- message: {
- title: "test_open_with_dialog",
- param: "dialog=yes",
- },
- finalizeFn: function () {},
- });
-}
-
-// Test for window.open()
-// when "browser.link.open_newwindow" is nsIBrowserDOMWindow.OPEN_NEWWINDOW
-function test_open_when_open_new_window_by_pref() {
- const PREF_NAME = "browser.link.open_newwindow";
- Services.prefs.setIntPref(PREF_NAME, Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW);
- is(Services.prefs.getIntPref(PREF_NAME), Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW,
- PREF_NAME + " is nsIBrowserDOMWindow.OPEN_NEWWINDOW at this time");
-
- waitForTabOpen({
- message: {
- title: "test_open_when_open_new_window_by_pref",
- param: "width=400,height=400",
- },
- finalizeFn: function () {
- Services.prefs.clearUserPref(PREF_NAME);
- },
- });
-}
-
-// Test for the pref, "browser.link.open_newwindow.disabled_in_fullscreen"
-function test_open_with_pref_to_disable_in_fullscreen() {
- Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, false);
-
- waitForWindowOpen({
- message: {
- title: "test_open_with_pref_disabled_in_fullscreen",
- param: "width=400,height=400",
- },
- finalizeFn: function () {
- Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, true);
- },
- });
-}
-
-
-// Test for window.open() called from chrome context.
-function test_open_from_chrome() {
- waitForWindowOpenFromChrome({
- message: {
- title: "test_open_from_chrome",
- param: "",
- },
- finalizeFn: function () {}
- });
-}
-
-function waitForTabOpen(aOptions) {
- let message = aOptions.message;
-
- if (!message.title) {
- ok(false, "Can't get message.title.");
- aOptions.finalizeFn();
- runNextTest();
- return;
- }
-
- info("Running test: " + message.title);
-
- let onTabOpen = function onTabOpen(aEvent) {
- gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true);
-
- let tab = aEvent.target;
- whenTabLoaded(tab, function () {
- is(tab.linkedBrowser.contentTitle, message.title,
- "Opened Tab is expected: " + message.title);
-
- if (aOptions.successFn) {
- aOptions.successFn();
- }
-
- gBrowser.removeTab(tab);
- finalize();
- });
- }
- gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true);
-
- let finalize = function () {
- aOptions.finalizeFn();
- info("Finished: " + message.title);
- runNextTest();
- };
-
- const URI = "data:text/html;charset=utf-8,<!DOCTYPE html><html><head><title>"+
- message.title +
- "<%2Ftitle><%2Fhead><body><%2Fbody><%2Fhtml>";
-
- executeWindowOpenInContent({
- uri: URI,
- title: message.title,
- option: message.param,
- });
-}
-
-
-function waitForWindowOpen(aOptions) {
- let message = aOptions.message;
- let url = aOptions.url || "about:blank";
-
- if (!message.title) {
- ok(false, "Can't get message.title");
- aOptions.finalizeFn();
- runNextTest();
- return;
- }
-
- info("Running test: " + message.title);
-
- let onFinalize = function () {
- aOptions.finalizeFn();
-
- info("Finished: " + message.title);
- runNextTest();
- };
-
- let listener = new WindowListener(message.title, getBrowserURL(), {
- onSuccess: aOptions.successFn,
- onFinalize: onFinalize,
- });
- Services.wm.addListener(listener);
-
- executeWindowOpenInContent({
- uri: url,
- title: message.title,
- option: message.param,
- });
-}
-
-function executeWindowOpenInContent(aParam) {
- ContentTask.spawn(gBrowser.selectedBrowser, JSON.stringify(aParam), function* (dataTestParam) {
- let testElm = content.document.getElementById("test");
- testElm.setAttribute("data-test-param", dataTestParam);
- testElm.click();
- });
-}
-
-function waitForWindowOpenFromChrome(aOptions) {
- let message = aOptions.message;
- let url = aOptions.url || "about:blank";
-
- if (!message.title) {
- ok(false, "Can't get message.title");
- aOptions.finalizeFn();
- runNextTest();
- return;
- }
-
- info("Running test: " + message.title);
-
- let onFinalize = function () {
- aOptions.finalizeFn();
-
- info("Finished: " + message.title);
- runNextTest();
- };
-
- let listener = new WindowListener(message.title, getBrowserURL(), {
- onSuccess: aOptions.successFn,
- onFinalize: onFinalize,
- });
- Services.wm.addListener(listener);
-
- window.open(url, message.title, message.option);
-}
-
-function WindowListener(aTitle, aUrl, aCallBackObj) {
- this.test_title = aTitle;
- this.test_url = aUrl;
- this.callback_onSuccess = aCallBackObj.onSuccess;
- this.callBack_onFinalize = aCallBackObj.onFinalize;
-}
-WindowListener.prototype = {
-
- test_title: null,
- test_url: null,
- callback_onSuccess: null,
- callBack_onFinalize: null,
-
- onOpenWindow: function(aXULWindow) {
- Services.wm.removeListener(this);
-
- let domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- let onLoad = aEvent => {
- is(domwindow.document.location.href, this.test_url,
- "Opened Window is expected: "+ this.test_title);
- if (this.callback_onSuccess) {
- this.callback_onSuccess();
- }
-
- domwindow.removeEventListener("load", onLoad, true);
-
- // wait for trasition to fullscreen on OSX Lion later
- if (isOSX) {
- setTimeout(function() {
- domwindow.close();
- executeSoon(this.callBack_onFinalize);
- }.bind(this), 3000);
- }
- else {
- domwindow.close();
- executeSoon(this.callBack_onFinalize);
- }
- };
- domwindow.addEventListener("load", onLoad, true);
- },
- onCloseWindow: function(aXULWindow) {},
- onWindowTitleChange: function(aXULWindow, aNewTitle) {},
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowMediatorListener,
- Ci.nsISupports]),
-};
diff --git a/browser/base/content/test/general/browser_fxa_migrate.js b/browser/base/content/test/general/browser_fxa_migrate.js
deleted file mode 100644
index 2faf9fb10..000000000
--- a/browser/base/content/test/general/browser_fxa_migrate.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const STATE_CHANGED_TOPIC = "fxa-migration:state-changed";
-const NOTIFICATION_TITLE = "fxa-migration";
-
-var imports = {};
-Cu.import("resource://services-sync/FxaMigrator.jsm", imports);
-
-add_task(function* test() {
- // Fake the state where we saw an EOL notification.
- Services.obs.notifyObservers(null, STATE_CHANGED_TOPIC, null);
-
- let notificationBox = document.getElementById("global-notificationbox");
- Assert.ok(notificationBox.allNotifications.some(n => {
- return n.getAttribute("value") == NOTIFICATION_TITLE;
- }), "Disconnect notification should be present");
-});
diff --git a/browser/base/content/test/general/browser_fxa_oauth.html b/browser/base/content/test/general/browser_fxa_oauth.html
deleted file mode 100644
index b31e7ceb4..000000000
--- a/browser/base/content/test/general/browser_fxa_oauth.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>fxa_oauth_test</title>
-</head>
-<body>
-<script>
- window.onload = function() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- // Note: This intentionally sends an object instead of a string, to ensure both work
- // (see browser_fxa_oauth_with_keys.html for the other test)
- detail: {
- id: "oauth_client_id",
- message: {
- command: "oauth_complete",
- data: {
- state: "state",
- code: "code1",
- closeWindow: "signin",
- },
- },
- },
- });
-
- window.dispatchEvent(event);
- };
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/browser_fxa_oauth.js b/browser/base/content/test/general/browser_fxa_oauth.js
deleted file mode 100644
index 1f688bfa8..000000000
--- a/browser/base/content/test/general/browser_fxa_oauth.js
+++ /dev/null
@@ -1,327 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.docShell is null");
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsOAuthClient",
- "resource://gre/modules/FxAccountsOAuthClient.jsm");
-
-const HTTP_PATH = "http://example.com";
-const HTTP_ENDPOINT = "/browser/browser/base/content/test/general/browser_fxa_oauth.html";
-const HTTP_ENDPOINT_WITH_KEYS = "/browser/browser/base/content/test/general/browser_fxa_oauth_with_keys.html";
-
-var gTests = [
- {
- desc: "FxA OAuth - should open a new tab, complete OAuth flow",
- run: function () {
- return new Promise(function(resolve, reject) {
- let tabOpened = false;
- let properURL = "http://example.com/browser/browser/base/content/test/general/browser_fxa_oauth.html";
- let queryStrings = [
- "action=signin",
- "client_id=client_id",
- "scope=",
- "state=state",
- "webChannelId=oauth_client_id",
- ];
- queryStrings.sort();
-
- waitForTab(function (tab) {
- Assert.ok("Tab successfully opened");
- Assert.ok(gBrowser.currentURI.spec.split("?")[0], properURL, "Check URL without params");
- let actualURL = new URL(gBrowser.currentURI.spec);
- let actualQueryStrings = actualURL.search.substring(1).split("&");
- actualQueryStrings.sort();
- Assert.equal(actualQueryStrings.length, queryStrings.length, "Check number of params");
-
- for (let i = 0; i < queryStrings.length; i++) {
- Assert.equal(actualQueryStrings[i], queryStrings[i], "Check parameter " + i);
- }
-
- tabOpened = true;
- });
-
- let client = new FxAccountsOAuthClient({
- parameters: {
- state: "state",
- client_id: "client_id",
- oauth_uri: HTTP_PATH,
- content_uri: HTTP_PATH,
- },
- authorizationEndpoint: HTTP_ENDPOINT
- });
-
- client.onComplete = function(tokenData) {
- Assert.ok(tabOpened);
- Assert.equal(tokenData.code, "code1");
- Assert.equal(tokenData.state, "state");
- resolve();
- };
-
- client.onError = reject;
-
- client.launchWebFlow();
- });
- }
- },
- {
- desc: "FxA OAuth - should open a new tab, complete OAuth flow when forcing auth",
- run: function () {
- return new Promise(function(resolve, reject) {
- let tabOpened = false;
- let properURL = "http://example.com/browser/browser/base/content/test/general/browser_fxa_oauth.html";
- let queryStrings = [
- "action=force_auth",
- "client_id=client_id",
- "scope=",
- "state=state",
- "webChannelId=oauth_client_id",
- "email=test%40invalid.com",
- ];
- queryStrings.sort();
-
- waitForTab(function (tab) {
- Assert.ok("Tab successfully opened");
- Assert.ok(gBrowser.currentURI.spec.split("?")[0], properURL, "Check URL without params");
-
- let actualURL = new URL(gBrowser.currentURI.spec);
- let actualQueryStrings = actualURL.search.substring(1).split("&");
- actualQueryStrings.sort();
- Assert.equal(actualQueryStrings.length, queryStrings.length, "Check number of params");
-
- for (let i = 0; i < queryStrings.length; i++) {
- Assert.equal(actualQueryStrings[i], queryStrings[i], "Check parameter " + i);
- }
-
- tabOpened = true;
- });
-
- let client = new FxAccountsOAuthClient({
- parameters: {
- state: "state",
- client_id: "client_id",
- oauth_uri: HTTP_PATH,
- content_uri: HTTP_PATH,
- action: "force_auth",
- email: "test@invalid.com"
- },
- authorizationEndpoint: HTTP_ENDPOINT
- });
-
- client.onComplete = function(tokenData) {
- Assert.ok(tabOpened);
- Assert.equal(tokenData.code, "code1");
- Assert.equal(tokenData.state, "state");
- resolve();
- };
-
- client.onError = reject;
-
- client.launchWebFlow();
- });
- }
- },
- {
- desc: "FxA OAuth - should receive an error when there's a state mismatch",
- run: function () {
- return new Promise(function(resolve, reject) {
- let tabOpened = false;
-
- waitForTab(function (tab) {
- Assert.ok("Tab successfully opened");
-
- // It should have passed in the expected non-matching state value.
- let queryString = gBrowser.currentURI.spec.split("?")[1];
- Assert.ok(queryString.indexOf('state=different-state') >= 0);
-
- tabOpened = true;
- });
-
- let client = new FxAccountsOAuthClient({
- parameters: {
- state: "different-state",
- client_id: "client_id",
- oauth_uri: HTTP_PATH,
- content_uri: HTTP_PATH,
- },
- authorizationEndpoint: HTTP_ENDPOINT
- });
-
- client.onComplete = reject;
-
- client.onError = function(err) {
- Assert.ok(tabOpened);
- Assert.equal(err.message, "OAuth flow failed. State doesn't match");
- resolve();
- };
-
- client.launchWebFlow();
- });
- }
- },
- {
- desc: "FxA OAuth - should be able to request keys during OAuth flow",
- run: function () {
- return new Promise(function(resolve, reject) {
- let tabOpened = false;
-
- waitForTab(function (tab) {
- Assert.ok("Tab successfully opened");
-
- // It should have asked for keys.
- let queryString = gBrowser.currentURI.spec.split('?')[1];
- Assert.ok(queryString.indexOf('keys=true') >= 0);
-
- tabOpened = true;
- });
-
- let client = new FxAccountsOAuthClient({
- parameters: {
- state: "state",
- client_id: "client_id",
- oauth_uri: HTTP_PATH,
- content_uri: HTTP_PATH,
- keys: true,
- },
- authorizationEndpoint: HTTP_ENDPOINT_WITH_KEYS
- });
-
- client.onComplete = function(tokenData, keys) {
- Assert.ok(tabOpened);
- Assert.equal(tokenData.code, "code1");
- Assert.equal(tokenData.state, "state");
- Assert.deepEqual(keys.kAr, {k: "kAr"});
- Assert.deepEqual(keys.kBr, {k: "kBr"});
- resolve();
- };
-
- client.onError = reject;
-
- client.launchWebFlow();
- });
- }
- },
- {
- desc: "FxA OAuth - should not receive keys if not explicitly requested",
- run: function () {
- return new Promise(function(resolve, reject) {
- let tabOpened = false;
-
- waitForTab(function (tab) {
- Assert.ok("Tab successfully opened");
-
- // It should not have asked for keys.
- let queryString = gBrowser.currentURI.spec.split('?')[1];
- Assert.ok(queryString.indexOf('keys=true') == -1);
-
- tabOpened = true;
- });
-
- let client = new FxAccountsOAuthClient({
- parameters: {
- state: "state",
- client_id: "client_id",
- oauth_uri: HTTP_PATH,
- content_uri: HTTP_PATH
- },
- // This endpoint will cause the completion message to contain keys.
- authorizationEndpoint: HTTP_ENDPOINT_WITH_KEYS
- });
-
- client.onComplete = function(tokenData, keys) {
- Assert.ok(tabOpened);
- Assert.equal(tokenData.code, "code1");
- Assert.equal(tokenData.state, "state");
- Assert.strictEqual(keys, undefined);
- resolve();
- };
-
- client.onError = reject;
-
- client.launchWebFlow();
- });
- }
- },
- {
- desc: "FxA OAuth - should receive an error if keys could not be obtained",
- run: function () {
- return new Promise(function(resolve, reject) {
- let tabOpened = false;
-
- waitForTab(function (tab) {
- Assert.ok("Tab successfully opened");
-
- // It should have asked for keys.
- let queryString = gBrowser.currentURI.spec.split('?')[1];
- Assert.ok(queryString.indexOf('keys=true') >= 0);
-
- tabOpened = true;
- });
-
- let client = new FxAccountsOAuthClient({
- parameters: {
- state: "state",
- client_id: "client_id",
- oauth_uri: HTTP_PATH,
- content_uri: HTTP_PATH,
- keys: true,
- },
- // This endpoint will cause the completion message not to contain keys.
- authorizationEndpoint: HTTP_ENDPOINT
- });
-
- client.onComplete = reject;
-
- client.onError = function(err) {
- Assert.ok(tabOpened);
- Assert.equal(err.message, "OAuth flow failed. Keys were not returned");
- resolve();
- };
-
- client.launchWebFlow();
- });
- }
- }
-]; // gTests
-
-function waitForTab(aCallback) {
- let container = gBrowser.tabContainer;
- container.addEventListener("TabOpen", function tabOpener(event) {
- container.removeEventListener("TabOpen", tabOpener, false);
- gBrowser.addEventListener("load", function listener() {
- gBrowser.removeEventListener("load", listener, true);
- let tab = event.target;
- aCallback(tab);
- }, true);
- }, false);
-}
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- const webchannelWhitelistPref = "webchannel.allowObject.urlWhitelist";
- let origWhitelist = Services.prefs.getCharPref(webchannelWhitelistPref);
- let newWhitelist = origWhitelist + " http://example.com";
- Services.prefs.setCharPref(webchannelWhitelistPref, newWhitelist);
- try {
- for (let testCase of gTests) {
- info("Running: " + testCase.desc);
- yield testCase.run();
- }
- } finally {
- Services.prefs.clearUserPref(webchannelWhitelistPref);
- }
- }).then(finish, ex => {
- Assert.ok(false, "Unexpected Exception: " + ex);
- finish();
- });
-}
diff --git a/browser/base/content/test/general/browser_fxa_oauth_with_keys.html b/browser/base/content/test/general/browser_fxa_oauth_with_keys.html
deleted file mode 100644
index 2c28f7088..000000000
--- a/browser/base/content/test/general/browser_fxa_oauth_with_keys.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>fxa_oauth_test</title>
-</head>
-<body>
-<script>
- window.onload = function() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- // Note: This intentionally sends a string instead of an object, to ensure both work
- // (see browser_fxa_oauth.html for the other test)
- detail: JSON.stringify({
- id: "oauth_client_id",
- message: {
- command: "oauth_complete",
- data: {
- state: "state",
- code: "code1",
- closeWindow: "signin",
- // Keys normally contain more information, but this is enough
- // to keep Loop's tests happy.
- keys: { kAr: { k: 'kAr' }, kBr: { k: 'kBr' }},
- },
- },
- }),
- });
-
- window.dispatchEvent(event);
- };
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/browser_fxa_web_channel.html b/browser/base/content/test/general/browser_fxa_web_channel.html
deleted file mode 100644
index be5631ff1..000000000
--- a/browser/base/content/test/general/browser_fxa_web_channel.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>fxa_web_channel_test</title>
-</head>
-<body>
-<script>
- var webChannelId = "account_updates_test";
-
- window.onload = function() {
- var testName = window.location.search.replace(/^\?/, "");
-
- switch (testName) {
- case "profile_change":
- test_profile_change();
- break;
- case "login":
- test_login();
- break;
- case "can_link_account":
- test_can_link_account();
- break;
- case "logout":
- test_logout();
- break;
- case "delete":
- test_delete();
- break;
- }
- };
-
- function test_profile_change() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: webChannelId,
- message: {
- command: "profile:change",
- data: {
- uid: "abc123",
- },
- },
- }),
- });
-
- window.dispatchEvent(event);
- }
-
- function test_login() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: webChannelId,
- message: {
- command: "fxaccounts:login",
- data: {
- authAt: Date.now(),
- email: "testuser@testuser.com",
- keyFetchToken: 'key_fetch_token',
- sessionToken: 'session_token',
- uid: 'uid',
- unwrapBKey: 'unwrap_b_key',
- verified: true,
- },
- messageId: 1,
- },
- }),
- });
-
- window.dispatchEvent(event);
- }
-
- function test_can_link_account() {
- window.addEventListener("WebChannelMessageToContent", function (e) {
- // echo any responses from the browser back to the tests on the
- // fxaccounts_webchannel_response_echo WebChannel. The tests are
- // listening for events and do the appropriate checks.
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: 'fxaccounts_webchannel_response_echo',
- message: e.detail.message,
- })
- });
-
- window.dispatchEvent(event);
- }, true);
-
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: webChannelId,
- message: {
- command: "fxaccounts:can_link_account",
- data: {
- email: "testuser@testuser.com",
- },
- messageId: 2,
- },
- }),
- });
-
- window.dispatchEvent(event);
- }
-
- function test_logout() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: webChannelId,
- message: {
- command: "fxaccounts:logout",
- data: {
- uid: 'uid'
- },
- messageId: 3,
- },
- }),
- });
-
- window.dispatchEvent(event);
- }
-
- function test_delete() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: webChannelId,
- message: {
- command: "fxaccounts:delete",
- data: {
- uid: 'uid'
- },
- messageId: 4,
- },
- }),
- });
-
- window.dispatchEvent(event);
- }
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/browser_fxa_web_channel.js b/browser/base/content/test/general/browser_fxa_web_channel.js
deleted file mode 100644
index eb0167ffb..000000000
--- a/browser/base/content/test/general/browser_fxa_web_channel.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
- return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {});
-});
-
-XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
- "resource://gre/modules/WebChannel.jsm");
-
-// FxAccountsWebChannel isn't explicitly exported by FxAccountsWebChannel.jsm
-// but we can get it here via a backstage pass.
-var {FxAccountsWebChannel} = Components.utils.import("resource://gre/modules/FxAccountsWebChannel.jsm", {});
-
-const TEST_HTTP_PATH = "http://example.com";
-const TEST_BASE_URL = TEST_HTTP_PATH + "/browser/browser/base/content/test/general/browser_fxa_web_channel.html";
-const TEST_CHANNEL_ID = "account_updates_test";
-
-var gTests = [
- {
- desc: "FxA Web Channel - should receive message about profile changes",
- run: function* () {
- let client = new FxAccountsWebChannel({
- content_uri: TEST_HTTP_PATH,
- channel_id: TEST_CHANNEL_ID,
- });
- let promiseObserver = new Promise((resolve, reject) => {
- makeObserver(FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION, function (subject, topic, data) {
- Assert.equal(data, "abc123");
- client.tearDown();
- resolve();
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: TEST_BASE_URL + "?profile_change"
- }, function* () {
- yield promiseObserver;
- });
- }
- },
- {
- desc: "fxa web channel - login messages should notify the fxAccounts object",
- run: function* () {
-
- let promiseLogin = new Promise((resolve, reject) => {
- let login = (accountData) => {
- Assert.equal(typeof accountData.authAt, 'number');
- Assert.equal(accountData.email, 'testuser@testuser.com');
- Assert.equal(accountData.keyFetchToken, 'key_fetch_token');
- Assert.equal(accountData.sessionToken, 'session_token');
- Assert.equal(accountData.uid, 'uid');
- Assert.equal(accountData.unwrapBKey, 'unwrap_b_key');
- Assert.equal(accountData.verified, true);
-
- client.tearDown();
- resolve();
- };
-
- let client = new FxAccountsWebChannel({
- content_uri: TEST_HTTP_PATH,
- channel_id: TEST_CHANNEL_ID,
- helpers: {
- login: login
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: TEST_BASE_URL + "?login"
- }, function* () {
- yield promiseLogin;
- });
- }
- },
- {
- desc: "fxa web channel - can_link_account messages should respond",
- run: function* () {
- let properUrl = TEST_BASE_URL + "?can_link_account";
-
- let promiseEcho = new Promise((resolve, reject) => {
-
- let webChannelOrigin = Services.io.newURI(properUrl, null, null);
- // responses sent to content are echoed back over the
- // `fxaccounts_webchannel_response_echo` channel. Ensure the
- // fxaccounts:can_link_account message is responded to.
- let echoWebChannel = new WebChannel('fxaccounts_webchannel_response_echo', webChannelOrigin);
- echoWebChannel.listen((webChannelId, message, target) => {
- Assert.equal(message.command, 'fxaccounts:can_link_account');
- Assert.equal(message.messageId, 2);
- Assert.equal(message.data.ok, true);
-
- client.tearDown();
- echoWebChannel.stopListening();
-
- resolve();
- });
-
- let client = new FxAccountsWebChannel({
- content_uri: TEST_HTTP_PATH,
- channel_id: TEST_CHANNEL_ID,
- helpers: {
- shouldAllowRelink(acctName) {
- return acctName === 'testuser@testuser.com';
- }
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: properUrl
- }, function* () {
- yield promiseEcho;
- });
- }
- },
- {
- desc: "fxa web channel - logout messages should notify the fxAccounts object",
- run: function* () {
- let promiseLogout = new Promise((resolve, reject) => {
- let logout = (uid) => {
- Assert.equal(uid, 'uid');
-
- client.tearDown();
- resolve();
- };
-
- let client = new FxAccountsWebChannel({
- content_uri: TEST_HTTP_PATH,
- channel_id: TEST_CHANNEL_ID,
- helpers: {
- logout: logout
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: TEST_BASE_URL + "?logout"
- }, function* () {
- yield promiseLogout;
- });
- }
- },
- {
- desc: "fxa web channel - delete messages should notify the fxAccounts object",
- run: function* () {
- let promiseDelete = new Promise((resolve, reject) => {
- let logout = (uid) => {
- Assert.equal(uid, 'uid');
-
- client.tearDown();
- resolve();
- };
-
- let client = new FxAccountsWebChannel({
- content_uri: TEST_HTTP_PATH,
- channel_id: TEST_CHANNEL_ID,
- helpers: {
- logout: logout
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: TEST_BASE_URL + "?delete"
- }, function* () {
- yield promiseDelete;
- });
- }
- }
-]; // gTests
-
-function makeObserver(aObserveTopic, aObserveFunc) {
- let callback = function (aSubject, aTopic, aData) {
- if (aTopic == aObserveTopic) {
- removeMe();
- aObserveFunc(aSubject, aTopic, aData);
- }
- };
-
- function removeMe() {
- Services.obs.removeObserver(callback, aObserveTopic);
- }
-
- Services.obs.addObserver(callback, aObserveTopic, false);
- return removeMe;
-}
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- for (let testCase of gTests) {
- info("Running: " + testCase.desc);
- yield testCase.run();
- }
- }).then(finish, ex => {
- Assert.ok(false, "Unexpected Exception: " + ex);
- finish();
- });
-}
diff --git a/browser/base/content/test/general/browser_fxaccounts.js b/browser/base/content/test/general/browser_fxaccounts.js
deleted file mode 100644
index 0f68286dc..000000000
--- a/browser/base/content/test/general/browser_fxaccounts.js
+++ /dev/null
@@ -1,261 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var {Log} = Cu.import("resource://gre/modules/Log.jsm", {});
-var {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
-var {fxAccounts} = Cu.import("resource://gre/modules/FxAccounts.jsm", {});
-var FxAccountsCommon = {};
-Cu.import("resource://gre/modules/FxAccountsCommon.js", FxAccountsCommon);
-
-const TEST_ROOT = "http://example.com/browser/browser/base/content/test/general/";
-
-// instrument gFxAccounts to send observer notifications when it's done
-// what it does.
-(function() {
- let unstubs = {}; // The original functions we stub out.
-
- // The stub functions.
- let stubs = {
- updateAppMenuItem: function() {
- return unstubs['updateAppMenuItem'].call(gFxAccounts).then(() => {
- Services.obs.notifyObservers(null, "test:browser_fxaccounts:updateAppMenuItem", null);
- });
- },
- // Opening preferences is trickier than it should be as leaks are reported
- // due to the promises it fires off at load time and there's no clear way to
- // know when they are done.
- // So just ensure openPreferences is called rather than whether it opens.
- openPreferences: function() {
- Services.obs.notifyObservers(null, "test:browser_fxaccounts:openPreferences", null);
- }
- };
-
- for (let name in stubs) {
- unstubs[name] = gFxAccounts[name];
- gFxAccounts[name] = stubs[name];
- }
- // and undo our damage at the end.
- registerCleanupFunction(() => {
- for (let name in unstubs) {
- gFxAccounts[name] = unstubs[name];
- }
- stubs = unstubs = null;
- });
-})();
-
-// Other setup/cleanup
-var newTab;
-
-Services.prefs.setCharPref("identity.fxaccounts.remote.signup.uri",
- TEST_ROOT + "accounts_testRemoteCommands.html");
-
-registerCleanupFunction(() => {
- Services.prefs.clearUserPref("identity.fxaccounts.remote.signup.uri");
- Services.prefs.clearUserPref("identity.fxaccounts.remote.profile.uri");
- gBrowser.removeTab(newTab);
-});
-
-add_task(function* initialize() {
- // Set a new tab with something other than about:blank, so it doesn't get reused.
- // We must wait for it to load or the promiseTabOpen() call in the next test
- // gets confused.
- newTab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla", {animate: false});
- yield promiseTabLoaded(newTab);
-});
-
-// The elements we care about.
-var panelUILabel = document.getElementById("PanelUI-fxa-label");
-var panelUIStatus = document.getElementById("PanelUI-fxa-status");
-var panelUIFooter = document.getElementById("PanelUI-footer-fxa");
-
-// The tests
-add_task(function* test_nouser() {
- let user = yield fxAccounts.getSignedInUser();
- Assert.strictEqual(user, null, "start with no user signed in");
- let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem");
- Services.obs.notifyObservers(null, this.FxAccountsCommon.ONLOGOUT_NOTIFICATION, null);
- yield promiseUpdateDone;
-
- // Check the world - the FxA footer area is visible as it is offering a signin.
- Assert.ok(isFooterVisible())
-
- Assert.equal(panelUILabel.getAttribute("label"), panelUIStatus.getAttribute("defaultlabel"));
- Assert.equal(panelUIStatus.getAttribute("tooltiptext"), panelUIStatus.getAttribute("signedinTooltiptext"));
- Assert.ok(!panelUIFooter.hasAttribute("fxastatus"), "no fxsstatus when signed out");
- Assert.ok(!panelUIFooter.hasAttribute("fxaprofileimage"), "no fxaprofileimage when signed out");
-
- let promisePreferencesOpened = promiseObserver("test:browser_fxaccounts:openPreferences");
- panelUIStatus.click();
- yield promisePreferencesOpened;
-});
-
-/*
-XXX - Bug 1191162 - need a better hawk mock story or this will leak in debug builds.
-
-add_task(function* test_unverifiedUser() {
- let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem");
- yield setSignedInUser(false); // this will fire the observer that does the update.
- yield promiseUpdateDone;
-
- // Check the world.
- Assert.ok(isFooterVisible())
-
- Assert.equal(panelUILabel.getAttribute("label"), "foo@example.com");
- Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
- panelUIStatus.getAttribute("signedinTooltiptext"));
- Assert.equal(panelUIFooter.getAttribute("fxastatus"), "signedin");
- let promisePreferencesOpened = promiseObserver("test:browser_fxaccounts:openPreferences");
- panelUIStatus.click();
- yield promisePreferencesOpened
- yield signOut();
-});
-*/
-
-add_task(function* test_verifiedUserEmptyProfile() {
- // We see 2 updateAppMenuItem() calls - one for the signedInUser and one after
- // we first fetch the profile. We want them both to fire or we aren't testing
- // the state we think we are testing.
- let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem", 2);
- gFxAccounts._cachedProfile = null;
- configureProfileURL({}); // successful but empty profile.
- yield setSignedInUser(true); // this will fire the observer that does the update.
- yield promiseUpdateDone;
-
- // Check the world.
- Assert.ok(isFooterVisible())
- Assert.equal(panelUILabel.getAttribute("label"), "foo@example.com");
- Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
- panelUIStatus.getAttribute("signedinTooltiptext"));
- Assert.equal(panelUIFooter.getAttribute("fxastatus"), "signedin");
-
- let promisePreferencesOpened = promiseObserver("test:browser_fxaccounts:openPreferences");
- panelUIStatus.click();
- yield promisePreferencesOpened;
- yield signOut();
-});
-
-add_task(function* test_verifiedUserDisplayName() {
- let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem", 2);
- gFxAccounts._cachedProfile = null;
- configureProfileURL({ displayName: "Test User Display Name" });
- yield setSignedInUser(true); // this will fire the observer that does the update.
- yield promiseUpdateDone;
-
- Assert.ok(isFooterVisible())
- Assert.equal(panelUILabel.getAttribute("label"), "Test User Display Name");
- Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
- panelUIStatus.getAttribute("signedinTooltiptext"));
- Assert.equal(panelUIFooter.getAttribute("fxastatus"), "signedin");
- yield signOut();
-});
-
-add_task(function* test_verifiedUserProfileFailure() {
- // profile failure means only one observer fires.
- let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem", 1);
- gFxAccounts._cachedProfile = null;
- configureProfileURL(null, 500);
- yield setSignedInUser(true); // this will fire the observer that does the update.
- yield promiseUpdateDone;
-
- Assert.ok(isFooterVisible())
- Assert.equal(panelUILabel.getAttribute("label"), "foo@example.com");
- Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
- panelUIStatus.getAttribute("signedinTooltiptext"));
- Assert.equal(panelUIFooter.getAttribute("fxastatus"), "signedin");
- yield signOut();
-});
-
-// Helpers.
-function isFooterVisible() {
- let style = window.getComputedStyle(panelUIFooter);
- return style.getPropertyValue("display") == "flex";
-}
-
-function configureProfileURL(profile, responseStatus = 200) {
- let responseBody = profile ? JSON.stringify(profile) : "";
- let url = TEST_ROOT + "fxa_profile_handler.sjs?" +
- "responseStatus=" + responseStatus +
- "responseBody=" + responseBody +
- // This is a bit cheeky - the FxA code will just append "/profile"
- // to the preference value. We arrange for this to be seen by our
- // .sjs as part of the query string.
- "&path=";
-
- Services.prefs.setCharPref("identity.fxaccounts.remote.profile.uri", url);
-}
-
-function promiseObserver(topic, count = 1) {
- return new Promise(resolve => {
- let obs = (aSubject, aTopic, aData) => {
- if (--count == 0) {
- Services.obs.removeObserver(obs, aTopic);
- resolve(aSubject);
- }
- }
- Services.obs.addObserver(obs, topic, false);
- });
-}
-
-// Stolen from browser_aboutHome.js
-function promiseWaitForEvent(node, type, capturing) {
- return new Promise((resolve) => {
- node.addEventListener(type, function listener(event) {
- node.removeEventListener(type, listener, capturing);
- resolve(event);
- }, capturing);
- });
-}
-
-var promiseTabOpen = Task.async(function*(urlBase) {
- info("Waiting for tab to open...");
- let event = yield promiseWaitForEvent(gBrowser.tabContainer, "TabOpen", true);
- let tab = event.target;
- yield promiseTabLoadEvent(tab);
- ok(tab.linkedBrowser.currentURI.spec.startsWith(urlBase),
- "Got " + tab.linkedBrowser.currentURI.spec + ", expecting " + urlBase);
- let whenUnloaded = promiseTabUnloaded(tab);
- gBrowser.removeTab(tab);
- yield whenUnloaded;
-});
-
-function promiseTabUnloaded(tab)
-{
- return new Promise(resolve => {
- info("Wait for tab to unload");
- function handle(event) {
- tab.linkedBrowser.removeEventListener("unload", handle, true);
- info("Got unload event");
- resolve(event);
- }
- tab.linkedBrowser.addEventListener("unload", handle, true, true);
- });
-}
-
-// FxAccounts helpers.
-function setSignedInUser(verified) {
- let data = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- assertion: "foobar",
- sessionToken: "dead",
- kA: "beef",
- kB: "cafe",
- verified: verified,
-
- oauthTokens: {
- // a token for the profile server.
- profile: "key value",
- }
- }
- return fxAccounts.setSignedInUser(data);
-}
-
-var signOut = Task.async(function* () {
- // This test needs to make sure that any updates for the logout have
- // completed before starting the next test, or we see the observer
- // notifications get out of sync.
- let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem");
- // we always want a "localOnly" signout here...
- yield fxAccounts.signOut(true);
- yield promiseUpdateDone;
-});
diff --git a/browser/base/content/test/general/browser_gZipOfflineChild.js b/browser/base/content/test/general/browser_gZipOfflineChild.js
deleted file mode 100644
index 09691bed8..000000000
--- a/browser/base/content/test/general/browser_gZipOfflineChild.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const URL = "http://mochi.test:8888/browser/browser/base/content/test/general/test_offline_gzip.html"
-
-registerCleanupFunction(function() {
- // Clean up after ourself
- let uri = Services.io.newURI(URL, null, null);
- let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
- Services.perms.removeFromPrincipal(principal, "offline-app");
- Services.prefs.clearUserPref("offline-apps.allow_by_default");
-});
-
-var cacheCount = 0;
-var intervalID = 0;
-
-//
-// Handle "message" events which are posted from the iframe upon
-// offline cache events.
-//
-function handleMessageEvents(event) {
- cacheCount++;
- switch (cacheCount) {
- case 1:
- // This is the initial caching off offline data.
- is(event.data, "oncache", "Child was successfully cached.");
- // Reload the frame; this will generate an error message
- // in the case of bug 501422.
- event.source.location.reload();
- // Use setInterval to repeatedly call a function which
- // checks that one of two things has occurred: either
- // the offline cache is udpated (which means our iframe
- // successfully reloaded), or the string "error" appears
- // in the iframe, as in the case of bug 501422.
- intervalID = setInterval(function() {
- // Sometimes document.body may not exist, and trying to access
- // it will throw an exception, so handle this case.
- try {
- var bodyInnerHTML = event.source.document.body.innerHTML;
- }
- catch (e) {
- bodyInnerHTML = "";
- }
- if (cacheCount == 2 || bodyInnerHTML.includes("error")) {
- clearInterval(intervalID);
- is(cacheCount, 2, "frame not reloaded successfully");
- if (cacheCount != 2) {
- finish();
- }
- }
- }, 100);
- break;
- case 2:
- is(event.data, "onupdate", "Child was successfully updated.");
- clearInterval(intervalID);
- finish();
- break;
- default:
- // how'd we get here?
- ok(false, "cacheCount not 1 or 2");
- }
-}
-
-function test() {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref("offline-apps.allow_by_default", true);
-
- // Open a new tab.
- gBrowser.selectedTab = gBrowser.addTab(URL);
- registerCleanupFunction(() => gBrowser.removeCurrentTab());
-
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
- let window = gBrowser.selectedBrowser.contentWindow;
-
- window.addEventListener("message", handleMessageEvents, false);
- });
-}
diff --git a/browser/base/content/test/general/browser_gestureSupport.js b/browser/base/content/test/general/browser_gestureSupport.js
deleted file mode 100644
index b31cad31d..000000000
--- a/browser/base/content/test/general/browser_gestureSupport.js
+++ /dev/null
@@ -1,670 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Simple gestures tests
-//
-// These tests require the ability to disable the fact that the
-// Firefox chrome intentionally prevents "simple gesture" events from
-// reaching web content.
-
-var test_utils;
-var test_commandset;
-var test_prefBranch = "browser.gesture.";
-
-function test()
-{
- waitForExplicitFinish();
-
- // Disable the default gestures support during the test
- gGestureSupport.init(false);
-
- test_utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
- getInterface(Components.interfaces.nsIDOMWindowUtils);
-
- // Run the tests of "simple gesture" events generally
- test_EnsureConstantsAreDisjoint();
- test_TestEventListeners();
- test_TestEventCreation();
-
- // Reenable the default gestures support. The remaining tests target
- // the Firefox gesture functionality.
- gGestureSupport.init(true);
-
- // Test Firefox's gestures support.
- test_commandset = document.getElementById("mainCommandSet");
- test_swipeGestures();
- test_latchedGesture("pinch", "out", "in", "MozMagnifyGesture");
- test_thresholdGesture("pinch", "out", "in", "MozMagnifyGesture");
- test_rotateGestures();
-}
-
-var test_eventCount = 0;
-var test_expectedType;
-var test_expectedDirection;
-var test_expectedDelta;
-var test_expectedModifiers;
-var test_expectedClickCount;
-var test_imageTab;
-
-function test_gestureListener(evt)
-{
- is(evt.type, test_expectedType,
- "evt.type (" + evt.type + ") does not match expected value");
- is(evt.target, test_utils.elementFromPoint(20, 20, false, false),
- "evt.target (" + evt.target + ") does not match expected value");
- is(evt.clientX, 20,
- "evt.clientX (" + evt.clientX + ") does not match expected value");
- is(evt.clientY, 20,
- "evt.clientY (" + evt.clientY + ") does not match expected value");
- isnot(evt.screenX, 0,
- "evt.screenX (" + evt.screenX + ") does not match expected value");
- isnot(evt.screenY, 0,
- "evt.screenY (" + evt.screenY + ") does not match expected value");
-
- is(evt.direction, test_expectedDirection,
- "evt.direction (" + evt.direction + ") does not match expected value");
- is(evt.delta, test_expectedDelta,
- "evt.delta (" + evt.delta + ") does not match expected value");
-
- is(evt.shiftKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.SHIFT_MASK) != 0,
- "evt.shiftKey did not match expected value");
- is(evt.ctrlKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.CONTROL_MASK) != 0,
- "evt.ctrlKey did not match expected value");
- is(evt.altKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.ALT_MASK) != 0,
- "evt.altKey did not match expected value");
- is(evt.metaKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.META_MASK) != 0,
- "evt.metaKey did not match expected value");
-
- if (evt.type == "MozTapGesture") {
- is(evt.clickCount, test_expectedClickCount, "evt.clickCount does not match");
- }
-
- test_eventCount++;
-}
-
-function test_helper1(type, direction, delta, modifiers)
-{
- // Setup the expected values
- test_expectedType = type;
- test_expectedDirection = direction;
- test_expectedDelta = delta;
- test_expectedModifiers = modifiers;
-
- let expectedEventCount = test_eventCount + 1;
-
- document.addEventListener(type, test_gestureListener, true);
- test_utils.sendSimpleGestureEvent(type, 20, 20, direction, delta, modifiers);
- document.removeEventListener(type, test_gestureListener, true);
-
- is(expectedEventCount, test_eventCount, "Event (" + type + ") was never received by event listener");
-}
-
-function test_clicks(type, clicks)
-{
- // Setup the expected values
- test_expectedType = type;
- test_expectedDirection = 0;
- test_expectedDelta = 0;
- test_expectedModifiers = 0;
- test_expectedClickCount = clicks;
-
- let expectedEventCount = test_eventCount + 1;
-
- document.addEventListener(type, test_gestureListener, true);
- test_utils.sendSimpleGestureEvent(type, 20, 20, 0, 0, 0, clicks);
- document.removeEventListener(type, test_gestureListener, true);
-
- is(expectedEventCount, test_eventCount, "Event (" + type + ") was never received by event listener");
-}
-
-function test_TestEventListeners()
-{
- let e = test_helper1; // easier to type this name
-
- // Swipe gesture animation events
- e("MozSwipeGestureStart", 0, -0.7, 0);
- e("MozSwipeGestureUpdate", 0, -0.4, 0);
- e("MozSwipeGestureEnd", 0, 0, 0);
- e("MozSwipeGestureStart", 0, 0.6, 0);
- e("MozSwipeGestureUpdate", 0, 0.3, 0);
- e("MozSwipeGestureEnd", 0, 1, 0);
-
- // Swipe gesture event
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_LEFT, 0.0, 0);
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0.0, 0);
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_UP, 0.0, 0);
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_DOWN, 0.0, 0);
- e("MozSwipeGesture",
- SimpleGestureEvent.DIRECTION_UP | SimpleGestureEvent.DIRECTION_LEFT, 0.0, 0);
- e("MozSwipeGesture",
- SimpleGestureEvent.DIRECTION_DOWN | SimpleGestureEvent.DIRECTION_RIGHT, 0.0, 0);
- e("MozSwipeGesture",
- SimpleGestureEvent.DIRECTION_UP | SimpleGestureEvent.DIRECTION_RIGHT, 0.0, 0);
- e("MozSwipeGesture",
- SimpleGestureEvent.DIRECTION_DOWN | SimpleGestureEvent.DIRECTION_LEFT, 0.0, 0);
-
- // magnify gesture events
- e("MozMagnifyGestureStart", 0, 50.0, 0);
- e("MozMagnifyGestureUpdate", 0, -25.0, 0);
- e("MozMagnifyGestureUpdate", 0, 5.0, 0);
- e("MozMagnifyGesture", 0, 30.0, 0);
-
- // rotate gesture events
- e("MozRotateGestureStart", SimpleGestureEvent.ROTATION_CLOCKWISE, 33.0, 0);
- e("MozRotateGestureUpdate", SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE, -13.0, 0);
- e("MozRotateGestureUpdate", SimpleGestureEvent.ROTATION_CLOCKWISE, 13.0, 0);
- e("MozRotateGesture", SimpleGestureEvent.ROTATION_CLOCKWISE, 33.0, 0);
-
- // Tap and presstap gesture events
- test_clicks("MozTapGesture", 1);
- test_clicks("MozTapGesture", 2);
- test_clicks("MozTapGesture", 3);
- test_clicks("MozPressTapGesture", 1);
-
- // simple delivery test for edgeui gestures
- e("MozEdgeUIStarted", 0, 0, 0);
- e("MozEdgeUICanceled", 0, 0, 0);
- e("MozEdgeUICompleted", 0, 0, 0);
-
- // event.shiftKey
- let modifier = Components.interfaces.nsIDOMEvent.SHIFT_MASK;
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
-
- // event.metaKey
- modifier = Components.interfaces.nsIDOMEvent.META_MASK;
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
-
- // event.altKey
- modifier = Components.interfaces.nsIDOMEvent.ALT_MASK;
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
-
- // event.ctrlKey
- modifier = Components.interfaces.nsIDOMEvent.CONTROL_MASK;
- e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier);
-}
-
-function test_eventDispatchListener(evt)
-{
- test_eventCount++;
- evt.stopPropagation();
-}
-
-function test_helper2(type, direction, delta, altKey, ctrlKey, shiftKey, metaKey)
-{
- let event = null;
- let successful;
-
- try {
- event = document.createEvent("SimpleGestureEvent");
- successful = true;
- }
- catch (ex) {
- successful = false;
- }
- ok(successful, "Unable to create SimpleGestureEvent");
-
- try {
- event.initSimpleGestureEvent(type, true, true, window, 1,
- 10, 10, 10, 10,
- ctrlKey, altKey, shiftKey, metaKey,
- 1, window,
- 0, direction, delta, 0);
- successful = true;
- }
- catch (ex) {
- successful = false;
- }
- ok(successful, "event.initSimpleGestureEvent should not fail");
-
- // Make sure the event fields match the expected values
- is(event.type, type, "Mismatch on evt.type");
- is(event.direction, direction, "Mismatch on evt.direction");
- is(event.delta, delta, "Mismatch on evt.delta");
- is(event.altKey, altKey, "Mismatch on evt.altKey");
- is(event.ctrlKey, ctrlKey, "Mismatch on evt.ctrlKey");
- is(event.shiftKey, shiftKey, "Mismatch on evt.shiftKey");
- is(event.metaKey, metaKey, "Mismatch on evt.metaKey");
- is(event.view, window, "Mismatch on evt.view");
- is(event.detail, 1, "Mismatch on evt.detail");
- is(event.clientX, 10, "Mismatch on evt.clientX");
- is(event.clientY, 10, "Mismatch on evt.clientY");
- is(event.screenX, 10, "Mismatch on evt.screenX");
- is(event.screenY, 10, "Mismatch on evt.screenY");
- is(event.button, 1, "Mismatch on evt.button");
- is(event.relatedTarget, window, "Mismatch on evt.relatedTarget");
-
- // Test event dispatch
- let expectedEventCount = test_eventCount + 1;
- document.addEventListener(type, test_eventDispatchListener, true);
- document.dispatchEvent(event);
- document.removeEventListener(type, test_eventDispatchListener, true);
- is(expectedEventCount, test_eventCount, "Dispatched event was never received by listener");
-}
-
-function test_TestEventCreation()
-{
- // Event creation
- test_helper2("MozMagnifyGesture", SimpleGestureEvent.DIRECTION_RIGHT, 20.0,
- true, false, true, false);
- test_helper2("MozMagnifyGesture", SimpleGestureEvent.DIRECTION_LEFT, -20.0,
- false, true, false, true);
-}
-
-function test_EnsureConstantsAreDisjoint()
-{
- let up = SimpleGestureEvent.DIRECTION_UP;
- let down = SimpleGestureEvent.DIRECTION_DOWN;
- let left = SimpleGestureEvent.DIRECTION_LEFT;
- let right = SimpleGestureEvent.DIRECTION_RIGHT;
-
- let clockwise = SimpleGestureEvent.ROTATION_CLOCKWISE;
- let cclockwise = SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE;
-
- ok(up ^ down, "DIRECTION_UP and DIRECTION_DOWN are not bitwise disjoint");
- ok(up ^ left, "DIRECTION_UP and DIRECTION_LEFT are not bitwise disjoint");
- ok(up ^ right, "DIRECTION_UP and DIRECTION_RIGHT are not bitwise disjoint");
- ok(down ^ left, "DIRECTION_DOWN and DIRECTION_LEFT are not bitwise disjoint");
- ok(down ^ right, "DIRECTION_DOWN and DIRECTION_RIGHT are not bitwise disjoint");
- ok(left ^ right, "DIRECTION_LEFT and DIRECTION_RIGHT are not bitwise disjoint");
- ok(clockwise ^ cclockwise, "ROTATION_CLOCKWISE and ROTATION_COUNTERCLOCKWISE are not bitwise disjoint");
-}
-
-// Helper for test of latched event processing. Emits the actual
-// gesture events to test whether the commands associated with the
-// gesture will only trigger once for each direction of movement.
-function test_emitLatchedEvents(eventPrefix, initialDelta, cmd)
-{
- let cumulativeDelta = 0;
- let isIncreasing = initialDelta > 0;
-
- let expect = {};
- // Reset the call counters and initialize expected values
- for (let dir in cmd)
- cmd[dir].callCount = expect[dir] = 0;
-
- let check = (aDir, aMsg) => ok(cmd[aDir].callCount == expect[aDir], aMsg);
- let checkBoth = function(aNum, aInc, aDec) {
- let prefix = "Step " + aNum + ": ";
- check("inc", prefix + aInc);
- check("dec", prefix + aDec);
- };
-
- // Send the "Start" event.
- test_utils.sendSimpleGestureEvent(eventPrefix + "Start", 0, 0, 0, initialDelta, 0);
- cumulativeDelta += initialDelta;
- if (isIncreasing) {
- expect.inc++;
- checkBoth(1, "Increasing command was not triggered", "Decreasing command was triggered");
- } else {
- expect.dec++;
- checkBoth(1, "Increasing command was triggered", "Decreasing command was not triggered");
- }
-
- // Send random values in the same direction and ensure neither
- // command triggers.
- for (let i = 0; i < 5; i++) {
- let delta = Math.random() * (isIncreasing ? 100 : -100);
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, delta, 0);
- cumulativeDelta += delta;
- checkBoth(2, "Increasing command was triggered", "Decreasing command was triggered");
- }
-
- // Now go back in the opposite direction.
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0,
- - initialDelta, 0);
- cumulativeDelta += - initialDelta;
- if (isIncreasing) {
- expect.dec++;
- checkBoth(3, "Increasing command was triggered", "Decreasing command was not triggered");
- } else {
- expect.inc++;
- checkBoth(3, "Increasing command was not triggered", "Decreasing command was triggered");
- }
-
- // Send random values in the opposite direction and ensure neither
- // command triggers.
- for (let i = 0; i < 5; i++) {
- let delta = Math.random() * (isIncreasing ? -100 : 100);
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, delta, 0);
- cumulativeDelta += delta;
- checkBoth(4, "Increasing command was triggered", "Decreasing command was triggered");
- }
-
- // Go back to the original direction. The original command should trigger.
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0,
- initialDelta, 0);
- cumulativeDelta += initialDelta;
- if (isIncreasing) {
- expect.inc++;
- checkBoth(5, "Increasing command was not triggered", "Decreasing command was triggered");
- } else {
- expect.dec++;
- checkBoth(5, "Increasing command was triggered", "Decreasing command was not triggered");
- }
-
- // Send the wrap-up event. No commands should be triggered.
- test_utils.sendSimpleGestureEvent(eventPrefix, 0, 0, 0, cumulativeDelta, 0);
- checkBoth(6, "Increasing command was triggered", "Decreasing command was triggered");
-}
-
-function test_addCommand(prefName, id)
-{
- let cmd = test_commandset.appendChild(document.createElement("command"));
- cmd.setAttribute("id", id);
- cmd.setAttribute("oncommand", "this.callCount++;");
-
- cmd.origPrefName = prefName;
- cmd.origPrefValue = gPrefService.getCharPref(prefName);
- gPrefService.setCharPref(prefName, id);
-
- return cmd;
-}
-
-function test_removeCommand(cmd)
-{
- gPrefService.setCharPref(cmd.origPrefName, cmd.origPrefValue);
- test_commandset.removeChild(cmd);
-}
-
-// Test whether latched events are only called once per direction of motion.
-function test_latchedGesture(gesture, inc, dec, eventPrefix)
-{
- let branch = test_prefBranch + gesture + ".";
-
- // Put the gesture into latched mode.
- let oldLatchedValue = gPrefService.getBoolPref(branch + "latched");
- gPrefService.setBoolPref(branch + "latched", true);
-
- // Install the test commands for increasing and decreasing motion.
- let cmd = {
- inc: test_addCommand(branch + inc, "test:incMotion"),
- dec: test_addCommand(branch + dec, "test:decMotion"),
- };
-
- // Test the gestures in each direction.
- test_emitLatchedEvents(eventPrefix, 500, cmd);
- test_emitLatchedEvents(eventPrefix, -500, cmd);
-
- // Restore the gesture to its original configuration.
- gPrefService.setBoolPref(branch + "latched", oldLatchedValue);
- for (let dir in cmd)
- test_removeCommand(cmd[dir]);
-}
-
-// Test whether non-latched events are triggered upon sufficient motion.
-function test_thresholdGesture(gesture, inc, dec, eventPrefix)
-{
- let branch = test_prefBranch + gesture + ".";
-
- // Disable latched mode for this gesture.
- let oldLatchedValue = gPrefService.getBoolPref(branch + "latched");
- gPrefService.setBoolPref(branch + "latched", false);
-
- // Set the triggering threshold value to 50.
- let oldThresholdValue = gPrefService.getIntPref(branch + "threshold");
- gPrefService.setIntPref(branch + "threshold", 50);
-
- // Install the test commands for increasing and decreasing motion.
- let cmdInc = test_addCommand(branch + inc, "test:incMotion");
- let cmdDec = test_addCommand(branch + dec, "test:decMotion");
-
- // Send the start event but stop short of triggering threshold.
- cmdInc.callCount = cmdDec.callCount = 0;
- test_utils.sendSimpleGestureEvent(eventPrefix + "Start", 0, 0, 0, 49.5, 0);
- ok(cmdInc.callCount == 0, "Increasing command was triggered");
- ok(cmdDec.callCount == 0, "Decreasing command was triggered");
-
- // Now trigger the threshold.
- cmdInc.callCount = cmdDec.callCount = 0;
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, 1, 0);
- ok(cmdInc.callCount == 1, "Increasing command was not triggered");
- ok(cmdDec.callCount == 0, "Decreasing command was triggered");
-
- // The tracking counter should go to zero. Go back the other way and
- // stop short of triggering the threshold.
- cmdInc.callCount = cmdDec.callCount = 0;
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, -49.5, 0);
- ok(cmdInc.callCount == 0, "Increasing command was triggered");
- ok(cmdDec.callCount == 0, "Decreasing command was triggered");
-
- // Now cross the threshold and trigger the decreasing command.
- cmdInc.callCount = cmdDec.callCount = 0;
- test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, -1.5, 0);
- ok(cmdInc.callCount == 0, "Increasing command was triggered");
- ok(cmdDec.callCount == 1, "Decreasing command was not triggered");
-
- // Send the wrap-up event. No commands should trigger.
- cmdInc.callCount = cmdDec.callCount = 0;
- test_utils.sendSimpleGestureEvent(eventPrefix, 0, 0, 0, -0.5, 0);
- ok(cmdInc.callCount == 0, "Increasing command was triggered");
- ok(cmdDec.callCount == 0, "Decreasing command was triggered");
-
- // Restore the gesture to its original configuration.
- gPrefService.setBoolPref(branch + "latched", oldLatchedValue);
- gPrefService.setIntPref(branch + "threshold", oldThresholdValue);
- test_removeCommand(cmdInc);
- test_removeCommand(cmdDec);
-}
-
-function test_swipeGestures()
-{
- // easier to type names for the direction constants
- let up = SimpleGestureEvent.DIRECTION_UP;
- let down = SimpleGestureEvent.DIRECTION_DOWN;
- let left = SimpleGestureEvent.DIRECTION_LEFT;
- let right = SimpleGestureEvent.DIRECTION_RIGHT;
-
- let branch = test_prefBranch + "swipe.";
-
- // Install the test commands for the swipe gestures.
- let cmdUp = test_addCommand(branch + "up", "test:swipeUp");
- let cmdDown = test_addCommand(branch + "down", "test:swipeDown");
- let cmdLeft = test_addCommand(branch + "left", "test:swipeLeft");
- let cmdRight = test_addCommand(branch + "right", "test:swipeRight");
-
- function resetCounts() {
- cmdUp.callCount = 0;
- cmdDown.callCount = 0;
- cmdLeft.callCount = 0;
- cmdRight.callCount = 0;
- }
-
- // UP
- resetCounts();
- test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, up, 0, 0);
- ok(cmdUp.callCount == 1, "Step 1: Up command was not triggered");
- ok(cmdDown.callCount == 0, "Step 1: Down command was triggered");
- ok(cmdLeft.callCount == 0, "Step 1: Left command was triggered");
- ok(cmdRight.callCount == 0, "Step 1: Right command was triggered");
-
- // DOWN
- resetCounts();
- test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, down, 0, 0);
- ok(cmdUp.callCount == 0, "Step 2: Up command was triggered");
- ok(cmdDown.callCount == 1, "Step 2: Down command was not triggered");
- ok(cmdLeft.callCount == 0, "Step 2: Left command was triggered");
- ok(cmdRight.callCount == 0, "Step 2: Right command was triggered");
-
- // LEFT
- resetCounts();
- test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, left, 0, 0);
- ok(cmdUp.callCount == 0, "Step 3: Up command was triggered");
- ok(cmdDown.callCount == 0, "Step 3: Down command was triggered");
- ok(cmdLeft.callCount == 1, "Step 3: Left command was not triggered");
- ok(cmdRight.callCount == 0, "Step 3: Right command was triggered");
-
- // RIGHT
- resetCounts();
- test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, right, 0, 0);
- ok(cmdUp.callCount == 0, "Step 4: Up command was triggered");
- ok(cmdDown.callCount == 0, "Step 4: Down command was triggered");
- ok(cmdLeft.callCount == 0, "Step 4: Left command was triggered");
- ok(cmdRight.callCount == 1, "Step 4: Right command was not triggered");
-
- // Make sure combinations do not trigger events.
- let combos = [ up | left, up | right, down | left, down | right];
- for (let i = 0; i < combos.length; i++) {
- resetCounts();
- test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, combos[i], 0, 0);
- ok(cmdUp.callCount == 0, "Step 5-"+i+": Up command was triggered");
- ok(cmdDown.callCount == 0, "Step 5-"+i+": Down command was triggered");
- ok(cmdLeft.callCount == 0, "Step 5-"+i+": Left command was triggered");
- ok(cmdRight.callCount == 0, "Step 5-"+i+": Right command was triggered");
- }
-
- // Remove the test commands.
- test_removeCommand(cmdUp);
- test_removeCommand(cmdDown);
- test_removeCommand(cmdLeft);
- test_removeCommand(cmdRight);
-}
-
-
-function test_rotateHelperGetImageRotation(aImageElement)
-{
- // Get the true image rotation from the transform matrix, bounded
- // to 0 <= result < 360
- let transformValue = content.window.getComputedStyle(aImageElement, null)
- .transform;
- if (transformValue == "none")
- return 0;
-
- transformValue = transformValue.split("(")[1]
- .split(")")[0]
- .split(",");
- var rotation = Math.round(Math.atan2(transformValue[1], transformValue[0]) *
- (180 / Math.PI));
- return (rotation < 0 ? rotation + 360 : rotation);
-}
-
-function test_rotateHelperOneGesture(aImageElement, aCurrentRotation,
- aDirection, aAmount, aStop)
-{
- if (aAmount <= 0 || aAmount > 90) // Bound to 0 < aAmount <= 90
- return;
-
- // easier to type names for the direction constants
- let clockwise = SimpleGestureEvent.ROTATION_CLOCKWISE;
-
- let delta = aAmount * (aDirection == clockwise ? 1 : -1);
-
- // Kill transition time on image so test isn't wrong and doesn't take 10 seconds
- aImageElement.style.transitionDuration = "0s";
-
- // Start the gesture, perform an update, and force flush
- test_utils.sendSimpleGestureEvent("MozRotateGestureStart", 0, 0, aDirection, .001, 0);
- test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, aDirection, delta, 0);
- aImageElement.clientTop;
-
- // If stop, check intermediate
- if (aStop) {
- // Send near-zero-delta to stop, and force flush
- test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, aDirection, .001, 0);
- aImageElement.clientTop;
-
- let stopExpectedRotation = (aCurrentRotation + delta) % 360;
- if (stopExpectedRotation < 0)
- stopExpectedRotation += 360;
-
- is(stopExpectedRotation, test_rotateHelperGetImageRotation(aImageElement),
- "Image rotation at gesture stop/hold: expected=" + stopExpectedRotation +
- ", observed=" + test_rotateHelperGetImageRotation(aImageElement) +
- ", init=" + aCurrentRotation +
- ", amt=" + aAmount +
- ", dir=" + (aDirection == clockwise ? "cl" : "ccl"));
- }
- // End it and force flush
- test_utils.sendSimpleGestureEvent("MozRotateGesture", 0, 0, aDirection, 0, 0);
- aImageElement.clientTop;
-
- let finalExpectedRotation;
-
- if (aAmount < 45 && aStop) {
- // Rotate a bit, then stop. Expect no change at end of gesture.
- finalExpectedRotation = aCurrentRotation;
- }
- else {
- // Either not stopping (expect 90 degree change in aDirection), OR
- // stopping but after 45, (expect 90 degree change in aDirection)
- finalExpectedRotation = (aCurrentRotation +
- (aDirection == clockwise ? 1 : -1) * 90) % 360;
- if (finalExpectedRotation < 0)
- finalExpectedRotation += 360;
- }
-
- is(finalExpectedRotation, test_rotateHelperGetImageRotation(aImageElement),
- "Image rotation gesture end: expected=" + finalExpectedRotation +
- ", observed=" + test_rotateHelperGetImageRotation(aImageElement) +
- ", init=" + aCurrentRotation +
- ", amt=" + aAmount +
- ", dir=" + (aDirection == clockwise ? "cl" : "ccl"));
-}
-
-function test_rotateGesturesOnTab()
-{
- gBrowser.selectedBrowser.removeEventListener("load", test_rotateGesturesOnTab, true);
-
- if (!(content.document instanceof ImageDocument)) {
- ok(false, "Image document failed to open for rotation testing");
- gBrowser.removeTab(test_imageTab);
- finish();
- return;
- }
-
- // easier to type names for the direction constants
- let cl = SimpleGestureEvent.ROTATION_CLOCKWISE;
- let ccl = SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE;
-
- let imgElem = content.document.body &&
- content.document.body.firstElementChild;
-
- if (!imgElem) {
- ok(false, "Could not get image element on ImageDocument for rotation!");
- gBrowser.removeTab(test_imageTab);
- finish();
- return;
- }
-
- // Quick function to normalize rotation to 0 <= r < 360
- var normRot = function(rotation) {
- rotation = rotation % 360;
- if (rotation < 0)
- rotation += 360;
- return rotation;
- }
-
- for (var initRot = 0; initRot < 360; initRot += 90) {
- // Test each case: at each 90 degree snap; cl/ccl;
- // amount more or less than 45; stop and hold or don't (32 total tests)
- // The amount added to the initRot is where it is expected to be
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 0), cl, 35, true );
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 0), cl, 35, false);
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 90), cl, 55, true );
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 180), cl, 55, false);
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 270), ccl, 35, true );
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 270), ccl, 35, false);
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 180), ccl, 55, true );
- test_rotateHelperOneGesture(imgElem, normRot(initRot + 90), ccl, 55, false);
-
- // Manually rotate it 90 degrees clockwise to prepare for next iteration,
- // and force flush
- test_utils.sendSimpleGestureEvent("MozRotateGestureStart", 0, 0, cl, .001, 0);
- test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, cl, 90, 0);
- test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, cl, .001, 0);
- test_utils.sendSimpleGestureEvent("MozRotateGesture", 0, 0, cl, 0, 0);
- imgElem.clientTop;
- }
-
- gBrowser.removeTab(test_imageTab);
- test_imageTab = null;
- finish();
-}
-
-function test_rotateGestures()
-{
- test_imageTab = gBrowser.addTab("chrome://branding/content/about-logo.png");
- gBrowser.selectedTab = test_imageTab;
-
- gBrowser.selectedBrowser.addEventListener("load", test_rotateGesturesOnTab, true);
-}
diff --git a/browser/base/content/test/general/browser_getshortcutoruri.js b/browser/base/content/test/general/browser_getshortcutoruri.js
deleted file mode 100644
index 9ebf8e9ca..000000000
--- a/browser/base/content/test/general/browser_getshortcutoruri.js
+++ /dev/null
@@ -1,143 +0,0 @@
-function getPostDataString(aIS) {
- if (!aIS)
- return null;
-
- var sis = Cc["@mozilla.org/scriptableinputstream;1"].
- createInstance(Ci.nsIScriptableInputStream);
- sis.init(aIS);
- var dataLines = sis.read(aIS.available()).split("\n");
-
- // only want the last line
- return dataLines[dataLines.length-1];
-}
-
-function keywordResult(aURL, aPostData, aIsUnsafe) {
- this.url = aURL;
- this.postData = aPostData;
- this.isUnsafe = aIsUnsafe;
-}
-
-function keyWordData() {}
-keyWordData.prototype = {
- init: function(aKeyWord, aURL, aPostData, aSearchWord) {
- this.keyword = aKeyWord;
- this.uri = makeURI(aURL);
- this.postData = aPostData;
- this.searchWord = aSearchWord;
-
- this.method = (this.postData ? "POST" : "GET");
- }
-}
-
-function bmKeywordData(aKeyWord, aURL, aPostData, aSearchWord) {
- this.init(aKeyWord, aURL, aPostData, aSearchWord);
-}
-bmKeywordData.prototype = new keyWordData();
-
-function searchKeywordData(aKeyWord, aURL, aPostData, aSearchWord) {
- this.init(aKeyWord, aURL, aPostData, aSearchWord);
-}
-searchKeywordData.prototype = new keyWordData();
-
-var testData = [
- [new bmKeywordData("bmget", "http://bmget/search=%s", null, "foo"),
- new keywordResult("http://bmget/search=foo", null)],
-
- [new bmKeywordData("bmpost", "http://bmpost/", "search=%s", "foo2"),
- new keywordResult("http://bmpost/", "search=foo2")],
-
- [new bmKeywordData("bmpostget", "http://bmpostget/search1=%s", "search2=%s", "foo3"),
- new keywordResult("http://bmpostget/search1=foo3", "search2=foo3")],
-
- [new bmKeywordData("bmget-nosearch", "http://bmget-nosearch/", null, ""),
- new keywordResult("http://bmget-nosearch/", null)],
-
- [new searchKeywordData("searchget", "http://searchget/?search={searchTerms}", null, "foo4"),
- new keywordResult("http://searchget/?search=foo4", null, true)],
-
- [new searchKeywordData("searchpost", "http://searchpost/", "search={searchTerms}", "foo5"),
- new keywordResult("http://searchpost/", "search=foo5", true)],
-
- [new searchKeywordData("searchpostget", "http://searchpostget/?search1={searchTerms}", "search2={searchTerms}", "foo6"),
- new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6", true)],
-
- // Bookmark keywords that don't take parameters should not be activated if a
- // parameter is passed (bug 420328).
- [new bmKeywordData("bmget-noparam", "http://bmget-noparam/", null, "foo7"),
- new keywordResult(null, null, true)],
- [new bmKeywordData("bmpost-noparam", "http://bmpost-noparam/", "not_a=param", "foo8"),
- new keywordResult(null, null, true)],
-
- // Test escaping (%s = escaped, %S = raw)
- // UTF-8 default
- [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "foé"),
- new keywordResult("http://bmget/?esc=fo%C3%A9&raw=foé", null)],
- // Explicitly-defined ISO-8859-1
- [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "foé"),
- new keywordResult("http://bmget/?esc=fo%E9&raw=foé", null)],
-
- // Bug 359809: Test escaping +, /, and @
- // UTF-8 default
- [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "+/@"),
- new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)],
- // Explicitly-defined ISO-8859-1
- [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "+/@"),
- new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)],
-
- // Test using a non-bmKeywordData object, to test the behavior of
- // getShortcutOrURIAndPostData for non-keywords (setupKeywords only adds keywords for
- // bmKeywordData objects)
- [{keyword: "http://gavinsharp.com"},
- new keywordResult(null, null, true)]
-];
-
-add_task(function* test_getshortcutoruri() {
- yield setupKeywords();
-
- for (let item of testData) {
- let [data, result] = item;
-
- let query = data.keyword;
- if (data.searchWord)
- query += " " + data.searchWord;
- let returnedData = yield getShortcutOrURIAndPostData(query);
- // null result.url means we should expect the same query we sent in
- let expected = result.url || query;
- is(returnedData.url, expected, "got correct URL for " + data.keyword);
- is(getPostDataString(returnedData.postData), result.postData, "got correct postData for " + data.keyword);
- is(returnedData.mayInheritPrincipal, !result.isUnsafe, "got correct mayInheritPrincipal for " + data.keyword);
- }
-
- yield cleanupKeywords();
-});
-
-var folder = null;
-var gAddedEngines = [];
-
-function* setupKeywords() {
- folder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- title: "keyword-test" });
- for (let item of testData) {
- let data = item[0];
- if (data instanceof bmKeywordData) {
- yield PlacesUtils.bookmarks.insert({ url: data.uri, parentGuid: folder.guid });
- yield PlacesUtils.keywords.insert({ keyword: data.keyword, url: data.uri.spec, postData: data.postData });
- }
-
- if (data instanceof searchKeywordData) {
- Services.search.addEngineWithDetails(data.keyword, "", data.keyword, "", data.method, data.uri.spec);
- let addedEngine = Services.search.getEngineByName(data.keyword);
- if (data.postData) {
- let [paramName, paramValue] = data.postData.split("=");
- addedEngine.addParam(paramName, paramValue, null);
- }
- gAddedEngines.push(addedEngine);
- }
- }
-}
-
-function* cleanupKeywords() {
- PlacesUtils.bookmarks.remove(folder);
- gAddedEngines.map(Services.search.removeEngine);
-}
diff --git a/browser/base/content/test/general/browser_hide_removing.js b/browser/base/content/test/general/browser_hide_removing.js
deleted file mode 100644
index be62e2d89..000000000
--- a/browser/base/content/test/general/browser_hide_removing.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Bug 587922: tabs don't get removed if they're hidden
-
-function test() {
- waitForExplicitFinish();
-
- // 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, false);
-
- // While the next tab is being selected, hide the removing tab
- numVisBeforeHide = gBrowser.visibleTabs.length;
- gBrowser.hideTab(testTab);
- numVisAfterHide = gBrowser.visibleTabs.length;
- }, false);
- 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;
- }
-
- is(numVisBeforeHide, 1, "animated remove has in 1 tab left");
- is(numVisAfterHide, 1, "hiding a removing tab is also has 1 tab");
- finish();
- }, 50);
- })();
-}
diff --git a/browser/base/content/test/general/browser_homeDrop.js b/browser/base/content/test/general/browser_homeDrop.js
deleted file mode 100644
index 6e87963d5..000000000
--- a/browser/base/content/test/general/browser_homeDrop.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function*() {
- let HOMEPAGE_PREF = "browser.startup.homepage";
-
- let homepageStr = Cc["@mozilla.org/supports-string;1"]
- .createInstance(Ci.nsISupportsString);
- homepageStr.data = "about:mozilla";
- yield pushPrefs([HOMEPAGE_PREF, homepageStr, Ci.nsISupportsString]);
-
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- // Since synthesizeDrop triggers the srcElement, need to use another button.
- let dragSrcElement = document.getElementById("downloads-button");
- ok(dragSrcElement, "Downloads button exists");
- let homeButton = document.getElementById("home-button");
- ok(homeButton, "home button present");
-
- function* drop(dragData, homepage) {
- let setHomepageDialogPromise = BrowserTestUtils.domWindowOpened();
-
- EventUtils.synthesizeDrop(dragSrcElement, homeButton, dragData, "copy", window);
-
- let setHomepageDialog = yield setHomepageDialogPromise;
- ok(true, "dialog appeared in response to home button drop");
- yield BrowserTestUtils.waitForEvent(setHomepageDialog, "load", false);
-
- let setHomepagePromise = new Promise(function(resolve) {
- let observer = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
- observe: function(subject, topic, data) {
- is(topic, "nsPref:changed", "observed correct topic");
- is(data, HOMEPAGE_PREF, "observed correct data");
- let modified = Services.prefs.getComplexValue(HOMEPAGE_PREF,
- Ci.nsISupportsString);
- is(modified.data, homepage, "homepage is set correctly");
- Services.prefs.removeObserver(HOMEPAGE_PREF, observer);
-
- Services.prefs.setComplexValue(HOMEPAGE_PREF,
- Ci.nsISupportsString, homepageStr);
-
- resolve();
- }
- };
- Services.prefs.addObserver(HOMEPAGE_PREF, observer, false);
- });
-
- setHomepageDialog.document.documentElement.acceptDialog();
-
- yield setHomepagePromise;
- }
-
- function dropInvalidURI() {
- return new Promise(resolve => {
- let consoleListener = {
- observe: function (m) {
- if (m.message.includes("NS_ERROR_DOM_BAD_URI")) {
- ok(true, "drop was blocked");
- resolve();
- }
- }
- };
- Services.console.registerListener(consoleListener);
- registerCleanupFunction(function () {
- Services.console.unregisterListener(consoleListener);
- });
-
- executeSoon(function () {
- info("Attempting second drop, of a javascript: URI");
- // The drop handler throws an exception when dragging URIs that inherit
- // principal, e.g. javascript:
- expectUncaughtException();
- EventUtils.synthesizeDrop(dragSrcElement, homeButton, [[{type: "text/plain", data: "javascript:8888"}]], "copy", window);
- });
- });
- }
-
- yield* drop([[{type: "text/plain",
- data: "http://mochi.test:8888/"}]],
- "http://mochi.test:8888/");
- yield* drop([[{type: "text/plain",
- data: "http://mochi.test:8888/\nhttp://mochi.test:8888/b\nhttp://mochi.test:8888/c"}]],
- "http://mochi.test:8888/|http://mochi.test:8888/b|http://mochi.test:8888/c");
- yield dropInvalidURI();
-});
-
diff --git a/browser/base/content/test/general/browser_identity_UI.js b/browser/base/content/test/general/browser_identity_UI.js
deleted file mode 100644
index 5aacb2e79..000000000
--- a/browser/base/content/test/general/browser_identity_UI.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Tests for correct behaviour of getEffectiveHost on identity handler */
-
-function test() {
- waitForExplicitFinish();
- requestLongerTimeout(2);
-
- ok(gIdentityHandler, "gIdentityHandler should exist");
-
- BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true).then(() => {
- gBrowser.selectedBrowser.addEventListener("load", checkResult, true);
- nextTest();
- });
-}
-
-// Greek IDN for 'example.test'.
-var idnDomain = "\u03C0\u03B1\u03C1\u03AC\u03B4\u03B5\u03B9\u03B3\u03BC\u03B1.\u03B4\u03BF\u03BA\u03B9\u03BC\u03AE";
-var tests = [
- {
- name: "normal domain",
- location: "http://test1.example.org/",
- effectiveHost: "test1.example.org"
- },
- {
- name: "view-source",
- location: "view-source:http://example.com/",
- effectiveHost: null
- },
- {
- name: "normal HTTPS",
- location: "https://example.com/",
- effectiveHost: "example.com",
- isHTTPS: true
- },
- {
- name: "IDN subdomain",
- location: "http://sub1." + idnDomain + "/",
- effectiveHost: "sub1." + idnDomain
- },
- {
- name: "subdomain with port",
- location: "http://sub1.test1.example.org:8000/",
- effectiveHost: "sub1.test1.example.org"
- },
- {
- name: "subdomain HTTPS",
- location: "https://test1.example.com/",
- effectiveHost: "test1.example.com",
- isHTTPS: true
- },
- {
- name: "view-source HTTPS",
- location: "view-source:https://example.com/",
- effectiveHost: null,
- isHTTPS: true
- },
- {
- name: "IP address",
- location: "http://127.0.0.1:8888/",
- effectiveHost: "127.0.0.1"
- },
-]
-
-var gCurrentTest, gCurrentTestIndex = -1, gTestDesc, gPopupHidden;
-// Go through the tests in both directions, to add additional coverage for
-// transitions between different states.
-var gForward = true;
-var gCheckETLD = false;
-function nextTest() {
- if (!gCheckETLD) {
- if (gForward)
- gCurrentTestIndex++;
- else
- gCurrentTestIndex--;
-
- if (gCurrentTestIndex == tests.length) {
- // Went too far, reverse
- gCurrentTestIndex--;
- gForward = false;
- }
-
- if (gCurrentTestIndex == -1) {
- gBrowser.selectedBrowser.removeEventListener("load", checkResult, true);
- gBrowser.removeCurrentTab();
- finish();
- return;
- }
-
- gCurrentTest = tests[gCurrentTestIndex];
- gTestDesc = "#" + gCurrentTestIndex + " (" + gCurrentTest.name + ")";
- if (!gForward)
- gTestDesc += " (second time)";
- if (gCurrentTest.isHTTPS) {
- gCheckETLD = true;
- }
-
- // Navigate to the next page, which will cause checkResult to fire.
- let spec = gBrowser.selectedBrowser.currentURI.spec;
- if (spec == "about:blank" || spec == gCurrentTest.location) {
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.location);
- } else {
- // Open the Control Center and make sure it closes after nav (Bug 1207542).
- let popupShown = promisePopupShown(gIdentityHandler._identityPopup);
- gPopupHidden = promisePopupHidden(gIdentityHandler._identityPopup);
- gIdentityHandler._identityBox.click();
- info("Waiting for the Control Center to be shown");
- popupShown.then(() => {
- is_element_visible(gIdentityHandler._identityPopup, "Control Center is visible");
- // Show the subview, which is an easy way in automation to reproduce
- // Bug 1207542, where the CC wouldn't close on navigation.
- gBrowser.ownerDocument.querySelector("#identity-popup-security-expander").click();
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.location);
- });
- }
- } else {
- gCheckETLD = false;
- gTestDesc = "#" + gCurrentTestIndex + " (" + gCurrentTest.name + " without eTLD in identity icon label)";
- if (!gForward)
- gTestDesc += " (second time)";
- gBrowser.selectedBrowser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE |
- Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY);
- }
-}
-
-function checkResult() {
- // Sanity check other values, and the value of gIdentityHandler.getEffectiveHost()
- is(gIdentityHandler._uri.spec, gCurrentTest.location, "location matches for test " + gTestDesc);
- // getEffectiveHost can't be called for all modes
- if (gCurrentTest.effectiveHost === null) {
- let identityBox = document.getElementById("identity-box");
- ok(identityBox.className == "unknownIdentity" ||
- identityBox.className == "chromeUI", "mode matched");
- } else {
- is(gIdentityHandler.getEffectiveHost(), gCurrentTest.effectiveHost, "effectiveHost matches for test " + gTestDesc);
- }
-
- if (gPopupHidden) {
- info("Waiting for the Control Center to hide");
- gPopupHidden.then(() => {
- gPopupHidden = null;
- is_element_hidden(gIdentityHandler._identityPopup, "control center is hidden");
- executeSoon(nextTest);
- });
- } else {
- executeSoon(nextTest);
- }
-}
diff --git a/browser/base/content/test/general/browser_insecureLoginForms.js b/browser/base/content/test/general/browser_insecureLoginForms.js
deleted file mode 100644
index 72db7dbe6..000000000
--- a/browser/base/content/test/general/browser_insecureLoginForms.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Load directly from the browser-chrome support files of login tests.
-const TEST_URL_PATH = "/browser/toolkit/components/passwordmgr/test/browser/";
-
-/**
- * Waits for the given number of occurrences of InsecureLoginFormsStateChange
- * on the given browser element.
- */
-function waitForInsecureLoginFormsStateChange(browser, count) {
- return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange",
- false, () => --count == 0);
-}
-
-/**
- * Checks the insecure login forms logic for the identity block.
- */
-add_task(function* test_simple() {
- yield new Promise(resolve => SpecialPowers.pushPrefEnv({
- "set": [["security.insecure_password.ui.enabled", true]],
- }, resolve));
-
- for (let [origin, expectWarning] of [
- ["http://example.com", true],
- ["http://127.0.0.1", false],
- ["https://example.com", false],
- ]) {
- let testUrlPath = origin + TEST_URL_PATH;
- let tab = gBrowser.addTab(testUrlPath + "form_basic.html");
- let browser = tab.linkedBrowser;
- yield Promise.all([
- BrowserTestUtils.switchTab(gBrowser, tab),
- BrowserTestUtils.browserLoaded(browser),
- // One event is triggered by pageshow and one by DOMFormHasPassword.
- waitForInsecureLoginFormsStateChange(browser, 2),
- ]);
-
- let { gIdentityHandler } = gBrowser.ownerGlobal;
- gIdentityHandler._identityBox.click();
- document.getElementById("identity-popup-security-expander").click();
-
- if (expectWarning) {
- is_element_visible(document.getElementById("connection-icon"));
- let connectionIconImage = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("connection-icon"), "")
- .getPropertyValue("list-style-image");
- let securityViewBG = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("identity-popup-securityView"), "")
- .getPropertyValue("background-image");
- let securityContentBG = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("identity-popup-security-content"), "")
- .getPropertyValue("background-image");
- is(connectionIconImage,
- "url(\"chrome://browser/skin/connection-mixed-active-loaded.svg#icon\")",
- "Using expected icon image in the identity block");
- is(securityViewBG,
- "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
- "Using expected icon image in the Control Center main view");
- is(securityContentBG,
- "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
- "Using expected icon image in the Control Center subview");
- is(Array.filter(document.querySelectorAll("[observes=identity-popup-insecure-login-forms-learn-more]"),
- element => !is_hidden(element)).length, 1,
- "The 'Learn more' link should be visible once.");
- }
-
- // Messages should be visible when the scheme is HTTP, and invisible when
- // the scheme is HTTPS.
- is(Array.every(document.querySelectorAll("[when-loginforms=insecure]"),
- element => !is_hidden(element)),
- expectWarning,
- "The relevant messages should be visible or hidden.");
-
- gIdentityHandler._identityPopup.hidden = true;
- gBrowser.removeTab(tab);
- }
-});
-
-/**
- * Checks that the insecure login forms logic does not regress mixed content
- * blocking messages when mixed active content is loaded.
- */
-add_task(function* test_mixedcontent() {
- yield new Promise(resolve => SpecialPowers.pushPrefEnv({
- "set": [["security.mixed_content.block_active_content", false]],
- }, resolve));
-
- // Load the page with the subframe in a new tab.
- let testUrlPath = "://example.com" + TEST_URL_PATH;
- let tab = gBrowser.addTab("https" + testUrlPath + "insecure_test.html");
- let browser = tab.linkedBrowser;
- yield Promise.all([
- BrowserTestUtils.switchTab(gBrowser, tab),
- BrowserTestUtils.browserLoaded(browser),
- // Two events are triggered by pageshow and one by DOMFormHasPassword.
- waitForInsecureLoginFormsStateChange(browser, 3),
- ]);
-
- assertMixedContentBlockingState(browser, { activeLoaded: true,
- activeBlocked: false,
- passiveLoaded: false });
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * Checks that insecure window.opener does not trigger a warning.
- */
-add_task(function* test_ignoring_window_opener() {
- let newTabURL = "https://example.com" + TEST_URL_PATH + "form_basic.html";
- let path = getRootDirectory(gTestPath)
- .replace("chrome://mochitests/content", "http://example.com");
- let url = path + "insecure_opener.html";
-
- yield BrowserTestUtils.withNewTab(url, function*(browser) {
- // Clicking the link will spawn a new tab.
- let loaded = BrowserTestUtils.waitForNewTab(gBrowser, newTabURL);
- yield ContentTask.spawn(browser, {}, function() {
- content.document.getElementById("link").click();
- });
- let tab = yield loaded;
- browser = tab.linkedBrowser;
- yield waitForInsecureLoginFormsStateChange(browser, 2);
-
- // Open the identity popup.
- let { gIdentityHandler } = gBrowser.ownerGlobal;
- gIdentityHandler._identityBox.click();
- document.getElementById("identity-popup-security-expander").click();
-
- ok(is_visible(document.getElementById("connection-icon")),
- "Connection icon is visible");
-
- // Assert that the identity indicators are still "secure".
- let connectionIconImage = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("connection-icon"))
- .getPropertyValue("list-style-image");
- let securityViewBG = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("identity-popup-securityView"))
- .getPropertyValue("background-image");
- let securityContentBG = gBrowser.ownerGlobal
- .getComputedStyle(document.getElementById("identity-popup-security-content"))
- .getPropertyValue("background-image");
- is(connectionIconImage,
- "url(\"chrome://browser/skin/connection-secure.svg\")",
- "Using expected icon image in the identity block");
- is(securityViewBG,
- "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
- "Using expected icon image in the Control Center main view");
- is(securityContentBG,
- "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
- "Using expected icon image in the Control Center subview");
-
- ok(Array.every(document.querySelectorAll("[when-loginforms=insecure]"),
- element => is_hidden(element)),
- "All messages should be hidden.");
-
- gIdentityHandler._identityPopup.hidden = true;
-
- yield BrowserTestUtils.removeTab(tab);
- });
-});
diff --git a/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js b/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js
deleted file mode 100644
index 8e69e781b..000000000
--- a/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js
+++ /dev/null
@@ -1,39 +0,0 @@
-"use strict";
-
-
-/**
- * Verify that loading an invalid URI does not clobber a previously-loaded page's history
- * entry, but that the invalid URI gets its own history entry instead. We're checking this
- * using nsIWebNavigation's canGoBack, as well as actually going back and then checking
- * canGoForward.
- */
-add_task(function* checkBackFromInvalidURI() {
- yield pushPrefs(["keyword.enabled", false]);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots", true);
- gURLBar.value = "::2600";
- gURLBar.focus();
-
- let promiseErrorPageLoaded = new Promise(resolve => {
- tab.linkedBrowser.addEventListener("DOMContentLoaded", function onLoad() {
- tab.linkedBrowser.removeEventListener("DOMContentLoaded", onLoad, false, true);
- resolve();
- }, false, true);
- });
- EventUtils.synthesizeKey("VK_RETURN", {});
- yield promiseErrorPageLoaded;
-
- ok(gBrowser.webNavigation.canGoBack, "Should be able to go back");
- if (gBrowser.webNavigation.canGoBack) {
- // Can't use DOMContentLoaded here because the page is bfcached. Can't use pageshow for
- // the error page because it doesn't seem to fire for those.
- let promiseOtherPageLoaded = BrowserTestUtils.waitForEvent(tab.linkedBrowser, "pageshow", false,
- // Be paranoid we *are* actually seeing this other page load, not some kind of race
- // for if/when we do start firing pageshow for the error page...
- function(e) { return gBrowser.currentURI.spec == "about:robots" }
- );
- gBrowser.goBack();
- yield promiseOtherPageLoaded;
- ok(gBrowser.webNavigation.canGoForward, "Should be able to go forward from previous page.");
- }
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_keywordBookmarklets.js b/browser/base/content/test/general/browser_keywordBookmarklets.js
deleted file mode 100644
index 5e94733fe..000000000
--- a/browser/base/content/test/general/browser_keywordBookmarklets.js
+++ /dev/null
@@ -1,54 +0,0 @@
-"use strict"
-
-add_task(function* test_keyword_bookmarklet() {
- let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- title: "bookmarklet",
- url: "javascript:'1';" });
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- registerCleanupFunction (function* () {
- gBrowser.removeTab(tab);
- yield PlacesUtils.bookmarks.remove(bm);
- });
- yield promisePageShow();
- let originalPrincipal = gBrowser.contentPrincipal;
-
- function getPrincipalURI() {
- return ContentTask.spawn(tab.linkedBrowser, null, function() {
- return content.document.nodePrincipal.URI.spec;
- });
- }
-
- let originalPrincipalURI = yield getPrincipalURI();
-
- yield PlacesUtils.keywords.insert({ keyword: "bm", url: "javascript:'1';" })
-
- // Enter bookmarklet keyword in the URL bar
- gURLBar.value = "bm";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
-
- yield promisePageShow();
-
- let newPrincipalURI = yield getPrincipalURI();
- is(newPrincipalURI, originalPrincipalURI, "content has the same principal");
-
- // In e10s, null principals don't round-trip so the same null principal sent
- // from the child will be a new null principal. Verify that this is the
- // case.
- if (tab.linkedBrowser.isRemoteBrowser) {
- ok(originalPrincipal.isNullPrincipal && gBrowser.contentPrincipal.isNullPrincipal,
- "both principals should be null principals in the parent");
- } 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);
- resolve();
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_keywordSearch.js b/browser/base/content/test/general/browser_keywordSearch.js
deleted file mode 100644
index cf8bd0c0e..000000000
--- a/browser/base/content/test/general/browser_keywordSearch.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- **/
-
-var gTests = [
- {
- name: "normal search (search service)",
- testText: "test search",
- searchURL: Services.search.defaultEngine.getSubmission("test search", null, "keyword").uri.spec
- },
- {
- name: "?-prefixed search (search service)",
- testText: "? foo ",
- searchURL: Services.search.defaultEngine.getSubmission("foo", null, "keyword").uri.spec
- }
-];
-
-function test() {
- waitForExplicitFinish();
-
- let windowObserver = {
- observe: function(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, false);
- win.close();
- }, false);
- executeSoon(finish);
- }
- }
- };
-
- Services.ww.registerNotification(windowObserver);
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let listener = {
- onStateChange: function onLocationChange(webProgress, req, flags, status) {
- // Only care about document starts
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if (!(flags & docStart))
- return;
-
- info("received document start");
-
- ok(req instanceof Ci.nsIChannel, "req is a channel");
- is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
- info("Actual URI: " + req.URI.spec);
-
- req.cancel(Components.results.NS_ERROR_FAILURE);
-
- executeSoon(nextTest);
- }
- };
- gBrowser.addProgressListener(listener);
-
- registerCleanupFunction(function () {
- Services.ww.unregisterNotification(windowObserver);
-
- gBrowser.removeProgressListener(listener);
- gBrowser.removeTab(tab);
- });
-
- nextTest();
-}
-
-var gCurrTest;
-function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- doTest();
- } else {
- finish();
- }
-}
-
-function doTest() {
- info("Running test: " + gCurrTest.name);
-
- // Simulate a user entering search terms
- gURLBar.value = gCurrTest.testText;
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
-}
diff --git a/browser/base/content/test/general/browser_keywordSearch_postData.js b/browser/base/content/test/general/browser_keywordSearch_postData.js
deleted file mode 100644
index 3f700fa58..000000000
--- a/browser/base/content/test/general/browser_keywordSearch_postData.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- **/
-
-var gTests = [
- {
- name: "normal search (search service)",
- testText: "test search",
- expectText: "test+search"
- },
- {
- name: "?-prefixed search (search service)",
- testText: "? foo ",
- expectText: "foo"
- }
-];
-
-function test() {
- waitForExplicitFinish();
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let searchObserver = function search_observer(aSubject, aTopic, aData) {
- let engine = aSubject.QueryInterface(Ci.nsISearchEngine);
- info("Observer: " + aData + " for " + engine.name);
-
- if (aData != "engine-added")
- return;
-
- if (engine.name != "POST Search")
- return;
-
- Services.search.defaultEngine = engine;
-
- registerCleanupFunction(function () {
- Services.search.removeEngine(engine);
- });
-
- // ready to execute the tests!
- executeSoon(nextTest);
- };
-
- Services.obs.addObserver(searchObserver, "browser-search-engine-modified", false);
-
- registerCleanupFunction(function () {
- gBrowser.removeTab(tab);
-
- Services.obs.removeObserver(searchObserver, "browser-search-engine-modified");
- });
-
- Services.search.addEngine("http://test:80/browser/browser/base/content/test/general/POSTSearchEngine.xml",
- null, null, false);
-}
-
-var gCurrTest;
-function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- doTest();
- } else {
- finish();
- }
-}
-
-function doTest() {
- info("Running test: " + gCurrTest.name);
-
- waitForLoad(function () {
- let loadedText = gBrowser.contentDocument.body.textContent;
- ok(loadedText, "search page loaded");
- let needle = "searchterms=" + gCurrTest.expectText;
- is(loadedText, needle, "The query POST data should be returned in the response");
- nextTest();
- });
-
- // Simulate a user entering search terms
- gURLBar.value = gCurrTest.testText;
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
-}
-
-
-function waitForLoad(cb) {
- let browser = gBrowser.selectedBrowser;
- browser.addEventListener("load", function listener() {
- if (browser.currentURI.spec == "about:blank")
- return;
- info("Page loaded: " + browser.currentURI.spec);
- browser.removeEventListener("load", listener, true);
-
- cb();
- }, true);
-}
diff --git a/browser/base/content/test/general/browser_lastAccessedTab.js b/browser/base/content/test/general/browser_lastAccessedTab.js
deleted file mode 100644
index 57bd330ae..000000000
--- a/browser/base/content/test/general/browser_lastAccessedTab.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// gBrowser.selectedTab.lastAccessed and Date.now() called from this test can't
-// run concurrently, and therefore don't always match exactly.
-const CURRENT_TIME_TOLERANCE_MS = 15;
-
-function isCurrent(tab, msg) {
- const DIFF = Math.abs(Date.now() - tab.lastAccessed);
- ok(DIFF <= CURRENT_TIME_TOLERANCE_MS, msg + " (difference: " + DIFF + ")");
-}
-
-function nextStep(fn) {
- setTimeout(fn, CURRENT_TIME_TOLERANCE_MS + 10);
-}
-
-var originalTab;
-var newTab;
-
-function test() {
- waitForExplicitFinish();
-
- originalTab = gBrowser.selectedTab;
- nextStep(step2);
-}
-
-function step2() {
- isCurrent(originalTab, "selected tab has the current timestamp");
- newTab = gBrowser.addTab("about:blank", {skipAnimation: true});
- nextStep(step3);
-}
-
-function step3() {
- ok(newTab.lastAccessed < Date.now(), "new tab hasn't been selected so far");
- gBrowser.selectedTab = newTab;
- isCurrent(newTab, "new tab has the current timestamp after being selected");
- nextStep(step4);
-}
-
-function step4() {
- ok(originalTab.lastAccessed < Date.now(),
- "original tab has old timestamp after being deselected");
- isCurrent(newTab, "new tab has the current timestamp since it's still selected");
-
- gBrowser.removeTab(newTab);
- finish();
-}
diff --git a/browser/base/content/test/general/browser_mcb_redirect.js b/browser/base/content/test/general/browser_mcb_redirect.js
deleted file mode 100644
index 41b4e9468..000000000
--- a/browser/base/content/test/general/browser_mcb_redirect.js
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Description of the Tests for
- * - Bug 418354 - Call Mixed content blocking on redirects
- *
- * Single redirect script tests
- * 1. Load a script over https inside an https page
- * - the server responds with a 302 redirect to a >> HTTP << script
- * - the doorhanger should appear!
- *
- * 2. Load a script over https inside an http page
- * - the server responds with a 302 redirect to a >> HTTP << script
- * - the doorhanger should not appear!
- *
- * Single redirect image tests
- * 3. Load an image over https inside an https page
- * - the server responds with a 302 redirect to a >> HTTP << image
- * - the image should not load
- *
- * 4. Load an image over https inside an http page
- * - the server responds with a 302 redirect to a >> HTTP << image
- * - the image should load and get cached
- *
- * Single redirect cached image tests
- * 5. Using offline mode to ensure we hit the cache, load a cached image over
- * https inside an http page
- * - the server would have responded with a 302 redirect to a >> HTTP <<
- * image, but instead we try to use the cached image.
- * - the image should load
- *
- * 6. Using offline mode to ensure we hit the cache, load a cached image over
- * https inside an https page
- * - the server would have responded with a 302 redirect to a >> HTTP <<
- * image, but instead we try to use the cached image.
- * - the image should not load
- *
- * Double redirect image test
- * 7. Load an image over https inside an http page
- * - the server responds with a 302 redirect to a >> HTTP << server
- * - the HTTP server responds with a 302 redirect to a >> HTTPS << image
- * - the image should load and get cached
- *
- * Double redirect cached image tests
- * 8. Using offline mode to ensure we hit the cache, load a cached image over
- * https inside an http page
- * - the image would have gone through two redirects: HTTPS->HTTP->HTTPS,
- * but instead we try to use the cached image.
- * - the image should load
- *
- * 9. Using offline mode to ensure we hit the cache, load a cached image over
- * https inside an https page
- * - the image would have gone through two redirects: HTTPS->HTTP->HTTPS,
- * but instead we try to use the cached image.
- * - the image should not load
- */
-
-const PREF_ACTIVE = "security.mixed_content.block_active_content";
-const PREF_DISPLAY = "security.mixed_content.block_display_content";
-const gHttpsTestRoot = "https://example.com/browser/browser/base/content/test/general/";
-const gHttpTestRoot = "http://example.com/browser/browser/base/content/test/general/";
-
-var origBlockActive;
-var origBlockDisplay;
-var gTestBrowser = null;
-
-// ------------------------ Helper Functions ---------------------
-
-registerCleanupFunction(function() {
- // Set preferences back to their original values
- Services.prefs.setBoolPref(PREF_ACTIVE, origBlockActive);
- Services.prefs.setBoolPref(PREF_DISPLAY, origBlockDisplay);
-
- // Make sure we are online again
- Services.io.offline = false;
-});
-
-function cleanUpAfterTests() {
- gBrowser.removeCurrentTab();
- window.focus();
- finish();
-}
-
-function waitForCondition(condition, nextTest, errorMsg, okMsg) {
- var tries = 0;
- var interval = setInterval(function() {
- if (tries >= 30) {
- ok(false, errorMsg);
- moveOn();
- }
- if (condition()) {
- ok(true, okMsg)
- moveOn();
- }
- tries++;
- }, 500);
- var moveOn = function() {
- clearInterval(interval); nextTest();
- };
-}
-
-// ------------------------ Test 1 ------------------------------
-
-function test1() {
- gTestBrowser.addEventListener("load", checkUIForTest1, true);
- var url = gHttpsTestRoot + "test_mcb_redirect.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkUIForTest1() {
- gTestBrowser.removeEventListener("load", checkUIForTest1, true);
-
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-
- var expected = "script blocked";
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test2, "Error: Waited too long for status in Test 1!",
- "OK: Expected result in innerHTML for Test1!");
-}
-
-// ------------------------ Test 2 ------------------------------
-
-function test2() {
- gTestBrowser.addEventListener("load", checkUIForTest2, true);
- var url = gHttpTestRoot + "test_mcb_redirect.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkUIForTest2() {
- gTestBrowser.removeEventListener("load", checkUIForTest2, true);
-
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
-
- var expected = "script executed";
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test3, "Error: Waited too long for status in Test 2!",
- "OK: Expected result in innerHTML for Test2!");
-}
-
-// ------------------------ Test 3 ------------------------------
-// HTTPS page loading insecure image
-function test3() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest3, true);
- var url = gHttpsTestRoot + "test_mcb_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest3() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest3, true);
-
- var expected = "image blocked"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test4, "Error: Waited too long for status in Test 3!",
- "OK: Expected result in innerHTML for Test3!");
-}
-
-// ------------------------ Test 4 ------------------------------
-// HTTP page loading insecure image
-function test4() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest4, true);
- var url = gHttpTestRoot + "test_mcb_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest4() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest4, true);
-
- var expected = "image loaded"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test5, "Error: Waited too long for status in Test 4!",
- "OK: Expected result in innerHTML for Test4!");
-}
-
-// ------------------------ Test 5 ------------------------------
-// HTTP page laoding insecure cached image
-// Assuming test 4 succeeded, the image has already been loaded once
-// and hence should be cached per the sjs cache-control header
-// Going into offline mode to ensure we are loading from the cache.
-function test5() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest5, true);
- // Go into offline mode
- Services.io.offline = true;
- var url = gHttpTestRoot + "test_mcb_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest5() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest5, true);
-
- var expected = "image loaded"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test6, "Error: Waited too long for status in Test 5!",
- "OK: Expected result in innerHTML for Test5!");
- // Go back online
- Services.io.offline = false;
-}
-
-// ------------------------ Test 6 ------------------------------
-// HTTPS page loading insecure cached image
-// Assuming test 4 succeeded, the image has already been loaded once
-// and hence should be cached per the sjs cache-control header
-// Going into offline mode to ensure we are loading from the cache.
-function test6() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest6, true);
- // Go into offline mode
- Services.io.offline = true;
- var url = gHttpsTestRoot + "test_mcb_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest6() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest6, true);
-
- var expected = "image blocked"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test7, "Error: Waited too long for status in Test 6!",
- "OK: Expected result in innerHTML for Test6!");
- // Go back online
- Services.io.offline = false;
-}
-
-// ------------------------ Test 7 ------------------------------
-// HTTP page loading insecure image that went through a double redirect
-function test7() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest7, true);
- var url = gHttpTestRoot + "test_mcb_double_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest7() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest7, true);
-
- var expected = "image loaded"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test8, "Error: Waited too long for status in Test 7!",
- "OK: Expected result in innerHTML for Test7!");
-}
-
-// ------------------------ Test 8 ------------------------------
-// HTTP page loading insecure cached image that went through a double redirect
-// Assuming test 7 succeeded, the image has already been loaded once
-// and hence should be cached per the sjs cache-control header
-// Going into offline mode to ensure we are loading from the cache.
-function test8() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest8, true);
- // Go into offline mode
- Services.io.offline = true;
- var url = gHttpTestRoot + "test_mcb_double_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest8() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest8, true);
-
- var expected = "image loaded"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- test9, "Error: Waited too long for status in Test 8!",
- "OK: Expected result in innerHTML for Test8!");
- // Go back online
- Services.io.offline = false;
-}
-
-// ------------------------ Test 9 ------------------------------
-// HTTPS page loading insecure cached image that went through a double redirect
-// Assuming test 7 succeeded, the image has already been loaded once
-// and hence should be cached per the sjs cache-control header
-// Going into offline mode to ensure we are loading from the cache.
-function test9() {
- gTestBrowser.addEventListener("load", checkLoadEventForTest9, true);
- // Go into offline mode
- Services.io.offline = true;
- var url = gHttpsTestRoot + "test_mcb_double_redirect_image.html"
- gTestBrowser.contentWindow.location = url;
-}
-
-function checkLoadEventForTest9() {
- gTestBrowser.removeEventListener("load", checkLoadEventForTest9, true);
-
- var expected = "image blocked"
- waitForCondition(
- () => content.document.getElementById('mctestdiv').innerHTML == expected,
- cleanUpAfterTests, "Error: Waited too long for status in Test 9!",
- "OK: Expected result in innerHTML for Test9!");
- // Go back online
- Services.io.offline = false;
-}
-
-// ------------------------ SETUP ------------------------------
-
-function test() {
- // Performing async calls, e.g. 'onload', we have to wait till all of them finished
- waitForExplicitFinish();
-
- // Store original preferences so we can restore settings after testing
- origBlockActive = Services.prefs.getBoolPref(PREF_ACTIVE);
- origBlockDisplay = Services.prefs.getBoolPref(PREF_DISPLAY);
- Services.prefs.setBoolPref(PREF_ACTIVE, true);
- Services.prefs.setBoolPref(PREF_DISPLAY, true);
-
- pushPrefs(["dom.ipc.processCount", 1]).then(() => {
- var newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
- newTab.linkedBrowser.stop();
-
- executeSoon(test1);
- });
-}
diff --git a/browser/base/content/test/general/browser_menuButtonBadgeManager.js b/browser/base/content/test/general/browser_menuButtonBadgeManager.js
deleted file mode 100644
index 9afe39ab7..000000000
--- a/browser/base/content/test/general/browser_menuButtonBadgeManager.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var menuButton = document.getElementById("PanelUI-menu-button");
-
-add_task(function* testButtonActivities() {
- is(menuButton.hasAttribute("badge-status"), false, "Should not have a badge status");
- is(menuButton.hasAttribute("badge"), false, "Should not have the badge attribute set");
-
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_FXA, "fxa-needs-authentication");
- is(menuButton.getAttribute("badge-status"), "fxa-needs-authentication", "Should have fxa-needs-authentication badge status");
-
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_APPUPDATE, "update-succeeded");
- is(menuButton.getAttribute("badge-status"), "update-succeeded", "Should have update-succeeded badge status (update > fxa)");
-
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_APPUPDATE, "update-failed");
- is(menuButton.getAttribute("badge-status"), "update-failed", "Should have update-failed badge status");
-
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_DOWNLOAD, "download-severe");
- is(menuButton.getAttribute("badge-status"), "download-severe", "Should have download-severe badge status");
-
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_DOWNLOAD, "download-warning");
- is(menuButton.getAttribute("badge-status"), "download-warning", "Should have download-warning badge status");
-
- gMenuButtonBadgeManager.addBadge("unknownbadge", "attr");
- is(menuButton.getAttribute("badge-status"), "download-warning", "Should not have changed badge status");
-
- gMenuButtonBadgeManager.removeBadge(gMenuButtonBadgeManager.BADGEID_DOWNLOAD);
- is(menuButton.getAttribute("badge-status"), "update-failed", "Should have update-failed badge status");
-
- gMenuButtonBadgeManager.removeBadge(gMenuButtonBadgeManager.BADGEID_APPUPDATE);
- is(menuButton.getAttribute("badge-status"), "fxa-needs-authentication", "Should have fxa-needs-authentication badge status");
-
- gMenuButtonBadgeManager.removeBadge(gMenuButtonBadgeManager.BADGEID_FXA);
- is(menuButton.hasAttribute("badge-status"), false, "Should not have a badge status");
-
- yield PanelUI.show();
- is(menuButton.hasAttribute("badge-status"), false, "Should not have a badge status (Hamburger menu opened)");
- PanelUI.hide();
-
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_FXA, "fxa-needs-authentication");
- gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_APPUPDATE, "update-succeeded");
- gMenuButtonBadgeManager.clearBadges();
- is(menuButton.hasAttribute("badge-status"), false, "Should not have a badge status (clearBadges called)");
-});
diff --git a/browser/base/content/test/general/browser_menuButtonFitts.js b/browser/base/content/test/general/browser_menuButtonFitts.js
deleted file mode 100644
index e2541b925..000000000
--- a/browser/base/content/test/general/browser_menuButtonFitts.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-function test () {
- waitForExplicitFinish();
- 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);
- var xPixel = boundingRect.width - 1; // Use the last pixel of the screen since it is maximized.
-
- function onPopupHidden() {
- PanelUI.panel.removeEventListener("popuphidden", onPopupHidden);
- window.restore();
- finish();
- }
- function onPopupShown() {
- PanelUI.panel.removeEventListener("popupshown", onPopupShown);
- ok(true, "Clicking at the far edge of the window opened the menu popup.");
- PanelUI.panel.addEventListener("popuphidden", onPopupHidden);
- PanelUI.hide();
- }
- registerCleanupFunction(function() {
- PanelUI.panel.removeEventListener("popupshown", onPopupShown);
- PanelUI.panel.removeEventListener("popuphidden", onPopupHidden);
- });
- PanelUI.panel.addEventListener("popupshown", onPopupShown);
- EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window);
-}
diff --git a/browser/base/content/test/general/browser_middleMouse_noJSPaste.js b/browser/base/content/test/general/browser_middleMouse_noJSPaste.js
deleted file mode 100644
index fa0c26f78..000000000
--- a/browser/base/content/test/general/browser_middleMouse_noJSPaste.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const middleMousePastePref = "middlemouse.contentLoadURL";
-const autoScrollPref = "general.autoScroll";
-
-add_task(function* () {
- yield pushPrefs([middleMousePastePref, true], [autoScrollPref, false]);
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
-
- let url = "javascript:http://www.example.com/";
- yield new Promise((resolve, reject) => {
- SimpleTest.waitForClipboard(url, () => {
- Components.classes["@mozilla.org/widget/clipboardhelper;1"]
- .getService(Components.interfaces.nsIClipboardHelper)
- .copyString(url);
- }, resolve, () => {
- ok(false, "Clipboard copy failed");
- reject();
- });
- });
-
- let middlePagePromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- // Middle click on the content area
- info("Middle clicking");
- yield BrowserTestUtils.synthesizeMouse(null, 10, 10, {button: 1}, gBrowser.selectedBrowser);
- yield middlePagePromise;
-
- is(gBrowser.currentURI.spec, url.replace(/^javascript:/, ""), "url loaded by middle click doesn't include JS");
-
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_minimize.js b/browser/base/content/test/general/browser_minimize.js
deleted file mode 100644
index 1d761c0da..000000000
--- a/browser/base/content/test/general/browser_minimize.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function *() {
- registerCleanupFunction(function() {
- window.restore();
- });
- function waitForActive() { return gBrowser.selectedTab.linkedBrowser.docShellIsActive; }
- function waitForInactive() { return !gBrowser.selectedTab.linkedBrowser.docShellIsActive; }
- yield promiseWaitForCondition(waitForActive);
- is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, true, "Docshell should be active");
- window.minimize();
- yield promiseWaitForCondition(waitForInactive);
- is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, false, "Docshell should be Inactive");
- window.restore();
- yield promiseWaitForCondition(waitForActive);
- is(gBrowser.selectedTab.linkedBrowser.docShellIsActive, true, "Docshell should be active again");
-});
diff --git a/browser/base/content/test/general/browser_misused_characters_in_strings.js b/browser/base/content/test/general/browser_misused_characters_in_strings.js
deleted file mode 100644
index fe8022662..000000000
--- a/browser/base/content/test/general/browser_misused_characters_in_strings.js
+++ /dev/null
@@ -1,244 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* This list allows pre-existing or 'unfixable' issues to remain, while we
- * detect newly occurring issues in shipping files. It is a list of objects
- * specifying conditions under which an error should be ignored.
- *
- * As each issue is found in the whitelist, it is removed from the list. At
- * the end of the test, there is an assertion that all items have been
- * removed from the whitelist, thus ensuring there are no stale entries. */
-let gWhitelist = [{
- file: "search.properties",
- key: "searchForSomethingWith",
- type: "single-quote"
- }, {
- file: "netError.dtd",
- key: "certerror.introPara",
- type: "single-quote"
- }, {
- file: "netError.dtd",
- key: "weakCryptoAdvanced.longDesc",
- type: "single-quote"
- }, {
- file: "netError.dtd",
- key: "weakCryptoAdvanced.override",
- type: "single-quote"
- }, {
- file: "netError.dtd",
- key: "inadequateSecurityError.longDesc",
- type: "single-quote"
- }, {
- file: "netError.dtd",
- key: "certerror.wrongSystemTime",
- type: "single-quote"
- }, {
- file: "phishing-afterload-warning-message.dtd",
- key: "safeb.blocked.malwarePage.shortDesc",
- type: "single-quote"
- }, {
- file: "phishing-afterload-warning-message.dtd",
- key: "safeb.blocked.unwantedPage.shortDesc",
- type: "single-quote"
- }, {
- file: "phishing-afterload-warning-message.dtd",
- key: "safeb.blocked.phishingPage.shortDesc2",
- type: "single-quote"
- }, {
- file: "mathfont.properties",
- key: "operator.\\u002E\\u002E\\u002E.postfix",
- type: "ellipsis"
- }, {
- file: "layout_errors.properties",
- key: "ImageMapRectBoundsError",
- type: "double-quote"
- }, {
- file: "layout_errors.properties",
- key: "ImageMapCircleWrongNumberOfCoords",
- type: "double-quote"
- }, {
- file: "layout_errors.properties",
- key: "ImageMapCircleNegativeRadius",
- type: "double-quote"
- }, {
- file: "layout_errors.properties",
- key: "ImageMapPolyWrongNumberOfCoords",
- type: "double-quote"
- }, {
- file: "layout_errors.properties",
- key: "ImageMapPolyOddNumberOfCoords",
- type: "double-quote"
- }, {
- file: "xbl.properties",
- key: "CommandNotInChrome",
- type: "double-quote"
- }, {
- file: "dom.properties",
- key: "PatternAttributeCompileFailure",
- type: "single-quote"
- }, {
- file: "pipnss.properties",
- key: "certErrorMismatchSingle2",
- type: "double-quote"
- }, {
- file: "pipnss.properties",
- key: "certErrorCodePrefix2",
- type: "double-quote"
- }, {
- file: "aboutSupport.dtd",
- key: "aboutSupport.pageSubtitle",
- type: "single-quote"
- }, {
- file: "aboutSupport.dtd",
- key: "aboutSupport.userJSDescription",
- type: "single-quote"
- }, {
- file: "netError.dtd",
- key: "inadequateSecurityError.longDesc",
- type: "single-quote"
- }, {
- file: "netErrorApp.dtd",
- key: "securityOverride.warningContent",
- type: "single-quote"
- }, {
- file: "pocket.properties",
- key: "tos",
- type: "double-quote"
- }, {
- file: "pocket.properties",
- key: "tos",
- type: "apostrophe"
- }, {
- file: "aboutNetworking.dtd",
- key: "aboutNetworking.logTutorial",
- type: "single-quote"
- }
-];
-
-var moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
-var {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
-
-/**
- * Check if an error should be ignored due to matching one of the whitelist
- * objects defined in gWhitelist.
- *
- * @param filepath The URI spec of the locale file
- * @param key The key of the entity that is being checked
- * @param type The type of error that has been found
- * @return true if the error should be ignored, false otherwise.
- */
-function ignoredError(filepath, key, type) {
- for (let index in gWhitelist) {
- let whitelistItem = gWhitelist[index];
- if (filepath.endsWith(whitelistItem.file) &&
- key == whitelistItem.key &&
- type == whitelistItem.type) {
- gWhitelist.splice(index, 1);
- return true;
- }
- }
- return false;
-}
-
-function fetchFile(uri) {
- return new Promise((resolve, reject) => {
- let xhr = new XMLHttpRequest();
- xhr.open("GET", uri, true);
- xhr.onreadystatechange = function() {
- if (this.readyState != this.DONE) {
- return;
- }
- try {
- resolve(this.responseText);
- } catch (ex) {
- ok(false, `Script error reading ${uri}: ${ex}`);
- resolve("");
- }
- };
- xhr.onerror = error => {
- ok(false, `XHR error reading ${uri}: ${error}`);
- resolve("");
- };
- xhr.send(null);
- });
-}
-
-function testForError(filepath, key, str, pattern, type, helpText) {
- if (str.match(pattern) &&
- !ignoredError(filepath, key, type)) {
- ok(false, `${filepath} with key=${key} has a misused ${type}. ${helpText}`);
- }
-}
-
-function testForErrors(filepath, key, str) {
- testForError(filepath, key, str, /\w'\w/, "apostrophe", "Strings with apostrophes should use foo\u2019s instead of foo's.");
- testForError(filepath, key, str, /\w\u2018\w/, "incorrect-apostrophe", "Strings with apostrophes should use foo\u2019s instead of foo\u2018s.");
- testForError(filepath, key, str, /'.+'/, "single-quote", "Single-quoted strings should use Unicode \u2018foo\u2019 instead of 'foo'.");
- testForError(filepath, key, str, /"/, "double-quote", "Double-quoted strings should use Unicode \u201cfoo\u201d instead of \"foo\".");
- testForError(filepath, key, str, /\.\.\./, "ellipsis", "Strings with an ellipsis should use the Unicode \u2026 character instead of three periods.");
-}
-
-function* getAllTheFiles(extension) {
- let appDirGreD = Services.dirsvc.get("GreD", Ci.nsIFile);
- let appDirXCurProcD = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
- if (appDirGreD.contains(appDirXCurProcD)) {
- return yield generateURIsFromDirTree(appDirGreD, [extension]);
- }
- if (appDirXCurProcD.contains(appDirGreD)) {
- return yield generateURIsFromDirTree(appDirXCurProcD, [extension]);
- }
- let urisGreD = yield generateURIsFromDirTree(appDirGreD, [extension]);
- let urisXCurProcD = yield generateURIsFromDirTree(appDirXCurProcD, [extension]);
- return Array.from(new Set(urisGreD.concat(appDirXCurProcD)));
-}
-
-add_task(function* checkAllTheProperties() {
- // This asynchronously produces a list of URLs (sadly, mostly sync on our
- // test infrastructure because it runs against jarfiles there, and
- // our zipreader APIs are all sync)
- let uris = yield getAllTheFiles(".properties");
- ok(uris.length, `Found ${uris.length} .properties files to scan for misused characters`);
-
- for (let uri of uris) {
- let bundle = new StringBundle(uri.spec);
- let entities = bundle.getAll();
- for (let entity of entities) {
- testForErrors(uri.spec, entity.key, entity.value);
- }
- }
-});
-
-var checkDTD = Task.async(function* (aURISpec) {
- let rawContents = yield fetchFile(aURISpec);
- // The regular expression below is adapted from:
- // https://hg.mozilla.org/mozilla-central/file/68c0b7d6f16ce5bb023e08050102b5f2fe4aacd8/python/compare-locales/compare_locales/parser.py#l233
- let entities = rawContents.match(/<!ENTITY\s+([\w\.]*)\s+("[^"]*"|'[^']*')\s*>/g);
- if (!entities) {
- // Some files, such as requestAutocomplete.dtd, have no entities defined.
- return;
- }
- for (let entity of entities) {
- let [, key, str] = entity.match(/<!ENTITY\s+([\w\.]*)\s+("[^"]*"|'[^']*')\s*>/);
- // The matched string includes the enclosing quotation marks,
- // we need to slice them off.
- str = str.slice(1, -1);
- testForErrors(aURISpec, key, str);
- }
-});
-
-add_task(function* checkAllTheDTDs() {
- let uris = yield getAllTheFiles(".dtd");
- ok(uris.length, `Found ${uris.length} .dtd files to scan for misused characters`);
- for (let uri of uris) {
- yield checkDTD(uri.spec);
- }
-
- // This support DTD file supplies a string with a newline to make sure
- // the regex in checkDTD works correctly for that case.
- let dtdLocation = gTestPath.replace(/\/[^\/]*$/i, "/bug1262648_string_with_newlines.dtd");
- yield checkDTD(dtdLocation);
-});
-
-add_task(function* ensureWhiteListIsEmpty() {
- is(gWhitelist.length, 0, "No remaining whitelist entries exist");
-});
diff --git a/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js b/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js
deleted file mode 100644
index ac19efd05..000000000
--- a/browser/base/content/test/general/browser_mixedContentFramesOnHttp.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- *
- * Test for Bug 1182551 -
- *
- * This test has a top level HTTP page with an HTTPS iframe. The HTTPS iframe
- * includes an HTTP image. We check that the top level security state is
- * STATE_IS_INSECURE. The mixed content from the iframe shouldn't "upgrade"
- * the HTTP top level page to broken HTTPS.
- */
-
-const gHttpTestUrl = "http://example.com/browser/browser/base/content/test/general/file_mixedContentFramesOnHttp.html";
-
-var gTestBrowser = null;
-
-add_task(function *() {
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({
- "set": [
- ["security.mixed_content.block_active_content", true],
- ["security.mixed_content.block_display_content", false]
- ]
- }, resolve);
- });
- let url = gHttpTestUrl
- yield BrowserTestUtils.withNewTab({gBrowser, url}, function*() {
- gTestBrowser = gBrowser.selectedBrowser;
- // check security state is insecure
- isSecurityState("insecure");
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
- });
-});
-
diff --git a/browser/base/content/test/general/browser_mixedContentFromOnunload.js b/browser/base/content/test/general/browser_mixedContentFromOnunload.js
deleted file mode 100644
index 9b39776f4..000000000
--- a/browser/base/content/test/general/browser_mixedContentFromOnunload.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- *
- * Tests for Bug 947079 - Fix bug in nsSecureBrowserUIImpl that sets the wrong
- * security state on a page because of a subresource load that is not on the
- * same page.
- */
-
-// We use different domains for each test and for navigation within each test
-const gHttpTestRoot1 = "http://example.com/browser/browser/base/content/test/general/";
-const gHttpsTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
-const gHttpTestRoot2 = "http://example.net/browser/browser/base/content/test/general/";
-const gHttpsTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
-
-var gTestBrowser = null;
-add_task(function *() {
- let url = gHttpTestRoot1 + "file_mixedContentFromOnunload.html";
- yield BrowserTestUtils.withNewTab({gBrowser, url}, function*() {
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({
- "set": [
- ["security.mixed_content.block_active_content", true],
- ["security.mixed_content.block_display_content", false]
- ]
- }, resolve);
- });
- gTestBrowser = gBrowser.selectedBrowser;
- // Navigation from an http page to a https page with no mixed content
- // The http page loads an http image on unload
- url = gHttpsTestRoot1 + "file_mixedContentFromOnunload_test1.html";
- yield BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
- // check security state. Since current url is https and doesn't have any
- // mixed content resources, we expect it to be secure.
- isSecurityState("secure");
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
- // Navigation from an http page to a https page that has mixed display content
- // The https page loads an http image on unload
- url = gHttpTestRoot2 + "file_mixedContentFromOnunload.html";
- yield BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
- url = gHttpsTestRoot2 + "file_mixedContentFromOnunload_test2.html";
- yield BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
- isSecurityState("broken");
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
- });
-});
diff --git a/browser/base/content/test/general/browser_mixed_content_cert_override.js b/browser/base/content/test/general/browser_mixed_content_cert_override.js
deleted file mode 100644
index 037fce5d2..000000000
--- a/browser/base/content/test/general/browser_mixed_content_cert_override.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Bug 1253771 - check mixed content blocking in combination with overriden certificates
- */
-
-"use strict";
-
-const MIXED_CONTENT_URL = "https://self-signed.example.com/browser/browser/base/content/test/general/test-mixedcontent-securityerrors.html";
-
-function getConnectionState() {
- return document.getElementById("identity-popup").getAttribute("connection");
-}
-
-function getPopupContentVerifier() {
- return document.getElementById("identity-popup-content-verifier");
-}
-
-function getConnectionIcon() {
- return window.getComputedStyle(document.getElementById("connection-icon")).listStyleImage;
-}
-
-function checkIdentityPopup(icon) {
- gIdentityHandler.refreshIdentityPopup();
- is(getConnectionIcon(), `url("chrome://browser/skin/${icon}")`);
- is(getConnectionState(), "secure-cert-user-overridden");
- isnot(getPopupContentVerifier().style.display, "none", "Overridden certificate warning is shown");
- ok(getPopupContentVerifier().textContent.includes("security exception"), "Text shows overridden certificate warning.");
-}
-
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser);
-
- // check that a warning is shown when loading a page with mixed content and an overridden certificate
- yield loadBadCertPage(MIXED_CONTENT_URL);
- checkIdentityPopup("connection-mixed-passive-loaded.svg#icon");
-
- // check that the crossed out icon is shown when disabling mixed content protection
- gIdentityHandler.disableMixedContentProtection();
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-
- checkIdentityPopup("connection-mixed-active-loaded.svg#icon");
-
- // check that a warning is shown even without mixed content
- yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://self-signed.example.com");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- checkIdentityPopup("connection-mixed-passive-loaded.svg#icon");
-
- // remove cert exception
- let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
- .getService(Ci.nsICertOverrideService);
- certOverrideService.clearValidityOverride("self-signed.example.com", -1);
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
diff --git a/browser/base/content/test/general/browser_mixedcontent_securityflags.js b/browser/base/content/test/general/browser_mixedcontent_securityflags.js
deleted file mode 100644
index 1c2614b86..000000000
--- a/browser/base/content/test/general/browser_mixedcontent_securityflags.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// The test loads a web page with mixed active and mixed display content and
-// makes sure that the mixed content flags on the docshell are set correctly.
-// * Using default about:config prefs (mixed active blocked, mixed display
-// loaded) we load the page and check the flags.
-// * We change the about:config prefs (mixed active blocked, mixed display
-// blocked), reload the page, and check the flags again.
-// * We override protection so all mixed content can load and check the
-// flags again.
-
-const TEST_URI = "https://example.com/browser/browser/base/content/test/general/test-mixedcontent-securityerrors.html";
-const PREF_DISPLAY = "security.mixed_content.block_display_content";
-const PREF_ACTIVE = "security.mixed_content.block_active_content";
-var gTestBrowser = null;
-
-registerCleanupFunction(function() {
- // Set preferences back to their original values
- Services.prefs.clearUserPref(PREF_DISPLAY);
- Services.prefs.clearUserPref(PREF_ACTIVE);
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* blockMixedActiveContentTest() {
- // Turn on mixed active blocking and mixed display loading and load the page.
- Services.prefs.setBoolPref(PREF_DISPLAY, false);
- Services.prefs.setBoolPref(PREF_ACTIVE, true);
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URI);
- gTestBrowser = gBrowser.getBrowserForTab(tab);
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- is(docShell.hasMixedDisplayContentBlocked, false, "hasMixedDisplayContentBlocked flag has been set");
- is(docShell.hasMixedActiveContentBlocked, true, "hasMixedActiveContentBlocked flag has been set");
- is(docShell.hasMixedDisplayContentLoaded, true, "hasMixedDisplayContentLoaded flag has been set");
- is(docShell.hasMixedActiveContentLoaded, false, "hasMixedActiveContentLoaded flag has been set");
- });
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: true});
-
- // Turn on mixed active and mixed display blocking and reload the page.
- Services.prefs.setBoolPref(PREF_DISPLAY, true);
- Services.prefs.setBoolPref(PREF_ACTIVE, true);
-
- gBrowser.reload();
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- is(docShell.hasMixedDisplayContentBlocked, true, "hasMixedDisplayContentBlocked flag has been set");
- is(docShell.hasMixedActiveContentBlocked, true, "hasMixedActiveContentBlocked flag has been set");
- is(docShell.hasMixedDisplayContentLoaded, false, "hasMixedDisplayContentLoaded flag has been set");
- is(docShell.hasMixedActiveContentLoaded, false, "hasMixedActiveContentLoaded flag has been set");
- });
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
-});
-
-add_task(function* overrideMCB() {
- // Disable mixed content blocking (reloads page) and retest
- let {gIdentityHandler} = gTestBrowser.ownerGlobal;
- gIdentityHandler.disableMixedContentProtection();
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- is(docShell.hasMixedDisplayContentLoaded, true, "hasMixedDisplayContentLoaded flag has not been set");
- is(docShell.hasMixedActiveContentLoaded, true, "hasMixedActiveContentLoaded flag has not been set");
- is(docShell.hasMixedDisplayContentBlocked, false, "second hasMixedDisplayContentBlocked flag has been set");
- is(docShell.hasMixedActiveContentBlocked, false, "second hasMixedActiveContentBlocked flag has been set");
- });
- assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: true});
-});
diff --git a/browser/base/content/test/general/browser_modifiedclick_inherit_principal.js b/browser/base/content/test/general/browser_modifiedclick_inherit_principal.js
deleted file mode 100644
index 3b5a5a149..000000000
--- a/browser/base/content/test/general/browser_modifiedclick_inherit_principal.js
+++ /dev/null
@@ -1,30 +0,0 @@
-"use strict";
-
-const kURL =
- "http://example.com/browser/browser/base/content/test/general/dummy_page.html";
- "data:text/html,<a href=''>Middle-click me</a>";
-
-/*
- * Check that when manually opening content JS links in new tabs/windows,
- * we use the correct principal, and we don't clear the URL bar.
- */
-add_task(function* () {
- yield BrowserTestUtils.withNewTab(kURL, function* (browser) {
- let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
- yield ContentTask.spawn(browser, null, function* () {
- let a = content.document.createElement("a");
- a.href = "javascript:document.write('spoof'); void(0);";
- a.textContent = "Some link";
- content.document.body.appendChild(a);
- });
- info("Added element");
- yield BrowserTestUtils.synthesizeMouseAtCenter("a", {button: 1}, browser);
- let newTab = yield newTabPromise;
- is(newTab.linkedBrowser.contentPrincipal.origin, "http://example.com",
- "Principal should be for example.com");
- yield BrowserTestUtils.switchTab(gBrowser, newTab);
- info(gURLBar.value);
- isnot(gURLBar.value, "", "URL bar should not be empty.");
- yield BrowserTestUtils.removeTab(newTab);
- });
-});
diff --git a/browser/base/content/test/general/browser_newTabDrop.js b/browser/base/content/test/general/browser_newTabDrop.js
deleted file mode 100644
index 03c90df3f..000000000
--- a/browser/base/content/test/general/browser_newTabDrop.js
+++ /dev/null
@@ -1,99 +0,0 @@
-registerCleanupFunction(function* cleanup() {
- while (gBrowser.tabs.length > 1) {
- yield BrowserTestUtils.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
- }
- Services.search.currentEngine = originalEngine;
- let engine = Services.search.getEngineByName("MozSearch");
- Services.search.removeEngine(engine);
-});
-
-let originalEngine;
-add_task(function* test_setup() {
- // Stop search-engine loads from hitting the network
- Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- let engine = Services.search.getEngineByName("MozSearch");
- originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-});
-
-// New Tab Button opens any link.
-add_task(function*() { yield dropText("mochi.test/first", 1); });
-add_task(function*() { yield dropText("javascript:'bad'", 1); });
-add_task(function*() { yield dropText("jAvascript:'bad'", 1); });
-add_task(function*() { yield dropText("mochi.test/second", 1); });
-add_task(function*() { yield dropText("data:text/html,bad", 1); });
-add_task(function*() { yield dropText("mochi.test/third", 1); });
-
-// Single text/plain item, with multiple links.
-add_task(function*() { yield dropText("mochi.test/1\nmochi.test/2", 2); });
-add_task(function*() { yield dropText("javascript:'bad1'\nmochi.test/3", 2); });
-add_task(function*() { yield dropText("mochi.test/4\ndata:text/html,bad1", 2); });
-
-// Multiple text/plain items, with single and multiple links.
-add_task(function*() {
- yield drop([[{type: "text/plain",
- data: "mochi.test/5"}],
- [{type: "text/plain",
- data: "mochi.test/6\nmochi.test/7"}]], 3);
-});
-
-// Single text/x-moz-url item, with multiple links.
-// "text/x-moz-url" has titles in even-numbered lines.
-add_task(function*() {
- yield drop([[{type: "text/x-moz-url",
- data: "mochi.test/8\nTITLE8\nmochi.test/9\nTITLE9"}]], 2);
-});
-
-// Single item with multiple types.
-add_task(function*() {
- yield drop([[{type: "text/plain",
- data: "mochi.test/10"},
- {type: "text/x-moz-url",
- data: "mochi.test/11\nTITLE11"}]], 1);
-});
-
-function dropText(text, expectedTabOpenCount=0) {
- return drop([[{type: "text/plain", data: text}]], expectedTabOpenCount);
-}
-
-function* drop(dragData, expectedTabOpenCount=0) {
- let dragDataString = JSON.stringify(dragData);
- info(`Starting test for datagData:${dragDataString}; expectedTabOpenCount:${expectedTabOpenCount}`);
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- // Since synthesizeDrop triggers the srcElement, need to use another button.
- let dragSrcElement = document.getElementById("downloads-button");
- ok(dragSrcElement, "Downloads button exists");
- let newTabButton = document.getElementById("new-tab-button");
- ok(newTabButton, "New Tab button exists");
-
- let awaitDrop = BrowserTestUtils.waitForEvent(newTabButton, "drop");
- let actualTabOpenCount = 0;
- let openedTabs = [];
- let checkCount = function(event) {
- openedTabs.push(event.target);
- actualTabOpenCount++;
- return actualTabOpenCount == expectedTabOpenCount;
- };
- let awaitTabOpen = expectedTabOpenCount && BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen", false, checkCount);
-
- EventUtils.synthesizeDrop(dragSrcElement, newTabButton, dragData, "link", window);
-
- let tabsOpened = false;
- if (awaitTabOpen) {
- yield awaitTabOpen;
- info("Got TabOpen event");
- tabsOpened = true;
- for (let tab of openedTabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- }
- is(tabsOpened, !!expectedTabOpenCount, `Tabs for ${dragDataString} should only open if any of dropped items are valid`);
-
- yield awaitDrop;
- ok(true, "Got drop event");
-}
diff --git a/browser/base/content/test/general/browser_newWindowDrop.js b/browser/base/content/test/general/browser_newWindowDrop.js
deleted file mode 100644
index f404d4eed..000000000
--- a/browser/base/content/test/general/browser_newWindowDrop.js
+++ /dev/null
@@ -1,120 +0,0 @@
-registerCleanupFunction(function* cleanup() {
- Services.search.currentEngine = originalEngine;
- let engine = Services.search.getEngineByName("MozSearch");
- Services.search.removeEngine(engine);
-});
-
-let originalEngine;
-add_task(function* test_setup() {
- // Opening multiple windows on debug build takes too long time.
- requestLongerTimeout(10);
-
- // Stop search-engine loads from hitting the network
- Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- let engine = Services.search.getEngineByName("MozSearch");
- originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- // Move New Window button to nav bar, to make it possible to drag and drop.
- let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
- let origPlacement = CustomizableUI.getPlacementOfWidget("new-window-button");
- if (!origPlacement || origPlacement.area != CustomizableUI.AREA_NAVBAR) {
- CustomizableUI.addWidgetToArea("new-window-button",
- CustomizableUI.AREA_NAVBAR,
- 0);
- CustomizableUI.ensureWidgetPlacedInWindow("new-window-button", window);
- registerCleanupFunction(function () {
- CustomizableUI.reset();
- });
- }
-});
-
-// New Window Button opens any link.
-add_task(function*() { yield dropText("mochi.test/first", 1); });
-add_task(function*() { yield dropText("javascript:'bad'", 1); });
-add_task(function*() { yield dropText("jAvascript:'bad'", 1); });
-add_task(function*() { yield dropText("mochi.test/second", 1); });
-add_task(function*() { yield dropText("data:text/html,bad", 1); });
-add_task(function*() { yield dropText("mochi.test/third", 1); });
-
-// Single text/plain item, with multiple links.
-add_task(function*() { yield dropText("mochi.test/1\nmochi.test/2", 2); });
-add_task(function*() { yield dropText("javascript:'bad1'\nmochi.test/3", 2); });
-add_task(function*() { yield dropText("mochi.test/4\ndata:text/html,bad1", 2); });
-
-// Multiple text/plain items, with single and multiple links.
-add_task(function*() {
- yield drop([[{type: "text/plain",
- data: "mochi.test/5"}],
- [{type: "text/plain",
- data: "mochi.test/6\nmochi.test/7"}]], 3);
-});
-
-// Single text/x-moz-url item, with multiple links.
-// "text/x-moz-url" has titles in even-numbered lines.
-add_task(function*() {
- yield drop([[{type: "text/x-moz-url",
- data: "mochi.test/8\nTITLE8\nmochi.test/9\nTITLE9"}]], 2);
-});
-
-// Single item with multiple types.
-add_task(function*() {
- yield drop([[{type: "text/plain",
- data: "mochi.test/10"},
- {type: "text/x-moz-url",
- data: "mochi.test/11\nTITLE11"}]], 1);
-});
-
-function dropText(text, expectedWindowOpenCount=0) {
- return drop([[{type: "text/plain", data: text}]], expectedWindowOpenCount);
-}
-
-function* drop(dragData, expectedWindowOpenCount=0) {
- let dragDataString = JSON.stringify(dragData);
- info(`Starting test for datagData:${dragDataString}; expectedWindowOpenCount:${expectedWindowOpenCount}`);
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- // Since synthesizeDrop triggers the srcElement, need to use another button.
- let dragSrcElement = document.getElementById("downloads-button");
- ok(dragSrcElement, "Downloads button exists");
- let newWindowButton = document.getElementById("new-window-button");
- ok(newWindowButton, "New Window button exists");
-
- let tmp = {};
- Cu.import("resource://testing-common/TestUtils.jsm", tmp);
-
- let awaitDrop = BrowserTestUtils.waitForEvent(newWindowButton, "drop");
- let actualWindowOpenCount = 0;
- let openedWindows = [];
- let checkCount = function(window) {
- // Add observer as soon as domWindow is opened to avoid missing the topic.
- let awaitStartup = tmp.TestUtils.topicObserved("browser-delayed-startup-finished",
- subject => subject == window);
- openedWindows.push([window, awaitStartup]);
- actualWindowOpenCount++;
- return actualWindowOpenCount == expectedWindowOpenCount;
- };
- let awaitWindowOpen = expectedWindowOpenCount && BrowserTestUtils.domWindowOpened(null, checkCount);
-
- EventUtils.synthesizeDrop(dragSrcElement, newWindowButton, dragData, "link", window);
-
- let windowsOpened = false;
- if (awaitWindowOpen) {
- yield awaitWindowOpen;
- info("Got Window opened");
- windowsOpened = true;
- for (let [window, awaitStartup] of openedWindows.reverse()) {
- // Wait for startup before closing, to properly close the browser window.
- yield awaitStartup;
- yield BrowserTestUtils.closeWindow(window);
- }
- }
- is(windowsOpened, !!expectedWindowOpenCount, `Windows for ${dragDataString} should only open if any of dropped items are valid`);
-
- yield awaitDrop;
- ok(true, "Got drop event");
-}
diff --git a/browser/base/content/test/general/browser_newwindow_focus.js b/browser/base/content/test/general/browser_newwindow_focus.js
deleted file mode 100644
index 7880db0bd..000000000
--- a/browser/base/content/test/general/browser_newwindow_focus.js
+++ /dev/null
@@ -1,96 +0,0 @@
-"use strict";
-
-/**
- * These tests are for the auto-focus behaviour on the initial browser
- * when a window is opened from content.
- */
-
-const PAGE = `data:text/html,<a id="target" href="%23" onclick="window.open('http://www.example.com', '_blank', 'width=100,height=100');">Click me</a>`;
-
-/**
- * Returns a Promise that resolves when a new window has
- * opened, and the "load" event has fired in that window.
- * We can't use BrowserTestUtils.domWindowOpened directly,
- * because by the time the "then" on the Promise runs,
- * DOMContentLoaded and load may have already run in the new
- * window. However, we want to be very explicit about what
- * events we're waiting for, and not rely on a quirk of our
- * 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);
- resolve(win);
- });
- }
- };
-
- Services.ww.registerNotification(observer);
- });
-}
-
-/**
- * Test that when a new window is opened from content, focus moves
- * to the initial browser in that window once the window has finished
- * painting.
- */
-add_task(function* test_focus_browser() {
- yield BrowserTestUtils.withNewTab({
- url: PAGE,
- gBrowser,
- }, function*(browser) {
- let newWinPromise = promiseNewWindow();
- let delayedStartupPromise = BrowserTestUtils.waitForNewWindow();
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#target", {}, browser);
- let newWin = yield newWinPromise;
- yield BrowserTestUtils.contentPainted(newWin.gBrowser.selectedBrowser);
- yield delayedStartupPromise;
-
- let focusedElement =
- Services.focus.getFocusedElementForWindow(newWin, false, {});
-
- Assert.equal(focusedElement, newWin.gBrowser.selectedBrowser,
- "Initial browser should be focused");
-
- yield BrowserTestUtils.closeWindow(newWin);
- });
-});
-
-/**
- * Test that when a new window is opened from content and focus
- * shifts in that window before the content has a chance to paint
- * that we _don't_ steal focus once content has painted.
- */
-add_task(function* test_no_steal_focus() {
- yield BrowserTestUtils.withNewTab({
- url: PAGE,
- gBrowser,
- }, function*(browser) {
- let newWinPromise = promiseNewWindow();
- let delayedStartupPromise = BrowserTestUtils.waitForNewWindow();
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#target", {}, browser);
- let newWin = yield newWinPromise;
-
- // Because we're switching focus, we shouldn't steal it once
- // content paints.
- newWin.gURLBar.focus();
-
- yield BrowserTestUtils.contentPainted(newWin.gBrowser.selectedBrowser);
- yield delayedStartupPromise;
-
- let focusedElement =
- Services.focus.getFocusedElementForWindow(newWin, false, {});
-
- Assert.equal(focusedElement, newWin.gURLBar.inputField,
- "URLBar should be focused");
-
- yield BrowserTestUtils.closeWindow(newWin);
- });
-});
diff --git a/browser/base/content/test/general/browser_no_mcb_on_http_site.js b/browser/base/content/test/general/browser_no_mcb_on_http_site.js
deleted file mode 100644
index 45fd67379..000000000
--- a/browser/base/content/test/general/browser_no_mcb_on_http_site.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Description of the Tests for
- * - Bug 909920 - Mixed content warning should not show on a HTTP site
- *
- * Description of the tests:
- * Test 1:
- * 1) Load an http page
- * 2) The page includes a css file using https
- * 3) The css file loads an |IMAGE| << over http
- *
- * Test 2:
- * 1) Load an http page
- * 2) The page includes a css file using https
- * 3) The css file loads a |FONT| over http
- *
- * Test 3:
- * 1) Load an http page
- * 2) The page includes a css file using https
- * 3) The css file imports (@import) another css file using http
- * 3) The imported css file loads a |FONT| over http
-*
- * Since the top-domain is >> NOT << served using https, the MCB
- * should >> NOT << trigger a warning.
- */
-
-const PREF_ACTIVE = "security.mixed_content.block_active_content";
-const PREF_DISPLAY = "security.mixed_content.block_display_content";
-
-const gHttpTestRoot = "http://example.com/browser/browser/base/content/test/general/";
-
-var gTestBrowser = null;
-
-function cleanUpAfterTests() {
- gBrowser.removeCurrentTab();
- window.focus();
-}
-
-add_task(function* init() {
- yield SpecialPowers.pushPrefEnv({ set: [[ PREF_ACTIVE, true ],
- [ PREF_DISPLAY, true ]] });
- let url = gHttpTestRoot + "test_no_mcb_on_http_site_img.html";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url)
- gTestBrowser = tab.linkedBrowser;
-});
-
-// ------------- TEST 1 -----------------------------------------
-
-add_task(function* test1() {
- let expected = "Verifying MCB does not trigger warning/error for an http page ";
- expected += "with https css that includes http image";
-
- yield ContentTask.spawn(gTestBrowser, expected, function* (condition) {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("testDiv").innerHTML == condition,
- "Waited too long for status in Test 1!");
- });
-
- // Explicit OKs needed because the harness requires at least one call to ok.
- ok(true, "test 1 passed");
-
- // set up test 2
- let url = gHttpTestRoot + "test_no_mcb_on_http_site_font.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-// ------------- TEST 2 -----------------------------------------
-
-add_task(function* test2() {
- let expected = "Verifying MCB does not trigger warning/error for an http page ";
- expected += "with https css that includes http font";
-
- yield ContentTask.spawn(gTestBrowser, expected, function* (condition) {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("testDiv").innerHTML == condition,
- "Waited too long for status in Test 2!");
- });
-
- ok(true, "test 2 passed");
-
- // set up test 3
- let url = gHttpTestRoot + "test_no_mcb_on_http_site_font2.html";
- BrowserTestUtils.loadURI(gTestBrowser, url);
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-// ------------- TEST 3 -----------------------------------------
-
-add_task(function* test3() {
- let expected = "Verifying MCB does not trigger warning/error for an http page "
- expected += "with https css that imports another http css which includes http font";
-
- yield ContentTask.spawn(gTestBrowser, expected, function* (condition) {
- yield ContentTaskUtils.waitForCondition(
- () => content.document.getElementById("testDiv").innerHTML == condition,
- "Waited too long for status in Test 3!");
- });
-
- ok(true, "test3 passed");
-});
-
-// ------------------------------------------------------
-
-add_task(function* cleanup() {
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/general/browser_offlineQuotaNotification.js b/browser/base/content/test/general/browser_offlineQuotaNotification.js
deleted file mode 100644
index e56bfe9a8..000000000
--- a/browser/base/content/test/general/browser_offlineQuotaNotification.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Test offline quota warnings - must be run as a mochitest-browser test or
-// else the test runner gets in the way of notifications due to bug 857897.
-
-const URL = "http://mochi.test:8888/browser/browser/base/content/test/general/offlineQuotaNotification.html";
-
-registerCleanupFunction(function() {
- // Clean up after ourself
- let uri = Services.io.newURI(URL, null, null);
- let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
- Services.perms.removeFromPrincipal(principal, "offline-app");
- Services.prefs.clearUserPref("offline-apps.quota.warn");
- Services.prefs.clearUserPref("offline-apps.allow_by_default");
- let {OfflineAppCacheHelper} = Components.utils.import("resource:///modules/offlineAppCache.jsm", {});
- OfflineAppCacheHelper.clear();
-});
-
-// Same as the other one, but for in-content preferences
-function checkInContentPreferences(win) {
- let doc = win.document;
- let sel = doc.getElementById("categories").selectedItems[0].id;
- let tab = doc.getElementById("advancedPrefs").selectedTab.id;
- is(gBrowser.currentURI.spec, "about:preferences#advanced", "about:preferences loaded");
- is(sel, "category-advanced", "Advanced pane was selected");
- is(tab, "networkTab", "Network tab is selected");
- // all good, we are done.
- win.close();
- finish();
-}
-
-function test() {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref("offline-apps.allow_by_default", false);
-
- // Open a new tab.
- gBrowser.selectedTab = gBrowser.addTab(URL);
- registerCleanupFunction(() => gBrowser.removeCurrentTab());
-
-
- Promise.all([
- // Wait for a notification that asks whether to allow offline storage.
- promiseNotification(),
- // Wait for the tab to load.
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser),
- ]).then(() => {
- info("Loaded page, adding onCached handler");
- // Need a promise to keep track of when we've added our handler.
- let mm = gBrowser.selectedBrowser.messageManager;
- let onCachedAttached = BrowserTestUtils.waitForMessage(mm, "Test:OnCachedAttached");
- let gotCached = ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- return new Promise(resolve => {
- content.window.applicationCache.oncached = function() {
- setTimeout(resolve, 0);
- };
- sendAsyncMessage("Test:OnCachedAttached");
- });
- });
- 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);
- executeSoon(function() {
- checkInContentPreferences(newTabBrowser.contentWindow);
- })
- }, 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);
- resolve();
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_overflowScroll.js b/browser/base/content/test/general/browser_overflowScroll.js
deleted file mode 100644
index 56932fae2..000000000
--- a/browser/base/content/test/general/browser_overflowScroll.js
+++ /dev/null
@@ -1,91 +0,0 @@
-var tabstrip = gBrowser.tabContainer.mTabstrip;
-var scrollbox = tabstrip._scrollbox;
-var originalSmoothScroll = tabstrip.smoothScroll;
-var tabs = gBrowser.tabs;
-
-var rect = ele => ele.getBoundingClientRect();
-var width = ele => rect(ele).width;
-var left = ele => rect(ele).left;
-var right = ele => rect(ele).right;
-var isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
-var isRight = (ele, msg) => is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
-var elementFromPoint = x => tabstrip._elementFromPoint(x);
-var nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
-var nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
-var firstScrollable = () => tabs[gBrowser._numPinnedTabs];
-
-function test() {
- requestLongerTimeout(2);
- waitForExplicitFinish();
-
- // If the previous (or more) test finished with cleaning up the tabs,
- // there may be some pending animations. That can cause a failure of
- // this tests, so, we should test this in another stack.
- setTimeout(doTest, 0);
-}
-
-function doTest() {
- tabstrip.smoothScroll = false;
-
- var tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
- var tabCountForOverflow = Math.ceil(width(tabstrip) / tabMinWidth * 3);
- while (tabs.length < tabCountForOverflow)
- gBrowser.addTab("about:blank", {skipAnimation: true});
- gBrowser.pinTab(tabs[0]);
-
- tabstrip.addEventListener("overflow", runOverflowTests, false);
-}
-
-function runOverflowTests(aEvent) {
- if (aEvent.detail != 1)
- return;
-
- tabstrip.removeEventListener("overflow", runOverflowTests, false);
-
- var upButton = tabstrip._scrollButtonUp;
- var downButton = tabstrip._scrollButtonDown;
- var element;
-
- gBrowser.selectedTab = firstScrollable();
- ok(left(scrollbox) <= left(firstScrollable()), "Selecting the first tab scrolls it into view " +
- "(" + left(scrollbox) + " <= " + left(firstScrollable()) + ")");
-
- element = nextRightElement();
- EventUtils.synthesizeMouseAtCenter(downButton, {});
- isRight(element, "Scrolled one tab to the right with a single click");
-
- gBrowser.selectedTab = tabs[tabs.length - 1];
- ok(right(gBrowser.selectedTab) <= right(scrollbox), "Selecting the last tab scrolls it into view " +
- "(" + right(gBrowser.selectedTab) + " <= " + right(scrollbox) + ")");
-
- element = nextLeftElement();
- EventUtils.synthesizeMouse(upButton, 1, 1, {});
- isLeft(element, "Scrolled one tab to the left with a single click");
-
- let elementPoint = left(scrollbox) - width(scrollbox);
- element = elementFromPoint(elementPoint);
- if (elementPoint == right(element)) {
- element = element.nextSibling;
- }
- EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 2});
- isLeft(element, "Scrolled one page of tabs with a double click");
-
- EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 3});
- var firstScrollableLeft = left(firstScrollable());
- ok(left(scrollbox) <= firstScrollableLeft, "Scrolled to the start with a triple click " +
- "(" + left(scrollbox) + " <= " + firstScrollableLeft + ")");
-
- for (var i = 2; i; i--)
- EventUtils.synthesizeWheel(scrollbox, 1, 1, { deltaX: -1.0, deltaMode: WheelEvent.DOM_DELTA_LINE });
- is(left(firstScrollable()), firstScrollableLeft, "Remained at the start with the mouse wheel");
-
- element = nextRightElement();
- EventUtils.synthesizeWheel(scrollbox, 1, 1, { deltaX: 1.0, deltaMode: WheelEvent.DOM_DELTA_LINE});
- isRight(element, "Scrolled one tab to the right with the mouse wheel");
-
- while (tabs.length > 1)
- gBrowser.removeTab(tabs[0]);
-
- tabstrip.smoothScroll = originalSmoothScroll;
- finish();
-}
diff --git a/browser/base/content/test/general/browser_pageInfo.js b/browser/base/content/test/general/browser_pageInfo.js
deleted file mode 100644
index 90fe2e17f..000000000
--- a/browser/base/content/test/general/browser_pageInfo.js
+++ /dev/null
@@ -1,38 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- var pageInfo;
-
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.selectedBrowser.addEventListener("load", function loadListener() {
- gBrowser.selectedBrowser.removeEventListener("load", loadListener, true);
-
- Services.obs.addObserver(observer, "page-info-dialog-loaded", false);
- pageInfo = BrowserPageInfo();
- }, 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);
- }
-
- function handlePageInfo() {
- ok(pageInfo.document.getElementById("feedTab"), "Feed tab");
- let feedListbox = pageInfo.document.getElementById("feedListbox");
- ok(feedListbox, "Feed list");
-
- var feedRowsNum = feedListbox.getRowCount();
- is(feedRowsNum, 3, "Number of feeds listed");
-
- for (var i = 0; i < feedRowsNum; i++) {
- let feedItem = feedListbox.getItemAtIndex(i);
- is(feedItem.getAttribute("name"), i + 1, "Feed name");
- }
-
- pageInfo.close();
- gBrowser.removeCurrentTab();
- finish();
- }
-}
diff --git a/browser/base/content/test/general/browser_page_style_menu.js b/browser/base/content/test/general/browser_page_style_menu.js
deleted file mode 100644
index cb080d52a..000000000
--- a/browser/base/content/test/general/browser_page_style_menu.js
+++ /dev/null
@@ -1,97 +0,0 @@
-"use strict";
-
-/**
- * Stylesheets are updated for a browser after the pageshow event.
- * This helper function returns a Promise that waits for that pageshow
- * event, and then resolves on the next tick to ensure that gPageStyleMenu
- * has had a chance to update the stylesheets.
- *
- * @param browser
- * The <xul:browser> to wait for.
- * @return Promise
- */
-function promiseStylesheetsUpdated(browser) {
- return ContentTask.spawn(browser, { PAGE }, function*(args) {
- return new Promise((resolve) => {
- addEventListener("pageshow", function onPageShow(e) {
- if (e.target.location == args.PAGE) {
- removeEventListener("pageshow", onPageShow);
- content.setTimeout(resolve, 0);
- }
- });
- })
- });
-}
-
-const PAGE = "http://example.com/browser/browser/base/content/test/general/page_style_sample.html";
-
-/*
- * Test that the right stylesheets do (and others don't) show up
- * in the page style menu.
- */
-add_task(function*() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", false);
- let browser = tab.linkedBrowser;
- yield BrowserTestUtils.loadURI(browser, PAGE);
- yield promiseStylesheetsUpdated(browser);
-
- let menupopup = document.getElementById("pageStyleMenu").menupopup;
- gPageStyleMenu.fillPopup(menupopup);
-
- var items = [];
- var current = menupopup.getElementsByTagName("menuseparator")[0];
- while (current.nextSibling) {
- current = current.nextSibling;
- items.push(current);
- }
-
- items = items.map(el => ({
- label: el.getAttribute("label"),
- checked: el.getAttribute("checked") == "true",
- }));
-
- let validLinks = yield ContentTask.spawn(gBrowser.selectedBrowser, items, function(contentItems) {
- let contentValidLinks = 0;
- Array.forEach(content.document.querySelectorAll("link, style"), function (el) {
- var title = el.getAttribute("title");
- var rel = el.getAttribute("rel");
- var media = el.getAttribute("media");
- var idstring = el.nodeName + " " + (title ? title : "without title and") +
- " with rel=\"" + rel + "\"" +
- (media ? " and media=\"" + media + "\"" : "");
-
- var item = contentItems.filter(aItem => aItem.label == title);
- var found = item.length == 1;
- var checked = found && item[0].checked;
-
- switch (el.getAttribute("data-state")) {
- case "0":
- ok(!found, idstring + " should not show up in page style menu");
- break;
- case "0-todo":
- contentValidLinks++;
- todo(!found, idstring + " should not show up in page style menu");
- ok(!checked, idstring + " should not be selected");
- break;
- case "1":
- contentValidLinks++;
- ok(found, idstring + " should show up in page style menu");
- ok(!checked, idstring + " should not be selected");
- break;
- case "2":
- contentValidLinks++;
- ok(found, idstring + " should show up in page style menu");
- ok(checked, idstring + " should be selected");
- break;
- default:
- throw "data-state attribute is missing or has invalid value";
- }
- });
- return contentValidLinks;
- });
-
- ok(items.length, "At least one item in the menu");
- is(items.length, validLinks, "all valid links found");
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_page_style_menu_update.js b/browser/base/content/test/general/browser_page_style_menu_update.js
deleted file mode 100644
index a0c741e48..000000000
--- a/browser/base/content/test/general/browser_page_style_menu_update.js
+++ /dev/null
@@ -1,67 +0,0 @@
-"use strict";
-
-const PAGE = "http://example.com/browser/browser/base/content/test/general/page_style_sample.html";
-
-/**
- * Stylesheets are updated for a browser after the pageshow event.
- * This helper function returns a Promise that waits for that pageshow
- * event, and then resolves on the next tick to ensure that gPageStyleMenu
- * has had a chance to update the stylesheets.
- *
- * @param browser
- * The <xul:browser> to wait for.
- * @return Promise
- */
-function promiseStylesheetsUpdated(browser) {
- return ContentTask.spawn(browser, { PAGE }, function*(args) {
- return new Promise((resolve) => {
- addEventListener("pageshow", function onPageShow(e) {
- if (e.target.location == args.PAGE) {
- removeEventListener("pageshow", onPageShow);
- content.setTimeout(resolve, 0);
- }
- });
- })
- });
-}
-
-/**
- * Tests that the Page Style menu shows the currently
- * selected Page Style after a new one has been selected.
- */
-add_task(function*() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", false);
- let browser = tab.linkedBrowser;
-
- yield BrowserTestUtils.loadURI(browser, PAGE);
- yield promiseStylesheetsUpdated(browser);
-
- let menupopup = document.getElementById("pageStyleMenu").menupopup;
- gPageStyleMenu.fillPopup(menupopup);
-
- // page_style_sample.html should default us to selecting the stylesheet
- // with the title "6" first.
- let selected = menupopup.querySelector("menuitem[checked='true']");
- is(selected.getAttribute("label"), "6", "Should have '6' stylesheet selected by default");
-
- // Now select stylesheet "1"
- let target = menupopup.querySelector("menuitem[label='1']");
- target.click();
-
- // Now we need to wait for the content process to send its stylesheet
- // update for the selected tab to the parent. Because messages are
- // guaranteed to be sent in order, we'll make sure we do the check
- // after the parent has been updated by yielding until the child
- // has finished running a ContentTask for us.
- yield ContentTask.spawn(browser, {}, function*() {
- dump('\nJust wasting some time.\n');
- });
-
- gPageStyleMenu.fillPopup(menupopup);
- // gPageStyleMenu empties out the menu between opens, so we need
- // to get a new reference to the selected menuitem
- selected = menupopup.querySelector("menuitem[checked='true']");
- is(selected.getAttribute("label"), "1", "Should now have stylesheet 1 selected");
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_pageinfo_svg_image.js b/browser/base/content/test/general/browser_pageinfo_svg_image.js
deleted file mode 100644
index 02514d79f..000000000
--- a/browser/base/content/test/general/browser_pageinfo_svg_image.js
+++ /dev/null
@@ -1,38 +0,0 @@
-function test() {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.selectedBrowser.addEventListener("load", function loadListener() {
- gBrowser.selectedBrowser.removeEventListener("load", loadListener, true);
- var pageInfo = BrowserPageInfo(gBrowser.selectedBrowser.currentURI.spec,
- "mediaTab");
-
- pageInfo.addEventListener("load", function loadListener2() {
- pageInfo.removeEventListener("load", loadListener2, 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)");
-
- is(imageRowsNum, 1, "should have one image");
-
- // Only bother running this if we've got the right number of rows.
- if (imageRowsNum == 1) {
- is(imageTree.view.getCellText(0, imageTree.columns[0]),
- "https://example.com/browser/browser/base/content/test/general/title_test.svg",
- "The URL should be the svg image.");
- }
-
- pageInfo.close();
- gBrowser.removeCurrentTab();
- finish();
- });
- });
- }, true);
- }, true);
-
- content.location =
- "https://example.com/browser/browser/base/content/test/general/svg_image.html";
-}
diff --git a/browser/base/content/test/general/browser_parsable_css.js b/browser/base/content/test/general/browser_parsable_css.js
deleted file mode 100644
index 72954d2e5..000000000
--- a/browser/base/content/test/general/browser_parsable_css.js
+++ /dev/null
@@ -1,376 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* This list allows pre-existing or 'unfixable' CSS issues to remain, while we
- * detect newly occurring issues in shipping CSS. It is a list of objects
- * specifying conditions under which an error should be ignored.
- *
- * Every property of the objects in it needs to consist of a regular expression
- * matching the offending error. If an object has multiple regex criteria, they
- * ALL need to match an error in order for that error not to cause a test
- * failure. */
-let whitelist = [
- // CodeMirror is imported as-is, see bug 1004423.
- {sourceName: /codemirror\.css$/i,
- isFromDevTools: true},
- // The debugger uses cross-browser CSS.
- {sourceName: /devtools\/client\/debugger\/new\/styles.css/i,
- isFromDevTools: true},
- // PDFjs is futureproofing its pseudoselectors, and those rules are dropped.
- {sourceName: /web\/viewer\.css$/i,
- errorMessage: /Unknown pseudo-class.*(fullscreen|selection)/i,
- isFromDevTools: false},
- // Tracked in bug 1004428.
- {sourceName: /aboutaccounts\/(main|normalize)\.css$/i,
- isFromDevTools: false},
- // Highlighter CSS uses a UA-only pseudo-class, see bug 985597.
- {sourceName: /highlighters\.css$/i,
- errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i,
- isFromDevTools: true},
- // Responsive Design Mode CSS uses a UA-only pseudo-class, see Bug 1241714.
- {sourceName: /responsive-ua\.css$/i,
- errorMessage: /Unknown pseudo-class.*moz-dropdown-list/i,
- isFromDevTools: true},
-
- {sourceName: /\b(contenteditable|EditorOverride|svg|forms|html|mathml|ua)\.css$/i,
- errorMessage: /Unknown pseudo-class.*-moz-/i,
- isFromDevTools: false},
- {sourceName: /\b(html|mathml|ua)\.css$/i,
- errorMessage: /Unknown property.*-moz-/i,
- isFromDevTools: false},
- // Reserved to UA sheets unless layout.css.overflow-clip-box.enabled flipped to true.
- {sourceName: /res\/forms\.css$/i,
- errorMessage: /Unknown property.*overflow-clip-box/i,
- isFromDevTools: false},
- {sourceName: /res\/(ua|html)\.css$/i,
- errorMessage: /Unknown pseudo-class .*\bfullscreen\b/i,
- isFromDevTools: false},
- {sourceName: /skin\/timepicker\.css$/i,
- errorMessage: /Error in parsing.*mask/i,
- isFromDevTools: false},
-];
-
-// Platform can be "linux", "macosx" or "win". If omitted, the exception applies to all platforms.
-let allowedImageReferences = [
- // Bug 1302691
- {file: "chrome://devtools/skin/images/dock-bottom-minimize@2x.png",
- from: "chrome://devtools/skin/toolbox.css",
- isFromDevTools: true},
- {file: "chrome://devtools/skin/images/dock-bottom-maximize@2x.png",
- from: "chrome://devtools/skin/toolbox.css",
- isFromDevTools: true},
-];
-
-var moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
-var {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
-
-// Add suffix to stylesheets' URI so that we always load them here and
-// have them parsed. Add a random number so that even if we run this
-// test multiple times, it would be unlikely to affect each other.
-const kPathSuffix = "?always-parse-css-" + Math.random();
-
-/**
- * Check if an error should be ignored due to matching one of the whitelist
- * objects defined in whitelist
- *
- * @param aErrorObject the error to check
- * @return true if the error should be ignored, false otherwise.
- */
-function ignoredError(aErrorObject) {
- for (let whitelistItem of whitelist) {
- let matches = true;
- for (let prop of ["sourceName", "errorMessage"]) {
- if (whitelistItem.hasOwnProperty(prop) &&
- !whitelistItem[prop].test(aErrorObject[prop] || "")) {
- matches = false;
- break;
- }
- }
- if (matches) {
- whitelistItem.used = true;
- return true;
- }
- }
- return false;
-}
-
-function once(target, name) {
- return new Promise((resolve, reject) => {
- let cb = () => {
- target.removeEventListener(name, cb);
- resolve();
- };
- target.addEventListener(name, cb);
- });
-}
-
-function fetchFile(uri) {
- return new Promise((resolve, reject) => {
- let xhr = new XMLHttpRequest();
- xhr.responseType = "text";
- xhr.open("GET", uri, true);
- xhr.onreadystatechange = function() {
- if (this.readyState != this.DONE) {
- return;
- }
- try {
- resolve(this.responseText);
- } catch (ex) {
- ok(false, `Script error reading ${uri}: ${ex}`);
- resolve("");
- }
- };
- xhr.onerror = error => {
- ok(false, `XHR error reading ${uri}: ${error}`);
- resolve("");
- };
- xhr.send(null);
- });
-}
-
-var gChromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Ci.nsIChromeRegistry);
-var gChromeMap = new Map();
-
-function getBaseUriForChromeUri(chromeUri) {
- let chromeFile = chromeUri + "gobbledygooknonexistentfile.reallynothere";
- let uri = Services.io.newURI(chromeFile, null, null);
- let fileUri = gChromeReg.convertChromeURL(uri);
- return fileUri.resolve(".");
-}
-
-function parseManifest(manifestUri) {
- return fetchFile(manifestUri.spec).then(data => {
- for (let line of data.split('\n')) {
- let [type, ...argv] = line.split(/\s+/);
- let component;
- if (type == "content" || type == "skin") {
- [component] = argv;
- } else {
- // skip unrelated lines
- continue;
- }
- let chromeUri = `chrome://${component}/${type}/`;
- gChromeMap.set(getBaseUriForChromeUri(chromeUri), chromeUri);
- }
- });
-}
-
-function convertToChromeUri(fileUri) {
- let baseUri = fileUri.spec;
- let path = "";
- while (true) {
- let slashPos = baseUri.lastIndexOf("/", baseUri.length - 2);
- if (slashPos < 0) {
- info(`File not accessible from chrome protocol: ${fileUri.path}`);
- return fileUri;
- }
- path = baseUri.slice(slashPos + 1) + path;
- baseUri = baseUri.slice(0, slashPos + 1);
- if (gChromeMap.has(baseUri)) {
- let chromeBaseUri = gChromeMap.get(baseUri);
- let chromeUri = `${chromeBaseUri}${path}`;
- return Services.io.newURI(chromeUri, null, null);
- }
- }
-}
-
-function messageIsCSSError(msg) {
- // Only care about CSS errors generated by our iframe:
- if ((msg instanceof Ci.nsIScriptError) &&
- msg.category.includes("CSS") &&
- msg.sourceName.endsWith(kPathSuffix)) {
- let sourceName = msg.sourceName.slice(0, -kPathSuffix.length);
- let msgInfo = { sourceName, errorMessage: msg.errorMessage };
- // Check if this error is whitelisted in whitelist
- if (!ignoredError(msgInfo)) {
- ok(false, `Got error message for ${sourceName}: ${msg.errorMessage}`);
- return true;
- }
- info(`Ignored error for ${sourceName} because of filter.`);
- }
- return false;
-}
-
-let imageURIsToReferencesMap = new Map();
-
-function processCSSRules(sheet) {
- for (let rule of sheet.cssRules) {
- if (rule instanceof CSSMediaRule) {
- processCSSRules(rule);
- continue;
- }
- if (!(rule instanceof CSSStyleRule))
- continue;
-
- // Extract urls from the css text.
- // Note: CSSStyleRule.cssText always has double quotes around URLs even
- // when the original CSS file didn't.
- let urls = rule.cssText.match(/url\("[^"]*"\)/g);
- if (!urls)
- continue;
-
- for (let url of urls) {
- // Remove the url(" prefix and the ") suffix.
- url = url.replace(/url\("(.*)"\)/, "$1");
- if (url.startsWith("data:"))
- continue;
-
- // Make the url absolute and remove the ref.
- let baseURI = Services.io.newURI(rule.parentStyleSheet.href, null, null);
- url = Services.io.newURI(url, null, baseURI).specIgnoringRef;
-
- // Store the image url along with the css file referencing it.
- let baseUrl = baseURI.spec.split("?always-parse-css")[0];
- if (!imageURIsToReferencesMap.has(url)) {
- imageURIsToReferencesMap.set(url, new Set([baseUrl]));
- } else {
- imageURIsToReferencesMap.get(url).add(baseUrl);
- }
- }
- }
-}
-
-function chromeFileExists(aURI)
-{
- let available = 0;
- try {
- let channel = NetUtil.newChannel({uri: aURI, loadUsingSystemPrincipal: true});
- let stream = channel.open();
- let sstream = Cc["@mozilla.org/scriptableinputstream;1"]
- .createInstance(Ci.nsIScriptableInputStream);
- sstream.init(stream);
- available = sstream.available();
- sstream.close();
- } catch (e) {
- if (e.result != Components.results.NS_ERROR_FILE_NOT_FOUND) {
- dump("Checking " + aURI + ": " + e + "\n");
- Cu.reportError(e);
- }
- }
- return available > 0;
-}
-
-add_task(function* checkAllTheCSS() {
- let appDir = Services.dirsvc.get("GreD", Ci.nsIFile);
- // This asynchronously produces a list of URLs (sadly, mostly sync on our
- // test infrastructure because it runs against jarfiles there, and
- // our zipreader APIs are all sync)
- let uris = yield generateURIsFromDirTree(appDir, [".css", ".manifest"]);
-
- // Create a clean iframe to load all the files into. This needs to live at a
- // chrome URI so that it's allowed to load and parse any styles.
- let testFile = getRootDirectory(gTestPath) + "dummy_page.html";
- let windowless = Services.appShell.createWindowlessBrowser();
- let iframe = windowless.document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
- windowless.document.documentElement.appendChild(iframe);
- let iframeLoaded = once(iframe, 'load');
- iframe.contentWindow.location = testFile;
- yield iframeLoaded;
- let doc = iframe.contentWindow.document;
-
- // Parse and remove all manifests from the list.
- // NOTE that this must be done before filtering out devtools paths
- // so that all chrome paths can be recorded.
- let manifestPromises = [];
- uris = uris.filter(uri => {
- if (uri.path.endsWith(".manifest")) {
- manifestPromises.push(parseManifest(uri));
- return false;
- }
- return true;
- });
- // Wait for all manifest to be parsed
- yield Promise.all(manifestPromises);
-
- // We build a list of promises that get resolved when their respective
- // files have loaded and produced no errors.
- let allPromises = [];
-
- // filter out either the devtools paths or the non-devtools paths:
- let isDevtools = SimpleTest.harnessParameters.subsuite == "devtools";
- let devtoolsPathBits = ["webide", "devtools"];
- uris = uris.filter(uri => isDevtools == devtoolsPathBits.some(path => uri.spec.includes(path)));
-
- for (let uri of uris) {
- let linkEl = doc.createElement("link");
- linkEl.setAttribute("rel", "stylesheet");
- let promiseForThisSpec = Promise.defer();
- let onLoad = (e) => {
- processCSSRules(linkEl.sheet);
- promiseForThisSpec.resolve();
- linkEl.removeEventListener("load", onLoad);
- linkEl.removeEventListener("error", onError);
- };
- let onError = (e) => {
- ok(false, "Loading " + linkEl.getAttribute("href") + " threw an error!");
- promiseForThisSpec.resolve();
- linkEl.removeEventListener("load", onLoad);
- linkEl.removeEventListener("error", onError);
- };
- linkEl.addEventListener("load", onLoad);
- linkEl.addEventListener("error", onError);
- linkEl.setAttribute("type", "text/css");
- let chromeUri = convertToChromeUri(uri);
- linkEl.setAttribute("href", chromeUri.spec + kPathSuffix);
- allPromises.push(promiseForThisSpec.promise);
- doc.head.appendChild(linkEl);
- }
-
- // Wait for all the files to have actually loaded:
- yield Promise.all(allPromises);
-
- // Check if all the files referenced from CSS actually exist.
- for (let [image, references] of imageURIsToReferencesMap) {
- if (!chromeFileExists(image)) {
- for (let ref of references) {
- let ignored = false;
- for (let item of allowedImageReferences) {
- if (image.endsWith(item.file) && ref.endsWith(item.from) &&
- isDevtools == item.isFromDevTools &&
- (!item.platforms || item.platforms.includes(AppConstants.platform))) {
- item.used = true;
- ignored = true;
- break;
- }
- }
- if (!ignored)
- ok(false, "missing " + image + " referenced from " + ref);
- }
- }
- }
-
- let messages = Services.console.getMessageArray();
- // Count errors (the test output will list actual issues for us, as well
- // as the ok(false) in messageIsCSSError.
- let errors = messages.filter(messageIsCSSError);
- is(errors.length, 0, "All the styles (" + allPromises.length + ") loaded without errors.");
-
- // Confirm that all whitelist rules have been used.
- for (let item of whitelist) {
- if (!item.used && isDevtools == item.isFromDevTools) {
- ok(false, "Unused whitelist item. " +
- (item.sourceName ? " sourceName: " + item.sourceName : "") +
- (item.errorMessage ? " errorMessage: " + item.errorMessage : ""));
- }
- }
-
- // Confirm that all file whitelist rules have been used.
- for (let item of allowedImageReferences) {
- if (!item.used && isDevtools == item.isFromDevTools &&
- (!item.platforms || item.platforms.includes(AppConstants.platform))) {
- ok(false, "Unused file whitelist item. " +
- " file: " + item.file +
- " from: " + item.from);
- }
- }
-
- // Clean up to avoid leaks:
- iframe.remove();
- doc.head.innerHTML = '';
- doc = null;
- iframe = null;
- windowless.close();
- windowless = null;
- imageURIsToReferencesMap = null;
-});
diff --git a/browser/base/content/test/general/browser_parsable_script.js b/browser/base/content/test/general/browser_parsable_script.js
deleted file mode 100644
index 50333dd65..000000000
--- a/browser/base/content/test/general/browser_parsable_script.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* This list allows pre-existing or 'unfixable' JS issues to remain, while we
- * detect newly occurring issues in shipping JS. It is a list of regexes
- * matching files which have errors:
- */
-const kWhitelist = new Set([
- /defaults\/profile\/prefs.js$/,
- /browser\/content\/browser\/places\/controller.js$/,
-]);
-
-
-var moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
-var {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
-
-// Normally we would use reflect.jsm to get Reflect.parse. However, if
-// we do that, then all the AST data is allocated in reflect.jsm's
-// zone. That exposes a bug in our GC. The GC collects reflect.jsm's
-// zone but not the zone in which our test code lives (since no new
-// data is being allocated in it). The cross-compartment wrappers in
-// our zone that point to the AST data never get collected, and so the
-// AST data itself is never collected. We need to GC both zones at
-// once to fix the problem.
-const init = Components.classes["@mozilla.org/jsreflect;1"].createInstance();
-init();
-
-/**
- * Check if an error should be ignored due to matching one of the whitelist
- * objects defined in kWhitelist
- *
- * @param uri the uri to check against the whitelist
- * @return true if the uri should be skipped, false otherwise.
- */
-function uriIsWhiteListed(uri) {
- for (let whitelistItem of kWhitelist) {
- if (whitelistItem.test(uri.spec)) {
- return true;
- }
- }
- return false;
-}
-
-function parsePromise(uri) {
- let promise = new Promise((resolve, reject) => {
- let xhr = new XMLHttpRequest();
- xhr.open("GET", uri, true);
- xhr.onreadystatechange = function() {
- if (this.readyState == this.DONE) {
- let scriptText = this.responseText;
- try {
- info("Checking " + uri);
- Reflect.parse(scriptText);
- resolve(true);
- } catch (ex) {
- let errorMsg = "Script error reading " + uri + ": " + ex;
- ok(false, errorMsg);
- resolve(false);
- }
- }
- };
- xhr.onerror = (error) => {
- ok(false, "XHR error reading " + uri + ": " + error);
- resolve(false);
- };
- xhr.overrideMimeType("application/javascript");
- xhr.send(null);
- });
- return promise;
-}
-
-add_task(function* checkAllTheJS() {
- // In debug builds, even on a fast machine, collecting the file list may take
- // more than 30 seconds, and parsing all files may take four more minutes.
- // For this reason, this test must be explictly requested in debug builds by
- // using the "--setpref parse=<filter>" argument to mach. You can specify:
- // - A case-sensitive substring of the file name to test (slow).
- // - A single absolute URI printed out by a previous run (fast).
- // - An empty string to run the test on all files (slowest).
- let parseRequested = Services.prefs.prefHasUserValue("parse");
- let parseValue = parseRequested && Services.prefs.getCharPref("parse");
- if (SpecialPowers.isDebugBuild) {
- if (!parseRequested) {
- ok(true, "Test disabled on debug build. To run, execute: ./mach" +
- " mochitest-browser --setpref parse=<case_sensitive_filter>" +
- " browser/base/content/test/general/browser_parsable_script.js");
- return;
- }
- // Request a 15 minutes timeout (30 seconds * 30) for debug builds.
- requestLongerTimeout(30);
- }
-
- let uris;
- // If an absolute URI is specified on the command line, use it immediately.
- if (parseValue && parseValue.includes(":")) {
- uris = [NetUtil.newURI(parseValue)];
- } else {
- let appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
- // This asynchronously produces a list of URLs (sadly, mostly sync on our
- // test infrastructure because it runs against jarfiles there, and
- // our zipreader APIs are all sync)
- let startTimeMs = Date.now();
- info("Collecting URIs");
- uris = yield generateURIsFromDirTree(appDir, [".js", ".jsm"]);
- info("Collected URIs in " + (Date.now() - startTimeMs) + "ms");
-
- // Apply the filter specified on the command line, if any.
- if (parseValue) {
- uris = uris.filter(uri => {
- if (uri.spec.includes(parseValue)) {
- return true;
- }
- info("Not checking filtered out " + uri.spec);
- return false;
- });
- }
- }
-
- // We create an array of promises so we can parallelize all our parsing
- // and file loading activity:
- let allPromises = [];
- for (let uri of uris) {
- if (uriIsWhiteListed(uri)) {
- info("Not checking whitelisted " + uri.spec);
- continue;
- }
- allPromises.push(parsePromise(uri.spec));
- }
-
- let promiseResults = yield Promise.all(allPromises);
- is(promiseResults.filter((x) => !x).length, 0, "There should be 0 parsing errors");
-});
diff --git a/browser/base/content/test/general/browser_permissions.js b/browser/base/content/test/general/browser_permissions.js
deleted file mode 100644
index 721a669d2..000000000
--- a/browser/base/content/test/general/browser_permissions.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Test the Permissions section in the Control Center.
- */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const PERMISSIONS_PAGE = "http://example.com/browser/browser/base/content/test/general/permissions.html";
-var {SitePermissions} = Cu.import("resource:///modules/SitePermissions.jsm", {});
-
-registerCleanupFunction(function() {
- SitePermissions.remove(gBrowser.currentURI, "cookie");
- SitePermissions.remove(gBrowser.currentURI, "geo");
- SitePermissions.remove(gBrowser.currentURI, "camera");
- SitePermissions.remove(gBrowser.currentURI, "microphone");
-
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-});
-
-function* openIdentityPopup() {
- let {gIdentityHandler} = gBrowser.ownerGlobal;
- let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
- gIdentityHandler._identityBox.click();
- return promise;
-}
-
-function* closeIdentityPopup() {
- let {gIdentityHandler} = gBrowser.ownerGlobal;
- let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden");
- gIdentityHandler._identityPopup.hidePopup();
- return promise;
-}
-
-add_task(function* testMainViewVisible() {
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
-
- let permissionsList = document.getElementById("identity-popup-permission-list");
- let emptyLabel = permissionsList.nextSibling.nextSibling;
-
- yield openIdentityPopup();
-
- ok(!is_hidden(emptyLabel), "List of permissions is empty");
-
- yield closeIdentityPopup();
-
- SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.ALLOW);
-
- yield openIdentityPopup();
-
- ok(is_hidden(emptyLabel), "List of permissions is not empty");
-
- let labelText = SitePermissions.getPermissionLabel("camera");
- let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
- is(labels.length, 1, "One permission visible in main view");
- is(labels[0].textContent, labelText, "Correct value");
-
- let img = permissionsList.querySelector("image.identity-popup-permission-icon");
- ok(img, "There is an image for the permissions");
- ok(img.classList.contains("camera-icon"), "proper class is in image class");
-
- yield closeIdentityPopup();
-
- SitePermissions.remove(gBrowser.currentURI, "camera");
-
- yield openIdentityPopup();
-
- ok(!is_hidden(emptyLabel), "List of permissions is empty");
-
- yield closeIdentityPopup();
-});
-
-add_task(function* testIdentityIcon() {
- let {gIdentityHandler} = gBrowser.ownerGlobal;
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
-
- SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
-
- ok(gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
- "identity-box signals granted permissions");
-
- SitePermissions.remove(gBrowser.currentURI, "geo");
-
- ok(!gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
- "identity-box doesn't signal granted permissions");
-
- SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK);
-
- ok(!gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
- "identity-box doesn't signal granted permissions");
-
- SitePermissions.set(gBrowser.currentURI, "cookie", SitePermissions.SESSION);
-
- ok(gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
- "identity-box signals granted permissions");
-
- SitePermissions.remove(gBrowser.currentURI, "geo");
- SitePermissions.remove(gBrowser.currentURI, "camera");
- SitePermissions.remove(gBrowser.currentURI, "cookie");
-});
-
-add_task(function* testCancelPermission() {
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
-
- let permissionsList = document.getElementById("identity-popup-permission-list");
- let emptyLabel = permissionsList.nextSibling.nextSibling;
-
- SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
- SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK);
-
- yield openIdentityPopup();
-
- ok(is_hidden(emptyLabel), "List of permissions is not empty");
-
- let cancelButtons = permissionsList
- .querySelectorAll(".identity-popup-permission-remove-button");
-
- cancelButtons[0].click();
- let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
- is(labels.length, 1, "One permission should be removed");
- cancelButtons[1].click();
- labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
- is(labels.length, 0, "One permission should be removed");
-
- yield closeIdentityPopup();
-});
-
-add_task(function* testPermissionHints() {
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
-
- let permissionsList = document.getElementById("identity-popup-permission-list");
- let emptyHint = document.getElementById("identity-popup-permission-empty-hint");
- let reloadHint = document.getElementById("identity-popup-permission-reload-hint");
-
- yield openIdentityPopup();
-
- ok(!is_hidden(emptyHint), "Empty hint is visible");
- ok(is_hidden(reloadHint), "Reload hint is hidden");
-
- yield closeIdentityPopup();
-
- SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
- SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK);
-
- yield openIdentityPopup();
-
- ok(is_hidden(emptyHint), "Empty hint is hidden");
- ok(is_hidden(reloadHint), "Reload hint is hidden");
-
- let cancelButtons = permissionsList
- .querySelectorAll(".identity-popup-permission-remove-button");
- SitePermissions.remove(gBrowser.currentURI, "camera");
-
- cancelButtons[0].click();
- ok(is_hidden(emptyHint), "Empty hint is hidden");
- ok(!is_hidden(reloadHint), "Reload hint is visible");
-
- cancelButtons[1].click();
- ok(is_hidden(emptyHint), "Empty hint is hidden");
- ok(!is_hidden(reloadHint), "Reload hint is visible");
-
- yield closeIdentityPopup();
- yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
- yield openIdentityPopup();
-
- ok(!is_hidden(emptyHint), "Empty hint is visible after reloading");
- ok(is_hidden(reloadHint), "Reload hint is hidden after reloading");
-
- yield closeIdentityPopup();
-});
-
-add_task(function* testPermissionIcons() {
- let {gIdentityHandler} = gBrowser.ownerGlobal;
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
-
- SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.ALLOW);
- SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.BLOCK);
- SitePermissions.set(gBrowser.currentURI, "microphone", SitePermissions.SESSION);
-
- let geoIcon = gIdentityHandler._identityBox
- .querySelector(".blocked-permission-icon[data-permission-id='geo']");
- ok(geoIcon.hasAttribute("showing"), "blocked permission icon is shown");
-
- let cameraIcon = gIdentityHandler._identityBox
- .querySelector(".blocked-permission-icon[data-permission-id='camera']");
- ok(!cameraIcon.hasAttribute("showing"),
- "allowed permission icon is not shown");
-
- let microphoneIcon = gIdentityHandler._identityBox
- .querySelector(".blocked-permission-icon[data-permission-id='microphone']");
- ok(!microphoneIcon.hasAttribute("showing"),
- "allowed permission icon is not shown");
-
- SitePermissions.remove(gBrowser.currentURI, "geo");
-
- ok(!geoIcon.hasAttribute("showing"),
- "blocked permission icon is not shown after reset");
-});
diff --git a/browser/base/content/test/general/browser_pinnedTabs.js b/browser/base/content/test/general/browser_pinnedTabs.js
deleted file mode 100644
index e0ddb5072..000000000
--- a/browser/base/content/test/general/browser_pinnedTabs.js
+++ /dev/null
@@ -1,75 +0,0 @@
-var tabs;
-
-function index(tab) {
- return Array.indexOf(gBrowser.tabs, tab);
-}
-
-function indexTest(tab, expectedIndex, msg) {
- var diag = "tab " + tab + " should be at index " + expectedIndex;
- if (msg)
- msg = msg + " (" + diag + ")";
- else
- msg = diag;
- is(index(tabs[tab]), expectedIndex, msg);
-}
-
-function PinUnpinHandler(tab, eventName) {
- this.eventCount = 0;
- var self = this;
- tab.addEventListener(eventName, function() {
- tab.removeEventListener(eventName, arguments.callee, true);
-
- self.eventCount++;
- }, true);
- gBrowser.tabContainer.addEventListener(eventName, function(e) {
- gBrowser.tabContainer.removeEventListener(eventName, arguments.callee, true);
-
- if (e.originalTarget == tab) {
- self.eventCount++;
- }
- }, true);
-}
-
-function test() {
- tabs = [gBrowser.selectedTab, gBrowser.addTab(), gBrowser.addTab(), gBrowser.addTab()];
- indexTest(0, 0);
- indexTest(1, 1);
- indexTest(2, 2);
- indexTest(3, 3);
-
- var eh = new PinUnpinHandler(tabs[3], "TabPinned");
- gBrowser.pinTab(tabs[3]);
- is(eh.eventCount, 2, "TabPinned event should be fired");
- indexTest(0, 1);
- indexTest(1, 2);
- indexTest(2, 3);
- indexTest(3, 0);
-
- eh = new PinUnpinHandler(tabs[1], "TabPinned");
- gBrowser.pinTab(tabs[1]);
- is(eh.eventCount, 2, "TabPinned event should be fired");
- indexTest(0, 2);
- indexTest(1, 1);
- indexTest(2, 3);
- indexTest(3, 0);
-
- gBrowser.moveTabTo(tabs[3], 3);
- indexTest(3, 1, "shouldn't be able to mix a pinned tab into normal tabs");
-
- gBrowser.moveTabTo(tabs[2], 0);
- indexTest(2, 2, "shouldn't be able to mix a normal tab into pinned tabs");
-
- eh = new PinUnpinHandler(tabs[1], "TabUnpinned");
- gBrowser.unpinTab(tabs[1]);
- is(eh.eventCount, 2, "TabUnpinned event should be fired");
- indexTest(1, 1, "unpinning a tab should move a tab to the start of normal tabs");
-
- eh = new PinUnpinHandler(tabs[3], "TabUnpinned");
- gBrowser.unpinTab(tabs[3]);
- is(eh.eventCount, 2, "TabUnpinned event should be fired");
- indexTest(3, 0, "unpinning a tab should move a tab to the start of normal tabs");
-
- gBrowser.removeTab(tabs[1]);
- gBrowser.removeTab(tabs[2]);
- gBrowser.removeTab(tabs[3]);
-}
diff --git a/browser/base/content/test/general/browser_plainTextLinks.js b/browser/base/content/test/general/browser_plainTextLinks.js
deleted file mode 100644
index 7a304fce0..000000000
--- a/browser/base/content/test/general/browser_plainTextLinks.js
+++ /dev/null
@@ -1,146 +0,0 @@
-function testExpected(expected, msg) {
- is(document.getElementById("context-openlinkincurrent").hidden, expected, msg);
-}
-
-function testLinkExpected(expected, msg) {
- is(gContextMenu.linkURL, expected, msg);
-}
-
-add_task(function *() {
- const url = "data:text/html;charset=UTF-8,Test For Non-Hyperlinked url selection";
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-
- yield SimpleTest.promiseFocus(gBrowser.selectedBrowser.contentWindowAsCPOW);
-
- // Initial setup of the content area.
- yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
- let doc = content.document;
- let range = doc.createRange();
- let selection = content.getSelection();
-
- let mainDiv = doc.createElement("div");
- let div = doc.createElement("div");
- let div2 = doc.createElement("div");
- let span1 = doc.createElement("span");
- let span2 = doc.createElement("span");
- let span3 = doc.createElement("span");
- let span4 = doc.createElement("span");
- let p1 = doc.createElement("p");
- let p2 = doc.createElement("p");
- span1.textContent = "http://index.";
- span2.textContent = "example.com example.com";
- span3.textContent = " - Test";
- span4.innerHTML = "<a href='http://www.example.com'>http://www.example.com/example</a>";
- p1.textContent = "mailto:test.com ftp.example.com";
- p2.textContent = "example.com -";
- div.appendChild(span1);
- div.appendChild(span2);
- div.appendChild(span3);
- div.appendChild(span4);
- div.appendChild(p1);
- div.appendChild(p2);
- let p3 = doc.createElement("p");
- p3.textContent = "main.example.com";
- div2.appendChild(p3);
- mainDiv.appendChild(div);
- mainDiv.appendChild(div2);
- doc.body.appendChild(mainDiv);
-
- function setSelection(el1, el2, index1, index2) {
- while (el1.nodeType != el1.TEXT_NODE)
- el1 = el1.firstChild;
- while (el2.nodeType != el1.TEXT_NODE)
- el2 = el2.firstChild;
-
- selection.removeAllRanges();
- range.setStart(el1, index1);
- range.setEnd(el2, index2);
- selection.addRange(range);
-
- return range;
- }
-
- // Each of these tests creates a selection and returns a range within it.
- content.tests = [
- () => setSelection(span1.firstChild, span2.firstChild, 0, 11),
- () => setSelection(span1.firstChild, span2.firstChild, 7, 11),
- () => setSelection(span1.firstChild, span2.firstChild, 8, 11),
- () => setSelection(span2.firstChild, span2.firstChild, 0, 11),
- () => setSelection(span2.firstChild, span2.firstChild, 11, 23),
- () => setSelection(span2.firstChild, span2.firstChild, 0, 10),
- () => setSelection(span2.firstChild, span3.firstChild, 12, 7),
- () => setSelection(span2.firstChild, span2.firstChild, 12, 19),
- () => setSelection(p1.firstChild, p1.firstChild, 0, 15),
- () => setSelection(p1.firstChild, p1.firstChild, 16, 31),
- () => setSelection(p2.firstChild, p2.firstChild, 0, 14),
- () => {
- selection.selectAllChildren(div2);
- return selection.getRangeAt(0);
- },
- () => {
- selection.selectAllChildren(span4);
- return selection.getRangeAt(0);
- },
- () => {
- mainDiv.innerHTML = "(open-suse.ru)";
- return setSelection(mainDiv, mainDiv, 1, 13);
- },
- () => setSelection(mainDiv, mainDiv, 1, 14)
- ];
- });
-
- let checks = [
- () => testExpected(false, "The link context menu should show for http://www.example.com"),
- () => testExpected(false, "The link context menu should show for www.example.com"),
- () => testExpected(true, "The link context menu should not show for ww.example.com"),
- () => {
- testExpected(false, "The link context menu should show for example.com");
- testLinkExpected("http://example.com/", "url for example.com selection should not prepend www");
- },
- () => testExpected(false, "The link context menu should show for example.com"),
- () => testExpected(true, "Link options should not show for selection that's not at a word boundary"),
- () => testExpected(true, "Link options should not show for selection that has whitespace"),
- () => testExpected(true, "Link options should not show unless a url is selected"),
- () => testExpected(true, "Link options should not show for mailto: links"),
- () => {
- testExpected(false, "Link options should show for ftp.example.com");
- testLinkExpected("http://ftp.example.com/", "ftp.example.com should be preceeded with http://");
- },
- () => testExpected(false, "Link options should show for www.example.com "),
- () => testExpected(false, "Link options should show for triple-click selections"),
- () => testLinkExpected("http://www.example.com/", "Linkified text should open the correct link"),
- () => {
- testExpected(false, "Link options should show for open-suse.ru");
- testLinkExpected("http://open-suse.ru/", "Linkified text should open the correct link");
- },
- () => testExpected(true, "Link options should not show for 'open-suse.ru)'")
- ];
-
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
-
- for (let testid = 0; testid < checks.length; testid++) {
- let menuPosition = yield ContentTask.spawn(gBrowser.selectedBrowser, { testid: testid }, function* (arg) {
- let range = content.tests[arg.testid]();
-
- // Get the range of the selection and determine its coordinates. These
- // coordinates will be returned to the parent process and the context menu
- // will be opened at that location.
- let rangeRect = range.getBoundingClientRect();
- return [rangeRect.x + 3, rangeRect.y + 3];
- });
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouseAtPoint(menuPosition[0], menuPosition[1],
- { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
- yield popupShownPromise;
-
- checks[testid]();
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- contentAreaContextMenu.hidePopup();
- yield popupHiddenPromise;
- }
-
- gBrowser.removeCurrentTab();
-});
-
diff --git a/browser/base/content/test/general/browser_printpreview.js b/browser/base/content/test/general/browser_printpreview.js
deleted file mode 100644
index c38fc18be..000000000
--- a/browser/base/content/test/general/browser_printpreview.js
+++ /dev/null
@@ -1,74 +0,0 @@
-let ourTab;
-
-function test() {
- waitForExplicitFinish();
-
- BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", true).then(function(tab) {
- ourTab = tab;
- ok(!gInPrintPreviewMode,
- "Should NOT be in print preview mode at starting this tests");
- // Skip access key test on platforms which don't support access key.
- if (!/Win|Linux/.test(navigator.platform)) {
- openPrintPreview(testClosePrintPreviewWithEscKey);
- } else {
- openPrintPreview(testClosePrintPreviewWithAccessKey);
- }
- });
-}
-
-function tidyUp() {
- BrowserTestUtils.removeTab(ourTab).then(finish);
-}
-
-function testClosePrintPreviewWithAccessKey() {
- EventUtils.synthesizeKey("c", { altKey: true });
- checkPrintPreviewClosed(function (aSucceeded) {
- ok(aSucceeded,
- "print preview mode should be finished by access key");
- openPrintPreview(testClosePrintPreviewWithEscKey);
- });
-}
-
-function testClosePrintPreviewWithEscKey() {
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- checkPrintPreviewClosed(function (aSucceeded) {
- ok(aSucceeded,
- "print preview mode should be finished by Esc key press");
- openPrintPreview(testClosePrintPreviewWithClosingWindowShortcutKey);
- });
-}
-
-function testClosePrintPreviewWithClosingWindowShortcutKey() {
- EventUtils.synthesizeKey("w", { accelKey: true });
- checkPrintPreviewClosed(function (aSucceeded) {
- ok(aSucceeded,
- "print preview mode should be finished by closing window shortcut key");
- tidyUp();
- });
-}
-
-function openPrintPreview(aCallback) {
- document.getElementById("cmd_printPreview").doCommand();
- executeSoon(function () {
- if (gInPrintPreviewMode) {
- executeSoon(aCallback);
- return;
- }
- executeSoon(arguments.callee);
- });
-}
-
-function checkPrintPreviewClosed(aCallback) {
- let count = 0;
- executeSoon(function () {
- if (!gInPrintPreviewMode) {
- executeSoon(function () { aCallback(count < 1000); });
- return;
- }
- if (++count == 1000) {
- // The test might fail.
- PrintUtils.exitPrintPreview();
- }
- executeSoon(arguments.callee);
- });
-}
diff --git a/browser/base/content/test/general/browser_private_browsing_window.js b/browser/base/content/test/general/browser_private_browsing_window.js
deleted file mode 100644
index 607a34060..000000000
--- a/browser/base/content/test/general/browser_private_browsing_window.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Make sure that we can open private browsing windows
-
-function test() {
- waitForExplicitFinish();
- var nonPrivateWin = OpenBrowserWindow();
- ok(!PrivateBrowsingUtils.isWindowPrivate(nonPrivateWin), "OpenBrowserWindow() should open a normal window");
- nonPrivateWin.close();
-
- var privateWin = OpenBrowserWindow({private: true});
- ok(PrivateBrowsingUtils.isWindowPrivate(privateWin), "OpenBrowserWindow({private: true}) should open a private window");
-
- nonPrivateWin = OpenBrowserWindow({private: false});
- ok(!PrivateBrowsingUtils.isWindowPrivate(nonPrivateWin), "OpenBrowserWindow({private: false}) should open a normal window");
- nonPrivateWin.close();
-
- whenDelayedStartupFinished(privateWin, function() {
- nonPrivateWin = privateWin.OpenBrowserWindow({private: false});
- ok(!PrivateBrowsingUtils.isWindowPrivate(nonPrivateWin), "privateWin.OpenBrowserWindow({private: false}) should open a normal window");
-
- nonPrivateWin.close();
-
- [
- { normal: "menu_newNavigator", private: "menu_newPrivateWindow", accesskey: true },
- { normal: "appmenu_newNavigator", private: "appmenu_newPrivateWindow", accesskey: false },
- ].forEach(function(menu) {
- let newWindow = privateWin.document.getElementById(menu.normal);
- let newPrivateWindow = privateWin.document.getElementById(menu.private);
- if (newWindow && newPrivateWindow) {
- ok(!newPrivateWindow.hidden, "New Private Window menu item should be hidden");
- isnot(newWindow.label, newPrivateWindow.label, "New Window's label shouldn't be overwritten");
- if (menu.accesskey) {
- isnot(newWindow.accessKey, newPrivateWindow.accessKey, "New Window's accessKey shouldn't be overwritten");
- }
- isnot(newWindow.command, newPrivateWindow.command, "New Window's command shouldn't be overwritten");
- }
- });
-
- privateWin.close();
-
- Services.prefs.setBoolPref("browser.privatebrowsing.autostart", true);
- privateWin = OpenBrowserWindow({private: true});
- whenDelayedStartupFinished(privateWin, function() {
- [
- { normal: "menu_newNavigator", private: "menu_newPrivateWindow", accessKey: true },
- { normal: "appmenu_newNavigator", private: "appmenu_newPrivateWindow", accessKey: false },
- ].forEach(function(menu) {
- let newWindow = privateWin.document.getElementById(menu.normal);
- let newPrivateWindow = privateWin.document.getElementById(menu.private);
- if (newWindow && newPrivateWindow) {
- ok(newPrivateWindow.hidden, "New Private Window menu item should be hidden");
- is(newWindow.label, newPrivateWindow.label, "New Window's label should be overwritten");
- if (menu.accesskey) {
- is(newWindow.accessKey, newPrivateWindow.accessKey, "New Window's accessKey should be overwritten");
- }
- is(newWindow.command, newPrivateWindow.command, "New Window's command should be overwritten");
- }
- });
-
- privateWin.close();
- Services.prefs.clearUserPref("browser.privatebrowsing.autostart");
- finish();
- });
- });
-}
-
diff --git a/browser/base/content/test/general/browser_private_no_prompt.js b/browser/base/content/test/general/browser_private_no_prompt.js
deleted file mode 100644
index c6c580f80..000000000
--- a/browser/base/content/test/general/browser_private_no_prompt.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function test() {
- waitForExplicitFinish();
- var privateWin = OpenBrowserWindow({private: true});
-
- whenDelayedStartupFinished(privateWin, function () {
- privateWin.BrowserOpenTab();
- privateWin.BrowserTryToCloseWindow();
- ok(true, "didn't prompt");
-
- executeSoon(finish);
- });
-}
diff --git a/browser/base/content/test/general/browser_purgehistory_clears_sh.js b/browser/base/content/test/general/browser_purgehistory_clears_sh.js
deleted file mode 100644
index 1a1e6554d..000000000
--- a/browser/base/content/test/general/browser_purgehistory_clears_sh.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const url = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-
-add_task(function* purgeHistoryTest() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url,
- }, function* purgeHistoryTestInner(browser) {
- let backButton = browser.ownerDocument.getElementById("Browser:Back");
- let forwardButton = browser.ownerDocument.getElementById("Browser:Forward");
-
- ok(!browser.webNavigation.canGoBack,
- "Initial value for webNavigation.canGoBack");
- ok(!browser.webNavigation.canGoForward,
- "Initial value for webNavigation.canGoBack");
- ok(backButton.hasAttribute("disabled"), "Back button is disabled");
- ok(forwardButton.hasAttribute("disabled"), "Forward button is disabled");
-
- yield ContentTask.spawn(browser, null, function*() {
- let startHistory = content.history.length;
- content.history.pushState({}, "");
- content.history.pushState({}, "");
- content.history.back();
- let newHistory = content.history.length;
- Assert.equal(startHistory, 1, "Initial SHistory size");
- Assert.equal(newHistory, 3, "New SHistory size");
- });
-
- ok(browser.webNavigation.canGoBack, true,
- "New value for webNavigation.canGoBack");
- ok(browser.webNavigation.canGoForward, true,
- "New value for webNavigation.canGoForward");
- ok(!backButton.hasAttribute("disabled"), "Back button was enabled");
- ok(!forwardButton.hasAttribute("disabled"), "Forward button was enabled");
-
-
- let tmp = {};
- Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tmp);
-
- let {Sanitizer} = tmp;
- let sanitizer = new Sanitizer();
-
- yield sanitizer.sanitize(["history"]);
-
- yield ContentTask.spawn(browser, null, function*() {
- Assert.equal(content.history.length, 1, "SHistory correctly cleared");
- });
-
- ok(!browser.webNavigation.canGoBack,
- "webNavigation.canGoBack correctly cleared");
- ok(!browser.webNavigation.canGoForward,
- "webNavigation.canGoForward correctly cleared");
- ok(backButton.hasAttribute("disabled"), "Back button was disabled");
- ok(forwardButton.hasAttribute("disabled"), "Forward button was disabled");
- });
-});
diff --git a/browser/base/content/test/general/browser_refreshBlocker.js b/browser/base/content/test/general/browser_refreshBlocker.js
deleted file mode 100644
index ee274f2c2..000000000
--- a/browser/base/content/test/general/browser_refreshBlocker.js
+++ /dev/null
@@ -1,135 +0,0 @@
-"use strict";
-
-const META_PAGE = "http://example.org/browser/browser/base/content/test/general/refresh_meta.sjs"
-const HEADER_PAGE = "http://example.org/browser/browser/base/content/test/general/refresh_header.sjs"
-const TARGET_PAGE = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
-const PREF = "accessibility.blockautorefresh";
-
-/**
- * Goes into the content, and simulates a meta-refresh header at a very
- * low level, and checks to see if it was blocked. This will always cancel
- * the refresh, regardless of whether or not the refresh was blocked.
- *
- * @param browser (<xul:browser>)
- * The browser to test for refreshing.
- * @param expectRefresh (bool)
- * Whether or not we expect the refresh attempt to succeed.
- * @returns Promise
- */
-function* attemptFakeRefresh(browser, expectRefresh) {
- yield ContentTask.spawn(browser, expectRefresh, function*(contentExpectRefresh) {
- let URI = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
- let refresher = docShell.QueryInterface(Ci.nsIRefreshURI);
- refresher.refreshURI(URI, 0, false, true);
-
- Assert.equal(refresher.refreshPending, contentExpectRefresh,
- "Got the right refreshPending state");
-
- if (refresher.refreshPending) {
- // Cancel the pending refresh
- refresher.cancelRefreshURITimers();
- }
-
- // The RefreshBlocker will wait until onLocationChange has
- // been fired before it will show any notifications (see bug
- // 1246291), so we cause this to occur manually here.
- content.location = URI.spec + "#foo";
- });
-}
-
-/**
- * Tests that we can enable the blocking pref and block a refresh
- * from occurring while showing a notification bar. Also tests that
- * when we disable the pref, that refreshes can go through again.
- */
-add_task(function* test_can_enable_and_block() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: TARGET_PAGE,
- }, function*(browser) {
- // By default, we should be able to reload the page.
- yield attemptFakeRefresh(browser, true);
-
- yield pushPrefs(["accessibility.blockautorefresh", true]);
-
- let notificationPromise =
- BrowserTestUtils.waitForNotificationBar(gBrowser, browser,
- "refresh-blocked");
-
- yield attemptFakeRefresh(browser, false);
-
- yield notificationPromise;
-
- yield pushPrefs(["accessibility.blockautorefresh", false]);
-
- // Page reloads should go through again.
- yield attemptFakeRefresh(browser, true);
- });
-});
-
-/**
- * Attempts a "real" refresh by opening a tab, and then sending it to
- * an SJS page that will attempt to cause a refresh. This will also pass
- * a delay amount to the SJS page. The refresh should be blocked, and
- * the notification should be shown. Once shown, the "Allow" button will
- * be clicked, and the refresh will go through. Finally, the helper will
- * close the tab and resolve the Promise.
- *
- * @param refreshPage (string)
- * The SJS page to use. Use META_PAGE for the <meta> tag refresh
- * case. Use HEADER_PAGE for the HTTP header case.
- * @param delay (int)
- * The amount, in ms, for the page to wait before attempting the
- * refresh.
- *
- * @returns Promise
- */
-function* testRealRefresh(refreshPage, delay) {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:blank",
- }, function*(browser) {
- yield pushPrefs(["accessibility.blockautorefresh", true]);
-
- browser.loadURI(refreshPage + "?p=" + TARGET_PAGE + "&d=" + delay);
- yield BrowserTestUtils.browserLoaded(browser);
-
- // Once browserLoaded resolves, all nsIWebProgressListener callbacks
- // should have fired, so the notification should be visible.
- let notificationBox = gBrowser.getNotificationBox(browser);
- let notification = notificationBox.currentNotification;
-
- ok(notification, "Notification should be visible");
- is(notification.value, "refresh-blocked",
- "Should be showing the right notification");
-
- // Then click the button to allow the refresh.
- let buttons = notification.querySelectorAll(".notification-button");
- is(buttons.length, 1, "Should have one button.");
-
- // Prepare a Promise that should resolve when the refresh goes through
- let refreshPromise = BrowserTestUtils.browserLoaded(browser);
- buttons[0].click();
-
- yield refreshPromise;
- });
-}
-
-/**
- * Tests the meta-tag case for both short and longer delay times.
- */
-add_task(function* test_can_allow_refresh() {
- yield testRealRefresh(META_PAGE, 0);
- yield testRealRefresh(META_PAGE, 100);
- yield testRealRefresh(META_PAGE, 500);
-});
-
-/**
- * Tests that when a HTTP header case for both short and longer
- * delay times.
- */
-add_task(function* test_can_block_refresh_from_header() {
- yield testRealRefresh(HEADER_PAGE, 0);
- yield testRealRefresh(HEADER_PAGE, 100);
- yield testRealRefresh(HEADER_PAGE, 500);
-});
diff --git a/browser/base/content/test/general/browser_registerProtocolHandler_notification.html b/browser/base/content/test/general/browser_registerProtocolHandler_notification.html
deleted file mode 100644
index 241b03b95..000000000
--- a/browser/base/content/test/general/browser_registerProtocolHandler_notification.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <title>Protocol registrar page</title>
- <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
- <meta content="utf-8" http-equiv="encoding">
- </head>
- <body>
- <script type="text/javascript">
- navigator.registerProtocolHandler("testprotocol",
- "https://example.com/foobar?uri=%s",
- "Test Protocol");
- </script>
- </body>
-</html>
diff --git a/browser/base/content/test/general/browser_registerProtocolHandler_notification.js b/browser/base/content/test/general/browser_registerProtocolHandler_notification.js
deleted file mode 100644
index b30ece0f6..000000000
--- a/browser/base/content/test/general/browser_registerProtocolHandler_notification.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
- let notificationValue = "Protocol Registration: testprotocol";
- let testURI = "http://example.com/browser/" +
- "browser/base/content/test/general/browser_registerProtocolHandler_notification.html";
-
- waitForCondition(function() {
- // Do not start until the notification is up
- let notificationBox = window.gBrowser.getNotificationBox();
- let notification = notificationBox.getNotificationWithValue(notificationValue);
- return notification;
- },
- function() {
-
- let notificationBox = window.gBrowser.getNotificationBox();
- let notification = notificationBox.getNotificationWithValue(notificationValue);
- ok(notification, "Notification box should be displayed");
- if (notification == null) {
- finish();
- return;
- }
- is(notification.type, "info", "We expect this notification to have the type of 'info'.");
- isnot(notification.image, null, "We expect this notification to have an icon.");
-
- let buttons = notification.getElementsByClassName("notification-button-default");
- is(buttons.length, 1, "We expect see one default button.");
-
- buttons = notification.getElementsByClassName("notification-button");
- is(buttons.length, 1, "We expect see one button.");
-
- let button = buttons[0];
- isnot(button.label, null, "We expect the add button to have a label.");
- todo_isnot(button.accesskey, null, "We expect the add button to have a accesskey.");
-
- finish();
- }, "Still can not get notification after retry 100 times.", 100);
-
- window.gBrowser.selectedBrowser.loadURI(testURI);
-}
diff --git a/browser/base/content/test/general/browser_relatedTabs.js b/browser/base/content/test/general/browser_relatedTabs.js
deleted file mode 100644
index 97cf51d84..000000000
--- a/browser/base/content/test/general/browser_relatedTabs.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function*() {
- is(gBrowser.tabs.length, 1, "one tab is open initially");
-
- // Add several new tabs in sequence, interrupted by selecting a
- // different tab, moving a tab around and closing a tab,
- // returning a list of opened tabs for verifying the expected order.
- // The new tab behaviour is documented in bug 465673
- let tabs = [];
- function addTab(aURL, aReferrer) {
- let tab = gBrowser.addTab(aURL, {referrerURI: aReferrer});
- tabs.push(tab);
- return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- }
-
- yield addTab("http://mochi.test:8888/#0");
- gBrowser.selectedTab = tabs[0];
- yield addTab("http://mochi.test:8888/#1");
- yield addTab("http://mochi.test:8888/#2", gBrowser.currentURI);
- yield addTab("http://mochi.test:8888/#3", gBrowser.currentURI);
- gBrowser.selectedTab = tabs[tabs.length - 1];
- gBrowser.selectedTab = tabs[0];
- yield addTab("http://mochi.test:8888/#4", gBrowser.currentURI);
- gBrowser.selectedTab = tabs[3];
- yield addTab("http://mochi.test:8888/#5", gBrowser.currentURI);
- gBrowser.removeTab(tabs.pop());
- yield addTab("about:blank", gBrowser.currentURI);
- gBrowser.moveTabTo(gBrowser.selectedTab, 1);
- yield addTab("http://mochi.test:8888/#6", gBrowser.currentURI);
- yield addTab();
- yield addTab("http://mochi.test:8888/#7");
-
- function testPosition(tabNum, expectedPosition, msg) {
- is(Array.indexOf(gBrowser.tabs, tabs[tabNum]), expectedPosition, msg);
- }
-
- testPosition(0, 3, "tab without referrer was opened to the far right");
- testPosition(1, 7, "tab without referrer was opened to the far right");
- testPosition(2, 5, "tab with referrer opened immediately to the right");
- testPosition(3, 1, "next tab with referrer opened further to the right");
- testPosition(4, 4, "tab selection changed, tab opens immediately to the right");
- testPosition(5, 6, "blank tab with referrer opens to the right of 3rd original tab where removed tab was");
- testPosition(6, 2, "tab has moved, new tab opens immediately to the right");
- testPosition(7, 8, "blank tab without referrer opens at the end");
- testPosition(8, 9, "tab without referrer opens at the end");
-
- tabs.forEach(gBrowser.removeTab, gBrowser);
-});
diff --git a/browser/base/content/test/general/browser_remoteTroubleshoot.js b/browser/base/content/test/general/browser_remoteTroubleshoot.js
deleted file mode 100644
index 5c939dbd0..000000000
--- a/browser/base/content/test/general/browser_remoteTroubleshoot.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var {WebChannel} = Cu.import("resource://gre/modules/WebChannel.jsm", {});
-
-const TEST_URL_TAIL = "example.com/browser/browser/base/content/test/general/test_remoteTroubleshoot.html"
-const TEST_URI_GOOD = Services.io.newURI("https://" + TEST_URL_TAIL, null, null);
-const TEST_URI_BAD = Services.io.newURI("http://" + TEST_URL_TAIL, null, null);
-const TEST_URI_GOOD_OBJECT = Services.io.newURI("https://" + TEST_URL_TAIL + "?object", null, null);
-
-// Creates a one-shot web-channel for the test data to be sent back from the test page.
-function promiseChannelResponse(channelID, originOrPermission) {
- return new Promise((resolve, reject) => {
- let channel = new WebChannel(channelID, originOrPermission);
- channel.listen((id, data, target) => {
- channel.stopListening();
- resolve(data);
- });
- });
-}
-
-// Loads the specified URI in a new tab and waits for it to send us data on our
-// test web-channel and resolves with that data.
-function promiseNewChannelResponse(uri) {
- let channelPromise = promiseChannelResponse("test-remote-troubleshooting-backchannel",
- uri);
- let tab = gBrowser.loadOneTab(uri.spec, { inBackground: false });
- return promiseTabLoaded(tab).then(
- () => channelPromise
- ).then(data => {
- gBrowser.removeTab(tab);
- return data;
- });
-}
-
-add_task(function*() {
- // We haven't set a permission yet - so even the "good" URI should fail.
- let got = yield promiseNewChannelResponse(TEST_URI_GOOD);
- // Should have no data.
- Assert.ok(got.message === undefined, "should have failed to get any data");
-
- // Add a permission manager entry for our URI.
- Services.perms.add(TEST_URI_GOOD,
- "remote-troubleshooting",
- Services.perms.ALLOW_ACTION);
- registerCleanupFunction(() => {
- Services.perms.remove(TEST_URI_GOOD, "remote-troubleshooting");
- });
-
- // Try again - now we are expecting a response with the actual data.
- got = yield promiseNewChannelResponse(TEST_URI_GOOD);
-
- // Check some keys we expect to always get.
- Assert.ok(got.message.extensions, "should have extensions");
- Assert.ok(got.message.graphics, "should have graphics");
-
- // Check we have channel and build ID info:
- Assert.equal(got.message.application.buildID, Services.appinfo.appBuildID,
- "should have correct build ID");
-
- let updateChannel = null;
- try {
- updateChannel = Cu.import("resource://gre/modules/UpdateUtils.jsm", {}).UpdateUtils.UpdateChannel;
- } catch (ex) {}
- if (!updateChannel) {
- Assert.ok(!('updateChannel' in got.message.application),
- "should not have update channel where not available.");
- } else {
- Assert.equal(got.message.application.updateChannel, updateChannel,
- "should have correct update channel.");
- }
-
-
- // And check some keys we know we decline to return.
- Assert.ok(!got.message.modifiedPreferences, "should not have a modifiedPreferences key");
- Assert.ok(!got.message.crashes, "should not have crash info");
-
- // Now a http:// URI - should get nothing even with the permission setup.
- got = yield promiseNewChannelResponse(TEST_URI_BAD);
- Assert.ok(got.message === undefined, "should have failed to get any data");
-
- // Check that the page can send an object as well if it's in the whitelist
- let webchannelWhitelistPref = "webchannel.allowObject.urlWhitelist";
- let origWhitelist = Services.prefs.getCharPref(webchannelWhitelistPref);
- let newWhitelist = origWhitelist + " https://example.com";
- Services.prefs.setCharPref(webchannelWhitelistPref, newWhitelist);
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref(webchannelWhitelistPref);
- });
- got = yield promiseNewChannelResponse(TEST_URI_GOOD_OBJECT);
- Assert.ok(got.message, "should have gotten some data back");
-});
diff --git a/browser/base/content/test/general/browser_remoteWebNavigation_postdata.js b/browser/base/content/test/general/browser_remoteWebNavigation_postdata.js
deleted file mode 100644
index 451323f50..000000000
--- a/browser/base/content/test/general/browser_remoteWebNavigation_postdata.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Cu.import("resource://gre/modules/BrowserUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-function makeInputStream(aString) {
- let stream = Cc["@mozilla.org/io/string-input-stream;1"]
- .createInstance(Ci.nsIStringInputStream);
- stream.data = aString;
- return stream; // XPConnect will QI this to nsIInputStream for us.
-}
-
-add_task(function* test_remoteWebNavigation_postdata() {
- let obj = {};
- Cu.import("resource://testing-common/httpd.js", obj);
- Cu.import("resource://services-common/utils.js", obj);
-
- let server = new obj.HttpServer();
- server.start(-1);
-
- let loadDeferred = Promise.defer();
-
- server.registerPathHandler("/test", (request, response) => {
- let body = obj.CommonUtils.readBytesFromInputStream(request.bodyInputStream);
- is(body, "success", "request body is correct");
- is(request.method, "POST", "request was a post");
- response.write("Received from POST: " + body);
- loadDeferred.resolve();
- });
-
- let i = server.identity;
- let path = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort + "/test";
-
- let postdata =
- "Content-Length: 7\r\n" +
- "Content-Type: application/x-www-form-urlencoded\r\n" +
- "\r\n" +
- "success";
-
- openUILinkIn(path, "tab", null, makeInputStream(postdata));
-
- yield loadDeferred.promise;
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- let serverStoppedDeferred = Promise.defer();
- server.stop(function() { serverStoppedDeferred.resolve(); });
- yield serverStoppedDeferred.promise;
-});
diff --git a/browser/base/content/test/general/browser_removeTabsToTheEnd.js b/browser/base/content/test/general/browser_removeTabsToTheEnd.js
deleted file mode 100644
index 351085d74..000000000
--- a/browser/base/content/test/general/browser_removeTabsToTheEnd.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- // Add two new tabs after the original tab. Pin the first one.
- let originalTab = gBrowser.selectedTab;
- let newTab1 = gBrowser.addTab();
- gBrowser.addTab();
- gBrowser.pinTab(newTab1);
-
- // Check that there is only one closable tab from originalTab to the end
- is(gBrowser.getTabsToTheEndFrom(originalTab).length, 1,
- "One unpinned tab to the right");
-
- // Remove tabs to the end
- gBrowser.removeTabsToTheEndFrom(originalTab);
- is(gBrowser.tabs.length, 2, "Length is 2");
- is(gBrowser.tabs[1], originalTab, "Starting tab is not removed");
- is(gBrowser.tabs[0], newTab1, "Pinned tab is not removed");
-
- // Remove pinned tab
- gBrowser.removeTab(newTab1);
-}
diff --git a/browser/base/content/test/general/browser_restore_isAppTab.js b/browser/base/content/test/general/browser_restore_isAppTab.js
deleted file mode 100644
index e20974d80..000000000
--- a/browser/base/content/test/general/browser_restore_isAppTab.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-const DUMMY = "http://example.com/browser/browser/base/content/test/general/dummy_page.html";
-
-function getMinidumpDirectory() {
- let dir = Services.dirsvc.get('ProfD', Ci.nsIFile);
- dir.append("minidumps");
- return dir;
-}
-
-// This observer is needed so we can clean up all evidence of the crash so
-// the testrunner thinks things are peachy.
-var CrashObserver = {
- observe: function(subject, topic, data) {
- is(topic, 'ipc:content-shutdown', 'Received correct observer topic.');
- ok(subject instanceof Ci.nsIPropertyBag2,
- 'Subject implements nsIPropertyBag2.');
- // we might see this called as the process terminates due to previous tests.
- // We are only looking for "abnormal" exits...
- if (!subject.hasKey("abnormal")) {
- info("This is a normal termination and isn't the one we are looking for...");
- return;
- }
-
- let dumpID;
- if ('nsICrashReporter' in Ci) {
- dumpID = subject.getPropertyAsAString('dumpID');
- ok(dumpID, "dumpID is present and not an empty string");
- }
-
- if (dumpID) {
- let minidumpDirectory = getMinidumpDirectory();
- let file = minidumpDirectory.clone();
- file.append(dumpID + '.dmp');
- file.remove(true);
- file = minidumpDirectory.clone();
- file.append(dumpID + '.extra');
- file.remove(true);
- }
- }
-}
-Services.obs.addObserver(CrashObserver, 'ipc:content-shutdown', false);
-
-registerCleanupFunction(() => {
- Services.obs.removeObserver(CrashObserver, 'ipc:content-shutdown');
-});
-
-function frameScript() {
- addMessageListener("Test:GetIsAppTab", function() {
- sendAsyncMessage("Test:IsAppTab", { isAppTab: docShell.isAppTab });
- });
-
- addMessageListener("Test:Crash", function() {
- privateNoteIntentionalCrash();
- Components.utils.import("resource://gre/modules/ctypes.jsm");
- let zero = new ctypes.intptr_t(8);
- let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
- badptr.contents
- });
-}
-
-function loadFrameScript(browser) {
- browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")();", true);
-}
-
-function isBrowserAppTab(browser) {
- return new Promise(resolve => {
- function listener({ data }) {
- browser.messageManager.removeMessageListener("Test:IsAppTab", listener);
- resolve(data.isAppTab);
- }
- // It looks like same-process messages may be reordered by the message
- // manager, so we need to wait one tick before sending the message.
- executeSoon(function () {
- browser.messageManager.addMessageListener("Test:IsAppTab", listener);
- browser.messageManager.sendAsyncMessage("Test:GetIsAppTab");
- });
- });
-}
-
-// Restarts the child process by crashing it then reloading the tab
-var restart = Task.async(function*(browser) {
- // If the tab isn't remote this would crash the main process so skip it
- if (!browser.isRemoteBrowser)
- return;
-
- // Make sure the main process has all of the current tab state before crashing
- yield TabStateFlusher.flush(browser);
-
- browser.messageManager.sendAsyncMessage("Test:Crash");
- yield promiseWaitForEvent(browser, "AboutTabCrashedLoad", false, true);
-
- let tab = gBrowser.getTabForBrowser(browser);
- SessionStore.reviveCrashedTab(tab);
-
- yield promiseTabLoaded(tab);
-});
-
-add_task(function* navigate() {
- let tab = gBrowser.addTab("about:robots");
- let browser = tab.linkedBrowser;
- gBrowser.selectedTab = tab;
- yield waitForDocLoadComplete();
- loadFrameScript(browser);
- let isAppTab = yield isBrowserAppTab(browser);
- ok(!isAppTab, "Docshell shouldn't think it is an app tab");
-
- gBrowser.pinTab(tab);
- isAppTab = yield isBrowserAppTab(browser);
- ok(isAppTab, "Docshell should think it is an app tab");
-
- gBrowser.loadURI(DUMMY);
- yield waitForDocLoadComplete();
- loadFrameScript(browser);
- isAppTab = yield isBrowserAppTab(browser);
- ok(isAppTab, "Docshell should think it is an app tab");
-
- gBrowser.unpinTab(tab);
- isAppTab = yield isBrowserAppTab(browser);
- ok(!isAppTab, "Docshell shouldn't think it is an app tab");
-
- gBrowser.pinTab(tab);
- isAppTab = yield isBrowserAppTab(browser);
- ok(isAppTab, "Docshell should think it is an app tab");
-
- gBrowser.loadURI("about:robots");
- yield waitForDocLoadComplete();
- loadFrameScript(browser);
- isAppTab = yield isBrowserAppTab(browser);
- ok(isAppTab, "Docshell should think it is an app tab");
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* crash() {
- if (!gMultiProcessBrowser || !("nsICrashReporter" in Ci))
- return;
-
- let tab = gBrowser.addTab(DUMMY);
- let browser = tab.linkedBrowser;
- gBrowser.selectedTab = tab;
- yield waitForDocLoadComplete();
- loadFrameScript(browser);
- let isAppTab = yield isBrowserAppTab(browser);
- ok(!isAppTab, "Docshell shouldn't think it is an app tab");
-
- gBrowser.pinTab(tab);
- isAppTab = yield isBrowserAppTab(browser);
- ok(isAppTab, "Docshell should think it is an app tab");
-
- yield restart(browser);
- loadFrameScript(browser);
- isAppTab = yield isBrowserAppTab(browser);
- ok(isAppTab, "Docshell should think it is an app tab");
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_sanitize-passwordDisabledHosts.js b/browser/base/content/test/general/browser_sanitize-passwordDisabledHosts.js
deleted file mode 100644
index 4f4f5c398..000000000
--- a/browser/base/content/test/general/browser_sanitize-passwordDisabledHosts.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Bug 474792 - Clear "Never remember passwords for this site" when
-// clearing site-specific settings in Clear Recent History dialog
-
-var tempScope = {};
-Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-var Sanitizer = tempScope.Sanitizer;
-
-add_task(function*() {
- var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
-
- // Add a disabled host
- pwmgr.setLoginSavingEnabled("http://example.com", false);
- // Sanity check
- is(pwmgr.getLoginSavingEnabled("http://example.com"), false,
- "example.com should be disabled for password saving since we haven't cleared that yet.");
-
- // Set up the sanitizer to just clear siteSettings
- let s = new Sanitizer();
- s.ignoreTimespan = false;
- s.prefDomain = "privacy.cpd.";
- var itemPrefs = gPrefService.getBranch(s.prefDomain);
- itemPrefs.setBoolPref("history", false);
- itemPrefs.setBoolPref("downloads", false);
- itemPrefs.setBoolPref("cache", false);
- itemPrefs.setBoolPref("cookies", false);
- itemPrefs.setBoolPref("formdata", false);
- itemPrefs.setBoolPref("offlineApps", false);
- itemPrefs.setBoolPref("passwords", false);
- itemPrefs.setBoolPref("sessions", false);
- itemPrefs.setBoolPref("siteSettings", true);
-
- // Clear it
- yield s.sanitize();
-
- // Make sure it's gone
- is(pwmgr.getLoginSavingEnabled("http://example.com"), true,
- "example.com should be enabled for password saving again now that we've cleared.");
-});
diff --git a/browser/base/content/test/general/browser_sanitize-sitepermissions.js b/browser/base/content/test/general/browser_sanitize-sitepermissions.js
deleted file mode 100644
index 1b43d62fc..000000000
--- a/browser/base/content/test/general/browser_sanitize-sitepermissions.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Bug 380852 - Delete permission manager entries in Clear Recent History
-
-var tempScope = {};
-Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-var Sanitizer = tempScope.Sanitizer;
-
-function countPermissions() {
- let result = 0;
- let enumerator = Services.perms.enumerator;
- while (enumerator.hasMoreElements()) {
- result++;
- enumerator.getNext();
- }
- return result;
-}
-
-add_task(function* test() {
- // sanitize before we start so we have a good baseline.
- // Set up the sanitizer to just clear siteSettings
- let s = new Sanitizer();
- s.ignoreTimespan = false;
- s.prefDomain = "privacy.cpd.";
- var itemPrefs = gPrefService.getBranch(s.prefDomain);
- itemPrefs.setBoolPref("history", false);
- itemPrefs.setBoolPref("downloads", false);
- itemPrefs.setBoolPref("cache", false);
- itemPrefs.setBoolPref("cookies", false);
- itemPrefs.setBoolPref("formdata", false);
- itemPrefs.setBoolPref("offlineApps", false);
- itemPrefs.setBoolPref("passwords", false);
- itemPrefs.setBoolPref("sessions", false);
- itemPrefs.setBoolPref("siteSettings", true);
- s.sanitize();
-
- // Count how many permissions we start with - some are defaults that
- // will not be sanitized.
- let numAtStart = countPermissions();
-
- // Add a permission entry
- var pm = Services.perms;
- pm.add(makeURI("http://example.com"), "testing", pm.ALLOW_ACTION);
-
- // Sanity check
- ok(pm.enumerator.hasMoreElements(), "Permission manager should have elements, since we just added one");
-
- // Clear it
- yield s.sanitize();
-
- // Make sure it's gone
- is(numAtStart, countPermissions(), "Permission manager should have the same count it started with");
-});
diff --git a/browser/base/content/test/general/browser_sanitize-timespans.js b/browser/base/content/test/general/browser_sanitize-timespans.js
deleted file mode 100644
index 3712c5e1c..000000000
--- a/browser/base/content/test/general/browser_sanitize-timespans.js
+++ /dev/null
@@ -1,733 +0,0 @@
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-requestLongerTimeout(2);
-
-// Bug 453440 - Test the timespan-based logic of the sanitizer code
-var now_mSec = Date.now();
-var now_uSec = now_mSec * 1000;
-
-const kMsecPerMin = 60 * 1000;
-const kUsecPerMin = 60 * 1000000;
-
-var tempScope = {};
-Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-var Sanitizer = tempScope.Sanitizer;
-
-var FormHistory = (Components.utils.import("resource://gre/modules/FormHistory.jsm", {})).FormHistory;
-var Downloads = (Components.utils.import("resource://gre/modules/Downloads.jsm", {})).Downloads;
-
-function promiseFormHistoryRemoved() {
- let deferred = Promise.defer();
- Services.obs.addObserver(function onfh() {
- Services.obs.removeObserver(onfh, "satchel-storage-changed", false);
- deferred.resolve();
- }, "satchel-storage-changed", false);
- return deferred.promise;
-}
-
-function promiseDownloadRemoved(list) {
- let deferred = Promise.defer();
-
- let view = {
- onDownloadRemoved: function(download) {
- list.removeView(view);
- deferred.resolve();
- }
- };
-
- list.addView(view);
-
- return deferred.promise;
-}
-
-add_task(function* test() {
- yield setupDownloads();
- yield setupFormHistory();
- yield setupHistory();
- yield onHistoryReady();
-});
-
-function countEntries(name, message, check) {
- let deferred = Promise.defer();
-
- var obj = {};
- if (name !== null)
- obj.fieldname = name;
-
- let count;
- FormHistory.count(obj, { handleResult: result => count = result,
- handleError: function (error) {
- deferred.reject(error)
- throw new Error("Error occurred searching form history: " + error);
- },
- handleCompletion: function (reason) {
- if (!reason) {
- check(count, message);
- deferred.resolve();
- }
- },
- });
-
- return deferred.promise;
-}
-
-function* onHistoryReady() {
- var hoursSinceMidnight = new Date().getHours();
- var minutesSinceMidnight = hoursSinceMidnight * 60 + new Date().getMinutes();
-
- // Should test cookies here, but nsICookieManager/nsICookieService
- // doesn't let us fake creation times. bug 463127
-
- let s = new Sanitizer();
- s.ignoreTimespan = false;
- s.prefDomain = "privacy.cpd.";
- var itemPrefs = gPrefService.getBranch(s.prefDomain);
- itemPrefs.setBoolPref("history", true);
- itemPrefs.setBoolPref("downloads", true);
- itemPrefs.setBoolPref("cache", false);
- itemPrefs.setBoolPref("cookies", false);
- itemPrefs.setBoolPref("formdata", true);
- itemPrefs.setBoolPref("offlineApps", false);
- itemPrefs.setBoolPref("passwords", false);
- itemPrefs.setBoolPref("sessions", false);
- itemPrefs.setBoolPref("siteSettings", false);
-
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
- let downloadPromise = promiseDownloadRemoved(publicList);
- let formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 10 minutes ago
- s.range = [now_uSec - 10*60*1000000, now_uSec];
- yield s.sanitize();
- s.range = null;
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://10minutes.com"))),
- "Pretend visit to 10minutes.com should now be deleted");
- ok((yield promiseIsURIVisited(makeURI("http://1hour.com"))),
- "Pretend visit to 1hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))),
- "Pretend visit to 1hour10minutes.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))),
- "Pretend visit to 2hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
- "Pretend visit to 2hour10minutes.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
- "Pretend visit to 4hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should should still exist");
- if (minutesSinceMidnight > 10) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- let checkZero = function(num, message) { is(num, 0, message); }
- let checkOne = function(num, message) { is(num, 1, message); }
-
- yield countEntries("10minutes", "10minutes form entry should be deleted", checkZero);
- yield countEntries("1hour", "1hour form entry should still exist", checkOne);
- yield countEntries("1hour10minutes", "1hour10minutes form entry should still exist", checkOne);
- yield countEntries("2hour", "2hour form entry should still exist", checkOne);
- yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
- yield countEntries("4hour", "4hour form entry should still exist", checkOne);
- yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
- if (minutesSinceMidnight > 10)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-10-minutes")), "10 minute download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-1-hour")), "<1 hour download should still be present");
- ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
-
- if (minutesSinceMidnight > 10)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 1 hour
- Sanitizer.prefs.setIntPref("timeSpan", 1);
- yield s.sanitize();
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://1hour.com"))),
- "Pretend visit to 1hour.com should now be deleted");
- ok((yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))),
- "Pretend visit to 1hour10minutes.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))),
- "Pretend visit to 2hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
- "Pretend visit to 2hour10minutes.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
- "Pretend visit to 4hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should should still exist");
- if (hoursSinceMidnight > 1) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- yield countEntries("1hour", "1hour form entry should be deleted", checkZero);
- yield countEntries("1hour10minutes", "1hour10minutes form entry should still exist", checkOne);
- yield countEntries("2hour", "2hour form entry should still exist", checkOne);
- yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
- yield countEntries("4hour", "4hour form entry should still exist", checkOne);
- yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
- if (hoursSinceMidnight > 1)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-1-hour")), "<1 hour download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
-
- if (hoursSinceMidnight > 1)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 1 hour 10 minutes
- s.range = [now_uSec - 70*60*1000000, now_uSec];
- yield s.sanitize();
- s.range = null;
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))),
- "Pretend visit to 1hour10minutes.com should now be deleted");
- ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))),
- "Pretend visit to 2hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
- "Pretend visit to 2hour10minutes.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
- "Pretend visit to 4hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should should still exist");
- if (minutesSinceMidnight > 70) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- yield countEntries("1hour10minutes", "1hour10minutes form entry should be deleted", checkZero);
- yield countEntries("2hour", "2hour form entry should still exist", checkOne);
- yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
- yield countEntries("4hour", "4hour form entry should still exist", checkOne);
- yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
- if (minutesSinceMidnight > 70)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute old download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
- if (minutesSinceMidnight > 70)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 2 hours
- Sanitizer.prefs.setIntPref("timeSpan", 2);
- yield s.sanitize();
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://2hour.com"))),
- "Pretend visit to 2hour.com should now be deleted");
- ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
- "Pretend visit to 2hour10minutes.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
- "Pretend visit to 4hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should should still exist");
- if (hoursSinceMidnight > 2) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- yield countEntries("2hour", "2hour form entry should be deleted", checkZero);
- yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
- yield countEntries("4hour", "4hour form entry should still exist", checkOne);
- yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
- if (hoursSinceMidnight > 2)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
- if (hoursSinceMidnight > 2)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 2 hours 10 minutes
- s.range = [now_uSec - 130*60*1000000, now_uSec];
- yield s.sanitize();
- s.range = null;
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
- "Pretend visit to 2hour10minutes.com should now be deleted");
- ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
- "Pretend visit to 4hour.com should should still exist");
- ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should should still exist");
- if (minutesSinceMidnight > 130) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- yield countEntries("2hour10minutes", "2hour10minutes form entry should be deleted", checkZero);
- yield countEntries("4hour", "4hour form entry should still exist", checkOne);
- yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
- if (minutesSinceMidnight > 130)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute old download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- if (minutesSinceMidnight > 130)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 4 hours
- Sanitizer.prefs.setIntPref("timeSpan", 3);
- yield s.sanitize();
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://4hour.com"))),
- "Pretend visit to 4hour.com should now be deleted");
- ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should should still exist");
- if (hoursSinceMidnight > 4) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- yield countEntries("4hour", "4hour form entry should be deleted", checkZero);
- yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
- if (hoursSinceMidnight > 4)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- if (hoursSinceMidnight > 4)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear 4 hours 10 minutes
- s.range = [now_uSec - 250*60*1000000, now_uSec];
- yield s.sanitize();
- s.range = null;
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
- "Pretend visit to 4hour10minutes.com should now be deleted");
- if (minutesSinceMidnight > 250) {
- ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should still exist");
- }
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
-
- yield countEntries("4hour10minutes", "4hour10minutes form entry should be deleted", checkZero);
- if (minutesSinceMidnight > 250)
- yield countEntries("today", "today form entry should still exist", checkOne);
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-
- ok(!(yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should now be deleted");
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
- if (minutesSinceMidnight > 250)
- ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
- // The 'Today' download might have been already deleted, in which case we
- // should not wait for a download removal notification.
- if (minutesSinceMidnight > 250) {
- downloadPromise = promiseDownloadRemoved(publicList);
- } else {
- downloadPromise = Promise.resolve();
- }
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Clear Today
- Sanitizer.prefs.setIntPref("timeSpan", 4);
- yield s.sanitize();
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- // Be careful. If we add our objectss just before midnight, and sanitize
- // runs immediately after, they won't be expired. This is expected, but
- // we should not test in that case. We cannot just test for opposite
- // condition because we could cross midnight just one moment after we
- // cache our time, then we would have an even worse random failure.
- var today = isToday(new Date(now_mSec));
- if (today) {
- ok(!(yield promiseIsURIVisited(makeURI("http://today.com"))),
- "Pretend visit to today.com should now be deleted");
-
- yield countEntries("today", "today form entry should be deleted", checkZero);
- ok(!(yield downloadExists(publicList, "fakefile-today")), "'Today' download should now be deleted");
- }
-
- ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should still exist");
- yield countEntries("b4today", "b4today form entry should still exist", checkOne);
- ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
-
- downloadPromise = promiseDownloadRemoved(publicList);
- formHistoryPromise = promiseFormHistoryRemoved();
-
- // Choose everything
- Sanitizer.prefs.setIntPref("timeSpan", 0);
- yield s.sanitize();
-
- yield formHistoryPromise;
- yield downloadPromise;
-
- ok(!(yield promiseIsURIVisited(makeURI("http://before-today.com"))),
- "Pretend visit to before-today.com should now be deleted");
-
- yield countEntries("b4today", "b4today form entry should be deleted", checkZero);
-
- ok(!(yield downloadExists(publicList, "fakefile-old")), "Year old download should now be deleted");
-}
-
-function setupHistory() {
- let deferred = Promise.defer();
-
- let places = [];
-
- function addPlace(aURI, aTitle, aVisitDate) {
- places.push({
- uri: aURI,
- title: aTitle,
- visits: [{
- visitDate: aVisitDate,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
- }]
- });
- }
-
- addPlace(makeURI("http://10minutes.com/"), "10 minutes ago", now_uSec - 10 * kUsecPerMin);
- addPlace(makeURI("http://1hour.com/"), "Less than 1 hour ago", now_uSec - 45 * kUsecPerMin);
- addPlace(makeURI("http://1hour10minutes.com/"), "1 hour 10 minutes ago", now_uSec - 70 * kUsecPerMin);
- addPlace(makeURI("http://2hour.com/"), "Less than 2 hours ago", now_uSec - 90 * kUsecPerMin);
- addPlace(makeURI("http://2hour10minutes.com/"), "2 hours 10 minutes ago", now_uSec - 130 * kUsecPerMin);
- addPlace(makeURI("http://4hour.com/"), "Less than 4 hours ago", now_uSec - 180 * kUsecPerMin);
- addPlace(makeURI("http://4hour10minutes.com/"), "4 hours 10 minutesago", now_uSec - 250 * kUsecPerMin);
-
- let today = new Date();
- today.setHours(0);
- today.setMinutes(0);
- today.setSeconds(1);
- addPlace(makeURI("http://today.com/"), "Today", today.getTime() * 1000);
-
- let lastYear = new Date();
- lastYear.setFullYear(lastYear.getFullYear() - 1);
- addPlace(makeURI("http://before-today.com/"), "Before Today", lastYear.getTime() * 1000);
- PlacesUtils.asyncHistory.updatePlaces(places, {
- handleError: () => ok(false, "Unexpected error in adding visit."),
- handleResult: () => { },
- handleCompletion: () => deferred.resolve()
- });
-
- return deferred.promise;
-}
-
-function* setupFormHistory() {
-
- function searchEntries(terms, params) {
- let deferred = Promise.defer();
-
- let results = [];
- FormHistory.search(terms, params, { handleResult: result => results.push(result),
- handleError: function (error) {
- deferred.reject(error);
- throw new Error("Error occurred searching form history: " + error);
- },
- handleCompletion: function (reason) { deferred.resolve(results); }
- });
- return deferred.promise;
- }
-
- function update(changes)
- {
- let deferred = Promise.defer();
- FormHistory.update(changes, { handleError: function (error) {
- deferred.reject(error);
- throw new Error("Error occurred searching form history: " + error);
- },
- handleCompletion: function (reason) { deferred.resolve(); }
- });
- return deferred.promise;
- }
-
- // Make sure we've got a clean DB to start with, then add the entries we'll be testing.
- yield update(
- [{
- op: "remove"
- },
- {
- op : "add",
- fieldname : "10minutes",
- value : "10m"
- }, {
- op : "add",
- fieldname : "1hour",
- value : "1h"
- }, {
- op : "add",
- fieldname : "1hour10minutes",
- value : "1h10m"
- }, {
- op : "add",
- fieldname : "2hour",
- value : "2h"
- }, {
- op : "add",
- fieldname : "2hour10minutes",
- value : "2h10m"
- }, {
- op : "add",
- fieldname : "4hour",
- value : "4h"
- }, {
- op : "add",
- fieldname : "4hour10minutes",
- value : "4h10m"
- }, {
- op : "add",
- fieldname : "today",
- value : "1d"
- }, {
- op : "add",
- fieldname : "b4today",
- value : "1y"
- }]);
-
- // Artifically age the entries to the proper vintage.
- let timestamp = now_uSec - 10 * kUsecPerMin;
- let results = yield searchEntries(["guid"], { fieldname: "10minutes" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- timestamp = now_uSec - 45 * kUsecPerMin;
- results = yield searchEntries(["guid"], { fieldname: "1hour" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- timestamp = now_uSec - 70 * kUsecPerMin;
- results = yield searchEntries(["guid"], { fieldname: "1hour10minutes" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- timestamp = now_uSec - 90 * kUsecPerMin;
- results = yield searchEntries(["guid"], { fieldname: "2hour" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- timestamp = now_uSec - 130 * kUsecPerMin;
- results = yield searchEntries(["guid"], { fieldname: "2hour10minutes" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- timestamp = now_uSec - 180 * kUsecPerMin;
- results = yield searchEntries(["guid"], { fieldname: "4hour" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- timestamp = now_uSec - 250 * kUsecPerMin;
- results = yield searchEntries(["guid"], { fieldname: "4hour10minutes" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- let today = new Date();
- today.setHours(0);
- today.setMinutes(0);
- today.setSeconds(1);
- timestamp = today.getTime() * 1000;
- results = yield searchEntries(["guid"], { fieldname: "today" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- let lastYear = new Date();
- lastYear.setFullYear(lastYear.getFullYear() - 1);
- timestamp = lastYear.getTime() * 1000;
- results = yield searchEntries(["guid"], { fieldname: "b4today" });
- yield update({ op: "update", firstUsed: timestamp, guid: results[0].guid });
-
- var checks = 0;
- let checkOne = function(num, message) { is(num, 1, message); checks++; }
-
- // Sanity check.
- yield countEntries("10minutes", "Checking for 10minutes form history entry creation", checkOne);
- yield countEntries("1hour", "Checking for 1hour form history entry creation", checkOne);
- yield countEntries("1hour10minutes", "Checking for 1hour10minutes form history entry creation", checkOne);
- yield countEntries("2hour", "Checking for 2hour form history entry creation", checkOne);
- yield countEntries("2hour10minutes", "Checking for 2hour10minutes form history entry creation", checkOne);
- yield countEntries("4hour", "Checking for 4hour form history entry creation", checkOne);
- yield countEntries("4hour10minutes", "Checking for 4hour10minutes form history entry creation", checkOne);
- yield countEntries("today", "Checking for today form history entry creation", checkOne);
- yield countEntries("b4today", "Checking for b4today form history entry creation", checkOne);
- is(checks, 9, "9 checks made");
-}
-
-function* setupDownloads() {
-
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
-
- let download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
- target: "fakefile-10-minutes"
- });
- download.startTime = new Date(now_mSec - 10 * kMsecPerMin), // 10 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
- target: "fakefile-1-hour"
- });
- download.startTime = new Date(now_mSec - 45 * kMsecPerMin), // 45 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
- target: "fakefile-1-hour-10-minutes"
- });
- download.startTime = new Date(now_mSec - 70 * kMsecPerMin), // 70 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
- target: "fakefile-2-hour"
- });
- download.startTime = new Date(now_mSec - 90 * kMsecPerMin), // 90 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
- target: "fakefile-2-hour-10-minutes"
- });
- download.startTime = new Date(now_mSec - 130 * kMsecPerMin), // 130 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
- target: "fakefile-4-hour"
- });
- download.startTime = new Date(now_mSec - 180 * kMsecPerMin), // 180 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
- target: "fakefile-4-hour-10-minutes"
- });
- download.startTime = new Date(now_mSec - 250 * kMsecPerMin), // 250 minutes ago
- download.canceled = true;
- yield publicList.add(download);
-
- // Add "today" download
- let today = new Date();
- today.setHours(0);
- today.setMinutes(0);
- today.setSeconds(1);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
- target: "fakefile-today"
- });
- download.startTime = today, // 12:00:01 AM this morning
- download.canceled = true;
- yield publicList.add(download);
-
- // Add "before today" download
- let lastYear = new Date();
- lastYear.setFullYear(lastYear.getFullYear() - 1);
-
- download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
- target: "fakefile-old"
- });
- download.startTime = lastYear,
- download.canceled = true;
- yield publicList.add(download);
-
- // Confirm everything worked
- let downloads = yield publicList.getAll();
- is(downloads.length, 9, "9 Pretend downloads added");
-
- ok((yield downloadExists(publicList, "fakefile-old")), "Pretend download for everything case should exist");
- ok((yield downloadExists(publicList, "fakefile-10-minutes")), "Pretend download for 10-minutes case should exist");
- ok((yield downloadExists(publicList, "fakefile-1-hour")), "Pretend download for 1-hour case should exist");
- ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "Pretend download for 1-hour-10-minutes case should exist");
- ok((yield downloadExists(publicList, "fakefile-2-hour")), "Pretend download for 2-hour case should exist");
- ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "Pretend download for 2-hour-10-minutes case should exist");
- ok((yield downloadExists(publicList, "fakefile-4-hour")), "Pretend download for 4-hour case should exist");
- ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "Pretend download for 4-hour-10-minutes case should exist");
- ok((yield downloadExists(publicList, "fakefile-today")), "Pretend download for Today case should exist");
-}
-
-/**
- * Checks to see if the downloads with the specified id exists.
- *
- * @param aID
- * The ids of the downloads to check.
- */
-let downloadExists = Task.async(function* (list, path) {
- let listArray = yield list.getAll();
- return listArray.some(i => i.target.path == path);
-});
-
-function isToday(aDate) {
- return aDate.getDate() == new Date().getDate();
-}
diff --git a/browser/base/content/test/general/browser_sanitizeDialog.js b/browser/base/content/test/general/browser_sanitizeDialog.js
deleted file mode 100644
index 50546be45..000000000
--- a/browser/base/content/test/general/browser_sanitizeDialog.js
+++ /dev/null
@@ -1,1027 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests the sanitize dialog (a.k.a. the clear recent history dialog).
- * See bug 480169.
- *
- * The purpose of this test is not to fully flex the sanitize timespan code;
- * browser/base/content/test/general/browser_sanitize-timespans.js does that. This
- * test checks the UI of the dialog and makes sure it's correctly connected to
- * the sanitize timespan code.
- *
- * Some of this code, especially the history creation parts, was taken from
- * browser/base/content/test/general/browser_sanitize-timespans.js.
- */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-var {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
-
-XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
- "resource://gre/modules/FormHistory.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
- "resource://gre/modules/Downloads.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Timer",
- "resource://gre/modules/Timer.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-var tempScope = {};
-Services.scriptloader.loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-var Sanitizer = tempScope.Sanitizer;
-
-const kMsecPerMin = 60 * 1000;
-const kUsecPerMin = 60 * 1000000;
-
-add_task(function* init() {
- requestLongerTimeout(3);
- yield blankSlate();
- registerCleanupFunction(function* () {
- yield blankSlate();
- yield PlacesTestUtils.promiseAsyncUpdates();
- });
-});
-
-/**
- * Initializes the dialog to its default state.
- */
-add_task(function* default_state() {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Select "Last Hour"
- this.selectDuration(Sanitizer.TIMESPAN_HOUR);
- // Hide details
- if (!this.getItemList().collapsed)
- this.toggleDetails();
- this.acceptDialog();
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-/**
- * Cancels the dialog, makes sure history not cleared.
- */
-add_task(function* test_cancel() {
- // Add history (within the past hour)
- let uris = [];
- let places = [];
- let pURI;
- for (let i = 0; i < 30; i++) {
- pURI = makeURI("http://" + i + "-minutes-ago.com/");
- places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
- uris.push(pURI);
- }
- yield PlacesTestUtils.addVisits(places);
-
- let wh = new WindowHelper();
- wh.onload = function () {
- this.selectDuration(Sanitizer.TIMESPAN_HOUR);
- this.checkPrefCheckbox("history", false);
- this.checkDetails(false);
-
- // Show details
- this.toggleDetails();
- this.checkDetails(true);
-
- // Hide details
- this.toggleDetails();
- this.checkDetails(false);
- this.cancelDialog();
- };
- wh.onunload = function* () {
- yield promiseHistoryClearedState(uris, false);
- yield blankSlate();
- yield promiseHistoryClearedState(uris, true);
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-/**
- * Ensures that the combined history-downloads checkbox clears both history
- * visits and downloads when checked; the dialog respects simple timespan.
- */
-add_task(function* test_history_downloads_checked() {
- // Add downloads (within the past hour).
- let downloadIDs = [];
- for (let i = 0; i < 5; i++) {
- yield addDownloadWithMinutesAgo(downloadIDs, i);
- }
- // Add downloads (over an hour ago).
- let olderDownloadIDs = [];
- for (let i = 0; i < 5; i++) {
- yield addDownloadWithMinutesAgo(olderDownloadIDs, 61 + i);
- }
-
- // Add history (within the past hour).
- let uris = [];
- let places = [];
- let pURI;
- for (let i = 0; i < 30; i++) {
- pURI = makeURI("http://" + i + "-minutes-ago.com/");
- places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
- uris.push(pURI);
- }
- // Add history (over an hour ago).
- let olderURIs = [];
- for (let i = 0; i < 5; i++) {
- pURI = makeURI("http://" + (61 + i) + "-minutes-ago.com/");
- places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i)});
- olderURIs.push(pURI);
- }
- let promiseSanitized = promiseSanitizationComplete();
-
- yield PlacesTestUtils.addVisits(places);
-
- let wh = new WindowHelper();
- wh.onload = function () {
- this.selectDuration(Sanitizer.TIMESPAN_HOUR);
- this.checkPrefCheckbox("history", true);
- this.acceptDialog();
- };
- wh.onunload = function* () {
- intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR,
- "timeSpan pref should be hour after accepting dialog with " +
- "hour selected");
- boolPrefIs("cpd.history", true,
- "history pref should be true after accepting dialog with " +
- "history checkbox checked");
- boolPrefIs("cpd.downloads", true,
- "downloads pref should be true after accepting dialog with " +
- "history checkbox checked");
-
- yield promiseSanitized;
-
- // History visits and downloads within one hour should be cleared.
- yield promiseHistoryClearedState(uris, true);
- yield ensureDownloadsClearedState(downloadIDs, true);
-
- // Visits and downloads > 1 hour should still exist.
- yield promiseHistoryClearedState(olderURIs, false);
- yield ensureDownloadsClearedState(olderDownloadIDs, false);
-
- // OK, done, cleanup after ourselves.
- yield blankSlate();
- yield promiseHistoryClearedState(olderURIs, true);
- yield ensureDownloadsClearedState(olderDownloadIDs, true);
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-/**
- * Ensures that the combined history-downloads checkbox removes neither
- * history visits nor downloads when not checked.
- */
-add_task(function* test_history_downloads_unchecked() {
- // Add form entries
- let formEntries = [];
-
- for (let i = 0; i < 5; i++) {
- formEntries.push((yield promiseAddFormEntryWithMinutesAgo(i)));
- }
-
-
- // Add downloads (within the past hour).
- let downloadIDs = [];
- for (let i = 0; i < 5; i++) {
- yield addDownloadWithMinutesAgo(downloadIDs, i);
- }
-
- // Add history, downloads, form entries (within the past hour).
- let uris = [];
- let places = [];
- let pURI;
- for (let i = 0; i < 5; i++) {
- pURI = makeURI("http://" + i + "-minutes-ago.com/");
- places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
- uris.push(pURI);
- }
-
- yield PlacesTestUtils.addVisits(places);
- let wh = new WindowHelper();
- wh.onload = function () {
- is(this.isWarningPanelVisible(), false,
- "Warning panel should be hidden after previously accepting dialog " +
- "with a predefined timespan");
- this.selectDuration(Sanitizer.TIMESPAN_HOUR);
-
- // Remove only form entries, leave history (including downloads).
- this.checkPrefCheckbox("history", false);
- this.checkPrefCheckbox("formdata", true);
- this.acceptDialog();
- };
- wh.onunload = function* () {
- intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR,
- "timeSpan pref should be hour after accepting dialog with " +
- "hour selected");
- boolPrefIs("cpd.history", false,
- "history pref should be false after accepting dialog with " +
- "history checkbox unchecked");
- boolPrefIs("cpd.downloads", false,
- "downloads pref should be false after accepting dialog with " +
- "history checkbox unchecked");
-
- // Of the three only form entries should be cleared.
- yield promiseHistoryClearedState(uris, false);
- yield ensureDownloadsClearedState(downloadIDs, false);
-
- for (let entry of formEntries) {
- let exists = yield formNameExists(entry);
- is(exists, false, "form entry " + entry + " should no longer exist");
- }
-
- // OK, done, cleanup after ourselves.
- yield blankSlate();
- yield promiseHistoryClearedState(uris, true);
- yield ensureDownloadsClearedState(downloadIDs, true);
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-/**
- * Ensures that the "Everything" duration option works.
- */
-add_task(function* test_everything() {
- // Add history.
- let uris = [];
- let places = [];
- let pURI;
- // within past hour, within past two hours, within past four hours and
- // outside past four hours
- [10, 70, 130, 250].forEach(function(aValue) {
- pURI = makeURI("http://" + aValue + "-minutes-ago.com/");
- places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)});
- uris.push(pURI);
- });
-
- let promiseSanitized = promiseSanitizationComplete();
-
- yield PlacesTestUtils.addVisits(places);
- let wh = new WindowHelper();
- wh.onload = function () {
- is(this.isWarningPanelVisible(), false,
- "Warning panel should be hidden after previously accepting dialog " +
- "with a predefined timespan");
- this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
- this.checkPrefCheckbox("history", true);
- this.checkDetails(true);
-
- // Hide details
- this.toggleDetails();
- this.checkDetails(false);
-
- // Show details
- this.toggleDetails();
- this.checkDetails(true);
-
- this.acceptDialog();
- };
- wh.onunload = function* () {
- yield promiseSanitized;
- intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
- "timeSpan pref should be everything after accepting dialog " +
- "with everything selected");
-
- yield promiseHistoryClearedState(uris, true);
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-/**
- * Ensures that the "Everything" warning is visible on dialog open after
- * the previous test.
- */
-add_task(function* test_everything_warning() {
- // Add history.
- let uris = [];
- let places = [];
- let pURI;
- // within past hour, within past two hours, within past four hours and
- // outside past four hours
- [10, 70, 130, 250].forEach(function(aValue) {
- pURI = makeURI("http://" + aValue + "-minutes-ago.com/");
- places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)});
- uris.push(pURI);
- });
-
- let promiseSanitized = promiseSanitizationComplete();
-
- yield PlacesTestUtils.addVisits(places);
- let wh = new WindowHelper();
- wh.onload = function () {
- is(this.isWarningPanelVisible(), true,
- "Warning panel should be visible after previously accepting dialog " +
- "with clearing everything");
- this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
- this.checkPrefCheckbox("history", true);
- this.acceptDialog();
- };
- wh.onunload = function* () {
- intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING,
- "timeSpan pref should be everything after accepting dialog " +
- "with everything selected");
-
- yield promiseSanitized;
-
- yield promiseHistoryClearedState(uris, true);
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-/**
- * The next three tests checks that when a certain history item cannot be
- * cleared then the checkbox should be both disabled and unchecked.
- * In addition, we ensure that this behavior does not modify the preferences.
- */
-add_task(function* test_cannot_clear_history() {
- // Add form entries
- let formEntries = [ (yield promiseAddFormEntryWithMinutesAgo(10)) ];
-
- let promiseSanitized = promiseSanitizationComplete();
-
- // Add history.
- let pURI = makeURI("http://" + 10 + "-minutes-ago.com/");
- yield PlacesTestUtils.addVisits({uri: pURI, visitDate: visitTimeForMinutesAgo(10)});
- let uris = [ pURI ];
-
- let wh = new WindowHelper();
- wh.onload = function() {
- // Check that the relevant checkboxes are enabled
- var cb = this.win.document.querySelectorAll(
- "#itemList > [preference='privacy.cpd.formdata']");
- ok(cb.length == 1 && !cb[0].disabled, "There is formdata, checkbox to " +
- "clear formdata should be enabled.");
-
- cb = this.win.document.querySelectorAll(
- "#itemList > [preference='privacy.cpd.history']");
- ok(cb.length == 1 && !cb[0].disabled, "There is history, checkbox to " +
- "clear history should be enabled.");
-
- this.checkAllCheckboxes();
- this.acceptDialog();
- };
- wh.onunload = function* () {
- yield promiseSanitized;
-
- yield promiseHistoryClearedState(uris, true);
-
- let exists = yield formNameExists(formEntries[0]);
- is(exists, false, "form entry " + formEntries[0] + " should no longer exist");
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-add_task(function* test_no_formdata_history_to_clear() {
- let promiseSanitized = promiseSanitizationComplete();
- let wh = new WindowHelper();
- wh.onload = function() {
- boolPrefIs("cpd.history", true,
- "history pref should be true after accepting dialog with " +
- "history checkbox checked");
- boolPrefIs("cpd.formdata", true,
- "formdata pref should be true after accepting dialog with " +
- "formdata checkbox checked");
-
- var cb = this.win.document.querySelectorAll(
- "#itemList > [preference='privacy.cpd.history']");
- ok(cb.length == 1 && !cb[0].disabled && cb[0].checked,
- "There is no history, but history checkbox should always be enabled " +
- "and will be checked from previous preference.");
-
- this.acceptDialog();
- }
- wh.open();
- yield wh.promiseClosed;
- yield promiseSanitized;
-});
-
-add_task(function* test_form_entries() {
- let formEntry = (yield promiseAddFormEntryWithMinutesAgo(10));
-
- let promiseSanitized = promiseSanitizationComplete();
-
- let wh = new WindowHelper();
- wh.onload = function() {
- boolPrefIs("cpd.formdata", true,
- "formdata pref should persist previous value after accepting " +
- "dialog where you could not clear formdata.");
-
- var cb = this.win.document.querySelectorAll(
- "#itemList > [preference='privacy.cpd.formdata']");
-
- info("There exists formEntries so the checkbox should be in sync with the pref.");
- is(cb.length, 1, "There is only one checkbox for form data");
- ok(!cb[0].disabled, "The checkbox is enabled");
- ok(cb[0].checked, "The checkbox is checked");
-
- this.acceptDialog();
- };
- wh.onunload = function* () {
- yield promiseSanitized;
- let exists = yield formNameExists(formEntry);
- is(exists, false, "form entry " + formEntry + " should no longer exist");
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-
-/**
- * Ensure that toggling details persists
- * across dialog openings.
- */
-add_task(function* test_toggling_details_persists() {
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Check all items and select "Everything"
- this.checkAllCheckboxes();
- this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
-
- // Hide details
- this.toggleDetails();
- this.checkDetails(false);
- this.acceptDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Details should remain closed because all items are checked.
- this.checkDetails(false);
-
- // Uncheck history.
- this.checkPrefCheckbox("history", false);
- this.acceptDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Details should be open because not all items are checked.
- this.checkDetails(true);
-
- // Modify the Site Preferences item state (bug 527820)
- this.checkAllCheckboxes();
- this.checkPrefCheckbox("siteSettings", false);
- this.acceptDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Details should be open because not all items are checked.
- this.checkDetails(true);
-
- // Hide details
- this.toggleDetails();
- this.checkDetails(false);
- this.cancelDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Details should be open because not all items are checked.
- this.checkDetails(true);
-
- // Select another duration
- this.selectDuration(Sanitizer.TIMESPAN_HOUR);
- // Hide details
- this.toggleDetails();
- this.checkDetails(false);
- this.acceptDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Details should not be open because "Last Hour" is selected
- this.checkDetails(false);
-
- this.cancelDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
- {
- let wh = new WindowHelper();
- wh.onload = function () {
- // Details should have remained closed
- this.checkDetails(false);
-
- // Show details
- this.toggleDetails();
- this.checkDetails(true);
- this.cancelDialog();
- };
- wh.open();
- yield wh.promiseClosed;
- }
-});
-
-// Test for offline cache deletion
-add_task(function* test_offline_cache() {
- // Prepare stuff, we will work with www.example.com
- var URL = "http://www.example.com";
- var URI = makeURI(URL);
- var principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(URI);
-
- // Give www.example.com privileges to store offline data
- Services.perms.addFromPrincipal(principal, "offline-app", Ci.nsIPermissionManager.ALLOW_ACTION);
- Services.perms.addFromPrincipal(principal, "offline-app", Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
-
- // Store something to the offline cache
- var appcacheserv = Cc["@mozilla.org/network/application-cache-service;1"]
- .getService(Ci.nsIApplicationCacheService);
- var appcachegroupid = appcacheserv.buildGroupIDForInfo(makeURI(URL + "/manifest"), LoadContextInfo.default);
- var appcache = appcacheserv.createApplicationCache(appcachegroupid);
- var storage = Services.cache2.appCacheStorage(LoadContextInfo.default, appcache);
-
- // Open the dialog
- let wh = new WindowHelper();
- wh.onload = function () {
- this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
- // Show details
- this.toggleDetails();
- // Clear only offlineApps
- this.uncheckAllCheckboxes();
- this.checkPrefCheckbox("offlineApps", true);
- this.acceptDialog();
- };
- wh.onunload = function () {
- // Check if the cache has been deleted
- var size = -1;
- var visitor = {
- onCacheStorageInfo: function (aEntryCount, aConsumption, aCapacity, aDiskDirectory)
- {
- size = aConsumption;
- }
- };
- storage.asyncVisitStorage(visitor, false);
- // Offline cache visit happens synchronously, since it's forwarded to the old code
- is(size, 0, "offline application cache entries evicted");
- };
-
- var cacheListener = {
- onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; },
- onCacheEntryAvailable: function (entry, isnew, unused, status) {
- is(status, Cr.NS_OK);
- var stream = entry.openOutputStream(0);
- var content = "content";
- stream.write(content, content.length);
- stream.close();
- entry.close();
- wh.open();
- }
- };
-
- storage.asyncOpenURI(makeURI(URL), "", Ci.nsICacheStorage.OPEN_TRUNCATE, cacheListener);
- yield wh.promiseClosed;
-});
-
-// Test for offline apps permission deletion
-add_task(function* test_offline_apps_permissions() {
- // Prepare stuff, we will work with www.example.com
- var URL = "http://www.example.com";
- var URI = makeURI(URL);
- var principal = Services.scriptSecurityManager.createCodebasePrincipal(URI, {});
-
- let promiseSanitized = promiseSanitizationComplete();
-
- // Open the dialog
- let wh = new WindowHelper();
- wh.onload = function () {
- this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING);
- // Show details
- this.toggleDetails();
- // Clear only offlineApps
- this.uncheckAllCheckboxes();
- this.checkPrefCheckbox("siteSettings", true);
- this.acceptDialog();
- };
- wh.onunload = function* () {
- yield promiseSanitized;
-
- // Check all has been deleted (privileges, data, cache)
- is(Services.perms.testPermissionFromPrincipal(principal, "offline-app"), 0, "offline-app permissions removed");
- };
- wh.open();
- yield wh.promiseClosed;
-});
-
-var now_mSec = Date.now();
-var now_uSec = now_mSec * 1000;
-
-/**
- * This wraps the dialog and provides some convenience methods for interacting
- * with it.
- *
- * @param aWin
- * The dialog's nsIDOMWindow
- */
-function WindowHelper(aWin) {
- this.win = aWin;
- this.promiseClosed = new Promise(resolve => { this._resolveClosed = resolve });
-}
-
-WindowHelper.prototype = {
- /**
- * "Presses" the dialog's OK button.
- */
- acceptDialog: function () {
- is(this.win.document.documentElement.getButton("accept").disabled, false,
- "Dialog's OK button should not be disabled");
- this.win.document.documentElement.acceptDialog();
- },
-
- /**
- * "Presses" the dialog's Cancel button.
- */
- cancelDialog: function () {
- this.win.document.documentElement.cancelDialog();
- },
-
- /**
- * Ensures that the details progressive disclosure button and the item list
- * hidden by it match up. Also makes sure the height of the dialog is
- * sufficient for the item list and warning panel.
- *
- * @param aShouldBeShown
- * True if you expect the details to be shown and false if hidden
- */
- checkDetails: function (aShouldBeShown) {
- let button = this.getDetailsButton();
- let list = this.getItemList();
- let hidden = list.hidden || list.collapsed;
- is(hidden, !aShouldBeShown,
- "Details should be " + (aShouldBeShown ? "shown" : "hidden") +
- " but were actually " + (hidden ? "hidden" : "shown"));
- let dir = hidden ? "down" : "up";
- is(button.className, "expander-" + dir,
- "Details button should be " + dir + " because item list is " +
- (hidden ? "" : "not ") + "hidden");
- let height = 0;
- if (!hidden) {
- ok(list.boxObject.height > 30, "listbox has sufficient size")
- height += list.boxObject.height;
- }
- if (this.isWarningPanelVisible())
- height += this.getWarningPanel().boxObject.height;
- ok(height < this.win.innerHeight,
- "Window should be tall enough to fit warning panel and item list");
- },
-
- /**
- * (Un)checks a history scope checkbox (browser & download history,
- * form history, etc.).
- *
- * @param aPrefName
- * The final portion of the checkbox's privacy.cpd.* preference name
- * @param aCheckState
- * True if the checkbox should be checked, false otherwise
- */
- checkPrefCheckbox: function (aPrefName, aCheckState) {
- var pref = "privacy.cpd." + aPrefName;
- var cb = this.win.document.querySelectorAll(
- "#itemList > [preference='" + pref + "']");
- is(cb.length, 1, "found checkbox for " + pref + " preference");
- if (cb[0].checked != aCheckState)
- cb[0].click();
- },
-
- /**
- * Makes sure all the checkboxes are checked.
- */
- _checkAllCheckboxesCustom: function (check) {
- var cb = this.win.document.querySelectorAll("#itemList > [preference]");
- ok(cb.length > 1, "found checkboxes for preferences");
- for (var i = 0; i < cb.length; ++i) {
- var pref = this.win.document.getElementById(cb[i].getAttribute("preference"));
- if (!!pref.value ^ check)
- cb[i].click();
- }
- },
-
- checkAllCheckboxes: function () {
- this._checkAllCheckboxesCustom(true);
- },
-
- uncheckAllCheckboxes: function () {
- this._checkAllCheckboxesCustom(false);
- },
-
- /**
- * @return The details progressive disclosure button
- */
- getDetailsButton: function () {
- return this.win.document.getElementById("detailsExpander");
- },
-
- /**
- * @return The dialog's duration dropdown
- */
- getDurationDropdown: function () {
- return this.win.document.getElementById("sanitizeDurationChoice");
- },
-
- /**
- * @return The item list hidden by the details progressive disclosure button
- */
- getItemList: function () {
- return this.win.document.getElementById("itemList");
- },
-
- /**
- * @return The clear-everything warning box
- */
- getWarningPanel: function () {
- return this.win.document.getElementById("sanitizeEverythingWarningBox");
- },
-
- /**
- * @return True if the "Everything" warning panel is visible (as opposed to
- * the tree)
- */
- isWarningPanelVisible: function () {
- return !this.getWarningPanel().hidden;
- },
-
- /**
- * Opens the clear recent history dialog. Before calling this, set
- * this.onload to a function to execute onload. It should close the dialog
- * when done so that the tests may continue. Set this.onunload to a function
- * to execute onunload. this.onunload is optional. If it returns true, the
- * caller is expected to call waitForAsyncUpdates at some point; if false is
- * returned, waitForAsyncUpdates is called automatically.
- */
- open: function () {
- let wh = this;
-
- function windowObserver(aSubject, aTopic, aData) {
- if (aTopic != "domwindowopened")
- return;
-
- Services.ww.unregisterNotification(windowObserver);
-
- var loaded = false;
- let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-
- win.addEventListener("load", function onload(event) {
- win.removeEventListener("load", onload, false);
-
- if (win.name !== "SanitizeDialog")
- return;
-
- wh.win = win;
- loaded = true;
- executeSoon(() => wh.onload());
- }, false);
-
- win.addEventListener("unload", function onunload(event) {
- if (win.name !== "SanitizeDialog") {
- win.removeEventListener("unload", onunload, false);
- return;
- }
-
- // Why is unload fired before load?
- if (!loaded)
- return;
-
- win.removeEventListener("unload", onunload, false);
- wh.win = win;
-
- // Some exceptions that reach here don't reach the test harness, but
- // ok()/is() do...
- Task.spawn(function* () {
- if (wh.onunload) {
- yield wh.onunload();
- }
- yield PlacesTestUtils.promiseAsyncUpdates();
- wh._resolveClosed();
- });
- }, false);
- }
- Services.ww.registerNotification(windowObserver);
- Services.ww.openWindow(null,
- "chrome://browser/content/sanitize.xul",
- "SanitizeDialog",
- "chrome,titlebar,dialog,centerscreen,modal",
- null);
- },
-
- /**
- * Selects a duration in the duration dropdown.
- *
- * @param aDurVal
- * One of the Sanitizer.TIMESPAN_* values
- */
- selectDuration: function (aDurVal) {
- this.getDurationDropdown().value = aDurVal;
- if (aDurVal === Sanitizer.TIMESPAN_EVERYTHING) {
- is(this.isWarningPanelVisible(), true,
- "Warning panel should be visible for TIMESPAN_EVERYTHING");
- }
- else {
- is(this.isWarningPanelVisible(), false,
- "Warning panel should not be visible for non-TIMESPAN_EVERYTHING");
- }
- },
-
- /**
- * Toggles the details progressive disclosure button.
- */
- toggleDetails: function () {
- this.getDetailsButton().click();
- }
-};
-
-function promiseSanitizationComplete() {
- return promiseTopicObserved("sanitizer-sanitization-complete");
-}
-
-/**
- * Adds a download to history.
- *
- * @param aMinutesAgo
- * The download will be downloaded this many minutes ago
- */
-function* addDownloadWithMinutesAgo(aExpectedPathList, aMinutesAgo) {
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
-
- let name = "fakefile-" + aMinutesAgo + "-minutes-ago";
- let download = yield Downloads.createDownload({
- source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
- target: name
- });
- download.startTime = new Date(now_mSec - (aMinutesAgo * kMsecPerMin));
- download.canceled = true;
- publicList.add(download);
-
- ok((yield downloadExists(name)),
- "Sanity check: download " + name +
- " should exist after creating it");
-
- aExpectedPathList.push(name);
-}
-
-/**
- * Adds a form entry to history.
- *
- * @param aMinutesAgo
- * The entry will be added this many minutes ago
- */
-function promiseAddFormEntryWithMinutesAgo(aMinutesAgo) {
- let name = aMinutesAgo + "-minutes-ago";
-
- // Artifically age the entry to the proper vintage.
- let timestamp = now_uSec - (aMinutesAgo * kUsecPerMin);
-
- return new Promise((resolve, reject) =>
- FormHistory.update({ op: "add", fieldname: name, value: "dummy", firstUsed: timestamp },
- { handleError: function (error) {
- reject();
- throw new Error("Error occurred updating form history: " + error);
- },
- handleCompletion: function (reason) {
- resolve(name);
- }
- })
- )
-}
-
-/**
- * Checks if a form entry exists.
- */
-function formNameExists(name)
-{
- return new Promise((resolve, reject) => {
- let count = 0;
- FormHistory.count({ fieldname: name },
- { handleResult: result => count = result,
- handleError: function (error) {
- reject(error);
- throw new Error("Error occurred searching form history: " + error);
- },
- handleCompletion: function (reason) {
- if (!reason) {
- resolve(count);
- }
- }
- });
- });
-}
-
-/**
- * Removes all history visits, downloads, and form entries.
- */
-function* blankSlate() {
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
- let downloads = yield publicList.getAll();
- for (let download of downloads) {
- yield publicList.remove(download);
- yield download.finalize(true);
- }
-
- yield new Promise((resolve, reject) => {
- FormHistory.update({op: "remove"}, {
- handleCompletion(reason) {
- if (!reason) {
- resolve();
- }
- },
- handleError(error) {
- reject(error);
- throw new Error("Error occurred updating form history: " + error);
- }
- });
- });
-
- yield PlacesTestUtils.clearHistory();
-}
-
-/**
- * Ensures that the given pref is the expected value.
- *
- * @param aPrefName
- * The pref's sub-branch under the privacy branch
- * @param aExpectedVal
- * The pref's expected value
- * @param aMsg
- * Passed to is()
- */
-function boolPrefIs(aPrefName, aExpectedVal, aMsg) {
- is(gPrefService.getBoolPref("privacy." + aPrefName), aExpectedVal, aMsg);
-}
-
-/**
- * Checks to see if the download with the specified path exists.
- *
- * @param aPath
- * The path of the download to check
- * @return True if the download exists, false otherwise
- */
-function* downloadExists(aPath) {
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
- let listArray = yield publicList.getAll();
- return listArray.some(i => i.target.path == aPath);
-}
-
-/**
- * Ensures that the specified downloads are either cleared or not.
- *
- * @param aDownloadIDs
- * Array of download database IDs
- * @param aShouldBeCleared
- * True if each download should be cleared, false otherwise
- */
-function* ensureDownloadsClearedState(aDownloadIDs, aShouldBeCleared) {
- let niceStr = aShouldBeCleared ? "no longer" : "still";
- for (let id of aDownloadIDs) {
- is((yield downloadExists(id)), !aShouldBeCleared,
- "download " + id + " should " + niceStr + " exist");
- }
-}
-
-/**
- * Ensures that the given pref is the expected value.
- *
- * @param aPrefName
- * The pref's sub-branch under the privacy branch
- * @param aExpectedVal
- * The pref's expected value
- * @param aMsg
- * Passed to is()
- */
-function intPrefIs(aPrefName, aExpectedVal, aMsg) {
- is(gPrefService.getIntPref("privacy." + aPrefName), aExpectedVal, aMsg);
-}
-
-/**
- * Creates a visit time.
- *
- * @param aMinutesAgo
- * The visit will be visited this many minutes ago
- */
-function visitTimeForMinutesAgo(aMinutesAgo) {
- return now_uSec - aMinutesAgo * kUsecPerMin;
-}
diff --git a/browser/base/content/test/general/browser_save_link-perwindowpb.js b/browser/base/content/test/general/browser_save_link-perwindowpb.js
deleted file mode 100644
index 5c99ba32a..000000000
--- a/browser/base/content/test/general/browser_save_link-perwindowpb.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var MockFilePicker = SpecialPowers.MockFilePicker;
-MockFilePicker.init(window);
-
-// Trigger a save of a link in public mode, then trigger an identical save
-// in private mode and ensure that the second request is differentiated from
-// the first by checking that cookies set by the first response are not sent
-// during the second request.
-function triggerSave(aWindow, aCallback) {
- info("started triggerSave");
- var fileName;
- let testBrowser = aWindow.gBrowser.selectedBrowser;
- // This page sets a cookie if and only if a cookie does not exist yet
- let testURI = "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517-2.html";
- testBrowser.loadURI(testURI);
- BrowserTestUtils.browserLoaded(testBrowser, false, testURI)
- .then(() => {
- waitForFocus(function () {
- info("register to handle popupshown");
- aWindow.document.addEventListener("popupshown", contextMenuOpened, false);
-
- BrowserTestUtils.synthesizeMouseAtCenter("#fff", {type: "contextmenu", button: 2}, testBrowser);
- info("right clicked!");
- }, aWindow);
- });
-
- function contextMenuOpened(event) {
- info("contextMenuOpened");
- aWindow.document.removeEventListener("popupshown", contextMenuOpened);
-
- // Create the folder the link will be saved into.
- var destDir = createTemporarySaveDirectory();
- var destFile = destDir.clone();
-
- MockFilePicker.displayDirectory = destDir;
- MockFilePicker.showCallback = function(fp) {
- info("showCallback");
- fileName = fp.defaultString;
- info("fileName: " + fileName);
- destFile.append (fileName);
- MockFilePicker.returnFiles = [destFile];
- MockFilePicker.filterIndex = 1; // kSaveAsType_URL
- info("done showCallback");
- };
-
- mockTransferCallback = function(downloadSuccess) {
- info("mockTransferCallback");
- onTransferComplete(aWindow, downloadSuccess, destDir);
- destDir.remove(true);
- ok(!destDir.exists(), "Destination dir should be removed");
- ok(!destFile.exists(), "Destination file should be removed");
- mockTransferCallback = null;
- info("done mockTransferCallback");
- }
-
- // Select "Save Link As" option from context menu
- var saveLinkCommand = aWindow.document.getElementById("context-savelink");
- info("saveLinkCommand: " + saveLinkCommand);
- saveLinkCommand.doCommand();
-
- event.target.hidePopup();
- info("popup hidden");
- }
-
- function onTransferComplete(aWindow2, downloadSuccess, destDir) {
- ok(downloadSuccess, "Link should have been downloaded successfully");
- aWindow2.close();
-
- executeSoon(() => aCallback());
- }
-}
-
-function test() {
- info("Start the test");
- waitForExplicitFinish();
-
- var gNumSet = 0;
- function testOnWindow(options, callback) {
- info("testOnWindow(" + options + ")");
- var win = OpenBrowserWindow(options);
- info("got " + win);
- whenDelayedStartupFinished(win, () => callback(win));
- }
-
- function whenDelayedStartupFinished(aWindow, aCallback) {
- info("whenDelayedStartupFinished");
- Services.obs.addObserver(function obs(aSubject, aTopic) {
- info("whenDelayedStartupFinished, got topic: " + aTopic + ", got subject: " + aSubject + ", waiting for " + aWindow);
- if (aWindow == aSubject) {
- Services.obs.removeObserver(obs, aTopic);
- executeSoon(aCallback);
- info("whenDelayedStartupFinished found our window");
- }
- }, "browser-delayed-startup-finished", false);
- }
-
- mockTransferRegisterer.register();
-
- registerCleanupFunction(function () {
- info("Running the cleanup code");
- mockTransferRegisterer.unregister();
- MockFilePicker.cleanup();
- Services.obs.removeObserver(observer, "http-on-modify-request");
- Services.obs.removeObserver(observer, "http-on-examine-response");
- info("Finished running the cleanup code");
- });
-
- function observer(subject, topic, state) {
- info("observer called with " + topic);
- if (topic == "http-on-modify-request") {
- onModifyRequest(subject);
- } else if (topic == "http-on-examine-response") {
- onExamineResponse(subject);
- }
- }
-
- function onExamineResponse(subject) {
- let channel = subject.QueryInterface(Ci.nsIHttpChannel);
- info("onExamineResponse with " + channel.URI.spec);
- if (channel.URI.spec != "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.sjs") {
- info("returning");
- return;
- }
- try {
- let cookies = channel.getResponseHeader("set-cookie");
- // From browser/base/content/test/general/bug792715.sjs, we receive a Set-Cookie
- // header with foopy=1 when there are no cookies for that domain.
- is(cookies, "foopy=1", "Cookie should be foopy=1");
- gNumSet += 1;
- info("gNumSet = " + gNumSet);
- } catch (ex) {
- if (ex.result == Cr.NS_ERROR_NOT_AVAILABLE) {
- info("onExamineResponse caught NOTAVAIL" + ex);
- } else {
- info("ionExamineResponse caught " + ex);
- }
- }
- }
-
- function onModifyRequest(subject) {
- let channel = subject.QueryInterface(Ci.nsIHttpChannel);
- info("onModifyRequest with " + channel.URI.spec);
- if (channel.URI.spec != "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.sjs") {
- return;
- }
- try {
- let cookies = channel.getRequestHeader("cookie");
- info("cookies: " + cookies);
- // From browser/base/content/test/general/bug792715.sjs, we should never send a
- // cookie because we are making only 2 requests: one in public mode, and
- // one in private mode.
- throw "We should never send a cookie in this test";
- } catch (ex) {
- if (ex.result == Cr.NS_ERROR_NOT_AVAILABLE) {
- info("onModifyRequest caught NOTAVAIL" + ex);
- } else {
- info("ionModifyRequest caught " + ex);
- }
- }
- }
-
- Services.obs.addObserver(observer, "http-on-modify-request", false);
- Services.obs.addObserver(observer, "http-on-examine-response", false);
-
- testOnWindow(undefined, function(win) {
- // The first save from a regular window sets a cookie.
- triggerSave(win, function() {
- is(gNumSet, 1, "1 cookie should be set");
-
- // The second save from a private window also sets a cookie.
- testOnWindow({private: true}, function(win2) {
- triggerSave(win2, function() {
- is(gNumSet, 2, "2 cookies should be set");
- finish();
- });
- });
- });
- });
-}
-
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
- this);
-
-function createTemporarySaveDirectory() {
- var saveDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("TmpD", Ci.nsIFile);
- saveDir.append("testsavedir");
- if (!saveDir.exists()) {
- info("create testsavedir!");
- saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
- }
- info("return from createTempSaveDir: " + saveDir.path);
- return saveDir;
-}
diff --git 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
deleted file mode 100644
index 2fd10b00e..000000000
--- a/browser/base/content/test/general/browser_save_link_when_window_navigates.js
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var MockFilePicker = SpecialPowers.MockFilePicker;
-MockFilePicker.init(window);
-
-const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite";
-const ALWAYS_DOWNLOAD_DIR_PREF = "browser.download.useDownloadDir";
-const UCT_URI = "chrome://mozapps/content/downloads/unknownContentType.xul";
-
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
- this);
-
-function createTemporarySaveDirectory() {
- var saveDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("TmpD", Ci.nsIFile);
- saveDir.append("testsavedir");
- if (!saveDir.exists()) {
- info("create testsavedir!");
- saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
- }
- info("return from createTempSaveDir: " + saveDir.path);
- return saveDir;
-}
-
-function triggerSave(aWindow, aCallback) {
- info("started triggerSave, persite downloads: " + (Services.prefs.getBoolPref(SAVE_PER_SITE_PREF) ? "on" : "off"));
- var fileName;
- let testBrowser = aWindow.gBrowser.selectedBrowser;
- let testURI = "http://mochi.test:8888/browser/browser/base/content/test/general/navigating_window_with_download.html";
- windowObserver.setCallback(onUCTDialog);
- testBrowser.loadURI(testURI);
-
- // Create the folder the link will be saved into.
- var destDir = createTemporarySaveDirectory();
- var destFile = destDir.clone();
-
- MockFilePicker.displayDirectory = destDir;
- MockFilePicker.showCallback = function(fp) {
- info("showCallback");
- fileName = fp.defaultString;
- info("fileName: " + fileName);
- destFile.append (fileName);
- MockFilePicker.returnFiles = [destFile];
- MockFilePicker.filterIndex = 1; // kSaveAsType_URL
- info("done showCallback");
- };
-
- mockTransferCallback = function(downloadSuccess) {
- info("mockTransferCallback");
- onTransferComplete(aWindow, downloadSuccess, destDir);
- destDir.remove(true);
- ok(!destDir.exists(), "Destination dir should be removed");
- ok(!destFile.exists(), "Destination file should be removed");
- mockTransferCallback = null;
- info("done mockTransferCallback");
- }
-
- function onUCTDialog(dialog) {
- function doLoad() {
- content.document.querySelector('iframe').remove();
- }
- testBrowser.messageManager.loadFrameScript("data:,(" + doLoad.toString() + ")()", false);
- executeSoon(continueDownloading);
- }
-
- function continueDownloading() {
- let windows = Services.wm.getEnumerator("");
- while (windows.hasMoreElements()) {
- let win = windows.getNext();
- if (win.location && win.location.href == UCT_URI) {
- win.document.documentElement._fireButtonEvent("accept");
- win.close();
- return;
- }
- }
- ok(false, "No Unknown Content Type dialog yet?");
- }
-
- function onTransferComplete(aWindow2, downloadSuccess) {
- ok(downloadSuccess, "Link should have been downloaded successfully");
- aWindow2.close();
-
- executeSoon(aCallback);
- }
-}
-
-
-var windowObserver = {
- setCallback: function(aCallback) {
- if (this._callback) {
- ok(false, "Should only be dealing with one callback at a time.");
- }
- this._callback = aCallback;
- },
- observe: function(aSubject, aTopic, aData) {
- if (aTopic != "domwindowopened") {
- return;
- }
-
- let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
-
- win.addEventListener("load", function onLoad(event) {
- win.removeEventListener("load", onLoad, false);
-
- if (win.location == UCT_URI) {
- SimpleTest.executeSoon(function() {
- if (windowObserver._callback) {
- windowObserver._callback(win);
- delete windowObserver._callback;
- } else {
- ok(false, "Unexpected UCT dialog!");
- }
- });
- }
- }, false);
- }
-};
-
-Services.ww.registerNotification(windowObserver);
-
-function test() {
- waitForExplicitFinish();
-
- function testOnWindow(options, callback) {
- info("testOnWindow(" + options + ")");
- var win = OpenBrowserWindow(options);
- info("got " + win);
- whenDelayedStartupFinished(win, () => callback(win));
- }
-
- function whenDelayedStartupFinished(aWindow, aCallback) {
- info("whenDelayedStartupFinished");
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- info("whenDelayedStartupFinished, got topic: " + aTopic + ", got subject: " + aSubject + ", waiting for " + aWindow);
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- executeSoon(aCallback);
- info("whenDelayedStartupFinished found our window");
- }
- }, "browser-delayed-startup-finished", false);
- }
-
- mockTransferRegisterer.register();
-
- registerCleanupFunction(function () {
- info("Running the cleanup code");
- mockTransferRegisterer.unregister();
- MockFilePicker.cleanup();
- Services.ww.unregisterNotification(windowObserver);
- Services.prefs.clearUserPref(ALWAYS_DOWNLOAD_DIR_PREF);
- Services.prefs.clearUserPref(SAVE_PER_SITE_PREF);
- info("Finished running the cleanup code");
- });
-
- Services.prefs.setBoolPref(ALWAYS_DOWNLOAD_DIR_PREF, false);
- testOnWindow(undefined, function(win) {
- let windowGonePromise = promiseWindowWillBeClosed(win);
- Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, true);
- triggerSave(win, function() {
- windowGonePromise.then(function() {
- Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, false);
- testOnWindow(undefined, function(win2) {
- triggerSave(win2, finish);
- });
- });
- });
- });
-}
-
diff --git a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
deleted file mode 100644
index e7ed5fa34..000000000
--- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function createTemporarySaveDirectory() {
- var saveDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("TmpD", Ci.nsIFile);
- saveDir.append("testsavedir");
- if (!saveDir.exists())
- saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
- return saveDir;
-}
-
-function promiseNoCacheEntry(filename) {
- return new Promise((resolve, reject) => {
- Visitor.prototype = {
- onCacheStorageInfo: function(num, consumption)
- {
- info("disk storage contains " + num + " entries");
- },
- onCacheEntryInfo: function(uri)
- {
- let urispec = uri.asciiSpec;
- info(urispec);
- is(urispec.includes(filename), false, "web content present in disk cache");
- },
- onCacheEntryVisitCompleted: function()
- {
- resolve();
- }
- };
- function Visitor() {}
-
- let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", null);
- let storage = cache.diskCacheStorage(LoadContextInfo.default, false);
- storage.asyncVisitStorage(new Visitor(), true /* Do walk entries */);
- });
-}
-
-function promiseImageDownloaded() {
- return new Promise((resolve, reject) => {
- let fileName;
- let MockFilePicker = SpecialPowers.MockFilePicker;
- MockFilePicker.init(window);
-
- function onTransferComplete(downloadSuccess) {
- ok(downloadSuccess, "Image file should have been downloaded successfully " + fileName);
-
- // Give the request a chance to finish and create a cache entry
- resolve(fileName);
- }
-
- // Create the folder the image will be saved into.
- var destDir = createTemporarySaveDirectory();
- var destFile = destDir.clone();
-
- MockFilePicker.displayDirectory = destDir;
- MockFilePicker.showCallback = function(fp) {
- fileName = fp.defaultString;
- destFile.append (fileName);
- MockFilePicker.returnFiles = [destFile];
- MockFilePicker.filterIndex = 1; // kSaveAsType_URL
- };
-
- mockTransferCallback = onTransferComplete;
- mockTransferRegisterer.register();
-
- registerCleanupFunction(function () {
- mockTransferCallback = null;
- mockTransferRegisterer.unregister();
- MockFilePicker.cleanup();
- destDir.remove(true);
- });
-
- });
-}
-
-add_task(function* () {
- let testURI = "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.html";
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let tab = yield BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, testURI);
-
- let contextMenu = privateWindow.document.getElementById("contentAreaContextMenu");
- let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- let popupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- yield BrowserTestUtils.synthesizeMouseAtCenter("#img", {
- type: "contextmenu",
- button: 2
- }, tab.linkedBrowser);
- yield popupShown;
-
- let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- cache.clear();
-
- let imageDownloaded = promiseImageDownloaded();
- // Select "Save Image As" option from context menu
- privateWindow.document.getElementById("context-saveimage").doCommand();
-
- contextMenu.hidePopup();
- yield popupHidden;
-
- // wait for image download
- let fileName = yield imageDownloaded;
- yield promiseNoCacheEntry(fileName);
-
- yield BrowserTestUtils.closeWindow(privateWindow);
-});
-
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
- this);
diff --git a/browser/base/content/test/general/browser_save_video.js b/browser/base/content/test/general/browser_save_video.js
deleted file mode 100644
index e81286b7a..000000000
--- a/browser/base/content/test/general/browser_save_video.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var MockFilePicker = SpecialPowers.MockFilePicker;
-MockFilePicker.init(window);
-
-/**
- * TestCase for bug 564387
- * <https://bugzilla.mozilla.org/show_bug.cgi?id=564387>
- */
-add_task(function* () {
- var fileName;
-
- let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- gBrowser.loadURI("http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html");
- yield loadPromise;
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#video1",
- { type: "contextmenu", button: 2 },
- gBrowser.selectedBrowser);
- info("context menu click on video1");
-
- yield popupShownPromise;
-
- info("context menu opened on video1");
-
- // Create the folder the video will be saved into.
- var destDir = createTemporarySaveDirectory();
- var destFile = destDir.clone();
-
- MockFilePicker.displayDirectory = destDir;
- MockFilePicker.showCallback = function(fp) {
- fileName = fp.defaultString;
- destFile.append(fileName);
- MockFilePicker.returnFiles = [destFile];
- MockFilePicker.filterIndex = 1; // kSaveAsType_URL
- };
-
- let transferCompletePromise = new Promise((resolve) => {
- function onTransferComplete(downloadSuccess) {
- ok(downloadSuccess, "Video file should have been downloaded successfully");
-
- is(fileName, "web-video1-expectedName.ogv",
- "Video file name is correctly retrieved from Content-Disposition http header");
- resolve();
- }
-
- mockTransferCallback = onTransferComplete;
- mockTransferRegisterer.register();
- });
-
- registerCleanupFunction(function () {
- mockTransferRegisterer.unregister();
- MockFilePicker.cleanup();
- destDir.remove(true);
- });
-
- // Select "Save Video As" option from context menu
- var saveVideoCommand = document.getElementById("context-savevideo");
- saveVideoCommand.doCommand();
- info("context-savevideo command executed");
-
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- contextMenu.hidePopup();
- yield popupHiddenPromise;
-
- yield transferCompletePromise;
-});
-
-
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
- this);
-
-function createTemporarySaveDirectory() {
- var saveDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("TmpD", Ci.nsIFile);
- saveDir.append("testsavedir");
- if (!saveDir.exists())
- saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
- return saveDir;
-}
diff --git a/browser/base/content/test/general/browser_save_video_frame.js b/browser/base/content/test/general/browser_save_video_frame.js
deleted file mode 100644
index e9b8a0475..000000000
--- a/browser/base/content/test/general/browser_save_video_frame.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const VIDEO_URL = "http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html";
-
-/**
- * mockTransfer.js provides a utility that lets us mock out
- * the "Save File" dialog.
- */
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
- this);
-
-/**
- * Creates and returns an nsIFile for a new temporary save
- * directory.
- *
- * @return nsIFile
- */
-function createTemporarySaveDirectory() {
- let saveDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("TmpD", Ci.nsIFile);
- saveDir.append("testsavedir");
- if (!saveDir.exists())
- saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
- return saveDir;
-}
-/**
- * MockTransfer exposes a "mockTransferCallback" global which
- * allows us to define a callback to be called once the mock file
- * selector has selected where to save the file.
- */
-function waitForTransferComplete() {
- return new Promise((resolve) => {
- mockTransferCallback = () => {
- ok(true, "Transfer completed");
- resolve();
- }
- });
-}
-
-/**
- * Given some browser, loads a framescript that right-clicks
- * on the video1 element to spawn a contextmenu.
- */
-function rightClickVideo(browser) {
- let frame_script = () => {
- const Ci = Components.interfaces;
- let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-
- let document = content.document;
- let video = document.getElementById("video1");
- let rect = video.getBoundingClientRect();
-
- /* Synthesize a click in the center of the video. */
- let left = rect.left + (rect.width / 2);
- let top = rect.top + (rect.height / 2);
-
- utils.sendMouseEvent("contextmenu", left, top,
- 2, /* aButton */
- 1, /* aClickCount */
- 0 /* aModifiers */);
- };
- let mm = browser.messageManager;
- mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
-}
-
-/**
- * Loads a page with a <video> element, right-clicks it and chooses
- * to save a frame screenshot to the disk. Completes once we've
- * verified that the frame has been saved to disk.
- */
-add_task(function*() {
- let MockFilePicker = SpecialPowers.MockFilePicker;
- MockFilePicker.init(window);
-
- // Create the folder the video will be saved into.
- let destDir = createTemporarySaveDirectory();
- let destFile = destDir.clone();
-
- MockFilePicker.displayDirectory = destDir;
- MockFilePicker.showCallback = function(fp) {
- destFile.append(fp.defaultString);
- MockFilePicker.returnFiles = [destFile];
- MockFilePicker.filterIndex = 1; // kSaveAsType_URL
- };
-
- mockTransferRegisterer.register();
-
- // Make sure that we clean these things up when we're done.
- registerCleanupFunction(function () {
- mockTransferRegisterer.unregister();
- MockFilePicker.cleanup();
- destDir.remove(true);
- });
-
- let tab = gBrowser.addTab();
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
- info("Loading video tab");
- yield promiseTabLoadEvent(tab, VIDEO_URL);
- info("Video tab loaded.");
-
- let context = document.getElementById("contentAreaContextMenu");
- let popupPromise = promisePopupShown(context);
-
- info("Synthesizing right-click on video element");
- rightClickVideo(browser);
- info("Waiting for popup to fire popupshown.");
- yield popupPromise;
- info("Popup fired popupshown");
-
- let saveSnapshotCommand = document.getElementById("context-video-saveimage");
- let promiseTransfer = waitForTransferComplete()
- info("Firing save snapshot command");
- saveSnapshotCommand.doCommand();
- context.hidePopup();
- info("Waiting for transfer completion");
- yield promiseTransfer;
- info("Transfer complete");
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_scope.js b/browser/base/content/test/general/browser_scope.js
deleted file mode 100644
index f8141e5f6..000000000
--- a/browser/base/content/test/general/browser_scope.js
+++ /dev/null
@@ -1,10 +0,0 @@
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.docShell is null");
-
-function test() {
- ok(!!gBrowser, "gBrowser exists");
- is(gBrowser, getBrowser(), "both ways of getting tabbrowser work");
-}
diff --git a/browser/base/content/test/general/browser_selectTabAtIndex.js b/browser/base/content/test/general/browser_selectTabAtIndex.js
deleted file mode 100644
index b6578aec0..000000000
--- a/browser/base/content/test/general/browser_selectTabAtIndex.js
+++ /dev/null
@@ -1,81 +0,0 @@
-"use strict";
-
-function test() {
- const isLinux = navigator.platform.indexOf("Linux") == 0;
-
- function assertTab(expectedTab) {
- is(gBrowser.tabContainer.selectedIndex, expectedTab,
- `tab index ${expectedTab} should be selected`);
- }
-
- function sendAccelKey(key) {
- // Make sure the keystroke goes to chrome.
- document.activeElement.blur();
- EventUtils.synthesizeKey(key.toString(), { altKey: isLinux, accelKey: !isLinux });
- }
-
- function createTabs(count) {
- for (let n = 0; n < count; n++)
- gBrowser.addTab();
- }
-
- function testKey(key, expectedTab) {
- sendAccelKey(key);
- assertTab(expectedTab);
- }
-
- function testIndex(index, expectedTab) {
- gBrowser.selectTabAtIndex(index);
- assertTab(expectedTab);
- }
-
- // Create fewer tabs than our 9 number keys.
- is(gBrowser.tabs.length, 1, "should have 1 tab");
- createTabs(4);
- is(gBrowser.tabs.length, 5, "should have 5 tabs");
-
- // Test keyboard shortcuts. Order tests so that no two test cases have the
- // same expected tab in a row. This ensures that tab selection actually
- // changed the selected tab.
- testKey(8, 4);
- testKey(1, 0);
- testKey(2, 1);
- testKey(4, 3);
- testKey(9, 4);
-
- // Test index selection.
- testIndex(0, 0);
- testIndex(4, 4);
- testIndex(-5, 0);
- testIndex(5, 4);
- testIndex(-4, 1);
- testIndex(1, 1);
- testIndex(-1, 4);
- testIndex(9, 4);
-
- // Create more tabs than our 9 number keys.
- createTabs(10);
- is(gBrowser.tabs.length, 15, "should have 15 tabs");
-
- // Test keyboard shortcuts.
- testKey(2, 1);
- testKey(1, 0);
- testKey(4, 3);
- testKey(8, 7);
- testKey(9, 14);
-
- // Test index selection.
- testIndex(-15, 0);
- testIndex(14, 14);
- testIndex(-14, 1);
- testIndex(15, 14);
- testIndex(-1, 14);
- testIndex(0, 0);
- testIndex(1, 1);
- testIndex(9, 9);
-
- // Clean up tabs.
- for (let n = 15; n > 1; n--)
- gBrowser.removeTab(gBrowser.selectedTab, {skipPermitUnload: true});
- is(gBrowser.tabs.length, 1, "should have 1 tab");
-}
diff --git a/browser/base/content/test/general/browser_selectpopup.js b/browser/base/content/test/general/browser_selectpopup.js
deleted file mode 100644
index d34254d1c..000000000
--- a/browser/base/content/test/general/browser_selectpopup.js
+++ /dev/null
@@ -1,563 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// This test checks that a <select> with an <optgroup> opens and can be navigated
-// in a child process. This is different than single-process as a <menulist> is used
-// to implement the dropdown list.
-
-requestLongerTimeout(2);
-
-const XHTML_DTD = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
-
-const PAGECONTENT =
- "<html xmlns='http://www.w3.org/1999/xhtml'>" +
- "<body onload='gChangeEvents = 0;gInputEvents = 0; document.body.firstChild.focus()'><select oninput='gInputEvents++' onchange='gChangeEvents++'>" +
- " <optgroup label='First Group'>" +
- " <option value='One'>One</option>" +
- " <option value='Two'>Two</option>" +
- " </optgroup>" +
- " <option value='Three'>Three</option>" +
- " <optgroup label='Second Group' disabled='true'>" +
- " <option value='Four'>Four</option>" +
- " <option value='Five'>Five</option>" +
- " </optgroup>" +
- " <option value='Six' disabled='true'>Six</option>" +
- " <optgroup label='Third Group'>" +
- " <option value='Seven'> Seven </option>" +
- " <option value='Eight'>&nbsp;&nbsp;Eight&nbsp;&nbsp;</option>" +
- " </optgroup></select><input />Text" +
- "</body></html>";
-
-const PAGECONTENT_SMALL =
- "<html>" +
- "<body><select id='one'>" +
- " <option value='One'>One</option>" +
- " <option value='Two'>Two</option>" +
- "</select><select id='two'>" +
- " <option value='Three'>Three</option>" +
- " <option value='Four'>Four</option>" +
- "</select><select id='three'>" +
- " <option value='Five'>Five</option>" +
- " <option value='Six'>Six</option>" +
- "</select></body></html>";
-
-const PAGECONTENT_SOMEHIDDEN =
- "<html><head><style>.hidden { display: none; }</style></head>" +
- "<body><select id='one'>" +
- " <option value='One' style='display: none;'>OneHidden</option>" +
- " <option value='Two' class='hidden'>TwoHidden</option>" +
- " <option value='Three'>ThreeVisible</option>" +
- " <option value='Four'style='display: table;'>FourVisible</option>" +
- " <option value='Five'>FiveVisible</option>" +
- " <optgroup label='GroupHidden' class='hidden'>" +
- " <option value='Four'>Six.OneHidden</option>" +
- " <option value='Five' style='display: block;'>Six.TwoHidden</option>" +
- " </optgroup>" +
- " <option value='Six' class='hidden' style='display: block;'>SevenVisible</option>" +
- "</select></body></html>";
-
-const PAGECONTENT_TRANSLATED =
- "<html><body>" +
- "<div id='div'>" +
- "<iframe id='frame' width='320' height='295' style='border: none;'" +
- " src='data:text/html,<select id=select autofocus><option>he he he</option><option>boo boo</option><option>baz baz</option></select>'" +
- "</iframe>" +
- "</div></body></html>";
-
-function openSelectPopup(selectPopup, withMouse, selector = "select", win = window)
-{
- let popupShownPromise = BrowserTestUtils.waitForEvent(selectPopup, "popupshown");
-
- if (withMouse) {
- return Promise.all([popupShownPromise,
- BrowserTestUtils.synthesizeMouseAtCenter(selector, { }, win.gBrowser.selectedBrowser)]);
- }
-
- EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true, code: "ArrowDown" }, win);
- return popupShownPromise;
-}
-
-function hideSelectPopup(selectPopup, mode = "enter", win = window)
-{
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
-
- if (mode == "escape") {
- EventUtils.synthesizeKey("KEY_Escape", { code: "Escape" }, win);
- }
- else if (mode == "enter") {
- EventUtils.synthesizeKey("KEY_Enter", { code: "Enter" }, win);
- }
- else if (mode == "click") {
- EventUtils.synthesizeMouseAtCenter(selectPopup.lastChild, { }, win);
- }
-
- return popupHiddenPromise;
-}
-
-function getInputEvents()
-{
- return ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
- return content.wrappedJSObject.gInputEvents;
- });
-}
-
-function getChangeEvents()
-{
- return ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
- return content.wrappedJSObject.gChangeEvents;
- });
-}
-
-function* doSelectTests(contentType, dtd)
-{
- const pageUrl = "data:" + contentType + "," + escape(dtd + "\n" + PAGECONTENT);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
-
- let menulist = document.getElementById("ContentSelectDropdown");
- let selectPopup = menulist.menupopup;
-
- yield openSelectPopup(selectPopup);
-
- let isWindows = navigator.platform.indexOf("Win") >= 0;
-
- is(menulist.selectedIndex, 1, "Initial selection");
- is(selectPopup.firstChild.localName, "menucaption", "optgroup is caption");
- is(selectPopup.firstChild.getAttribute("label"), "First Group", "optgroup label");
- is(selectPopup.childNodes[1].localName, "menuitem", "option is menuitem");
- is(selectPopup.childNodes[1].getAttribute("label"), "One", "option label");
-
- EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" });
- is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(2), "Select item 2");
- is(menulist.selectedIndex, isWindows ? 2 : 1, "Select item 2 selectedIndex");
-
- EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" });
- is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(3), "Select item 3");
- is(menulist.selectedIndex, isWindows ? 3 : 1, "Select item 3 selectedIndex");
-
- EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" });
-
- // On Windows, one can navigate on disabled menuitems
- is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(9),
- "Skip optgroup header and disabled items select item 7");
- is(menulist.selectedIndex, isWindows ? 9 : 1, "Select or skip disabled item selectedIndex");
-
- for (let i = 0; i < 10; i++) {
- is(menulist.getItemAtIndex(i).disabled, i >= 4 && i <= 7, "item " + i + " disabled")
- }
-
- EventUtils.synthesizeKey("KEY_ArrowUp", { code: "ArrowUp" });
- is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(3), "Select item 3 again");
- is(menulist.selectedIndex, isWindows ? 3 : 1, "Select item 3 selectedIndex");
-
- is((yield getInputEvents()), 0, "Before closed - number of input events");
- is((yield getChangeEvents()), 0, "Before closed - number of change events");
-
- EventUtils.synthesizeKey("a", { accelKey: true });
- yield ContentTask.spawn(gBrowser.selectedBrowser, { isWindows }, function(args) {
- Assert.equal(String(content.getSelection()), args.isWindows ? "Text" : "",
- "Select all while popup is open");
- });
-
- // Backspace should not go back
- let handleKeyPress = function(event) {
- ok(false, "Should not get keypress event");
- }
- window.addEventListener("keypress", handleKeyPress);
- EventUtils.synthesizeKey("VK_BACK_SPACE", { });
- window.removeEventListener("keypress", handleKeyPress);
-
- yield hideSelectPopup(selectPopup);
-
- is(menulist.selectedIndex, 3, "Item 3 still selected");
- is((yield getInputEvents()), 1, "After closed - number of input events");
- is((yield getChangeEvents()), 1, "After closed - number of change events");
-
- // Opening and closing the popup without changing the value should not fire a change event.
- yield openSelectPopup(selectPopup, true);
- yield hideSelectPopup(selectPopup, "escape");
- is((yield getInputEvents()), 1, "Open and close with no change - number of input events");
- is((yield getChangeEvents()), 1, "Open and close with no change - number of change events");
- EventUtils.synthesizeKey("VK_TAB", { });
- EventUtils.synthesizeKey("VK_TAB", { shiftKey: true });
- is((yield getInputEvents()), 1, "Tab away from select with no change - number of input events");
- is((yield getChangeEvents()), 1, "Tab away from select with no change - number of change events");
-
- yield openSelectPopup(selectPopup, true);
- EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" });
- yield hideSelectPopup(selectPopup, "escape");
- is((yield getInputEvents()), isWindows ? 2 : 1, "Open and close with change - number of input events");
- is((yield getChangeEvents()), isWindows ? 2 : 1, "Open and close with change - number of change events");
- EventUtils.synthesizeKey("VK_TAB", { });
- EventUtils.synthesizeKey("VK_TAB", { shiftKey: true });
- is((yield getInputEvents()), isWindows ? 2 : 1, "Tab away from select with change - number of input events");
- is((yield getChangeEvents()), isWindows ? 2 : 1, "Tab away from select with change - number of change events");
-
- is(selectPopup.lastChild.previousSibling.label, "Seven", "Spaces collapsed");
- is(selectPopup.lastChild.label, "\xA0\xA0Eight\xA0\xA0", "Non-breaking spaces not collapsed");
-
- yield BrowserTestUtils.removeTab(tab);
-}
-
-add_task(function*() {
- yield doSelectTests("text/html", "");
-});
-
-add_task(function*() {
- yield doSelectTests("application/xhtml+xml", XHTML_DTD);
-});
-
-// This test opens a select popup and removes the content node of a popup while
-// The popup should close if its node is removed.
-add_task(function*() {
- const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
-
- let menulist = document.getElementById("ContentSelectDropdown");
- let selectPopup = menulist.menupopup;
-
- // First, try it when a different <select> element than the one that is open is removed
- yield openSelectPopup(selectPopup, true, "#one");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
- content.document.body.removeChild(content.document.getElementById("two"));
- });
-
- // Wait a bit just to make sure the popup won't close.
- yield new Promise(resolve => setTimeout(resolve, 1000));
-
- is(selectPopup.state, "open", "Different popup did not affect open popup");
-
- yield hideSelectPopup(selectPopup);
-
- // Next, try it when the same <select> element than the one that is open is removed
- yield openSelectPopup(selectPopup, true, "#three");
-
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
- content.document.body.removeChild(content.document.getElementById("three"));
- });
- yield popupHiddenPromise;
-
- ok(true, "Popup hidden when select is removed");
-
- // Finally, try it when the tab is closed while the select popup is open.
- yield openSelectPopup(selectPopup, true, "#one");
-
- popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
- yield BrowserTestUtils.removeTab(tab);
- yield popupHiddenPromise;
-
- ok(true, "Popup hidden when tab is closed");
-});
-
-// This test opens a select popup that is isn't a frame and has some translations applied.
-add_task(function*() {
- const pageUrl = "data:text/html," + escape(PAGECONTENT_TRANSLATED);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
-
- let menulist = document.getElementById("ContentSelectDropdown");
- let selectPopup = menulist.menupopup;
-
- // First, get the position of the select popup when no translations have been applied.
- yield openSelectPopup(selectPopup, false);
-
- let rect = selectPopup.getBoundingClientRect();
- let expectedX = rect.left;
- let expectedY = rect.top;
-
- yield hideSelectPopup(selectPopup);
-
- // Iterate through a set of steps which each add more translation to the select's expected position.
- let steps = [
- [ "div", "transform: translateX(7px) translateY(13px);", 7, 13 ],
- [ "frame", "border-top: 5px solid green; border-left: 10px solid red; border-right: 35px solid blue;", 10, 5 ],
- [ "frame", "border: none; padding-left: 6px; padding-right: 12px; padding-top: 2px;", -4, -3 ],
- [ "select", "margin: 9px; transform: translateY(-3px);", 9, 6 ],
- ];
-
- for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
- let step = steps[stepIndex];
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, step, function*(contentStep) {
- return new Promise(resolve => {
- let changedWin = content;
-
- 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);
- resolve();
- });
-
- elem.style = contentStep[1];
- elem.getBoundingClientRect();
- });
- });
-
- yield openSelectPopup(selectPopup, false);
-
- expectedX += step[2];
- expectedY += step[3];
-
- let popupRect = selectPopup.getBoundingClientRect();
- is(popupRect.left, expectedX, "step " + (stepIndex + 1) + " x");
- is(popupRect.top, expectedY, "step " + (stepIndex + 1) + " y");
-
- yield hideSelectPopup(selectPopup);
- }
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-// Test that we get the right events when a select popup is changed.
-add_task(function* test_event_order() {
- const URL = "data:text/html," + escape(PAGECONTENT_SMALL);
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: URL,
- }, function*(browser) {
- let menulist = document.getElementById("ContentSelectDropdown");
- let selectPopup = menulist.menupopup;
-
- // According to https://html.spec.whatwg.org/#the-select-element,
- // we want to fire input, change, and then click events on the
- // <select> (in that order) when it has changed.
- let expectedEnter = [
- {
- type: "input",
- cancelable: false,
- targetIsOption: false,
- },
- {
- type: "change",
- cancelable: false,
- targetIsOption: false,
- },
- ];
-
- let expectedClick = [
- {
- type: "mousedown",
- cancelable: true,
- targetIsOption: true,
- },
- {
- type: "mouseup",
- cancelable: true,
- targetIsOption: true,
- },
- {
- type: "input",
- cancelable: false,
- targetIsOption: false,
- },
- {
- type: "change",
- cancelable: false,
- targetIsOption: false,
- },
- {
- type: "click",
- cancelable: true,
- targetIsOption: true,
- },
- ];
-
- for (let mode of ["enter", "click"]) {
- let expected = mode == "enter" ? expectedEnter : expectedClick;
- yield openSelectPopup(selectPopup, true, mode == "enter" ? "#one" : "#two");
-
- let eventsPromise = ContentTask.spawn(browser, [mode, expected], function*([contentMode, contentExpected]) {
- return new Promise((resolve) => {
- function onEvent(event) {
- select.removeEventListener(event.type, onEvent);
- Assert.ok(contentExpected.length, "Unexpected event " + event.type);
- let expectation = contentExpected.shift();
- Assert.equal(event.type, expectation.type,
- "Expected the right event order");
- Assert.ok(event.bubbles, "All of these events should bubble");
- Assert.equal(event.cancelable, expectation.cancelable,
- "Cancellation property should match");
- Assert.equal(event.target.localName,
- expectation.targetIsOption ? "option" : "select",
- "Target matches");
- if (!contentExpected.length) {
- resolve();
- }
- }
-
- let select = content.document.getElementById(contentMode == "enter" ? "one" : "two");
- for (let event of ["input", "change", "mousedown", "mouseup", "click"]) {
- select.addEventListener(event, onEvent);
- }
- });
- });
-
- EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" });
- yield hideSelectPopup(selectPopup, mode);
- yield eventsPromise;
- }
- });
-});
-
-function* performLargePopupTests(win)
-{
- let browser = win.gBrowser.selectedBrowser;
-
- yield ContentTask.spawn(browser, null, function*() {
- let doc = content.document;
- let select = doc.getElementById("one");
- for (var i = 0; i < 180; i++) {
- select.add(new content.Option("Test" + i));
- }
-
- select.options[60].selected = true;
- select.focus();
- });
-
- let selectPopup = win.document.getElementById("ContentSelectDropdown").menupopup;
- let browserRect = browser.getBoundingClientRect();
-
- let positions = [
- "margin-top: 300px;",
- "position: fixed; bottom: 100px;",
- "width: 100%; height: 9999px;"
- ];
-
- let position;
- while (true) {
- yield openSelectPopup(selectPopup, false, "select", win);
-
- let rect = selectPopup.getBoundingClientRect();
- ok(rect.top >= browserRect.top, "Popup top position in within browser area");
- ok(rect.bottom <= browserRect.bottom, "Popup bottom position in within browser area");
-
- // Don't check the scroll position for the last step as the popup will be cut off.
- if (positions.length > 0) {
- let cs = win.getComputedStyle(selectPopup);
- let bpBottom = parseFloat(cs.paddingBottom) + parseFloat(cs.borderBottomWidth);
-
- is(selectPopup.childNodes[60].getBoundingClientRect().bottom,
- selectPopup.getBoundingClientRect().bottom - bpBottom,
- "Popup scroll at correct position " + bpBottom);
- }
-
- yield hideSelectPopup(selectPopup, "enter", win);
-
- position = positions.shift();
- if (!position) {
- break;
- }
-
- let contentPainted = BrowserTestUtils.contentPainted(browser);
- yield ContentTask.spawn(browser, position, function*(contentPosition) {
- let select = content.document.getElementById("one");
- select.setAttribute("style", contentPosition);
- select.getBoundingClientRect();
- });
- yield contentPainted;
- }
-}
-
-// This test checks select elements with a large number of options to ensure that
-// the popup appears within the browser area.
-add_task(function* test_large_popup() {
- const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
-
- yield* performLargePopupTests(window);
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-// This test checks the same as the previous test but in a new smaller window.
-add_task(function* test_large_popup_in_small_window() {
- let newwin = yield BrowserTestUtils.openNewBrowserWindow({ width: 400, height: 400 });
-
- const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
- let browserLoadedPromise = BrowserTestUtils.browserLoaded(newwin.gBrowser.selectedBrowser);
- yield BrowserTestUtils.loadURI(newwin.gBrowser.selectedBrowser, pageUrl);
- yield browserLoadedPromise;
-
- newwin.gBrowser.selectedBrowser.focus();
-
- yield* performLargePopupTests(newwin);
-
- yield BrowserTestUtils.closeWindow(newwin);
-});
-
-// This test checks that a mousemove event is fired correctly at the menu and
-// not at the browser, ensuring that any mouse capture has been cleared.
-add_task(function* test_mousemove_correcttarget() {
- const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
-
- 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);
- is(event.target.localName.indexOf("menu"), 0, "mouse over menu");
- resolve();
- }, true);
-
- EventUtils.synthesizeMouseAtCenter(selectPopup.firstChild, { type: "mousemove" });
- });
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mouseup" }, gBrowser.selectedBrowser);
-
- yield hideSelectPopup(selectPopup);
-
- // The popup should be closed when fullscreen mode is entered or exited.
- for (let steps = 0; steps < 2; steps++) {
- yield openSelectPopup(selectPopup, true);
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
- let sizeModeChanged = BrowserTestUtils.waitForEvent(window, "sizemodechange");
- BrowserFullScreen();
- yield sizeModeChanged;
- yield popupHiddenPromise;
- }
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-// This test checks when a <select> element has some options with altered display values.
-add_task(function* test_somehidden() {
- const pageUrl = "data:text/html," + escape(PAGECONTENT_SOMEHIDDEN);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
-
- let selectPopup = document.getElementById("ContentSelectDropdown").menupopup;
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(selectPopup, "popupshown");
- yield BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mousedown" }, gBrowser.selectedBrowser);
- yield popupShownPromise;
-
- // The exact number is not needed; just ensure the height is larger than 4 items to accomodate any popup borders.
- ok(selectPopup.getBoundingClientRect().height >= selectPopup.lastChild.getBoundingClientRect().height * 4, "Height contains at least 4 items");
- ok(selectPopup.getBoundingClientRect().height < selectPopup.lastChild.getBoundingClientRect().height * 5, "Height doesn't contain 5 items");
-
- // The label contains the substring 'Visible' for items that are visible.
- // Otherwise, it is expected to be display: none.
- is(selectPopup.parentNode.itemCount, 9, "Correct number of items");
- let child = selectPopup.firstChild;
- let idx = 1;
- while (child) {
- is(getComputedStyle(child).display, child.label.indexOf("Visible") > 0 ? "-moz-box" : "none",
- "Item " + (idx++) + " is visible");
- child = child.nextSibling;
- }
-
- yield hideSelectPopup(selectPopup, "escape");
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/general/browser_ssl_error_reports.js b/browser/base/content/test/general/browser_ssl_error_reports.js
deleted file mode 100644
index b1b1c8b84..000000000
--- a/browser/base/content/test/general/browser_ssl_error_reports.js
+++ /dev/null
@@ -1,174 +0,0 @@
-"use strict";
-
-const URL_REPORTS = "https://example.com/browser/browser/base/content/test/general/ssl_error_reports.sjs?";
-const URL_BAD_CHAIN = "https://badchain.include-subdomains.pinning.example.com/";
-const URL_NO_CERT = "https://fail-handshake.example.com/";
-const URL_BAD_CERT = "https://expired.example.com/";
-const URL_BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443/";
-const ROOT = getRootDirectory(gTestPath);
-const PREF_REPORT_ENABLED = "security.ssl.errorReporting.enabled";
-const PREF_REPORT_AUTOMATIC = "security.ssl.errorReporting.automatic";
-const PREF_REPORT_URL = "security.ssl.errorReporting.url";
-
-SimpleTest.requestCompleteLog();
-
-Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
-
-function cleanup() {
- Services.prefs.clearUserPref(PREF_REPORT_ENABLED);
- Services.prefs.clearUserPref(PREF_REPORT_AUTOMATIC);
- Services.prefs.clearUserPref(PREF_REPORT_URL);
-}
-
-registerCleanupFunction(() => {
- Services.prefs.clearUserPref("security.cert_pinning.enforcement_level");
- cleanup();
-});
-
-add_task(function* test_send_report_neterror() {
- yield testSendReportAutomatically(URL_BAD_CHAIN, "succeed", "neterror");
- yield testSendReportAutomatically(URL_NO_CERT, "nocert", "neterror");
- yield testSetAutomatic(URL_NO_CERT, "nocert", "neterror");
-});
-
-
-add_task(function* test_send_report_certerror() {
- yield testSendReportAutomatically(URL_BAD_CERT, "badcert", "certerror");
- yield testSetAutomatic(URL_BAD_CERT, "badcert", "certerror");
-});
-
-add_task(function* test_send_disabled() {
- Services.prefs.setBoolPref(PREF_REPORT_ENABLED, false);
- Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, true);
- Services.prefs.setCharPref(PREF_REPORT_URL, "https://example.com/invalid");
-
- // Check with enabled=false but automatic=true.
- yield testSendReportDisabled(URL_NO_CERT, "neterror");
- yield testSendReportDisabled(URL_BAD_CERT, "certerror");
-
- Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, false);
-
- // Check again with both prefs false.
- yield testSendReportDisabled(URL_NO_CERT, "neterror");
- yield testSendReportDisabled(URL_BAD_CERT, "certerror");
- cleanup();
-});
-
-function* testSendReportAutomatically(testURL, suffix, errorURISuffix) {
- Services.prefs.setBoolPref(PREF_REPORT_ENABLED, true);
- Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, true);
- Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
-
- // Add a tab and wait until it's loaded.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
- let browser = tab.linkedBrowser;
-
- // Load the page and wait for the error report submission.
- let promiseStatus = createReportResponseStatusPromise(URL_REPORTS + suffix);
- browser.loadURI(testURL);
- yield promiseErrorPageLoaded(browser);
-
- ok(!isErrorStatus(yield promiseStatus),
- "SSL error report submitted successfully");
-
- // Check that we loaded the right error page.
- yield checkErrorPage(browser, errorURISuffix);
-
- // Cleanup.
- gBrowser.removeTab(tab);
- cleanup();
-}
-
-function* testSetAutomatic(testURL, suffix, errorURISuffix) {
- Services.prefs.setBoolPref(PREF_REPORT_ENABLED, true);
- Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, false);
- Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
-
- // Add a tab and wait until it's loaded.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
- let browser = tab.linkedBrowser;
-
- // Load the page.
- browser.loadURI(testURL);
- yield promiseErrorPageLoaded(browser);
-
- // Check that we loaded the right error page.
- yield checkErrorPage(browser, errorURISuffix);
-
- let statusPromise = createReportResponseStatusPromise(URL_REPORTS + suffix);
-
- // Click the checkbox, enable automatic error reports.
- yield ContentTask.spawn(browser, null, function* () {
- content.document.getElementById("automaticallyReportInFuture").click();
- });
-
- // Wait for the error report submission.
- yield statusPromise;
-
- let isAutomaticReportingEnabled = () =>
- Services.prefs.getBoolPref(PREF_REPORT_AUTOMATIC);
-
- // Check that the pref was flipped.
- ok(isAutomaticReportingEnabled(), "automatic SSL report submission enabled");
-
- // Disable automatic error reports.
- yield ContentTask.spawn(browser, null, function* () {
- content.document.getElementById("automaticallyReportInFuture").click();
- });
-
- // Check that the pref was flipped.
- ok(!isAutomaticReportingEnabled(), "automatic SSL report submission disabled");
-
- // Cleanup.
- gBrowser.removeTab(tab);
- cleanup();
-}
-
-function* testSendReportDisabled(testURL, errorURISuffix) {
- // Add a tab and wait until it's loaded.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
- let browser = tab.linkedBrowser;
-
- // Load the page.
- browser.loadURI(testURL);
- yield promiseErrorPageLoaded(browser);
-
- // Check that we loaded the right error page.
- yield checkErrorPage(browser, errorURISuffix);
-
- // Check that the error reporting section is hidden.
- yield ContentTask.spawn(browser, null, function* () {
- let section = content.document.getElementById("certificateErrorReporting");
- Assert.equal(content.getComputedStyle(section).display, "none",
- "error reporting section should be hidden");
- });
-
- // Cleanup.
- gBrowser.removeTab(tab);
-}
-
-function isErrorStatus(status) {
- return status < 200 || status >= 300;
-}
-
-// use the observer service to see when a report is sent
-function createReportResponseStatusPromise(expectedURI) {
- return new Promise(resolve => {
- let observer = (subject, topic, data) => {
- subject.QueryInterface(Ci.nsIHttpChannel);
- let requestURI = subject.URI.spec;
- if (requestURI == expectedURI) {
- Services.obs.removeObserver(observer, "http-on-examine-response");
- resolve(subject.responseStatus);
- }
- };
- Services.obs.addObserver(observer, "http-on-examine-response", false);
- });
-}
-
-function checkErrorPage(browser, suffix) {
- return ContentTask.spawn(browser, { suffix }, function* (args) {
- let uri = content.document.documentURI;
- Assert.ok(uri.startsWith(`about:${args.suffix}`), "correct error page loaded");
- });
-}
diff --git a/browser/base/content/test/general/browser_star_hsts.js b/browser/base/content/test/general/browser_star_hsts.js
deleted file mode 100644
index c52e563bc..000000000
--- a/browser/base/content/test/general/browser_star_hsts.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var secureURL = "https://example.com/browser/browser/base/content/test/general/browser_star_hsts.sjs";
-var unsecureURL = "http://example.com/browser/browser/base/content/test/general/browser_star_hsts.sjs";
-
-add_task(function* test_star_redirect() {
- registerCleanupFunction(function() {
- // Ensure to remove example.com from the HSTS list.
- let sss = Cc["@mozilla.org/ssservice;1"]
- .getService(Ci.nsISiteSecurityService);
- sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS,
- NetUtil.newURI("http://example.com/"), 0);
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- gBrowser.removeCurrentTab();
- });
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- // This will add the page to the HSTS cache.
- yield promiseTabLoadEvent(tab, secureURL, secureURL);
- // This should transparently be redirected to the secure page.
- yield promiseTabLoadEvent(tab, unsecureURL, secureURL);
-
- yield promiseStarState(BookmarkingUI.STATUS_UNSTARRED);
-
- let promiseBookmark = promiseOnBookmarkItemAdded(gBrowser.currentURI);
- BookmarkingUI.star.click();
- // This resolves on the next tick, so the star should have already been
- // updated at that point.
- yield promiseBookmark;
-
- is(BookmarkingUI.status, BookmarkingUI.STATUS_STARRED, "The star is starred");
-});
-
-/**
- * Waits for the star to reflect the expected state.
- */
-function promiseStarState(aValue) {
- let deferred = Promise.defer();
- let expectedStatus = aValue ? BookmarkingUI.STATUS_STARRED
- : BookmarkingUI.STATUS_UNSTARRED;
- (function checkState() {
- if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING ||
- BookmarkingUI.status != expectedStatus) {
- info("Waiting for star button change.");
- setTimeout(checkState, 1000);
- } else {
- deferred.resolve();
- }
- })();
- return deferred.promise;
-}
-
-/**
- * Starts a load in an existing tab and waits for it to finish (via some event).
- *
- * @param aTab
- * The tab to load into.
- * @param aUrl
- * The url to load.
- * @param [optional] aFinalURL
- * The url to wait for, same as aURL if not defined.
- * @return {Promise} resolved when the event is handled.
- */
-function promiseTabLoadEvent(aTab, aURL, aFinalURL)
-{
- if (!aFinalURL)
- aFinalURL = aURL;
- let deferred = Promise.defer();
- info("Wait for load tab event");
- aTab.linkedBrowser.addEventListener("load", function load(event) {
- if (event.originalTarget != aTab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank" ||
- event.target.location.href != aFinalURL) {
- info("skipping spurious load event");
- return;
- }
- aTab.linkedBrowser.removeEventListener("load", load, true);
- info("Tab load event received");
- deferred.resolve();
- }, true, true);
- aTab.linkedBrowser.loadURI(aURL);
- return deferred.promise;
-}
diff --git a/browser/base/content/test/general/browser_star_hsts.sjs b/browser/base/content/test/general/browser_star_hsts.sjs
deleted file mode 100644
index 10c7aae12..000000000
--- a/browser/base/content/test/general/browser_star_hsts.sjs
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function handleRequest(request, response)
-{
- let page = "<!DOCTYPE html><html><body><p>HSTS page</p></body></html>";
- response.setStatusLine(request.httpVersion, "200", "OK");
- response.setHeader("Strict-Transport-Security", "max-age=60");
- response.setHeader("Content-Type", "text/html", false);
- response.setHeader("Content-Length", page.length + "", false);
- response.write(page);
-}
diff --git a/browser/base/content/test/general/browser_subframe_favicons_not_used.js b/browser/base/content/test/general/browser_subframe_favicons_not_used.js
deleted file mode 100644
index 7efe78d9b..000000000
--- a/browser/base/content/test/general/browser_subframe_favicons_not_used.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Make sure <link rel="..."> isn't respected in sub-frames. */
-
-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);
-}
diff --git a/browser/base/content/test/general/browser_syncui.js b/browser/base/content/test/general/browser_syncui.js
deleted file mode 100644
index daf0fa497..000000000
--- a/browser/base/content/test/general/browser_syncui.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var {Log} = Cu.import("resource://gre/modules/Log.jsm", {});
-var {Weave} = Cu.import("resource://services-sync/main.js", {});
-
-var stringBundle = Cc["@mozilla.org/intl/stringbundle;1"]
- .getService(Ci.nsIStringBundleService)
- .createBundle("chrome://weave/locale/services/sync.properties");
-
-// ensure test output sees log messages.
-Log.repository.getLogger("browserwindow.syncui").addAppender(new Log.DumpAppender());
-
-// Send the specified sync-related notification and return a promise that
-// resolves once gSyncUI._promiseUpateUI is complete and the UI is ready to check.
-function notifyAndPromiseUIUpdated(topic) {
- return new Promise(resolve => {
- // Instrument gSyncUI so we know when the update is complete.
- let oldPromiseUpdateUI = gSyncUI._promiseUpdateUI.bind(gSyncUI);
- gSyncUI._promiseUpdateUI = function() {
- return oldPromiseUpdateUI().then(() => {
- // Restore our override.
- gSyncUI._promiseUpdateUI = oldPromiseUpdateUI;
- // Resolve the promise so the caller knows the update is done.
- resolve();
- });
- };
- // Now send the notification.
- Services.obs.notifyObservers(null, topic, null);
- });
-}
-
-// Sync manages 3 broadcasters so the menus correctly reflect the Sync state.
-// Only one of these 3 should ever be visible - pass the ID of the broadcaster
-// you expect to be visible and it will check it's the only one that is.
-function checkBroadcasterVisible(broadcasterId) {
- let all = ["sync-reauth-state", "sync-setup-state", "sync-syncnow-state"];
- Assert.ok(all.indexOf(broadcasterId) >= 0, "valid id");
- for (let check of all) {
- let eltHidden = document.getElementById(check).hidden;
- Assert.equal(eltHidden, check == broadcasterId ? false : true, check);
- }
-}
-
-function promiseObserver(topic) {
- return new Promise(resolve => {
- let obs = (aSubject, aTopic, aData) => {
- Services.obs.removeObserver(obs, aTopic);
- resolve(aSubject);
- }
- Services.obs.addObserver(obs, topic, false);
- });
-}
-
-function checkButtonTooltips(stringPrefix) {
- for (let butId of ["PanelUI-remotetabs-syncnow", "PanelUI-fxa-icon"]) {
- let text = document.getElementById(butId).getAttribute("tooltiptext");
- let desc = `Text is "${text}", expecting it to start with "${stringPrefix}"`
- Assert.ok(text.startsWith(stringPrefix), desc);
- }
-}
-
-add_task(function* prepare() {
- // add the Sync button to the toolbar so we can get it!
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_NAVBAR);
- registerCleanupFunction(() => {
- CustomizableUI.removeWidgetFromArea("sync-button");
- });
-
- let xps = Components.classes["@mozilla.org/weave/service;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- yield xps.whenLoaded();
- // Put Sync and the UI into a known state.
- Weave.Status.login = Weave.LOGIN_FAILED_NO_USERNAME;
- yield notifyAndPromiseUIUpdated("weave:service:login:error");
-
- checkBroadcasterVisible("sync-setup-state");
- checkButtonTooltips("Sign In To Sync");
- // mock out the "_needsSetup()" function so we don't short-circuit.
- let oldNeedsSetup = window.gSyncUI._needsSetup;
- window.gSyncUI._needsSetup = () => Promise.resolve(false);
- registerCleanupFunction(() => {
- window.gSyncUI._needsSetup = oldNeedsSetup;
- // and an observer to set the state back to what it should be now we've
- // restored the stub.
- Services.obs.notifyObservers(null, "weave:service:login:finish", null);
- });
- // and a notification to have the state change away from "needs setup"
- yield notifyAndPromiseUIUpdated("weave:service:login:finish");
- checkBroadcasterVisible("sync-syncnow-state");
- // open the sync-button panel so we can check elements in that.
- document.getElementById("sync-button").click();
-});
-
-add_task(function* testSyncNeedsVerification() {
- // mock out the "_needsVerification()" function
- let oldNeedsVerification = window.gSyncUI._needsVerification;
- window.gSyncUI._needsVerification = () => true;
- try {
- // a notification for the state change
- yield notifyAndPromiseUIUpdated("weave:service:login:finish");
- checkButtonTooltips("Verify");
- } finally {
- window.gSyncUI._needsVerification = oldNeedsVerification;
- }
-});
-
-
-add_task(function* testSyncLoginError() {
- checkBroadcasterVisible("sync-syncnow-state");
-
- // Pretend we are in a "login failed" error state
- Weave.Status.sync = Weave.LOGIN_FAILED;
- Weave.Status.login = Weave.LOGIN_FAILED_LOGIN_REJECTED;
- yield notifyAndPromiseUIUpdated("weave:ui:sync:error");
-
- // But the menu *should* reflect the login error.
- checkBroadcasterVisible("sync-reauth-state");
- // The tooltips for the buttons should also reflect it.
- checkButtonTooltips("Reconnect");
-
- // Now pretend we just had a successful login - the error notification should go away.
- Weave.Status.sync = Weave.STATUS_OK;
- Weave.Status.login = Weave.LOGIN_SUCCEEDED;
- yield notifyAndPromiseUIUpdated("weave:service:login:start");
- yield notifyAndPromiseUIUpdated("weave:service:login:finish");
- // The menus should be back to "all good"
- checkBroadcasterVisible("sync-syncnow-state");
-});
-
-function checkButtonsStatus(shouldBeActive) {
- for (let eid of [
- "sync-status", // the broadcaster itself.
- "sync-button", // the main sync button which observes the broadcaster
- "PanelUI-fxa-icon", // the sync icon in the fxa footer that observes it.
- ]) {
- let elt = document.getElementById(eid);
- if (shouldBeActive) {
- Assert.equal(elt.getAttribute("syncstatus"), "active", `${eid} should be active`);
- } else {
- Assert.ok(!elt.hasAttribute("syncstatus"), `${eid} should have no status attr`);
- }
- }
-}
-
-function* testButtonActions(startNotification, endNotification, expectActive = true) {
- checkButtonsStatus(false);
- // pretend a sync is starting.
- yield notifyAndPromiseUIUpdated(startNotification);
- checkButtonsStatus(expectActive);
- // and has stopped
- yield notifyAndPromiseUIUpdated(endNotification);
- checkButtonsStatus(false);
-}
-
-function *doTestButtonActivities() {
- // logins do not "activate" the spinner/button as they may block and make
- // the UI look like Sync is never completing.
- yield testButtonActions("weave:service:login:start", "weave:service:login:finish", false);
- yield testButtonActions("weave:service:login:start", "weave:service:login:error", false);
-
- // But notifications for Sync itself should activate it.
- yield testButtonActions("weave:service:sync:start", "weave:service:sync:finish");
- yield testButtonActions("weave:service:sync:start", "weave:service:sync:error");
-
- // and ensure the counters correctly handle multiple in-flight syncs
- yield notifyAndPromiseUIUpdated("weave:service:sync:start");
- checkButtonsStatus(true);
- // sync stops.
- yield notifyAndPromiseUIUpdated("weave:service:sync:finish");
- // Button should not be active.
- checkButtonsStatus(false);
-}
-
-add_task(function* testButtonActivitiesInNavBar() {
- // check the button's functionality while the button is in the NavBar - which
- // it already is.
- yield doTestButtonActivities();
-});
-
-add_task(function* testFormatLastSyncDateNow() {
- let now = new Date();
- let nowString = gSyncUI.formatLastSyncDate(now);
- Assert.equal(nowString, "Last sync: " + now.toLocaleDateString(undefined, {weekday: 'long', hour: 'numeric', minute: 'numeric'}));
-});
-
-add_task(function* testFormatLastSyncDateMonthAgo() {
- let monthAgo = new Date();
- monthAgo.setMonth(monthAgo.getMonth() - 1);
- let monthAgoString = gSyncUI.formatLastSyncDate(monthAgo);
- Assert.equal(monthAgoString, "Last sync: " + monthAgo.toLocaleDateString(undefined, {month: 'long', day: 'numeric'}));
-});
-
-add_task(function* testButtonActivitiesInPanel() {
- // check the button's functionality while the button is in the panel - it's
- // currently in the NavBar - move it to the panel and open it.
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- yield PanelUI.show();
- try {
- yield doTestButtonActivities();
- } finally {
- PanelUI.hide();
- }
-});
diff --git a/browser/base/content/test/general/browser_tabDrop.js b/browser/base/content/test/general/browser_tabDrop.js
deleted file mode 100644
index fd743e6dc..000000000
--- a/browser/base/content/test/general/browser_tabDrop.js
+++ /dev/null
@@ -1,103 +0,0 @@
-registerCleanupFunction(function* cleanup() {
- while (gBrowser.tabs.length > 1) {
- yield BrowserTestUtils.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
- }
- Services.search.currentEngine = originalEngine;
- let engine = Services.search.getEngineByName("MozSearch");
- Services.search.removeEngine(engine);
-});
-
-let originalEngine;
-add_task(function* test_setup() {
- // Stop search-engine loads from hitting the network
- Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- let engine = Services.search.getEngineByName("MozSearch");
- originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-});
-
-add_task(function*() { yield dropText("mochi.test/first", 1); });
-add_task(function*() { yield dropText("javascript:'bad'"); });
-add_task(function*() { yield dropText("jAvascript:'bad'"); });
-add_task(function*() { yield dropText("search this", 1); });
-add_task(function*() { yield dropText("mochi.test/second", 1); });
-add_task(function*() { yield dropText("data:text/html,bad"); });
-add_task(function*() { yield dropText("mochi.test/third", 1); });
-
-// Single text/plain item, with multiple links.
-add_task(function*() { yield dropText("mochi.test/1\nmochi.test/2", 2); });
-add_task(function*() { yield dropText("javascript:'bad1'\nmochi.test/3", 0); });
-add_task(function*() { yield dropText("mochi.test/4\ndata:text/html,bad1", 0); });
-
-// Multiple text/plain items, with single and multiple links.
-add_task(function*() {
- yield drop([[{type: "text/plain",
- data: "mochi.test/5"}],
- [{type: "text/plain",
- data: "mochi.test/6\nmochi.test/7"}]], 3);
-});
-
-// Single text/x-moz-url item, with multiple links.
-// "text/x-moz-url" has titles in even-numbered lines.
-add_task(function*() {
- yield drop([[{type: "text/x-moz-url",
- data: "mochi.test/8\nTITLE8\nmochi.test/9\nTITLE9"}]], 2);
-});
-
-// Single item with multiple types.
-add_task(function*() {
- yield drop([[{type: "text/plain",
- data: "mochi.test/10"},
- {type: "text/x-moz-url",
- data: "mochi.test/11\nTITLE11"}]], 1);
-});
-
-function dropText(text, expectedTabOpenCount=0) {
- return drop([[{type: "text/plain", data: text}]], expectedTabOpenCount);
-}
-
-function* drop(dragData, expectedTabOpenCount=0) {
- let dragDataString = JSON.stringify(dragData);
- info(`Starting test for datagData:${dragDataString}; expectedTabOpenCount:${expectedTabOpenCount}`);
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- let awaitDrop = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "drop");
- let actualTabOpenCount = 0;
- let openedTabs = [];
- let checkCount = function(event) {
- openedTabs.push(event.target);
- actualTabOpenCount++;
- return actualTabOpenCount == expectedTabOpenCount;
- };
- let awaitTabOpen = expectedTabOpenCount && BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen", false, checkCount);
- // A drop type of "link" onto an existing tab would normally trigger a
- // load in that same tab, but tabbrowser code in _getDragTargetTab treats
- // drops on the outer edges of a tab differently (loading a new tab
- // instead). Make events created by synthesizeDrop have all of their
- // coordinates set to 0 (screenX/screenY), so they're treated as drops
- // on the outer edge of the tab, thus they open new tabs.
- var event = {
- clientX: 0,
- clientY: 0,
- screenX: 0,
- screenY: 0,
- };
- EventUtils.synthesizeDrop(gBrowser.selectedTab, gBrowser.selectedTab, dragData, "link", window, undefined, event);
- let tabsOpened = false;
- if (awaitTabOpen) {
- yield awaitTabOpen;
- info("Got TabOpen event");
- tabsOpened = true;
- for (let tab of openedTabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- }
- is(tabsOpened, !!expectedTabOpenCount, `Tabs for ${dragDataString} should only open if any of dropped items are valid`);
-
- yield awaitDrop;
- ok(true, "Got drop event");
-}
diff --git a/browser/base/content/test/general/browser_tabReorder.js b/browser/base/content/test/general/browser_tabReorder.js
deleted file mode 100644
index 9e0503e95..000000000
--- a/browser/base/content/test/general/browser_tabReorder.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- let initialTabsLength = gBrowser.tabs.length;
-
- let newTab1 = gBrowser.selectedTab = gBrowser.addTab("about:robots", {skipAnimation: true});
- let newTab2 = gBrowser.selectedTab = gBrowser.addTab("about:about", {skipAnimation: true});
- let newTab3 = gBrowser.selectedTab = gBrowser.addTab("about:config", {skipAnimation: true});
- registerCleanupFunction(function () {
- while (gBrowser.tabs.length > initialTabsLength) {
- gBrowser.removeTab(gBrowser.tabs[initialTabsLength]);
- }
- });
-
- is(gBrowser.tabs.length, initialTabsLength + 3, "new tabs are opened");
- is(gBrowser.tabs[initialTabsLength], newTab1, "newTab1 position is correct");
- is(gBrowser.tabs[initialTabsLength + 1], newTab2, "newTab2 position is correct");
- is(gBrowser.tabs[initialTabsLength + 2], newTab3, "newTab3 position is correct");
-
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- function dragAndDrop(tab1, tab2, copy) {
- let rect = tab2.getBoundingClientRect();
- let event = {
- ctrlKey: copy,
- altKey: copy,
- clientX: rect.left + rect.width / 2 + 10,
- clientY: rect.top + rect.height / 2,
- };
-
- EventUtils.synthesizeDrop(tab1, tab2, null, copy ? "copy" : "move", window, window, event);
- }
-
- dragAndDrop(newTab1, newTab2, false);
- is(gBrowser.tabs.length, initialTabsLength + 3, "tabs are still there");
- is(gBrowser.tabs[initialTabsLength], newTab2, "newTab2 and newTab1 are swapped");
- is(gBrowser.tabs[initialTabsLength + 1], newTab1, "newTab1 and newTab2 are swapped");
- is(gBrowser.tabs[initialTabsLength + 2], newTab3, "newTab3 stays same place");
-
- dragAndDrop(newTab2, newTab1, true);
- is(gBrowser.tabs.length, initialTabsLength + 4, "a tab is duplicated");
- is(gBrowser.tabs[initialTabsLength], newTab2, "newTab2 stays same place");
- is(gBrowser.tabs[initialTabsLength + 1], newTab1, "newTab1 stays same place");
- is(gBrowser.tabs[initialTabsLength + 3], newTab3, "a new tab is inserted before newTab3");
-}
diff --git a/browser/base/content/test/general/browser_tab_close_dependent_window.js b/browser/base/content/test/general/browser_tab_close_dependent_window.js
deleted file mode 100644
index ab8a960ac..000000000
--- a/browser/base/content/test/general/browser_tab_close_dependent_window.js
+++ /dev/null
@@ -1,24 +0,0 @@
-"use strict";
-
-add_task(function* closing_tab_with_dependents_should_close_window() {
- info("Opening window");
- let win = yield BrowserTestUtils.openNewBrowserWindow();
-
- info("Opening tab with data URI");
- let tab = yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, `data:text/html,<html%20onclick="W=window.open()"><body%20onbeforeunload="W.close()">`);
- info("Closing original tab in this window.");
- yield BrowserTestUtils.removeTab(win.gBrowser.tabs[0]);
- info("Clicking into the window");
- let depTabOpened = BrowserTestUtils.waitForEvent(win.gBrowser.tabContainer, "TabOpen");
- yield BrowserTestUtils.synthesizeMouse("html", 0, 0, {}, tab.linkedBrowser);
-
- let openedTab = (yield depTabOpened).target;
- info("Got opened tab");
-
- let windowClosedPromise = BrowserTestUtils.windowClosed(win);
- yield BrowserTestUtils.removeTab(tab);
- is(Cu.isDeadWrapper(openedTab) || openedTab.linkedBrowser == null, true, "Opened tab should also have closed");
- info("If we timeout now, the window failed to close - that shouldn't happen!");
- yield windowClosedPromise;
-});
-
diff --git a/browser/base/content/test/general/browser_tab_detach_restore.js b/browser/base/content/test/general/browser_tab_detach_restore.js
deleted file mode 100644
index d482edc26..000000000
--- a/browser/base/content/test/general/browser_tab_detach_restore.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-add_task(function*() {
- let uri = "http://example.com/browser/browser/base/content/test/general/dummy_page.html";
-
- // Clear out the closed windows set to start
- while (SessionStore.getClosedWindowCount() > 0)
- SessionStore.forgetClosedWindow(0);
-
- let tab = gBrowser.addTab();
- tab.linkedBrowser.loadURI(uri);
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
-
- let key = tab.linkedBrowser.permanentKey;
- let win = gBrowser.replaceTabWithWindow(tab);
- yield new Promise(resolve => whenDelayedStartupFinished(win, resolve));
-
- is(win.gBrowser.selectedBrowser.permanentKey, key, "Should have properly copied the permanentKey");
- yield BrowserTestUtils.closeWindow(win);
-
- is(SessionStore.getClosedWindowCount(), 1, "Should have restore data for the closed window");
-
- win = SessionStore.undoCloseWindow(0);
- yield BrowserTestUtils.waitForEvent(win, "load");
- yield BrowserTestUtils.waitForEvent(win.gBrowser.tabs[0], "SSTabRestored");
-
- is(win.gBrowser.tabs.length, 1, "Should have restored one tab");
- is(win.gBrowser.selectedBrowser.currentURI.spec, uri, "Should have restored the right page");
-
- yield promiseWindowClosed(win);
-});
diff --git a/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js b/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js
deleted file mode 100644
index a8fc34083..000000000
--- a/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js
+++ /dev/null
@@ -1,216 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-requestLongerTimeout(2);
-
-const EVENTUTILS_URL = "chrome://mochikit/content/tests/SimpleTest/EventUtils.js";
-var EventUtils = {};
-
-Services.scriptloader.loadSubScript(EVENTUTILS_URL, EventUtils);
-
-/**
- * Tests that tabs from Private Browsing windows cannot be dragged
- * into non-private windows, and vice-versa.
- */
-add_task(function* test_dragging_private_windows() {
- let normalWin = yield BrowserTestUtils.openNewBrowserWindow();
- let privateWin =
- yield BrowserTestUtils.openNewBrowserWindow({private: true});
-
- let normalTab =
- yield BrowserTestUtils.openNewForegroundTab(normalWin.gBrowser);
- let privateTab =
- yield BrowserTestUtils.openNewForegroundTab(privateWin.gBrowser);
-
- let effect = EventUtils.synthesizeDrop(normalTab, privateTab,
- [[{type: TAB_DROP_TYPE, data: normalTab}]],
- null, normalWin, privateWin);
- is(effect, "none", "Should not be able to drag a normal tab to a private window");
-
- effect = EventUtils.synthesizeDrop(privateTab, normalTab,
- [[{type: TAB_DROP_TYPE, data: privateTab}]],
- null, privateWin, normalWin);
- is(effect, "none", "Should not be able to drag a private tab to a normal window");
-
- normalWin.gBrowser.swapBrowsersAndCloseOther(normalTab, privateTab);
- is(normalWin.gBrowser.tabs.length, 2,
- "Prevent moving a normal tab to a private tabbrowser");
- is(privateWin.gBrowser.tabs.length, 2,
- "Prevent accepting a normal tab in a private tabbrowser");
-
- privateWin.gBrowser.swapBrowsersAndCloseOther(privateTab, normalTab);
- is(privateWin.gBrowser.tabs.length, 2,
- "Prevent moving a private tab to a normal tabbrowser");
- is(normalWin.gBrowser.tabs.length, 2,
- "Prevent accepting a private tab in a normal tabbrowser");
-
- yield BrowserTestUtils.closeWindow(normalWin);
- yield BrowserTestUtils.closeWindow(privateWin);
-});
-
-/**
- * Tests that tabs from e10s windows cannot be dragged into non-e10s
- * windows, and vice-versa.
- */
-add_task(function* test_dragging_e10s_windows() {
- if (!gMultiProcessBrowser) {
- return;
- }
-
- let remoteWin = yield BrowserTestUtils.openNewBrowserWindow({remote: true});
- let nonRemoteWin = yield BrowserTestUtils.openNewBrowserWindow({remote: false});
-
- let remoteTab =
- yield BrowserTestUtils.openNewForegroundTab(remoteWin.gBrowser);
- let nonRemoteTab =
- yield BrowserTestUtils.openNewForegroundTab(nonRemoteWin.gBrowser);
-
- let effect = EventUtils.synthesizeDrop(remoteTab, nonRemoteTab,
- [[{type: TAB_DROP_TYPE, data: remoteTab}]],
- null, remoteWin, nonRemoteWin);
- is(effect, "none", "Should not be able to drag a remote tab to a non-e10s window");
-
- effect = EventUtils.synthesizeDrop(nonRemoteTab, remoteTab,
- [[{type: TAB_DROP_TYPE, data: nonRemoteTab}]],
- null, nonRemoteWin, remoteWin);
- is(effect, "none", "Should not be able to drag a non-remote tab to an e10s window");
-
- remoteWin.gBrowser.swapBrowsersAndCloseOther(remoteTab, nonRemoteTab);
- is(remoteWin.gBrowser.tabs.length, 2,
- "Prevent moving a normal tab to a private tabbrowser");
- is(nonRemoteWin.gBrowser.tabs.length, 2,
- "Prevent accepting a normal tab in a private tabbrowser");
-
- nonRemoteWin.gBrowser.swapBrowsersAndCloseOther(nonRemoteTab, remoteTab);
- is(nonRemoteWin.gBrowser.tabs.length, 2,
- "Prevent moving a private tab to a normal tabbrowser");
- is(remoteWin.gBrowser.tabs.length, 2,
- "Prevent accepting a private tab in a normal tabbrowser");
-
- yield BrowserTestUtils.closeWindow(remoteWin);
- yield BrowserTestUtils.closeWindow(nonRemoteWin);
-});
-
-/**
- * Tests that remoteness-blacklisted tabs from e10s windows can
- * be dragged between e10s windows.
- */
-add_task(function* test_dragging_blacklisted() {
- if (!gMultiProcessBrowser) {
- return;
- }
-
- let remoteWin1 = yield BrowserTestUtils.openNewBrowserWindow({remote: true});
- remoteWin1.gBrowser.myID = "remoteWin1";
- let remoteWin2 = yield BrowserTestUtils.openNewBrowserWindow({remote: true});
- remoteWin2.gBrowser.myID = "remoteWin2";
-
- // Anything under chrome://mochitests/content/ will be blacklisted, and
- // open in the parent process.
- const BLACKLISTED_URL = getRootDirectory(gTestPath) +
- "browser_tab_drag_drop_perwindow.js";
- let blacklistedTab =
- yield BrowserTestUtils.openNewForegroundTab(remoteWin1.gBrowser,
- BLACKLISTED_URL);
-
- ok(blacklistedTab.linkedBrowser, "Newly created tab should have a browser.");
-
- ok(!blacklistedTab.linkedBrowser.isRemoteBrowser,
- `Expected a non-remote browser for URL: ${BLACKLISTED_URL}`);
-
- let otherTab =
- yield BrowserTestUtils.openNewForegroundTab(remoteWin2.gBrowser);
-
- let effect = EventUtils.synthesizeDrop(blacklistedTab, otherTab,
- [[{type: TAB_DROP_TYPE, data: blacklistedTab}]],
- null, remoteWin1, remoteWin2);
- is(effect, "move", "Should be able to drag the blacklisted tab.");
-
- // The synthesized drop should also do the work of swapping the
- // browsers, so no need to call swapBrowsersAndCloseOther manually.
-
- is(remoteWin1.gBrowser.tabs.length, 1,
- "Should have moved the blacklisted tab out of this window.");
- is(remoteWin2.gBrowser.tabs.length, 3,
- "Should have inserted the blacklisted tab into the other window.");
-
- // The currently selected tab in the second window should be the
- // one we just dragged in.
- let draggedBrowser = remoteWin2.gBrowser.selectedBrowser;
- ok(!draggedBrowser.isRemoteBrowser,
- "The browser we just dragged in should not be remote.");
-
- is(draggedBrowser.currentURI.spec, BLACKLISTED_URL,
- `Expected the URL of the dragged in tab to be ${BLACKLISTED_URL}`);
-
- yield BrowserTestUtils.closeWindow(remoteWin1);
- yield BrowserTestUtils.closeWindow(remoteWin2);
-});
-
-
-/**
- * Tests that tabs dragged between windows dispatch TabOpen and TabClose
- * events with the appropriate adoption details.
- */
-add_task(function* test_dragging_adoption_events() {
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(win1.gBrowser);
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(win2.gBrowser);
-
- let awaitCloseEvent = BrowserTestUtils.waitForEvent(tab1, "TabClose");
- let awaitOpenEvent = BrowserTestUtils.waitForEvent(win2, "TabOpen");
-
- let effect = EventUtils.synthesizeDrop(tab1, tab2,
- [[{type: TAB_DROP_TYPE, data: tab1}]],
- null, win1, win2);
- is(effect, "move", "Tab should be moved from win1 to win2.");
-
- let closeEvent = yield awaitCloseEvent;
- let openEvent = yield awaitOpenEvent;
-
- is(openEvent.detail.adoptedTab, tab1, "New tab adopted old tab");
- is(closeEvent.detail.adoptedBy, openEvent.target, "Old tab adopted by new tab");
-
- yield BrowserTestUtils.closeWindow(win1);
- yield BrowserTestUtils.closeWindow(win2);
-});
-
-
-/**
- * Tests that per-site zoom settings remain active after a tab is
- * dragged between windows.
- */
-add_task(function* test_dragging_zoom_handling() {
- const ZOOM_FACTOR = 1.62;
-
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(win1.gBrowser);
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(win2.gBrowser,
- "http://example.com/");
-
- win2.FullZoom.setZoom(ZOOM_FACTOR);
- FullZoomHelper.zoomTest(tab2, ZOOM_FACTOR,
- "Original tab should have correct zoom factor");
-
- let effect = EventUtils.synthesizeDrop(tab2, tab1,
- [[{type: TAB_DROP_TYPE, data: tab2}]],
- null, win2, win1);
- is(effect, "move", "Tab should be moved from win2 to win1.");
-
- // Delay slightly to make sure we've finished executing any promise
- // chains in the zoom code.
- yield new Promise(resolve => setTimeout(resolve, 0));
-
- FullZoomHelper.zoomTest(win1.gBrowser.selectedTab, ZOOM_FACTOR,
- "Dragged tab should have correct zoom factor");
-
- win1.FullZoom.reset();
-
- yield BrowserTestUtils.closeWindow(win1);
- yield BrowserTestUtils.closeWindow(win2);
-});
diff --git a/browser/base/content/test/general/browser_tab_dragdrop.js b/browser/base/content/test/general/browser_tab_dragdrop.js
deleted file mode 100644
index cfe996e1e..000000000
--- a/browser/base/content/test/general/browser_tab_dragdrop.js
+++ /dev/null
@@ -1,186 +0,0 @@
-function swapTabsAndCloseOther(a, b) {
- gBrowser.swapBrowsersAndCloseOther(gBrowser.tabs[b], gBrowser.tabs[a]);
-}
-
-var getClicks = function(tab) {
- return ContentTask.spawn(tab.linkedBrowser, {}, function() {
- return content.wrappedJSObject.clicks;
- });
-}
-
-var clickTest = Task.async(function*(tab) {
- let clicks = yield getClicks(tab);
-
- yield ContentTask.spawn(tab.linkedBrowser, {}, function() {
- let target = content.document.body;
- let rect = target.getBoundingClientRect();
- let left = (rect.left + rect.right) / 2;
- let top = (rect.top + rect.bottom) / 2;
-
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
-
- let newClicks = yield getClicks(tab);
- is(newClicks, clicks + 1, "adding 1 more click on BODY");
-});
-
-function loadURI(tab, url) {
- tab.linkedBrowser.loadURI(url);
- return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-}
-
-// Creates a framescript which caches the current object value from the plugin
-// in the page. checkObjectValue below verifies that the framescript is still
-// active for the browser and that the cached value matches that from the plugin
-// in the page which tells us the plugin hasn't been reinitialized.
-function* cacheObjectValue(browser) {
- yield ContentTask.spawn(browser, null, function*() {
- let plugin = content.document.wrappedJSObject.body.firstChild;
- info(`plugin is ${plugin}`);
- let win = content.document.defaultView;
- info(`win is ${win}`);
- win.objectValue = plugin.getObjectValue();
- info(`got objectValue: ${win.objectValue}`);
- win.checkObjectValueListener = () => {
- let result;
- let exception;
- try {
- result = plugin.checkObjectValue(win.objectValue);
- } catch (e) {
- exception = e.toString();
- }
- info(`sending plugin.checkObjectValue(objectValue): ${result}`);
- sendAsyncMessage("Test:CheckObjectValueResult", {
- result,
- exception
- });
- };
-
- addMessageListener("Test:CheckObjectValue", win.checkObjectValueListener);
- });
-}
-
-// Note, can't run this via registerCleanupFunction because it needs the
-// browser to still be alive and have a messageManager.
-function* cleanupObjectValue(browser) {
- info("entered cleanupObjectValue")
- yield ContentTask.spawn(browser, null, function*() {
- info("in cleanup function");
- let win = content.document.defaultView;
- info(`about to delete objectValue: ${win.objectValue}`);
- delete win.objectValue;
- removeMessageListener("Test:CheckObjectValue", win.checkObjectValueListener);
- info(`about to delete checkObjectValueListener: ${win.checkObjectValueListener}`);
- delete win.checkObjectValueListener;
- info(`deleted objectValue (${win.objectValue}) and checkObjectValueListener (${win.checkObjectValueListener})`);
- });
- info("exiting cleanupObjectValue")
-}
-
-// See the notes for cacheObjectValue above.
-function checkObjectValue(browser) {
- let mm = browser.messageManager;
-
- return new Promise((resolve, reject) => {
- let listener = ({ data }) => {
- mm.removeMessageListener("Test:CheckObjectValueResult", listener);
- if (data.result === null) {
- ok(false, "checkObjectValue threw an exception: " + data.exception);
- reject(data.exception);
- } else {
- resolve(data.result);
- }
- };
-
- mm.addMessageListener("Test:CheckObjectValueResult", listener);
- mm.sendAsyncMessage("Test:CheckObjectValue");
- });
-}
-
-add_task(function*() {
- let embed = '<embed type="application/x-test" allowscriptaccess="always" allowfullscreen="true" wmode="window" width="640" height="480"></embed>'
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-
- // create a few tabs
- let tabs = [
- gBrowser.tabs[0],
- gBrowser.addTab("about:blank", {skipAnimation: true}),
- gBrowser.addTab("about:blank", {skipAnimation: true}),
- gBrowser.addTab("about:blank", {skipAnimation: true}),
- gBrowser.addTab("about:blank", {skipAnimation: true})
- ];
-
- // Initially 0 1 2 3 4
- yield loadURI(tabs[1], "data:text/html;charset=utf-8,<title>tab1</title><body>tab1<iframe>");
- yield loadURI(tabs[2], "data:text/plain;charset=utf-8,tab2");
- yield loadURI(tabs[3], "data:text/html;charset=utf-8,<title>tab3</title><body>tab3<iframe>");
- yield loadURI(tabs[4], "data:text/html;charset=utf-8,<body onload='clicks=0' onclick='++clicks'>"+embed);
- yield BrowserTestUtils.switchTab(gBrowser, tabs[3]);
-
- swapTabsAndCloseOther(2, 3); // now: 0 1 2 4
- is(gBrowser.tabs[1], tabs[1], "tab1");
- is(gBrowser.tabs[2], tabs[3], "tab3");
- is(gBrowser.tabs[3], tabs[4], "tab4");
- delete tabs[2];
-
- info("about to cacheObjectValue")
- yield cacheObjectValue(tabs[4].linkedBrowser);
- info("just finished cacheObjectValue")
-
- swapTabsAndCloseOther(3, 2); // now: 0 1 4
- is(Array.prototype.indexOf.call(gBrowser.tabs, gBrowser.selectedTab), 2,
- "The third tab should be selected");
- delete tabs[4];
-
-
- ok((yield checkObjectValue(gBrowser.tabs[2].linkedBrowser)), "same plugin instance");
-
- is(gBrowser.tabs[1], tabs[1], "tab1");
- is(gBrowser.tabs[2], tabs[3], "tab4");
-
- let clicks = yield getClicks(gBrowser.tabs[2]);
- is(clicks, 0, "no click on BODY so far");
- yield clickTest(gBrowser.tabs[2]);
-
- swapTabsAndCloseOther(2, 1); // now: 0 4
- is(gBrowser.tabs[1], tabs[1], "tab1");
- delete tabs[3];
-
- ok((yield checkObjectValue(gBrowser.tabs[1].linkedBrowser)), "same plugin instance");
- yield cleanupObjectValue(gBrowser.tabs[1].linkedBrowser);
-
- yield clickTest(gBrowser.tabs[1]);
-
- // Load a new document (about:blank) in tab4, then detach that tab into a new window.
- // In the new window, navigate back to the original document and click on its <body>,
- // verify that its onclick was called.
- is(Array.prototype.indexOf.call(gBrowser.tabs, gBrowser.selectedTab), 1,
- "The second tab should be selected");
- is(gBrowser.tabs[1], tabs[1],
- "The second tab in gBrowser.tabs should be equal to the second tab in our array");
- is(gBrowser.selectedTab, tabs[1],
- "The second tab in our array is the selected tab");
- yield loadURI(tabs[1], "about:blank");
- let key = tabs[1].linkedBrowser.permanentKey;
-
- let win = gBrowser.replaceTabWithWindow(tabs[1]);
- yield new Promise(resolve => whenDelayedStartupFinished(win, resolve));
- delete tabs[1];
-
- // Verify that the original window now only has the initial tab left in it.
- is(gBrowser.tabs[0], tabs[0], "tab0");
- is(gBrowser.tabs[0].linkedBrowser.currentURI.spec, "about:blank", "tab0 uri");
-
- let tab = win.gBrowser.tabs[0];
- is(tab.linkedBrowser.permanentKey, key, "Should have kept the key");
-
- let awaitPageShow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
- win.gBrowser.goBack();
- yield awaitPageShow;
-
- yield clickTest(tab);
- promiseWindowClosed(win);
-});
diff --git a/browser/base/content/test/general/browser_tab_dragdrop2.js b/browser/base/content/test/general/browser_tab_dragdrop2.js
deleted file mode 100644
index 2ab622d8b..000000000
--- a/browser/base/content/test/general/browser_tab_dragdrop2.js
+++ /dev/null
@@ -1,57 +0,0 @@
-"use strict";
-
-const ROOT = getRootDirectory(gTestPath);
-const URI = ROOT + "browser_tab_dragdrop2_frame1.xul";
-
-// Load the test page (which runs some child popup tests) in a new window.
-// After the tests were run, tear off the tab into a new window and run popup
-// tests a second time. We don't care about tests results, exceptions and
-// crashes will be caught.
-add_task(function* () {
- // Open a new window.
- let args = "chrome,all,dialog=no";
- let win = window.openDialog(getBrowserURL(), "_blank", args, URI);
-
- // Wait until the tests were run.
- yield promiseTestsDone(win);
- ok(true, "tests succeeded");
-
- // Create a second tab so that we can move the original one out.
- win.gBrowser.addTab("about:blank", {skipAnimation: true});
-
- // Tear off the original tab.
- let browser = win.gBrowser.selectedBrowser;
- let tabClosed = promiseWaitForEvent(browser, "pagehide", true);
- let win2 = win.gBrowser.replaceTabWithWindow(win.gBrowser.tabs[0]);
-
- // Add a 'TestsDone' event listener to ensure that the docShells is properly
- // swapped to the new window instead of the page being loaded again. If this
- // works fine we should *NOT* see a TestsDone event.
- let onTestsDone = () => ok(false, "shouldn't run tests when tearing off");
- win2.addEventListener("TestsDone", onTestsDone);
-
- // Wait until the original tab is gone and the new window is ready.
- yield Promise.all([tabClosed, promiseDelayedStartupFinished(win2)]);
-
- // Remove the 'TestsDone' event listener as now
- // we're kicking off a new test run manually.
- win2.removeEventListener("TestsDone", onTestsDone);
-
- // Run tests once again.
- let promise = promiseTestsDone(win2);
- win2.content.test_panels();
- yield promise;
- ok(true, "tests succeeded a second time");
-
- // Cleanup.
- yield promiseWindowClosed(win2);
- yield promiseWindowClosed(win);
-});
-
-function promiseTestsDone(win) {
- return promiseWaitForEvent(win, "TestsDone");
-}
-
-function promiseDelayedStartupFinished(win) {
- return new Promise(resolve => whenDelayedStartupFinished(win, resolve));
-}
diff --git a/browser/base/content/test/general/browser_tab_dragdrop2_frame1.xul b/browser/base/content/test/general/browser_tab_dragdrop2_frame1.xul
deleted file mode 100644
index d11709942..000000000
--- a/browser/base/content/test/general/browser_tab_dragdrop2_frame1.xul
+++ /dev/null
@@ -1,169 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<!--
- XUL Widget Test for panels
- -->
-<window title="Titlebar" width="200" height="200"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-
-<tree id="tree" seltype="single" width="100" height="100">
- <treecols>
- <treecol flex="1"/>
- <treecol flex="1"/>
- </treecols>
- <treechildren id="treechildren">
- <treeitem><treerow><treecell label="One"/><treecell label="Two"/></treerow></treeitem>
- <treeitem><treerow><treecell label="One"/><treecell label="Two"/></treerow></treeitem>
- <treeitem><treerow><treecell label="One"/><treecell label="Two"/></treerow></treeitem>
- <treeitem><treerow><treecell label="One"/><treecell label="Two"/></treerow></treeitem>
- <treeitem><treerow><treecell label="One"/><treecell label="Two"/></treerow></treeitem>
- <treeitem><treerow><treecell label="One"/><treecell label="Two"/></treerow></treeitem>
- </treechildren>
-</tree>
-
-
- <!-- test results are displayed in the html:body -->
- <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
-
- <!-- test code goes here -->
- <script type="application/javascript"><![CDATA[
-
-SimpleTest.waitForExplicitFinish();
-
-var currentTest = null;
-
-var i, waitSteps;
-var my_debug = false;
-function test_panels()
-{
- i = waitSteps = 0;
- checkTreeCoords();
-
- addEventListener("popupshown", popupShown, false);
- addEventListener("popuphidden", nextTest, false);
- return nextTest();
-}
-
-function nextTest()
-{
- ok(true,"popuphidden " + i)
- if (i == tests.length) {
- let details = {bubbles: true, cancelable: false};
- document.dispatchEvent(new CustomEvent("TestsDone", details));
- return i;
- }
-
- currentTest = tests[i];
- var panel = createPanel(currentTest.attrs);
- SimpleTest.waitForFocus(() => currentTest.test(panel));
- return i;
-}
-
-function popupShown(event)
-{
- var panel = event.target;
- if (waitSteps > 0 && navigator.platform.indexOf("Linux") >= 0 &&
- panel.boxObject.screenY == 210) {
- waitSteps--;
- setTimeout(popupShown, 10, event);
- return;
- }
- ++i;
-
- currentTest.result(currentTest.testname + " ", panel);
- panel.hidePopup();
-}
-
-function createPanel(attrs)
-{
- var panel = document.createElement("panel");
- for (var a in attrs) {
- panel.setAttribute(a, attrs[a]);
- }
-
- var button = document.createElement("button");
- panel.appendChild(button);
- button.label = "OK";
- button.width = 120;
- button.height = 40;
- button.setAttribute("style", "-moz-appearance: none; border: 0; margin: 0;");
- panel.setAttribute("style", "-moz-appearance: none; border: 0; margin: 0;");
- return document.documentElement.appendChild(panel);
-}
-
-function checkTreeCoords()
-{
- var tree = $("tree");
- var treechildren = $("treechildren");
- tree.currentIndex = 0;
- tree.treeBoxObject.scrollToRow(0);
- synthesizeMouse(treechildren, 10, tree.treeBoxObject.rowHeight + 2, { });
-
- tree.treeBoxObject.scrollToRow(2);
- synthesizeMouse(treechildren, 10, tree.treeBoxObject.rowHeight + 2, { });
-}
-
-var tests = [
- {
- testname: "normal panel",
- attrs: { },
- test: function(panel) {
- panel.openPopupAtScreen(200, 210);
- },
- result: function(testname, panel) {
- if (my_debug) alert(testname);
- var panelrect = panel.getBoundingClientRect();
- }
- },
- {
- // only noautohide panels support titlebars, so one shouldn't be shown here
- testname: "autohide panel with titlebar",
- attrs: { titlebar: "normal" },
- test: function(panel) {
- panel.openPopupAtScreen(200, 210);
- },
- result: function(testname, panel) {
- if (my_debug) alert(testname);
- var panelrect = panel.getBoundingClientRect();
- }
- },
- {
- testname: "noautohide panel with titlebar",
- attrs: { noautohide: true, titlebar: "normal" },
- test: function(panel) {
- waitSteps = 25;
- panel.openPopupAtScreen(200, 210);
- },
- result: function(testname, panel) {
- if (my_debug) alert(testname);
- var panelrect = panel.getBoundingClientRect();
-
- var gotMouseEvent = false;
- function mouseMoved(event)
- {
- gotMouseEvent = true;
- }
-
- panel.addEventListener("mousemove", mouseMoved, true);
- synthesizeMouse(panel, 10, 10, { type: "mousemove" });
- panel.removeEventListener("mousemove", mouseMoved, true);
-
- var tree = $("tree");
- tree.currentIndex = 0;
- panel.appendChild(tree);
- checkTreeCoords();
- }
- }
-];
-
-SimpleTest.waitForFocus(test_panels);
-
-]]>
-</script>
-
-</window>
diff --git a/browser/base/content/test/general/browser_tabbar_big_widgets.js b/browser/base/content/test/general/browser_tabbar_big_widgets.js
deleted file mode 100644
index 7a4c45138..000000000
--- a/browser/base/content/test/general/browser_tabbar_big_widgets.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const kButtonId = "test-tabbar-size-with-large-buttons";
-
-function test() {
- registerCleanupFunction(cleanup);
- let titlebar = document.getElementById("titlebar");
- let originalHeight = titlebar.getBoundingClientRect().height;
- let button = document.createElement("toolbarbutton");
- button.id = kButtonId;
- button.setAttribute("style", "min-height: 100px");
- gNavToolbox.palette.appendChild(button);
- CustomizableUI.addWidgetToArea(kButtonId, CustomizableUI.AREA_TABSTRIP);
- let currentHeight = titlebar.getBoundingClientRect().height;
- ok(currentHeight > originalHeight, "Titlebar should have grown");
- CustomizableUI.removeWidgetFromArea(kButtonId);
- currentHeight = titlebar.getBoundingClientRect().height;
- is(currentHeight, originalHeight, "Titlebar should have gone back to its original size.");
-}
-
-function cleanup() {
- let btn = document.getElementById(kButtonId);
- if (btn) {
- btn.remove();
- }
-}
-
diff --git a/browser/base/content/test/general/browser_tabfocus.js b/browser/base/content/test/general/browser_tabfocus.js
deleted file mode 100644
index 4042421e8..000000000
--- a/browser/base/content/test/general/browser_tabfocus.js
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * This test checks that focus is adjusted properly when switching tabs.
- */
-
-var testPage1 = "<html id='html1'><body id='body1'><button id='button1'>Tab 1</button></body></html>";
-var testPage2 = "<html id='html2'><body id='body2'><button id='button2'>Tab 2</button></body></html>";
-var testPage3 = "<html id='html3'><body id='body3'><button id='button3'>Tab 3</button></body></html>";
-
-const fm = Services.focus;
-
-function EventStore() {
- this["main-window"] = [];
- this["window1"] = [];
- this["window2"] = [];
-}
-
-EventStore.prototype = {
- "push": function (event) {
- if (event.indexOf("1") > -1) {
- this["window1"].push(event);
- } else if (event.indexOf("2") > -1) {
- this["window2"].push(event);
- } else {
- this["main-window"].push(event);
- }
- }
-}
-
-var tab1 = null;
-var tab2 = null;
-var browser1 = null;
-var browser2 = null;
-var _lastfocus;
-var _lastfocuswindow = null;
-var actualEvents = new EventStore();
-var expectedEvents = new EventStore();
-var currentTestName = "";
-var _expectedElement = null;
-var _expectedWindow = null;
-
-var currentPromiseResolver = null;
-
-function* getFocusedElementForBrowser(browser, dontCheckExtraFocus = false)
-{
- if (gMultiProcessBrowser) {
- return new Promise((resolve, reject) => {
- messageManager.addMessageListener("Browser:GetCurrentFocus", function getCurrentFocus(message) {
- messageManager.removeMessageListener("Browser:GetCurrentFocus", getCurrentFocus);
- resolve(message.data.details);
- });
-
- // The dontCheckExtraFocus flag is used to indicate not to check some
- // additional focus related properties. This is needed as both URLs are
- // loaded using the same child process and share focus managers.
- browser.messageManager.sendAsyncMessage("Browser:GetFocusedElement",
- { dontCheckExtraFocus : dontCheckExtraFocus });
- });
- }
- var focusedWindow = {};
- var node = fm.getFocusedElementForWindow(browser.contentWindow, false, focusedWindow);
- return "Focus is " + (node ? node.id : "<none>");
-}
-
-function focusInChild()
-{
- var contentFM = Components.classes["@mozilla.org/focus-manager;1"].
- getService(Components.interfaces.nsIFocusManager);
-
- function getWindowDocId(target)
- {
- return (String(target.location).indexOf("1") >= 0) ? "window1" : "window2";
- }
-
- function eventListener(event) {
- var id;
- if (event.target instanceof Components.interfaces.nsIDOMWindow)
- id = getWindowDocId(event.originalTarget) + "-window";
- else if (event.target instanceof Components.interfaces.nsIDOMDocument)
- id = getWindowDocId(event.originalTarget) + "-document";
- else
- id = event.originalTarget.id;
- sendSyncMessage("Browser:FocusChanged", { details : event.type + ": " + id });
- }
-
- addEventListener("focus", eventListener, true);
- addEventListener("blur", eventListener, true);
-
- addMessageListener("Browser:ChangeFocus", function changeFocus(message) {
- content.document.getElementById(message.data.id)[message.data.type]();
- });
-
- addMessageListener("Browser:GetFocusedElement", function getFocusedElement(message) {
- var focusedWindow = {};
- var node = contentFM.getFocusedElementForWindow(content, false, focusedWindow);
- var details = "Focus is " + (node ? node.id : "<none>");
-
- /* Check focus manager properties. Add an error onto the string if they are
- not what is expected which will cause matching to fail in the parent process. */
- let doc = content.document;
- if (!message.data.dontCheckExtraFocus) {
- if (contentFM.focusedElement != node) {
- details += "<ERROR: focusedElement doesn't match>";
- }
- if (contentFM.focusedWindow && contentFM.focusedWindow != content) {
- details += "<ERROR: focusedWindow doesn't match>";
- }
- if ((contentFM.focusedWindow == content) != doc.hasFocus()) {
- details += "<ERROR: child hasFocus() is not correct>";
- }
- if ((contentFM.focusedElement && doc.activeElement != contentFM.focusedElement) ||
- (!contentFM.focusedElement && doc.activeElement != doc.body)) {
- details += "<ERROR: child activeElement is not correct>";
- }
- }
-
- sendSyncMessage("Browser:GetCurrentFocus", { details : details });
- });
-}
-
-function focusElementInChild(elementid, type)
-{
- let browser = (elementid.indexOf("1") >= 0) ? browser1 : browser2;
- if (gMultiProcessBrowser) {
- browser.messageManager.sendAsyncMessage("Browser:ChangeFocus",
- { id: elementid, type: type });
- }
- else {
- browser.contentDocument.getElementById(elementid)[type]();
- }
-}
-
-add_task(function*() {
- tab1 = gBrowser.addTab();
- browser1 = gBrowser.getBrowserForTab(tab1);
-
- tab2 = gBrowser.addTab();
- browser2 = gBrowser.getBrowserForTab(tab2);
-
- yield promiseTabLoadEvent(tab1, "data:text/html," + escape(testPage1));
- yield promiseTabLoadEvent(tab2, "data:text/html," + escape(testPage2));
-
- var childFocusScript = "data:,(" + focusInChild.toString() + ")();";
- browser1.messageManager.loadFrameScript(childFocusScript, true);
- browser2.messageManager.loadFrameScript(childFocusScript, true);
-
- gURLBar.focus();
- yield SimpleTest.promiseFocus();
-
- if (gMultiProcessBrowser) {
- messageManager.addMessageListener("Browser:FocusChanged", message => {
- actualEvents.push(message.data.details);
- compareFocusResults();
- });
- }
-
- _lastfocus = "urlbar";
- _lastfocuswindow = "main-window";
-
- window.addEventListener("focus", _browser_tabfocus_test_eventOccured, true);
- window.addEventListener("blur", _browser_tabfocus_test_eventOccured, true);
-
- // make sure that the focus initially starts out blank
- var focusedWindow = {};
-
- let focused = yield getFocusedElementForBrowser(browser1);
- is(focused, "Focus is <none>", "initial focus in tab 1");
-
- focused = yield getFocusedElementForBrowser(browser2);
- is(focused, "Focus is <none>", "initial focus in tab 2");
-
- is(document.activeElement, gURLBar.inputField, "focus after loading two tabs");
-
- yield* expectFocusShiftAfterTabSwitch(tab2, "window2", null, true,
- "after tab change, focus in new tab");
-
- focused = yield getFocusedElementForBrowser(browser2);
- is(focused, "Focus is <none>", "focusedElement after tab change, focus in new tab");
-
- // switching tabs when nothing in the new tab is focused
- // should focus the browser
- yield* expectFocusShiftAfterTabSwitch(tab1, "window1", null, true,
- "after tab change, focus in original tab");
-
- focused = yield getFocusedElementForBrowser(browser1);
- is(focused, "Focus is <none>", "focusedElement after tab change, focus in original tab");
-
- // focusing a button in the current tab should focus it
- yield expectFocusShift(() => focusElementInChild("button1", "focus"),
- "window1", "button1", true,
- "after button focused");
-
- focused = yield getFocusedElementForBrowser(browser1);
- is(focused, "Focus is button1", "focusedElement in first browser after button focused");
-
- // focusing a button in a background tab should not change the actual
- // focus, but should set the focus that would be in that background tab to
- // that button.
- yield expectFocusShift(() => focusElementInChild("button2", "focus"),
- "window1", "button1", false,
- "after button focus in unfocused tab");
-
- focused = yield getFocusedElementForBrowser(browser1, false);
- is(focused, "Focus is button1", "focusedElement in first browser after button focus in unfocused tab");
- focused = yield getFocusedElementForBrowser(browser2, true);
- is(focused, "Focus is button2", "focusedElement in second browser after button focus in unfocused tab");
-
- // switching tabs should now make the button in the other tab focused
- yield* expectFocusShiftAfterTabSwitch(tab2, "window2", "button2", true,
- "after tab change with button focused");
-
- // blurring an element in a background tab should not change the active
- // focus, but should clear the focus in that tab.
- yield expectFocusShift(() => focusElementInChild("button1", "blur"),
- "window2", "button2", false,
- "focusedWindow after blur in unfocused tab");
-
- focused = yield getFocusedElementForBrowser(browser1, true);
- is(focused, "Focus is <none>", "focusedElement in first browser after focus in unfocused tab");
- focused = yield getFocusedElementForBrowser(browser2, false);
- is(focused, "Focus is button2", "focusedElement in second browser after focus in unfocused tab");
-
- // When focus is in the tab bar, it should be retained there
- yield expectFocusShift(() => gBrowser.selectedTab.focus(),
- "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);
- executeSoon(resolve);
- });
- });
- }
-
- 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.
- // Otherwise, the _adjustFocusAfterTabSwitch in tabbrowser gets confused and
- // isn't sure what tab is really focused.
- if (gMultiProcessBrowser) {
- yield switchWaiter;
- }
-
- yield expectFocusShift(() => gBrowser.selectedTab.blur(),
- "main-window", null, true,
- "blurring tab element");
-
- // focusing the url field should switch active focus away from the browser but
- // not clear what would be the focus in the browser
- focusElementInChild("button1", "focus");
-
- yield expectFocusShift(() => gURLBar.focus(),
- "main-window", "urlbar", true,
- "focusedWindow after url field focused");
- focused = yield getFocusedElementForBrowser(browser1, true);
- is(focused, "Focus is button1", "focusedElement after url field focused, first browser");
- focused = yield getFocusedElementForBrowser(browser2, true);
- is(focused, "Focus is button2", "focusedElement after url field focused, second browser");
-
- yield expectFocusShift(() => gURLBar.blur(),
- "main-window", null, true,
- "blurring url field");
-
- // when a chrome element is focused, switching tabs to a tab with a button
- // with the current focus should focus the button
- yield* expectFocusShiftAfterTabSwitch(tab1, "window1", "button1", true,
- "after tab change, focus in url field, button focused in new tab");
-
- focused = yield getFocusedElementForBrowser(browser1, false);
- is(focused, "Focus is button1", "after switch tab, focus in unfocused tab, first browser");
- focused = yield getFocusedElementForBrowser(browser2, true);
- is(focused, "Focus is button2", "after switch tab, focus in unfocused tab, second browser");
-
- // blurring an element in the current tab should clear the active focus
- yield expectFocusShift(() => focusElementInChild("button1", "blur"),
- "window1", null, true,
- "after blur in focused tab");
-
- focused = yield getFocusedElementForBrowser(browser1, false);
- is(focused, "Focus is <none>", "focusedWindow after blur in focused tab, child");
- focusedWindow = {};
- is(fm.getFocusedElementForWindow(window, false, focusedWindow), browser1, "focusedElement after blur in focused tab, parent");
-
- // blurring an non-focused url field should have no effect
- yield expectFocusShift(() => gURLBar.blur(),
- "window1", null, false,
- "after blur in unfocused url field");
-
- focusedWindow = {};
- is(fm.getFocusedElementForWindow(window, false, focusedWindow), browser1, "focusedElement after blur in unfocused url field");
-
- // switch focus to a tab with a currently focused element
- yield* expectFocusShiftAfterTabSwitch(tab2, "window2", "button2", true,
- "after switch from unfocused to focused tab");
- focused = yield getFocusedElementForBrowser(browser2, true);
- is(focused, "Focus is button2", "focusedElement after switch from unfocused to focused tab");
-
- // clearing focus on the chrome window should switch the focus to the
- // chrome window
- yield expectFocusShift(() => fm.clearFocus(window),
- "main-window", null, true,
- "after switch to chrome with no focused element");
-
- focusedWindow = {};
- is(fm.getFocusedElementForWindow(window, false, focusedWindow), null, "focusedElement after switch to chrome with no focused element");
-
- // switch focus to another tab when neither have an active focus
- yield* expectFocusShiftAfterTabSwitch(tab1, "window1", null, true,
- "focusedWindow after tab switch from no focus to no focus");
-
- focused = yield getFocusedElementForBrowser(browser1, false);
- is(focused, "Focus is <none>", "after tab switch from no focus to no focus, first browser");
- focused = yield getFocusedElementForBrowser(browser2, true);
- is(focused, "Focus is button2", "after tab switch from no focus to no focus, second browser");
-
- // next, check whether navigating forward, focusing the urlbar and then
- // navigating back maintains the focus in the urlbar.
- yield expectFocusShift(() => focusElementInChild("button1", "focus"),
- "window1", "button1", true,
- "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);
- resolve();
- }, 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();
- actualEvents = new EventStore();
- _lastfocus = "urlbar";
- _lastfocuswindow = "main-window";
-
- yield expectFocusShift(() => EventUtils.synthesizeKey("VK_F6", { }),
- "window1", "html1",
- true, "switch document forward with f6");
-
- EventUtils.synthesizeKey("VK_F6", { });
- is(fm.focusedWindow, window, "switch document forward again with f6");
-
- browser1.style.MozUserFocus = "ignore";
- browser1.clientWidth;
- EventUtils.synthesizeKey("VK_F6", { });
- is(fm.focusedWindow, window, "switch document forward again with f6 when browser non-focusable");
-
- browser1.style.MozUserFocus = "normal";
- browser1.clientWidth;
- }
-
- window.removeEventListener("focus", _browser_tabfocus_test_eventOccured, true);
- window.removeEventListener("blur", _browser_tabfocus_test_eventOccured, true);
-
- gBrowser.removeCurrentTab();
- gBrowser.removeCurrentTab();
-
- finish();
-});
-
-function _browser_tabfocus_test_eventOccured(event)
-{
- function getWindowDocId(target)
- {
- if (target == browser1.contentWindow || target == browser1.contentDocument) {
- return "window1";
- }
- if (target == browser2.contentWindow || target == browser2.contentDocument) {
- return "window2";
- }
- return "main-window";
- }
-
- var id;
-
- // Some focus events from the child bubble up? Ignore them.
- if (Cu.isCrossProcessWrapper(event.originalTarget))
- return;
-
- if (event.target instanceof Window)
- id = getWindowDocId(event.originalTarget) + "-window";
- else if (event.target instanceof Document)
- id = getWindowDocId(event.originalTarget) + "-document";
- else if (event.target.id == "urlbar" && event.originalTarget.localName == "input")
- id = "urlbar";
- else if (event.originalTarget.localName == "browser")
- id = (event.originalTarget == browser1) ? "browser1" : "browser2";
- else if (event.originalTarget.localName == "tab")
- id = (event.originalTarget == tab1) ? "tab1" : "tab2";
- else
- id = event.originalTarget.id;
-
- actualEvents.push(event.type + ": " + id);
- compareFocusResults();
-}
-
-function getId(element)
-{
- if (!element) {
- return null;
- }
-
- if (element.localName == "browser") {
- return element == browser1 ? "browser1" : "browser2";
- }
-
- if (element.localName == "tab") {
- return element == tab1 ? "tab1" : "tab2";
- }
-
- return (element.localName == "input") ? "urlbar" : element.id;
-}
-
-function compareFocusResults()
-{
- if (!currentPromiseResolver)
- return;
-
- let winIds = ["main-window", "window1", "window2"];
-
- for (let winId of winIds) {
- if (actualEvents[winId].length < expectedEvents[winId].length)
- return;
- }
-
- for (let winId of winIds) {
- for (let e = 0; e < expectedEvents.length; e++) {
- is(actualEvents[winId][e], expectedEvents[winId][e], currentTestName + " events [event " + e + "]");
- }
- actualEvents[winId] = [];
- }
-
- // Use executeSoon as this will be called during a focus/blur event handler
- executeSoon(() => {
- let matchWindow = window;
- if (gMultiProcessBrowser) {
- is(_expectedWindow, "main-window", "main-window is always expected");
- }
- else if (_expectedWindow != "main-window") {
- matchWindow = (_expectedWindow == "window1" ? browser1.contentWindow : browser2.contentWindow);
- }
-
- var focusedElement = fm.focusedElement;
- is(getId(focusedElement), _expectedElement, currentTestName + " focusedElement");
- is(fm.focusedWindow, matchWindow, currentTestName + " focusedWindow");
- var focusedWindow = {};
- is(getId(fm.getFocusedElementForWindow(matchWindow, false, focusedWindow)),
- _expectedElement, currentTestName + " getFocusedElementForWindow");
- is(focusedWindow.value, matchWindow, currentTestName + " getFocusedElementForWindow frame");
- is(matchWindow.document.hasFocus(), true, currentTestName + " hasFocus");
- var expectedActive = _expectedElement;
- if (!expectedActive) {
- expectedActive = matchWindow.document instanceof XULDocument ?
- "main-window" : getId(matchWindow.document.body);
- }
- is(getId(matchWindow.document.activeElement), expectedActive, currentTestName + " activeElement");
-
- currentPromiseResolver();
- currentPromiseResolver = null;
- });
-}
-
-function* expectFocusShiftAfterTabSwitch(tab, expectedWindow, expectedElement, focusChanged, testid)
-{
- let tabSwitchPromise = null;
- yield expectFocusShift(() => { tabSwitchPromise = BrowserTestUtils.switchTab(gBrowser, tab) },
- expectedWindow, expectedElement, focusChanged, testid)
- yield tabSwitchPromise;
-}
-
-function* expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid)
-{
- currentPromiseResolver = null;
- currentTestName = testid;
-
- expectedEvents = new EventStore();
-
- if (focusChanged) {
- _expectedElement = expectedElement;
- _expectedWindow = expectedWindow;
-
- // When the content is in a child process, the expected element in the chrome window
- // will always be the urlbar or a browser element.
- if (gMultiProcessBrowser) {
- if (_expectedWindow == "window1") {
- _expectedElement = "browser1";
- }
- else if (_expectedWindow == "window2") {
- _expectedElement = "browser2";
- }
- _expectedWindow = "main-window";
- }
-
- if (gMultiProcessBrowser && _lastfocuswindow != "main-window" &&
- _lastfocuswindow != expectedWindow) {
- let browserid = _lastfocuswindow == "window1" ? "browser1" : "browser2";
- expectedEvents.push("blur: " + browserid);
- }
-
- var newElementIsFocused = (expectedElement && !expectedElement.startsWith("html"));
- if (newElementIsFocused && gMultiProcessBrowser &&
- _lastfocuswindow != "main-window" &&
- expectedWindow == "main-window") {
- // When switching from a child to a chrome element, the focus on the element will arrive first.
- expectedEvents.push("focus: " + expectedElement);
- newElementIsFocused = false;
- }
-
- if (_lastfocus && _lastfocus != _expectedElement)
- expectedEvents.push("blur: " + _lastfocus);
-
- if (_lastfocuswindow &&
- _lastfocuswindow != expectedWindow) {
-
- if (!gMultiProcessBrowser || _lastfocuswindow != "main-window") {
- expectedEvents.push("blur: " + _lastfocuswindow + "-document");
- expectedEvents.push("blur: " + _lastfocuswindow + "-window");
- }
- }
-
- if (expectedWindow && _lastfocuswindow != expectedWindow) {
- if (gMultiProcessBrowser && expectedWindow != "main-window") {
- let browserid = expectedWindow == "window1" ? "browser1" : "browser2";
- expectedEvents.push("focus: " + browserid);
- }
-
- if (!gMultiProcessBrowser || expectedWindow != "main-window") {
- expectedEvents.push("focus: " + expectedWindow + "-document");
- expectedEvents.push("focus: " + expectedWindow + "-window");
- }
- }
-
- if (newElementIsFocused) {
- expectedEvents.push("focus: " + expectedElement);
- }
-
- _lastfocus = expectedElement;
- _lastfocuswindow = expectedWindow;
- }
-
- return new Promise((resolve, reject) => {
- currentPromiseResolver = resolve;
- callback();
-
- // No events are expected, so resolve the promise immediately.
- if (expectedEvents["main-window"].length + expectedEvents["window1"].length + expectedEvents["window2"].length == 0) {
- currentPromiseResolver();
- currentPromiseResolver = null;
- }
- });
-}
diff --git a/browser/base/content/test/general/browser_tabkeynavigation.js b/browser/base/content/test/general/browser_tabkeynavigation.js
deleted file mode 100644
index d8e51f4b9..000000000
--- a/browser/base/content/test/general/browser_tabkeynavigation.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * This test checks that keyboard navigation for tabs isn't blocked by content
- */
-add_task(function* test() {
-
- let testPage1 = "data:text/html,<html id='tab1'><body><button id='button1'>Tab 1</button></body></html>";
- let testPage2 = "data:text/html,<html id='tab2'><body><button id='button2'>Tab 2</button><script>function preventDefault(event) { event.preventDefault(); event.stopImmediatePropagation(); } window.addEventListener('keydown', preventDefault, true); window.addEventListener('keypress', preventDefault, true);</script></body></html>";
- let testPage3 = "data:text/html,<html id='tab3'><body><button id='button3'>Tab 3</button></body></html>";
-
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage1);
- let browser1 = gBrowser.getBrowserForTab(tab1);
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2);
- let tab3 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage3);
-
- // Kill the animation for simpler test.
- Services.prefs.setBoolPref("browser.tabs.animate", false);
-
- gBrowser.selectedTab = tab1;
- browser1.focus();
-
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated");
- EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+Tab on Tab1");
-
- EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true });
- is(gBrowser.selectedTab, tab3,
- "Tab3 should be activated by pressing Ctrl+Tab on Tab2");
-
- EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+Shift+Tab on Tab3");
-
- EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: true });
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated by pressing Ctrl+Shift+Tab on Tab2");
-
- gBrowser.selectedTab = tab1;
- browser1.focus();
-
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated");
- EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+PageDown on Tab1");
-
- EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true });
- is(gBrowser.selectedTab, tab3,
- "Tab3 should be activated by pressing Ctrl+PageDown on Tab2");
-
- EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+PageUp on Tab3");
-
- EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true });
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated by pressing Ctrl+PageUp on Tab2");
-
- if (gBrowser.mTabBox._handleMetaAltArrows) {
- gBrowser.selectedTab = tab1;
- browser1.focus();
-
- let ltr = window.getComputedStyle(gBrowser.mTabBox, "").direction == "ltr";
- let advanceKey = ltr ? "VK_RIGHT" : "VK_LEFT";
- let reverseKey = ltr ? "VK_LEFT" : "VK_RIGHT";
-
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated");
- EventUtils.synthesizeKey(advanceKey, { altKey: true, metaKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+" + advanceKey + " on Tab1");
-
- EventUtils.synthesizeKey(advanceKey, { altKey: true, metaKey: true });
- is(gBrowser.selectedTab, tab3,
- "Tab3 should be activated by pressing Ctrl+" + advanceKey + " on Tab2");
-
- EventUtils.synthesizeKey(reverseKey, { altKey: true, metaKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+" + reverseKey + " on Tab3");
-
- EventUtils.synthesizeKey(reverseKey, { altKey: true, metaKey: true });
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated by pressing Ctrl+" + reverseKey + " on Tab2");
- }
-
- gBrowser.selectedTab = tab2;
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated");
- is(gBrowser.tabContainer.selectedIndex, 2,
- "Tab2 index should be 2");
-
- EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true, shiftKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated after Ctrl+Shift+PageDown");
- is(gBrowser.tabContainer.selectedIndex, 3,
- "Tab2 index should be 1 after Ctrl+Shift+PageDown");
-
- EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true, shiftKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated after Ctrl+Shift+PageUp");
- is(gBrowser.tabContainer.selectedIndex, 2,
- "Tab2 index should be 2 after Ctrl+Shift+PageUp");
-
- if (navigator.platform.indexOf("Mac") == 0) {
- gBrowser.selectedTab = tab1;
- browser1.focus();
-
- // XXX Currently, Command + "{" and "}" don't work if keydown event is
- // consumed because following keypress event isn't fired.
-
- let ltr = window.getComputedStyle(gBrowser.mTabBox, "").direction == "ltr";
- let advanceKey = ltr ? "}" : "{";
- let reverseKey = ltr ? "{" : "}";
-
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated");
-
- EventUtils.synthesizeKey(advanceKey, { metaKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+" + advanceKey + " on Tab1");
-
- EventUtils.synthesizeKey(advanceKey, { metaKey: true });
- is(gBrowser.selectedTab, tab3,
- "Tab3 should be activated by pressing Ctrl+" + advanceKey + " on Tab2");
-
- EventUtils.synthesizeKey(reverseKey, { metaKey: true });
- is(gBrowser.selectedTab, tab2,
- "Tab2 should be activated by pressing Ctrl+" + reverseKey + " on Tab3");
-
- EventUtils.synthesizeKey(reverseKey, { metaKey: true });
- is(gBrowser.selectedTab, tab1,
- "Tab1 should be activated by pressing Ctrl+" + reverseKey + " on Tab2");
- } else {
- gBrowser.selectedTab = tab2;
- EventUtils.synthesizeKey("VK_F4", { type: "keydown", ctrlKey: true });
-
- isnot(gBrowser.selectedTab, tab2,
- "Tab2 should be closed by pressing Ctrl+F4 on Tab2");
- is(gBrowser.tabs.length, 3,
- "The count of tabs should be 3 since tab2 should be closed");
-
- // NOTE: keypress event shouldn't be fired since the keydown event should
- // be consumed by tab2.
- EventUtils.synthesizeKey("VK_F4", { type: "keyup", ctrlKey: true });
- is(gBrowser.tabs.length, 3,
- "The count of tabs should be 3 since renaming key events shouldn't close other tabs");
- }
-
- gBrowser.selectedTab = tab3;
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-
- Services.prefs.clearUserPref("browser.tabs.animate");
-});
diff --git a/browser/base/content/test/general/browser_tabopen_reflows.js b/browser/base/content/test/general/browser_tabopen_reflows.js
deleted file mode 100644
index 8e04cf12e..000000000
--- a/browser/base/content/test/general/browser_tabopen_reflows.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-XPCOMUtils.defineLazyGetter(this, "docShell", () => {
- return window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
-});
-
-const EXPECTED_REFLOWS = [
- // tabbrowser.adjustTabstrip() call after tabopen animation has finished
- "adjustTabstrip@chrome://browser/content/tabbrowser.xml|" +
- "_handleNewTab@chrome://browser/content/tabbrowser.xml|" +
- "onxbltransitionend@chrome://browser/content/tabbrowser.xml|",
-
- // switching focus in updateCurrentBrowser() causes reflows
- "_adjustFocusAfterTabSwitch@chrome://browser/content/tabbrowser.xml|" +
- "updateCurrentBrowser@chrome://browser/content/tabbrowser.xml|" +
- "onselect@chrome://browser/content/browser.xul|",
-
- // switching focus in openLinkIn() causes reflows
- "openLinkIn@chrome://browser/content/utilityOverlay.js|" +
- "openUILinkIn@chrome://browser/content/utilityOverlay.js|" +
- "BrowserOpenTab@chrome://browser/content/browser.js|",
-
- // accessing element.scrollPosition in _fillTrailingGap() flushes layout
- "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml|" +
- "_fillTrailingGap@chrome://browser/content/tabbrowser.xml|" +
- "_handleNewTab@chrome://browser/content/tabbrowser.xml|" +
- "onxbltransitionend@chrome://browser/content/tabbrowser.xml|",
-
- // SessionStore.getWindowDimensions()
- "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm|" +
- "ssi_updateWindowFeatures/<@resource:///modules/sessionstore/SessionStore.jsm|" +
- "ssi_updateWindowFeatures@resource:///modules/sessionstore/SessionStore.jsm|" +
- "ssi_collectWindowData@resource:///modules/sessionstore/SessionStore.jsm|",
-
- // selection change notification may cause querying the focused editor content
- // by IME and that will cause reflow.
- "select@chrome://global/content/bindings/textbox.xml|" +
- "focusAndSelectUrlBar@chrome://browser/content/browser.js|" +
- "openLinkIn@chrome://browser/content/utilityOverlay.js|" +
- "openUILinkIn@chrome://browser/content/utilityOverlay.js|" +
- "BrowserOpenTab@chrome://browser/content/browser.js|",
-
-];
-
-const PREF_PRELOAD = "browser.newtab.preload";
-const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directory.source";
-
-/*
- * This test ensures that there are no unexpected
- * uninterruptible reflows when opening new tabs.
- */
-add_task(function*() {
- let DirectoryLinksProvider = Cu.import("resource:///modules/DirectoryLinksProvider.jsm", {}).DirectoryLinksProvider;
- let NewTabUtils = Cu.import("resource://gre/modules/NewTabUtils.jsm", {}).NewTabUtils;
- let Promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
-
- // resolves promise when directory links are downloaded and written to disk
- function watchLinksChangeOnce() {
- let deferred = Promise.defer();
- let observer = {
- onManyLinksChanged: () => {
- DirectoryLinksProvider.removeObserver(observer);
- NewTabUtils.links.populateCache(() => {
- NewTabUtils.allPages.update();
- deferred.resolve();
- }, true);
- }
- };
- observer.onDownloadFail = observer.onManyLinksChanged;
- DirectoryLinksProvider.addObserver(observer);
- return deferred.promise;
- }
-
- let gOrigDirectorySource = Services.prefs.getCharPref(PREF_NEWTAB_DIRECTORYSOURCE);
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref(PREF_PRELOAD);
- Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, gOrigDirectorySource);
- return watchLinksChangeOnce();
- });
-
- Services.prefs.setBoolPref(PREF_PRELOAD, false);
- // set directory source to dummy/empty links
- Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, 'data:application/json,{"test":1}');
-
- // run tests when directory source change completes
- yield watchLinksChangeOnce();
-
- // Perform a click in the top left of content to ensure the mouse isn't
- // hovering over any of the tiles
- let target = gBrowser.selectedBrowser;
- let rect = target.getBoundingClientRect();
- let left = rect.left + 1;
- let top = rect.top + 1;
-
- let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
-
- // Add a reflow observer and open a new tab.
- docShell.addWeakReflowObserver(observer);
- BrowserOpenTab();
-
- // Wait until the tabopen animation has finished.
- yield waitForTransitionEnd();
-
- // Remove reflow observer and clean up.
- docShell.removeWeakReflowObserver(observer);
- gBrowser.removeCurrentTab();
-});
-
-var observer = {
- reflow: function (start, end) {
- // Gather information about the current code path.
- let path = (new Error().stack).split("\n").slice(1).map(line => {
- return line.replace(/:\d+:\d+$/, "");
- }).join("|");
- let pathWithLineNumbers = (new Error().stack).split("\n").slice(1).join("|");
-
- // Stack trace is empty. Reflow was triggered by native code.
- if (path === "") {
- return;
- }
-
- // Check if this is an expected reflow.
- for (let stack of EXPECTED_REFLOWS) {
- if (path.startsWith(stack)) {
- ok(true, "expected uninterruptible reflow '" + stack + "'");
- return;
- }
- }
-
- ok(false, "unexpected uninterruptible reflow '" + pathWithLineNumbers + "'");
- },
-
- reflowInterruptible: function (start, end) {
- // We're not interested in interruptible reflows.
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
- Ci.nsISupportsWeakReference])
-};
-
-function waitForTransitionEnd() {
- return new Promise(resolve => {
- let tab = gBrowser.selectedTab;
- tab.addEventListener("transitionend", function onEnd(event) {
- if (event.propertyName === "max-width") {
- tab.removeEventListener("transitionend", onEnd);
- resolve();
- }
- });
- });
-}
diff --git a/browser/base/content/test/general/browser_tabs_close_beforeunload.js b/browser/base/content/test/general/browser_tabs_close_beforeunload.js
deleted file mode 100644
index b867efd72..000000000
--- a/browser/base/content/test/general/browser_tabs_close_beforeunload.js
+++ /dev/null
@@ -1,49 +0,0 @@
-"use strict";
-
-SimpleTest.requestCompleteLog();
-
-SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
-
-const FIRST_TAB = getRootDirectory(gTestPath) + "close_beforeunload_opens_second_tab.html";
-const SECOND_TAB = getRootDirectory(gTestPath) + "close_beforeunload.html";
-
-add_task(function*() {
- info("Opening first tab");
- let firstTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, FIRST_TAB);
- let secondTabLoadedPromise;
- let secondTab;
- let tabOpened = new Promise(resolve => {
- info("Adding tabopen listener");
- gBrowser.tabContainer.addEventListener("TabOpen", function tabOpenListener(e) {
- info("Got tabopen, removing listener and waiting for load");
- gBrowser.tabContainer.removeEventListener("TabOpen", tabOpenListener, false, false);
- secondTab = e.target;
- secondTabLoadedPromise = BrowserTestUtils.browserLoaded(secondTab.linkedBrowser, false, SECOND_TAB);
- resolve();
- }, false, false);
- });
- info("Opening second tab using a click");
- yield ContentTask.spawn(firstTab.linkedBrowser, "", function*() {
- content.document.getElementsByTagName("a")[0].click();
- });
- info("Waiting for the second tab to be opened");
- yield tabOpened;
- info("Waiting for the load in that tab to finish");
- yield secondTabLoadedPromise;
-
- let closeBtn = document.getAnonymousElementByAttribute(secondTab, "anonid", "close-button");
- let closePromise = BrowserTestUtils.removeTab(secondTab, {dontRemove: true});
- info("closing second tab (which will self-close in beforeunload)");
- closeBtn.click();
- ok(secondTab.closing, "Second tab should be marked as closing synchronously.");
- yield closePromise;
- ok(secondTab.closing, "Second tab should still be marked as closing");
- ok(!secondTab.linkedBrowser, "Second tab's browser should be dead");
- ok(!firstTab.closing, "First tab should not be closing");
- ok(firstTab.linkedBrowser, "First tab's browser should be alive");
- info("closing first tab");
- yield BrowserTestUtils.removeTab(firstTab);
-
- ok(firstTab.closing, "First tab should be marked as closing");
- ok(!firstTab.linkedBrowser, "First tab's browser should be dead");
-});
diff --git a/browser/base/content/test/general/browser_tabs_isActive.js b/browser/base/content/test/general/browser_tabs_isActive.js
deleted file mode 100644
index 0725757e7..000000000
--- a/browser/base/content/test/general/browser_tabs_isActive.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- 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);
- executeSoon(resolve);
- });
- });
-}
-
-function getParentTabState(aTab) {
- return aTab.linkedBrowser.docShellIsActive;
-}
-
-function getChildTabState(aTab) {
- return ContentTask.spawn(aTab.linkedBrowser, {}, function* () {
- return docShell.isActive;
- });
-}
-
-function checkState(parentSide, childSide, value, message) {
- is(parentSide, value, message + " (parent side)");
- is(childSide, value, message + " (child side)");
-}
-
-function waitForMs(aMs) {
- return new Promise((resolve) => {
- setTimeout(done, aMs);
- function done() {
- resolve(true);
- }
- });
-}
-
-add_task(function *() {
- let url = kTestPage;
- let originalTab = gBrowser.selectedTab; // test tab
- let newTab = gBrowser.addTab(url, {skipAnimation: true});
- let parentSide, childSide;
-
- // new tab added but not selected checks
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, false, "newly added " + url + " tab is not active");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, true, "original tab is active initially");
-
- // select the newly added tab and wait for TabSwitchDone event
- let tabSwitchedPromise = promiseNewTabSwitched();
- gBrowser.selectedTab = newTab;
- yield tabSwitchedPromise;
-
- if (Services.appinfo.browserTabsRemoteAutostart) {
- ok(newTab.linkedBrowser.isRemoteBrowser, "for testing we need a remote tab");
- }
-
- // check active state of both tabs
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, true, "newly added " + url + " tab is active after selection");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, false, "original tab is not active while unselected");
-
- // switch back to the original test tab and wait for TabSwitchDone event
- tabSwitchedPromise = promiseNewTabSwitched();
- gBrowser.selectedTab = originalTab;
- yield tabSwitchedPromise;
-
- // check active state of both tabs
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, false, "newly added " + url + " tab is not active after switch back");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, true, "original tab is active again after switch back");
-
- // switch to the new tab and wait for TabSwitchDone event
- tabSwitchedPromise = promiseNewTabSwitched();
- gBrowser.selectedTab = newTab;
- yield tabSwitchedPromise;
-
- // check active state of both tabs
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, true, "newly added " + url + " tab is not active after switch back");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, false, "original tab is active again after switch back");
-
- gBrowser.removeTab(newTab);
-});
-
-add_task(function *() {
- let url = "about:about";
- let originalTab = gBrowser.selectedTab; // test tab
- let newTab = gBrowser.addTab(url, {skipAnimation: true});
- let parentSide, childSide;
-
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, false, "newly added " + url + " tab is not active");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, true, "original tab is active initially");
-
- let tabSwitchedPromise = promiseNewTabSwitched();
- gBrowser.selectedTab = newTab;
- yield tabSwitchedPromise;
-
- if (Services.appinfo.browserTabsRemoteAutostart) {
- ok(!newTab.linkedBrowser.isRemoteBrowser, "for testing we need a local tab");
- }
-
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, true, "newly added " + url + " tab is active after selection");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, false, "original tab is not active while unselected");
-
- tabSwitchedPromise = promiseNewTabSwitched();
- gBrowser.selectedTab = originalTab;
- yield tabSwitchedPromise;
-
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, false, "newly added " + url + " tab is not active after switch back");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, true, "original tab is active again after switch back");
-
- tabSwitchedPromise = promiseNewTabSwitched();
- gBrowser.selectedTab = newTab;
- yield tabSwitchedPromise;
-
- parentSide = getParentTabState(newTab);
- childSide = yield getChildTabState(newTab);
- checkState(parentSide, childSide, true, "newly added " + url + " tab is not active after switch back");
- parentSide = getParentTabState(originalTab);
- childSide = yield getChildTabState(originalTab);
- checkState(parentSide, childSide, false, "original tab is active again after switch back");
-
- gBrowser.removeTab(newTab);
-});
diff --git a/browser/base/content/test/general/browser_tabs_owner.js b/browser/base/content/test/general/browser_tabs_owner.js
deleted file mode 100644
index 300d783ba..000000000
--- a/browser/base/content/test/general/browser_tabs_owner.js
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: gBrowser._finalizeTabSwitch is not a function");
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: gBrowser._finalizeTabSwitch is not a function");
-
-function test() {
- gBrowser.addTab();
- gBrowser.addTab();
- gBrowser.addTab();
-
- var tabs = gBrowser.tabs;
- var owner;
-
- is(tabs.length, 4, "4 tabs are open");
-
- owner = gBrowser.selectedTab = tabs[2];
- BrowserOpenTab();
- is(gBrowser.selectedTab, tabs[4], "newly opened tab is selected");
- gBrowser.removeCurrentTab();
- is(gBrowser.selectedTab, owner, "owner is selected");
-
- owner = gBrowser.selectedTab;
- BrowserOpenTab();
- gBrowser.selectedTab = tabs[1];
- gBrowser.selectedTab = tabs[4];
- gBrowser.removeCurrentTab();
- isnot(gBrowser.selectedTab, owner, "selecting a different tab clears the owner relation");
-
- owner = gBrowser.selectedTab;
- BrowserOpenTab();
- gBrowser.moveTabTo(gBrowser.selectedTab, 0);
- gBrowser.removeCurrentTab();
- is(gBrowser.selectedTab, owner, "owner relatitionship persists when tab is moved");
-
- while (tabs.length > 1)
- gBrowser.removeCurrentTab();
-}
diff --git a/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js b/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
deleted file mode 100644
index f90f047d3..000000000
--- a/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const OPEN_LOCATION_PREF = "browser.link.open_newwindow";
-const NON_REMOTE_PAGE = "about:welcomeback";
-
-Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
-
-requestLongerTimeout(2);
-
-function frame_script() {
- content.document.body.innerHTML = `
- <a href="about:home" target="_blank" id="testAnchor">Open a window</a>
- `;
-
- let element = content.document.getElementById("testAnchor");
- element.click();
-}
-
-/**
- * Takes some browser in some window, and forces that browser
- * to become non-remote, and then navigates it to a page that
- * we're not supposed to be displaying remotely. Returns a
- * Promise that resolves when the browser is no longer remote.
- */
-function prepareNonRemoteBrowser(aWindow, browser) {
- browser.loadURI(NON_REMOTE_PAGE);
- return BrowserTestUtils.browserLoaded(browser);
-}
-
-registerCleanupFunction(() => {
- Services.prefs.clearUserPref(OPEN_LOCATION_PREF);
-});
-
-/**
- * Test that if we open a new tab from a link in a non-remote
- * browser in an e10s window, that the new tab will load properly.
- */
-add_task(function* test_new_tab() {
- let normalWindow = yield BrowserTestUtils.openNewBrowserWindow({
- remote: true,
- });
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({
- remote: true,
- private: true,
- });
-
- for (let testWindow of [normalWindow, privateWindow]) {
- yield promiseWaitForFocus(testWindow);
- let testBrowser = testWindow.gBrowser.selectedBrowser;
- info("Preparing non-remote browser");
- yield prepareNonRemoteBrowser(testWindow, testBrowser);
- info("Non-remote browser prepared - sending frame script");
-
- // Get our framescript ready
- let mm = testBrowser.messageManager;
- mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
-
- let tabOpenEvent = yield waitForNewTabEvent(testWindow.gBrowser);
- let newTab = tabOpenEvent.target;
-
- yield promiseTabLoadEvent(newTab);
-
- // Our framescript opens to about:home which means that the
- // tab should eventually become remote.
- ok(newTab.linkedBrowser.isRemoteBrowser,
- "The opened browser never became remote.");
-
- testWindow.gBrowser.removeTab(newTab);
- }
-
- normalWindow.close();
- privateWindow.close();
-});
-
-/**
- * Test that if we open a new window from a link in a non-remote
- * browser in an e10s window, that the new window is not an e10s
- * window. Also tests with a private browsing window.
- */
-add_task(function* test_new_window() {
- let normalWindow = yield BrowserTestUtils.openNewBrowserWindow({
- remote: true
- }, true);
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({
- remote: true,
- private: true,
- }, true);
-
- // Fiddle with the prefs so that we open target="_blank" links
- // in new windows instead of new tabs.
- Services.prefs.setIntPref(OPEN_LOCATION_PREF,
- Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW);
-
- for (let testWindow of [normalWindow, privateWindow]) {
- yield promiseWaitForFocus(testWindow);
- let testBrowser = testWindow.gBrowser.selectedBrowser;
- yield prepareNonRemoteBrowser(testWindow, testBrowser);
-
- // Get our framescript ready
- let mm = testBrowser.messageManager;
- mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
-
- // Click on the link in the browser, and wait for the new window.
- let {subject: newWindow} =
- yield promiseTopicObserved("browser-delayed-startup-finished");
-
- is(PrivateBrowsingUtils.isWindowPrivate(testWindow),
- PrivateBrowsingUtils.isWindowPrivate(newWindow),
- "Private browsing state of new window does not match the original!");
-
- let newTab = newWindow.gBrowser.selectedTab;
-
- yield promiseTabLoadEvent(newTab);
-
- // Our framescript opens to about:home which means that the
- // tab should eventually become remote.
- ok(newTab.linkedBrowser.isRemoteBrowser,
- "The opened browser never became remote.");
- newWindow.close();
- }
-
- normalWindow.close();
- privateWindow.close();
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_1.js b/browser/base/content/test/general/browser_trackingUI_1.js
deleted file mode 100644
index 937d607af..000000000
--- a/browser/base/content/test/general/browser_trackingUI_1.js
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Test that the Tracking Protection section is visible in the Control Center
- * and has the correct state for the cases when:
- * 1) A page with no tracking elements is loaded.
- * 2) A page with tracking elements is loaded and they are blocked.
- * 3) A page with tracking elements is loaded and they are not blocked.
- * See also Bugs 1175327, 1043801, 1178985
- */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const PREF = "privacy.trackingprotection.enabled";
-const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
-const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
-const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
-var TrackingProtection = null;
-var tabbrowser = null;
-
-var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-registerCleanupFunction(function() {
- TrackingProtection = tabbrowser = null;
- UrlClassifierTestUtils.cleanupTestTrackers();
- Services.prefs.clearUserPref(PREF);
- Services.prefs.clearUserPref(PB_PREF);
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-});
-
-function hidden(sel) {
- let win = tabbrowser.ownerGlobal;
- let el = win.document.querySelector(sel);
- let display = win.getComputedStyle(el).getPropertyValue("display", null);
- let opacity = win.getComputedStyle(el).getPropertyValue("opacity", null);
- return display === "none" || opacity === "0";
-}
-
-function clickButton(sel) {
- let win = tabbrowser.ownerGlobal;
- let el = win.document.querySelector(sel);
- el.doCommand();
-}
-
-function testBenignPage() {
- info("Non-tracking content must not be blocked");
- ok(!TrackingProtection.container.hidden, "The container is visible");
- ok(!TrackingProtection.content.hasAttribute("state"), "content: no state");
- ok(!TrackingProtection.icon.hasAttribute("state"), "icon: no state");
- ok(!TrackingProtection.icon.hasAttribute("tooltiptext"), "icon: no tooltip");
-
- ok(hidden("#tracking-protection-icon"), "icon is hidden");
- ok(hidden("#tracking-action-block"), "blockButton is hidden");
- ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-
- // Make sure that the no tracking elements message appears
- ok(!hidden("#tracking-not-detected"), "labelNoTracking is visible");
- ok(hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
- ok(hidden("#tracking-blocked"), "labelTrackingBlocked is hidden");
-}
-
-function testTrackingPage(window) {
- info("Tracking content must be blocked");
- ok(!TrackingProtection.container.hidden, "The container is visible");
- is(TrackingProtection.content.getAttribute("state"), "blocked-tracking-content",
- 'content: state="blocked-tracking-content"');
- is(TrackingProtection.icon.getAttribute("state"), "blocked-tracking-content",
- 'icon: state="blocked-tracking-content"');
- is(TrackingProtection.icon.getAttribute("tooltiptext"),
- gNavigatorBundle.getString("trackingProtection.icon.activeTooltip"), "correct tooltip");
-
- ok(!hidden("#tracking-protection-icon"), "icon is visible");
- ok(hidden("#tracking-action-block"), "blockButton is hidden");
-
-
- if (PrivateBrowsingUtils.isWindowPrivate(window)) {
- ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
- ok(!hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is visible");
- } else {
- ok(!hidden("#tracking-action-unblock"), "unblockButton is visible");
- ok(hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is hidden");
- }
-
- // Make sure that the blocked tracking elements message appears
- ok(hidden("#tracking-not-detected"), "labelNoTracking is hidden");
- ok(hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
- ok(!hidden("#tracking-blocked"), "labelTrackingBlocked is visible");
-}
-
-function testTrackingPageUnblocked() {
- info("Tracking content must be white-listed and not blocked");
- ok(!TrackingProtection.container.hidden, "The container is visible");
- is(TrackingProtection.content.getAttribute("state"), "loaded-tracking-content",
- 'content: state="loaded-tracking-content"');
- is(TrackingProtection.icon.getAttribute("state"), "loaded-tracking-content",
- 'icon: state="loaded-tracking-content"');
- is(TrackingProtection.icon.getAttribute("tooltiptext"),
- gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
-
- ok(!hidden("#tracking-protection-icon"), "icon is visible");
- ok(!hidden("#tracking-action-block"), "blockButton is visible");
- ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-
- // Make sure that the blocked tracking elements message appears
- ok(hidden("#tracking-not-detected"), "labelNoTracking is hidden");
- ok(!hidden("#tracking-loaded"), "labelTrackingLoaded is visible");
- ok(hidden("#tracking-blocked"), "labelTrackingBlocked is hidden");
-}
-
-function* testTrackingProtectionForTab(tab) {
- info("Load a test page not containing tracking elements");
- yield promiseTabLoadEvent(tab, BENIGN_PAGE);
- testBenignPage();
-
- info("Load a test page containing tracking elements");
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
- testTrackingPage(tab.ownerGlobal);
-
- info("Disable TP for the page (which reloads the page)");
- let tabReloadPromise = promiseTabLoadEvent(tab);
- clickButton("#tracking-action-unblock");
- yield tabReloadPromise;
- testTrackingPageUnblocked();
-
- info("Re-enable TP for the page (which reloads the page)");
- tabReloadPromise = promiseTabLoadEvent(tab);
- clickButton("#tracking-action-block");
- yield tabReloadPromise;
- testTrackingPage(tab.ownerGlobal);
-}
-
-add_task(function* testNormalBrowsing() {
- yield UrlClassifierTestUtils.addTestTrackers();
-
- tabbrowser = gBrowser;
- let tab = tabbrowser.selectedTab = tabbrowser.addTab();
-
- TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
- is(TrackingProtection.enabled, Services.prefs.getBoolPref(PREF),
- "TP.enabled is based on the original pref value");
-
- Services.prefs.setBoolPref(PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- yield testTrackingProtectionForTab(tab);
-
- Services.prefs.setBoolPref(PREF, false);
- ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
-});
-
-add_task(function* testPrivateBrowsing() {
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- tabbrowser = privateWin.gBrowser;
- let tab = tabbrowser.selectedTab = tabbrowser.addTab();
-
- TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the private window");
- is(TrackingProtection.enabled, Services.prefs.getBoolPref(PB_PREF),
- "TP.enabled is based on the pb pref value");
-
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- yield testTrackingProtectionForTab(tab);
-
- Services.prefs.setBoolPref(PB_PREF, false);
- ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
-
- privateWin.close();
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_2.js b/browser/base/content/test/general/browser_trackingUI_2.js
deleted file mode 100644
index 96ccb6c2e..000000000
--- a/browser/base/content/test/general/browser_trackingUI_2.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Test that the Tracking Protection section is never visible in the
- * Control Center when the feature is off.
- * See also Bugs 1175327, 1043801, 1178985.
- */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const PREF = "privacy.trackingprotection.enabled";
-const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
-const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
-const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
-var TrackingProtection = null;
-var tabbrowser = null;
-
-var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-registerCleanupFunction(function() {
- TrackingProtection = tabbrowser = null;
- UrlClassifierTestUtils.cleanupTestTrackers();
- Services.prefs.clearUserPref(PREF);
- Services.prefs.clearUserPref(PB_PREF);
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-});
-
-function hidden(el) {
- let win = el.ownerGlobal;
- let display = win.getComputedStyle(el).getPropertyValue("display", null);
- let opacity = win.getComputedStyle(el).getPropertyValue("opacity", null);
-
- return display === "none" || opacity === "0";
-}
-
-add_task(function* testNormalBrowsing() {
- yield UrlClassifierTestUtils.addTestTrackers();
-
- tabbrowser = gBrowser;
- let {gIdentityHandler} = tabbrowser.ownerGlobal;
- let tab = tabbrowser.selectedTab = tabbrowser.addTab();
-
- TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
- is(TrackingProtection.enabled, Services.prefs.getBoolPref(PREF),
- "TP.enabled is based on the original pref value");
-
- Services.prefs.setBoolPref(PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- Services.prefs.setBoolPref(PREF, false);
- ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
-
- info("Load a test page containing tracking elements");
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
- gIdentityHandler._identityBox.click();
- ok(hidden(TrackingProtection.container), "The container is hidden");
- gIdentityHandler._identityPopup.hidden = true;
-
- info("Load a test page not containing tracking elements");
- yield promiseTabLoadEvent(tab, BENIGN_PAGE);
- gIdentityHandler._identityBox.click();
- ok(hidden(TrackingProtection.container), "The container is hidden");
- gIdentityHandler._identityPopup.hidden = true;
-});
-
-add_task(function* testPrivateBrowsing() {
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- tabbrowser = privateWin.gBrowser;
- let {gIdentityHandler} = tabbrowser.ownerGlobal;
- let tab = tabbrowser.selectedTab = tabbrowser.addTab();
-
- TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the private window");
- is(TrackingProtection.enabled, Services.prefs.getBoolPref(PB_PREF),
- "TP.enabled is based on the pb pref value");
-
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- Services.prefs.setBoolPref(PB_PREF, false);
- ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
-
- info("Load a test page containing tracking elements");
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
- gIdentityHandler._identityBox.click();
- ok(hidden(TrackingProtection.container), "The container is hidden");
- gIdentityHandler._identityPopup.hidden = true;
-
- info("Load a test page not containing tracking elements");
- gIdentityHandler._identityBox.click();
- yield promiseTabLoadEvent(tab, BENIGN_PAGE);
- ok(hidden(TrackingProtection.container), "The container is hidden");
- gIdentityHandler._identityPopup.hidden = true;
-
- privateWin.close();
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_3.js b/browser/base/content/test/general/browser_trackingUI_3.js
deleted file mode 100644
index 63f8a13bc..000000000
--- a/browser/base/content/test/general/browser_trackingUI_3.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Test that the Tracking Protection is correctly enabled / disabled
- * in both normal and private windows given all possible states of the prefs:
- * privacy.trackingprotection.enabled
- * privacy.trackingprotection.pbmode.enabled
- * See also Bug 1178985.
- */
-
-const PREF = "privacy.trackingprotection.enabled";
-const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
-
-registerCleanupFunction(function() {
- Services.prefs.clearUserPref(PREF);
- Services.prefs.clearUserPref(PB_PREF);
-});
-
-add_task(function* testNormalBrowsing() {
- let TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
-
- Services.prefs.setBoolPref(PREF, true);
- Services.prefs.setBoolPref(PB_PREF, false);
- ok(TrackingProtection.enabled, "TP is enabled (ENABLED=true,PB=false)");
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled (ENABLED=true,PB=true)");
-
- Services.prefs.setBoolPref(PREF, false);
- Services.prefs.setBoolPref(PB_PREF, false);
- ok(!TrackingProtection.enabled, "TP is disabled (ENABLED=false,PB=false)");
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(!TrackingProtection.enabled, "TP is disabled (ENABLED=false,PB=true)");
-});
-
-add_task(function* testPrivateBrowsing() {
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- let TrackingProtection = privateWin.gBrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
-
- Services.prefs.setBoolPref(PREF, true);
- Services.prefs.setBoolPref(PB_PREF, false);
- ok(TrackingProtection.enabled, "TP is enabled (ENABLED=true,PB=false)");
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled (ENABLED=true,PB=true)");
-
- Services.prefs.setBoolPref(PREF, false);
- Services.prefs.setBoolPref(PB_PREF, false);
- ok(!TrackingProtection.enabled, "TP is disabled (ENABLED=false,PB=false)");
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled (ENABLED=false,PB=true)");
-
- privateWin.close();
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_4.js b/browser/base/content/test/general/browser_trackingUI_4.js
deleted file mode 100644
index 93a06913e..000000000
--- a/browser/base/content/test/general/browser_trackingUI_4.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Test that the Tracking Protection icon is properly animated in the identity
- * block when loading tabs and switching between tabs.
- * See also Bug 1175858.
- */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const PREF = "privacy.trackingprotection.enabled";
-const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
-const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
-const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
-var TrackingProtection = null;
-var tabbrowser = null;
-
-var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-registerCleanupFunction(function() {
- TrackingProtection = tabbrowser = null;
- UrlClassifierTestUtils.cleanupTestTrackers();
- Services.prefs.clearUserPref(PREF);
- Services.prefs.clearUserPref(PB_PREF);
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-});
-
-function waitForSecurityChange(numChanges = 1) {
- return new Promise(resolve => {
- let n = 0;
- let listener = {
- onSecurityChange: function() {
- n = n + 1;
- info ("Received onSecurityChange event " + n + " of " + numChanges);
- if (n >= numChanges) {
- tabbrowser.removeProgressListener(listener);
- resolve();
- }
- }
- };
- tabbrowser.addProgressListener(listener);
- });
-}
-
-function* testTrackingProtectionAnimation() {
- info("Load a test page not containing tracking elements");
- let benignTab = yield BrowserTestUtils.openNewForegroundTab(tabbrowser, BENIGN_PAGE);
-
- ok(!TrackingProtection.icon.hasAttribute("state"), "icon: no state");
- ok(TrackingProtection.icon.hasAttribute("animate"), "icon: animate");
-
- info("Load a test page containing tracking elements");
- let trackingTab = yield BrowserTestUtils.openNewForegroundTab(tabbrowser, TRACKING_PAGE);
-
- ok(TrackingProtection.icon.hasAttribute("state"), "icon: state");
- ok(TrackingProtection.icon.hasAttribute("animate"), "icon: animate");
-
- info("Switch from tracking -> benign tab");
- let securityChanged = waitForSecurityChange();
- tabbrowser.selectedTab = benignTab;
- yield securityChanged;
-
- ok(!TrackingProtection.icon.hasAttribute("state"), "icon: no state");
- ok(!TrackingProtection.icon.hasAttribute("animate"), "icon: no animate");
-
- info("Switch from benign -> tracking tab");
- securityChanged = waitForSecurityChange();
- tabbrowser.selectedTab = trackingTab;
- yield securityChanged;
-
- ok(TrackingProtection.icon.hasAttribute("state"), "icon: state");
- ok(!TrackingProtection.icon.hasAttribute("animate"), "icon: no animate");
-
- info("Reload tracking tab");
- securityChanged = waitForSecurityChange(2);
- tabbrowser.reload();
- yield securityChanged;
-
- ok(TrackingProtection.icon.hasAttribute("state"), "icon: state");
- ok(TrackingProtection.icon.hasAttribute("animate"), "icon: animate");
-}
-
-add_task(function* testNormalBrowsing() {
- yield UrlClassifierTestUtils.addTestTrackers();
-
- tabbrowser = gBrowser;
-
- TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
-
- Services.prefs.setBoolPref(PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- yield testTrackingProtectionAnimation();
-});
-
-add_task(function* testPrivateBrowsing() {
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- tabbrowser = privateWin.gBrowser;
-
- TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the private window");
-
- Services.prefs.setBoolPref(PB_PREF, true);
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- yield testTrackingProtectionAnimation();
-
- privateWin.close();
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_5.js b/browser/base/content/test/general/browser_trackingUI_5.js
deleted file mode 100644
index 23164a5b2..000000000
--- a/browser/base/content/test/general/browser_trackingUI_5.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that sites added to the Tracking Protection whitelist in private
-// browsing mode don't persist once the private browsing window closes.
-
-const PB_PREF = "privacy.trackingprotection.pbmode.enabled";
-const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
-var TrackingProtection = null;
-var browser = null;
-var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-registerCleanupFunction(function() {
- TrackingProtection = browser = null;
- UrlClassifierTestUtils.cleanupTestTrackers();
-});
-
-function hidden(sel) {
- let win = browser.ownerGlobal;
- let el = win.document.querySelector(sel);
- let display = win.getComputedStyle(el).getPropertyValue("display", null);
- return display === "none";
-}
-
-function identityPopupState() {
- let win = browser.ownerGlobal;
- return win.document.getElementById("identity-popup").state;
-}
-
-function clickButton(sel) {
- let win = browser.ownerGlobal;
- let el = win.document.querySelector(sel);
- el.doCommand();
-}
-
-function testTrackingPage(window) {
- info("Tracking content must be blocked");
- ok(!TrackingProtection.container.hidden, "The container is visible");
- is(TrackingProtection.content.getAttribute("state"), "blocked-tracking-content",
- 'content: state="blocked-tracking-content"');
- is(TrackingProtection.icon.getAttribute("state"), "blocked-tracking-content",
- 'icon: state="blocked-tracking-content"');
-
- ok(!hidden("#tracking-protection-icon"), "icon is visible");
- ok(hidden("#tracking-action-block"), "blockButton is hidden");
-
- ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
- ok(!hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is visible");
-
- // Make sure that the blocked tracking elements message appears
- ok(hidden("#tracking-not-detected"), "labelNoTracking is hidden");
- ok(hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
- ok(!hidden("#tracking-blocked"), "labelTrackingBlocked is visible");
-}
-
-function testTrackingPageUnblocked() {
- info("Tracking content must be white-listed and not blocked");
- ok(!TrackingProtection.container.hidden, "The container is visible");
- is(TrackingProtection.content.getAttribute("state"), "loaded-tracking-content",
- 'content: state="loaded-tracking-content"');
- is(TrackingProtection.icon.getAttribute("state"), "loaded-tracking-content",
- 'icon: state="loaded-tracking-content"');
-
- ok(!hidden("#tracking-protection-icon"), "icon is visible");
- ok(!hidden("#tracking-action-block"), "blockButton is visible");
- ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-
- // Make sure that the blocked tracking elements message appears
- ok(hidden("#tracking-not-detected"), "labelNoTracking is hidden");
- ok(!hidden("#tracking-loaded"), "labelTrackingLoaded is visible");
- ok(hidden("#tracking-blocked"), "labelTrackingBlocked is hidden");
-}
-
-add_task(function* testExceptionAddition() {
- yield UrlClassifierTestUtils.addTestTrackers();
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- browser = privateWin.gBrowser;
- let tab = browser.selectedTab = browser.addTab();
-
- TrackingProtection = browser.ownerGlobal.TrackingProtection;
- yield pushPrefs([PB_PREF, true]);
-
- ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-
- info("Load a test page containing tracking elements");
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
-
- testTrackingPage(tab.ownerGlobal);
-
- info("Disable TP for the page (which reloads the page)");
- let tabReloadPromise = promiseTabLoadEvent(tab);
- clickButton("#tracking-action-unblock");
- is(identityPopupState(), "closed", "foobar");
-
- yield tabReloadPromise;
- testTrackingPageUnblocked();
-
- info("Test that the exception is remembered across tabs in the same private window");
- tab = browser.selectedTab = browser.addTab();
-
- info("Load a test page containing tracking elements");
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
- testTrackingPageUnblocked();
-
- yield promiseWindowClosed(privateWin);
-});
-
-add_task(function* testExceptionPersistence() {
- info("Open another private browsing window");
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- browser = privateWin.gBrowser;
- let tab = browser.selectedTab = browser.addTab();
-
- TrackingProtection = browser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection.enabled, "TP is still enabled");
-
- info("Load a test page containing tracking elements");
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
-
- testTrackingPage(tab.ownerGlobal);
-
- info("Disable TP for the page (which reloads the page)");
- let tabReloadPromise = promiseTabLoadEvent(tab);
- clickButton("#tracking-action-unblock");
- is(identityPopupState(), "closed", "foobar");
-
- yield tabReloadPromise;
- testTrackingPageUnblocked();
-
- privateWin.close();
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_6.js b/browser/base/content/test/general/browser_trackingUI_6.js
deleted file mode 100644
index be91bc4a0..000000000
--- a/browser/base/content/test/general/browser_trackingUI_6.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const URL = "http://mochi.test:8888/browser/browser/base/content/test/general/file_trackingUI_6.html";
-
-function waitForSecurityChange(numChanges = 1) {
- return new Promise(resolve => {
- let n = 0;
- let listener = {
- onSecurityChange: function() {
- n = n + 1;
- info ("Received onSecurityChange event " + n + " of " + numChanges);
- if (n >= numChanges) {
- gBrowser.removeProgressListener(listener);
- resolve();
- }
- }
- };
- gBrowser.addProgressListener(listener);
- });
-}
-
-add_task(function* test_fetch() {
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({ set: [['privacy.trackingprotection.enabled', true]] },
- resolve);
- });
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: URL }, function* (newTabBrowser) {
- let securityChange = waitForSecurityChange();
- yield ContentTask.spawn(newTabBrowser, null, function* () {
- yield content.wrappedJSObject.test_fetch()
- .then(response => Assert.ok(false, "should have denied the request"))
- .catch(e => Assert.ok(true, `Caught exception: ${e}`));
- });
- yield securityChange;
-
- var TrackingProtection = newTabBrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "got TP object");
- ok(TrackingProtection.enabled, "TP is enabled");
-
- is(TrackingProtection.content.getAttribute("state"), "blocked-tracking-content",
- 'content: state="blocked-tracking-content"');
- is(TrackingProtection.icon.getAttribute("state"), "blocked-tracking-content",
- 'icon: state="blocked-tracking-content"');
- is(TrackingProtection.icon.getAttribute("tooltiptext"),
- gNavigatorBundle.getString("trackingProtection.icon.activeTooltip"), "correct tooltip");
- });
-});
diff --git a/browser/base/content/test/general/browser_trackingUI_telemetry.js b/browser/base/content/test/general/browser_trackingUI_telemetry.js
deleted file mode 100644
index d9fce18d4..000000000
--- a/browser/base/content/test/general/browser_trackingUI_telemetry.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Test telemetry for Tracking Protection
- */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const PREF = "privacy.trackingprotection.enabled";
-const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
-const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
-const {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-/**
- * Enable local telemetry recording for the duration of the tests.
- */
-var oldCanRecord = Services.telemetry.canRecordExtended;
-Services.telemetry.canRecordExtended = true;
-Services.prefs.setBoolPref(PREF, false);
-Services.telemetry.getHistogramById("TRACKING_PROTECTION_ENABLED").clear();
-registerCleanupFunction(function () {
- UrlClassifierTestUtils.cleanupTestTrackers();
- Services.telemetry.canRecordExtended = oldCanRecord;
- Services.prefs.clearUserPref(PREF);
-});
-
-function getShieldHistogram() {
- return Services.telemetry.getHistogramById("TRACKING_PROTECTION_SHIELD");
-}
-
-function getEnabledHistogram() {
- return Services.telemetry.getHistogramById("TRACKING_PROTECTION_ENABLED");
-}
-
-function getEventsHistogram() {
- return Services.telemetry.getHistogramById("TRACKING_PROTECTION_EVENTS");
-}
-
-function getShieldCounts() {
- return getShieldHistogram().snapshot().counts;
-}
-
-function getEnabledCounts() {
- return getEnabledHistogram().snapshot().counts;
-}
-
-function getEventCounts() {
- return getEventsHistogram().snapshot().counts;
-}
-
-add_task(function* setup() {
- yield UrlClassifierTestUtils.addTestTrackers();
-
- let TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
- ok(!TrackingProtection.enabled, "TP is not enabled");
-
- // Open a window with TP disabled to make sure 'enabled' is logged correctly.
- let newWin = yield promiseOpenAndLoadWindow({}, true);
- yield promiseWindowClosed(newWin);
-
- is(getEnabledCounts()[0], 1, "TP was disabled once on start up");
- is(getEnabledCounts()[1], 0, "TP was not enabled on start up");
-
- // Enable TP so the next browser to open will log 'enabled'
- Services.prefs.setBoolPref(PREF, true);
-});
-
-
-add_task(function* testNewWindow() {
- let newWin = yield promiseOpenAndLoadWindow({}, true);
- let tab = newWin.gBrowser.selectedTab = newWin.gBrowser.addTab();
- let TrackingProtection = newWin.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
-
- is(getEnabledCounts()[0], 1, "TP was disabled once on start up");
- is(getEnabledCounts()[1], 1, "TP was enabled once on start up");
-
- // Reset these to make counting easier
- getEventsHistogram().clear();
- getShieldHistogram().clear();
-
- yield promiseTabLoadEvent(tab, BENIGN_PAGE);
- is(getEventCounts()[0], 1, "Total page loads");
- is(getEventCounts()[1], 0, "Disable actions");
- is(getEventCounts()[2], 0, "Enable actions");
- is(getShieldCounts()[0], 1, "Page loads without tracking");
-
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
- // Note that right now the events and shield histogram is not measuring what
- // you might think. Since onSecurityChange fires twice for a tracking page,
- // the total page loads count is double counting, and the shield count
- // (which is meant to measure times when the shield wasn't shown) fires even
- // when tracking elements exist on the page.
- todo_is(getEventCounts()[0], 2, "FIXME: TOTAL PAGE LOADS IS DOUBLE COUNTING");
- is(getEventCounts()[1], 0, "Disable actions");
- is(getEventCounts()[2], 0, "Enable actions");
- todo_is(getShieldCounts()[0], 1, "FIXME: TOTAL PAGE LOADS WITHOUT TRACKING IS DOUBLE COUNTING");
-
- info("Disable TP for the page (which reloads the page)");
- let tabReloadPromise = promiseTabLoadEvent(tab);
- newWin.document.querySelector("#tracking-action-unblock").doCommand();
- yield tabReloadPromise;
- todo_is(getEventCounts()[0], 3, "FIXME: TOTAL PAGE LOADS IS DOUBLE COUNTING");
- is(getEventCounts()[1], 1, "Disable actions");
- is(getEventCounts()[2], 0, "Enable actions");
- todo_is(getShieldCounts()[0], 1, "FIXME: TOTAL PAGE LOADS WITHOUT TRACKING IS DOUBLE COUNTING");
-
- info("Re-enable TP for the page (which reloads the page)");
- tabReloadPromise = promiseTabLoadEvent(tab);
- newWin.document.querySelector("#tracking-action-block").doCommand();
- yield tabReloadPromise;
- todo_is(getEventCounts()[0], 4, "FIXME: TOTAL PAGE LOADS IS DOUBLE COUNTING");
- is(getEventCounts()[1], 1, "Disable actions");
- is(getEventCounts()[2], 1, "Enable actions");
- todo_is(getShieldCounts()[0], 1, "FIXME: TOTAL PAGE LOADS WITHOUT TRACKING IS DOUBLE COUNTING");
-
- yield promiseWindowClosed(newWin);
-
- // Reset these to make counting easier for the next test
- getEventsHistogram().clear();
- getShieldHistogram().clear();
- getEnabledHistogram().clear();
-});
-
-add_task(function* testPrivateBrowsing() {
- let privateWin = yield promiseOpenAndLoadWindow({private: true}, true);
- let tab = privateWin.gBrowser.selectedTab = privateWin.gBrowser.addTab();
- let TrackingProtection = privateWin.TrackingProtection;
- ok(TrackingProtection, "TP is attached to the browser window");
-
- // Do a bunch of actions and make sure that no telemetry data is gathered
- yield promiseTabLoadEvent(tab, BENIGN_PAGE);
- yield promiseTabLoadEvent(tab, TRACKING_PAGE);
- let tabReloadPromise = promiseTabLoadEvent(tab);
- privateWin.document.querySelector("#tracking-action-unblock").doCommand();
- yield tabReloadPromise;
- tabReloadPromise = promiseTabLoadEvent(tab);
- privateWin.document.querySelector("#tracking-action-block").doCommand();
- yield tabReloadPromise;
-
- // Sum up all the counts to make sure that nothing got logged
- is(getEnabledCounts().reduce((p, c) => p+c), 0, "Telemetry logging off in PB mode");
- is(getEventCounts().reduce((p, c) => p+c), 0, "Telemetry logging off in PB mode");
- is(getShieldCounts().reduce((p, c) => p+c), 0, "Telemetry logging off in PB mode");
-
- yield promiseWindowClosed(privateWin);
-});
diff --git a/browser/base/content/test/general/browser_typeAheadFind.js b/browser/base/content/test/general/browser_typeAheadFind.js
deleted file mode 100644
index 1d550944a..000000000
--- a/browser/base/content/test/general/browser_typeAheadFind.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function *() {
- let testWindow = yield BrowserTestUtils.openNewBrowserWindow();
-
- testWindow.gBrowser.loadURI("data:text/html,<h1>A Page</h1>");
- yield BrowserTestUtils.browserLoaded(testWindow.gBrowser.selectedBrowser);
-
- yield SimpleTest.promiseFocus(testWindow.gBrowser.selectedBrowser);
-
- ok(!testWindow.gFindBarInitialized, "find bar is not initialized");
-
- let findBarOpenPromise = promiseWaitForEvent(testWindow.gBrowser, "findbaropen");
- EventUtils.synthesizeKey("/", {}, testWindow);
- yield findBarOpenPromise;
-
- ok(testWindow.gFindBarInitialized, "find bar is now initialized");
-
- yield BrowserTestUtils.closeWindow(testWindow);
-});
diff --git a/browser/base/content/test/general/browser_unknownContentType_title.js b/browser/base/content/test/general/browser_unknownContentType_title.js
deleted file mode 100644
index 269406bdb..000000000
--- a/browser/base/content/test/general/browser_unknownContentType_title.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const url = "data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3Ctitle%3ETest%20Page%3C%2Ftitle%3E%3C%2Fhead%3E%3C%2Fhtml%3E";
-const unknown_url = "http://example.com/browser/browser/base/content/test/general/unknownContentType_file.pif";
-
-function waitForNewWindow() {
- return new Promise(resolve => {
- let listener = (win) => {
- Services.obs.removeObserver(listener, "toplevel-window-ready");
- win.addEventListener("load", () => {
- resolve(win);
- });
- };
-
- Services.obs.addObserver(listener, "toplevel-window-ready", false)
- });
-}
-
-add_task(function*() {
- let tab = gBrowser.selectedTab = gBrowser.addTab(url);
- let browser = tab.linkedBrowser;
- yield promiseTabLoaded(gBrowser.selectedTab);
-
- is(gBrowser.contentTitle, "Test Page", "Should have the right title.")
-
- browser.loadURI(unknown_url);
- let win = yield waitForNewWindow();
- is(win.location, "chrome://mozapps/content/downloads/unknownContentType.xul",
- "Should have seen the unknown content dialog.");
- is(gBrowser.contentTitle, "Test Page", "Should still have the right title.")
-
- win.close();
- yield promiseWaitForFocus(window);
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/general/browser_unloaddialogs.js b/browser/base/content/test/general/browser_unloaddialogs.js
deleted file mode 100644
index bf3790b95..000000000
--- a/browser/base/content/test/general/browser_unloaddialogs.js
+++ /dev/null
@@ -1,41 +0,0 @@
-var testUrls =
- [
- "data:text/html,<script>" +
- "function handle(evt) {" +
- "evt.target.removeEventListener(evt.type, handle, true);" +
- "try { alert('This should NOT appear'); } catch(e) { }" +
- "}" +
- "window.addEventListener('pagehide', handle, true);" +
- "window.addEventListener('beforeunload', handle, true);" +
- "window.addEventListener('unload', handle, true);" +
- "</script><body>Testing alert during pagehide/beforeunload/unload</body>",
- "data:text/html,<script>" +
- "function handle(evt) {" +
- "evt.target.removeEventListener(evt.type, handle, true);" +
- "try { prompt('This should NOT appear'); } catch(e) { }" +
- "}" +
- "window.addEventListener('pagehide', handle, true);" +
- "window.addEventListener('beforeunload', handle, true);" +
- "window.addEventListener('unload', handle, true);" +
- "</script><body>Testing prompt during pagehide/beforeunload/unload</body>",
- "data:text/html,<script>" +
- "function handle(evt) {" +
- "evt.target.removeEventListener(evt.type, handle, true);" +
- "try { confirm('This should NOT appear'); } catch(e) { }" +
- "}" +
- "window.addEventListener('pagehide', handle, true);" +
- "window.addEventListener('beforeunload', handle, true);" +
- "window.addEventListener('unload', handle, true);" +
- "</script><body>Testing confirm during pagehide/beforeunload/unload</body>",
- ];
-
-add_task(function*() {
- for (let url of testUrls) {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
- ok(true, "Loaded page " + url);
- // Wait one turn of the event loop before closing, so everything settles.
- yield new Promise(resolve => setTimeout(resolve, 0));
- yield BrowserTestUtils.removeTab(tab);
- ok(true, "Closed page " + url + " without timeout");
- }
-});
diff --git a/browser/base/content/test/general/browser_utilityOverlay.js b/browser/base/content/test/general/browser_utilityOverlay.js
deleted file mode 100644
index 34adc00d9..000000000
--- a/browser/base/content/test/general/browser_utilityOverlay.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const gTests = [
- test_eventMatchesKey,
- test_getTopWin,
- test_getBoolPref,
- test_openNewTabWith,
- test_openUILink
-];
-
-function test () {
- waitForExplicitFinish();
- executeSoon(runNextTest);
-}
-
-function runNextTest() {
- if (gTests.length) {
- let testFun = gTests.shift();
- info("Running " + testFun.name);
- testFun()
- }
- else {
- finish();
- }
-}
-
-function test_eventMatchesKey() {
- let eventMatchResult;
- let key;
- let checkEvent = function(e) {
- e.stopPropagation();
- e.preventDefault();
- eventMatchResult = eventMatchesKey(e, key);
- }
- document.addEventListener("keypress", checkEvent);
-
- try {
- key = document.createElement("key");
- let keyset = document.getElementById("mainKeyset");
- key.setAttribute("key", "t");
- key.setAttribute("modifiers", "accel");
- keyset.appendChild(key);
- EventUtils.synthesizeKey("t", {accelKey: true});
- is(eventMatchResult, true, "eventMatchesKey: one modifier");
- keyset.removeChild(key);
-
- key = document.createElement("key");
- key.setAttribute("key", "g");
- key.setAttribute("modifiers", "accel,shift");
- keyset.appendChild(key);
- EventUtils.synthesizeKey("g", {accelKey: true, shiftKey: true});
- is(eventMatchResult, true, "eventMatchesKey: combination modifiers");
- keyset.removeChild(key);
-
- key = document.createElement("key");
- key.setAttribute("key", "w");
- key.setAttribute("modifiers", "accel");
- keyset.appendChild(key);
- EventUtils.synthesizeKey("f", {accelKey: true});
- is(eventMatchResult, false, "eventMatchesKey: mismatch keys");
- keyset.removeChild(key);
-
- key = document.createElement("key");
- key.setAttribute("keycode", "VK_DELETE");
- keyset.appendChild(key);
- EventUtils.synthesizeKey("VK_DELETE", {accelKey: true});
- is(eventMatchResult, false, "eventMatchesKey: mismatch modifiers");
- keyset.removeChild(key);
- } finally {
- // Make sure to remove the event listener so future tests don't
- // fail when they simulate key presses.
- document.removeEventListener("keypress", checkEvent);
- }
-
- runNextTest();
-}
-
-function test_getTopWin() {
- is(getTopWin(), window, "got top window");
- runNextTest();
-}
-
-
-function test_getBoolPref() {
- is(getBoolPref("browser.search.openintab", false), false, "getBoolPref");
- is(getBoolPref("this.pref.doesnt.exist", true), true, "getBoolPref fallback");
- is(getBoolPref("this.pref.doesnt.exist", false), false, "getBoolPref fallback #2");
- runNextTest();
-}
-
-function test_openNewTabWith() {
- openNewTabWith("http://example.com/");
- let tab = gBrowser.selectedTab = gBrowser.tabs[1];
- BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
- is(tab.linkedBrowser.currentURI.spec, "http://example.com/", "example.com loaded");
- gBrowser.removeCurrentTab();
- runNextTest();
- });
-}
-
-function test_openUILink() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
- is(tab.linkedBrowser.currentURI.spec, "http://example.org/", "example.org loaded");
- gBrowser.removeCurrentTab();
- runNextTest();
- });
-
- openUILink("http://example.org/"); // defaults to "current"
-}
diff --git a/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js b/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
deleted file mode 100644
index c8f3cdc96..000000000
--- a/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
+++ /dev/null
@@ -1,55 +0,0 @@
-function wait_while_tab_is_busy() {
- return new Promise(resolve => {
- let progressListener = {
- onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
- if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
- gBrowser.removeProgressListener(this);
- setTimeout(resolve, 0);
- }
- }
- };
- gBrowser.addProgressListener(progressListener);
- });
-}
-
-// This function waits for the tab to stop being busy instead of waiting for it
-// to load, since the canViewSource change happens at that time.
-var with_new_tab_opened = Task.async(function* (options, taskFn) {
- let busyPromise = wait_while_tab_is_busy();
- let tab = yield BrowserTestUtils.openNewForegroundTab(options.gBrowser, options.url, false);
- yield busyPromise;
- yield taskFn(tab.linkedBrowser);
- gBrowser.removeTab(tab);
-});
-
-add_task(function*() {
- yield new Promise((resolve) => {
- SpecialPowers.pushPrefEnv({"set": [
- ["view_source.tab", true],
- ]}, resolve);
- });
-});
-
-add_task(function* test_regular_page() {
- function* test_expect_view_source_enabled(browser) {
- ok(!XULBrowserWindow.canViewSource.hasAttribute("disabled"),
- "View Source should be enabled");
- }
-
- yield with_new_tab_opened({
- gBrowser,
- url: "http://example.com",
- }, test_expect_view_source_enabled);
-});
-
-add_task(function* test_view_source_page() {
- function* test_expect_view_source_disabled(browser) {
- ok(XULBrowserWindow.canViewSource.hasAttribute("disabled"),
- "View Source should be disabled");
- }
-
- yield with_new_tab_opened({
- gBrowser,
- url: "view-source:http://example.com",
- }, test_expect_view_source_disabled);
-});
diff --git a/browser/base/content/test/general/browser_visibleFindSelection.js b/browser/base/content/test/general/browser_visibleFindSelection.js
deleted file mode 100644
index 630490644..000000000
--- a/browser/base/content/test/general/browser_visibleFindSelection.js
+++ /dev/null
@@ -1,52 +0,0 @@
-add_task(function*() {
- const childContent = "<div style='position: absolute; left: 2200px; background: green; width: 200px; height: 200px;'>" +
- "div</div><div style='position: absolute; left: 0px; background: red; width: 200px; height: 200px;'>" +
- "<span id='s'>div</span></div>";
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- yield promiseTabLoadEvent(tab, "data:text/html," + escape(childContent));
- yield SimpleTest.promiseFocus(gBrowser.selectedBrowser.contentWindowAsCPOW);
-
- let findBarOpenPromise = promiseWaitForEvent(gBrowser, "findbaropen");
- EventUtils.synthesizeKey("f", { accelKey: true });
- yield findBarOpenPromise;
-
- ok(gFindBarInitialized, "find bar is now initialized");
-
- // Finds the div in the green box.
- let scrollPromise = promiseWaitForEvent(gBrowser, "scroll");
- EventUtils.synthesizeKey("d", {});
- EventUtils.synthesizeKey("i", {});
- EventUtils.synthesizeKey("v", {});
- yield scrollPromise;
-
- // Wait for one paint to ensure we've processed the previous key events and scrolling.
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- return new Promise(
- resolve => {
- content.requestAnimationFrame(() => {
- setTimeout(resolve, 0);
- });
- }
- );
- });
-
- // Finds the div in the red box.
- scrollPromise = promiseWaitForEvent(gBrowser, "scroll");
- EventUtils.synthesizeKey("g", { accelKey: true });
- yield scrollPromise;
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- Assert.ok(content.document.getElementById("s").getBoundingClientRect().left >= 0,
- "scroll should include find result");
- });
-
- // clear the find bar
- EventUtils.synthesizeKey("a", { accelKey: true });
- EventUtils.synthesizeKey("VK_DELETE", { });
-
- gFindBar.close();
- gBrowser.removeCurrentTab();
-});
-
diff --git a/browser/base/content/test/general/browser_visibleTabs.js b/browser/base/content/test/general/browser_visibleTabs.js
deleted file mode 100644
index e9130bc18..000000000
--- a/browser/base/content/test/general/browser_visibleTabs.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function* () {
- // There should be one tab when we start the test
- let [origTab] = gBrowser.visibleTabs;
-
- // Add a tab that will get pinned
- let pinned = gBrowser.addTab();
- gBrowser.pinTab(pinned);
-
- let testTab = gBrowser.addTab();
-
- let visible = gBrowser.visibleTabs;
- is(visible.length, 3, "3 tabs should be open");
- is(visible[0], pinned, "the pinned tab is first");
- is(visible[1], origTab, "original tab is next");
- is(visible[2], testTab, "last created tab is last");
-
- // Only show the test tab (but also get pinned and selected)
- is(gBrowser.selectedTab, origTab, "sanity check that we're on the original tab");
- gBrowser.showOnlyTheseTabs([testTab]);
- is(gBrowser.visibleTabs.length, 3, "all 3 tabs are still visible");
-
- // Select the test tab and only show that (and pinned)
- gBrowser.selectedTab = testTab;
- gBrowser.showOnlyTheseTabs([testTab]);
-
- visible = gBrowser.visibleTabs;
- is(visible.length, 2, "2 tabs should be visible including the pinned");
- is(visible[0], pinned, "first is pinned");
- is(visible[1], testTab, "next is the test tab");
- is(gBrowser.tabs.length, 3, "3 tabs should still be open");
-
- gBrowser.selectTabAtIndex(1);
- is(gBrowser.selectedTab, testTab, "second tab is the test tab");
- gBrowser.selectTabAtIndex(0);
- is(gBrowser.selectedTab, pinned, "first tab is pinned");
- gBrowser.selectTabAtIndex(2);
- is(gBrowser.selectedTab, testTab, "no third tab, so no change");
- gBrowser.selectTabAtIndex(0);
- is(gBrowser.selectedTab, pinned, "switch back to the pinned");
- gBrowser.selectTabAtIndex(2);
- is(gBrowser.selectedTab, testTab, "no third tab, so select last tab");
- gBrowser.selectTabAtIndex(-2);
- is(gBrowser.selectedTab, pinned, "pinned tab is second from left (when orig tab is hidden)");
- gBrowser.selectTabAtIndex(-1);
- is(gBrowser.selectedTab, testTab, "last tab is the test tab");
-
- gBrowser.tabContainer.advanceSelectedTab(1, true);
- is(gBrowser.selectedTab, pinned, "wrapped around the end to pinned");
- gBrowser.tabContainer.advanceSelectedTab(1, true);
- is(gBrowser.selectedTab, testTab, "next to test tab");
- gBrowser.tabContainer.advanceSelectedTab(1, true);
- is(gBrowser.selectedTab, pinned, "next to pinned again");
-
- gBrowser.tabContainer.advanceSelectedTab(-1, true);
- is(gBrowser.selectedTab, testTab, "going backwards to last tab");
- gBrowser.tabContainer.advanceSelectedTab(-1, true);
- is(gBrowser.selectedTab, pinned, "next to pinned");
- gBrowser.tabContainer.advanceSelectedTab(-1, true);
- is(gBrowser.selectedTab, testTab, "next to test tab again");
-
- // Try showing all tabs
- gBrowser.showOnlyTheseTabs(Array.slice(gBrowser.tabs));
- is(gBrowser.visibleTabs.length, 3, "all 3 tabs are visible again");
-
- // Select the pinned tab and show the testTab to make sure selection updates
- gBrowser.selectedTab = pinned;
- gBrowser.showOnlyTheseTabs([testTab]);
- is(gBrowser.tabs[1], origTab, "make sure origTab is in the middle");
- is(origTab.hidden, true, "make sure it's hidden");
- gBrowser.removeTab(pinned);
- is(gBrowser.selectedTab, testTab, "making sure origTab was skipped");
- is(gBrowser.visibleTabs.length, 1, "only testTab is there");
-
- // Only show one of the non-pinned tabs (but testTab is selected)
- gBrowser.showOnlyTheseTabs([origTab]);
- is(gBrowser.visibleTabs.length, 2, "got 2 tabs");
-
- // Now really only show one of the tabs
- gBrowser.showOnlyTheseTabs([testTab]);
- visible = gBrowser.visibleTabs;
- is(visible.length, 1, "only the original tab is visible");
- is(visible[0], testTab, "it's the original tab");
- is(gBrowser.tabs.length, 2, "still have 2 open tabs");
-
- // Close the last visible tab and make sure we still get a visible tab
- gBrowser.removeTab(testTab);
- is(gBrowser.visibleTabs.length, 1, "only orig is left and visible");
- is(gBrowser.tabs.length, 1, "sanity check that it matches");
- is(gBrowser.selectedTab, origTab, "got the orig tab");
- is(origTab.hidden, false, "and it's not hidden -- visible!");
-});
diff --git a/browser/base/content/test/general/browser_visibleTabs_bookmarkAllPages.js b/browser/base/content/test/general/browser_visibleTabs_bookmarkAllPages.js
deleted file mode 100644
index 827f86c05..000000000
--- a/browser/base/content/test/general/browser_visibleTabs_bookmarkAllPages.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- let tabOne = gBrowser.addTab("about:blank");
- let tabTwo = gBrowser.addTab("http://mochi.test:8888/");
- gBrowser.selectedTab = tabTwo;
-
- let browser = gBrowser.getBrowserForTab(tabTwo);
- let onLoad = function() {
- browser.removeEventListener("load", onLoad, true);
-
- gBrowser.showOnlyTheseTabs([tabTwo]);
-
- is(gBrowser.visibleTabs.length, 1, "Only one tab is visible");
-
- let uris = PlacesCommandHook.uniqueCurrentPages;
- is(uris.length, 1, "Only one uri is returned");
-
- is(uris[0].uri.spec, tabTwo.linkedBrowser.currentURI.spec, "It's the correct URI");
-
- gBrowser.removeTab(tabOne);
- gBrowser.removeTab(tabTwo);
- Array.forEach(gBrowser.tabs, function(tab) {
- gBrowser.showTab(tab);
- });
-
- finish();
- }
- browser.addEventListener("load", onLoad, true);
-}
diff --git a/browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js b/browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js
deleted file mode 100644
index 0a0ea87bd..000000000
--- a/browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- // There should be one tab when we start the test
- let [origTab] = gBrowser.visibleTabs;
- is(gBrowser.visibleTabs.length, 1, "1 tab should be open");
- is(Disabled(), true, "Bookmark All Tabs should be disabled");
-
- // Add a tab
- 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");
-
- // Add a tab that will get pinned
- let pinned = gBrowser.addTab();
- is(gBrowser.visibleTabs.length, 2, "2 tabs should be visible now");
- is(Disabled(), false, "Bookmark All Tabs should be available as there are two visible tabs");
- gBrowser.pinTab(pinned);
- is(Hidden(), false, "Bookmark All Tabs should be visible on a normal tab");
- is(Disabled(), true, "Bookmark All Tabs should not be available since one tab is pinned");
- gBrowser.selectedTab = pinned;
- is(Hidden(), true, "Bookmark All Tabs should be hidden on a pinned tab");
-
- // Show all tabs
- let allTabs = Array.from(gBrowser.tabs);
- gBrowser.showOnlyTheseTabs(allTabs);
-
- // reset the environment
- gBrowser.removeTab(testTab2);
- 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);
-}
-
-function Disabled() {
- updateTabContextMenu();
- return document.getElementById("Browser:BookmarkAllTabs").getAttribute("disabled") == "true";
-}
-
-function Hidden() {
- updateTabContextMenu();
- return document.getElementById("context_bookmarkAllTabs").hidden;
-}
diff --git a/browser/base/content/test/general/browser_visibleTabs_contextMenu.js b/browser/base/content/test/general/browser_visibleTabs_contextMenu.js
deleted file mode 100644
index 4fdab3d8a..000000000
--- a/browser/base/content/test/general/browser_visibleTabs_contextMenu.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const remoteClientsFixture = [ { id: 1, name: "Foo"}, { id: 2, name: "Bar"} ];
-
-add_task(function* test() {
- // There should be one tab when we start the test
- let [origTab] = gBrowser.visibleTabs;
- is(gBrowser.visibleTabs.length, 1, "there is one visible tab");
- let testTab = gBrowser.addTab();
- is(gBrowser.visibleTabs.length, 2, "there are now two visible tabs");
-
- // Check the context menu with two tabs
- updateTabContextMenu(origTab);
- is(document.getElementById("context_closeTab").disabled, false, "Close Tab is enabled");
- is(document.getElementById("context_reloadAllTabs").disabled, false, "Reload All Tabs is enabled");
-
-
- if (gFxAccounts.sendTabToDeviceEnabled) {
- // Check the send tab to device menu item
- const oldGetter = setupRemoteClientsFixture(remoteClientsFixture);
- yield updateTabContextMenu(origTab, function* () {
- yield openMenuItemSubmenu("context_sendTabToDevice");
- });
- is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");
- let targets = document.getElementById("context_sendTabToDevicePopupMenu").childNodes;
- is(targets[0].getAttribute("label"), "Foo", "Foo target is present");
- is(targets[1].getAttribute("label"), "Bar", "Bar target is present");
- is(targets[3].getAttribute("label"), "All Devices", "All Devices target is present");
- restoreRemoteClients(oldGetter);
- }
-
- // Hide the original tab.
- gBrowser.selectedTab = testTab;
- gBrowser.showOnlyTheseTabs([testTab]);
- is(gBrowser.visibleTabs.length, 1, "now there is only one visible tab");
-
- // Check the context menu with one tab.
- updateTabContextMenu(testTab);
- is(document.getElementById("context_closeTab").disabled, false, "Close Tab is enabled when more than one tab exists");
- is(document.getElementById("context_reloadAllTabs").disabled, true, "Reload All Tabs is disabled");
-
- // Add a tab that will get pinned
- // So now there's one pinned tab, one visible unpinned tab, and one hidden tab
- let pinned = gBrowser.addTab();
- gBrowser.pinTab(pinned);
- is(gBrowser.visibleTabs.length, 2, "now there are two visible tabs");
-
- // Check the context menu on the unpinned visible tab
- updateTabContextMenu(testTab);
- is(document.getElementById("context_closeOtherTabs").disabled, true, "Close Other Tabs is disabled");
- is(document.getElementById("context_closeTabsToTheEnd").disabled, true, "Close Tabs To The End is disabled");
-
- // Show all tabs
- let allTabs = Array.from(gBrowser.tabs);
- gBrowser.showOnlyTheseTabs(allTabs);
-
- // Check the context menu now
- updateTabContextMenu(testTab);
- is(document.getElementById("context_closeOtherTabs").disabled, false, "Close Other Tabs is enabled");
- is(document.getElementById("context_closeTabsToTheEnd").disabled, true, "Close Tabs To The End is disabled");
-
- // Check the context menu of the original tab
- // Close Tabs To The End should now be enabled
- updateTabContextMenu(origTab);
- is(document.getElementById("context_closeTabsToTheEnd").disabled, false, "Close Tabs To The End is enabled");
-
- gBrowser.removeTab(testTab);
- gBrowser.removeTab(pinned);
-});
-
diff --git a/browser/base/content/test/general/browser_visibleTabs_tabPreview.js b/browser/base/content/test/general/browser_visibleTabs_tabPreview.js
deleted file mode 100644
index 7ce4b143f..000000000
--- a/browser/base/content/test/general/browser_visibleTabs_tabPreview.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test() {
- gPrefService.setBoolPref("browser.ctrlTab.previews", true);
-
- let [origTab] = gBrowser.visibleTabs;
- let tabOne = gBrowser.addTab();
- let tabTwo = gBrowser.addTab();
-
- // test the ctrlTab.tabList
- pressCtrlTab();
- ok(ctrlTab.tabList.length, 3, "Show 3 tabs in tab preview");
- releaseCtrl();
-
- gBrowser.showOnlyTheseTabs([origTab]);
- pressCtrlTab();
- ok(ctrlTab.tabList.length, 1, "Show 1 tab in tab preview");
- ok(!ctrlTab.isOpen, "With 1 tab open, Ctrl+Tab doesn't open the preview panel");
-
- gBrowser.showOnlyTheseTabs([origTab, tabOne, tabTwo]);
- pressCtrlTab();
- ok(ctrlTab.isOpen, "With 3 tabs open, Ctrl+Tab does open the preview panel");
- releaseCtrl();
-
- // cleanup
- gBrowser.removeTab(tabOne);
- gBrowser.removeTab(tabTwo);
-
- if (gPrefService.prefHasUserValue("browser.ctrlTab.previews"))
- gPrefService.clearUserPref("browser.ctrlTab.previews");
-});
-
-function pressCtrlTab(aShiftKey) {
- EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: !!aShiftKey });
-}
-
-function releaseCtrl() {
- EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" });
-}
diff --git a/browser/base/content/test/general/browser_web_channel.html b/browser/base/content/test/general/browser_web_channel.html
deleted file mode 100644
index f117ccca2..000000000
--- a/browser/base/content/test/general/browser_web_channel.html
+++ /dev/null
@@ -1,189 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>web_channel_test</title>
-</head>
-<body>
-<script>
- var IFRAME_SRC_ROOT = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_web_channel_iframe.html";
-
- window.onload = function() {
- var testName = window.location.search.replace(/^\?/, "");
-
- switch (testName) {
- case "generic":
- test_generic();
- break;
- case "twoway":
- test_twoWay();
- break;
- case "multichannel":
- test_multichannel();
- break;
- case "iframe":
- test_iframe();
- break;
- case "iframe_pre_redirect":
- test_iframe_pre_redirect();
- break;
- case "unsolicited":
- test_unsolicited();
- break;
- case "bubbles":
- test_bubbles();
- break;
- case "object":
- test_object();
- break;
- default:
- throw new Error(`INVALID TEST NAME ${testName}`);
- }
- };
-
- function test_generic() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "generic",
- message: {
- something: {
- nested: "hello",
- },
- }
- })
- });
-
- window.dispatchEvent(event);
- }
-
- function test_twoWay() {
- var firstMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "twoway",
- message: {
- command: "one",
- },
- })
- });
-
- window.addEventListener("WebChannelMessageToContent", function(e) {
- var secondMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "twoway",
- message: {
- command: "two",
- detail: e.detail.message,
- },
- }),
- });
-
- if (!e.detail.message.error) {
- window.dispatchEvent(secondMessage);
- }
- }, true);
-
- window.dispatchEvent(firstMessage);
- }
-
- function test_multichannel() {
- var event1 = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "wrongchannel",
- message: {},
- })
- });
-
- var event2 = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "multichannel",
- message: {},
- })
- });
-
- window.dispatchEvent(event1);
- window.dispatchEvent(event2);
- }
-
- function test_iframe() {
- // Note that this message is the response to the message sent
- // by the iframe! This is bad, as this page is *not* trusted.
- window.addEventListener("WebChannelMessageToContent", function(e) {
- // the test parent will fail if the echo message is received.
- echoEventToChannel(e, "echo");
- });
-
- // only attach the iframe for the iframe test to avoid
- // interfering with other tests.
- var iframe = document.createElement("iframe");
- iframe.setAttribute("src", IFRAME_SRC_ROOT + "?iframe");
- document.body.appendChild(iframe);
- }
-
- function test_iframe_pre_redirect() {
- var iframe = document.createElement("iframe");
- iframe.setAttribute("src", IFRAME_SRC_ROOT + "?iframe_pre_redirect");
- document.body.appendChild(iframe);
- }
-
- function test_unsolicited() {
- // echo any unsolicted events back to chrome.
- window.addEventListener("WebChannelMessageToContent", function(e) {
- echoEventToChannel(e, "echo");
- }, true);
- }
-
- function test_bubbles() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "not_a_window",
- message: {
- command: "start"
- }
- })
- });
-
- var nonWindowTarget = document.getElementById("not_a_window");
-
- nonWindowTarget.addEventListener("WebChannelMessageToContent", function(e) {
- echoEventToChannel(e, "not_a_window");
- }, true);
-
-
- nonWindowTarget.dispatchEvent(event);
- }
-
- function test_object() {
- let objectMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "objects",
- message: { type: "object" }
- }
- });
-
- let stringMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "objects",
- message: { type: "string" }
- })
- });
- // Test fails if objectMessage is received, we send stringMessage to know
- // when we should stop listening for objectMessage
- window.dispatchEvent(objectMessage);
- window.dispatchEvent(stringMessage);
- }
-
- function echoEventToChannel(e, channelId) {
- var echoedEvent = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: channelId,
- message: e.detail.message,
- })
- });
-
- e.target.dispatchEvent(echoedEvent);
- }
-</script>
-
-<div id="not_a_window"></div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/browser_web_channel.js b/browser/base/content/test/general/browser_web_channel.js
deleted file mode 100644
index abc1c6fef..000000000
--- a/browser/base/content/test/general/browser_web_channel.js
+++ /dev/null
@@ -1,436 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
- "resource://gre/modules/WebChannel.jsm");
-
-const HTTP_PATH = "http://example.com";
-const HTTP_ENDPOINT = "/browser/browser/base/content/test/general/browser_web_channel.html";
-const HTTP_MISMATCH_PATH = "http://example.org";
-const HTTP_IFRAME_PATH = "http://mochi.test:8888";
-const HTTP_REDIRECTED_IFRAME_PATH = "http://example.org";
-
-requestLongerTimeout(2); // timeouts in debug builds.
-
-// Keep this synced with /mobile/android/tests/browser/robocop/testWebChannel.js
-// as much as possible. (We only have that since we can't run browser chrome
-// tests on Android. Yet?)
-var gTests = [
- {
- desc: "WebChannel generic message",
- run: function* () {
- return new Promise(function(resolve, reject) {
- let tab;
- let channel = new WebChannel("generic", Services.io.newURI(HTTP_PATH, null, null));
- channel.listen(function (id, message, target) {
- is(id, "generic");
- is(message.something.nested, "hello");
- channel.stopListening();
- gBrowser.removeTab(tab);
- resolve();
- });
-
- tab = gBrowser.addTab(HTTP_PATH + HTTP_ENDPOINT + "?generic");
- });
- }
- },
- {
- desc: "WebChannel generic message in a private window.",
- run: function* () {
- let promiseTestDone = new Promise(function(resolve, reject) {
- let channel = new WebChannel("generic", Services.io.newURI(HTTP_PATH, null, null));
- channel.listen(function(id, message, target) {
- is(id, "generic");
- is(message.something.nested, "hello");
- channel.stopListening();
- resolve();
- });
- });
-
- const url = HTTP_PATH + HTTP_ENDPOINT + "?generic";
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, url);
- yield promiseTestDone;
- yield BrowserTestUtils.closeWindow(privateWindow);
- }
- },
- {
- desc: "WebChannel two way communication",
- run: function* () {
- return new Promise(function(resolve, reject) {
- let tab;
- let channel = new WebChannel("twoway", Services.io.newURI(HTTP_PATH, null, null));
-
- channel.listen(function (id, message, sender) {
- is(id, "twoway", "bad id");
- ok(message.command, "command not ok");
-
- if (message.command === "one") {
- channel.send({ data: { nested: true } }, sender);
- }
-
- if (message.command === "two") {
- is(message.detail.data.nested, true);
- channel.stopListening();
- gBrowser.removeTab(tab);
- resolve();
- }
- });
-
- tab = gBrowser.addTab(HTTP_PATH + HTTP_ENDPOINT + "?twoway");
- });
- }
- },
- {
- desc: "WebChannel two way communication in an iframe",
- run: function* () {
- let parentChannel = new WebChannel("echo", Services.io.newURI(HTTP_PATH, null, null));
- let iframeChannel = new WebChannel("twoway", Services.io.newURI(HTTP_IFRAME_PATH, null, null));
- let promiseTestDone = new Promise(function (resolve, reject) {
- parentChannel.listen(function (id, message, sender) {
- reject(new Error("WebChannel message incorrectly sent to parent"));
- });
-
- iframeChannel.listen(function (id, message, sender) {
- is(id, "twoway", "bad id (2)");
- ok(message.command, "command not ok (2)");
-
- if (message.command === "one") {
- iframeChannel.send({ data: { nested: true } }, sender);
- }
-
- if (message.command === "two") {
- is(message.detail.data.nested, true);
- resolve();
- }
- });
- });
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?iframe"
- }, function* () {
- yield promiseTestDone;
- parentChannel.stopListening();
- iframeChannel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel response to a redirected iframe",
- run: function* () {
- /**
- * This test checks that WebChannel responses are only sent
- * to an iframe if the iframe has not redirected to another origin.
- * Test flow:
- * 1. create a page, embed an iframe on origin A.
- * 2. the iframe sends a message `redirecting`, then redirects to
- * origin B.
- * 3. the iframe at origin B is set up to echo any messages back to the
- * test parent.
- * 4. the test parent receives the `redirecting` message from origin A.
- * the test parent creates a new channel with origin B.
- * 5. when origin B is ready, it sends a `loaded` message to the test
- * parent, letting the test parent know origin B is ready to echo
- * messages.
- * 5. the test parent tries to send a response to origin A. If the
- * WebChannel does not perform a valid origin check, the response
- * will be received by origin B. If the WebChannel does perform
- * a valid origin check, the response will not be sent.
- * 6. the test parent sends a `done` message to origin B, which origin
- * B echoes back. If the response to origin A is not echoed but
- * the message to origin B is, then hooray, the test passes.
- */
-
- let preRedirectChannel = new WebChannel("pre_redirect", Services.io.newURI(HTTP_IFRAME_PATH, null, null));
- let postRedirectChannel = new WebChannel("post_redirect", Services.io.newURI(HTTP_REDIRECTED_IFRAME_PATH, null, null));
-
- let promiseTestDone = new Promise(function (resolve, reject) {
- preRedirectChannel.listen(function (id, message, preRedirectSender) {
- if (message.command === "redirecting") {
-
- postRedirectChannel.listen(function (aId, aMessage, aPostRedirectSender) {
- is(aId, "post_redirect");
- isnot(aMessage.command, "no_response_expected");
-
- if (aMessage.command === "loaded") {
- // The message should not be received on the preRedirectChannel
- // because the target window has redirected.
- preRedirectChannel.send({ command: "no_response_expected" }, preRedirectSender);
- postRedirectChannel.send({ command: "done" }, aPostRedirectSender);
- } else if (aMessage.command === "done") {
- resolve();
- } else {
- reject(new Error(`Unexpected command ${aMessage.command}`));
- }
- });
- } else {
- reject(new Error(`Unexpected command ${message.command}`));
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?iframe_pre_redirect"
- }, function* () {
- yield promiseTestDone;
- preRedirectChannel.stopListening();
- postRedirectChannel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel multichannel",
- run: function* () {
- return new Promise(function(resolve, reject) {
- let tab;
- let channel = new WebChannel("multichannel", Services.io.newURI(HTTP_PATH, null, null));
-
- channel.listen(function (id, message, sender) {
- is(id, "multichannel");
- gBrowser.removeTab(tab);
- resolve();
- });
-
- tab = gBrowser.addTab(HTTP_PATH + HTTP_ENDPOINT + "?multichannel");
- });
- }
- },
- {
- desc: "WebChannel unsolicited send, using system principal",
- run: function* () {
- let channel = new WebChannel("echo", Services.io.newURI(HTTP_PATH, null, null));
-
- // an unsolicted message is sent from Chrome->Content which is then
- // echoed back. If the echo is received here, then the content
- // received the message.
- let messagePromise = new Promise(function (resolve, reject) {
- channel.listen(function (id, message, sender) {
- is(id, "echo");
- is(message.command, "unsolicited");
-
- resolve()
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?unsolicited"
- }, function* (targetBrowser) {
- channel.send({ command: "unsolicited" }, {
- browser: targetBrowser,
- principal: Services.scriptSecurityManager.getSystemPrincipal()
- });
- yield messagePromise;
- channel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel unsolicited send, using target origin's principal",
- run: function* () {
- let targetURI = Services.io.newURI(HTTP_PATH, null, null);
- let channel = new WebChannel("echo", targetURI);
-
- // an unsolicted message is sent from Chrome->Content which is then
- // echoed back. If the echo is received here, then the content
- // received the message.
- let messagePromise = new Promise(function (resolve, reject) {
- channel.listen(function (id, message, sender) {
- is(id, "echo");
- is(message.command, "unsolicited");
-
- resolve();
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?unsolicited"
- }, function* (targetBrowser) {
-
- channel.send({ command: "unsolicited" }, {
- browser: targetBrowser,
- principal: Services.scriptSecurityManager.getNoAppCodebasePrincipal(targetURI)
- });
-
- yield messagePromise;
- channel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel unsolicited send with principal mismatch",
- run: function* () {
- let targetURI = Services.io.newURI(HTTP_PATH, null, null);
- let channel = new WebChannel("echo", targetURI);
-
- // two unsolicited messages are sent from Chrome->Content. The first,
- // `unsolicited_no_response_expected` is sent to the wrong principal
- // and should not be echoed back. The second, `done`, is sent to the
- // correct principal and should be echoed back.
- let messagePromise = new Promise(function (resolve, reject) {
- channel.listen(function (id, message, sender) {
- is(id, "echo");
-
- if (message.command === "done") {
- resolve();
- } else {
- reject(new Error(`Unexpected command ${message.command}`));
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?unsolicited"
- }, function* (targetBrowser) {
-
- let mismatchURI = Services.io.newURI(HTTP_MISMATCH_PATH, null, null);
- let mismatchPrincipal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(mismatchURI);
-
- // send a message to the wrong principal. It should not be delivered
- // to content, and should not be echoed back.
- channel.send({ command: "unsolicited_no_response_expected" }, {
- browser: targetBrowser,
- principal: mismatchPrincipal
- });
-
- let targetPrincipal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(targetURI);
-
- // send the `done` message to the correct principal. It
- // should be echoed back.
- channel.send({ command: "done" }, {
- browser: targetBrowser,
- principal: targetPrincipal
- });
-
- yield messagePromise;
- channel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel non-window target",
- run: function* () {
- /**
- * This test ensures messages can be received from and responses
- * sent to non-window elements.
- *
- * First wait for the non-window element to send a "start" message.
- * Then send the non-window element a "done" message.
- * The non-window element will echo the "done" message back, if it
- * receives the message.
- * Listen for the response. If received, good to go!
- */
- let channel = new WebChannel("not_a_window", Services.io.newURI(HTTP_PATH, null, null));
-
- let testDonePromise = new Promise(function (resolve, reject) {
- channel.listen(function (id, message, sender) {
- if (message.command === "start") {
- channel.send({ command: "done" }, sender);
- } else if (message.command === "done") {
- resolve();
- } else {
- reject(new Error(`Unexpected command ${message.command}`));
- }
- });
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?bubbles"
- }, function* () {
- yield testDonePromise;
- channel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel disallows non-string message from non-whitelisted origin",
- run: function* () {
- /**
- * This test ensures that non-string messages can't be sent via WebChannels.
- * We create a page (on a non-whitelisted origin) which should send us two
- * messages immediately. The first message has an object for it's detail,
- * and the second has a string. We check that we only get the second
- * message.
- */
- let channel = new WebChannel("objects", Services.io.newURI(HTTP_PATH, null, null));
- let testDonePromise = new Promise((resolve, reject) => {
- channel.listen((id, message, sender) => {
- is(id, "objects");
- is(message.type, "string");
- resolve();
- });
- });
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?object"
- }, function* () {
- yield testDonePromise;
- channel.stopListening();
- });
- }
- },
- {
- desc: "WebChannel allows both string and non-string message from whitelisted origin",
- run: function* () {
- /**
- * Same process as above, but we whitelist the origin before loading the page,
- * and expect to get *both* messages back (each exactly once).
- */
- let channel = new WebChannel("objects", Services.io.newURI(HTTP_PATH, null, null));
-
- let testDonePromise = new Promise((resolve, reject) => {
- let sawObject = false;
- let sawString = false;
- channel.listen((id, message, sender) => {
- is(id, "objects");
- if (message.type === "object") {
- ok(!sawObject);
- sawObject = true;
- } else if (message.type === "string") {
- ok(!sawString);
- sawString = true;
- } else {
- reject(new Error(`Unknown message type: ${message.type}`))
- }
- if (sawObject && sawString) {
- resolve();
- }
- });
- });
- const webchannelWhitelistPref = "webchannel.allowObject.urlWhitelist";
- let origWhitelist = Services.prefs.getCharPref(webchannelWhitelistPref);
- let newWhitelist = origWhitelist + " " + HTTP_PATH;
- Services.prefs.setCharPref(webchannelWhitelistPref, newWhitelist);
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: HTTP_PATH + HTTP_ENDPOINT + "?object"
- }, function* () {
- yield testDonePromise;
- Services.prefs.setCharPref(webchannelWhitelistPref, origWhitelist);
- channel.stopListening();
- });
- }
- }
-]; // gTests
-
-function test() {
- waitForExplicitFinish();
-
- Task.spawn(function* () {
- for (let testCase of gTests) {
- info("Running: " + testCase.desc);
- yield testCase.run();
- }
- }).then(finish, ex => {
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
-}
diff --git a/browser/base/content/test/general/browser_web_channel_iframe.html b/browser/base/content/test/general/browser_web_channel_iframe.html
deleted file mode 100644
index 7900e7530..000000000
--- a/browser/base/content/test/general/browser_web_channel_iframe.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>web_channel_test (iframe)</title>
-</head>
-<body>
-<script>
- var REDIRECTED_IFRAME_SRC_ROOT = "http://example.org/browser/browser/base/content/test/general/browser_web_channel_iframe.html";
-
- window.onload = function() {
- var testName = window.location.search.replace(/^\?/, "");
- switch (testName) {
- case "iframe":
- test_iframe();
- break;
- case "iframe_pre_redirect":
- test_iframe_pre_redirect();
- break;
- case "iframe_post_redirect":
- test_iframe_post_redirect();
- break;
- default:
- throw new Error(`INVALID TEST NAME ${testName}`);
- }
- };
-
- function test_iframe() {
- var firstMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "twoway",
- message: {
- command: "one",
- },
- })
- });
-
- window.addEventListener("WebChannelMessageToContent", function(e) {
- var secondMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "twoway",
- message: {
- command: "two",
- detail: e.detail.message,
- },
- }),
- });
-
- if (!e.detail.message.error) {
- window.dispatchEvent(secondMessage);
- }
- }, true);
-
- window.dispatchEvent(firstMessage);
- }
-
-
- function test_iframe_pre_redirect() {
- var firstMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "pre_redirect",
- message: {
- command: "redirecting",
- },
- }),
- });
- window.dispatchEvent(firstMessage);
- document.location = REDIRECTED_IFRAME_SRC_ROOT + "?iframe_post_redirect";
- }
-
- function test_iframe_post_redirect() {
- window.addEventListener("WebChannelMessageToContent", function(e) {
- var echoMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "post_redirect",
- message: e.detail.message,
- }),
- });
-
- window.dispatchEvent(echoMessage);
- }, true);
-
- // Let the test parent know the page has loaded and is ready to echo events
- var loadedMessage = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "post_redirect",
- message: {
- command: "loaded",
- },
- }),
- });
- window.dispatchEvent(loadedMessage);
- }
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/browser_windowactivation.js b/browser/base/content/test/general/browser_windowactivation.js
deleted file mode 100644
index ae4ba75dc..000000000
--- a/browser/base/content/test/general/browser_windowactivation.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * This test checks that window activation state is set properly with multiple tabs.
- */
-
-var testPage = "data:text/html,<body><style>:-moz-window-inactive { background-color: red; }</style><div id='area'></div></body>";
-
-var colorChangeNotifications = 0;
-var otherWindow;
-
-var browser1, browser2;
-
-function test() {
- waitForExplicitFinish();
- waitForFocus(reallyRunTests);
-}
-
-function reallyRunTests() {
-
- let tab1 = gBrowser.addTab();
- let tab2 = gBrowser.addTab();
- browser1 = gBrowser.getBrowserForTab(tab1);
- browser2 = gBrowser.getBrowserForTab(tab2);
-
- gURLBar.focus();
-
- var loadCount = 0;
- function check()
- {
- // wait for both tabs to load
- if (++loadCount != 2) {
- return;
- }
-
- browser1.removeEventListener("load", check, true);
- browser2.removeEventListener("load", check, true);
-
- sendGetBackgroundRequest(true);
- }
-
- // The test performs four checks, using -moz-window-inactive on two child tabs.
- // First, the initial state should be transparent. The second check is done
- // while another window is focused. The third check is done after that window
- // is closed and the main window focused again. The fourth check is done after
- // switching to the second tab.
- window.messageManager.addMessageListener("Test:BackgroundColorChanged", function(message) {
- colorChangeNotifications++;
-
- switch (colorChangeNotifications) {
- case 1:
- is(message.data.color, "transparent", "first window initial");
- break;
- case 2:
- is(message.data.color, "transparent", "second window initial");
- runOtherWindowTests();
- break;
- case 3:
- is(message.data.color, "rgb(255, 0, 0)", "first window lowered");
- break;
- case 4:
- is(message.data.color, "rgb(255, 0, 0)", "second window lowered");
- sendGetBackgroundRequest(true);
- otherWindow.close();
- break;
- case 5:
- is(message.data.color, "transparent", "first window raised");
- break;
- case 6:
- is(message.data.color, "transparent", "second window raised");
- gBrowser.selectedTab = tab2;
- break;
- case 7:
- is(message.data.color, "transparent", "first window after tab switch");
- break;
- case 8:
- is(message.data.color, "transparent", "second window after tab switch");
- finishTest();
- break;
- case 9:
- ok(false, "too many color change notifications");
- break;
- }
- });
-
- window.messageManager.addMessageListener("Test:FocusReceived", function(message) {
- // No color change should occur after a tab switch.
- if (colorChangeNotifications == 6) {
- sendGetBackgroundRequest(false);
- }
- });
-
- window.messageManager.addMessageListener("Test:ActivateEvent", function(message) {
- ok(message.data.ok, "Test:ActivateEvent");
- });
-
- window.messageManager.addMessageListener("Test:DeactivateEvent", function(message) {
- ok(message.data.ok, "Test:DeactivateEvent");
- });
-
- browser1.addEventListener("load", check, true);
- browser2.addEventListener("load", check, true);
- browser1.contentWindow.location = testPage;
- browser2.contentWindow.location = testPage;
-
- browser1.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true);
- browser2.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true);
-
- gBrowser.selectedTab = tab1;
-}
-
-function sendGetBackgroundRequest(ifChanged)
-{
- browser1.messageManager.sendAsyncMessage("Test:GetBackgroundColor", { ifChanged: ifChanged });
- browser2.messageManager.sendAsyncMessage("Test:GetBackgroundColor", { ifChanged: ifChanged });
-}
-
-function runOtherWindowTests() {
- otherWindow = window.open("data:text/html,<body>Hi</body>", "", "chrome");
- waitForFocus(function () {
- sendGetBackgroundRequest(true);
- }, otherWindow);
-}
-
-function finishTest()
-{
- gBrowser.removeCurrentTab();
- gBrowser.removeCurrentTab();
- otherWindow = null;
- finish();
-}
-
-function childFunction()
-{
- let oldColor = null;
-
- let expectingResponse = false;
- let ifChanged = true;
-
- addMessageListener("Test:GetBackgroundColor", function(message) {
- expectingResponse = true;
- ifChanged = message.data.ifChanged;
- });
-
- content.addEventListener("focus", function () {
- sendAsyncMessage("Test:FocusReceived", { });
- }, false);
-
- var windowGotActivate = false;
- var windowGotDeactivate = false;
- addEventListener("activate", function() {
- sendAsyncMessage("Test:ActivateEvent", { ok: !windowGotActivate });
- windowGotActivate = false;
- });
-
- addEventListener("deactivate", function() {
- sendAsyncMessage("Test:DeactivateEvent", { ok: !windowGotDeactivate });
- windowGotDeactivate = false;
- });
- content.addEventListener("activate", function() {
- windowGotActivate = true;
- });
-
- content.addEventListener("deactivate", function() {
- windowGotDeactivate = true;
- });
-
- content.setInterval(function () {
- if (!expectingResponse) {
- return;
- }
-
- let area = content.document.getElementById("area");
- if (!area) {
- return; /* hasn't loaded yet */
- }
-
- let color = content.getComputedStyle(area, "").backgroundColor;
- if (oldColor != color || !ifChanged) {
- expectingResponse = false;
- oldColor = color;
- sendAsyncMessage("Test:BackgroundColorChanged", { color: color });
- }
- }, 20);
-}
diff --git a/browser/base/content/test/general/browser_windowopen_reflows.js b/browser/base/content/test/general/browser_windowopen_reflows.js
deleted file mode 100644
index 7dac8aad6..000000000
--- a/browser/base/content/test/general/browser_windowopen_reflows.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const EXPECTED_REFLOWS = [
- // handleEvent flushes layout to get the tabstrip width after a resize.
- "handleEvent@chrome://browser/content/tabbrowser.xml|",
-
- // Loading a tab causes a reflow.
- "loadTabs@chrome://browser/content/tabbrowser.xml|" +
- "loadOneOrMoreURIs@chrome://browser/content/browser.js|" +
- "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|",
-
- // Selecting the address bar causes a reflow.
- "select@chrome://global/content/bindings/textbox.xml|" +
- "focusAndSelectUrlBar@chrome://browser/content/browser.js|" +
- "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|",
-
- // Focusing the content area causes a reflow.
- "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|",
-
- // Sometimes sessionstore collects data during this test, which causes a sync reflow
- // (https://bugzilla.mozilla.org/show_bug.cgi?id=892154 will fix this)
- "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm",
-];
-
-if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
- // TabsInTitlebar._update causes a reflow on OS X and Windows trying to do calculations
- // since layout info is already dirty. This doesn't seem to happen before
- // MozAfterPaint on Linux.
- EXPECTED_REFLOWS.push("TabsInTitlebar._update/rect@chrome://browser/content/browser-tabsintitlebar.js|" +
- "TabsInTitlebar._update@chrome://browser/content/browser-tabsintitlebar.js|" +
- "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js|" +
- "handleEvent@chrome://browser/content/tabbrowser.xml|");
-}
-
-if (Services.appinfo.OS == "Darwin") {
- // _onOverflow causes a reflow getting widths.
- EXPECTED_REFLOWS.push("OverflowableToolbar.prototype._onOverflow@resource:///modules/CustomizableUI.jsm|" +
- "OverflowableToolbar.prototype.init@resource:///modules/CustomizableUI.jsm|" +
- "OverflowableToolbar.prototype.observe@resource:///modules/CustomizableUI.jsm|" +
- "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|");
- // Same as above since in packaged builds there are no function names and the resource URI includes "app"
- EXPECTED_REFLOWS.push("@resource://app/modules/CustomizableUI.jsm|" +
- "@resource://app/modules/CustomizableUI.jsm|" +
- "@resource://app/modules/CustomizableUI.jsm|" +
- "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|");
-}
-
-/*
- * This test ensures that there are no unexpected
- * uninterruptible reflows when opening new windows.
- */
-function test() {
- waitForExplicitFinish();
-
- // Add a reflow observer and open a new window
- let win = OpenBrowserWindow();
- let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
- docShell.addWeakReflowObserver(observer);
-
- // Wait until the mozafterpaint event occurs.
- waitForMozAfterPaint(win, function paintListener() {
- // Remove reflow observer and clean up.
- docShell.removeWeakReflowObserver(observer);
- win.close();
-
- finish();
- });
-}
-
-var observer = {
- reflow: function (start, end) {
- // Gather information about the current code path.
- let stack = new Error().stack;
- let path = stack.split("\n").slice(1).map(line => {
- return line.replace(/:\d+:\d+$/, "");
- }).join("|");
- let pathWithLineNumbers = (new Error().stack).split("\n").slice(1).join("|");
-
- // Stack trace is empty. Reflow was triggered by native code.
- if (path === "") {
- return;
- }
-
- // Check if this is an expected reflow.
- for (let expectedStack of EXPECTED_REFLOWS) {
- if (path.startsWith(expectedStack) ||
- // Accept an empty function name for gBrowserInit._delayedStartup or TabsInTitlebar._update to workaround bug 906578.
- path.startsWith(expectedStack.replace(/(^|\|)(gBrowserInit\._delayedStartup|TabsInTitlebar\._update)@/, "$1@"))) {
- ok(true, "expected uninterruptible reflow '" + expectedStack + "'");
- return;
- }
- }
-
- ok(false, "unexpected uninterruptible reflow '" + pathWithLineNumbers + "'");
- },
-
- reflowInterruptible: function (start, end) {
- // We're not interested in interruptible reflows.
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
- Ci.nsISupportsWeakReference])
-};
-
-function waitForMozAfterPaint(win, callback) {
- win.addEventListener("MozAfterPaint", function onEnd(event) {
- if (event.target != win)
- return;
- win.removeEventListener("MozAfterPaint", onEnd);
- executeSoon(callback);
- });
-}
diff --git a/browser/base/content/test/general/browser_zbug569342.js b/browser/base/content/test/general/browser_zbug569342.js
deleted file mode 100644
index 2dac5acde..000000000
--- a/browser/base/content/test/general/browser_zbug569342.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var gTab = null;
-
-function load(url, cb) {
- gTab = gBrowser.addTab(url);
- gBrowser.addEventListener("load", function (event) {
- if (event.target.location != url)
- return;
-
- gBrowser.removeEventListener("load", arguments.callee, true);
- // Trigger onLocationChange by switching tabs.
- gBrowser.selectedTab = gTab;
- cb();
- }, true);
-}
-
-function test() {
- waitForExplicitFinish();
-
- ok(gFindBar.hidden, "Find bar should not be visible by default");
-
- // Open the Find bar before we navigate to pages that shouldn't have it.
- EventUtils.synthesizeKey("f", { accelKey: true });
- ok(!gFindBar.hidden, "Find bar should be visible");
-
- nextTest();
-}
-
-var urls = [
- "about:config",
- "about:addons",
-];
-
-function nextTest() {
- let url = urls.shift();
- if (url) {
- testFindDisabled(url, nextTest);
- } else {
- // Make sure the find bar is re-enabled after disabled page is closed.
- testFindEnabled("about:blank", function () {
- EventUtils.synthesizeKey("VK_ESCAPE", { });
- ok(gFindBar.hidden, "Find bar should now be hidden");
- finish();
- });
- }
-}
-
-function testFindDisabled(url, cb) {
- load(url, function() {
- ok(gFindBar.hidden, "Find bar should not be visible");
- EventUtils.synthesizeKey("/", {}, gTab.linkedBrowser.contentWindow);
- ok(gFindBar.hidden, "Find bar should not be visible");
- EventUtils.synthesizeKey("f", { accelKey: true });
- ok(gFindBar.hidden, "Find bar should not be visible");
- ok(document.getElementById("cmd_find").getAttribute("disabled"),
- "Find command should be disabled");
-
- gBrowser.removeTab(gTab);
- cb();
- });
-}
-
-function testFindEnabled(url, cb) {
- load(url, function() {
- ok(!document.getElementById("cmd_find").getAttribute("disabled"),
- "Find command should not be disabled");
-
- // Open Find bar and then close it.
- EventUtils.synthesizeKey("f", { accelKey: true });
- ok(!gFindBar.hidden, "Find bar should be visible again");
- EventUtils.synthesizeKey("VK_ESCAPE", { });
- ok(gFindBar.hidden, "Find bar should now be hidden");
-
- gBrowser.removeTab(gTab);
- cb();
- });
-}
diff --git a/browser/base/content/test/general/bug1262648_string_with_newlines.dtd b/browser/base/content/test/general/bug1262648_string_with_newlines.dtd
deleted file mode 100644
index 308072c4e..000000000
--- a/browser/base/content/test/general/bug1262648_string_with_newlines.dtd
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY foo.bar "This string
-contains
-newlines!"> \ No newline at end of file
diff --git a/browser/base/content/test/general/bug364677-data.xml b/browser/base/content/test/general/bug364677-data.xml
deleted file mode 100644
index b48915c05..000000000
--- a/browser/base/content/test/general/bug364677-data.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<rss version="2.0">
- <channel>
- <title>t</title>
- </channel>
-</rss>
diff --git a/browser/base/content/test/general/bug364677-data.xml^headers^ b/browser/base/content/test/general/bug364677-data.xml^headers^
deleted file mode 100644
index f203c6368..000000000
--- a/browser/base/content/test/general/bug364677-data.xml^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/xml
diff --git a/browser/base/content/test/general/bug395533-data.txt b/browser/base/content/test/general/bug395533-data.txt
deleted file mode 100644
index e0ed39850..000000000
--- a/browser/base/content/test/general/bug395533-data.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-<rss version="2.0">
- <channel>
- <link>http://example.org/</link>
- <title>t</title>
- </channel>
-</rss>
diff --git a/browser/base/content/test/general/bug592338.html b/browser/base/content/test/general/bug592338.html
deleted file mode 100644
index 159b21a76..000000000
--- a/browser/base/content/test/general/bug592338.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html>
-<head>
-<script type="text/javascript">
-var theme = {
- id: "test",
- name: "Test Background",
- headerURL: "http://example.com/firefox/personas/01/header.jpg",
- footerURL: "http://example.com/firefox/personas/01/footer.jpg",
- textcolor: "#fff",
- accentcolor: "#6b6b6b"
-};
-
-function setTheme(node) {
- node.setAttribute("data-browsertheme", JSON.stringify(theme));
- var event = document.createEvent("Events");
- event.initEvent("InstallBrowserTheme", true, false);
- node.dispatchEvent(event);
-}
-</script>
-</head>
-<body>
-<a id="theme-install" href="#" onclick="setTheme(this)">Install</a>
-</body>
-</html>
diff --git a/browser/base/content/test/general/bug792517-2.html b/browser/base/content/test/general/bug792517-2.html
deleted file mode 100644
index bfc24d817..000000000
--- a/browser/base/content/test/general/bug792517-2.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
-<a href="bug792517.sjs" id="fff">this is a link</a>
-</body>
-</html>
diff --git a/browser/base/content/test/general/bug792517.html b/browser/base/content/test/general/bug792517.html
deleted file mode 100644
index e7c040bf1..000000000
--- a/browser/base/content/test/general/bug792517.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
-<img src="moz.png" id="img">
-</body>
-</html>
diff --git a/browser/base/content/test/general/bug792517.sjs b/browser/base/content/test/general/bug792517.sjs
deleted file mode 100644
index 91e5aa23f..000000000
--- a/browser/base/content/test/general/bug792517.sjs
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-function handleRequest(aRequest, aResponse) {
- aResponse.setStatusLine(aRequest.httpVersion, 200);
- if (aRequest.hasHeader('Cookie')) {
- aResponse.write("cookie-present");
- } else {
- aResponse.setHeader("Set-Cookie", "foopy=1");
- aResponse.write("cookie-not-present");
- }
-}
diff --git a/browser/base/content/test/general/bug839103.css b/browser/base/content/test/general/bug839103.css
deleted file mode 100644
index 611907d3d..000000000
--- a/browser/base/content/test/general/bug839103.css
+++ /dev/null
@@ -1 +0,0 @@
-* {}
diff --git a/browser/base/content/test/general/clipboard_pastefile.html b/browser/base/content/test/general/clipboard_pastefile.html
deleted file mode 100644
index fcbf60ed2..000000000
--- a/browser/base/content/test/general/clipboard_pastefile.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html><body>
-<script>
-function checkPaste(event)
-{
- let output = document.getElementById("output");
- output.textContent = checkPasteHelper(event);
-}
-
-function checkPasteHelper(event)
-{
- let dt = event.clipboardData;
- if (dt.types.length != 2)
- return "Wrong number of types; got " + dt.types.length;
-
- for (let type of dt.types) {
- if (type != "Files" && type != "application/x-moz-file")
- return "Invalid type for types; got" + type;
- }
-
- for (let type of dt.mozTypesAt(0)) {
- if (type != "Files" && type != "application/x-moz-file")
- return "Invalid type for mozTypesAt; got" + type;
- }
-
- if (dt.getData("text/plain"))
- return "text/plain found with getData";
- if (dt.mozGetDataAt("text/plain", 0))
- return "text/plain found with mozGetDataAt";
-
- return "Passed";
-}
-</script>
-
-<input id="input" onpaste="checkPaste(event)">
-<div id="output"></div>
-
-</body></html>
diff --git a/browser/base/content/test/general/close_beforeunload.html b/browser/base/content/test/general/close_beforeunload.html
deleted file mode 100644
index 4b62002cc..000000000
--- a/browser/base/content/test/general/close_beforeunload.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<body>
- <p>I will close myself if you close me.</p>
- <script>
- window.onbeforeunload = function() {
- window.close();
- };
- </script>
-</body>
diff --git a/browser/base/content/test/general/close_beforeunload_opens_second_tab.html b/browser/base/content/test/general/close_beforeunload_opens_second_tab.html
deleted file mode 100644
index 243307a0e..000000000
--- a/browser/base/content/test/general/close_beforeunload_opens_second_tab.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<body>
- <a href="#" onclick="window.open('close_beforeunload.html', '_blank')">Open second tab</a>
-</body>
diff --git a/browser/base/content/test/general/contentSearchUI.html b/browser/base/content/test/general/contentSearchUI.html
deleted file mode 100644
index 3750ac2b0..000000000
--- a/browser/base/content/test/general/contentSearchUI.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<html>
-<head>
-<meta charset="utf-8">
-<script type="application/javascript;version=1.8"
- src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js">
-</script>
-<script type="application/javascript;version=1.8"
- src="chrome://browser/content/contentSearchUI.js">
-</script>
-<link rel="stylesheet" href="chrome://browser/content/contentSearchUI.css"/>
-</head>
-<body>
-
-<div id="container" style="position: relative;"><input type="text" value=""/></div>
-
-</body>
-</html>
diff --git a/browser/base/content/test/general/contentSearchUI.js b/browser/base/content/test/general/contentSearchUI.js
deleted file mode 100644
index 0e46230a2..000000000
--- a/browser/base/content/test/general/contentSearchUI.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-(function () {
-
-const TEST_MSG = "ContentSearchUIControllerTest";
-const ENGINE_NAME = "browser_searchSuggestionEngine searchSuggestionEngine.xml";
-var gController;
-
-addMessageListener(TEST_MSG, msg => {
- messageHandlers[msg.data.type](msg.data.data);
-});
-
-var messageHandlers = {
-
- init: function() {
- Services.search.currentEngine = Services.search.getEngineByName(ENGINE_NAME);
- let input = content.document.querySelector("input");
- gController =
- new content.ContentSearchUIController(input, input.parentNode, "test", "test");
- content.addEventListener("ContentSearchService", function listener(aEvent) {
- if (aEvent.detail.type == "State" &&
- gController.defaultEngine.name == ENGINE_NAME) {
- content.removeEventListener("ContentSearchService", listener);
- ack("init");
- }
- });
- gController.remoteTimeout = 5000;
- },
-
- key: function (arg) {
- let keyName = typeof(arg) == "string" ? arg : arg.key;
- content.synthesizeKey(keyName, arg.modifiers || {});
- let wait = arg.waitForSuggestions ? waitForSuggestions : cb => cb();
- wait(ack.bind(null, "key"));
- },
-
- startComposition: function (arg) {
- content.synthesizeComposition({ type: "compositionstart", data: "" });
- ack("startComposition");
- },
-
- changeComposition: function (arg) {
- let data = typeof(arg) == "string" ? arg : arg.data;
- content.synthesizeCompositionChange({
- composition: {
- string: data,
- clauses: [
- { length: data.length, attr: content.COMPOSITION_ATTR_RAW_CLAUSE }
- ]
- },
- caret: { start: data.length, length: 0 }
- });
- let wait = arg.waitForSuggestions ? waitForSuggestions : cb => cb();
- wait(ack.bind(null, "changeComposition"));
- },
-
- commitComposition: function () {
- content.synthesizeComposition({ type: "compositioncommitasis" });
- ack("commitComposition");
- },
-
- focus: function () {
- gController.input.focus();
- ack("focus");
- },
-
- blur: function () {
- gController.input.blur();
- ack("blur");
- },
-
- waitForSearch: function () {
- waitForContentSearchEvent("Search", aData => ack("waitForSearch", aData));
- },
-
- waitForSearchSettings: function () {
- waitForContentSearchEvent("ManageEngines",
- aData => ack("waitForSearchSettings", aData));
- },
-
- mousemove: function (itemIndex) {
- let row;
- if (itemIndex == -1) {
- row = gController._table.firstChild;
- }
- else {
- let allElts = [...gController._suggestionsList.children,
- ...gController._oneOffButtons,
- content.document.getElementById("contentSearchSettingsButton")];
- row = allElts[itemIndex];
- }
- let event = {
- type: "mousemove",
- clickcount: 0,
- }
- row.addEventListener("mousemove", function handler() {
- row.removeEventListener("mousemove", handler);
- ack("mousemove");
- });
- content.synthesizeMouseAtCenter(row, event);
- },
-
- click: function (arg) {
- let eltIdx = typeof(arg) == "object" ? arg.eltIdx : arg;
- let row;
- if (eltIdx == -1) {
- row = gController._table.firstChild;
- }
- else {
- let allElts = [...gController._suggestionsList.children,
- ...gController._oneOffButtons,
- content.document.getElementById("contentSearchSettingsButton")];
- row = allElts[eltIdx];
- }
- let event = arg.modifiers || {};
- // synthesizeMouseAtCenter defaults to sending a mousedown followed by a
- // mouseup if the event type is not specified.
- content.synthesizeMouseAtCenter(row, event);
- ack("click");
- },
-
- addInputValueToFormHistory: function () {
- gController.addInputValueToFormHistory();
- ack("addInputValueToFormHistory");
- },
-
- addDuplicateOneOff: function () {
- let btn = gController._oneOffButtons[gController._oneOffButtons.length - 1];
- let newBtn = btn.cloneNode(true);
- btn.parentNode.appendChild(newBtn);
- gController._oneOffButtons.push(newBtn);
- ack("addDuplicateOneOff");
- },
-
- removeLastOneOff: function () {
- gController._oneOffButtons.pop().remove();
- ack("removeLastOneOff");
- },
-
- reset: function () {
- // Reset both the input and suggestions by select all + delete. If there was
- // no text entered, this won't have any effect, so also escape to ensure the
- // suggestions table is closed.
- gController.input.focus();
- content.synthesizeKey("a", { accelKey: true });
- content.synthesizeKey("VK_DELETE", {});
- content.synthesizeKey("VK_ESCAPE", {});
- ack("reset");
- },
-};
-
-function ack(aType, aData) {
- sendAsyncMessage(TEST_MSG, { type: aType, data: aData || currentState() });
-}
-
-function waitForSuggestions(cb) {
- let observer = new content.MutationObserver(() => {
- if (gController.input.getAttribute("aria-expanded") == "true") {
- observer.disconnect();
- cb();
- }
- });
- observer.observe(gController.input, {
- attributes: true,
- attributeFilter: ["aria-expanded"],
- });
-}
-
-function waitForContentSearchEvent(messageType, cb) {
- let mm = content.SpecialPowers.Cc["@mozilla.org/globalmessagemanager;1"].
- getService(content.SpecialPowers.Ci.nsIMessageListenerManager);
- mm.addMessageListener("ContentSearch", function listener(aMsg) {
- if (aMsg.data.type != messageType) {
- return;
- }
- mm.removeMessageListener("ContentSearch", listener);
- cb(aMsg.data.data);
- });
-}
-
-function currentState() {
- let state = {
- selectedIndex: gController.selectedIndex,
- selectedButtonIndex: gController.selectedButtonIndex,
- numSuggestions: gController._table.hidden ? 0 : gController.numSuggestions,
- suggestionAtIndex: [],
- isFormHistorySuggestionAtIndex: [],
-
- tableHidden: gController._table.hidden,
-
- inputValue: gController.input.value,
- ariaExpanded: gController.input.getAttribute("aria-expanded"),
- };
-
- if (state.numSuggestions) {
- for (let i = 0; i < gController.numSuggestions; i++) {
- state.suggestionAtIndex.push(gController.suggestionAtIndex(i));
- state.isFormHistorySuggestionAtIndex.push(
- gController.isFormHistorySuggestionAtIndex(i));
- }
- }
-
- return state;
-}
-
-})();
diff --git a/browser/base/content/test/general/content_aboutAccounts.js b/browser/base/content/test/general/content_aboutAccounts.js
deleted file mode 100644
index 12ac04934..000000000
--- a/browser/base/content/test/general/content_aboutAccounts.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This file is loaded as a "content script" for browser_aboutAccounts tests
-"use strict";
-
-var {interfaces: Ci, utils: Cu} = Components;
-
-addEventListener("load", function load(event) {
- if (event.target != content.document) {
- return;
- }
-// content.document.removeEventListener("load", load, true);
- sendAsyncMessage("test:document:load");
- // Opening Sync prefs in tests is a pain as leaks are reported due to the
- // in-flight promises. For now we just mock the openPrefs() function and have
- // it send a message back to the test so we know it was called.
- content.openPrefs = function() {
- sendAsyncMessage("test:openPrefsCalled");
- }
-}, true);
-
-addEventListener("DOMContentLoaded", function domContentLoaded(event) {
- removeEventListener("DOMContentLoaded", domContentLoaded, true);
- let iframe = content.document.getElementById("remote");
- if (!iframe) {
- // at least one test initially loads about:blank - in that case, we are done.
- return;
- }
- // We use DOMContentLoaded here as that fires for our iframe even when we've
- // arranged for the URL in the iframe to cause an error.
- addEventListener("DOMContentLoaded", function iframeLoaded(dclEvent) {
- if (iframe.contentWindow.location.href == "about:blank" ||
- dclEvent.target != iframe.contentDocument) {
- return;
- }
- removeEventListener("DOMContentLoaded", iframeLoaded, true);
- sendAsyncMessage("test:iframe:load", {url: iframe.contentDocument.location.href});
- // And an event listener for the test responses, which we send to the test
- // via a message.
- iframe.contentWindow.addEventListener("FirefoxAccountsTestResponse", function (fxAccountsEvent) {
- sendAsyncMessage("test:response", {data: fxAccountsEvent.detail.data});
- }, true);
- }, true);
-}, true);
-
-// Return the visibility state of a list of ids.
-addMessageListener("test:check-visibilities", function (message) {
- let result = {};
- for (let id of message.data.ids) {
- let elt = content.document.getElementById(id);
- if (elt) {
- let displayStyle = content.window.getComputedStyle(elt).display;
- if (displayStyle == 'none') {
- result[id] = false;
- } else if (displayStyle == 'block') {
- result[id] = true;
- } else {
- result[id] = "strange: " + displayStyle; // tests should fail!
- }
- } else {
- result[id] = "doesn't exist: " + id;
- }
- }
- sendAsyncMessage("test:check-visibilities-response", result);
-});
-
-addMessageListener("test:load-with-mocked-profile-path", function (message) {
- addEventListener("DOMContentLoaded", function domContentLoaded(event) {
- removeEventListener("DOMContentLoaded", domContentLoaded, true);
- content.getDefaultProfilePath = () => message.data.profilePath;
- // now wait for the iframe to load.
- let iframe = content.document.getElementById("remote");
- iframe.addEventListener("load", function iframeLoaded(loadEvent) {
- if (iframe.contentWindow.location.href == "about:blank" ||
- loadEvent.target != iframe) {
- return;
- }
- iframe.removeEventListener("load", iframeLoaded, true);
- sendAsyncMessage("test:load-with-mocked-profile-path-response",
- {url: iframe.contentDocument.location.href});
- }, true);
- });
- let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
- webNav.loadURI(message.data.url, webNav.LOAD_FLAGS_NONE, null, null, null);
-}, true);
diff --git a/browser/base/content/test/general/contextmenu_common.js b/browser/base/content/test/general/contextmenu_common.js
deleted file mode 100644
index 1a0fa931a..000000000
--- a/browser/base/content/test/general/contextmenu_common.js
+++ /dev/null
@@ -1,324 +0,0 @@
-var lastElement;
-
-function openContextMenuFor(element, shiftkey, waitForSpellCheck) {
- // Context menu should be closed before we open it again.
- is(SpecialPowers.wrap(contextMenu).state, "closed", "checking if popup is closed");
-
- if (lastElement)
- lastElement.blur();
- element.focus();
-
- // Some elements need time to focus and spellcheck before any tests are
- // run on them.
- function actuallyOpenContextMenuFor() {
- lastElement = element;
- var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
- synthesizeMouse(element, 2, 2, eventDetails, element.ownerGlobal);
- }
-
- if (waitForSpellCheck) {
- var { onSpellCheck } = SpecialPowers.Cu.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm", {});
- onSpellCheck(element, actuallyOpenContextMenuFor);
- }
- else {
- actuallyOpenContextMenuFor();
- }
-}
-
-function closeContextMenu() {
- contextMenu.hidePopup();
-}
-
-function getVisibleMenuItems(aMenu, aData) {
- var items = [];
- var accessKeys = {};
- for (var i = 0; i < aMenu.childNodes.length; i++) {
- var item = aMenu.childNodes[i];
- if (item.hidden)
- continue;
-
- var key = item.accessKey;
- if (key)
- key = key.toLowerCase();
-
- var isPageMenuItem = item.hasAttribute("generateditemid");
-
- if (item.nodeName == "menuitem") {
- var isGenerated = item.className == "spell-suggestion"
- || item.className == "sendtab-target";
- if (isGenerated) {
- is(item.id, "", "child menuitem #" + i + " is generated");
- } else if (isPageMenuItem) {
- is(item.id, "", "child menuitem #" + i + " is a generated page menu item");
- } else {
- ok(item.id, "child menuitem #" + i + " has an ID");
- }
- var label = item.getAttribute("label");
- ok(label.length, "menuitem " + item.id + " has a label");
- if (isGenerated) {
- is(key, "", "Generated items shouldn't have an access key");
- items.push("*" + label);
- } else if (isPageMenuItem) {
- items.push("+" + label);
- } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
- item.id != "spell-no-suggestions" &&
- item.id != "spell-add-dictionaries-main" &&
- item.id != "context-savelinktopocket" &&
- item.id != "fill-login-saved-passwords" &&
- item.id != "fill-login-no-logins") {
- ok(key, "menuitem " + item.id + " has an access key");
- if (accessKeys[key])
- ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
- else
- accessKeys[key] = item.id;
- }
- if (!isGenerated && !isPageMenuItem) {
- items.push(item.id);
- }
- if (isPageMenuItem) {
- var p = {};
- p.type = item.getAttribute("type");
- p.icon = item.getAttribute("image");
- p.checked = item.hasAttribute("checked");
- p.disabled = item.hasAttribute("disabled");
- items.push(p);
- } else {
- items.push(!item.disabled);
- }
- } else if (item.nodeName == "menuseparator") {
- ok(true, "--- seperator id is " + item.id);
- items.push("---");
- items.push(null);
- } else if (item.nodeName == "menu") {
- if (isPageMenuItem) {
- item.id = "generated-submenu-" + aData.generatedSubmenuId++;
- }
- ok(item.id, "child menu #" + i + " has an ID");
- if (!isPageMenuItem) {
- ok(key, "menu has an access key");
- if (accessKeys[key])
- ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
- else
- accessKeys[key] = item.id;
- }
- items.push(item.id);
- items.push(!item.disabled);
- // Add a dummy item so that the indexes in checkMenu are the same
- // for expectedItems and actualItems.
- items.push([]);
- items.push(null);
- } else if (item.nodeName == "menugroup") {
- ok(item.id, "child menugroup #" + i + " has an ID");
- items.push(item.id);
- items.push(!item.disabled);
- var menugroupChildren = [];
- for (var child of item.children) {
- if (child.hidden)
- continue;
-
- menugroupChildren.push([child.id, !child.disabled]);
- }
- items.push(menugroupChildren);
- items.push(null);
- } else {
- ok(false, "child #" + i + " of menu ID " + aMenu.id +
- " has an unknown type (" + item.nodeName + ")");
- }
- }
- return items;
-}
-
-function checkContextMenu(expectedItems) {
- is(contextMenu.state, "open", "checking if popup is open");
- var data = { generatedSubmenuId: 1 };
- checkMenu(contextMenu, expectedItems, data);
-}
-
-function checkMenuItem(actualItem, actualEnabled, expectedItem, expectedEnabled, index) {
- is(actualItem, expectedItem,
- "checking item #" + index/2 + " (" + expectedItem + ") name");
-
- if (typeof expectedEnabled == "object" && expectedEnabled != null ||
- typeof actualEnabled == "object" && actualEnabled != null) {
-
- ok(!(actualEnabled == null), "actualEnabled is not null");
- ok(!(expectedEnabled == null), "expectedEnabled is not null");
- is(typeof actualEnabled, typeof expectedEnabled, "checking types");
-
- if (typeof actualEnabled != typeof expectedEnabled ||
- actualEnabled == null || expectedEnabled == null)
- return;
-
- is(actualEnabled.type, expectedEnabled.type,
- "checking item #" + index/2 + " (" + expectedItem + ") type attr value");
- var icon = actualEnabled.icon;
- if (icon) {
- var tmp = "";
- var j = icon.length - 1;
- while (j && icon[j] != "/") {
- tmp = icon[j--] + tmp;
- }
- icon = tmp;
- }
- is(icon, expectedEnabled.icon,
- "checking item #" + index/2 + " (" + expectedItem + ") icon attr value");
- is(actualEnabled.checked, expectedEnabled.checked,
- "checking item #" + index/2 + " (" + expectedItem + ") has checked attr");
- is(actualEnabled.disabled, expectedEnabled.disabled,
- "checking item #" + index/2 + " (" + expectedItem + ") has disabled attr");
- } else if (expectedEnabled != null)
- is(actualEnabled, expectedEnabled,
- "checking item #" + index/2 + " (" + expectedItem + ") enabled state");
-}
-
-/*
- * checkMenu - checks to see if the specified <menupopup> contains the
- * expected items and state.
- * expectedItems is a array of (1) item IDs and (2) a boolean specifying if
- * the item is enabled or not (or null to ignore it). Submenus can be checked
- * by providing a nested array entry after the expected <menu> ID.
- * For example: ["blah", true, // item enabled
- * "submenu", null, // submenu
- * ["sub1", true, // submenu contents
- * "sub2", false], null, // submenu contents
- * "lol", false] // item disabled
- *
- */
-function checkMenu(menu, expectedItems, data) {
- var actualItems = getVisibleMenuItems(menu, data);
- // ok(false, "Items are: " + actualItems);
- for (var i = 0; i < expectedItems.length; i+=2) {
- var actualItem = actualItems[i];
- var actualEnabled = actualItems[i + 1];
- var expectedItem = expectedItems[i];
- var expectedEnabled = expectedItems[i + 1];
- if (expectedItem instanceof Array) {
- ok(true, "Checking submenu/menugroup...");
- var previousId = expectedItems[i - 2]; // The last item was the menu ID.
- var previousItem = menu.getElementsByAttribute("id", previousId)[0];
- ok(previousItem, (previousItem ? previousItem.nodeName : "item") + " with previous id (" + previousId + ") found");
- if (previousItem && previousItem.nodeName == "menu") {
- ok(previousItem, "got a submenu element of id='" + previousId + "'");
- is(previousItem.nodeName, "menu", "submenu element of id='" + previousId +
- "' has expected nodeName");
- checkMenu(previousItem.menupopup, expectedItem, data, i);
- } else if (previousItem && previousItem.nodeName == "menugroup") {
- ok(expectedItem.length, "menugroup must not be empty");
- for (var j = 0; j < expectedItem.length / 2; j++) {
- checkMenuItem(actualItems[i][j][0], actualItems[i][j][1], expectedItem[j*2], expectedItem[j*2+1], i+j*2);
- }
- i += j;
- } else {
- ok(false, "previous item is not a menu or menugroup");
- }
- } else {
- checkMenuItem(actualItem, actualEnabled, expectedItem, expectedEnabled, i);
- }
- }
- // Could find unexpected extra items at the end...
- is(actualItems.length, expectedItems.length, "checking expected number of menu entries");
-}
-
-let lastElementSelector = null;
-/**
- * Right-clicks on the element that matches `selector` and checks the
- * context menu that appears against the `menuItems` array.
- *
- * @param {String} selector
- * A selector passed to querySelector to find
- * the element that will be referenced.
- * @param {Array} menuItems
- * An array of menuitem ids and their associated enabled state. A state
- * of null means that it will be ignored. Ids of '---' are used for
- * menuseparators.
- * @param {Object} options, optional
- * skipFocusChange: don't move focus to the element before test, useful
- * if you want to delay spell-check initialization
- * offsetX: horizontal mouse offset from the top-left corner of
- * the element, optional
- * offsetY: vertical mouse offset from the top-left corner of the
- * element, optional
- * centered: if true, mouse position is centered in element, defaults
- * to true if offsetX and offsetY are not provided
- * waitForSpellCheck: wait until spellcheck is initialized before
- * starting test
- * preCheckContextMenuFn: callback to run before opening menu
- * onContextMenuShown: callback to run when the context menu is shown
- * postCheckContextMenuFn: callback to run after opening menu
- * @return {Promise} resolved after the test finishes
- */
-function* test_contextmenu(selector, menuItems, options={}) {
- contextMenu = document.getElementById("contentAreaContextMenu");
- is(contextMenu.state, "closed", "checking if popup is closed");
-
- // Default to centered if no positioning is defined.
- if (!options.offsetX && !options.offsetY) {
- options.centered = true;
- }
-
- if (!options.skipFocusChange) {
- yield ContentTask.spawn(gBrowser.selectedBrowser,
- [lastElementSelector, selector],
- function*([contentLastElementSelector, contentSelector]) {
- if (contentLastElementSelector) {
- let contentLastElement = content.document.querySelector(contentLastElementSelector);
- contentLastElement.blur();
- }
- let element = content.document.querySelector(contentSelector);
- element.focus();
- });
- lastElementSelector = selector;
- info(`Moved focus to ${selector}`);
- }
-
- if (options.preCheckContextMenuFn) {
- yield options.preCheckContextMenuFn();
- info("Completed preCheckContextMenuFn");
- }
-
- if (options.waitForSpellCheck) {
- info("Waiting for spell check");
- yield ContentTask.spawn(gBrowser.selectedBrowser, selector, function*(contentSelector) {
- let {onSpellCheck} = Cu.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm", {});
- let element = content.document.querySelector(contentSelector);
- yield new Promise(resolve => onSpellCheck(element, resolve));
- info("Spell check running");
- });
- }
-
- let awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouse(selector, options.offsetX || 0, options.offsetY || 0, {
- type: "contextmenu",
- button: 2,
- shiftkey: options.shiftkey,
- centered: options.centered
- },
- gBrowser.selectedBrowser);
- yield awaitPopupShown;
- info("Popup Shown");
-
- if (options.onContextMenuShown) {
- yield options.onContextMenuShown();
- info("Completed onContextMenuShown");
- }
-
- if (menuItems) {
- if (Services.prefs.getBoolPref("devtools.inspector.enabled")) {
- let inspectItems = ["---", null,
- "context-inspect", true];
- menuItems = menuItems.concat(inspectItems);
- }
-
- checkContextMenu(menuItems);
- }
-
- let awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
-
- if (options.postCheckContextMenuFn) {
- yield options.postCheckContextMenuFn();
- info("Completed postCheckContextMenuFn");
- }
-
- contextMenu.hidePopup();
- yield awaitPopupHidden;
-}
diff --git a/browser/base/content/test/general/ctxmenu-image.png b/browser/base/content/test/general/ctxmenu-image.png
deleted file mode 100644
index 4c3be5084..000000000
--- a/browser/base/content/test/general/ctxmenu-image.png
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/discovery.html b/browser/base/content/test/general/discovery.html
deleted file mode 100644
index 1679e6545..000000000
--- a/browser/base/content/test/general/discovery.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head id="linkparent">
- <title>Autodiscovery Test</title>
- </head>
- <body>
- </body>
-</html>
diff --git a/browser/base/content/test/general/download_page.html b/browser/base/content/test/general/download_page.html
deleted file mode 100644
index 4f9154033..000000000
--- a/browser/base/content/test/general/download_page.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=676619
--->
- <head>
- <title>Test for the download attribute</title>
-
- </head>
- <body>
- <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=676619">Bug 676619</a>
- <br/>
- <ul>
- <li><a href="data:text/plain,Hey What are you looking for?"
- download="test.txt" id="link1">Download "test.txt"</a></li>
- <li><a href="video.ogg"
- download id="link2">Download "video.ogg"</a></li>
- <li><a href="video.ogg"
- download="just some video" id="link3">Download "just some video"</a></li>
- <li><a href="data:text/plain,test"
- download="with-target.txt" id="link4">Download "with-target.txt"</a></li>
- <li><a href="javascript:(1+2)+''"
- download="javascript.txt" id="link5">Download "javascript.txt"</a></li>
- </ul>
- <script>
- var li = document.createElement('li');
- var a = document.createElement('a');
-
- a.href = window.URL.createObjectURL(new Blob(["just text"])) ;
- a.download = "test.blob";
- a.id = "link6";
- a.textContent = 'Download "test.blob"';
-
- li.appendChild(a);
- document.getElementsByTagName('ul')[0].appendChild(li);
-
- window.addEventListener("beforeunload", function (evt) {
- document.getElementById("unload-flag").textContent = "Fail";
- });
- </script>
- <ul>
- <li><a href="http://example.com/"
- download="example.com" id="link7" target="_blank">Download "example.com"</a></li>
- <ul>
- <div id="unload-flag">Okay</div>
- </body>
-</html>
diff --git a/browser/base/content/test/general/dummy_page.html b/browser/base/content/test/general/dummy_page.html
deleted file mode 100644
index 1a87e2840..000000000
--- a/browser/base/content/test/general/dummy_page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>Dummy test page</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<p>Dummy test page</p>
-</body>
-</html>
diff --git a/browser/base/content/test/general/feed_discovery.html b/browser/base/content/test/general/feed_discovery.html
deleted file mode 100644
index baecba19b..000000000
--- a/browser/base/content/test/general/feed_discovery.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=377611
--->
- <head>
- <title>Test for feed discovery</title>
- <meta charset="utf-8">
-
- <!-- Straight up standard -->
- <link rel="alternate" type="application/atom+xml" title="1" href="/1.atom" />
- <link rel="alternate" type="application/rss+xml" title="2" href="/2.rss" />
- <link rel="feed" title="3" href="/3.xml" />
-
- <!-- rel is a space-separated list -->
- <link rel=" alternate " type="application/atom+xml" title="4" href="/4.atom" />
- <link rel="foo alternate" type="application/atom+xml" title="5" href="/5.atom" />
- <link rel="alternate foo" type="application/atom+xml" title="6" href="/6.atom" />
- <link rel="foo alternate foo" type="application/atom+xml" title="7" href="/7.atom" />
- <link rel="meat feed cake" title="8" href="/8.atom" />
-
- <!-- rel is case-insensitive -->
- <link rel="ALTERNate" type="application/atom+xml" title="9" href="/9.atom" />
- <link rel="fEEd" title="10" href="/10.atom" />
-
- <!-- type can have leading and trailing whitespace -->
- <link rel="alternate" type=" application/atom+xml " title="11" href="/11.atom" />
-
- <!-- type is case-insensitive -->
- <link rel="alternate" type="aPPliCAtion/ATom+xML" title="12" href="/12.atom" />
-
- <!-- "feed stylesheet" is a feed, though "alternate stylesheet" isn't -->
- <link rel="feed stylesheet" title="13" href="/13.atom" />
-
- <!-- hyphens or letters around rel not allowed -->
- <link rel="disabled-alternate" type="application/atom+xml" title="Bogus1" href="/Bogus1" />
- <link rel="alternates" type="application/atom+xml" title="Bogus2" href="/Bogus2" />
- <link rel=" alternate-like" type="application/atom+xml" title="Bogus3" href="/Bogus3" />
-
- <!-- don't tolerate text/xml if title includes 'rss' not as a word -->
- <link rel="alternate" type="text/xml" title="Bogus4 scissorsshaped" href="/Bogus4" />
-
- <!-- don't tolerate application/xml if title includes 'rss' not as a word -->
- <link rel="alternate" type="application/xml" title="Bogus5 scissorsshaped" href="/Bogus5" />
-
- <!-- don't tolerate application/rdf+xml if title includes 'rss' not as a word -->
- <link rel="alternate" type="application/rdf+xml" title="Bogus6 scissorsshaped" href="/Bogus6" />
-
- <!-- don't tolerate random types -->
- <link rel="alternate" type="text/plain" title="Bogus7 rss" href="/Bogus7" />
-
- <!-- don't find Atom by title -->
- <link rel="foopy" type="application/atom+xml" title="Bogus8 Atom and RSS" href="/Bogus8" />
-
- <!-- don't find application/rss+xml by title -->
- <link rel="goats" type="application/rss+xml" title="Bogus9 RSS and Atom" href="/Bogus9" />
-
- <!-- don't find application/rdf+xml by title -->
- <link rel="alternate" type="application/rdf+xml" title="Bogus10 RSS and Atom" href="/Bogus10" />
-
- <!-- don't find application/xml by title -->
- <link rel="alternate" type="application/xml" title="Bogus11 RSS and Atom" href="/Bogus11" />
-
- <!-- don't find text/xml by title -->
- <link rel="alternate" type="text/xml" title="Bogus12 RSS and Atom" href="/Bogus12" />
-
- <!-- alternate and stylesheet isn't a feed -->
- <link rel="alternate stylesheet" type="application/rss+xml" title="Bogus13 RSS" href="/Bogus13" />
- </head>
- <body>
- </body>
-</html>
-
diff --git a/browser/base/content/test/general/feed_tab.html b/browser/base/content/test/general/feed_tab.html
deleted file mode 100644
index 50903f48b..000000000
--- a/browser/base/content/test/general/feed_tab.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=458579
--->
- <head>
- <title>Test for page info feeds tab</title>
-
- <!-- Straight up standard -->
- <link rel="alternate" type="application/atom+xml" title="1" href="/1.atom" />
- <link rel="alternate" type="application/rss+xml" title="2" href="/2.rss" />
- <link rel="feed" title="3" href="/3.xml" />
-
- </head>
- <body>
- </body>
-</html>
diff --git a/browser/base/content/test/general/file_bug1045809_1.html b/browser/base/content/test/general/file_bug1045809_1.html
deleted file mode 100644
index 9baf2d45d..000000000
--- a/browser/base/content/test/general/file_bug1045809_1.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
- <head>
- </head>
- <body>
- <iframe src="http://test1.example.com/browser/browser/base/content/test/general/file_bug1045809_2.html"></iframe>
- </body>
-</html>
diff --git a/browser/base/content/test/general/file_bug1045809_2.html b/browser/base/content/test/general/file_bug1045809_2.html
deleted file mode 100644
index 67a297dbc..000000000
--- a/browser/base/content/test/general/file_bug1045809_2.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
- <head>
- </head>
- <body>
- <div id="mixedContentContainer">Mixed Content is here</div>
- </body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_1.html b/browser/base/content/test/general/file_bug822367_1.html
deleted file mode 100644
index 62f42d226..000000000
--- a/browser/base/content/test/general/file_bug822367_1.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 1 for Mixed Content Blocker User Override - Mixed Script
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 1 for Bug 822367</title>
-</head>
-<body>
- <div id="testContent">
- <p id="p1"></p>
- </div>
- <script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">
- </script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_1.js b/browser/base/content/test/general/file_bug822367_1.js
deleted file mode 100644
index 175de363b..000000000
--- a/browser/base/content/test/general/file_bug822367_1.js
+++ /dev/null
@@ -1 +0,0 @@
-document.getElementById('p1').innerHTML="hello";
diff --git a/browser/base/content/test/general/file_bug822367_2.html b/browser/base/content/test/general/file_bug822367_2.html
deleted file mode 100644
index fe56ee213..000000000
--- a/browser/base/content/test/general/file_bug822367_2.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 2 for Mixed Content Blocker User Override - Mixed Display
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 2 for Bug 822367 - Mixed Display</title>
-</head>
-<body>
- <div id="testContent">
- <img src="http://example.com/tests/image/test/mochitest/blue.png">
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_3.html b/browser/base/content/test/general/file_bug822367_3.html
deleted file mode 100644
index c1ff2c000..000000000
--- a/browser/base/content/test/general/file_bug822367_3.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 3 for Mixed Content Blocker User Override - Mixed Script and Display
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 3 for Bug 822367</title>
- <script>
- function foo() {
- var x = document.createElement('p');
- x.setAttribute("id", "p2");
- x.innerHTML = "bye";
- document.getElementById("testContent").appendChild(x);
- }
- </script>
-</head>
-<body>
- <div id="testContent">
- <p id="p1"></p>
- <img src="http://example.com/tests/image/test/mochitest/blue.png" onload="foo()">
- </div>
- <script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">
- </script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_4.html b/browser/base/content/test/general/file_bug822367_4.html
deleted file mode 100644
index 9a073143f..000000000
--- a/browser/base/content/test/general/file_bug822367_4.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 4 for Mixed Content Blocker User Override - Mixed Script and Display
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 4 for Bug 822367</title>
-</head>
-<body>
- <div id="testContent">
- <p id="p1"></p>
- </div>
- <script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_4.js">
- </script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_4.js b/browser/base/content/test/general/file_bug822367_4.js
deleted file mode 100644
index 301db89c7..000000000
--- a/browser/base/content/test/general/file_bug822367_4.js
+++ /dev/null
@@ -1 +0,0 @@
-document.location = "https://example.com/browser/browser/base/content/test/general/file_bug822367_4B.html";
diff --git a/browser/base/content/test/general/file_bug822367_4B.html b/browser/base/content/test/general/file_bug822367_4B.html
deleted file mode 100644
index 76ea2b623..000000000
--- a/browser/base/content/test/general/file_bug822367_4B.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 4B for Mixed Content Blocker User Override - Location Changed
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 4B Location Change for Bug 822367</title>
-</head>
-<body>
- <div id="testContent">
- <p id="p1"></p>
- </div>
- <script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">
- </script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_5.html b/browser/base/content/test/general/file_bug822367_5.html
deleted file mode 100644
index 3c9a9317e..000000000
--- a/browser/base/content/test/general/file_bug822367_5.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 5 for Mixed Content Blocker User Override - Mixed Script in document.open()
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 5 for Bug 822367</title>
- <script>
- function createDoc()
- {
- var doc=document.open("text/html", "replace");
- doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
- doc.close();
- }
- </script>
-</head>
-<body>
- <div id="testContent">
- <img src="https://example.com/tests/image/test/mochitest/blue.png" onload="createDoc()">
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug822367_6.html b/browser/base/content/test/general/file_bug822367_6.html
deleted file mode 100644
index baa5674c2..000000000
--- a/browser/base/content/test/general/file_bug822367_6.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 6 for Mixed Content Blocker User Override - Mixed Script in document.open() within an iframe
-https://bugzilla.mozilla.org/show_bug.cgi?id=822367
--->
-<head>
- <meta charset="utf-8">
- <title>Test 6 for Bug 822367</title>
-</head>
-<body>
- <div id="testContent">
- <iframe name="f1" id="f1" src="https://example.com/browser/browser/base/content/test/general/file_bug822367_5.html"></iframe>
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug902156.js b/browser/base/content/test/general/file_bug902156.js
deleted file mode 100644
index f943dd628..000000000
--- a/browser/base/content/test/general/file_bug902156.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Once the mixed content blocker is disabled for the page, this scripts loads
- * and updates the text inside the div container.
- */
-document.getElementById("mctestdiv").innerHTML = "Mixed Content Blocker disabled";
diff --git a/browser/base/content/test/general/file_bug902156_1.html b/browser/base/content/test/general/file_bug902156_1.html
deleted file mode 100644
index e3625de99..000000000
--- a/browser/base/content/test/general/file_bug902156_1.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 1 for Bug 902156 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=902156
--->
-<head>
- <meta charset="utf-8">
- <title>Test 1 for Bug 902156</title>
-</head>
-<body>
- <div id="mctestdiv">Mixed Content Blocker enabled</div>
- <script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug902156.js" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug902156_2.html b/browser/base/content/test/general/file_bug902156_2.html
deleted file mode 100644
index 25aff3349..000000000
--- a/browser/base/content/test/general/file_bug902156_2.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 2 for Bug 902156 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=902156
--->
-<head>
- <meta charset="utf-8">
- <title>Test 2 for Bug 902156</title>
-</head>
-<body>
- <div id="mctestdiv">Mixed Content Blocker enabled</div>
- <a href="https://test2.example.com/browser/browser/base/content/test/general/file_bug902156_1.html"
- id="mctestlink" target="_top">Go to http site</a>
- <script src="http://test2.example.com/browser/browser/base/content/test/general/file_bug902156.js" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug902156_3.html b/browser/base/content/test/general/file_bug902156_3.html
deleted file mode 100644
index 65805adff..000000000
--- a/browser/base/content/test/general/file_bug902156_3.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 3 for Bug 902156 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=902156
--->
-<head>
- <meta charset="utf-8">
- <title>Test 3 for Bug 902156</title>
-</head>
-<body>
- <div id="mctestdiv">Mixed Content Blocker enabled</div>
- <script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug902156.js" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug906190.js b/browser/base/content/test/general/file_bug906190.js
deleted file mode 100644
index f943dd628..000000000
--- a/browser/base/content/test/general/file_bug906190.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Once the mixed content blocker is disabled for the page, this scripts loads
- * and updates the text inside the div container.
- */
-document.getElementById("mctestdiv").innerHTML = "Mixed Content Blocker disabled";
diff --git a/browser/base/content/test/general/file_bug906190.sjs b/browser/base/content/test/general/file_bug906190.sjs
deleted file mode 100644
index bff126874..000000000
--- a/browser/base/content/test/general/file_bug906190.sjs
+++ /dev/null
@@ -1,17 +0,0 @@
-function handleRequest(request, response) {
- var page = "<!DOCTYPE html><html><body>bug 906190</body></html>";
- var path = "https://test1.example.com/browser/browser/base/content/test/general/";
- var url;
-
- if (request.queryString.includes('bad-redirection=1')) {
- url = path + "this_page_does_not_exist.html";
- } else {
- url = path + "file_bug906190_redirected.html";
- }
-
- response.setHeader("Cache-Control", "no-cache", false);
- response.setHeader("Content-Type", "text/html", false);
- response.setStatusLine(request.httpVersion, "302", "Found");
- response.setHeader("Location", url, false);
- response.write(page);
-}
diff --git a/browser/base/content/test/general/file_bug906190_1.html b/browser/base/content/test/general/file_bug906190_1.html
deleted file mode 100644
index cbb3cac26..000000000
--- a/browser/base/content/test/general/file_bug906190_1.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 1 for Bug 906190 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=906190
--->
-<head>
- <meta charset="utf-8">
- <title>Test 1 for Bug 906190</title>
-</head>
-<body>
- <div id="mctestdiv">Mixed Content Blocker enabled</div>
- <script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug906190.js" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug906190_2.html b/browser/base/content/test/general/file_bug906190_2.html
deleted file mode 100644
index 70c7c61cf..000000000
--- a/browser/base/content/test/general/file_bug906190_2.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 2 for Bug 906190 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=906190
--->
-<head>
- <meta charset="utf-8">
- <title>Test 2 for Bug 906190</title>
-</head>
-<body>
- <div id="mctestdiv">Mixed Content Blocker enabled</div>
- <script src="http://test2.example.com/browser/browser/base/content/test/general/file_bug906190.js" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug906190_3_4.html b/browser/base/content/test/general/file_bug906190_3_4.html
deleted file mode 100644
index aea6648a9..000000000
--- a/browser/base/content/test/general/file_bug906190_3_4.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 3 and 4 for Bug 906190 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=906190
--->
-<head>
- <meta charset="utf-8">
- <meta http-equiv="refresh" content="0; url=https://test1.example.com/browser/browser/base/content/test/general/file_bug906190_redirected.html">
- <title>Test 3 and 4 for Bug 906190</title>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug906190_redirected.html b/browser/base/content/test/general/file_bug906190_redirected.html
deleted file mode 100644
index cc324bd25..000000000
--- a/browser/base/content/test/general/file_bug906190_redirected.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Redirected Page of Test 3 to 6 for Bug 906190 - See file browser_bug902156.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=906190
--->
-<head>
- <meta charset="utf-8">
- <title>Redirected Page for Bug 906190</title>
-</head>
-<body>
- <div id="mctestdiv">Mixed Content Blocker enabled</div>
- <script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug906190.js" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug970276_favicon1.ico b/browser/base/content/test/general/file_bug970276_favicon1.ico
deleted file mode 100644
index d44438903..000000000
--- a/browser/base/content/test/general/file_bug970276_favicon1.ico
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/file_bug970276_favicon2.ico b/browser/base/content/test/general/file_bug970276_favicon2.ico
deleted file mode 100644
index d44438903..000000000
--- a/browser/base/content/test/general/file_bug970276_favicon2.ico
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/file_bug970276_popup1.html b/browser/base/content/test/general/file_bug970276_popup1.html
deleted file mode 100644
index 5ce7dab87..000000000
--- a/browser/base/content/test/general/file_bug970276_popup1.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test file for bug 970276.</title>
-
- <!--Set a favicon; that's the whole point of this file.-->
- <link rel="icon" href="file_bug970276_favicon1.ico">
-</head>
-<body>
- Test file for bug 970276.
-
- <iframe src="file_bug970276_popup2.html">
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_bug970276_popup2.html b/browser/base/content/test/general/file_bug970276_popup2.html
deleted file mode 100644
index 0b9e5294e..000000000
--- a/browser/base/content/test/general/file_bug970276_popup2.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test file for bug 970276.</title>
-
- <!--Set a favicon; that's the whole point of this file.-->
- <link rel="icon" href="file_bug970276_favicon2.ico">
-</head>
-<body>
- Test inner file for bug 970276.
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_csp_block_all_mixedcontent.html b/browser/base/content/test/general/file_csp_block_all_mixedcontent.html
deleted file mode 100644
index 93a7f13d9..000000000
--- a/browser/base/content/test/general/file_csp_block_all_mixedcontent.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html><head><meta charset="utf-8">
-<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
-</head>
-<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
-<body>
-<script src="http://example.com/browser/browser/base/content/test/general/file_csp_block_all_mixedcontent.js"/>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_csp_block_all_mixedcontent.js b/browser/base/content/test/general/file_csp_block_all_mixedcontent.js
deleted file mode 100644
index dc6d6a64e..000000000
--- a/browser/base/content/test/general/file_csp_block_all_mixedcontent.js
+++ /dev/null
@@ -1,3 +0,0 @@
-// empty script file just used for testing Bug 1122236.
-// Making sure the UI is not degraded when blocking
-// mixed content using the CSP directive: block-all-mixed-content.
diff --git a/browser/base/content/test/general/file_documentnavigation_frameset.html b/browser/base/content/test/general/file_documentnavigation_frameset.html
deleted file mode 100644
index beb01addf..000000000
--- a/browser/base/content/test/general/file_documentnavigation_frameset.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<html id="outer">
-
-<frameset rows="30%, 70%">
- <frame src="data:text/html,&lt;html id='htmlframe1' &gt;&lt;body id='framebody1'&gt;&lt;input id='i1'&gt;&lt;body&gt;&lt;/html&gt;">
- <frameset cols="30%, 33%, 34%">
- <frame src="data:text/html,&lt;html id='htmlframe2'&gt;&lt;body id='framebody2'&gt;&lt;input id='i2'&gt;&lt;body&gt;&lt;/html&gt;">
- <frame src="data:text/html,&lt;html id='htmlframe3'&gt;&lt;body id='framebody3'&gt;&lt;input id='i3'&gt;&lt;body&gt;&lt;/html&gt;">
- <frame src="data:text/html,&lt;html id='htmlframe4'&gt;&lt;body id='framebody4'&gt;&lt;input id='i4'&gt;&lt;body&gt;&lt;/html&gt;">
- </frameset>
-</frameset>
-
-</html>
diff --git a/browser/base/content/test/general/file_double_close_tab.html b/browser/base/content/test/general/file_double_close_tab.html
deleted file mode 100644
index 0bead5efc..000000000
--- a/browser/base/content/test/general/file_double_close_tab.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>Test page that blocks beforeunload. Used in tests for bug 1050638 and bug 305085</title>
- </head>
- <body>
- This page will block beforeunload. It should still be user-closable at all times.
- <script>
- window.onbeforeunload = function() {
- return "stop";
- };
- </script>
- </body>
-</html>
diff --git a/browser/base/content/test/general/file_favicon_change.html b/browser/base/content/test/general/file_favicon_change.html
deleted file mode 100644
index 18ac6526b..000000000
--- a/browser/base/content/test/general/file_favicon_change.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <link rel="icon" href="http://example.org/one-icon" type="image/ico" id="i">
-</head>
-<body>
- <script>
- window.addEventListener("PleaseChangeFavicon", function() {
- var ico = document.getElementById("i");
- ico.setAttribute("href", "http://example.org/other-icon");
- });
- </script>
-</body></html>
diff --git a/browser/base/content/test/general/file_favicon_change_not_in_document.html b/browser/base/content/test/general/file_favicon_change_not_in_document.html
deleted file mode 100644
index deebb07dc..000000000
--- a/browser/base/content/test/general/file_favicon_change_not_in_document.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <link rel="icon" href="http://example.org/one-icon" type="image/ico" id="i">
-</head>
-<body onload="onload()">
- <script>
- function onload() {
- var ico = document.createElement("link");
- ico.setAttribute("rel", "icon");
- ico.setAttribute("type", "image/ico");
- ico.setAttribute("href", "http://example.org/other-icon");
- setTimeout(function() {
- ico.setAttribute("href", "http://example.org/yet-another-icon");
- document.getElementById("i").remove();
- document.head.appendChild(ico);
- }, 1000);
- }
- </script>
-</body></html>
-
diff --git a/browser/base/content/test/general/file_fullscreen-window-open.html b/browser/base/content/test/general/file_fullscreen-window-open.html
deleted file mode 100644
index 1584f4c98..000000000
--- a/browser/base/content/test/general/file_fullscreen-window-open.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!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);
-
- document.getElementById("test").addEventListener("click", onClick, true);
- }, 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);
- }
- </script>
- <a id="test" href="" data-test-param="">Test</a>
- </body>
-</html>
diff --git a/browser/base/content/test/general/file_generic_favicon.ico b/browser/base/content/test/general/file_generic_favicon.ico
deleted file mode 100644
index d44438903..000000000
--- a/browser/base/content/test/general/file_generic_favicon.ico
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/file_mediaPlayback.html b/browser/base/content/test/general/file_mediaPlayback.html
deleted file mode 100644
index a6979287e..000000000
--- a/browser/base/content/test/general/file_mediaPlayback.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<audio src="audio.ogg" controls loop>
diff --git a/browser/base/content/test/general/file_mixedContentFramesOnHttp.html b/browser/base/content/test/general/file_mixedContentFramesOnHttp.html
deleted file mode 100644
index 3bd16aea5..000000000
--- a/browser/base/content/test/general/file_mixedContentFramesOnHttp.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test for https://bugzilla.mozilla.org/show_bug.cgi?id=1182551
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 1182551</title>
-</head>
-<body>
- <p>Test for Bug 1182551. This is an HTTP top level page. We include an HTTPS iframe that loads mixed passive content.</p>
- <iframe src="https://example.org/browser/browser/base/content/test/general/file_mixedPassiveContent.html"></iframe>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_mixedContentFromOnunload.html b/browser/base/content/test/general/file_mixedContentFromOnunload.html
deleted file mode 100644
index fb28a2889..000000000
--- a/browser/base/content/test/general/file_mixedContentFromOnunload.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test for https://bugzilla.mozilla.org/show_bug.cgi?id=947079
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 947079</title>
-</head>
-<body>
- <p>Test for Bug 947079</p>
- <script>
- window.addEventListener('unload', function() {
- new Image().src = 'http://mochi.test:8888/tests/image/test/mochitest/blue.png';
- });
- </script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_mixedContentFromOnunload_test1.html b/browser/base/content/test/general/file_mixedContentFromOnunload_test1.html
deleted file mode 100644
index 1d027b036..000000000
--- a/browser/base/content/test/general/file_mixedContentFromOnunload_test1.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 1 for https://bugzilla.mozilla.org/show_bug.cgi?id=947079
-Page with no insecure subresources
--->
-<head>
- <meta charset="utf-8">
- <title>Test 1 for Bug 947079</title>
-</head>
-<body>
- <p>There are no insecure resource loads on this page</p>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_mixedContentFromOnunload_test2.html b/browser/base/content/test/general/file_mixedContentFromOnunload_test2.html
deleted file mode 100644
index 4813337cc..000000000
--- a/browser/base/content/test/general/file_mixedContentFromOnunload_test2.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test 2 for https://bugzilla.mozilla.org/show_bug.cgi?id=947079
-Page with an insecure image load
--->
-<head>
- <meta charset="utf-8">
- <title>Test 2 for Bug 947079</title>
-</head>
-<body>
- <p>Page with http image load</p>
- <img src="http://test2.example.com/tests/image/test/mochitest/blue.png">
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_mixedPassiveContent.html b/browser/base/content/test/general/file_mixedPassiveContent.html
deleted file mode 100644
index a60ac94e8..000000000
--- a/browser/base/content/test/general/file_mixedPassiveContent.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-Test for https://bugzilla.mozilla.org/show_bug.cgi?id=1182551
--->
-<head>
- <meta charset="utf-8">
- <title>HTTPS page with HTTP image</title>
-</head>
-<body>
- <img src="http://mochi.test:8888/tests/image/test/mochitest/blue.png">
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_trackingUI_6.html b/browser/base/content/test/general/file_trackingUI_6.html
deleted file mode 100644
index 52e1ae63f..000000000
--- a/browser/base/content/test/general/file_trackingUI_6.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="UTF-8">
- <title>Testing the shield from fetch and XHR</title>
-</head>
-<body>
- <p>Hello there!</p>
- <script type="application/javascript; version=1.8">
- function test_fetch() {
- let url = "http://trackertest.org/browser/browser/base/content/test/general/file_trackingUI_6.js";
- return fetch(url);
- }
- </script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/file_trackingUI_6.js b/browser/base/content/test/general/file_trackingUI_6.js
deleted file mode 100644
index f7ac687cf..000000000
--- a/browser/base/content/test/general/file_trackingUI_6.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Some code goes here! */
-void 0;
diff --git a/browser/base/content/test/general/file_trackingUI_6.js^headers^ b/browser/base/content/test/general/file_trackingUI_6.js^headers^
deleted file mode 100644
index cb762eff8..000000000
--- a/browser/base/content/test/general/file_trackingUI_6.js^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Access-Control-Allow-Origin: *
diff --git a/browser/base/content/test/general/file_with_favicon.html b/browser/base/content/test/general/file_with_favicon.html
deleted file mode 100644
index 0702b4aab..000000000
--- a/browser/base/content/test/general/file_with_favicon.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test file for bugs with favicons</title>
-
- <!--Set a favicon; that's the whole point of this file.-->
- <link rel="icon" href="file_generic_favicon.ico">
-</head>
-<body>
- Test file for bugs with favicons
-</body>
-</html>
diff --git a/browser/base/content/test/general/fxa_profile_handler.sjs b/browser/base/content/test/general/fxa_profile_handler.sjs
deleted file mode 100644
index 7160b76d0..000000000
--- a/browser/base/content/test/general/fxa_profile_handler.sjs
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// This is basically an echo server!
-// We just grab responseStatus and responseBody query params!
-
-function reallyHandleRequest(request, response) {
- var query = "?" + request.queryString;
-
- var responseStatus = 200;
- var match = /responseStatus=([^&]*)/.exec(query);
- if (match) {
- responseStatus = parseInt(match[1]);
- }
-
- var responseBody = "";
- match = /responseBody=([^&]*)/.exec(query);
- if (match) {
- responseBody = decodeURIComponent(match[1]);
- }
-
- response.setStatusLine("1.0", responseStatus, "OK");
- response.write(responseBody);
-}
-
-function handleRequest(request, response)
-{
- try {
- reallyHandleRequest(request, response);
- } catch (e) {
- response.setStatusLine("1.0", 500, "NotOK");
- response.write("Error handling request: " + e);
- }
-}
diff --git a/browser/base/content/test/general/gZipOfflineChild.cacheManifest b/browser/base/content/test/general/gZipOfflineChild.cacheManifest
deleted file mode 100644
index ae0545d12..000000000
--- a/browser/base/content/test/general/gZipOfflineChild.cacheManifest
+++ /dev/null
@@ -1,2 +0,0 @@
-CACHE MANIFEST
-gZipOfflineChild.html
diff --git a/browser/base/content/test/general/gZipOfflineChild.cacheManifest^headers^ b/browser/base/content/test/general/gZipOfflineChild.cacheManifest^headers^
deleted file mode 100644
index 257f2eb60..000000000
--- a/browser/base/content/test/general/gZipOfflineChild.cacheManifest^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/cache-manifest
diff --git a/browser/base/content/test/general/gZipOfflineChild.html b/browser/base/content/test/general/gZipOfflineChild.html
deleted file mode 100644
index ea2caa125..000000000
--- a/browser/base/content/test/general/gZipOfflineChild.html
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/gZipOfflineChild.html^headers^ b/browser/base/content/test/general/gZipOfflineChild.html^headers^
deleted file mode 100644
index 4204d8601..000000000
--- a/browser/base/content/test/general/gZipOfflineChild.html^headers^
+++ /dev/null
@@ -1,2 +0,0 @@
-Content-Type: text/html
-Content-Encoding: gzip
diff --git a/browser/base/content/test/general/gZipOfflineChild_uncompressed.html b/browser/base/content/test/general/gZipOfflineChild_uncompressed.html
deleted file mode 100644
index 4ab8f8d5e..000000000
--- a/browser/base/content/test/general/gZipOfflineChild_uncompressed.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<html manifest="gZipOfflineChild.cacheManifest">
-<head>
- <!-- This file is gzipped to create gZipOfflineChild.html -->
-<title></title>
-<script type="text/javascript">
-
-function finish(success) {
- window.parent.postMessage(success, "*");
-}
-
-applicationCache.oncached = function() { finish("oncache"); }
-applicationCache.onnoupdate = function() { finish("onupdate"); }
-applicationCache.onerror = function() { finish("onerror"); }
-
-</script>
-</head>
-
-<body>
-<h1>Child</h1>
-</body>
-</html>
diff --git a/browser/base/content/test/general/head.js b/browser/base/content/test/general/head.js
deleted file mode 100644
index 6c28615fe..000000000
--- a/browser/base/content/test/general/head.js
+++ /dev/null
@@ -1,1069 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "TabCrashHandler",
- "resource:///modules/ContentCrashHandlers.jsm");
-
-/**
- * Wait for a <notification> to be closed then call the specified callback.
- */
-function waitForNotificationClose(notification, cb) {
- let parent = notification.parentNode;
-
- let observer = new MutationObserver(function onMutatations(mutations) {
- for (let mutation of mutations) {
- for (let i = 0; i < mutation.removedNodes.length; i++) {
- let node = mutation.removedNodes.item(i);
- if (node != notification) {
- continue;
- }
- observer.disconnect();
- cb();
- }
- }
- });
- observer.observe(parent, {childList: true});
-}
-
-function closeAllNotifications () {
- let notificationBox = document.getElementById("global-notificationbox");
-
- if (!notificationBox || !notificationBox.currentNotification) {
- return Promise.resolve();
- }
-
- let deferred = Promise.defer();
- for (let notification of notificationBox.allNotifications) {
- waitForNotificationClose(notification, function () {
- if (notificationBox.allNotifications.length === 0) {
- deferred.resolve();
- }
- });
- notification.close();
- }
-
- return deferred.promise;
-}
-
-function whenDelayedStartupFinished(aWindow, aCallback) {
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- executeSoon(aCallback);
- }
- }, "browser-delayed-startup-finished", false);
-}
-
-function updateTabContextMenu(tab, onOpened) {
- let menu = document.getElementById("tabContextMenu");
- if (!tab)
- tab = gBrowser.selectedTab;
- var evt = new Event("");
- tab.dispatchEvent(evt);
- menu.openPopup(tab, "end_after", 0, 0, true, false, evt);
- is(TabContextMenu.contextTab, tab, "TabContextMenu context is the expected tab");
- const onFinished = () => menu.hidePopup();
- if (onOpened) {
- return Task.spawn(function*() {
- yield onOpened();
- onFinished();
- });
- }
- onFinished();
- return Promise.resolve();
-}
-
-function openToolbarCustomizationUI(aCallback, aBrowserWin) {
- if (!aBrowserWin)
- aBrowserWin = window;
-
- aBrowserWin.gCustomizeMode.enter();
-
- aBrowserWin.gNavToolbox.addEventListener("customizationready", function UI_loaded() {
- aBrowserWin.gNavToolbox.removeEventListener("customizationready", UI_loaded);
- executeSoon(function() {
- aCallback(aBrowserWin)
- });
- });
-}
-
-function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
- aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function unloaded() {
- aBrowserWin.gNavToolbox.removeEventListener("aftercustomization", unloaded);
- executeSoon(aCallback);
- });
-
- aBrowserWin.gCustomizeMode.exit();
-}
-
-function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
- retryTimes = typeof retryTimes !== 'undefined' ? retryTimes : 30;
- var tries = 0;
- var interval = setInterval(function() {
- if (tries >= retryTimes) {
- ok(false, errorMsg);
- moveOn();
- }
- var conditionPassed;
- try {
- conditionPassed = condition();
- } catch (e) {
- ok(false, e + "\n" + e.stack);
- conditionPassed = false;
- }
- if (conditionPassed) {
- moveOn();
- }
- tries++;
- }, 100);
- var moveOn = function() { clearInterval(interval); nextTest(); };
-}
-
-function promiseWaitForCondition(aConditionFn) {
- let deferred = Promise.defer();
- waitForCondition(aConditionFn, deferred.resolve, "Condition didn't pass.");
- return deferred.promise;
-}
-
-function promiseWaitForEvent(object, eventName, capturing = false, chrome = false) {
- return new Promise((resolve) => {
- function listener(event) {
- info("Saw " + eventName);
- object.removeEventListener(eventName, listener, capturing, chrome);
- resolve(event);
- }
-
- info("Waiting for " + eventName);
- object.addEventListener(eventName, listener, capturing, chrome);
- });
-}
-
-/**
- * Allows setting focus on a window, and waiting for that window to achieve
- * focus.
- *
- * @param aWindow
- * The window to focus and wait for.
- *
- * @return {Promise}
- * @resolves When the window is focused.
- * @rejects Never.
- */
-function promiseWaitForFocus(aWindow) {
- return new Promise((resolve) => {
- waitForFocus(resolve, aWindow);
- });
-}
-
-function getTestPlugin(aName) {
- var pluginName = aName || "Test Plug-in";
- var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
- var tags = ph.getPluginTags();
-
- // Find the test plugin
- for (var i = 0; i < tags.length; i++) {
- if (tags[i].name == pluginName)
- return tags[i];
- }
- ok(false, "Unable to find plugin");
- return null;
-}
-
-// call this to set the test plugin(s) initially expected enabled state.
-// it will automatically be reset to it's previous value after the test
-// ends
-function setTestPluginEnabledState(newEnabledState, pluginName) {
- var plugin = getTestPlugin(pluginName);
- var oldEnabledState = plugin.enabledState;
- plugin.enabledState = newEnabledState;
- SimpleTest.registerCleanupFunction(function() {
- getTestPlugin(pluginName).enabledState = oldEnabledState;
- });
-}
-
-function pushPrefs(...aPrefs) {
- let deferred = Promise.defer();
- SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve);
- return deferred.promise;
-}
-
-function updateBlocklist(aCallback) {
- var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
- .getService(Ci.nsITimerCallback);
- var observer = function() {
- Services.obs.removeObserver(observer, "blocklist-updated");
- SimpleTest.executeSoon(aCallback);
- };
- Services.obs.addObserver(observer, "blocklist-updated", false);
- blocklistNotifier.notify(null);
-}
-
-var _originalTestBlocklistURL = null;
-function setAndUpdateBlocklist(aURL, aCallback) {
- if (!_originalTestBlocklistURL)
- _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
- Services.prefs.setCharPref("extensions.blocklist.url", aURL);
- updateBlocklist(aCallback);
-}
-
-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, false);
- aCallback(win);
- }, false);
-}
-
-function promiseWindowWillBeClosed(win) {
- return new Promise((resolve, reject) => {
- Services.obs.addObserver(function observe(subject, topic) {
- if (subject == win) {
- Services.obs.removeObserver(observe, topic);
- resolve();
- }
- }, "domwindowclosed", false);
- });
-}
-
-function promiseWindowClosed(win) {
- let promise = promiseWindowWillBeClosed(win);
- win.close();
- return promise;
-}
-
-function promiseOpenAndLoadWindow(aOptions, aWaitForDelayedStartup=false) {
- let deferred = Promise.defer();
- let win = OpenBrowserWindow(aOptions);
- if (aWaitForDelayedStartup) {
- Services.obs.addObserver(function onDS(aSubject, aTopic, aData) {
- 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);
- deferred.resolve(win);
- });
- }
- return deferred.promise;
-}
-
-/**
- * Waits for all pending async statements on the default connection, before
- * proceeding with aCallback.
- *
- * @param aCallback
- * Function to be called when done.
- * @param aScope
- * Scope for the callback.
- * @param aArguments
- * Arguments array for the callback.
- *
- * @note The result is achieved by asynchronously executing a query requiring
- * a write lock. Since all statements on the same connection are
- * serialized, the end of this write operation means that all writes are
- * complete. Note that WAL makes so that writers don't block readers, but
- * this is a problem only across different connections.
- */
-function waitForAsyncUpdates(aCallback, aScope, aArguments) {
- let scope = aScope || this;
- let args = aArguments || [];
- let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
- .DBConnection;
- let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
- begin.executeAsync();
- begin.finalize();
-
- let commit = db.createAsyncStatement("COMMIT");
- commit.executeAsync({
- handleResult: function() {},
- handleError: function() {},
- handleCompletion: function(aReason) {
- aCallback.apply(scope, args);
- }
- });
- commit.finalize();
-}
-
-/**
- * Asynchronously check a url is visited.
-
- * @param aURI The URI.
- * @param aExpectedValue The expected value.
- * @return {Promise}
- * @resolves When the check has been added successfully.
- * @rejects JavaScript exception.
- */
-function promiseIsURIVisited(aURI, aExpectedValue) {
- let deferred = Promise.defer();
- PlacesUtils.asyncHistory.isURIVisited(aURI, function(unused, aIsVisited) {
- deferred.resolve(aIsVisited);
- });
-
- return deferred.promise;
-}
-
-function whenNewTabLoaded(aWindow, aCallback) {
- aWindow.BrowserOpenTab();
-
- let browser = aWindow.gBrowser.selectedBrowser;
- if (browser.contentDocument.readyState === "complete") {
- aCallback();
- return;
- }
-
- whenTabLoaded(aWindow.gBrowser.selectedTab, aCallback);
-}
-
-function whenTabLoaded(aTab, aCallback) {
- promiseTabLoadEvent(aTab).then(aCallback);
-}
-
-function promiseTabLoaded(aTab) {
- let deferred = Promise.defer();
- whenTabLoaded(aTab, deferred.resolve);
- return deferred.promise;
-}
-
-/**
- * Ensures that the specified URIs are either cleared or not.
- *
- * @param aURIs
- * Array of page URIs
- * @param aShouldBeCleared
- * True if each visit to the URI should be cleared, false otherwise
- */
-function promiseHistoryClearedState(aURIs, aShouldBeCleared) {
- let deferred = Promise.defer();
- let callbackCount = 0;
- let niceStr = aShouldBeCleared ? "no longer" : "still";
- function callbackDone() {
- if (++callbackCount == aURIs.length)
- deferred.resolve();
- }
- aURIs.forEach(function (aURI) {
- PlacesUtils.asyncHistory.isURIVisited(aURI, function(uri, isVisited) {
- is(isVisited, !aShouldBeCleared,
- "history visit " + uri.spec + " should " + niceStr + " exist");
- callbackDone();
- });
- });
-
- return deferred.promise;
-}
-
-/**
- * Waits for the next top-level document load in the current browser. The URI
- * of the document is compared against aExpectedURL. The load is then stopped
- * before it actually starts.
- *
- * @param aExpectedURL
- * The URL of the document that is expected to load.
- * @param aStopFromProgressListener
- * Whether to cancel the load directly from the progress listener. Defaults to true.
- * If you're using this method to avoid hitting the network, you want the default (true).
- * However, the browser UI will behave differently for loads stopped directly from
- * the progress listener (effectively in the middle of a call to loadURI) and so there
- * are cases where you may want to avoid stopping the load directly from within the
- * progress listener callback.
- * @return promise
- */
-function waitForDocLoadAndStopIt(aExpectedURL, aBrowser=gBrowser.selectedBrowser, aStopFromProgressListener=true) {
- function content_script(contentStopFromProgressListener) {
- let { interfaces: Ci, utils: Cu } = Components;
- Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
- let wp = docShell.QueryInterface(Ci.nsIWebProgress);
-
- function stopContent(now, uri) {
- if (now) {
- /* Hammer time. */
- content.stop();
-
- /* Let the parent know we're done. */
- sendAsyncMessage("Test:WaitForDocLoadAndStopIt", { uri });
- } else {
- setTimeout(stopContent.bind(null, true, uri), 0);
- }
- }
-
- let progressListener = {
- onStateChange: function (webProgress, req, flags, status) {
- dump("waitForDocLoadAndStopIt: onStateChange " + flags.toString(16) + ": " + req.name + "\n");
-
- if (webProgress.isTopLevel &&
- flags & Ci.nsIWebProgressListener.STATE_START) {
- wp.removeProgressListener(progressListener);
-
- let chan = req.QueryInterface(Ci.nsIChannel);
- dump(`waitForDocLoadAndStopIt: Document start: ${chan.URI.spec}\n`);
-
- stopContent(contentStopFromProgressListener, chan.originalURI.spec);
- }
- },
- QueryInterface: XPCOMUtils.generateQI(["nsISupportsWeakReference"])
- };
- wp.addProgressListener(progressListener, wp.NOTIFY_STATE_WINDOW);
-
- /**
- * As |this| is undefined and we can't extend |docShell|, adding an unload
- * event handler is the easiest way to ensure the weakly referenced
- * progress listener is kept alive as long as necessary.
- */
- addEventListener("unload", function () {
- try {
- wp.removeProgressListener(progressListener);
- } catch (e) { /* Will most likely fail. */ }
- });
- }
-
- return new Promise((resolve, reject) => {
- function complete({ data }) {
- is(data.uri, aExpectedURL, "waitForDocLoadAndStopIt: The expected URL was loaded");
- mm.removeMessageListener("Test:WaitForDocLoadAndStopIt", complete);
- resolve();
- }
-
- let mm = aBrowser.messageManager;
- mm.loadFrameScript("data:,(" + content_script.toString() + ")(" + aStopFromProgressListener + ");", true);
- mm.addMessageListener("Test:WaitForDocLoadAndStopIt", complete);
- info("waitForDocLoadAndStopIt: Waiting for URL: " + aExpectedURL);
- });
-}
-
-/**
- * Waits for the next load to complete in any browser or the given browser.
- * If a <tabbrowser> is given it waits for a load in any of its browsers.
- *
- * @return promise
- */
-function waitForDocLoadComplete(aBrowser=gBrowser) {
- return new Promise(resolve => {
- let listener = {
- onStateChange: function (webProgress, req, flags, status) {
- let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
- Ci.nsIWebProgressListener.STATE_STOP;
- info("Saw state " + flags.toString(16) + " and status " + status.toString(16));
-
- // When a load needs to be retargetted to a new process it is cancelled
- // with NS_BINDING_ABORTED so ignore that case
- if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) {
- aBrowser.removeProgressListener(this);
- waitForDocLoadComplete.listeners.delete(this);
-
- let chan = req.QueryInterface(Ci.nsIChannel);
- info("Browser loaded " + chan.originalURI.spec);
- resolve();
- }
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference])
- };
- aBrowser.addProgressListener(listener);
- waitForDocLoadComplete.listeners.add(listener);
- info("Waiting for browser load");
- });
-}
-
-// Keep a set of progress listeners for waitForDocLoadComplete() to make sure
-// they're not GC'ed before we saw the page load.
-waitForDocLoadComplete.listeners = new Set();
-registerCleanupFunction(() => waitForDocLoadComplete.listeners.clear());
-
-var FullZoomHelper = {
-
- selectTabAndWaitForLocationChange: function selectTabAndWaitForLocationChange(tab) {
- if (!tab)
- throw new Error("tab must be given.");
- if (gBrowser.selectedTab == tab)
- return Promise.resolve();
-
- return Promise.all([BrowserTestUtils.switchTab(gBrowser, tab),
- this.waitForLocationChange()]);
- },
-
- removeTabAndWaitForLocationChange: function removeTabAndWaitForLocationChange(tab) {
- tab = tab || gBrowser.selectedTab;
- let selected = gBrowser.selectedTab == tab;
- gBrowser.removeTab(tab);
- if (selected)
- return this.waitForLocationChange();
- return Promise.resolve();
- },
-
- waitForLocationChange: function waitForLocationChange() {
- return new Promise(resolve => {
- Services.obs.addObserver(function obs(subj, topic, data) {
- Services.obs.removeObserver(obs, topic);
- resolve();
- }, "browser-fullZoom:location-change", false);
- });
- },
-
- load: function load(tab, url) {
- return new Promise(resolve => {
- let didLoad = false;
- let didZoom = false;
-
- promiseTabLoadEvent(tab).then(event => {
- didLoad = true;
- if (didZoom)
- resolve();
- }, true);
-
- this.waitForLocationChange().then(function () {
- didZoom = true;
- if (didLoad)
- resolve();
- });
-
- tab.linkedBrowser.loadURI(url);
- });
- },
-
- zoomTest: function zoomTest(tab, val, msg) {
- is(ZoomManager.getZoomForBrowser(tab.linkedBrowser), val, msg);
- },
-
- enlarge: function enlarge() {
- return new Promise(resolve => FullZoom.enlarge(resolve));
- },
-
- reduce: function reduce() {
- return new Promise(resolve => FullZoom.reduce(resolve));
- },
-
- reset: function reset() {
- return FullZoom.reset();
- },
-
- 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);
- didPs = true;
- if (didZoom)
- resolve();
- }, true);
-
- if (direction == this.BACK)
- gBrowser.goBack();
- else if (direction == this.FORWARD)
- gBrowser.goForward();
-
- this.waitForLocationChange().then(function () {
- didZoom = true;
- if (didPs)
- resolve();
- });
- });
- },
-
- failAndContinue: function failAndContinue(func) {
- return function (err) {
- ok(false, err);
- func();
- };
- },
-};
-
-/**
- * Waits for a load (or custom) event to finish in a given tab. If provided
- * load an uri into the tab.
- *
- * @param tab
- * The tab to load into.
- * @param [optional] url
- * The url to load, or the current url.
- * @return {Promise} resolved when the event is handled.
- * @resolves to the received event
- * @rejects if a valid load event is not received within a meaningful interval
- */
-function promiseTabLoadEvent(tab, url)
-{
- info("Wait tab event: load");
-
- function handle(loadedUrl) {
- if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
- info(`Skipping spurious load event for ${loadedUrl}`);
- return false;
- }
-
- info("Tab event received: load");
- return true;
- }
-
- let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
-
- if (url)
- BrowserTestUtils.loadURI(tab.linkedBrowser, url);
-
- return loaded;
-}
-
-/**
- * Returns a Promise that resolves once a new tab has been opened in
- * a xul:tabbrowser.
- *
- * @param aTabBrowser
- * The xul:tabbrowser to monitor for a new tab.
- * @return {Promise}
- * Resolved when the new tab has been opened.
- * @resolves to the TabOpen event that was fired.
- * @rejects Never.
- */
-function waitForNewTabEvent(aTabBrowser) {
- return promiseWaitForEvent(aTabBrowser.tabContainer, "TabOpen");
-}
-
-/**
- * Test the state of the identity box and control center to make
- * sure they are correctly showing the expected mixed content states.
- *
- * @note The checks are done synchronously, but new code should wait on the
- * returned Promise object to ensure the identity panel has closed.
- * Bug 1221114 is filed to fix the existing code.
- *
- * @param tabbrowser
- * @param Object states
- * MUST include the following properties:
- * {
- * activeLoaded: true|false,
- * activeBlocked: true|false,
- * passiveLoaded: true|false,
- * }
- *
- * @return {Promise}
- * @resolves When the operation has finished and the identity panel has closed.
- */
-function assertMixedContentBlockingState(tabbrowser, states = {}) {
- if (!tabbrowser || !("activeLoaded" in states) ||
- !("activeBlocked" in states) || !("passiveLoaded" in states)) {
- throw new Error("assertMixedContentBlockingState requires a browser and a states object");
- }
-
- let {passiveLoaded, activeLoaded, activeBlocked} = states;
- let {gIdentityHandler} = tabbrowser.ownerGlobal;
- let doc = tabbrowser.ownerDocument;
- let identityBox = gIdentityHandler._identityBox;
- let classList = identityBox.classList;
- let connectionIcon = doc.getElementById("connection-icon");
- let connectionIconImage = tabbrowser.ownerGlobal.getComputedStyle(connectionIcon).
- getPropertyValue("list-style-image");
-
- let stateSecure = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_SECURE;
- let stateBroken = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
- let stateInsecure = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_INSECURE;
- let stateActiveBlocked = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
- let stateActiveLoaded = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT;
- let statePassiveLoaded = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT;
-
- is(activeBlocked, !!stateActiveBlocked, "Expected state for activeBlocked matches UI state");
- is(activeLoaded, !!stateActiveLoaded, "Expected state for activeLoaded matches UI state");
- is(passiveLoaded, !!statePassiveLoaded, "Expected state for passiveLoaded matches UI state");
-
- if (stateInsecure) {
- // HTTP request, there should be no MCB classes for the identity box and the non secure icon
- // should always be visible regardless of MCB state.
- ok(classList.contains("unknownIdentity"), "unknownIdentity on HTTP page");
- is_element_hidden(connectionIcon);
-
- ok(!classList.contains("mixedActiveContent"), "No MCB icon on HTTP page");
- ok(!classList.contains("mixedActiveBlocked"), "No MCB icon on HTTP page");
- ok(!classList.contains("mixedDisplayContent"), "No MCB icon on HTTP page");
- ok(!classList.contains("mixedDisplayContentLoadedActiveBlocked"), "No MCB icon on HTTP page");
- } else {
- // Make sure the identity box UI has the correct mixedcontent states and icons
- is(classList.contains("mixedActiveContent"), activeLoaded,
- "identityBox has expected class for activeLoaded");
- is(classList.contains("mixedActiveBlocked"), activeBlocked && !passiveLoaded,
- "identityBox has expected class for activeBlocked && !passiveLoaded");
- is(classList.contains("mixedDisplayContent"), passiveLoaded && !(activeLoaded || activeBlocked),
- "identityBox has expected class for passiveLoaded && !(activeLoaded || activeBlocked)");
- is(classList.contains("mixedDisplayContentLoadedActiveBlocked"), passiveLoaded && activeBlocked,
- "identityBox has expected class for passiveLoaded && activeBlocked");
-
- is_element_visible(connectionIcon);
- if (activeLoaded) {
- is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-active-loaded.svg#icon\")",
- "Using active loaded icon");
- }
- if (activeBlocked && !passiveLoaded) {
- is(connectionIconImage, "url(\"chrome://browser/skin/connection-secure.svg\")",
- "Using active blocked icon");
- }
- if (passiveLoaded && !(activeLoaded || activeBlocked)) {
- is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
- "Using passive loaded icon");
- }
- if (passiveLoaded && activeBlocked) {
- is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
- "Using active blocked and passive loaded icon");
- }
- }
-
- // Make sure the identity popup has the correct mixedcontent states
- gIdentityHandler._identityBox.click();
- let popupAttr = doc.getElementById("identity-popup").getAttribute("mixedcontent");
- let bodyAttr = doc.getElementById("identity-popup-securityView-body").getAttribute("mixedcontent");
-
- is(popupAttr.includes("active-loaded"), activeLoaded,
- "identity-popup has expected attr for activeLoaded");
- is(bodyAttr.includes("active-loaded"), activeLoaded,
- "securityView-body has expected attr for activeLoaded");
-
- is(popupAttr.includes("active-blocked"), activeBlocked,
- "identity-popup has expected attr for activeBlocked");
- is(bodyAttr.includes("active-blocked"), activeBlocked,
- "securityView-body has expected attr for activeBlocked");
-
- is(popupAttr.includes("passive-loaded"), passiveLoaded,
- "identity-popup has expected attr for passiveLoaded");
- is(bodyAttr.includes("passive-loaded"), passiveLoaded,
- "securityView-body has expected attr for passiveLoaded");
-
- // Make sure the correct icon is visible in the Control Center.
- // This logic is controlled with CSS, so this helps prevent regressions there.
- let securityView = doc.getElementById("identity-popup-securityView");
- let securityViewBG = tabbrowser.ownerGlobal.getComputedStyle(securityView).
- getPropertyValue("background-image");
- let securityContentBG = tabbrowser.ownerGlobal.getComputedStyle(securityView).
- getPropertyValue("background-image");
-
- if (stateInsecure) {
- is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/conn-not-secure.svg\")",
- "CC using 'not secure' icon");
- is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/conn-not-secure.svg\")",
- "CC using 'not secure' icon");
- }
-
- if (stateSecure) {
- is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
- "CC using secure icon");
- is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
- "CC using secure icon");
- }
-
- if (stateBroken) {
- if (activeLoaded) {
- is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
- "CC using active loaded icon");
- is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
- "CC using active loaded icon");
- } else if (activeBlocked || passiveLoaded) {
- is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
- "CC using degraded icon");
- is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
- "CC using degraded icon");
- } else {
- // There is a case here with weak ciphers, but no bc tests are handling this yet.
- is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
- "CC using degraded icon");
- is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
- "CC using degraded icon");
- }
- }
-
- if (activeLoaded || activeBlocked || passiveLoaded) {
- doc.getElementById("identity-popup-security-expander").click();
- is(Array.filter(doc.querySelectorAll("[observes=identity-popup-mcb-learn-more]"),
- element => !is_hidden(element)).length, 1,
- "The 'Learn more' link should be visible once.");
- }
-
- gIdentityHandler._identityPopup.hidden = true;
-
- // Wait for the panel to be closed before continuing. The promisePopupHidden
- // function cannot be used because it's unreliable unless promisePopupShown is
- // also called before closing the panel. This cannot be done until all callers
- // are made asynchronous (bug 1221114).
- return new Promise(resolve => executeSoon(resolve));
-}
-
-function is_hidden(element) {
- var style = element.ownerGlobal.getComputedStyle(element);
- if (style.display == "none")
- return true;
- if (style.visibility != "visible")
- return true;
- if (style.display == "-moz-popup")
- return ["hiding", "closed"].indexOf(element.state) != -1;
-
- // Hiding a parent element will hide all its children
- if (element.parentNode != element.ownerDocument)
- return is_hidden(element.parentNode);
-
- return false;
-}
-
-function is_visible(element) {
- var style = element.ownerGlobal.getComputedStyle(element);
- if (style.display == "none")
- return false;
- if (style.visibility != "visible")
- return false;
- if (style.display == "-moz-popup" && element.state != "open")
- return false;
-
- // Hiding a parent element will hide all its children
- if (element.parentNode != element.ownerDocument)
- return is_visible(element.parentNode);
-
- return true;
-}
-
-function is_element_visible(element, msg) {
- isnot(element, null, "Element should not be null, when checking visibility");
- ok(is_visible(element), msg || "Element should be visible");
-}
-
-function is_element_hidden(element, msg) {
- isnot(element, null, "Element should not be null, when checking visibility");
- ok(is_hidden(element), msg || "Element should be hidden");
-}
-
-function promisePopupEvent(popup, eventSuffix) {
- let endState = {shown: "open", hidden: "closed"}[eventSuffix];
-
- if (popup.state == endState)
- return Promise.resolve();
-
- let eventType = "popup" + eventSuffix;
- let deferred = Promise.defer();
- popup.addEventListener(eventType, function onPopupShown(event) {
- popup.removeEventListener(eventType, onPopupShown);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
-function promisePopupShown(popup) {
- return promisePopupEvent(popup, "shown");
-}
-
-function promisePopupHidden(popup) {
- return promisePopupEvent(popup, "hidden");
-}
-
-function promiseNotificationShown(notification) {
- let win = notification.browser.ownerGlobal;
- if (win.PopupNotifications.panel.state == "open") {
- return Promise.resolve();
- }
- let panelPromise = promisePopupShown(win.PopupNotifications.panel);
- notification.reshow();
- return panelPromise;
-}
-
-/**
- * Allows waiting for an observer notification once.
- *
- * @param aTopic
- * Notification topic to observe.
- *
- * @return {Promise}
- * @resolves An object with subject and data properties from the observed
- * notification.
- * @rejects Never.
- */
-function promiseTopicObserved(aTopic)
-{
- return new Promise((resolve) => {
- Services.obs.addObserver(
- function PTO_observe(aSubject, aTopic2, aData) {
- Services.obs.removeObserver(PTO_observe, aTopic2);
- resolve({subject: aSubject, data: aData});
- }, aTopic, false);
- });
-}
-
-function promiseNewSearchEngine(basename) {
- return new Promise((resolve, reject) => {
- info("Waiting for engine to be added: " + basename);
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- registerCleanupFunction(() => Services.search.removeEngine(engine));
- resolve(engine);
- },
- onError: function (errCode) {
- Assert.ok(false, "addEngine failed with error code " + errCode);
- reject();
- },
- });
- });
-}
-
-// Compares the security state of the page with what is expected
-function isSecurityState(expectedState) {
- let ui = gTestBrowser.securityUI;
- if (!ui) {
- ok(false, "No security UI to get the security state");
- return;
- }
-
- const wpl = Components.interfaces.nsIWebProgressListener;
-
- // determine the security state
- let isSecure = ui.state & wpl.STATE_IS_SECURE;
- let isBroken = ui.state & wpl.STATE_IS_BROKEN;
- let isInsecure = ui.state & wpl.STATE_IS_INSECURE;
-
- let actualState;
- if (isSecure && !(isBroken || isInsecure)) {
- actualState = "secure";
- } else if (isBroken && !(isSecure || isInsecure)) {
- actualState = "broken";
- } else if (isInsecure && !(isSecure || isBroken)) {
- actualState = "insecure";
- } else {
- actualState = "unknown";
- }
-
- is(expectedState, actualState, "Expected state " + expectedState + " and the actual state is " + actualState + ".");
-}
-
-/**
- * Resolves when a bookmark with the given uri is added.
- */
-function promiseOnBookmarkItemAdded(aExpectedURI) {
- return new Promise((resolve, reject) => {
- let bookmarksObserver = {
- onItemAdded: function (aItemId, aFolderId, aIndex, aItemType, aURI) {
- info("Added a bookmark to " + aURI.spec);
- PlacesUtils.bookmarks.removeObserver(bookmarksObserver);
- if (aURI.equals(aExpectedURI)) {
- resolve();
- }
- else {
- reject(new Error("Added an unexpected bookmark"));
- }
- },
- onBeginUpdateBatch: function () {},
- onEndUpdateBatch: function () {},
- onItemRemoved: function () {},
- onItemChanged: function () {},
- onItemVisited: function () {},
- onItemMoved: function () {},
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsINavBookmarkObserver,
- ])
- };
- info("Waiting for a bookmark to be added");
- PlacesUtils.bookmarks.addObserver(bookmarksObserver, false);
- });
-}
-
-function promiseErrorPageLoaded(browser) {
- return new Promise(resolve => {
- browser.addEventListener("DOMContentLoaded", function onLoad() {
- browser.removeEventListener("DOMContentLoaded", onLoad, false, true);
- resolve();
- }, false, true);
- });
-}
-
-function* loadBadCertPage(url) {
- const EXCEPTION_DIALOG_URI = "chrome://pippki/content/exceptionDialog.xul";
- let exceptionDialogResolved = new Promise(function(resolve) {
- // When the certificate exception dialog has opened, click the button to add
- // an exception.
- let certExceptionDialogObserver = {
- observe: function(aSubject, aTopic, aData) {
- if (aTopic == "cert-exception-ui-ready") {
- Services.obs.removeObserver(this, "cert-exception-ui-ready");
- let certExceptionDialog = getCertExceptionDialog(EXCEPTION_DIALOG_URI);
- ok(certExceptionDialog, "found exception dialog");
- executeSoon(function() {
- certExceptionDialog.documentElement.getButton("extra1").click();
- resolve();
- });
- }
- }
- };
-
- Services.obs.addObserver(certExceptionDialogObserver,
- "cert-exception-ui-ready", false);
- });
-
- let loaded = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser);
- yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
- yield loaded;
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
- content.document.getElementById("exceptionDialogButton").click();
- });
- yield exceptionDialogResolved;
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-}
-
-// Utility function to get a handle on the certificate exception dialog.
-// Modified from toolkit/components/passwordmgr/test/prompt_common.js
-function getCertExceptionDialog(aLocation) {
- let enumerator = Services.wm.getXULWindowEnumerator(null);
-
- while (enumerator.hasMoreElements()) {
- let win = enumerator.getNext();
- let windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
-
- let containedDocShells = windowDocShell.getDocShellEnumerator(
- Ci.nsIDocShellTreeItem.typeChrome,
- Ci.nsIDocShell.ENUMERATE_FORWARDS);
- while (containedDocShells.hasMoreElements()) {
- // Get the corresponding document for this docshell
- let childDocShell = containedDocShells.getNext();
- let childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
- .contentViewer
- .DOMDocument;
-
- if (childDoc.location.href == aLocation) {
- return childDoc;
- }
- }
- }
- return undefined;
-}
-
-function setupRemoteClientsFixture(fixture) {
- let oldRemoteClientsGetter =
- Object.getOwnPropertyDescriptor(gFxAccounts, "remoteClients").get;
-
- Object.defineProperty(gFxAccounts, "remoteClients", {
- get: function() { return fixture; }
- });
- return oldRemoteClientsGetter;
-}
-
-function restoreRemoteClients(getter) {
- Object.defineProperty(gFxAccounts, "remoteClients", {
- get: getter
- });
-}
-
-function* openMenuItemSubmenu(id) {
- let menuPopup = document.getElementById(id).menupopup;
- let menuPopupPromise = BrowserTestUtils.waitForEvent(menuPopup, "popupshown");
- menuPopup.showPopup();
- yield menuPopupPromise;
-}
diff --git a/browser/base/content/test/general/head_plain.js b/browser/base/content/test/general/head_plain.js
deleted file mode 100644
index 3796c7d2b..000000000
--- a/browser/base/content/test/general/head_plain.js
+++ /dev/null
@@ -1,27 +0,0 @@
-
-function getTestPlugin(pluginName) {
- var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
- .getService(SpecialPowers.Ci.nsIPluginHost);
- var tags = ph.getPluginTags();
- var name = pluginName || "Test Plug-in";
- for (var tag of tags) {
- if (tag.name == name) {
- return tag;
- }
- }
-
- ok(false, "Could not find plugin tag with plugin name '" + name + "'");
- return null;
-}
-
-// call this to set the test plugin(s) initially expected enabled state.
-// it will automatically be reset to it's previous value after the test
-// ends
-function setTestPluginEnabledState(newEnabledState, pluginName) {
- var plugin = getTestPlugin(pluginName);
- var oldEnabledState = plugin.enabledState;
- plugin.enabledState = newEnabledState;
- SimpleTest.registerCleanupFunction(function() {
- getTestPlugin(pluginName).enabledState = oldEnabledState;
- });
-}
diff --git a/browser/base/content/test/general/healthreport_pingData.js b/browser/base/content/test/general/healthreport_pingData.js
deleted file mode 100644
index 1737baba1..000000000
--- a/browser/base/content/test/general/healthreport_pingData.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var TEST_PINGS = [
- {
- type: "test-telemetryArchive-1",
- payload: { foo: "bar" },
- date: new Date(2010, 1, 1, 10, 0, 0),
- },
- {
- type: "test-telemetryArchive-2",
- payload: { x: { y: "z"} },
- date: new Date(2010, 1, 1, 11, 0, 0),
- },
- {
- type: "test-telemetryArchive-3",
- payload: { moo: "meh" },
- date: new Date(2010, 1, 1, 12, 0, 0),
- },
-];
diff --git a/browser/base/content/test/general/healthreport_testRemoteCommands.html b/browser/base/content/test/general/healthreport_testRemoteCommands.html
deleted file mode 100644
index 7978914f2..000000000
--- a/browser/base/content/test/general/healthreport_testRemoteCommands.html
+++ /dev/null
@@ -1,243 +0,0 @@
-<html>
- <head>
- <meta charset="utf-8">
-<script type="application/javascript;version=1.7"
- src="healthreport_pingData.js">
-</script>
-<script type="application/javascript;version=1.7">
-
-function init() {
- window.addEventListener("message", doTest, false);
- doTest();
-}
-
-function checkSubmissionValue(payload, expectedValue) {
- return payload.enabled == expectedValue;
-}
-
-function isArray(arg) {
- return Object.prototype.toString.call(arg) === '[object Array]';
-}
-
-function writeDiagnostic(text) {
- let node = document.createTextNode(text);
- let br = document.createElement("br");
- document.body.appendChild(node);
- document.body.appendChild(br);
-}
-
-function validateCurrentTelemetryEnvironment(data) {
- // Simple check for now: check that the received object has the expected
- // top-level properties.
- const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
- return expectedKeys.every(key => (key in data));
-}
-
-function validateCurrentTelemetryPingData(ping) {
- // Simple check for now: check that the received object has the expected
- // top-level properties and that the type and reason match.
- const expectedKeys = ["environment", "clientId", "payload", "application",
- "version", "type", "id"];
- return expectedKeys.every(key => (key in ping)) &&
- (ping.type == "main") &&
- ("info" in ping.payload) &&
- ("reason" in ping.payload.info) &&
- (ping.payload.info.reason == "gather-subsession-payload");
-}
-
-function validateTelemetryPingList(list) {
- if (!isArray(list)) {
- console.log("Telemetry ping list is not an array.");
- return false;
- }
-
- // Telemetry may generate other pings (e.g. "deletion" pings), so filter those
- // out.
- const TEST_TYPES_REGEX = /^test-telemetryArchive/;
- list = list.filter(p => TEST_TYPES_REGEX.test(p.type));
-
- if (list.length != TEST_PINGS.length) {
- console.log("Telemetry ping length is not correct.");
- return false;
- }
-
- let valid = true;
- for (let i=0; i<list.length; ++i) {
- let received = list[i];
- let expected = TEST_PINGS[i];
- if (received.type != expected.type ||
- received.timestampCreated != expected.date.getTime()) {
- writeDiagnostic("Telemetry ping " + i + " does not match.");
- writeDiagnostic("Expected: " + JSON.stringify(expected));
- writeDiagnostic("Received: " + JSON.stringify(received));
- valid = false;
- } else {
- writeDiagnostic("Telemetry ping " + i + " matches.");
- }
- }
-
- return true;
-}
-
-function validateTelemetryPingData(expected, received) {
- const receivedDate = new Date(received.creationDate);
- if (received.id != expected.id ||
- received.type != expected.type ||
- receivedDate.getTime() != expected.date.getTime()) {
- writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
- writeDiagnostic("Expected: " + JSON.stringify(expected));
- writeDiagnostic("Received: " + JSON.stringify(received));
- return false;
- }
-
- writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
- return true;
-}
-
-var tests = [
-{
- info: "Checking initial value is enabled",
- event: "RequestCurrentPrefs",
- payloadType: "prefs",
- validateResponse: function(payload) {
- return checkSubmissionValue(payload, true);
- },
-},
-{
- info: "Verifying disabling works",
- event: "DisableDataSubmission",
- payloadType: "prefs",
- validateResponse: function(payload) {
- return checkSubmissionValue(payload, false);
- },
-},
-{
- info: "Verifying we're still disabled",
- event: "RequestCurrentPrefs",
- payloadType: "prefs",
- validateResponse: function(payload) {
- return checkSubmissionValue(payload, false);
- },
-},
-{
- info: "Verifying that we can get the current ping data while submission is disabled",
- event: "RequestCurrentPingData",
- payloadType: "telemetry-current-ping-data",
- validateResponse: function(payload) {
- return validateCurrentTelemetryPingData(payload);
- },
-},
-{
- info: "Verifying enabling works",
- event: "EnableDataSubmission",
- payloadType: "prefs",
- validateResponse: function(payload) {
- return checkSubmissionValue(payload, true);
- },
-},
-{
- info: "Verifying we're still re-enabled",
- event: "RequestCurrentPrefs",
- payloadType: "prefs",
- validateResponse: function(payload) {
- return checkSubmissionValue(payload, true);
- },
-},
-{
- info: "Verifying that we can get the current Telemetry environment data",
- event: "RequestCurrentEnvironment",
- payloadType: "telemetry-current-environment-data",
- validateResponse: function(payload) {
- return validateCurrentTelemetryEnvironment(payload);
- },
-},
-{
- info: "Verifying that we can get the current Telemetry ping data",
- event: "RequestCurrentPingData",
- payloadType: "telemetry-current-ping-data",
- validateResponse: function(payload) {
- return validateCurrentTelemetryPingData(payload);
- },
-},
-{
- info: "Verifying that we get the proper Telemetry ping list",
- event: "RequestTelemetryPingList",
- payloadType: "telemetry-ping-list",
- validateResponse: function(payload) {
- // Validate the ping list
- if (!validateTelemetryPingList(payload)) {
- return false;
- }
-
- // Now that we received the ping ids, set up additional test tasks
- // that check loading the individual pings.
- for (let i=0; i<TEST_PINGS.length; ++i) {
- TEST_PINGS[i].id = payload[i].id;
- tests.push({
- info: "Verifying that we can get the proper Telemetry ping data #" + (i + 1),
- event: "RequestTelemetryPingData",
- eventData: { id: TEST_PINGS[i].id },
- payloadType: "telemetry-ping-data",
- validateResponse: function(payload) {
- return validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
- },
- });
- }
-
- return true;
- },
-},
-];
-
-var currentTest = -1;
-function doTest(evt) {
- if (evt) {
- if (currentTest < 0 || !evt.data.content)
- return; // not yet testing
-
- var test = tests[currentTest];
- if (evt.data.type != test.payloadType)
- return; // skip unrequested events
-
- var error = JSON.stringify(evt.data.content);
- var pass = false;
- try {
- pass = test.validateResponse(evt.data.content)
- } catch (e) {}
- reportResult(test.info, pass, error);
- }
- // start the next test if there are any left
- if (tests[++currentTest])
- sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
- else
- reportFinished();
-}
-
-function reportResult(info, pass, error) {
- var data = {type: "testResult", info: info, pass: pass, error: error};
- var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
- document.dispatchEvent(event);
-}
-
-function reportFinished(cmd) {
- var data = {type: "testsComplete", count: tests.length};
- var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
- document.dispatchEvent(event);
-}
-
-function sendToBrowser(type, eventData) {
- eventData = eventData || {};
- let detail = {command: type};
- for (let key of Object.keys(eventData)) {
- detail[key] = eventData[key];
- }
-
- var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
- document.dispatchEvent(event);
-}
-
-</script>
- </head>
- <body onload="init()">
- </body>
-</html>
diff --git a/browser/base/content/test/general/insecure_opener.html b/browser/base/content/test/general/insecure_opener.html
deleted file mode 100644
index 26ed014f6..000000000
--- a/browser/base/content/test/general/insecure_opener.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html dir="ltr" xml:lang="en-US" lang="en-US">
- <head>
- <meta charset="utf8">
- </head>
- <body>
- <a id="link" target="_blank" href="https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html">Click me, I'm "secure".</a>
- </body>
-</html>
diff --git a/browser/base/content/test/general/mochitest.ini b/browser/base/content/test/general/mochitest.ini
deleted file mode 100644
index a07a01b87..000000000
--- a/browser/base/content/test/general/mochitest.ini
+++ /dev/null
@@ -1,27 +0,0 @@
-[DEFAULT]
-support-files =
- audio.ogg
- bug364677-data.xml
- bug364677-data.xml^headers^
- bug395533-data.txt
- contextmenu_common.js
- ctxmenu-image.png
- head_plain.js
- offlineByDefault.js
- offlineChild.cacheManifest
- offlineChild.cacheManifest^headers^
- offlineChild.html
- offlineChild2.cacheManifest
- offlineChild2.cacheManifest^headers^
- offlineChild2.html
- offlineEvent.cacheManifest
- offlineEvent.cacheManifest^headers^
- offlineEvent.html
- subtst_contextmenu.html
- video.ogg
- !/image/test/mochitest/blue.png
-
-[test_bug364677.html]
-[test_bug395533.html]
-[test_offlineNotification.html]
-skip-if = e10s # Bug 1257785
diff --git a/browser/base/content/test/general/moz.png b/browser/base/content/test/general/moz.png
deleted file mode 100644
index 769c63634..000000000
--- a/browser/base/content/test/general/moz.png
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/navigating_window_with_download.html b/browser/base/content/test/general/navigating_window_with_download.html
deleted file mode 100644
index 6b0918941..000000000
--- a/browser/base/content/test/general/navigating_window_with_download.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head><title>This window will navigate while you're downloading something</title></head>
- <body>
- <iframe src="http://mochi.test:8888/browser/browser/base/content/test/general/unknownContentType_file.pif"></iframe>
- </body>
-</html>
diff --git a/browser/base/content/test/general/offlineByDefault.js b/browser/base/content/test/general/offlineByDefault.js
deleted file mode 100644
index 72f7e52a0..000000000
--- a/browser/base/content/test/general/offlineByDefault.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var offlineByDefault = {
- defaultValue: false,
- prefBranch: SpecialPowers.Cc["@mozilla.org/preferences-service;1"].getService(SpecialPowers.Ci.nsIPrefBranch),
- set: function(allow) {
- try {
- this.defaultValue = this.prefBranch.getBoolPref("offline-apps.allow_by_default");
- } catch (e) {
- this.defaultValue = false
- }
- this.prefBranch.setBoolPref("offline-apps.allow_by_default", allow);
- },
- reset: function() {
- this.prefBranch.setBoolPref("offline-apps.allow_by_default", this.defaultValue);
- }
-}
-
-offlineByDefault.set(false);
diff --git a/browser/base/content/test/general/offlineChild.cacheManifest b/browser/base/content/test/general/offlineChild.cacheManifest
deleted file mode 100644
index 091fe7194..000000000
--- a/browser/base/content/test/general/offlineChild.cacheManifest
+++ /dev/null
@@ -1,2 +0,0 @@
-CACHE MANIFEST
-offlineChild.html
diff --git a/browser/base/content/test/general/offlineChild.cacheManifest^headers^ b/browser/base/content/test/general/offlineChild.cacheManifest^headers^
deleted file mode 100644
index 257f2eb60..000000000
--- a/browser/base/content/test/general/offlineChild.cacheManifest^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/cache-manifest
diff --git a/browser/base/content/test/general/offlineChild.html b/browser/base/content/test/general/offlineChild.html
deleted file mode 100644
index 43f225b3b..000000000
--- a/browser/base/content/test/general/offlineChild.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html manifest="offlineChild.cacheManifest">
-<head>
-<title></title>
-<script type="text/javascript">
-
-function finish(success) {
- window.parent.postMessage(success ? "success" : "failure", "*");
-}
-
-applicationCache.oncached = function() { finish(true); }
-applicationCache.onnoupdate = function() { finish(true); }
-applicationCache.onerror = function() { finish(false); }
-
-</script>
-</head>
-
-<body>
-<h1>Child</h1>
-</body>
-</html>
diff --git a/browser/base/content/test/general/offlineChild2.cacheManifest b/browser/base/content/test/general/offlineChild2.cacheManifest
deleted file mode 100644
index 19efe54fe..000000000
--- a/browser/base/content/test/general/offlineChild2.cacheManifest
+++ /dev/null
@@ -1,2 +0,0 @@
-CACHE MANIFEST
-offlineChild2.html
diff --git a/browser/base/content/test/general/offlineChild2.cacheManifest^headers^ b/browser/base/content/test/general/offlineChild2.cacheManifest^headers^
deleted file mode 100644
index 257f2eb60..000000000
--- a/browser/base/content/test/general/offlineChild2.cacheManifest^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/cache-manifest
diff --git a/browser/base/content/test/general/offlineChild2.html b/browser/base/content/test/general/offlineChild2.html
deleted file mode 100644
index ac762e759..000000000
--- a/browser/base/content/test/general/offlineChild2.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html manifest="offlineChild2.cacheManifest">
-<head>
-<title></title>
-<script type="text/javascript">
-
-function finish(success) {
- window.parent.postMessage(success ? "success" : "failure", "*");
-}
-
-applicationCache.oncached = function() { finish(true); }
-applicationCache.onnoupdate = function() { finish(true); }
-applicationCache.onerror = function() { finish(false); }
-
-</script>
-</head>
-
-<body>
-<h1>Child</h1>
-</body>
-</html>
diff --git a/browser/base/content/test/general/offlineEvent.cacheManifest b/browser/base/content/test/general/offlineEvent.cacheManifest
deleted file mode 100644
index 091fe7194..000000000
--- a/browser/base/content/test/general/offlineEvent.cacheManifest
+++ /dev/null
@@ -1,2 +0,0 @@
-CACHE MANIFEST
-offlineChild.html
diff --git a/browser/base/content/test/general/offlineEvent.cacheManifest^headers^ b/browser/base/content/test/general/offlineEvent.cacheManifest^headers^
deleted file mode 100644
index 257f2eb60..000000000
--- a/browser/base/content/test/general/offlineEvent.cacheManifest^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/cache-manifest
diff --git a/browser/base/content/test/general/offlineEvent.html b/browser/base/content/test/general/offlineEvent.html
deleted file mode 100644
index f6e2494e2..000000000
--- a/browser/base/content/test/general/offlineEvent.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html manifest="offlineEvent.cacheManifest">
-<head>
-<title></title>
-</head>
-
-<body>
-<h1>Child</h1>
-</body>
-</html>
diff --git a/browser/base/content/test/general/offlineQuotaNotification.cacheManifest b/browser/base/content/test/general/offlineQuotaNotification.cacheManifest
deleted file mode 100644
index 2e210abd2..000000000
--- a/browser/base/content/test/general/offlineQuotaNotification.cacheManifest
+++ /dev/null
@@ -1,7 +0,0 @@
-CACHE MANIFEST
-# Any copyright is dedicated to the Public Domain.
-# http://creativecommons.org/publicdomain/zero/1.0/
-
-# store a "large" file so an "over quota warning" will be issued - any file
-# larger than 1kb and in '_BROWSER_FILES' should be right...
-title_test.svg
diff --git a/browser/base/content/test/general/offlineQuotaNotification.html b/browser/base/content/test/general/offlineQuotaNotification.html
deleted file mode 100644
index b1b91bf9e..000000000
--- a/browser/base/content/test/general/offlineQuotaNotification.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html manifest="offlineQuotaNotification.cacheManifest">
-<head>
- <meta charset="utf-8">
- <title>Test offline app quota notification</title>
- <!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-</head>
-</html>
diff --git a/browser/base/content/test/general/page_style_sample.html b/browser/base/content/test/general/page_style_sample.html
deleted file mode 100644
index 54cbaa9e6..000000000
--- a/browser/base/content/test/general/page_style_sample.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<html>
- <head>
- <title>Test for page style menu</title>
- <!-- data-state values:
- 0: should not appear in the page style menu
- 0-todo: should not appear in the page style menu, but does
- 1: should appear in the page style menu
- 2: should appear in the page style menu as the selected stylesheet -->
- <link data-state="1" href="404.css" title="1" rel="alternate stylesheet">
- <link data-state="0" title="2" rel="alternate stylesheet">
- <link data-state="0" href="404.css" rel="alternate stylesheet">
- <link data-state="0" href="404.css" title="" rel="alternate stylesheet">
- <link data-state="1" href="404.css" title="3" rel="stylesheet alternate">
- <link data-state="1" href="404.css" title="4" rel=" alternate stylesheet ">
- <link data-state="1" href="404.css" title="5" rel="alternate stylesheet">
- <link data-state="2" href="404.css" title="6" rel="stylesheet">
- <link data-state="1" href="404.css" title="7" rel="foo stylesheet">
- <link data-state="0" href="404.css" title="8" rel="alternate">
- <link data-state="1" href="404.css" title="9" rel="alternate STYLEsheet">
- <link data-state="1" href="404.css" title="10" rel="alternate stylesheet" media="">
- <link data-state="1" href="404.css" title="11" rel="alternate stylesheet" media="all">
- <link data-state="1" href="404.css" title="12" rel="alternate stylesheet" media="ALL ">
- <link data-state="1" href="404.css" title="13" rel="alternate stylesheet" media="screen">
- <link data-state="1" href="404.css" title="14" rel="alternate stylesheet" media=" Screen">
- <link data-state="0" href="404.css" title="15" rel="alternate stylesheet" media="screen foo">
- <link data-state="0" href="404.css" title="16" rel="alternate stylesheet" media="all screen">
- <link data-state="0" href="404.css" title="17" rel="alternate stylesheet" media="foo bar">
- <link data-state="1" href="404.css" title="18" rel="alternate stylesheet" media="all,screen">
- <link data-state="1" href="404.css" title="19" rel="alternate stylesheet" media="all, screen">
- <link data-state="0" href="404.css" title="20" rel="alternate stylesheet" media="all screen">
- <link data-state="0" href="404.css" title="21" rel="alternate stylesheet" media="foo">
- <link data-state="0" href="404.css" title="22" rel="alternate stylesheet" media="allscreen">
- <link data-state="0" href="404.css" title="23" rel="alternate stylesheet" media="_all">
- <link data-state="0" href="404.css" title="24" rel="alternate stylesheet" media="not screen">
- <link data-state="1" href="404.css" title="25" rel="alternate stylesheet" media="only screen">
- <link data-state="1" href="404.css" title="26" rel="alternate stylesheet" media="screen and (min-device-width: 1px)">
- <link data-state="0" href="404.css" title="27" rel="alternate stylesheet" media="screen and (max-device-width: 1px)">
- <style data-state="1" title="28">/* some more styles */</style>
- </head>
- <body></body>
-</html>
diff --git a/browser/base/content/test/general/parsingTestHelpers.jsm b/browser/base/content/test/general/parsingTestHelpers.jsm
deleted file mode 100644
index 69c764483..000000000
--- a/browser/base/content/test/general/parsingTestHelpers.jsm
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["generateURIsFromDirTree"];
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-/* Shorthand constructors to construct an nsI(Local)File and zip reader: */
-const LocalFile = new Components.Constructor("@mozilla.org/file/local;1", Ci.nsIFile, "initWithPath");
-const ZipReader = new Components.Constructor("@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open");
-
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/osfile.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-
-
-/**
- * Returns a promise that is resolved with a list of files that have one of the
- * extensions passed, represented by their nsIURI objects, which exist inside
- * the directory passed.
- *
- * @param dir the directory which to scan for files (nsIFile)
- * @param extensions the extensions of files we're interested in (Array).
- */
-function generateURIsFromDirTree(dir, extensions) {
- if (!Array.isArray(extensions)) {
- extensions = [extensions];
- }
- let dirQueue = [dir.path];
- return Task.spawn(function*() {
- let rv = [];
- while (dirQueue.length) {
- let nextDir = dirQueue.shift();
- let {subdirs, files} = yield iterateOverPath(nextDir, extensions);
- dirQueue.push(...subdirs);
- rv.push(...files);
- }
- return rv;
- });
-}
-
-/**
- * Uses OS.File.DirectoryIterator to asynchronously iterate over a directory.
- * It returns a promise that is resolved with an object with two properties:
- * - files: an array of nsIURIs corresponding to files that match the extensions passed
- * - subdirs: an array of paths for subdirectories we need to recurse into
- * (handled by generateURIsFromDirTree above)
- *
- * @param path the path to check (string)
- * @param extensions the file extensions we're interested in.
- */
-function iterateOverPath(path, extensions) {
- let iterator = new OS.File.DirectoryIterator(path);
- let parentDir = new LocalFile(path);
- let subdirs = [];
- let files = [];
-
- let pathEntryIterator = (entry) => {
- if (entry.isDir) {
- subdirs.push(entry.path);
- } else if (extensions.some((extension) => entry.name.endsWith(extension))) {
- let file = parentDir.clone();
- file.append(entry.name);
- // the build system might leave dead symlinks hanging around, which are
- // returned as part of the directory iterator, but don't actually exist:
- if (file.exists()) {
- let uriSpec = getURLForFile(file);
- files.push(Services.io.newURI(uriSpec, null, null));
- }
- } else if (entry.name.endsWith(".ja") || entry.name.endsWith(".jar") ||
- entry.name.endsWith(".zip") || entry.name.endsWith(".xpi")) {
- let file = parentDir.clone();
- file.append(entry.name);
- for (let extension of extensions) {
- let jarEntryIterator = generateEntriesFromJarFile(file, extension);
- files.push(...jarEntryIterator);
- }
- }
- };
-
- return new Promise((resolve, reject) => {
- Task.spawn(function* () {
- try {
- // Iterate through the directory
- yield iterator.forEach(pathEntryIterator);
- resolve({files: files, subdirs: subdirs});
- } catch (ex) {
- reject(ex);
- } finally {
- iterator.close();
- }
- });
- });
-}
-
-/* Helper function to generate a URI spec (NB: not an nsIURI yet!)
- * given an nsIFile object */
-function getURLForFile(file) {
- let fileHandler = Services.io.getProtocolHandler("file");
- fileHandler = fileHandler.QueryInterface(Ci.nsIFileProtocolHandler);
- return fileHandler.getURLSpecFromActualFile(file);
-}
-
-/**
- * A generator that generates nsIURIs for particular files found in jar files
- * like omni.ja.
- *
- * @param jarFile an nsIFile object for the jar file that needs checking.
- * @param extension the extension we're interested in.
- */
-function* generateEntriesFromJarFile(jarFile, extension) {
- let zr = new ZipReader(jarFile);
- let entryEnumerator = zr.findEntries("*" + extension + "$");
-
- const kURIStart = getURLForFile(jarFile);
- while (entryEnumerator.hasMore()) {
- let entry = entryEnumerator.getNext();
- // Ignore the JS cache which is stored in omni.ja
- if (entry.startsWith("jsloader") || entry.startsWith("jssubloader")) {
- continue;
- }
- let entryURISpec = "jar:" + kURIStart + "!/" + entry;
- yield Services.io.newURI(entryURISpec, null, null);
- }
- zr.close();
-}
-
-
diff --git a/browser/base/content/test/general/permissions.html b/browser/base/content/test/general/permissions.html
deleted file mode 100644
index 46436a006..000000000
--- a/browser/base/content/test/general/permissions.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<html dir="ltr" xml:lang="en-US" lang="en-US">
- <head>
- <meta charset="utf8">
- </head>
- <body>
- <!-- This page could eventually request permissions from content
- and make sure that chrome responds appropriately -->
- <button id="geo" onclick="navigator.geolocation.getCurrentPosition(() => {})">Geolocation</button>
- </body>
-</html>
diff --git a/browser/base/content/test/general/pinning_headers.sjs b/browser/base/content/test/general/pinning_headers.sjs
deleted file mode 100644
index 51496183a..000000000
--- a/browser/base/content/test/general/pinning_headers.sjs
+++ /dev/null
@@ -1,23 +0,0 @@
-const INVALIDPIN1 = "pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\";";
-const INVALIDPIN2 = "pin-sha256=\"AAAAAAAAAAAAAAAAAAAAAAAAAj0e1Md7GkYYkVoZWmM=\";";
-const VALIDPIN = "pin-sha256=\"hXweb81C3HnmM2Ai1dnUzFba40UJMhuu8qZmvN/6WWc=\";";
-
-function handleRequest(request, response)
-{
- // avoid confusing cache behaviors
- response.setHeader("Cache-Control", "no-cache", false);
-
- response.setHeader("Content-Type", "text/plain; charset=utf-8", false);
- switch (request.queryString) {
- case "zeromaxagevalid":
- response.setHeader("Public-Key-Pins", "max-age=0;" + VALIDPIN +
- INVALIDPIN2 + "includeSubdomains");
- break;
- case "valid":
- default:
- response.setHeader("Public-Key-Pins", "max-age=50000;" + VALIDPIN +
- INVALIDPIN2 + "includeSubdomains");
- }
-
- response.write("Hello world!" + request.host);
-}
diff --git a/browser/base/content/test/general/print_postdata.sjs b/browser/base/content/test/general/print_postdata.sjs
deleted file mode 100644
index 4175a2480..000000000
--- a/browser/base/content/test/general/print_postdata.sjs
+++ /dev/null
@@ -1,22 +0,0 @@
-const CC = Components.Constructor;
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-
-function handleRequest(request, response) {
- response.setHeader("Content-Type", "text/plain", false);
- if (request.method == "GET") {
- response.write(request.queryString);
- } else {
- var body = new BinaryInputStream(request.bodyInputStream);
-
- var avail;
- var bytes = [];
-
- while ((avail = body.available()) > 0)
- Array.prototype.push.apply(bytes, body.readByteArray(avail));
-
- var data = String.fromCharCode.apply(null, bytes);
- response.bodyOutputStream.write(data, data.length);
- }
-}
diff --git a/browser/base/content/test/general/refresh_header.sjs b/browser/base/content/test/general/refresh_header.sjs
deleted file mode 100644
index 327372f9b..000000000
--- a/browser/base/content/test/general/refresh_header.sjs
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Will cause an auto-refresh to the URL provided in the query string
- * after some delay using the refresh HTTP header.
- *
- * Expects the query string to be in the format:
- *
- * ?p=[URL of the page to redirect to]&d=[delay]
- *
- * Example:
- *
- * ?p=http%3A%2F%2Fexample.org%2Fbrowser%2Fbrowser%2Fbase%2Fcontent%2Ftest%2Fgeneral%2Frefresh_meta.sjs&d=200
- */
-function handleRequest(request, response) {
- Components.utils.importGlobalProperties(["URLSearchParams"]);
- let query = new URLSearchParams(request.queryString);
-
- let page = query.get("p");
- let delay = query.get("d");
-
- response.setHeader("Content-Type", "text/html", false);
- response.setStatusLine(request.httpVersion, "200", "Found");
- response.setHeader("refresh", `${delay}; url=${page}`);
- response.write("OK");
-} \ No newline at end of file
diff --git a/browser/base/content/test/general/refresh_meta.sjs b/browser/base/content/test/general/refresh_meta.sjs
deleted file mode 100644
index 648fac1a3..000000000
--- a/browser/base/content/test/general/refresh_meta.sjs
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Will cause an auto-refresh to the URL provided in the query string
- * after some delay using a <meta> tag.
- *
- * Expects the query string to be in the format:
- *
- * ?p=[URL of the page to redirect to]&d=[delay]
- *
- * Example:
- *
- * ?p=http%3A%2F%2Fexample.org%2Fbrowser%2Fbrowser%2Fbase%2Fcontent%2Ftest%2Fgeneral%2Frefresh_meta.sjs&d=200
- */
-function handleRequest(request, response) {
- Components.utils.importGlobalProperties(["URLSearchParams"]);
- let query = new URLSearchParams(request.queryString);
-
- let page = query.get("p");
- let delay = query.get("d");
-
- let html = `<!DOCTYPE HTML>
- <html>
- <head>
- <meta charset='utf-8'>
- <META http-equiv='refresh' content='${delay}; url=${page}'>
- <title>Gonna refresh you, folks.</title>
- </head>
- <body>
- <h1>Wait for it...</h1>
- </body>
- </html>`;
-
- response.setHeader("Content-Type", "text/html", false);
- response.setStatusLine(request.httpVersion, "200", "Found");
- response.setHeader("Cache-Control", "no-cache", false);
- response.write(html);
-} \ No newline at end of file
diff --git a/browser/base/content/test/general/searchSuggestionEngine.sjs b/browser/base/content/test/general/searchSuggestionEngine.sjs
deleted file mode 100644
index 1978b4f66..000000000
--- a/browser/base/content/test/general/searchSuggestionEngine.sjs
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function handleRequest(req, resp) {
- let suffixes = ["foo", "bar"];
- let data = [req.queryString, suffixes.map(s => req.queryString + s)];
- resp.setHeader("Content-Type", "application/json", false);
- resp.write(JSON.stringify(data));
-}
diff --git a/browser/base/content/test/general/searchSuggestionEngine.xml b/browser/base/content/test/general/searchSuggestionEngine.xml
deleted file mode 100644
index 3d1f294f5..000000000
--- a/browser/base/content/test/general/searchSuggestionEngine.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_searchSuggestionEngine searchSuggestionEngine.xml</ShortName>
-<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/base/content/test/general/searchSuggestionEngine.sjs?{searchTerms}"/>
-<Url type="text/html" method="GET" template="http://mochi.test:8888/" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/base/content/test/general/searchSuggestionEngine2.xml b/browser/base/content/test/general/searchSuggestionEngine2.xml
deleted file mode 100644
index 05644649a..000000000
--- a/browser/base/content/test/general/searchSuggestionEngine2.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_searchSuggestionEngine searchSuggestionEngine2.xml</ShortName>
-<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/base/content/test/general/searchSuggestionEngine.sjs?{searchTerms}"/>
-<Url type="text/html" method="GET" template="http://www.browser-searchSuggestionEngine.com/searchSuggestionEngine2&amp;terms={searchTerms}" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/base/content/test/general/ssl_error_reports.sjs b/browser/base/content/test/general/ssl_error_reports.sjs
deleted file mode 100644
index e2e5bafc0..000000000
--- a/browser/base/content/test/general/ssl_error_reports.sjs
+++ /dev/null
@@ -1,91 +0,0 @@
-const EXPECTED_CHAIN = [
- "MIIDCjCCAfKgAwIBAgIENUiGYDANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDExtBbHRlcm5hdGUgVHJ1c3RlZCBBdXRob3JpdHkwHhcNMTQxMDAxMjExNDE5WhcNMjQxMDAxMjExNDE5WjAxMS8wLQYDVQQDEyZpbmNsdWRlLXN1YmRvbWFpbnMucGlubmluZy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxYrge8C4eVfTb6/lJ4k/+/4J6wlnWpp5Szxy1MHhsLB+LJh/HRHqkO/tsigT204kTeU3dxuAfQHz0g+Td8dr6KICLLNVFUPw+XjhBV4AtxV8wcprs6EmdBhJgAjkFB4M76BL7/Ow0NfH012WNESn8TTbsp3isgkmrXjTZhWR33vIL1eDNimykp/Os/+JO+x9KVfdCtDCrPwO9Yusial5JiaW7qemRtVuUDL87NSJ7xokPEOSc9luv/fBamZ3rgqf3K6epqg+0o3nNCCcNFnfLW52G0t69+dIjr39WISHnqqZj3Sb7JPU6OmxTd13ByoLkoM3ZUQ2Lpas+RJvQyGXkCAwEAAaM1MDMwMQYDVR0RBCowKIImaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAAmzXfeoOS59FkNABRonFPRyFl7BoGpVJENUteFfTa2pdAhGYdo19Y4uILTTj+vtDAa5yryb5Uvd+YuJnExosbMMkzCrmZ9+VJCJdqUTb+idwk9/sgPl2gtGeRmefB0hXSUFHc/p1CDufSpYOmj9NCUZD2JEsybgJQNulkfAsVnS3lzDcxAwcO+RC/1uJDSiUtcBpWS4FW58liuDYE7PD67kLJHZPVUV2WCMuIl4VM2tKPtvShz1JkZ5UytOLs6jPfviNAk/ftXczaE2/RJgM2MnDX9nGzOxG6ONcVNCljL8avhFBCosutE6i5LYSZR6V14YY/xOn15WDSuWdnIsJCo=",
- "MIIC2jCCAcKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDExtBbHRlcm5hdGUgVHJ1c3RlZCBBdXRob3JpdHkwHhcNMTQwOTI1MjEyMTU0WhcNMjQwOTI1MjEyMTU0WjAmMSQwIgYDVQQDExtBbHRlcm5hdGUgVHJ1c3RlZCBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBT+BwAhO52IWgSIdZZifU9LHOs3IR/+8DCC0WP5d/OuyKlZ6Rqd0tsd3i7durhQyjHSbLf2lJStcnFjcVEbEnNI76RuvlN8xLLn5eV+2Ayr4cZYKztudwRmw+DV/iYAiMSy0hs7m3ssfX7qpoi1aNRjUanwU0VTCPQhF1bEKAC2du+C5Z8e92zN5t87w7bYr7lt+m8197XliXEu+0s9RgnGwGaZ296BIRz6NOoJYTa43n06LU1I1+Z4d6lPdzUFrSR0GBaMhUSurUBtOin3yWiMhg1VHX/KwqGc4als5GyCVXy8HGrA/0zQPOhetxrlhEVAdK/xBt7CZvByj1Rcc7AgMBAAGjEzARMA8GA1UdEwQIMAYBAf8CAQAwDQYJKoZIhvcNAQELBQADggEBAJq/hogSRqzPWTwX4wTn/DVSNdWwFLv53qep9YrSMJ8ZsfbfK9Es4VP4dBLRQAVMJ0Z5mW1I6d/n0KayTanuUBvemYdxPi/qQNSs8UJcllqdhqWzmzAg6a0LxrMnEeKzPBPD6q8PwQ7tYP+B4sBN9tnnsnyPgti9ZiNZn5FwXZliHXseQ7FE9/SqHlLw5LXW3YtKjuti6RmuV6fq3j+D4oeC5vb1mKgIyoTqGN6ze57v8RHi+pQ8Q+kmoUn/L3Z2YmFe4SKN/4WoyXr8TdejpThGOCGCAd3565s5gOx5QfSQX11P8NZKO8hcN0tme3VzmGpHK0Z/6MTmdpNaTwQ6odk="
- ];
-
-const MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE = -16384;
-
-function parseReport(request) {
- // read the report from the request
- let inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
- inputStream.init(request.bodyInputStream, 0x01, 0004, 0);
-
- let body = "";
- if (inputStream) {
- while (inputStream.available()) {
- body = body + inputStream.read(inputStream.available());
- }
- }
- // parse the report
- return JSON.parse(body);
-}
-
-function handleRequest(request, response) {
- let report = {};
- let certChain = [];
-
- switch (request.queryString) {
- case "succeed":
- report = parseReport(request);
- certChain = report.failedCertChain;
-
- // ensure the cert chain is what we expect
- for (idx in certChain) {
- if (certChain[idx] !== EXPECTED_CHAIN[idx]) {
- // if the chain differs, send an error response to cause test
- // failure
- response.setStatusLine("1.1", 500, "Server error");
- response.write("<html>The report contained an unexpected chain</html>");
- return;
- }
- }
-
- if (report.errorCode !== MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE) {
- response.setStatusLine("1.1", 500, "Server error");
- response.write("<html>The report contained an unexpected error code</html>");
- return;
- }
-
- // if all is as expected, send the 201 the client expects
- response.setStatusLine("1.1", 201, "Created");
- response.write("<html>OK</html>");
- break;
- case "nocert":
- report = parseReport(request);
- certChain = report.failedCertChain;
-
- if (certChain && certChain.length > 0) {
- // We're not expecting a chain; if there is one, send an error
- response.setStatusLine("1.1", 500, "Server error");
- response.write("<html>The report contained an unexpected chain</html>");
- return;
- }
-
- // if all is as expected, send the 201 the client expects
- response.setStatusLine("1.1", 201, "Created");
- response.write("<html>OK</html>");
- break;
- case "badcert":
- report = parseReport(request);
- certChain = report.failedCertChain;
-
- if (!certChain || certChain.length != 2) {
- response.setStatusLine("1.1", 500, "Server error");
- response.write("<html>The report contained an unexpected chain</html>");
- return;
- }
-
- // if all is as expected, send the 201 the client expects
- response.setStatusLine("1.1", 201, "Created");
- response.write("<html>OK</html>");
- break;
- case "error":
- response.setStatusLine("1.1", 500, "Server error");
- response.write("<html>server error</html>");
- break;
- default:
- response.setStatusLine("1.1", 500, "Server error");
- response.write("<html>succeed, nocert or error expected (got " + request.queryString + ")</html>");
- break;
- }
-}
diff --git a/browser/base/content/test/general/subtst_contextmenu.html b/browser/base/content/test/general/subtst_contextmenu.html
deleted file mode 100644
index 1768f399f..000000000
--- a/browser/base/content/test/general/subtst_contextmenu.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Subtest for browser context menu</title>
-</head>
-<body>
-Browser context menu subtest.
-
-<div id="test-text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
-<a id="test-link" href="http://mozilla.com">Click the monkey!</a>
-<a id="test-mailto" href="mailto:codemonkey@mozilla.com">Mail the monkey!</a><br>
-<input id="test-input"><br>
-<img id="test-image" src="ctxmenu-image.png">
-<canvas id="test-canvas" width="100" height="100" style="background-color: blue"></canvas>
-<video controls id="test-video-ok" src="video.ogg" width="100" height="100" style="background-color: green"></video>
-<video id="test-audio-in-video" src="audio.ogg" width="100" height="100" style="background-color: red"></video>
-<video controls id="test-video-bad" src="bogus.duh" width="100" height="100" style="background-color: orange"></video>
-<video controls id="test-video-bad2" width="100" height="100" style="background-color: yellow">
- <source src="bogus.duh" type="video/durrrr;">
-</video>
-<iframe id="test-iframe" width="98" height="98" style="border: 1px solid black"></iframe>
-<iframe id="test-video-in-iframe" src="video.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
-<iframe id="test-audio-in-iframe" src="audio.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
-<iframe id="test-image-in-iframe" src="ctxmenu-image.png" width="98" height="98" style="border: 1px solid black"></iframe>
-<textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
-<div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
-<div id="test-contenteditable-spellcheck-false" contenteditable="true" spellcheck="false">test</div> <!-- No Check Spelling menu item -->
-<div id="test-dom-full-screen">DOM full screen FTW</div>
-<div contextmenu="myMenu">
- <p id="test-pagemenu" hopeless="true">I've got a context menu!</p>
- <menu id="myMenu" type="context">
- <menuitem label="Plain item" onclick="document.getElementById('test-pagemenu').removeAttribute('hopeless');"></menuitem>
- <menuitem label="Disabled item" disabled></menuitem>
- <menuitem> Item w/ textContent</menuitem>
- <menu>
- <menuitem type="checkbox" label="Checkbox" checked></menuitem>
- </menu>
- <menu>
- <menuitem type="radio" label="Radio1" checked></menuitem>
- <menuitem type="radio" label="Radio2"></menuitem>
- <menuitem type="radio" label="Radio3"></menuitem>
- </menu>
- <menu>
- <menuitem label="Item w/ icon" icon="favicon.ico"></menuitem>
- <menuitem label="Item w/ bad icon" icon="data://www.mozilla.org/favicon.ico"></menuitem>
- </menu>
- <menu label="Submenu">
- <menuitem type="radio" label="Radio1" radiogroup="rg"></menuitem>
- <menuitem type="radio" label="Radio2" checked radiogroup="rg"></menuitem>
- <menuitem type="radio" label="Radio3" radiogroup="rg"></menuitem>
- <menu>
- <menuitem type="checkbox" label="Checkbox"></menuitem>
- </menu>
- </menu>
- <menu hidden>
- <menuitem label="Bogus item"></menuitem>
- </menu>
- <menu>
- </menu>
- <menuitem label="Hidden item" hidden></menuitem>
- <menuitem></menuitem>
- </menu>
-</div>
-<div id="test-select-text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
-<div id="test-select-text-link">http://mozilla.com</div>
-<a id="test-image-link" href="#"><img src="ctxmenu-image.png"></a>
-<input id="test-select-input-text" type="text" value="input">
-<input id="test-select-input-text-type-password" type="password" value="password">
-<embed id="test-plugin" style="width: 200px; height: 200px;" type="application/x-test"></embed>
-<img id="test-longdesc" src="ctxmenu-image.png" longdesc="http://www.mozilla.org"></embed>
-<iframe id="test-srcdoc" width="98" height="98" srcdoc="Hello World" style="border: 1px solid black"></iframe>
-</body>
-</html>
diff --git a/browser/base/content/test/general/subtst_contextmenu_input.html b/browser/base/content/test/general/subtst_contextmenu_input.html
deleted file mode 100644
index c5be977ea..000000000
--- a/browser/base/content/test/general/subtst_contextmenu_input.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Subtest for browser context menu</title>
-</head>
-<body>
- Browser context menu subtest.
- <input id="input_text">
- <input id="input_spellcheck_no_value">
- <input id="input_spellcheck_incorrect" spellcheck="true" value="prodkjfgigrty">
- <input id="input_spellcheck_correct" spellcheck="true" value="foo">
- <input id="input_disabled" disabled="true">
- <input id="input_password">
- <input id="input_email" type="email">
- <input id="input_tel" type="tel">
- <input id="input_url" type="url">
- <input id="input_number" type="number">
- <input id="input_date" type="date">
- <input id="input_time" type="time">
- <input id="input_color" type="color">
- <input id="input_range" type="range">
- <input id="input_search" type="search">
- <input id="input_datetime" type="datetime">
- <input id="input_month" type="month">
- <input id="input_week" type="week">
- <input id="input_datetime-local" type="datetime-local">
- <input id="input_readonly" readonly="true">
-</body>
-</html>
diff --git a/browser/base/content/test/general/subtst_contextmenu_xul.xul b/browser/base/content/test/general/subtst_contextmenu_xul.xul
deleted file mode 100644
index 5a2ab42e8..000000000
--- a/browser/base/content/test/general/subtst_contextmenu_xul.xul
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this file,
- - You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:html="http://www.w3.org/1999/xhtml">
- <label id="test-xul-text-link-label" class="text-link" value="XUL text-link label" href="https://www.mozilla.com"/>
-</page>
diff --git a/browser/base/content/test/general/svg_image.html b/browser/base/content/test/general/svg_image.html
deleted file mode 100644
index 7ab17c33a..000000000
--- a/browser/base/content/test/general/svg_image.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Test for page info svg images</title>
- </head>
- <body>
- <svg width="20" height="20">
- <image xlink:href="title_test.svg" width="20" height="20">
- </svg>
- </body>
-</html>
diff --git a/browser/base/content/test/general/test-mixedcontent-securityerrors.html b/browser/base/content/test/general/test-mixedcontent-securityerrors.html
deleted file mode 100644
index cb8cfdaaf..000000000
--- a/browser/base/content/test/general/test-mixedcontent-securityerrors.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
- Bug 875456 - Log mixed content messages from the Mixed Content Blocker to the
- Security Pane in the Web Console
--->
-
-<!DOCTYPE HTML>
-<html dir="ltr" xml:lang="en-US" lang="en-US">
- <head>
- <meta charset="utf8">
- <title>Mixed Content test - http on https</title>
- <script src="testscript.js"></script>
- <!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/
- -->
- </head>
- <body>
- <iframe src="http://example.com"></iframe>
- <img src="http://example.com/tests/image/test/mochitest/blue.png"></img>
- </body>
-</html>
diff --git a/browser/base/content/test/general/test_bug364677.html b/browser/base/content/test/general/test_bug364677.html
deleted file mode 100644
index 67b9729d1..000000000
--- a/browser/base/content/test/general/test_bug364677.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=364677
--->
-<head>
- <title>Test for Bug 364677</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=364677">Mozilla Bug 364677</a>
-<p id="display"><iframe id="testFrame" src="bug364677-data.xml"></iframe></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 364677 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- is(SpecialPowers.wrap($("testFrame")).contentDocument.documentElement.id, "feedHandler",
- "Feed served as text/xml without a channel/link should have been sniffed");
-});
-addLoadEvent(SimpleTest.finish);
-</script>
-</pre>
-</body>
-</html>
-
diff --git a/browser/base/content/test/general/test_bug395533.html b/browser/base/content/test/general/test_bug395533.html
deleted file mode 100644
index ad6209047..000000000
--- a/browser/base/content/test/general/test_bug395533.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=395533
--->
-<head>
- <title>Test for Bug 395533</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=395533">Mozilla Bug 395533</a>
-<p id="display"><iframe id="testFrame" src="bug395533-data.txt"></iframe></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 395533 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- // Need privs because the feed seems to have an about:feeds principal or some
- // such. It's not same-origin with us in any case.
- is(SpecialPowers.wrap($("testFrame")).contentDocument.documentElement.id, "",
- "Text got sniffed as a feed?");
-});
-addLoadEvent(SimpleTest.finish);
-
-
-
-
-</script>
-</pre>
-</body>
-</html>
-
diff --git a/browser/base/content/test/general/test_bug435035.html b/browser/base/content/test/general/test_bug435035.html
deleted file mode 100644
index a6624db15..000000000
--- a/browser/base/content/test/general/test_bug435035.html
+++ /dev/null
@@ -1 +0,0 @@
-<img src="http://example.com/browser/browser/base/content/test/general/moz.png">
diff --git a/browser/base/content/test/general/test_bug462673.html b/browser/base/content/test/general/test_bug462673.html
deleted file mode 100644
index d864990e4..000000000
--- a/browser/base/content/test/general/test_bug462673.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<html>
-<head>
-<script>
-var w;
-function openIt() {
- w = window.open("", "window2");
-}
-function closeIt() {
- if (w) {
- w.close();
- w = null;
- }
-}
-</script>
-</head>
-<body onload="openIt();" onunload="closeIt();">
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_bug628179.html b/browser/base/content/test/general/test_bug628179.html
deleted file mode 100644
index d35e17a7c..000000000
--- a/browser/base/content/test/general/test_bug628179.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Test for closing the Find bar in subdocuments</title>
- </head>
- <body>
- <iframe id=iframe src="http://example.com/" width=320 height=240></iframe>
- </body>
-</html>
-
diff --git a/browser/base/content/test/general/test_bug839103.html b/browser/base/content/test/general/test_bug839103.html
deleted file mode 100644
index 3639d4bda..000000000
--- a/browser/base/content/test/general/test_bug839103.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Document for Bug 839103</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <style></style>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_bug959531.html b/browser/base/content/test/general/test_bug959531.html
deleted file mode 100644
index e749b198a..000000000
--- a/browser/base/content/test/general/test_bug959531.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Test for content page with settings button</title>
- </head>
- <body>
- <button name="settings" id="settings">Settings</button>
- </body>
-</html>
diff --git a/browser/base/content/test/general/test_mcb_double_redirect_image.html b/browser/base/content/test/general/test_mcb_double_redirect_image.html
deleted file mode 100644
index 1b54774ec..000000000
--- a/browser/base/content/test/general/test_mcb_double_redirect_image.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 7-9 for Bug 1082837 - See file browser_mcb_redirect.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=1082837
--->
-<head>
- <meta charset="utf-8">
- <title>Bug 1082837</title>
- <script>
- function image_loaded() {
- document.getElementById("mctestdiv").innerHTML = "image loaded";
- }
- function image_blocked() {
- document.getElementById("mctestdiv").innerHTML = "image blocked";
- }
- </script>
-</head>
-<body>
- <div id="mctestdiv"></div>
- <img src="https://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?image_redirect_http_sjs" onload="image_loaded()" onerror="image_blocked()" ></image>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_mcb_redirect.html b/browser/base/content/test/general/test_mcb_redirect.html
deleted file mode 100644
index 88af791a3..000000000
--- a/browser/base/content/test/general/test_mcb_redirect.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 1 for Bug 418354 - See file browser_mcb_redirect.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=418354
--->
-<head>
- <meta charset="utf-8">
- <title>Bug 418354</title>
-</head>
-<body>
- <div id="mctestdiv">script blocked</div>
- <script src="https://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?script" ></script>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_mcb_redirect.js b/browser/base/content/test/general/test_mcb_redirect.js
deleted file mode 100644
index 48538c940..000000000
--- a/browser/base/content/test/general/test_mcb_redirect.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Once the mixed content blocker is disabled for the page, this scripts loads
- * and updates the text inside the div container.
- */
-document.getElementById("mctestdiv").innerHTML = "script executed";
diff --git a/browser/base/content/test/general/test_mcb_redirect.sjs b/browser/base/content/test/general/test_mcb_redirect.sjs
deleted file mode 100644
index 9a1811dfa..000000000
--- a/browser/base/content/test/general/test_mcb_redirect.sjs
+++ /dev/null
@@ -1,22 +0,0 @@
-function handleRequest(request, response) {
- var page = "<!DOCTYPE html><html><body>bug 418354 and bug 1082837</body></html>";
-
- if (request.queryString === "script") {
- var redirect = "http://example.com/browser/browser/base/content/test/general/test_mcb_redirect.js";
- response.setHeader("Cache-Control", "no-cache", false);
- } else if (request.queryString === "image_http") {
- var redirect = "http://example.com/tests/image/test/mochitest/blue.png";
- response.setHeader("Cache-Control", "max-age=3600", false);
- } else if (request.queryString === "image_redirect_http_sjs") {
- var redirect = "http://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?image_redirect_https";
- response.setHeader("Cache-Control", "max-age=3600", false);
- } else if (request.queryString === "image_redirect_https") {
- var redirect = "https://example.com/tests/image/test/mochitest/blue.png";
- response.setHeader("Cache-Control", "max-age=3600", false);
- }
-
- response.setHeader("Content-Type", "text/html", false);
- response.setStatusLine(request.httpVersion, "302", "Found");
- response.setHeader("Location", redirect, false);
- response.write(page);
-}
diff --git a/browser/base/content/test/general/test_mcb_redirect_image.html b/browser/base/content/test/general/test_mcb_redirect_image.html
deleted file mode 100644
index c70cd8987..000000000
--- a/browser/base/content/test/general/test_mcb_redirect_image.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 3-6 for Bug 1082837 - See file browser_mcb_redirect.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=1082837
--->
-<head>
- <meta charset="utf-8">
- <title>Bug 1082837</title>
- <script>
- function image_loaded() {
- document.getElementById("mctestdiv").innerHTML = "image loaded";
- }
- function image_blocked() {
- document.getElementById("mctestdiv").innerHTML = "image blocked";
- }
- </script>
-</head>
-<body>
- <div id="mctestdiv"></div>
- <img src="https://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?image_http" onload="image_loaded()" onerror="image_blocked()" ></image>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_no_mcb_on_http_site_font.css b/browser/base/content/test/general/test_no_mcb_on_http_site_font.css
deleted file mode 100644
index 68a6954cc..000000000
--- a/browser/base/content/test/general/test_no_mcb_on_http_site_font.css
+++ /dev/null
@@ -1,10 +0,0 @@
-@font-face {
- font-family: testFont;
- src: url(http://example.com/browser/devtools/client/fontinspector/test/browser_font.woff);
-}
-body {
- font-family: Arial;
-}
-div {
- font-family: testFont;
-}
diff --git a/browser/base/content/test/general/test_no_mcb_on_http_site_font.html b/browser/base/content/test/general/test_no_mcb_on_http_site_font.html
deleted file mode 100644
index 28a9cb2c0..000000000
--- a/browser/base/content/test/general/test_no_mcb_on_http_site_font.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 2 for Bug 909920 - See file browser_no_mcb_on_http_site.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=909920
--->
-<head>
- <meta charset="utf-8">
- <title>Test 2 for Bug 909920</title>
- <link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_font.css" />
-<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-
-<script type="text/javascript">
- function checkLoadStates() {
- var ui = SpecialPowers.wrap(window)
- .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
- .getInterface(SpecialPowers.Ci.nsIWebNavigation)
- .QueryInterface(SpecialPowers.Ci.nsIDocShell)
- .securityUI;
-
- var loadedMixedActive = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT);
- is(loadedMixedActive, false, "OK: Should not load mixed active content!");
-
- var blockedMixedActive = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT);
- is(blockedMixedActive, false, "OK: Should not block mixed active content!");
-
- var loadedMixedDisplay = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT);
- is(loadedMixedDisplay, false, "OK: Should not load mixed display content!");
-
- var blockedMixedDisplay = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT);
- is(blockedMixedDisplay, false, "OK: Should not block mixed display content!");
-
- var newValue = "Verifying MCB does not trigger warning/error for an http page with https css that includes http font";
- document.getElementById("testDiv").innerHTML = newValue;
- }
-</script>
-</head>
-<body onload="checkLoadStates()">
- <div class="testDiv" id="testDiv">
- Testing MCB does not trigger warning/error for an http page with https css that includes http font
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_no_mcb_on_http_site_font2.css b/browser/base/content/test/general/test_no_mcb_on_http_site_font2.css
deleted file mode 100644
index f73b573b4..000000000
--- a/browser/base/content/test/general/test_no_mcb_on_http_site_font2.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url(http://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_font.css);
diff --git a/browser/base/content/test/general/test_no_mcb_on_http_site_font2.html b/browser/base/content/test/general/test_no_mcb_on_http_site_font2.html
deleted file mode 100644
index 2b3164902..000000000
--- a/browser/base/content/test/general/test_no_mcb_on_http_site_font2.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 3 for Bug 909920 - See file browser_no_mcb_on_http_site.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=909920
--->
-<head>
- <meta charset="utf-8">
- <title>Test 3 for Bug 909920</title>
- <link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_font2.css" />
-<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-
-<script type="text/javascript">
- function checkLoadStates() {
- var ui = SpecialPowers.wrap(window)
- .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
- .getInterface(SpecialPowers.Ci.nsIWebNavigation)
- .QueryInterface(SpecialPowers.Ci.nsIDocShell)
- .securityUI;
-
- var loadedMixedActive = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT);
- is(loadedMixedActive, false, "OK: Should not load mixed active content!");
-
- var blockedMixedActive = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT);
- is(blockedMixedActive, false, "OK: Should not block mixed active content!");
-
- var loadedMixedDisplay = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT);
- is(loadedMixedDisplay, false, "OK: Should not load mixed display content!");
-
- var blockedMixedDisplay = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT);
- is(blockedMixedDisplay, false, "OK: Should not block mixed display content!");
-
- var newValue = "Verifying MCB does not trigger warning/error for an http page ";
- newValue += "with https css that imports another http css which includes http font";
- document.getElementById("testDiv").innerHTML = newValue;
- }
-</script>
-</head>
-<body onload="checkLoadStates()">
- <div class="testDiv" id="testDiv">
- Testing MCB does not trigger warning/error for an http page with https css that imports another http css which includes http font
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_no_mcb_on_http_site_img.css b/browser/base/content/test/general/test_no_mcb_on_http_site_img.css
deleted file mode 100644
index d045e21ba..000000000
--- a/browser/base/content/test/general/test_no_mcb_on_http_site_img.css
+++ /dev/null
@@ -1,3 +0,0 @@
-#testDiv {
- background: url(http://example.com/tests/image/test/mochitest/blue.png)
-}
diff --git a/browser/base/content/test/general/test_no_mcb_on_http_site_img.html b/browser/base/content/test/general/test_no_mcb_on_http_site_img.html
deleted file mode 100644
index 741573260..000000000
--- a/browser/base/content/test/general/test_no_mcb_on_http_site_img.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
- Test 1 for Bug 909920 - See file browser_no_mcb_on_http_site.js for description.
- https://bugzilla.mozilla.org/show_bug.cgi?id=909920
--->
-<head>
- <meta charset="utf-8">
- <title>Test 1 for Bug 909920</title>
- <link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_img.css" />
-<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-
-<script type="text/javascript">
- function checkLoadStates() {
- var ui = SpecialPowers.wrap(window)
- .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
- .getInterface(SpecialPowers.Ci.nsIWebNavigation)
- .QueryInterface(SpecialPowers.Ci.nsIDocShell)
- .securityUI;
-
- var loadedMixedActive = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT);
- is(loadedMixedActive, false, "OK: Should not load mixed active content!");
-
- var blockedMixedActive = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT);
- is(blockedMixedActive, false, "OK: Should not block mixed active content!");
-
- var loadedMixedDisplay = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT);
- is(loadedMixedDisplay, false, "OK: Should not load mixed display content!");
-
- var blockedMixedDisplay = ui &&
- !!(ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT);
- is(blockedMixedDisplay, false, "OK: Should not block mixed display content!");
-
- var newValue = "Verifying MCB does not trigger warning/error for an http page with https css that includes http image";
- document.getElementById("testDiv").innerHTML = newValue;
- }
-</script>
-</head>
-<body onload="checkLoadStates()">
- <div class="testDiv" id="testDiv">
- Testing MCB does not trigger warning/error for an http page with https css that includes http image
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_offlineNotification.html b/browser/base/content/test/general/test_offlineNotification.html
deleted file mode 100644
index 4f78184b4..000000000
--- a/browser/base/content/test/general/test_offlineNotification.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=462856
--->
-<head>
- <title>Test offline app notification</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript" src="offlineByDefault.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<p id="display">
-<!-- Load the test frame twice from the same domain,
- to make sure we get notifications for both -->
-<iframe name="testFrame" src="offlineChild.html"></iframe>
-<iframe name="testFrame2" src="offlineChild2.html"></iframe>
-<!-- Load from another domain to make sure we get a second allow/deny
- notification -->
-<iframe name="testFrame3" src="http://example.com/tests/browser/base/content/test/general/offlineChild.html"></iframe>
-
-<iframe id="eventsTestFrame" src="offlineEvent.html"></iframe>
-
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-SimpleTest.waitForExplicitFinish();
-const Cc = SpecialPowers.Cc;
-
-var numFinished = 0;
-
-window.addEventListener("message", function(event) {
- is(event.data, "success", "Child was successfully cached.");
-
- if (++numFinished == 3) {
- // Clean up after ourself
- var pm = Cc["@mozilla.org/permissionmanager;1"].
- getService(SpecialPowers.Ci.nsIPermissionManager);
- var ioService = Cc["@mozilla.org/network/io-service;1"]
- .getService(SpecialPowers.Ci.nsIIOService);
- var uri1 = ioService.newURI(frames.testFrame.location, null, null);
- var uri2 = ioService.newURI(frames.testFrame3.location, null, null);
-
- var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
- .getService(SpecialPowers.Ci.nsIScriptSecurityManager);
- var principal1 = ssm.createCodebasePrincipal(uri1, {});
- var principal2 = ssm.createCodebasePrincipal(uri2, {});
-
- pm.removeFromPrincipal(principal1, "offline-app");
- pm.removeFromPrincipal(principal2, "offline-app");
-
- offlineByDefault.reset();
-
- SimpleTest.finish();
- }
- }, false);
-
-var count = 0;
-var expectedEvent = "";
-function eventHandler(evt) {
- ++count;
- is(evt.type, expectedEvent, "Wrong event!");
-}
-
-function testEventHandling() {
- var events = [ "checking",
- "error",
- "noupdate",
- "downloading",
- "progress",
- "updateready",
- "cached",
- "obsolete"];
- var w = document.getElementById("eventsTestFrame").contentWindow;
- var e;
- for (var i = 0; i < events.length; ++i) {
- count = 0;
- expectedEvent = events[i];
- e = w.document.createEvent("event");
- e.initEvent(expectedEvent, true, true);
- w.applicationCache["on" + expectedEvent] = eventHandler;
- w.applicationCache.addEventListener(expectedEvent, eventHandler, true);
- w.applicationCache.dispatchEvent(e);
- is(count, 2, "Wrong number events!");
- w.applicationCache["on" + expectedEvent] = null;
- w.applicationCache.removeEventListener(expectedEvent, eventHandler, true);
- w.applicationCache.dispatchEvent(e);
- is(count, 2, "Wrong number events!");
- }
-
- // Test some random event.
- count = 0;
- expectedEvent = "foo";
- e = w.document.createEvent("event");
- e.initEvent(expectedEvent, true, true);
- w.applicationCache.addEventListener(expectedEvent, eventHandler, true);
- w.applicationCache.dispatchEvent(e);
- is(count, 1, "Wrong number events!");
- w.applicationCache.removeEventListener(expectedEvent, eventHandler, true);
- w.applicationCache.dispatchEvent(e);
- is(count, 1, "Wrong number events!");
-}
-
-function loaded() {
- testEventHandling();
-
- // Click the notification panel's "Allow" button. This should kick
- // off updates, which will eventually lead to getting messages from
- // the children.
- var wm = SpecialPowers.Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(SpecialPowers.Ci.nsIWindowMediator);
- var win = wm.getMostRecentWindow("navigator:browser");
- var panel = win.PopupNotifications.panel;
- is(panel.childElementCount, 2, "2 notifications being displayed");
- panel.firstElementChild.button.click();
-
- // should have dismissed one of the notifications.
- is(panel.childElementCount, 1, "1 notification now being displayed");
- panel.firstElementChild.button.click();
-}
-
-SimpleTest.waitForFocus(loaded);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_offline_gzip.html b/browser/base/content/test/general/test_offline_gzip.html
deleted file mode 100644
index a18d6604e..000000000
--- a/browser/base/content/test/general/test_offline_gzip.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=501422
-
-When content which was transported over the network with
-Content-Type: gzip is added to the offline
-cache, it can be fetched from the cache successfully.
--->
-<head>
- <title>Test gzipped offline resources</title>
- <meta charset="utf-8">
-</head>
-<body>
-<p id="display">
-<iframe name="testFrame" src="gZipOfflineChild.html"></iframe>
-
-<div id="content" style="display: none">
-</div>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_process_flags_chrome.html b/browser/base/content/test/general/test_process_flags_chrome.html
deleted file mode 100644
index adcbf0340..000000000
--- a/browser/base/content/test/general/test_process_flags_chrome.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<body>
-<p>chrome: test page</p>
-<p><a href="chrome://mochitests/content/browser/browser/base/content/test/general/test_process_flags_chrome.html">chrome</a></p>
-<p><a href="chrome://mochitests-any/content/browser/browser/base/content/test/general/test_process_flags_chrome.html">canremote</a></p>
-<p><a href="chrome://mochitests-content/content/browser/browser/base/content/test/general/test_process_flags_chrome.html">mustremote</a></p>
-</body>
-</html>
diff --git a/browser/base/content/test/general/test_remoteTroubleshoot.html b/browser/base/content/test/general/test_remoteTroubleshoot.html
deleted file mode 100644
index 7ba1c5268..000000000
--- a/browser/base/content/test/general/test_remoteTroubleshoot.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<script>
-// This test is run multiple times, once with only strings allowed through the
-// WebChannel, and once with objects allowed. This function allows us to handle
-// both cases without too much pain.
-function makeDetails(object) {
- if (window.location.search.indexOf("object") >= 0) {
- return object;
- }
- return JSON.stringify(object)
-}
-// Add a listener for responses to our remote requests.
-window.addEventListener("WebChannelMessageToContent", function (event) {
- if (event.detail.id == "remote-troubleshooting") {
- // Send what we got back to the test.
- var backEvent = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: makeDetails({
- id: "test-remote-troubleshooting-backchannel",
- message: {
- message: event.detail.message,
- },
- }),
- });
- window.dispatchEvent(backEvent);
- // and stick it in our DOM just for good measure/diagnostics.
- document.getElementById("troubleshooting").textContent =
- JSON.stringify(event.detail.message, null, 2);
- }
-});
-
-// Make a request for the troubleshooting data as we load.
-window.onload = function() {
- var event = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: makeDetails({
- id: "remote-troubleshooting",
- message: {
- command: "request",
- },
- }),
- });
- window.dispatchEvent(event);
-}
-</script>
-
-<body>
- <pre id="troubleshooting"/>
-</body>
-
-</html>
diff --git a/browser/base/content/test/general/title_test.svg b/browser/base/content/test/general/title_test.svg
deleted file mode 100644
index 7638fd5cc..000000000
--- a/browser/base/content/test/general/title_test.svg
+++ /dev/null
@@ -1,59 +0,0 @@
-<svg width="640px" height="480px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <title>This is a root SVG element's title</title>
- <foreignObject>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <svg xmlns="http://www.w3.org/2000/svg" id="svg1">
- <title>This is a non-root SVG element title</title>
- </svg>
- </body>
- </html>
- </foreignObject>
- <text id="text1" x="10px" y="32px" font-size="24px">
- This contains only &lt;title&gt;
- <title>
-
-
- This is a title
-
- </title>
- </text>
- <text id="text2" x="10px" y="96px" font-size="24px">
- This contains only &lt;desc&gt;
- <desc>This is a desc</desc>
- </text>
- <text id="text3" x="10px" y="128px" font-size="24px" title="ignored for SVG">
- This contains nothing.
- </text>
- <a id="link1" xlink:href="#">
- This link contains &lt;title&gt;
- <title>
- This is a title
- </title>
- <text id="text4" x="10px" y="192px" font-size="24px">
- </text>
- </a>
- <a id="link2" xlink:href="#">
- <text x="10px" y="192px" font-size="24px">
- This text contains &lt;title&gt;
- <title>
- This is a title
- </title>
- </text>
- </a>
- <a id="link3" xlink:href="#" xlink:title="This is an xlink:title attribute">
- <text x="10px" y="224px" font-size="24px">
- This link contains &lt;title&gt; &amp; xlink:title attr.
- <title>This is a title</title>
- </text>
- </a>
- <a id="link4" xlink:href="#" xlink:title="This is an xlink:title attribute">
- <text x="10px" y="256px" font-size="24px">
- This link contains xlink:title attr.
- </text>
- </a>
- <text id="text5" x="10px" y="160px" font-size="24px"
- xlink:title="This is an xlink:title attribute but it isn't on a link" >
- This contains nothing.
- </text>
-</svg>
diff --git a/browser/base/content/test/general/trackingPage.html b/browser/base/content/test/general/trackingPage.html
deleted file mode 100644
index 17f0e459e..000000000
--- a/browser/base/content/test/general/trackingPage.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<html dir="ltr" xml:lang="en-US" lang="en-US">
- <head>
- <meta charset="utf8">
- </head>
- <body>
- <iframe src="http://tracking.example.com/"></iframe>
- </body>
-</html>
diff --git a/browser/base/content/test/general/unknownContentType_file.pif b/browser/base/content/test/general/unknownContentType_file.pif
deleted file mode 100644
index 9353d1312..000000000
--- a/browser/base/content/test/general/unknownContentType_file.pif
+++ /dev/null
@@ -1 +0,0 @@
-Dummy content for unknownContentType_dialog_layout_data.pif
diff --git a/browser/base/content/test/general/unknownContentType_file.pif^headers^ b/browser/base/content/test/general/unknownContentType_file.pif^headers^
deleted file mode 100644
index 09b22facc..000000000
--- a/browser/base/content/test/general/unknownContentType_file.pif^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: application/octet-stream
diff --git a/browser/base/content/test/general/video.ogg b/browser/base/content/test/general/video.ogg
deleted file mode 100644
index ac7ece351..000000000
--- a/browser/base/content/test/general/video.ogg
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/web_video.html b/browser/base/content/test/general/web_video.html
deleted file mode 100644
index 467fb0ce1..000000000
--- a/browser/base/content/test/general/web_video.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
- <head>
- <title>Document with Web Video</title>
- </head>
- <body>
- This document has some web video in it.
- <br>
- <video src="web_video1.ogv" id="video1"> </video>
- </body>
-</html>
diff --git a/browser/base/content/test/general/web_video1.ogv b/browser/base/content/test/general/web_video1.ogv
deleted file mode 100644
index 093158432..000000000
--- a/browser/base/content/test/general/web_video1.ogv
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/web_video1.ogv^headers^ b/browser/base/content/test/general/web_video1.ogv^headers^
deleted file mode 100644
index 4511e9255..000000000
--- a/browser/base/content/test/general/web_video1.ogv^headers^
+++ /dev/null
@@ -1,3 +0,0 @@
-Content-Disposition: filename="web-video1-expectedName.ogv"
-Content-Type: video/ogg
-
diff --git a/browser/base/content/test/general/zoom_test.html b/browser/base/content/test/general/zoom_test.html
deleted file mode 100644
index bf80490ca..000000000
--- a/browser/base/content/test/general/zoom_test.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=416661
--->
- <head>
- <title>Test for zoom setting</title>
-
- </head>
- <body>
- <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=416661">Bug 416661</a>
- <p>Site specific zoom settings should not apply to image documents.</p>
- </body>
-</html>
diff --git a/browser/base/content/test/newtab/.eslintrc.js b/browser/base/content/test/newtab/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/newtab/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/newtab/browser.ini b/browser/base/content/test/newtab/browser.ini
deleted file mode 100644
index 2d14d208d..000000000
--- a/browser/base/content/test/newtab/browser.ini
+++ /dev/null
@@ -1,55 +0,0 @@
-[DEFAULT]
-skip-if = (os == 'linux') # Bug 1243103, Bug 1243398, etc.
-support-files =
- head.js
-
-[browser_newtab_1188015.js]
-[browser_newtab_background_captures.js]
-[browser_newtab_block.js]
-[browser_newtab_bug721442.js]
-[browser_newtab_bug722273.js]
-skip-if = (os == "mac" && debug) # temporary skip-if due to increase in intermittent failures on Mac debug - bug 1119906
-[browser_newtab_bug723102.js]
-[browser_newtab_bug723121.js]
-[browser_newtab_bug725996.js]
-[browser_newtab_bug734043.js]
-[browser_newtab_bug735987.js]
-[browser_newtab_bug752841.js]
-[browser_newtab_bug765628.js]
-[browser_newtab_bug876313.js]
-[browser_newtab_bug991111.js]
-[browser_newtab_bug991210.js]
-[browser_newtab_bug998387.js]
-[browser_newtab_bug1145428.js]
-[browser_newtab_bug1178586.js]
-[browser_newtab_bug1194895.js]
-[browser_newtab_bug1271075.js]
-[browser_newtab_disable.js]
-[browser_newtab_drag_drop.js]
-[browser_newtab_drag_drop_ext.js]
-# temporary until determine why more intermittent on VM
-subsuite = clipboard
-[browser_newtab_drop_preview.js]
-[browser_newtab_enhanced.js]
-[browser_newtab_focus.js]
-[browser_newtab_perwindow_private_browsing.js]
-[browser_newtab_reportLinkAction.js]
-[browser_newtab_reflow_load.js]
-support-files =
- content-reflows.js
-[browser_newtab_search.js]
-support-files =
- searchEngineNoLogo.xml
- searchEngineFavicon.xml
- searchEngine1xLogo.xml
- searchEngine2xLogo.xml
- searchEngine1x2xLogo.xml
- ../general/searchSuggestionEngine.xml
- ../general/searchSuggestionEngine.sjs
-[browser_newtab_sponsored_icon_click.js]
-skip-if = true # Bug 1314619
-[browser_newtab_undo.js]
-# temporary until determine why more intermittent on VM
-subsuite = clipboard
-[browser_newtab_unpin.js]
-[browser_newtab_update.js]
diff --git a/browser/base/content/test/newtab/browser_newtab_1188015.js b/browser/base/content/test/newtab/browser_newtab_1188015.js
deleted file mode 100644
index f19aae1b9..000000000
--- a/browser/base/content/test/newtab/browser_newtab_1188015.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "directory": [{
- url: "http://example1.com/",
- enhancedImageURI: "data:image/png;base64,helloWORLD2",
- title: "title1",
- type: "affiliate",
- titleBgColor: "green"
- }]
-});
-
-add_task(function* () {
- yield pushPrefs(["browser.newtab.preload", false]);
-
- // Make the page have a directory link
- yield setLinks([]);
- yield* addNewTabPageTab();
-
- let color = yield performOnCell(0, cell => {
- return cell.node.querySelector(".newtab-title").style.backgroundColor;
- });
-
- is(color, "green", "title bg color is green");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_background_captures.js b/browser/base/content/test/newtab/browser_newtab_background_captures.js
deleted file mode 100644
index 5e838196e..000000000
--- a/browser/base/content/test/newtab/browser_newtab_background_captures.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Verifies that hidden, pre-loaded newtabs don't allow background captures, and
- * when unhidden, do allow background captures.
- */
-
-const CAPTURE_PREF = "browser.pagethumbnails.capturing_disabled";
-
-add_task(function* () {
- let imports = {};
- Cu.import("resource://gre/modules/PageThumbs.jsm", imports);
-
- // Disable captures.
- yield pushPrefs([CAPTURE_PREF, false]);
-
- // Make sure the thumbnail doesn't exist yet.
- let url = "http://example.com/";
- let path = imports.PageThumbsStorage.getFilePathForURL(url);
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- file.initWithPath(path);
- try {
- file.remove(false);
- }
- catch (err) {}
-
- // Add a top site.
- yield setLinks("-1");
-
- // We need a handle to a hidden, pre-loaded newtab so we can verify that it
- // doesn't allow background captures. Ensure we have a preloaded browser.
- gBrowser._createPreloadBrowser();
-
- // Wait for the preloaded browser to load.
- if (gBrowser._preloadedBrowser.contentDocument.readyState != "complete") {
- yield BrowserTestUtils.waitForEvent(gBrowser._preloadedBrowser, "load", true);
- }
-
- // We're now ready to use the preloaded browser.
- BrowserOpenTab();
- let tab = gBrowser.selectedTab;
-
- let thumbnailCreatedPromise = new Promise(resolve => {
- // Showing the preloaded tab should trigger thumbnail capture.
- Services.obs.addObserver(function onCreate(subj, topic, data) {
- if (data != url)
- return;
- Services.obs.removeObserver(onCreate, "page-thumbnail:create");
- ok(true, "thumbnail created after preloaded tab was shown");
-
- resolve();
- }, "page-thumbnail:create", false);
- });
-
- // Enable captures.
- yield pushPrefs([CAPTURE_PREF, false]);
-
- yield thumbnailCreatedPromise;
-
- // Test finished!
- gBrowser.removeTab(tab);
- file.remove(false);
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_block.js b/browser/base/content/test/newtab/browser_newtab_block.js
deleted file mode 100644
index 70656462a..000000000
--- a/browser/base/content/test/newtab/browser_newtab_block.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-requestLongerTimeout(2);
-
-/*
- * These tests make sure that blocking/removing sites from the grid works
- * as expected. Pinned tabs should not be moved. Gaps will be re-filled
- * if more sites are available.
- */
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "suggested": [{
- url: "http://suggested.com/",
- imageURI: "data:image/png;base64,helloWORLD3",
- title: "title",
- type: "affiliate",
- adgroup_name: "test",
- frecent_sites: ["example0.com"]
- }]
-});
-
-add_task(function* () {
- let origGetFrecentSitesName = DirectoryLinksProvider.getFrecentSitesName;
- DirectoryLinksProvider.getFrecentSitesName = () => "";
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = (site) => false;
-
- // we remove sites and expect the gaps to be filled as long as there still
- // are some sites available
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield customizeNewTabPage("enhanced"); // Toggle enhanced off
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield blockCell(4);
- yield* checkGrid("0,1,2,3,5,6,7,8,9");
-
- yield blockCell(4);
- yield* checkGrid("0,1,2,3,6,7,8,9,");
-
- yield blockCell(4);
- yield* checkGrid("0,1,2,3,7,8,9,,");
-
- // we removed a pinned site
- yield restore();
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",1");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1p,2,3,4,5,6,7,8");
-
- yield blockCell(1);
- yield* checkGrid("0,2,3,4,5,6,7,8,");
-
- // we remove the last site on the grid (which is pinned) and expect the gap
- // to be re-filled and the new site to be unpinned
- yield restore();
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- setPinnedLinks(",,,,,,,,8");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8p");
-
- yield blockCell(8);
- yield* checkGrid("0,1,2,3,4,5,6,7,9");
-
- // we remove the first site on the grid with the last one pinned. all cells
- // but the last one should shift to the left and a new site fades in
- yield restore();
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- setPinnedLinks(",,,,,,,,8");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8p");
-
- yield blockCell(0);
- yield* checkGrid("1,2,3,4,5,6,7,9,8p");
-
- // Test that blocking the targeted site also removes its associated suggested tile
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- yield restore();
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- yield customizeNewTabPage("enhanced"); // Toggle enhanced on
- yield* addNewTabPageTab();
-
- yield* checkGrid("http://suggested.com/,0,1,2,3,4,5,6,7,8,9");
-
- yield blockCell(1);
- yield* addNewTabPageTab();
- yield* checkGrid("1,2,3,4,5,6,7,8,9");
- DirectoryLinksProvider.getFrecentSitesName = origGetFrecentSitesName;
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug1145428.js b/browser/base/content/test/newtab/browser_newtab_bug1145428.js
deleted file mode 100644
index 72fe70212..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug1145428.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that pinning suggested tile results in:
- * - making suggested tile a history tile and replacing enhancedImageURI with imageURI
- * - upond end of campaign, replaces landing url with baseDomain and switches
- * background image to thumbnail
- */
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "suggested": [{
- url: "http://example.com/landing/page.html",
- imageURI: "data:image/png;base64,helloWORLD3",
- enhancedImageURI: "data:image/png;base64,helloWORLD2",
- title: "title",
- type: "affiliate",
- adgroup_name: "example",
- frecent_sites: ["example0.com"],
- }]
-});
-
-add_task(function* () {
- let origGetFrecentSitesName = DirectoryLinksProvider.getFrecentSitesName;
- DirectoryLinksProvider.getFrecentSitesName = () => "";
-
- function getData(cellNum) {
- return performOnCell(cellNum, cell => {
- if (!cell.site)
- return null;
- let siteNode = cell.site.node;
- return {
- type: siteNode.getAttribute("type"),
- thumbnail: siteNode.querySelector(".newtab-thumbnail.thumbnail").style.backgroundImage,
- enhanced: siteNode.querySelector(".enhanced-content").style.backgroundImage,
- title: siteNode.querySelector(".newtab-title").textContent,
- suggested: siteNode.getAttribute("suggested"),
- url: siteNode.querySelector(".newtab-link").getAttribute("href"),
- };
- });
- }
-
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- // load another newtab since the first may not get suggested tile
- yield* addNewTabPageTab();
- yield* checkGrid("http://example.com/landing/page.html,0,1,2,3,4,5,6,7,8,9");
- // evaluate suggested tile
- let tileData = yield getData(0);
- is(tileData.type, "affiliate", "unpinned type");
- is(tileData.thumbnail, "url(\"data:image/png;base64,helloWORLD3\")", "unpinned thumbnail");
- is(tileData.enhanced, "url(\"data:image/png;base64,helloWORLD2\")", "unpinned enhanced");
- is(tileData.suggested, "true", "has suggested set", "unpinned suggested exists");
- is(tileData.url, "http://example.com/landing/page.html", "unpinned landing page");
-
- // suggested tile should not be pinned
- is(NewTabUtils.pinnedLinks.isPinned({url: "http://example.com/landing/page.html"}), false, "suggested tile is not pinned");
-
- // pin suggested tile
- let updatedPromise = whenPagesUpdated();
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-site > .newtab-control-pin", {}, gBrowser.selectedBrowser);
- yield updatedPromise;
-
- // tile should be pinned and turned into history tile
- is(NewTabUtils.pinnedLinks.isPinned({url: "http://example.com/landing/page.html"}), true, "suggested tile is pinned");
- tileData = yield getData(0);
- is(tileData.type, "history", "pinned type");
- is(tileData.suggested, null, "no suggested attribute");
- is(tileData.url, "http://example.com/landing/page.html", "original landing page");
-
- // set pinned tile endTime into past and reload the page
- NewTabUtils.pinnedLinks._links[0].endTime = Date.now() - 1000;
- yield* addNewTabPageTab();
-
- // check that url is reset to base domain and thumbnail points to moz-page-thumb service
- is(NewTabUtils.pinnedLinks.isPinned({url: "http://example.com/"}), true, "baseDomain url is pinned");
- tileData = yield getData(0);
- is(tileData.type, "history", "type is history");
- is(tileData.title, "example.com", "title changed to baseDomain");
- is(tileData.thumbnail.indexOf("moz-page-thumb") != -1, true, "thumbnail contains moz-page-thumb");
- is(tileData.enhanced, "", "no enhanced image");
- is(tileData.url, "http://example.com/", "url points to baseDomian");
-
- DirectoryLinksProvider.getFrecentSitesName = origGetFrecentSitesName;
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug1178586.js b/browser/base/content/test/newtab/browser_newtab_bug1178586.js
deleted file mode 100644
index 84d5cb577..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug1178586.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that pinned suggested tile turns into history tile
- * and remains a history tile after a user clicks on it
- */
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "suggested": [{
- url: "http://example.com/hardlanding/page.html",
- imageURI: "data:image/png;base64,helloWORLD3",
- enhancedImageURI: "data:image/png;base64,helloWORLD2",
- title: "title",
- type: "affiliate",
- adgroup_name: "example",
- frecent_sites: ["example0.com"],
- }]
-});
-
-add_task(function* () {
- let origGetFrecentSitesName = DirectoryLinksProvider.getFrecentSitesName;
- DirectoryLinksProvider.getFrecentSitesName = () => "";
-
- function getData(cellNum) {
- return performOnCell(cellNum, cell => {
- if (!cell.site)
- return null;
- let siteNode = cell.site.node;
- return {
- type: siteNode.getAttribute("type"),
- thumbnail: siteNode.querySelector(".newtab-thumbnail.thumbnail").style.backgroundImage,
- enhanced: siteNode.querySelector(".enhanced-content").style.backgroundImage,
- title: siteNode.querySelector(".newtab-title").textContent,
- suggested: siteNode.getAttribute("suggested"),
- url: siteNode.querySelector(".newtab-link").getAttribute("href"),
- };
- });
- }
-
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- // load another newtab since the first may not get suggested tile
- yield* addNewTabPageTab();
- yield* checkGrid("http://example.com/hardlanding/page.html,0,1,2,3,4,5,6,7,8,9");
- // evaluate suggested tile
- let tileData = yield getData(0);
- is(tileData.type, "affiliate", "unpinned type");
- is(tileData.thumbnail, "url(\"data:image/png;base64,helloWORLD3\")", "unpinned thumbnail");
- is(tileData.enhanced, "url(\"data:image/png;base64,helloWORLD2\")", "unpinned enhanced");
- is(tileData.suggested, "true", "has suggested set", "unpinned suggested exists");
- is(tileData.url, "http://example.com/hardlanding/page.html", "unpinned landing page");
-
- // suggested tile should not be pinned
- is(NewTabUtils.pinnedLinks.isPinned({url: "http://example.com/hardlanding/page.html"}), false, "suggested tile is not pinned");
-
- // pin suggested tile
- let updatedPromise = whenPagesUpdated();
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-site > .newtab-control-pin", {}, gBrowser.selectedBrowser);
- yield updatedPromise;
-
- // tile should be pinned and turned into history tile
- is(NewTabUtils.pinnedLinks.isPinned({url: "http://example.com/hardlanding/page.html"}), true, "suggested tile is pinned");
- tileData = yield getData(0);
- is(tileData.type, "history", "pinned type");
- is(tileData.suggested, null, "no suggested attribute");
- is(tileData.url, "http://example.com/hardlanding/page.html", "original landing page");
-
- // click the pinned tile
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-site", {}, gBrowser.selectedBrowser);
- // add new page twice to avoid using cached version
- yield* addNewTabPageTab();
- yield* addNewTabPageTab();
-
- // check that type and suggested did not change
- tileData = yield getData(0);
- is(tileData.type, "history", "pinned type");
- is(tileData.suggested, null, "no suggested attribute");
-
- DirectoryLinksProvider.getFrecentSitesName = origGetFrecentSitesName;
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug1194895.js b/browser/base/content/test/newtab/browser_newtab_bug1194895.js
deleted file mode 100644
index c08b23185..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug1194895.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const PRELOAD_PREF = "browser.newtab.preload";
-const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
-const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
-
-function populateDirectoryTiles() {
- let directoryTiles = [];
- let i = 0;
- while (i++ < 14) {
- directoryTiles.push({
- directoryId: i,
- url: "http://example" + i + ".com/",
- enhancedImageURI: "data:image/png;base64,helloWORLD",
- title: "dirtitle" + i,
- type: "affiliate"
- });
- }
- return directoryTiles;
-}
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "directory": populateDirectoryTiles()
-});
-
-
-add_task(function* () {
- requestLongerTimeout(4);
- let origEnhanced = NewTabUtils.allPages.enhanced;
- let origCompareLinks = NewTabUtils.links.compareLinks;
- registerCleanupFunction(() => {
- NewTabUtils.allPages.enhanced = origEnhanced;
- NewTabUtils.links.compareLinks = origCompareLinks;
- });
-
- // turn off preload to ensure grid updates on every setLinks
- yield pushPrefs([PRELOAD_PREF, false]);
- // set newtab to have three columns only
- yield pushPrefs([PREF_NEWTAB_COLUMNS, 3]);
- yield pushPrefs([PREF_NEWTAB_ROWS, 5]);
-
- yield* addNewTabPageTab();
- yield customizeNewTabPage("enhanced"); // Toggle enhanced off
-
- // Testing history tiles
-
- // two rows of tiles should always fit on any screen
- yield setLinks("0,1,2,3,4,5");
- yield* addNewTabPageTab();
-
- // should do not see scrollbar since tiles fit into visible space
- yield* checkGrid("0,1,2,3,4,5");
- let scrolling = yield hasScrollbar();
- ok(!scrolling, "no scrollbar");
-
- // add enough tiles to cause extra two rows and observe scrollbar
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8,9");
- scrolling = yield hasScrollbar();
- ok(scrolling, "document has scrollbar");
-
- // pin the last tile to make it stay at the bottom of the newtab
- yield pinCell(9);
- // block first 6 tiles, which should not remove the scroll bar
- // since the last tile is pinned in the nineth position
- for (let i = 0; i < 6; i++) {
- yield blockCell(0);
- }
- yield* addNewTabPageTab();
- yield* checkGrid("6,7,8,,,,,,,9p");
- scrolling = yield hasScrollbar();
- ok(scrolling, "document has scrollbar when tile is pinned to the last row");
-
- // unpin the site: this will move tile up and make scrollbar disappear
- yield unpinCell(9);
- yield* addNewTabPageTab();
- yield* checkGrid("6,7,8,9");
- scrolling = yield hasScrollbar();
- ok(!scrolling, "no scrollbar when bottom row tile is unpinned");
-
- // reset everything to clean slate
- NewTabUtils.restore();
-
- // Testing directory tiles
- yield customizeNewTabPage("enhanced"); // Toggle enhanced on
-
- // setup page with no history tiles to test directory only display
- yield setLinks([]);
- yield* addNewTabPageTab();
- ok(!scrolling, "no scrollbar for directory tiles");
-
- // introduce one history tile - it should occupy the last
- // available slot at the bottom of newtab and cause scrollbar
- yield setLinks("41");
- yield* addNewTabPageTab();
- scrolling = yield hasScrollbar();
- ok(scrolling, "adding low frecency history site causes scrollbar");
-
- // set PREF_NEWTAB_ROWS to 4, that should clip off the history tile
- // and remove scroll bar
- yield pushPrefs([PREF_NEWTAB_ROWS, 4]);
- yield* addNewTabPageTab();
-
- scrolling = yield hasScrollbar();
- ok(!scrolling, "no scrollbar if history tiles falls past max rows");
-
- // restore max rows and watch scrollbar re-appear
- yield pushPrefs([PREF_NEWTAB_ROWS, 5]);
- yield* addNewTabPageTab();
- scrolling = yield hasScrollbar();
- ok(scrolling, "scrollbar is back when max rows allow for bottom history tile");
-
- // block that history tile, and watch scrollbar disappear
- yield blockCell(14);
- yield* addNewTabPageTab();
- scrolling = yield hasScrollbar();
- ok(!scrolling, "no scrollbar after bottom history tiles is blocked");
-
- // Test well-populated user history - newtab has highly-frecent history sites
- // redefine compareLinks to always choose history tiles first
- NewTabUtils.links.compareLinks = function (aLink1, aLink2) {
- if (aLink1.type == aLink2.type) {
- return aLink2.frecency - aLink1.frecency ||
- aLink2.lastVisitDate - aLink1.lastVisitDate;
- }
- if (aLink2.type == "history") {
- return 1;
- }
- return -1;
- };
-
- // add a row of history tiles, directory tiles will be clipped off, hence no scrollbar
- yield setLinks("31,32,33");
- yield* addNewTabPageTab();
- scrolling = yield hasScrollbar();
- ok(!scrolling, "no scrollbar when directory tiles follow history tiles");
-
- // fill first four rows with history tiles and observer scrollbar
- yield setLinks("30,31,32,33,34,35,36,37,38,39");
- yield* addNewTabPageTab();
- scrolling = yield hasScrollbar();
- ok(scrolling, "scrollbar appears when history tiles need extra row");
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_bug1271075.js b/browser/base/content/test/newtab/browser_newtab_bug1271075.js
deleted file mode 100644
index 723b48fc6..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug1271075.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- is(gBrowser.tabs.length, 1, "one tab is open initially");
-
- // Add a few tabs.
- let tabs = [];
- function addTab(aURL, aReferrer) {
- let tab = gBrowser.addTab(aURL, {referrerURI: aReferrer});
- tabs.push(tab);
- return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- }
-
- yield addTab("http://mochi.test:8888/#0");
- yield addTab("http://mochi.test:8888/#1");
- yield addTab("http://mochi.test:8888/#2");
- yield addTab("http://mochi.test:8888/#3");
-
- // Create a new tab page with a "www.example.com" tile and move it to the 2nd tab position.
- yield setLinks("-1");
- yield* addNewTabPageTab();
- gBrowser.moveTabTo(gBrowser.selectedTab, 1);
-
- // Send a middle-click and confirm that the clicked site opens immediately next to the new tab page.
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-cell",
- {button: 1}, gBrowser.selectedBrowser);
-
- yield BrowserTestUtils.browserLoaded(gBrowser.getBrowserAtIndex(2));
- is(gBrowser.getBrowserAtIndex(2).currentURI.spec, "http://example.com/",
- "Middle click opens site in a new tab immediately to the right.");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug721442.js b/browser/base/content/test/newtab/browser_newtab_bug721442.js
deleted file mode 100644
index 99bd8d930..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug721442.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks([
- {url: "http://example7.com/", title: ""},
- {url: "http://example8.com/", title: "title"},
- {url: "http://example9.com/", title: "http://example9.com/"}
- ]);
-
- yield* addNewTabPageTab();
- yield* checkGrid("7p,8p,9p,0,1,2,3,4,5");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- function checkTooltip(aIndex, aExpected, aMessage) {
- let cell = content.gGrid.cells[aIndex];
-
- let link = cell.node.querySelector(".newtab-link");
- Assert.equal(link.getAttribute("title"), aExpected, aMessage);
- }
-
- checkTooltip(0, "http://example7.com/", "1st tooltip is correct");
- checkTooltip(1, "title\nhttp://example8.com/", "2nd tooltip is correct");
- checkTooltip(2, "http://example9.com/", "3rd tooltip is correct");
- });
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_bug722273.js b/browser/base/content/test/newtab/browser_newtab_bug722273.js
deleted file mode 100644
index 5cbfcd3ff..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug722273.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const NOW = Date.now() * 1000;
-const URL = "http://fake-site.com/";
-
-var tmp = {};
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tmp);
-
-var {Sanitizer} = tmp;
-
-add_task(function* () {
- yield promiseSanitizeHistory();
- yield promiseAddFakeVisits();
- yield* addNewTabPageTab();
-
- let cellUrl = yield performOnCell(0, cell => { return cell.site.url; });
- is(cellUrl, URL, "first site is our fake site");
-
- let updatedPromise = whenPagesUpdated();
- yield promiseSanitizeHistory();
- yield updatedPromise;
-
- let isGone = yield performOnCell(0, cell => { return cell.site == null; });
- ok(isGone, "fake site is gone");
-});
-
-function promiseAddFakeVisits() {
- let visits = [];
- for (let i = 59; i > 0; i--) {
- visits.push({
- visitDate: NOW - i * 60 * 1000000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
- });
- }
- let place = {
- uri: makeURI(URL),
- title: "fake site",
- visits: visits
- };
- return new Promise((resolve, reject) => {
- PlacesUtils.asyncHistory.updatePlaces(place, {
- handleError: () => reject(new Error("Couldn't add visit")),
- handleResult: function () {},
- handleCompletion: function () {
- NewTabUtils.links.populateCache(function () {
- NewTabUtils.allPages.update();
- resolve();
- }, true);
- }
- });
- });
-}
-
-function promiseSanitizeHistory() {
- let s = new Sanitizer();
- s.prefDomain = "privacy.cpd.";
-
- let prefs = gPrefService.getBranch(s.prefDomain);
- prefs.setBoolPref("history", true);
- prefs.setBoolPref("downloads", false);
- prefs.setBoolPref("cache", false);
- prefs.setBoolPref("cookies", false);
- prefs.setBoolPref("formdata", false);
- prefs.setBoolPref("offlineApps", false);
- prefs.setBoolPref("passwords", false);
- prefs.setBoolPref("sessions", false);
- prefs.setBoolPref("siteSettings", false);
-
- return s.sanitize();
-}
diff --git a/browser/base/content/test/newtab/browser_newtab_bug723102.js b/browser/base/content/test/newtab/browser_newtab_bug723102.js
deleted file mode 100644
index 02282dc97..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug723102.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- // create a new tab page and hide it.
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- let firstTab = gBrowser.selectedTab;
-
- yield* addNewTabPageTab();
- yield BrowserTestUtils.removeTab(firstTab);
-
- ok(NewTabUtils.allPages.enabled, "page is enabled");
- NewTabUtils.allPages.enabled = false;
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- Assert.ok(content.gGrid.node.hasAttribute("page-disabled"), "page is disabled");
- });
-
- NewTabUtils.allPages.enabled = true;
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_bug723121.js b/browser/base/content/test/newtab/browser_newtab_bug723121.js
deleted file mode 100644
index 82f45ebd5..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug723121.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
- let grid = content.gGrid;
- let cell = grid.cells[0];
- let site = cell.site.node;
- let link = site.querySelector(".newtab-link");
-
- function checkGridLocked(aLocked, aMessage) {
- Assert.equal(grid.node.hasAttribute("locked"), aLocked, aMessage);
- }
-
- function sendDragEvent(aEventType, aTarget) {
- let dataTransfer = new content.DataTransfer(aEventType, false);
- let event = content.document.createEvent("DragEvent");
- event.initDragEvent(aEventType, true, true, content, 0, 0, 0, 0, 0,
- false, false, false, false, 0, null, dataTransfer);
- aTarget.dispatchEvent(event);
- }
-
- checkGridLocked(false, "grid is unlocked");
-
- sendDragEvent("dragstart", link);
- checkGridLocked(true, "grid is now locked");
-
- sendDragEvent("dragend", link);
- checkGridLocked(false, "grid isn't locked anymore");
-
- sendDragEvent("dragstart", cell.node);
- checkGridLocked(false, "grid isn't locked - dragstart was ignored");
-
- sendDragEvent("dragstart", site);
- checkGridLocked(false, "grid isn't locked - dragstart was ignored");
- });
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug725996.js b/browser/base/content/test/newtab/browser_newtab_bug725996.js
deleted file mode 100644
index e0de809c8..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug725996.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- function doDrop(data) {
- return ContentTask.spawn(gBrowser.selectedBrowser, { data: data }, function*(args) {
- let dataTransfer = new content.DataTransfer("dragstart", false);
- dataTransfer.mozSetDataAt("text/x-moz-url", args.data, 0);
- let event = content.document.createEvent("DragEvent");
- event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
- false, false, false, false, 0, null, dataTransfer);
-
- let target = content.gGrid.cells[0].node;
- target.dispatchEvent(event);
- });
- }
-
- yield doDrop("http://example99.com/\nblank");
- is(NewTabUtils.pinnedLinks.links[0].url, "http://example99.com/",
- "first cell is pinned and contains the dropped site");
-
- yield whenPagesUpdated();
- yield* checkGrid("99p,0,1,2,3,4,5,6,7");
-
- yield doDrop("");
- is(NewTabUtils.pinnedLinks.links[0].url, "http://example99.com/",
- "first cell is still pinned with the site we dropped before");
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_bug734043.js b/browser/base/content/test/newtab/browser_newtab_bug734043.js
deleted file mode 100644
index 02f765274..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug734043.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- content.addEventListener("error", function () {
- sendAsyncMessage("test:newtab-error", {});
- });
- });
-
- let receivedError = false;
- let mm = gBrowser.selectedBrowser.messageManager;
- mm.addMessageListener("test:newtab-error", function onResponse(message) {
- mm.removeMessageListener("test:newtab-error", onResponse);
- ok(false, "Error event happened");
- receivedError = true;
- });
-
- let pagesUpdatedPromise = whenPagesUpdated();
-
- for (let i = 0; i < 3; i++) {
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-control-block", {}, gBrowser.selectedBrowser);
- }
-
- yield pagesUpdatedPromise;
-
- ok(!receivedError, "we got here without any errors");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug735987.js b/browser/base/content/test/newtab/browser_newtab_bug735987.js
deleted file mode 100644
index 2ae541c70..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug735987.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield* simulateExternalDrop(1);
- yield* checkGrid("0,99p,1,2,3,4,5,6,7");
-
- yield blockCell(1);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield* simulateExternalDrop(1);
- yield* checkGrid("0,99p,1,2,3,4,5,6,7");
-
- // Simulate a restart and force the next about:newtab
- // instance to read its data from the storage again.
- NewTabUtils.blockedLinks.resetCache();
-
- // Update all open pages, e.g. preloaded ones.
- NewTabUtils.allPages.update();
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,99p,1,2,3,4,5,6,7");
-
- yield blockCell(1);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug752841.js b/browser/base/content/test/newtab/browser_newtab_bug752841.js
deleted file mode 100644
index e3faad13f..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug752841.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
-const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
-
-function getCellsCount()
-{
- return ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- return content.gGrid.cells.length;
- });
-}
-
-add_task(function* () {
- let testValues = [
- {row: 0, column: 0},
- {row: -1, column: -1},
- {row: -1, column: 0},
- {row: 0, column: -1},
- {row: 2, column: 4},
- {row: 2, column: 5},
- ];
-
- // Expected length of grid
- let expectedValues = [1, 1, 1, 1, 8, 10];
-
- // Values before setting new pref values (15 is the default value -> 5 x 3)
- let previousValues = [15, 1, 1, 1, 1, 8];
-
- yield* addNewTabPageTab();
- let existingTab = gBrowser.selectedTab;
-
- for (let i = 0; i < expectedValues.length; i++) {
- let existingTabGridLength = yield getCellsCount();
- is(existingTabGridLength, previousValues[i],
- "Grid length of existing page before update is correctly.");
-
- yield pushPrefs([PREF_NEWTAB_ROWS, testValues[i].row]);
- yield pushPrefs([PREF_NEWTAB_COLUMNS, testValues[i].column]);
-
- existingTabGridLength = yield getCellsCount();
- is(existingTabGridLength, expectedValues[i],
- "Existing page grid is updated correctly.");
-
- yield* addNewTabPageTab();
- let newTab = gBrowser.selectedTab;
- let newTabGridLength = yield getCellsCount();
- is(newTabGridLength, expectedValues[i],
- "New page grid is updated correctly.");
-
- yield BrowserTestUtils.removeTab(newTab);
- }
-
- gBrowser.removeTab(existingTab);
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_bug765628.js b/browser/base/content/test/newtab/browser_newtab_bug765628.js
deleted file mode 100644
index 25afd32a9..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug765628.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
- const BAD_DRAG_DATA = "javascript:alert('h4ck0rz');\nbad stuff";
- const GOOD_DRAG_DATA = "http://example99.com/\nsite 99";
-
- function sendDropEvent(aCellIndex, aDragData) {
- let dataTransfer = new content.DataTransfer("dragstart", false);
- dataTransfer.mozSetDataAt("text/x-moz-url", aDragData, 0);
- let event = content.document.createEvent("DragEvent");
- event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
- false, false, false, false, 0, null, dataTransfer);
-
- let target = content.gGrid.cells[aCellIndex].node;
- target.dispatchEvent(event);
- }
-
- sendDropEvent(0, BAD_DRAG_DATA);
- sendDropEvent(1, GOOD_DRAG_DATA);
- });
-
- yield whenPagesUpdated();
- yield* checkGrid("0,99p,1,2,3,4,5,6,7");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug876313.js b/browser/base/content/test/newtab/browser_newtab_bug876313.js
deleted file mode 100644
index 1c0b0f501..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug876313.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * This test makes sure that the changes made by unpinning
- * a site are actually written to NewTabUtils' storage.
- */
-add_task(function* () {
- // Second cell is pinned with page #99.
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",99");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,99p,1,2,3,4,5,6,7");
-
- // Unpin the second cell's site.
- yield unpinCell(1);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- // Clear the pinned cache to force NewTabUtils to read the pref again.
- NewTabUtils.pinnedLinks.resetCache();
- NewTabUtils.allPages.update();
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug991111.js b/browser/base/content/test/newtab/browser_newtab_bug991111.js
deleted file mode 100644
index 37aa8213b..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug991111.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- // set max rows to 1, to avoid scroll events by clicking middle button
- yield pushPrefs(["browser.newtabpage.rows", 1]);
- yield setLinks("-1");
- yield* addNewTabPageTab();
- // we need a second newtab to honor max rows
- yield* addNewTabPageTab();
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {index: 0}, function* (args) {
- let {site} = content.wrappedJSObject.gGrid.cells[args.index];
-
- let origOnClick = site.onClick;
- site.onClick = e => {
- origOnClick.call(site, e);
- sendAsyncMessage("test:clicked-on-cell", {});
- };
- });
-
- let mm = gBrowser.selectedBrowser.messageManager;
- let messagePromise = new Promise(resolve => {
- mm.addMessageListener("test:clicked-on-cell", function onResponse(message) {
- mm.removeMessageListener("test:clicked-on-cell", onResponse);
- resolve();
- });
- });
-
- // Send a middle-click and make sure it happened
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-cell",
- {button: 1}, gBrowser.selectedBrowser);
- yield messagePromise;
- ok(true, "middle click triggered click listener");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug991210.js b/browser/base/content/test/newtab/browser_newtab_bug991210.js
deleted file mode 100644
index 367c49f5c..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug991210.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- // turn off preload to ensure that a newtab page loads
- yield pushPrefs(["browser.newtab.preload", false]);
-
- // add a test provider that waits for load
- let afterLoadProvider = {
- getLinks: function(callback) {
- this.callback = callback;
- },
- addObserver: function() {},
- };
- NewTabUtils.links.addProvider(afterLoadProvider);
-
- // wait until about:newtab loads before calling provider callback
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab");
-
- afterLoadProvider.callback([]);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let {_cellHeight, _cellWidth, node} = content.gGrid;
- Assert.notEqual(_cellHeight, null, "grid has a computed cell height");
- Assert.notEqual(_cellWidth, null, "grid has a computed cell width");
- let {height, maxHeight, maxWidth} = node.style;
- Assert.notEqual(height, "", "grid has a computed grid height");
- Assert.notEqual(maxHeight, "", "grid has a computed grid max-height");
- Assert.notEqual(maxWidth, "", "grid has a computed grid max-width");
- });
-
- // restore original state
- NewTabUtils.links.removeProvider(afterLoadProvider);
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_bug998387.js b/browser/base/content/test/newtab/browser_newtab_bug998387.js
deleted file mode 100644
index 30424c2e5..000000000
--- a/browser/base/content/test/newtab/browser_newtab_bug998387.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- // set max rows to 1, to avoid scroll events by clicking middle button
- yield pushPrefs(["browser.newtabpage.rows", 1]);
- yield setLinks("0");
- yield* addNewTabPageTab();
- // we need a second newtab to honor max rows
- yield* addNewTabPageTab();
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {index: 0}, function* (args) {
- let {site} = content.wrappedJSObject.gGrid.cells[args.index];
-
- let origOnClick = site.onClick;
- site.onClick = e => {
- origOnClick.call(site, e);
- sendAsyncMessage("test:clicked-on-cell", {});
- };
- });
-
- let mm = gBrowser.selectedBrowser.messageManager;
- let messagePromise = new Promise(resolve => {
- mm.addMessageListener("test:clicked-on-cell", function onResponse(message) {
- mm.removeMessageListener("test:clicked-on-cell", onResponse);
- resolve();
- });
- });
-
- // Send a middle-click and make sure it happened
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-control-block",
- {button: 1}, gBrowser.selectedBrowser);
-
- yield messagePromise;
- ok(true, "middle click triggered click listener");
-
- // Make sure the cell didn't actually get blocked
- yield* checkGrid("0");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_disable.js b/browser/base/content/test/newtab/browser_newtab_disable.js
deleted file mode 100644
index 58b9a18af..000000000
--- a/browser/base/content/test/newtab/browser_newtab_disable.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that the 'New Tab Page' feature can be disabled if the
- * decides not to use it.
- */
-add_task(function* () {
- // create a new tab page and hide it.
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- let firstTab = yield* addNewTabPageTab();
-
- function isGridDisabled(browser = gBrowser.selectedBrowser)
- {
- return ContentTask.spawn(browser, {}, function*() {
- return content.gGrid.node.hasAttribute("page-disabled");
- });
- }
-
- let isDisabled = yield isGridDisabled();
- ok(!isDisabled, "page is not disabled");
-
- NewTabUtils.allPages.enabled = false;
-
- isDisabled = yield isGridDisabled();
- ok(isDisabled, "page is disabled");
-
- // create a second new tab page and make sure it's disabled. enable it
- // again and check if the former page gets enabled as well.
- yield* addNewTabPageTab();
- isDisabled = yield isGridDisabled(firstTab.linkedBrowser);
- ok(isDisabled, "page is disabled");
-
- // check that no sites have been rendered
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
- Assert.equal(content.document.querySelectorAll(".site").length, 0,
- "no sites have been rendered");
- });
-
- NewTabUtils.allPages.enabled = true;
-
- isDisabled = yield isGridDisabled();
- ok(!isDisabled, "page is not disabled");
-
- isDisabled = yield isGridDisabled(firstTab.linkedBrowser);
- ok(!isDisabled, "old page is not disabled");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_drag_drop.js b/browser/base/content/test/newtab/browser_newtab_drag_drop.js
deleted file mode 100644
index da9d89de7..000000000
--- a/browser/base/content/test/newtab/browser_newtab_drag_drop.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that dragging and dropping sites works as expected.
- * Sites contained in the grid need to shift around to indicate the result
- * of the drag-and-drop operation. If the grid is full and we're dragging
- * a new site into it another one gets pushed out.
- */
-add_task(function* () {
- requestLongerTimeout(2);
- yield* addNewTabPageTab();
-
- // test a simple drag-and-drop scenario
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield doDragEvent(0, 1);
- yield* checkGrid("1,0p,2,3,4,5,6,7,8");
-
- // drag a cell to its current cell and make sure it's not pinned afterwards
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- yield doDragEvent(0, 0);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- // ensure that pinned pages aren't moved if that's not necessary
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",1,2");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1p,2p,3,4,5,6,7,8");
-
- yield doDragEvent(0, 3);
- yield* checkGrid("3,1p,2p,0p,4,5,6,7,8");
-
- // pinned sites should always be moved around as blocks. if a pinned site is
- // moved around, neighboring pinned are affected as well
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("0,1");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0p,1p,2,3,4,5,6,7,8");
-
- yield doDragEvent(2, 0);
- yield* checkGrid("2p,0p,1p,3,4,5,6,7,8");
-
- // pinned sites should not be pushed out of the grid (unless there are only
- // pinned ones left on the grid)
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",,,,,,,7,8");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7p,8p");
-
- yield doDragEvent(2, 5);
- yield* checkGrid("0,1,3,4,5,2p,6,7p,8p");
-
- // make sure that pinned sites are re-positioned correctly
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("0,1,2,,,5");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0p,1p,2p,3,4,5p,6,7,8");
-
- yield doDragEvent(0, 4);
- yield* checkGrid("3,1p,2p,4,0p,5p,6,7,8");
-});
-
-function doDragEvent(sourceIndex, dropIndex) {
- return ContentTask.spawn(gBrowser.selectedBrowser,
- { sourceIndex: sourceIndex, dropIndex: dropIndex }, function*(args) {
- let dataTransfer = new content.DataTransfer("dragstart", false);
- let event = content.document.createEvent("DragEvent");
- event.initDragEvent("dragstart", true, true, content, 0, 0, 0, 0, 0,
- false, false, false, false, 0, null, dataTransfer);
-
- let target = content.gGrid.cells[args.sourceIndex].site.node;
- target.dispatchEvent(event);
-
- event = content.document.createEvent("DragEvent");
- event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
- false, false, false, false, 0, null, dataTransfer);
-
- target = content.gGrid.cells[args.dropIndex].node;
- target.dispatchEvent(event);
- });
-}
diff --git a/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js b/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js
deleted file mode 100644
index 4e7b062cb..000000000
--- a/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-requestLongerTimeout(2);
-
-const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
-
-/*
- * These tests make sure that dragging and dropping sites works as expected.
- * Sites contained in the grid need to shift around to indicate the result
- * of the drag-and-drop operation. If the grid is full and we're dragging
- * a new site into it another one gets pushed out.
- * This is a continuation of browser_newtab_drag_drop.js
- * to decrease test run time, focusing on external sites.
- */
- add_task(function* () {
- yield* addNewTabPageTab();
-
- // drag a new site onto the very first cell
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",,,,,,,7,8");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7p,8p");
-
- yield* simulateExternalDrop(0);
- yield* checkGrid("99p,0,1,2,3,4,5,7p,8p");
-
- // drag a new site onto the grid and make sure that pinned cells don't get
- // pushed out
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",,,,,,,7,8");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7p,8p");
-
- // force the grid to be small enough that a pinned cell could be pushed out
- yield pushPrefs([PREF_NEWTAB_COLUMNS, 3]);
- yield* simulateExternalDrop(5);
- yield* checkGrid("0,1,2,3,4,99p,5,7p,8p");
-
- // drag a new site beneath a pinned cell and make sure the pinned cell is
- // not moved
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",,,,,,,,8");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1,2,3,4,5,6,7,8p");
-
- yield* simulateExternalDrop(5);
- yield* checkGrid("0,1,2,3,4,99p,5,6,8p");
-
- // drag a new site onto a block of pinned sites and make sure they're shifted
- // around accordingly
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("0,1,2,,,,,,");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0p,1p,2p");
-
- yield* simulateExternalDrop(1);
- yield* checkGrid("0p,99p,1p,2p,3,4,5,6,7");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_drop_preview.js b/browser/base/content/test/newtab/browser_newtab_drop_preview.js
deleted file mode 100644
index f9e37f629..000000000
--- a/browser/base/content/test/newtab/browser_newtab_drop_preview.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests ensure that the drop preview correctly arranges sites when
- * dragging them around.
- */
-add_task(function* () {
- yield* addNewTabPageTab();
-
- // the first three sites are pinned - make sure they're re-arranged correctly
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("0,1,2,,,5");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0p,1p,2p,3,4,5p,6,7,8");
-
- let foundSites = yield ContentTask.spawn(gWindow.gBrowser.selectedBrowser, {}, function*() {
- let cells = content.gGrid.cells;
- content.gDrag._draggedSite = cells[0].site;
- let sites = content.gDropPreview.rearrange(cells[4]);
- content.gDrag._draggedSite = null;
-
- sites = sites.slice(0, 9);
- return sites.map(function (aSite) {
- if (!aSite)
- return "";
-
- let pinned = aSite.isPinned();
- if (pinned != aSite.node.hasAttribute("pinned")) {
- Assert.ok(false, "invalid state (site.isPinned() != site[pinned])");
- }
-
- return aSite.url.replace(/^http:\/\/example(\d+)\.com\/$/, "$1") + (pinned ? "p" : "");
- });
- });
-
- let expectedSites = "3,1p,2p,4,0p,5p,6,7,8"
- is(foundSites, expectedSites, "grid status = " + expectedSites);
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_enhanced.js b/browser/base/content/test/newtab/browser_newtab_enhanced.js
deleted file mode 100644
index 5ac07ce55..000000000
--- a/browser/base/content/test/newtab/browser_newtab_enhanced.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-requestLongerTimeout(2);
-
-const PRELOAD_PREF = "browser.newtab.preload";
-
-var suggestedLink = {
- url: "http://example1.com/2",
- imageURI: "data:image/png;base64,helloWORLD3",
- title: "title2",
- type: "affiliate",
- adgroup_name: "Technology",
- frecent_sites: ["classroom.google.com", "codeacademy.org", "codecademy.com", "codeschool.com", "codeyear.com", "elearning.ut.ac.id", "how-to-build-websites.com", "htmlcodetutorial.com", "htmldog.com", "htmlplayground.com", "learn.jquery.com", "quackit.com", "roseindia.net", "teamtreehouse.com", "tizag.com", "tutorialspoint.com", "udacity.com", "w3schools.com", "webdevelopersnotes.com"]
-};
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "enhanced": [{
- url: "http://example.com/",
- enhancedImageURI: "data:image/png;base64,helloWORLD",
- title: "title",
- type: "organic",
- }],
- "directory": [{
- url: "http://example1.com/",
- enhancedImageURI: "data:image/png;base64,helloWORLD2",
- title: "title1",
- type: "organic"
- }],
- "suggested": [suggestedLink]
-});
-
-add_task(function* () {
- let origEnhanced = NewTabUtils.allPages.enhanced;
- registerCleanupFunction(() => {
- NewTabUtils.allPages.enhanced = origEnhanced;
- });
-
- yield pushPrefs([PRELOAD_PREF, false]);
-
- function getData(cellNum) {
- return performOnCell(cellNum, cell => {
- if (!cell.site)
- return null;
- let siteNode = cell.site.node;
- return {
- type: siteNode.getAttribute("type"),
- enhanced: siteNode.querySelector(".enhanced-content").style.backgroundImage,
- title: siteNode.querySelector(".newtab-title").textContent,
- suggested: siteNode.querySelector(".newtab-suggested").innerHTML
- };
- });
- }
-
- // Make the page have a directory link, enhanced link, and history link
- yield setLinks("-1");
-
- // Test with enhanced = false
- yield* addNewTabPageTab();
- yield customizeNewTabPage("classic");
- yield customizeNewTabPage("enhanced"); // Toggle enhanced off
- let {type, enhanced, title, suggested} = yield getData(0);
- isnot(type, "enhanced", "history link is not enhanced");
- is(enhanced, "", "history link has no enhanced image");
- is(title, "example.com");
- is(suggested, "", "There is no suggested explanation");
-
- let data = yield getData(1);
- is(data, null, "there is only one link and it's a history link");
-
- // Test with enhanced = true
- yield* addNewTabPageTab();
- yield customizeNewTabPage("enhanced"); // Toggle enhanced on
- ({type, enhanced, title, suggested} = yield getData(0));
- is(type, "organic", "directory link is organic");
- isnot(enhanced, "", "directory link has enhanced image");
- is(title, "title1");
- is(suggested, "", "There is no suggested explanation");
-
- ({type, enhanced, title, suggested} = yield getData(1));
- is(type, "enhanced", "history link is enhanced");
- isnot(enhanced, "", "history link has enhanced image");
- is(title, "title");
- is(suggested, "", "There is no suggested explanation");
-
- data = yield getData(2);
- is(data, null, "there are only 2 links, directory and enhanced history");
-
- // Test with a pinned link
- setPinnedLinks("-1");
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- is(type, "enhanced", "pinned history link is enhanced");
- isnot(enhanced, "", "pinned history link has enhanced image");
- is(title, "title");
- is(suggested, "", "There is no suggested explanation");
-
- ({type, enhanced, title, suggested} = yield getData(1));
- is(type, "organic", "directory link is organic");
- isnot(enhanced, "", "directory link has enhanced image");
- is(title, "title1");
- is(suggested, "", "There is no suggested explanation");
-
- data = yield getData(2);
- is(data, null, "directory link pushed out by pinned history link");
-
- // Test pinned link with enhanced = false
- yield* addNewTabPageTab();
- yield customizeNewTabPage("enhanced"); // Toggle enhanced off
- ({type, enhanced, title, suggested} = yield getData(0));
- isnot(type, "enhanced", "history link is not enhanced");
- is(enhanced, "", "history link has no enhanced image");
- is(title, "example.com");
- is(suggested, "", "There is no suggested explanation");
-
- data = yield getData(1);
- is(data, null, "directory link still pushed out by pinned history link");
-
- yield unpinCell(0);
-
-
-
- // Test that a suggested tile is not enhanced by a directory tile
- NewTabUtils.isTopPlacesSite = () => true;
- yield setLinks("-1,2,3,4,5,6,7,8");
-
- // Test with enhanced = false
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- isnot(type, "enhanced", "history link is not enhanced");
- is(enhanced, "", "history link has no enhanced image");
- is(title, "example.com");
- is(suggested, "", "There is no suggested explanation");
-
- data = yield getData(7);
- isnot(data, null, "there are 8 history links");
- data = yield getData(8);
- is(data, null, "there are 8 history links");
-
-
- // Test with enhanced = true
- yield* addNewTabPageTab();
- yield customizeNewTabPage("enhanced");
-
- // Suggested link was not enhanced by directory link with same domain
- ({type, enhanced, title, suggested} = yield getData(0));
- is(type, "affiliate", "suggested link is affiliate");
- is(enhanced, "", "suggested link has no enhanced image");
- is(title, "title2");
- ok(suggested.indexOf("Suggested for <strong> Technology </strong> visitors") > -1, "Suggested for 'Technology'");
-
- // Enhanced history link shows up second
- ({type, enhanced, title, suggested} = yield getData(1));
- is(type, "enhanced", "pinned history link is enhanced");
- isnot(enhanced, "", "pinned history link has enhanced image");
- is(title, "title");
- is(suggested, "", "There is no suggested explanation");
-
- data = yield getData(9);
- is(data, null, "there is a suggested link followed by an enhanced history link and the remaining history links");
-
-
-
- // Test no override category/adgroup name.
- let linksChangedPromise = watchLinksChangeOnce();
- yield pushPrefs([PREF_NEWTAB_DIRECTORYSOURCE,
- "data:application/json," + JSON.stringify({"suggested": [suggestedLink]})]);
- yield linksChangedPromise;
-
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- Cu.reportError("SUGGEST " + suggested);
- ok(suggested.indexOf("Suggested for <strong> Technology </strong> visitors") > -1, "Suggested for 'Technology'");
-
-
- // Test server provided explanation string.
- suggestedLink.explanation = "Suggested for %1$S enthusiasts who visit sites like %2$S";
- linksChangedPromise = watchLinksChangeOnce();
- yield pushPrefs([PREF_NEWTAB_DIRECTORYSOURCE,
- "data:application/json," + encodeURIComponent(JSON.stringify({"suggested": [suggestedLink]}))]);
- yield linksChangedPromise;
-
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- Cu.reportError("SUGGEST " + suggested);
- ok(suggested.indexOf("Suggested for <strong> Technology </strong> enthusiasts who visit sites like <strong> classroom.google.com </strong>") > -1, "Suggested for 'Technology' enthusiasts");
-
-
- // Test server provided explanation string with category override.
- suggestedLink.adgroup_name = "webdev education";
- linksChangedPromise = watchLinksChangeOnce();
- yield pushPrefs([PREF_NEWTAB_DIRECTORYSOURCE,
- "data:application/json," + encodeURIComponent(JSON.stringify({"suggested": [suggestedLink]}))]);
- yield linksChangedPromise;
-
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- Cu.reportError("SUGGEST " + suggested);
- ok(suggested.indexOf("Suggested for <strong> webdev education </strong> enthusiasts who visit sites like <strong> classroom.google.com </strong>") > -1, "Suggested for 'webdev education' enthusiasts");
-
-
-
- // Test with xml entities in category name
- suggestedLink.url = "http://example1.com/3";
- suggestedLink.adgroup_name = ">angles< & \"quotes\'";
- linksChangedPromise = watchLinksChangeOnce();
- yield pushPrefs([PREF_NEWTAB_DIRECTORYSOURCE,
- "data:application/json," + encodeURIComponent(JSON.stringify({"suggested": [suggestedLink]}))]);
- yield linksChangedPromise;
-
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- Cu.reportError("SUGGEST " + suggested);
- ok(suggested.indexOf("Suggested for <strong> &gt;angles&lt; &amp; \"quotes\' </strong> enthusiasts who visit sites like <strong> classroom.google.com </strong>") > -1, "Suggested for 'xml entities' enthusiasts");
-
-
- // Test with xml entities in explanation.
- suggestedLink.explanation = "Testing junk explanation &<>\"'";
- linksChangedPromise = watchLinksChangeOnce();
- yield pushPrefs([PREF_NEWTAB_DIRECTORYSOURCE,
- "data:application/json," + encodeURIComponent(JSON.stringify({"suggested": [suggestedLink]}))]);
- yield linksChangedPromise;
-
- yield* addNewTabPageTab();
- ({type, enhanced, title, suggested} = yield getData(0));
- Cu.reportError("SUGGEST " + suggested);
- ok(suggested.indexOf("Testing junk explanation &amp;&lt;&gt;\"'") > -1, "Junk test");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_focus.js b/browser/base/content/test/newtab/browser_newtab_focus.js
deleted file mode 100644
index ae0dd8d29..000000000
--- a/browser/base/content/test/newtab/browser_newtab_focus.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that focusing the 'New Tab Page' works as expected.
- */
-add_task(function* () {
- yield pushPrefs(["accessibility.tabfocus", 7]);
-
- // Focus count in new tab page.
- // 30 = 9 * 3 + 3 = 9 sites, each with link, pin and remove buttons; search
- // bar; search button; and toggle button. Additionaly there may or may not be
- // a scroll bar caused by fix to 1180387, which will eat an extra focus
- let FOCUS_COUNT = 30;
-
- // Create a new tab page.
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("");
-
- yield* addNewTabPageTab();
- gURLBar.focus();
-
- // Count the focus with the enabled page.
- countFocus(FOCUS_COUNT);
-
- // Disable page and count the focus with the disabled page.
- NewTabUtils.allPages.enabled = false;
-
- countFocus(4);
-
- NewTabUtils.allPages.enabled = true;
-});
-
-/**
- * Focus the urlbar and count how many focus stops to return again to the urlbar.
- */
-function countFocus(aExpectedCount) {
- let focusCount = 0;
- do {
- EventUtils.synthesizeKey("VK_TAB", {});
- if (document.activeElement == gBrowser.selectedBrowser) {
- focusCount++;
- }
- } while (document.activeElement != gURLBar.inputField);
-
- ok(focusCount == aExpectedCount || focusCount == (aExpectedCount + 1),
- "Validate focus count in the new tab page.");
-}
diff --git a/browser/base/content/test/newtab/browser_newtab_perwindow_private_browsing.js b/browser/base/content/test/newtab/browser_newtab_perwindow_private_browsing.js
deleted file mode 100644
index b330bec13..000000000
--- a/browser/base/content/test/newtab/browser_newtab_perwindow_private_browsing.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests ensure that all changes made to the new tab page in private
- * browsing mode are discarded after switching back to normal mode again.
- * The private browsing mode should start with the current grid shown in normal
- * mode.
- */
-
-add_task(function* () {
- // prepare the grid
- yield testOnWindow(undefined);
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
-
- yield* addNewTabPageTab();
- yield pinCell(0);
- yield* checkGrid("0p,1,2,3,4,5,6,7,8");
-
- // open private window
- yield testOnWindow({private: true});
-
- yield* addNewTabPageTab();
- yield* checkGrid("0p,1,2,3,4,5,6,7,8");
-
- // modify the grid while we're in pb mode
- yield blockCell(1);
- yield* checkGrid("0p,2,3,4,5,6,7,8");
-
- yield unpinCell(0);
- yield* checkGrid("0,2,3,4,5,6,7,8");
-
- // open normal window
- yield testOnWindow(undefined);
-
- // check that the grid is the same as before entering pb mode
- yield* addNewTabPageTab();
- yield* checkGrid("0,2,3,4,5,6,7,8")
-});
-
-var windowsToClose = [];
-function* testOnWindow(options) {
- let newWindowPromise = BrowserTestUtils.waitForNewWindow();
- var win = OpenBrowserWindow(options);
- windowsToClose.push(win);
- gWindow = win;
- yield newWindowPromise;
-}
-
-registerCleanupFunction(function () {
- gWindow = window;
- windowsToClose.forEach(function(win) {
- win.close();
- });
-});
-
diff --git a/browser/base/content/test/newtab/browser_newtab_reflow_load.js b/browser/base/content/test/newtab/browser_newtab_reflow_load.js
deleted file mode 100644
index b8a24595e..000000000
--- a/browser/base/content/test/newtab/browser_newtab_reflow_load.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const FRAME_SCRIPT = getRootDirectory(gTestPath) + "content-reflows.js";
-const ADDITIONAL_WAIT_MS = 2000;
-
-/*
- * Ensure that loading about:newtab doesn't cause uninterruptible reflows.
- */
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- return gBrowser.selectedTab = gBrowser.addTab("about:blank", {animate: false});
- }, false);
-
- let browser = gBrowser.selectedBrowser;
- let mm = browser.messageManager;
- mm.loadFrameScript(FRAME_SCRIPT, true);
- mm.addMessageListener("newtab-reflow", ({data: stack}) => {
- ok(false, `unexpected uninterruptible reflow ${stack}`);
- });
-
- let browserLoadedPromise = BrowserTestUtils.waitForEvent(browser, "load", true);
- browser.loadURI("about:newtab");
- yield browserLoadedPromise;
-
- // Wait some more to catch sync reflows after the page has loaded.
- yield new Promise(resolve => {
- setTimeout(resolve, ADDITIONAL_WAIT_MS);
- });
-
- // Clean up.
- gBrowser.removeCurrentTab({animate: false});
-
- ok(true, "Each test requires at least one pass, fail or todo so here is a pass.");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_reportLinkAction.js b/browser/base/content/test/newtab/browser_newtab_reportLinkAction.js
deleted file mode 100644
index 24e1be369..000000000
--- a/browser/base/content/test/newtab/browser_newtab_reportLinkAction.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const PRELOAD_PREF = "browser.newtab.preload";
-
-gDirectorySource = "data:application/json," + JSON.stringify({
- "directory": [{
- url: "http://example.com/organic",
- type: "organic"
- }, {
- url: "http://localhost/sponsored",
- type: "sponsored"
- }]
-});
-
-add_task(function* () {
- yield pushPrefs([PRELOAD_PREF, false]);
-
- let originalReportSitesAction = DirectoryLinksProvider.reportSitesAction;
- registerCleanupFunction(() => {
- DirectoryLinksProvider.reportSitesAction = originalReportSitesAction;
- });
-
- let expected = {};
-
- function expectReportSitesAction() {
- return new Promise(resolve => {
- DirectoryLinksProvider.reportSitesAction = function(sites, action, siteIndex) {
- let {link} = sites[siteIndex];
- is(link.type, expected.type, "got expected type");
- is(action, expected.action, "got expected action");
- is(NewTabUtils.pinnedLinks.isPinned(link), expected.pinned, "got expected pinned");
- resolve();
- }
- });
- }
-
- // Test that the last visible site (index 1) is reported
- let reportSitesPromise = expectReportSitesAction();
- expected.type = "sponsored";
- expected.action = "view";
- expected.pinned = false;
- yield* addNewTabPageTab();
- yield reportSitesPromise;
-
- // Click the pin button on the link in the 1th tile spot
- expected.action = "pin";
- // tiles become "history" when pinned
- expected.type = "history";
- expected.pinned = true;
- let pagesUpdatedPromise = whenPagesUpdated();
- reportSitesPromise = expectReportSitesAction();
-
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-cell + .newtab-cell .newtab-control-pin", {}, gBrowser.selectedBrowser);
- yield pagesUpdatedPromise;
- yield reportSitesPromise;
-
- // Unpin that link
- expected.action = "unpin";
- expected.pinned = false;
- pagesUpdatedPromise = whenPagesUpdated();
- reportSitesPromise = expectReportSitesAction();
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-cell + .newtab-cell .newtab-control-pin", {}, gBrowser.selectedBrowser);
- yield pagesUpdatedPromise;
- yield reportSitesPromise;
-
- // Block the site in the 0th tile spot
- expected.type = "organic";
- expected.action = "block";
- expected.pinned = false;
- pagesUpdatedPromise = whenPagesUpdated();
- reportSitesPromise = expectReportSitesAction();
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-site .newtab-control-block", {}, gBrowser.selectedBrowser);
- yield pagesUpdatedPromise;
- yield reportSitesPromise;
-
- // Click the 1th link now in the 0th tile spot
- expected.type = "history";
- expected.action = "click";
- reportSitesPromise = expectReportSitesAction();
- yield BrowserTestUtils.synthesizeMouseAtCenter(".newtab-site", {}, gBrowser.selectedBrowser);
- yield reportSitesPromise;
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_search.js b/browser/base/content/test/newtab/browser_newtab_search.js
deleted file mode 100644
index 19ed4ba74..000000000
--- a/browser/base/content/test/newtab/browser_newtab_search.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// See browser/components/search/test/browser_*_behavior.js for tests of actual
-// searches.
-
-Cu.import("resource://gre/modules/Task.jsm");
-
-const ENGINE_NO_LOGO = {
- name: "searchEngineNoLogo.xml",
- numLogos: 0,
-};
-
-const ENGINE_FAVICON = {
- name: "searchEngineFavicon.xml",
- logoPrefix1x: "data:image/png;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsA",
- numLogos: 1,
-};
-ENGINE_FAVICON.logoPrefix2x = ENGINE_FAVICON.logoPrefix1x;
-
-const ENGINE_1X_LOGO = {
- name: "searchEngine1xLogo.xml",
- logoPrefix1x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADEw",
- numLogos: 1,
-};
-ENGINE_1X_LOGO.logoPrefix2x = ENGINE_1X_LOGO.logoPrefix1x;
-
-const ENGINE_2X_LOGO = {
- name: "searchEngine2xLogo.xml",
- logoPrefix2x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMU",
- numLogos: 1,
-};
-ENGINE_2X_LOGO.logoPrefix1x = ENGINE_2X_LOGO.logoPrefix2x;
-
-const ENGINE_1X_2X_LOGO = {
- name: "searchEngine1x2xLogo.xml",
- logoPrefix1x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADIG",
- logoPrefix2x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMo",
- numLogos: 2,
-};
-
-const ENGINE_SUGGESTIONS = {
- name: "searchSuggestionEngine.xml",
- numLogos: 0,
-};
-
-// The test has an expected search event queue and a search event listener.
-// Search events that are expected to happen are added to the queue, and the
-// listener consumes the queue and ensures that each event it receives is at
-// the head of the queue.
-let gExpectedSearchEventQueue = [];
-let gExpectedSearchEventResolver = null;
-
-let gNewEngines = [];
-
-add_task(function* () {
- let oldCurrentEngine = Services.search.currentEngine;
-
- yield* addNewTabPageTab();
-
- // The tab is removed at the end of the test, so there's no need to remove
- // this listener at the end of the test.
- info("Adding search event listener");
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- const SERVICE_EVENT_NAME = "ContentSearchService";
- content.addEventListener(SERVICE_EVENT_NAME, function (event) {
- sendAsyncMessage("test:search-event", { eventType: event.detail.type });
- });
- });
-
- let mm = gBrowser.selectedBrowser.messageManager;
- mm.addMessageListener("test:search-event", function (message) {
- let eventType = message.data.eventType;
- if (!gExpectedSearchEventResolver) {
- ok(false, "Got search event " + eventType + " with no promise assigned");
- }
-
- let expectedEventType = gExpectedSearchEventQueue.shift();
- is(eventType, expectedEventType, "Got expected search event " + expectedEventType);
- if (!gExpectedSearchEventQueue.length) {
- gExpectedSearchEventResolver();
- gExpectedSearchEventResolver = null;
- }
- });
-
- // Add the engine without any logos and switch to it.
- let noLogoEngine = yield promiseNewSearchEngine(ENGINE_NO_LOGO);
- let searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = noLogoEngine;
- yield searchEventsPromise;
- yield* checkCurrentEngine(ENGINE_NO_LOGO);
-
- // Add the engine with favicon and switch to it.
- let faviconEngine = yield promiseNewSearchEngine(ENGINE_FAVICON);
- searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = faviconEngine;
- yield searchEventsPromise;
- yield* checkCurrentEngine(ENGINE_FAVICON);
-
- // Add the engine with a 1x-DPI logo and switch to it.
- let logo1xEngine = yield promiseNewSearchEngine(ENGINE_1X_LOGO);
- searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = logo1xEngine;
- yield searchEventsPromise;
- yield* checkCurrentEngine(ENGINE_1X_LOGO);
-
- // Add the engine with a 2x-DPI logo and switch to it.
- let logo2xEngine = yield promiseNewSearchEngine(ENGINE_2X_LOGO);
- searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = logo2xEngine;
- yield searchEventsPromise;
- yield* checkCurrentEngine(ENGINE_2X_LOGO);
-
- // Add the engine with 1x- and 2x-DPI logos and switch to it.
- let logo1x2xEngine = yield promiseNewSearchEngine(ENGINE_1X_2X_LOGO);
- searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = logo1x2xEngine;
- yield searchEventsPromise;
- yield* checkCurrentEngine(ENGINE_1X_2X_LOGO);
-
- // Add the engine that provides search suggestions and switch to it.
- let suggestionEngine = yield promiseNewSearchEngine(ENGINE_SUGGESTIONS);
- searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = suggestionEngine;
- yield searchEventsPromise;
- yield* checkCurrentEngine(ENGINE_SUGGESTIONS);
-
- // Avoid intermittent failures.
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- content.gSearch._contentSearchController.remoteTimeout = 5000;
- });
-
- // Type an X in the search input. This is only a smoke test. See
- // browser_searchSuggestionUI.js for comprehensive content search suggestion
- // UI tests.
- let suggestionsOpenPromise = new Promise(resolve => {
- mm.addMessageListener("test:newtab-suggestions-open", function onResponse(message) {
- mm.removeMessageListener("test:newtab-suggestions-open", onResponse);
- resolve();
- });
- });
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let table = content.document.getElementById("searchSuggestionTable");
-
- let input = content.document.getElementById("newtab-search-text");
- input.focus();
-
- info("Waiting for suggestions table to open");
- let observer = new content.MutationObserver(() => {
- if (input.getAttribute("aria-expanded") == "true") {
- observer.disconnect();
- Assert.ok(!table.hidden, "Search suggestion table unhidden");
- sendAsyncMessage("test:newtab-suggestions-open", {});
- }
- });
- observer.observe(input, {
- attributes: true,
- attributeFilter: ["aria-expanded"],
- });
- });
-
- let suggestionsPromise = promiseSearchEvents(["Suggestions"]);
-
- EventUtils.synthesizeKey("x", {});
-
- // Wait for the search suggestions to become visible and for the Suggestions
- // message.
- yield suggestionsOpenPromise;
- yield suggestionsPromise;
-
- // Empty the search input, causing the suggestions to be hidden.
- EventUtils.synthesizeKey("a", { accelKey: true });
- EventUtils.synthesizeKey("VK_DELETE", {});
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- Assert.ok(content.document.getElementById("searchSuggestionTable").hidden,
- "Search suggestion table hidden");
- });
-
- // Done. Revert the current engine and remove the new engines.
- searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
- Services.search.currentEngine = oldCurrentEngine;
- yield searchEventsPromise;
-
- let events = Array(gNewEngines.length).fill("CurrentState", 0, gNewEngines.length);
- searchEventsPromise = promiseSearchEvents(events);
-
- for (let engine of gNewEngines) {
- Services.search.removeEngine(engine);
- }
- yield searchEventsPromise;
-});
-
-function promiseSearchEvents(events) {
- info("Expecting search events: " + events);
- return new Promise(resolve => {
- gExpectedSearchEventQueue.push(...events);
- gExpectedSearchEventResolver = resolve;
- });
-}
-
-function promiseNewSearchEngine({name: basename, numLogos}) {
- info("Waiting for engine to be added: " + basename);
-
- // Wait for the search events triggered by adding the new engine.
- // engine-added engine-loaded
- let expectedSearchEvents = ["CurrentState", "CurrentState"];
- // engine-changed for each of the logos
- for (let i = 0; i < numLogos; i++) {
- expectedSearchEvents.push("CurrentState");
- }
- let eventPromise = promiseSearchEvents(expectedSearchEvents);
-
- // Wait for addEngine().
- let addEnginePromise = new Promise((resolve, reject) => {
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- gNewEngines.push(engine);
- resolve(engine);
- },
- onError: function (errCode) {
- ok(false, "addEngine failed with error code " + errCode);
- reject();
- },
- });
- });
-
- return Promise.all([addEnginePromise, eventPromise]).then(([newEngine, _]) => {
- return newEngine;
- });
-}
-
-function* checkCurrentEngine(engineInfo)
-{
- let engine = Services.search.currentEngine;
- ok(engine.name.includes(engineInfo.name),
- "Sanity check: current engine: engine.name=" + engine.name +
- " basename=" + engineInfo.name);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, { name: engine.name }, function* (args) {
- Assert.equal(content.gSearch._contentSearchController.defaultEngine.name,
- args.name, "currentEngineName: " + args.name);
- });
-}
diff --git a/browser/base/content/test/newtab/browser_newtab_sponsored_icon_click.js b/browser/base/content/test/newtab/browser_newtab_sponsored_icon_click.js
deleted file mode 100644
index f6bb85d47..000000000
--- a/browser/base/content/test/newtab/browser_newtab_sponsored_icon_click.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* () {
- yield setLinks("0");
- yield* addNewTabPageTab();
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- var EventUtils = {};
- EventUtils.window = {};
- EventUtils.parent = EventUtils.window;
- EventUtils._EU_Ci = Components.interfaces;
-
- Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- let cell = content.gGrid.cells[0];
-
- let site = cell.node.querySelector(".newtab-site");
- site.setAttribute("type", "sponsored");
-
- // test explain text appearing upon a click
- let sponsoredButton = site.querySelector(".newtab-sponsored");
- EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, content);
- let explain = site.querySelector(".sponsored-explain");
- Assert.notEqual(explain, null, "Sponsored explanation shown");
- Assert.ok(explain.querySelector("input").classList.contains("newtab-control-block"),
- "sponsored tiles show blocked image");
- Assert.ok(sponsoredButton.hasAttribute("active"), "Sponsored button has active attribute");
-
- // test dismissing sponsored explain
- EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, content);
- Assert.equal(site.querySelector(".sponsored-explain"), null,
- "Sponsored explanation no longer shown");
- Assert.ok(!sponsoredButton.hasAttribute("active"),
- "Sponsored button does not have active attribute");
-
- // test with enhanced tile
- site.setAttribute("type", "enhanced");
- EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, content);
- explain = site.querySelector(".sponsored-explain");
- Assert.notEqual(explain, null, "Sponsored explanation shown");
- Assert.ok(explain.querySelector("input").classList.contains("newtab-customize"),
- "enhanced tiles show customize image");
- Assert.ok(sponsoredButton.hasAttribute("active"), "Sponsored button has active attribute");
-
- // test dismissing enhanced explain
- EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, content);
- Assert.equal(site.querySelector(".sponsored-explain"), null,
- "Sponsored explanation no longer shown");
- Assert.ok(!sponsoredButton.hasAttribute("active"),
- "Sponsored button does not have active attribute");
- });
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_undo.js b/browser/base/content/test/newtab/browser_newtab_undo.js
deleted file mode 100644
index ba094cb26..000000000
--- a/browser/base/content/test/newtab/browser_newtab_undo.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that the undo dialog works as expected.
- */
-add_task(function* () {
- // remove unpinned sites and undo it
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks("5");
-
- yield* addNewTabPageTab();
- yield* checkGrid("5p,0,1,2,3,4,6,7,8");
-
- yield blockCell(4);
- yield blockCell(4);
- yield* checkGrid("5p,0,1,2,6,7,8");
-
- yield* undo();
- yield* checkGrid("5p,0,1,2,4,6,7,8");
-
- // now remove a pinned site and undo it
- yield blockCell(0);
- yield* checkGrid("0,1,2,4,6,7,8");
-
- yield* undo();
- yield* checkGrid("5p,0,1,2,4,6,7,8");
-
- // remove a site and restore all
- yield blockCell(1);
- yield* checkGrid("5p,1,2,4,6,7,8");
-
- yield* undoAll();
- yield* checkGrid("5p,0,1,2,3,4,6,7,8");
-});
-
-function* undo() {
- let updatedPromise = whenPagesUpdated();
- yield BrowserTestUtils.synthesizeMouseAtCenter("#newtab-undo-button", {}, gBrowser.selectedBrowser);
- yield updatedPromise;
-}
-
-function* undoAll() {
- let updatedPromise = whenPagesUpdated();
- yield BrowserTestUtils.synthesizeMouseAtCenter("#newtab-undo-restore-button", {}, gBrowser.selectedBrowser);
- yield updatedPromise;
-}
diff --git a/browser/base/content/test/newtab/browser_newtab_unpin.js b/browser/base/content/test/newtab/browser_newtab_unpin.js
deleted file mode 100644
index 14751465f..000000000
--- a/browser/base/content/test/newtab/browser_newtab_unpin.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * These tests make sure that when a site gets unpinned it is either moved to
- * its actual place in the grid or removed in case it's not on the grid anymore.
- */
-add_task(function* () {
- // we have a pinned link that didn't change its position since it was pinned.
- // nothing should happen when we unpin it.
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",1");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,1p,2,3,4,5,6,7,8");
-
- yield unpinCell(1);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- // we have a pinned link that is not anymore in the list of the most-visited
- // links. this should disappear, the remaining links adjust their positions
- // and a new link will appear at the end of the grid.
- yield setLinks("0,1,2,3,4,5,6,7,8");
- setPinnedLinks(",99");
-
- yield* addNewTabPageTab();
- yield* checkGrid("0,99p,1,2,3,4,5,6,7");
-
- yield unpinCell(1);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-
- // we have a pinned link that changed its position since it was pinned. it
- // should be moved to its new position after being unpinned.
- yield setLinks("0,1,2,3,4,5,6,7");
- setPinnedLinks(",1,,,,,,,0");
-
- yield* addNewTabPageTab();
- yield* checkGrid("2,1p,3,4,5,6,7,,0p");
-
- yield unpinCell(1);
- yield* checkGrid("1,2,3,4,5,6,7,,0p");
-
- yield unpinCell(8);
- yield* checkGrid("0,1,2,3,4,5,6,7,");
-
- // we have pinned link that changed its position since it was pinned. the
- // link will disappear from the grid because it's now a much lower priority
- yield setLinks("0,1,2,3,4,5,6,7,8,9");
- setPinnedLinks("9");
-
- yield* addNewTabPageTab();
- yield* checkGrid("9p,0,1,2,3,4,5,6,7");
-
- yield unpinCell(0);
- yield* checkGrid("0,1,2,3,4,5,6,7,8");
-});
diff --git a/browser/base/content/test/newtab/browser_newtab_update.js b/browser/base/content/test/newtab/browser_newtab_update.js
deleted file mode 100644
index 6cf089dfd..000000000
--- a/browser/base/content/test/newtab/browser_newtab_update.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * Checks that newtab is updated as its links change.
- */
-add_task(function* () {
- // First, start with an empty page. setLinks will trigger a hidden page
- // update because it calls clearHistory. We need to wait for that update to
- // happen so that the next time we wait for a page update below, we catch the
- // right update and not the one triggered by setLinks.
- let updatedPromise = whenPagesUpdated();
- let setLinksPromise = setLinks([]);
- yield Promise.all([updatedPromise, setLinksPromise]);
-
- // Strategy: Add some visits, open a new page, check the grid, repeat.
- yield fillHistoryAndWaitForPageUpdate([1]);
- yield* addNewTabPageTab();
- yield* checkGrid("1,,,,,,,,");
-
- yield fillHistoryAndWaitForPageUpdate([2]);
- yield* addNewTabPageTab();
- yield* checkGrid("2,1,,,,,,,");
-
- yield fillHistoryAndWaitForPageUpdate([1]);
- yield* addNewTabPageTab();
- yield* checkGrid("1,2,,,,,,,");
-
- yield fillHistoryAndWaitForPageUpdate([2, 3, 4]);
- yield* addNewTabPageTab();
- yield* checkGrid("2,1,3,4,,,,,");
-
- // Make sure these added links have the right type
- let type = yield performOnCell(1, cell => { return cell.site.link.type });
- is(type, "history", "added link is history");
-});
-
-function fillHistoryAndWaitForPageUpdate(links) {
- let updatedPromise = whenPagesUpdated;
- let fillHistoryPromise = fillHistory(links.map(link));
- return Promise.all([updatedPromise, fillHistoryPromise]);
-}
-
-function link(id) {
- return { url: "http://example" + id + ".com/", title: "site#" + id };
-}
diff --git a/browser/base/content/test/newtab/content-reflows.js b/browser/base/content/test/newtab/content-reflows.js
deleted file mode 100644
index f1a53782e..000000000
--- a/browser/base/content/test/newtab/content-reflows.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-(function () {
- "use strict";
-
- const Ci = Components.interfaces;
-
- docShell.addWeakReflowObserver({
- reflow() {
- // Gather information about the current code path.
- let path = (new Error().stack).split("\n").slice(1).join("\n");
- if (path) {
- sendSyncMessage("newtab-reflow", path);
- }
- },
-
- reflowInterruptible() {
- // We're not interested in interruptible reflows.
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
- Ci.nsISupportsWeakReference])
- });
-})();
diff --git a/browser/base/content/test/newtab/head.js b/browser/base/content/test/newtab/head.js
deleted file mode 100644
index d702103a0..000000000
--- a/browser/base/content/test/newtab/head.js
+++ /dev/null
@@ -1,552 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
-const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directory.source";
-
-Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true);
-
-var tmp = {};
-Cu.import("resource://gre/modules/NewTabUtils.jsm", tmp);
-Cu.import("resource:///modules/DirectoryLinksProvider.jsm", tmp);
-Cu.import("resource://testing-common/PlacesTestUtils.jsm", tmp);
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tmp);
-var {NewTabUtils, Sanitizer, DirectoryLinksProvider, PlacesTestUtils} = tmp;
-
-var gWindow = window;
-
-// Default to dummy/empty directory links
-var gDirectorySource = 'data:application/json,{"test":1}';
-var gOrigDirectorySource;
-
-// The tests assume all 3 rows and all 3 columns of sites are shown, but the
-// window may be too small to actually show everything. Resize it if necessary.
-var requiredSize = {};
-requiredSize.innerHeight =
- 40 + 32 + // undo container + bottom margin
- 44 + 32 + // search bar + bottom margin
- (3 * (180 + 32)) + // 3 rows * (tile height + title and bottom margin)
- 100; // breathing room
-requiredSize.innerWidth =
- (3 * (290 + 20)) + // 3 cols * (tile width + side margins)
- 100; // breathing room
-
-var oldSize = {};
-Object.keys(requiredSize).forEach(prop => {
- info([prop, gBrowser.contentWindow[prop], requiredSize[prop]]);
- if (gBrowser.contentWindow[prop] < requiredSize[prop]) {
- oldSize[prop] = gBrowser.contentWindow[prop];
- info("Changing browser " + prop + " from " + oldSize[prop] + " to " +
- requiredSize[prop]);
- gBrowser.contentWindow[prop] = requiredSize[prop];
- }
-});
-
-var screenHeight = {};
-var screenWidth = {};
-Cc["@mozilla.org/gfx/screenmanager;1"].
- getService(Ci.nsIScreenManager).
- primaryScreen.
- GetAvailRectDisplayPix({}, {}, screenWidth, screenHeight);
-screenHeight = screenHeight.value;
-screenWidth = screenWidth.value;
-
-if (screenHeight < gBrowser.contentWindow.outerHeight) {
- info("Warning: Browser outer height is now " +
- gBrowser.contentWindow.outerHeight + ", which is larger than the " +
- "available screen height, " + screenHeight +
- ". That may cause problems.");
-}
-
-if (screenWidth < gBrowser.contentWindow.outerWidth) {
- info("Warning: Browser outer width is now " +
- gBrowser.contentWindow.outerWidth + ", which is larger than the " +
- "available screen width, " + screenWidth +
- ". That may cause problems.");
-}
-
-registerCleanupFunction(function () {
- while (gWindow.gBrowser.tabs.length > 1)
- gWindow.gBrowser.removeTab(gWindow.gBrowser.tabs[1]);
-
- Object.keys(oldSize).forEach(prop => {
- if (oldSize[prop]) {
- gBrowser.contentWindow[prop] = oldSize[prop];
- }
- });
-
- // Stop any update timers to prevent unexpected updates in later tests
- let timer = NewTabUtils.allPages._scheduleUpdateTimeout;
- if (timer) {
- clearTimeout(timer);
- delete NewTabUtils.allPages._scheduleUpdateTimeout;
- }
-
- Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
- Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, gOrigDirectorySource);
-
- return watchLinksChangeOnce();
-});
-
-function pushPrefs(...aPrefs) {
- return new Promise(resolve =>
- SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve));
-}
-
-/**
- * Resolves promise when directory links are downloaded and written to disk
- */
-function watchLinksChangeOnce() {
- return new Promise(resolve => {
- let observer = {
- onManyLinksChanged: () => {
- DirectoryLinksProvider.removeObserver(observer);
- resolve();
- }
- };
- observer.onDownloadFail = observer.onManyLinksChanged;
- DirectoryLinksProvider.addObserver(observer);
- });
-}
-
-add_task(function* setup() {
- registerCleanupFunction(function() {
- return new Promise(resolve => {
- function cleanupAndFinish() {
- PlacesTestUtils.clearHistory().then(() => {
- whenPagesUpdated().then(resolve);
- NewTabUtils.restore();
- });
- }
-
- let callbacks = NewTabUtils.links._populateCallbacks;
- let numCallbacks = callbacks.length;
-
- if (numCallbacks)
- callbacks.splice(0, numCallbacks, cleanupAndFinish);
- else
- cleanupAndFinish();
- });
- });
-
- let promiseReady = Task.spawn(function*() {
- yield watchLinksChangeOnce();
- yield whenPagesUpdated();
- });
-
- // Save the original directory source (which is set globally for tests)
- gOrigDirectorySource = Services.prefs.getCharPref(PREF_NEWTAB_DIRECTORYSOURCE);
- Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, gDirectorySource);
- yield promiseReady;
-});
-
-/** Perform an action on a cell within the newtab page.
- * @param aIndex index of cell
- * @param aFn function to call in child process or tab.
- * @returns result of calling the function.
- */
-function performOnCell(aIndex, aFn) {
- return ContentTask.spawn(gWindow.gBrowser.selectedBrowser,
- { index: aIndex, fn: aFn.toString() }, function* (args) {
- let cell = content.gGrid.cells[args.index];
- return eval(args.fn)(cell);
- });
-}
-
-/**
- * Allows to provide a list of links that is used to construct the grid.
- * @param aLinksPattern the pattern (see below)
- *
- * Example: setLinks("-1,0,1,2,3")
- * Result: [{url: "http://example.com/", title: "site#-1"},
- * {url: "http://example0.com/", title: "site#0"},
- * {url: "http://example1.com/", title: "site#1"},
- * {url: "http://example2.com/", title: "site#2"},
- * {url: "http://example3.com/", title: "site#3"}]
- */
-function setLinks(aLinks) {
- return new Promise(resolve => {
- let links = aLinks;
-
- if (typeof links == "string") {
- links = aLinks.split(/\s*,\s*/).map(function (id) {
- return {url: "http://example" + (id != "-1" ? id : "") + ".com/",
- title: "site#" + id};
- });
- }
-
- // Call populateCache() once to make sure that all link fetching that is
- // currently in progress has ended. We clear the history, fill it with the
- // given entries and call populateCache() now again to make sure the cache
- // has the desired contents.
- NewTabUtils.links.populateCache(function () {
- PlacesTestUtils.clearHistory().then(() => {
- fillHistory(links).then(() => {
- NewTabUtils.links.populateCache(function () {
- NewTabUtils.allPages.update();
- resolve();
- }, true);
- });
- });
- });
- });
-}
-
-function fillHistory(aLinks) {
- return new Promise(resolve => {
- let numLinks = aLinks.length;
- if (!numLinks) {
- executeSoon(resolve);
- return;
- }
-
- let transitionLink = Ci.nsINavHistoryService.TRANSITION_LINK;
-
- // Important: To avoid test failures due to clock jitter on Windows XP, call
- // Date.now() once here, not each time through the loop.
- let now = Date.now() * 1000;
-
- for (let i = 0; i < aLinks.length; i++) {
- let link = aLinks[i];
- let place = {
- uri: makeURI(link.url),
- title: link.title,
- // Links are secondarily sorted by visit date descending, so decrease the
- // visit date as we progress through the array so that links appear in the
- // grid in the order they're present in the array.
- visits: [{visitDate: now - i, transitionType: transitionLink}]
- };
-
- PlacesUtils.asyncHistory.updatePlaces(place, {
- handleError: () => ok(false, "couldn't add visit to history"),
- handleResult: function () {},
- handleCompletion: function () {
- if (--numLinks == 0) {
- resolve();
- }
- }
- });
- }
- });
-}
-
-/**
- * Allows to specify the list of pinned links (that have a fixed position in
- * the grid.
- * @param aLinksPattern the pattern (see below)
- *
- * Example: setPinnedLinks("3,,1")
- * Result: 'http://example3.com/' is pinned in the first cell. 'http://example1.com/' is
- * pinned in the third cell.
- */
-function setPinnedLinks(aLinks) {
- let links = aLinks;
-
- if (typeof links == "string") {
- links = aLinks.split(/\s*,\s*/).map(function (id) {
- if (id)
- return {url: "http://example" + (id != "-1" ? id : "") + ".com/",
- title: "site#" + id,
- type: "history"};
- return undefined;
- });
- }
-
- let string = Cc["@mozilla.org/supports-string;1"]
- .createInstance(Ci.nsISupportsString);
- string.data = JSON.stringify(links);
- Services.prefs.setComplexValue("browser.newtabpage.pinned",
- Ci.nsISupportsString, string);
-
- NewTabUtils.pinnedLinks.resetCache();
- NewTabUtils.allPages.update();
-}
-
-/**
- * Restore the grid state.
- */
-function restore() {
- return new Promise(resolve => {
- whenPagesUpdated().then(resolve);
- NewTabUtils.restore();
- });
-}
-
-/**
- * Wait until a given condition becomes true.
- */
-function waitForCondition(aConditionFn, aMaxTries=50, aCheckInterval=100) {
- return new Promise((resolve, reject) => {
- let tries = 0;
-
- function tryNow() {
- tries++;
-
- if (aConditionFn()) {
- resolve();
- } else if (tries < aMaxTries) {
- tryAgain();
- } else {
- reject("Condition timed out: " + aConditionFn.toSource());
- }
- }
-
- function tryAgain() {
- setTimeout(tryNow, aCheckInterval);
- }
-
- tryAgain();
- });
-}
-
-/**
- * Creates a new tab containing 'about:newtab'.
- */
-function* addNewTabPageTab() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gWindow.gBrowser, "about:newtab", false);
- let browser = tab.linkedBrowser;
-
- // Wait for the document to become visible in case it was preloaded.
- yield waitForCondition(() => !browser.contentDocument.hidden)
-
- yield new Promise(resolve => {
- if (NewTabUtils.allPages.enabled) {
- // Continue when the link cache has been populated.
- NewTabUtils.links.populateCache(function () {
- whenSearchInitDone().then(resolve);
- });
- } else {
- resolve();
- }
- });
-
- return tab;
-}
-
-/**
- * Compares the current grid arrangement with the given pattern.
- * @param the pattern (see below)
- *
- * Example: checkGrid("3p,2,,1p")
- * Result: We expect the first cell to contain the pinned site 'http://example3.com/'.
- * The second cell contains 'http://example2.com/'. The third cell is empty.
- * The fourth cell contains the pinned site 'http://example4.com/'.
- */
-function* checkGrid(pattern) {
- let length = pattern.split(",").length;
-
- yield ContentTask.spawn(gWindow.gBrowser.selectedBrowser,
- { length, pattern }, function* (args) {
- let grid = content.wrappedJSObject.gGrid;
-
- let sites = grid.sites.slice(0, args.length);
- let foundPattern = sites.map(function (aSite) {
- if (!aSite)
- return "";
-
- let pinned = aSite.isPinned();
- let hasPinnedAttr = aSite.node.hasAttribute("pinned");
-
- if (pinned != hasPinnedAttr)
- ok(false, "invalid state (site.isPinned() != site[pinned])");
-
- return aSite.url.replace(/^http:\/\/example(\d+)\.com\/$/, "$1") + (pinned ? "p" : "");
- });
-
- Assert.equal(foundPattern, args.pattern, "grid status = " + args.pattern);
- });
-}
-
-/**
- * Blocks a site from the grid.
- * @param aIndex The cell index.
- */
-function blockCell(aIndex) {
- return new Promise(resolve => {
- whenPagesUpdated().then(resolve);
- performOnCell(aIndex, cell => {
- return cell.site.block();
- });
- });
-}
-
-/**
- * Pins a site on a given position.
- * @param aIndex The cell index.
- * @param aPinIndex The index the defines where the site should be pinned.
- */
-function pinCell(aIndex) {
- performOnCell(aIndex, cell => {
- cell.site.pin();
- });
-}
-
-/**
- * Unpins the given cell's site.
- * @param aIndex The cell index.
- */
-function unpinCell(aIndex) {
- return new Promise(resolve => {
- whenPagesUpdated().then(resolve);
- performOnCell(aIndex, cell => {
- cell.site.unpin();
- });
- });
-}
-
-/**
- * Simulates a drag and drop operation. Instead of rearranging a site that is
- * is already contained in the newtab grid, this is used to simulate dragging
- * an external link onto the grid e.g. the text from the URL bar.
- * @param aDestIndex The cell index of the drop target.
- */
-function* simulateExternalDrop(aDestIndex) {
- let pagesUpdatedPromise = whenPagesUpdated();
-
- yield ContentTask.spawn(gWindow.gBrowser.selectedBrowser, aDestIndex, function*(dropIndex) {
- return new Promise(resolve => {
- const url = "data:text/html;charset=utf-8," +
- "<a id='link' href='http://example99.com/'>link</a>";
-
- let doc = content.document;
- let iframe = doc.createElement("iframe");
-
- function iframeLoaded() {
- let dataTransfer = new iframe.contentWindow.DataTransfer("dragstart", false);
- dataTransfer.mozSetDataAt("text/x-moz-url", "http://example99.com/", 0);
-
- let event = content.document.createEvent("DragEvent");
- event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
- false, false, false, false, 0, null, dataTransfer);
-
- let target = content.gGrid.cells[dropIndex].node;
- target.dispatchEvent(event);
-
- iframe.remove();
-
- resolve();
- }
-
- iframe.addEventListener("load", function onLoad() {
- iframe.removeEventListener("load", onLoad);
- content.setTimeout(iframeLoaded, 0);
- });
-
- 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
- let margin = doc.getElementById("newtab-search-container");
- margin.appendChild(iframe);
- });
- });
-
- yield pagesUpdatedPromise;
-}
-
-/**
- * Resumes testing when all pages have been updated.
- */
-function whenPagesUpdated() {
- return new Promise(resolve => {
- let page = {
- observe: _ => _,
-
- update() {
- NewTabUtils.allPages.unregister(this);
- executeSoon(resolve);
- }
- };
-
- NewTabUtils.allPages.register(page);
- registerCleanupFunction(function () {
- NewTabUtils.allPages.unregister(page);
- });
- });
-}
-
-/**
- * Waits for the response to the page's initial search state request.
- */
-function whenSearchInitDone() {
- return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, {}, function*() {
- return new Promise(resolve => {
- if (content.gSearch) {
- let searchController = content.gSearch._contentSearchController;
- if (searchController.defaultEngine) {
- resolve();
- return;
- }
- }
-
- let eventName = "ContentSearchService";
- content.addEventListener(eventName, function onEvent(event) {
- if (event.detail.type == "State") {
- content.removeEventListener(eventName, onEvent);
- let resolver = function() {
- // Wait for the search controller to receive the event, then resolve.
- if (content.gSearch._contentSearchController.defaultEngine) {
- resolve();
- return;
- }
- }
- content.setTimeout(resolver, 0);
- }
- });
- });
- });
-}
-
-/**
- * Changes the newtab customization option and waits for the panel to open and close
- *
- * @param {string} aTheme
- * Can be any of("blank"|"classic"|"enhanced")
- */
-function customizeNewTabPage(aTheme) {
- return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, aTheme, function*(aTheme) {
-
- let document = content.document;
- let panel = document.getElementById("newtab-customize-panel");
- let customizeButton = document.getElementById("newtab-customize-button");
-
- function panelOpened(opened) {
- return new Promise( (resolve) => {
- let options = {attributes: true, oldValue: true};
- let observer = new content.MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- document.getElementById("newtab-customize-" + aTheme).click();
- observer.disconnect();
- if (opened == panel.hasAttribute("open")) {
- resolve();
- }
- });
- });
- observer.observe(panel, options);
- });
- }
-
- let opened = panelOpened(true);
- customizeButton.click();
- yield opened;
-
- let closed = panelOpened(false);
- customizeButton.click();
- yield closed;
- });
-}
-
-/**
- * Reports presence of a scrollbar
- */
-function hasScrollbar() {
- return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, {}, function* () {
- let docElement = content.document.documentElement;
- return docElement.scrollHeight > docElement.clientHeight;
- });
-}
diff --git a/browser/base/content/test/newtab/searchEngine1x2xLogo.xml b/browser/base/content/test/newtab/searchEngine1x2xLogo.xml
deleted file mode 100644
index c8b6749b3..000000000
--- a/browser/base/content/test/newtab/searchEngine1x2xLogo.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_newtab_search searchEngine1x2xLogo.xml</ShortName>
-<Url type="text/html" method="GET" template="http://browser-newtab-search.com/1x2xlogo" rel="searchform"/>
-<!-- #00FF00 -->
-<Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADIGr0+8uwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVRYw+3PAREAAAQEsKd/Z3I4W4NVJtd14uDg4ODg4ODg4ODg4ODg4ODg8Pqw7M0BM+n9I0oAAAAASUVORK5CYII=</Image>
-<!-- #00FFFF -->
-<Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMoaoKANQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAYklEQVR42u3RQQ0AAAjEMMC/58MECZ9OwtqVlL4bCzAIAwZhwCAMGIQBgzBgEAYMwoBBGDAIAwZhwCAMGIQBgzBgEAYMwoBBGIQBgzBgEAYMwoBBGDAIAwZhwCAMGIQBg+5ar7sCZiri9VUAAAAASUVORK5CYII=</Image>
-</SearchPlugin>
diff --git a/browser/base/content/test/newtab/searchEngine1xLogo.xml b/browser/base/content/test/newtab/searchEngine1xLogo.xml
deleted file mode 100644
index 19ac03f48..000000000
--- a/browser/base/content/test/newtab/searchEngine1xLogo.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_newtab_search searchEngine1xLogo.xml</ShortName>
-<Url type="text/html" method="GET" template="http://browser-newtab-search.com/1xlogo" rel="searchform"/>
-<!-- #FF0000 -->
-<Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADEwS9h64QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVRYw+3PAREAAAQEsKd/Z3I4W4PV5LyOg4ODg4ODg4ODg4ODg4ODg4PD78MC7cwBM02qquMAAAAASUVORK5CYII=</Image>
-</SearchPlugin>
diff --git a/browser/base/content/test/newtab/searchEngine2xLogo.xml b/browser/base/content/test/newtab/searchEngine2xLogo.xml
deleted file mode 100644
index 941bf040d..000000000
--- a/browser/base/content/test/newtab/searchEngine2xLogo.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_newtab_search searchEngine2xLogo.xml</ShortName>
-<Url type="text/html" method="GET" template="http://browser-newtab-search.com/2xlogo" rel="searchform"/>
-<!-- #0000FF -->
-<Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMURe38sgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAYklEQVR42u3RQQ0AAAjEsAP/nsEECZ9OwlrJRN+1BRiEAYMwYBAGDMKAQRgwCAMGYcAgDBiEAYMwYBAGDMKAQRgwCAMGYcAgDMKAQRgwCAMGYcAgDBiEAYMwYBAGDMKAQXctkIQBZ/1YP3YAAAAASUVORK5CYII=</Image>
-</SearchPlugin>
diff --git a/browser/base/content/test/newtab/searchEngineFavicon.xml b/browser/base/content/test/newtab/searchEngineFavicon.xml
deleted file mode 100644
index 6f2a970f5..000000000
--- a/browser/base/content/test/newtab/searchEngineFavicon.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_newtab_search searchEngineFavicon.xml</ShortName>
-<Url type="text/html" method="GET" template="http://browser-newtab-search.com/1xlogo" rel="searchform"/>
-<Image width="16" height="16">data:application/ico;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsAAAAAAAAAAAAA/wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEwsAABMLAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-</SearchPlugin>
diff --git a/browser/base/content/test/newtab/searchEngineNoLogo.xml b/browser/base/content/test/newtab/searchEngineNoLogo.xml
deleted file mode 100644
index bbff6cf8f..000000000
--- a/browser/base/content/test/newtab/searchEngineNoLogo.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_newtab_search searchEngineNoLogo.xml</ShortName>
-<Url type="text/html" method="GET" template="http://browser-newtab-search.com/nologo" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/base/content/test/plugins/.eslintrc.js b/browser/base/content/test/plugins/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/plugins/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/plugins/blockNoPlugins.xml b/browser/base/content/test/plugins/blockNoPlugins.xml
deleted file mode 100644
index e4e191b37..000000000
--- a/browser/base/content/test/plugins/blockNoPlugins.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310001">
- <emItems>
- </emItems>
- <pluginItems>
- </pluginItems>
-</blocklist>
diff --git a/browser/base/content/test/plugins/blockPluginHard.xml b/browser/base/content/test/plugins/blockPluginHard.xml
deleted file mode 100644
index 24eb5bc6f..000000000
--- a/browser/base/content/test/plugins/blockPluginHard.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
- <emItems>
- </emItems>
- <pluginItems>
- <pluginItem blockID="p9999">
- <match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" />
- <versionRange severity="2"></versionRange>
- </pluginItem>
- </pluginItems>
-</blocklist>
diff --git a/browser/base/content/test/plugins/blockPluginInfoURL.xml b/browser/base/content/test/plugins/blockPluginInfoURL.xml
deleted file mode 100644
index c16808896..000000000
--- a/browser/base/content/test/plugins/blockPluginInfoURL.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
- <emItems>
- </emItems>
- <pluginItems>
- <pluginItem blockID="p9999">
- <match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" />
- <versionRange severity="2"></versionRange>
- <infoURL>http://test.url.com/</infoURL>
- </pluginItem>
- </pluginItems>
-</blocklist>
diff --git a/browser/base/content/test/plugins/blockPluginVulnerableNoUpdate.xml b/browser/base/content/test/plugins/blockPluginVulnerableNoUpdate.xml
deleted file mode 100644
index bf8545afe..000000000
--- a/browser/base/content/test/plugins/blockPluginVulnerableNoUpdate.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
- <emItems>
- </emItems>
- <pluginItems>
- <pluginItem blockID="p9999">
- <match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" />
- <versionRange severity="0" vulnerabilitystatus="2"></versionRange>
- </pluginItem>
- </pluginItems>
-</blocklist>
diff --git a/browser/base/content/test/plugins/blockPluginVulnerableUpdatable.xml b/browser/base/content/test/plugins/blockPluginVulnerableUpdatable.xml
deleted file mode 100644
index 5545162b1..000000000
--- a/browser/base/content/test/plugins/blockPluginVulnerableUpdatable.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
- <emItems>
- </emItems>
- <pluginItems>
- <pluginItem blockID="p9999">
- <match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" />
- <versionRange severity="0" vulnerabilitystatus="1"></versionRange>
- </pluginItem>
- </pluginItems>
-</blocklist>
diff --git a/browser/base/content/test/plugins/blocklist_proxy.js b/browser/base/content/test/plugins/blocklist_proxy.js
deleted file mode 100644
index 1a4ed4726..000000000
--- a/browser/base/content/test/plugins/blocklist_proxy.js
+++ /dev/null
@@ -1,78 +0,0 @@
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-var Cm = Components.manager;
-
-const kBlocklistServiceUUID = "{66354bc9-7ed1-4692-ae1d-8da97d6b205e}";
-const kBlocklistServiceContractID = "@mozilla.org/extensions/blocklist;1";
-const kBlocklistServiceFactory = Cm.getClassObject(Cc[kBlocklistServiceContractID], Ci.nsIFactory);
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-/*
- * A lightweight blocklist proxy for the testing purposes.
- */
-var BlocklistProxy = {
- _uuid: null,
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
- Ci.nsIBlocklistService,
- Ci.nsITimerCallback]),
-
- init: function() {
- if (!this._uuid) {
- this._uuid =
- Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator)
- .generateUUID();
- Cm.nsIComponentRegistrar.registerFactory(this._uuid, "",
- "@mozilla.org/extensions/blocklist;1",
- this);
- }
- },
-
- uninit: function() {
- if (this._uuid) {
- Cm.nsIComponentRegistrar.unregisterFactory(this._uuid, this);
- Cm.nsIComponentRegistrar.registerFactory(Components.ID(kBlocklistServiceUUID),
- "Blocklist Service",
- "@mozilla.org/extensions/blocklist;1",
- kBlocklistServiceFactory);
- this._uuid = null;
- }
- },
-
- notify: function (aTimer) {
- },
-
- observe: function (aSubject, aTopic, aData) {
- },
-
- isAddonBlocklisted: function (aAddon, aAppVersion, aToolkitVersion) {
- return false;
- },
-
- getAddonBlocklistState: function (aAddon, aAppVersion, aToolkitVersion) {
- return 0; // STATE_NOT_BLOCKED
- },
-
- getPluginBlocklistState: function (aPluginTag, aAppVersion, aToolkitVersion) {
- return 0; // STATE_NOT_BLOCKED
- },
-
- getAddonBlocklistURL: function (aAddon, aAppVersion, aToolkitVersion) {
- return "";
- },
-
- getPluginBlocklistURL: function (aPluginTag) {
- return "";
- },
-
- getPluginInfoURL: function (aPluginTag) {
- return "";
- },
-}
-
-BlocklistProxy.init();
-addEventListener("unload", () => {
- BlocklistProxy.uninit();
-});
diff --git a/browser/base/content/test/plugins/browser.ini b/browser/base/content/test/plugins/browser.ini
deleted file mode 100644
index cfc1f769c..000000000
--- a/browser/base/content/test/plugins/browser.ini
+++ /dev/null
@@ -1,78 +0,0 @@
-[DEFAULT]
-support-files =
- blocklist_proxy.js
- blockNoPlugins.xml
- blockPluginHard.xml
- blockPluginInfoURL.xml
- blockPluginVulnerableNoUpdate.xml
- blockPluginVulnerableUpdatable.xml
- browser_clearplugindata.html
- browser_clearplugindata_noage.html
- head.js
- plugin_add_dynamically.html
- plugin_alternate_content.html
- plugin_big.html
- plugin_both.html
- plugin_both2.html
- plugin_bug744745.html
- plugin_bug749455.html
- plugin_bug787619.html
- plugin_bug797677.html
- plugin_bug820497.html
- plugin_clickToPlayAllow.html
- plugin_clickToPlayDeny.html
- plugin_data_url.html
- plugin_hidden_to_visible.html
- plugin_iframe.html
- plugin_outsideScrollArea.html
- plugin_overlayed.html
- plugin_positioned.html
- plugin_small.html
- plugin_small_2.html
- plugin_syncRemoved.html
- plugin_test.html
- plugin_test2.html
- plugin_test3.html
- plugin_two_types.html
- plugin_unknown.html
- plugin_crashCommentAndURL.html
- plugin_zoom.html
-
-[browser_bug743421.js]
-[browser_bug744745.js]
-[browser_bug787619.js]
-[browser_bug797677.js]
-[browser_bug812562.js]
-[browser_bug818118.js]
-[browser_bug820497.js]
-[browser_clearplugindata.js]
-[browser_CTP_context_menu.js]
-skip-if = toolkit == "gtk2" || toolkit == "gtk3" # fails intermittently on Linux (bug 909342)
-[browser_CTP_crashreporting.js]
-skip-if = !crashreporter
-[browser_CTP_data_urls.js]
-[browser_CTP_drag_drop.js]
-[browser_CTP_hide_overlay.js]
-[browser_CTP_iframe.js]
-[browser_CTP_multi_allow.js]
-[browser_CTP_nonplugins.js]
-[browser_CTP_notificationBar.js]
-[browser_CTP_outsideScrollArea.js]
-[browser_CTP_remove_navigate.js]
-[browser_CTP_resize.js]
-[browser_CTP_zoom.js]
-[browser_blocking.js]
-[browser_plugins_added_dynamically.js]
-[browser_pluginnotification.js]
-[browser_plugin_reloading.js]
-[browser_blocklist_content.js]
-skip-if = !e10s
-[browser_globalplugin_crashinfobar.js]
-skip-if = !crashreporter
-[browser_pluginCrashCommentAndURL.js]
-skip-if = !crashreporter
-[browser_pageInfo_plugins.js]
-[browser_pluginCrashReportNonDeterminism.js]
-skip-if = !crashreporter || os == 'linux' # Bug 1152811
-[browser_private_clicktoplay.js]
-
diff --git a/browser/base/content/test/plugins/browser_CTP_context_menu.js b/browser/base/content/test/plugins/browser_CTP_context_menu.js
deleted file mode 100644
index 03f3e18ef..000000000
--- a/browser/base/content/test/plugins/browser_CTP_context_menu.js
+++ /dev/null
@@ -1,69 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- });
-});
-
-// Test that the activate action in content menus for CTP plugins works
-add_task(function* () {
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- let bindingPromise = waitForEvent(gBrowser.selectedBrowser, "PluginBindingAttached", null, true, true);
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
- yield bindingPromise;
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(popupNotification, "Test 1, Should have a click-to-play notification");
-
- // check plugin state
- let pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser);
- ok(!pluginInfo.activated, "plugin should not be activated");
-
- // Display a context menu on the test plugin so we can test
- // activation menu options.
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("contextmenu", left, top, 2, 1, 0);
- });
-
- popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(popupNotification, "Should have a click-to-play notification");
- ok(popupNotification.dismissed, "notification should be dismissed");
-
- // fixes a occasional test timeout on win7 opt
- yield promiseForCondition(() => document.getElementById("context-ctp-play"));
-
- let actMenuItem = document.getElementById("context-ctp-play");
- ok(actMenuItem, "Should have a context menu entry for activating the plugin");
-
- // Activate the plugin via the context menu
- EventUtils.synthesizeMouseAtCenter(actMenuItem, {});
-
- yield promiseForCondition(() => !PopupNotifications.panel.dismissed && PopupNotifications.panel.firstChild);
-
- // Activate the plugin
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser);
- ok(pluginInfo.activated, "plugin should not be activated");
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_crashreporting.js b/browser/base/content/test/plugins/browser_CTP_crashreporting.js
deleted file mode 100644
index bb52d5704..000000000
--- a/browser/base/content/test/plugins/browser_CTP_crashreporting.js
+++ /dev/null
@@ -1,233 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
-const PLUGIN_PAGE = gTestRoot + "plugin_big.html";
-const PLUGIN_SMALL_PAGE = gTestRoot + "plugin_small.html";
-
-/**
- * Takes an nsIPropertyBag and converts it into a JavaScript Object. It
- * will also convert any nsIPropertyBag's within the nsIPropertyBag
- * recursively.
- *
- * @param aBag
- * The nsIPropertyBag to convert.
- * @return Object
- * Keyed on the names of the nsIProperty's within the nsIPropertyBag,
- * and mapping to their values.
- */
-function convertPropertyBag(aBag) {
- let result = {};
- let enumerator = aBag.enumerator;
- while (enumerator.hasMoreElements()) {
- let { name, value } = enumerator.getNext().QueryInterface(Ci.nsIProperty);
- if (value instanceof Ci.nsIPropertyBag) {
- value = convertPropertyBag(value);
- }
- result[name] = value;
- }
- return result;
-}
-
-add_task(function* setup() {
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
- // crash reports. This test needs them enabled. The test also needs a mock
- // report server, and fortunately one is already set up by toolkit/
- // crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
- // which CrashSubmit.jsm uses as a server override.
- let env = Cc["@mozilla.org/process/environment;1"].
- getService(Components.interfaces.nsIEnvironment);
- let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
- let serverURL = env.get("MOZ_CRASHREPORTER_URL");
- env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
- env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- registerCleanupFunction(function cleanUp() {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
- env.set("MOZ_CRASHREPORTER_URL", serverURL);
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- window.focus();
- });
-});
-
-/**
- * Test that plugin crash submissions still work properly after
- * click-to-play activation.
- */
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PLUGIN_PAGE,
- }, function* (browser) {
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(browser);
-
- let pluginInfo = yield promiseForPluginInfo("test", browser);
- ok(!pluginInfo.activated, "Plugin should not be activated");
-
- // Simulate clicking the "Allow Always" button.
- let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
- yield promiseForNotificationShown(notification, browser);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // Prepare a crash report topic observer that only returns when
- // the crash report has been successfully sent.
- let crashReportChecker = (subject, data) => {
- return (data == "success");
- };
- let crashReportPromise = TestUtils.topicObserved("crash-report-status",
- crashReportChecker);
-
- yield ContentTask.spawn(browser, null, function*() {
- let plugin = content.document.getElementById("test");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-
- yield ContentTaskUtils.waitForCondition(() => {
- return plugin.activated;
- }, "Waited too long for plugin to activate.");
-
- try {
- Components.utils.waiveXrays(plugin).crash();
- } catch (e) {
- }
-
- let doc = plugin.ownerDocument;
-
- let getUI = (anonid) => {
- return doc.getAnonymousElementByAttribute(plugin, "anonid", anonid);
- };
-
- // Now wait until the plugin crash report UI shows itself, which is
- // asynchronous.
- let statusDiv;
-
- yield ContentTaskUtils.waitForCondition(() => {
- statusDiv = getUI("submitStatus");
- return statusDiv.getAttribute("status") == "please";
- }, "Waited too long for plugin to show crash report UI");
-
- // Make sure the UI matches our expectations...
- let style = content.getComputedStyle(getUI("pleaseSubmit"));
- if (style.display != "block") {
- throw new Error(`Submission UI visibility is not correct. ` +
- `Expected block style, got ${style.display}.`);
- }
-
- // Fill the crash report in with some test values that we'll test for in
- // the parent.
- getUI("submitComment").value = "a test comment";
- let optIn = getUI("submitURLOptIn");
- if (!optIn.checked) {
- throw new Error("URL opt-in should default to true.");
- }
-
- // Submit the report.
- optIn.click();
- getUI("submitButton").click();
-
- // And wait for the parent to say that the crash report was submitted
- // successfully.
- yield ContentTaskUtils.waitForCondition(() => {
- return statusDiv.getAttribute("status") == "success";
- }, "Timed out waiting for plugin binding to be in success state");
- });
-
- let [subject, ] = yield crashReportPromise;
-
- ok(subject instanceof Ci.nsIPropertyBag,
- "The crash report subject should be an nsIPropertyBag.");
-
- let crashData = convertPropertyBag(subject);
- ok(crashData.serverCrashID, "Should have a serverCrashID set.");
-
- // Remove the submitted report file after ensuring it exists.
- let file = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(Services.crashmanager._submittedDumpsDir);
- file.append(crashData.serverCrashID + ".txt");
- ok(file.exists(), "Submitted report file should exist");
- file.remove(false);
-
- ok(crashData.extra, "Extra data should exist");
- is(crashData.extra.PluginUserComment, "a test comment",
- "Comment in extra data should match comment in textbox");
-
- is(crashData.extra.PluginContentURL, undefined,
- "URL should be absent from extra data when opt-in not checked");
- });
-});
-
-/**
- * Test that plugin crash submissions still work properly after
- * click-to-play with the notification bar.
- */
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PLUGIN_SMALL_PAGE,
- }, function* (browser) {
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(browser);
-
- let pluginInfo = yield promiseForPluginInfo("test", browser);
- ok(pluginInfo.activated, "Plugin should be activated from previous test");
-
- // Prepare a crash report topic observer that only returns when
- // the crash report has been successfully sent.
- let crashReportChecker = (subject, data) => {
- return (data == "success");
- };
- let crashReportPromise = TestUtils.topicObserved("crash-report-status",
- crashReportChecker);
-
- yield ContentTask.spawn(browser, null, function*() {
- let plugin = content.document.getElementById("test");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-
- yield ContentTaskUtils.waitForCondition(() => {
- return plugin.activated;
- }, "Waited too long for plugin to activate.");
-
- try {
- Components.utils.waiveXrays(plugin).crash();
- } catch (e) {}
- });
-
- // Wait for the notification bar to be displayed.
- let notification = yield waitForNotificationBar("plugin-crashed", browser);
-
- // Then click the button to submit the crash report.
- let buttons = notification.querySelectorAll(".notification-button");
- is(buttons.length, 2, "Should have two buttons.");
-
- // The "Submit Crash Report" button should be the second one.
- let submitButton = buttons[1];
- submitButton.click();
-
- let [subject, ] = yield crashReportPromise;
-
- ok(subject instanceof Ci.nsIPropertyBag,
- "The crash report subject should be an nsIPropertyBag.");
-
- let crashData = convertPropertyBag(subject);
- ok(crashData.serverCrashID, "Should have a serverCrashID set.");
-
- // Remove the submitted report file after ensuring it exists.
- let file = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(Services.crashmanager._submittedDumpsDir);
- file.append(crashData.serverCrashID + ".txt");
- ok(file.exists(), "Submitted report file should exist");
- file.remove(false);
-
- is(crashData.extra.PluginContentURL, undefined,
- "URL should be absent from extra data when opt-in not checked");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_data_urls.js b/browser/base/content/test/plugins/browser_CTP_data_urls.js
deleted file mode 100644
index 0f4747b1e..000000000
--- a/browser/base/content/test/plugins/browser_CTP_data_urls.js
+++ /dev/null
@@ -1,255 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-});
-
-// Test that the click-to-play doorhanger still works when navigating to data URLs
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_data_url.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "Test 1a, Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 1a, plugin should not be activated");
-
- let loadPromise = promiseTabLoadEvent(gBrowser.selectedTab);
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- // navigate forward to a page with 'test' in it
- content.document.getElementById("data-link-1").click();
- });
- yield loadPromise;
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "Test 1b, Should have a click-to-play notification");
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 1b, plugin should not be activated");
-
- let promise = promisePopupNotification("click-to-play-plugins");
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
- yield promise;
-
- // Simulate clicking the "Allow Always" button.
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
- PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 1b, plugin should be activated");
-});
-
-// Test that the click-to-play notification doesn't break when navigating
-// to data URLs with multiple plugins.
-add_task(function* () {
- // We click activated above
- clearAllPluginPermissions();
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_data_url.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 2a, Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 2a, plugin should not be activated");
-
- let loadPromise = promiseTabLoadEvent(gBrowser.selectedTab);
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- // navigate forward to a page with 'test1' & 'test2' in it
- content.document.getElementById("data-link-2").click();
- });
- yield loadPromise;
-
- // Work around for delayed PluginBindingAttached
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- content.document.getElementById("test1").clientTop;
- content.document.getElementById("test2").clientTop;
- });
-
- pluginInfo = yield promiseForPluginInfo("test1");
- ok(!pluginInfo.activated, "Test 2a, test1 should not be activated");
- pluginInfo = yield promiseForPluginInfo("test2");
- ok(!pluginInfo.activated, "Test 2a, test2 should not be activated");
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 2b, Should have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- // Simulate choosing "Allow now" for the test plugin
- is(notification.options.pluginData.size, 2, "Test 2b, Should have two types of plugin in the notification");
-
- let centerAction = null;
- for (let action of notification.options.pluginData.values()) {
- if (action.pluginName == "Test") {
- centerAction = action;
- break;
- }
- }
- ok(centerAction, "Test 2b, found center action for the Test plugin");
-
- let centerItem = null;
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- is(item.value, "block", "Test 2b, all plugins should start out blocked");
- if (item.action == centerAction) {
- centerItem = item;
- break;
- }
- }
- ok(centerItem, "Test 2b, found center item for the Test plugin");
-
- // "click" the button to activate the Test plugin
- centerItem.value = "allownow";
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("test1");
- ok(pluginInfo.activated, "Test 2b, plugin should be activated");
-});
-
-add_task(function* () {
- // We click activated above
- clearAllPluginPermissions();
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_data_url.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-});
-
-// Test that when navigating to a data url, the plugin permission is inherited
-add_task(function* () {
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 3a, Should have a click-to-play notification");
-
- // check plugin state
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 3a, plugin should not be activated");
-
- let promise = promisePopupNotification("click-to-play-plugins");
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
- yield promise;
-
- // Simulate clicking the "Allow Always" button.
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
- PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 3a, plugin should be activated");
-
- let loadPromise = promiseTabLoadEvent(gBrowser.selectedTab);
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- // navigate forward to a page with 'test' in it
- content.document.getElementById("data-link-1").click();
- });
- yield loadPromise;
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 3b, plugin should be activated");
-
- clearAllPluginPermissions();
-});
-
-// Test that the click-to-play doorhanger still works
-// when directly navigating to data URLs.
-// Fails, bug XXX. Plugins plus a data url don't fire a load event.
-/*
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab,
- "data:text/html,Hi!<embed id='test' style='width:200px; height:200px' type='application/x-test'/>");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 4a, Should have a click-to-play notification");
-
- // check plugin state
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 4a, plugin should not be activated");
-
- let promise = promisePopupNotification("click-to-play-plugins");
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
- yield promise;
-
- // Simulate clicking the "Allow Always" button.
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
- PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 4a, plugin should be activated");
-});
-*/
diff --git a/browser/base/content/test/plugins/browser_CTP_drag_drop.js b/browser/base/content/test/plugins/browser_CTP_drag_drop.js
deleted file mode 100644
index 7c9858e27..000000000
--- a/browser/base/content/test/plugins/browser_CTP_drag_drop.js
+++ /dev/null
@@ -1,96 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gNewWindow = null;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gNewWindow.close();
- gNewWindow = null;
- window.focus();
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-});
-
-add_task(function* () {
- gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
-
- // XXX technically can't load fire before we get this call???
- yield waitForEvent(gNewWindow, "load", null, true);
-
- yield promisePopupNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser);
-
- ok(PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should have a click-to-play notification in the tab in the new window");
- ok(!PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should not have a click-to-play notification in the old window now");
-});
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, gNewWindow.gBrowser.selectedTab);
-
- yield promisePopupNotification("click-to-play-plugins", gBrowser.selectedBrowser);
-
- ok(PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should have a click-to-play notification in the initial tab again");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-});
-
-add_task(function* () {
- yield promisePopupNotification("click-to-play-plugins");
-
- gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
-
- yield promiseWaitForFocus(gNewWindow);
-
- yield promisePopupNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser);
-});
-
-add_task(function* () {
- ok(PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should have a click-to-play notification in the tab in the new window");
- ok(!PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should not have a click-to-play notification in the old window now");
-
- let pluginInfo = yield promiseForPluginInfo("test", gNewWindow.gBrowser.selectedBrowser);
- ok(!pluginInfo.activated, "plugin should not be activated");
-
- yield ContentTask.spawn(gNewWindow.gBrowser.selectedBrowser, {}, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
-
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed && gNewWindow.PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
-});
-
-add_task(function* () {
- // Click the activate button on doorhanger to make sure it works
- gNewWindow.PopupNotifications.panel.firstChild._primaryButton.click();
-
- let pluginInfo = yield promiseForPluginInfo("test", gNewWindow.gBrowser.selectedBrowser);
- ok(pluginInfo.activated, "plugin should be activated");
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_hide_overlay.js b/browser/base/content/test/plugins/browser_CTP_hide_overlay.js
deleted file mode 100644
index 5fab7f6ed..000000000
--- a/browser/base/content/test/plugins/browser_CTP_hide_overlay.js
+++ /dev/null
@@ -1,88 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-
- // Tests that the overlay can be hidden for plugins using the close icon.
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon")
- let bounds = closeIcon.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
-
- Assert.ok(!overlay.classList.contains("visible"), "overlay should be hidden.");
- });
-});
-
-// Test that the overlay cannot be interacted with after the user closes the overlay
-add_task(function* () {
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon")
- let closeIconBounds = closeIcon.getBoundingClientRect();
- let overlayBounds = overlay.getBoundingClientRect();
- let overlayLeft = (overlayBounds.left + overlayBounds.right) / 2;
- let overlayTop = (overlayBounds.left + overlayBounds.right) / 2 ;
- let closeIconLeft = (closeIconBounds.left + closeIconBounds.right) / 2;
- let closeIconTop = (closeIconBounds.top + closeIconBounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- // Simulate clicking on the close icon.
- utils.sendMouseEvent("mousedown", closeIconLeft, closeIconTop, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", closeIconLeft, closeIconTop, 0, 1, 0, false, 0, 0);
-
- // Simulate clicking on the overlay.
- utils.sendMouseEvent("mousedown", overlayLeft, overlayTop, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", overlayLeft, overlayTop, 0, 1, 0, false, 0, 0);
-
- Assert.ok(overlay.hasAttribute("dismissed") && !overlay.classList.contains("visible"),
- "Overlay should be hidden");
- });
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins");
-
- ok(notification.dismissed, "No notification should be shown");
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_iframe.js b/browser/base/content/test/plugins/browser_CTP_iframe.js
deleted file mode 100644
index 58565559f..000000000
--- a/browser/base/content/test/plugins/browser_CTP_iframe.js
+++ /dev/null
@@ -1,48 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_iframe.html");
-
- // Tests that the overlays are visible and actionable if the plugin is in an iframe.
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
- let frame = content.document.getElementById("frame");
- let doc = frame.contentDocument;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(plugin && overlay.classList.contains("visible"),
- "Test 1, Plugin overlay should exist, not be hidden");
-
- let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon");
- let bounds = closeIcon.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = doc.defaultView.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- Assert.ok(!overlay.classList.contains("visible"),
- "Test 1, Plugin overlay should exist, be hidden");
- });
-});
-
diff --git a/browser/base/content/test/plugins/browser_CTP_multi_allow.js b/browser/base/content/test/plugins/browser_CTP_multi_allow.js
deleted file mode 100644
index 7bc6aaabf..000000000
--- a/browser/base/content/test/plugins/browser_CTP_multi_allow.js
+++ /dev/null
@@ -1,99 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-
- // Test that the click-to-play doorhanger for multiple plugins shows the correct
- // state when re-opening without reloads or navigation.
-
- let pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser);
- ok(!pluginInfo.activated, "plugin should be activated");
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(notification, "Test 1a, Should have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- is(notification.options.pluginData.size, 2,
- "Test 1a, Should have two types of plugin in the notification");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-
- is(PopupNotifications.panel.firstChild.childNodes.length, 2, "have child nodes");
-
- let pluginItem = null;
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- is(item.value, "block", "Test 1a, all plugins should start out blocked");
- if (item.action.pluginName == "Test") {
- pluginItem = item;
- }
- }
-
- // Choose "Allow now" for the test plugin
- pluginItem.value = "allownow";
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test", gBrowser.selectedBrowser);
- ok(pluginInfo.activated, "plugin should be activated");
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(notification, "Test 1b, Should have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- pluginItem = null;
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- if (item.action.pluginName == "Test") {
- is(item.value, "allownow", "Test 1b, Test plugin should now be set to 'Allow now'");
- } else {
- is(item.value, "block", "Test 1b, Second Test plugin should still be blocked");
- pluginItem = item;
- }
- }
-
- // Choose "Allow and remember" for the Second Test plugin
- pluginItem.value = "allowalways";
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("secondtestA", gBrowser.selectedBrowser);
- ok(pluginInfo.activated, "plugin should be activated");
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(notification, "Test 1c, Should have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- if (item.action.pluginName == "Test") {
- is(item.value, "allownow", "Test 1c, Test plugin should be set to 'Allow now'");
- } else {
- is(item.value, "allowalways", "Test 1c, Second Test plugin should be set to 'Allow always'");
- }
- }
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_nonplugins.js b/browser/base/content/test/plugins/browser_CTP_nonplugins.js
deleted file mode 100644
index cdef44d9d..000000000
--- a/browser/base/content/test/plugins/browser_CTP_nonplugins.js
+++ /dev/null
@@ -1,58 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_DISABLED, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
-
- // Test that the click-to-play notification is not shown for non-plugin object elements
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(popupNotification, "Test 1, Should have a click-to-play notification");
-
- let pluginRemovedPromise = waitForEvent(gBrowser.selectedBrowser, "PluginRemoved", null, true, true);
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let plugin = content.document.getElementById("secondtestA");
- plugin.parentNode.removeChild(plugin);
- plugin = content.document.getElementById("secondtestB");
- plugin.parentNode.removeChild(plugin);
-
- let image = content.document.createElement("object");
- image.type = "image/png";
- image.data = "moz.png";
- content.document.body.appendChild(image);
- });
- yield pluginRemovedPromise;
-
- popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(popupNotification, "Test 2, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.parentNode.removeChild(plugin);
- });
-
- popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser);
- ok(popupNotification, "Test 3, Should still have a click-to-play notification");
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_notificationBar.js b/browser/base/content/test/plugins/browser_CTP_notificationBar.js
deleted file mode 100644
index 3c7bd911c..000000000
--- a/browser/base/content/test/plugins/browser_CTP_notificationBar.js
+++ /dev/null
@@ -1,151 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- // Expecting a notification bar for hidden plugins
- yield promiseForNotificationBar("plugin-hidden", gTestBrowser);
-});
-
-add_task(function* () {
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
- yield promiseForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null);
-});
-
-add_task(function* () {
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_overlayed.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // Expecting a plugin notification bar when plugins are overlaid.
- yield promiseForNotificationBar("plugin-hidden", gTestBrowser);
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_overlayed.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.equal(plugin.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 3b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
- });
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 1a, plugin should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!(overlay && overlay.classList.contains("visible")),
- "Test 3b, overlay should be hidden.");
- });
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_positioned.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // Expecting a plugin notification bar when plugins are overlaid offscreen.
- yield promisePopupNotification("click-to-play-plugins");
- yield promiseForNotificationBar("plugin-hidden", gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.equal(plugin.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 4b, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!(overlay && overlay.classList.contains("visible")),
- "Test 4b, overlay should be hidden.");
- });
-});
-
-// Test that the notification bar is getting dismissed when directly activating plugins
-// via the doorhanger.
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_small.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // Expecting a plugin notification bar when plugins are overlaid offscreen.
- yield promisePopupNotification("click-to-play-plugins");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.equal(plugin.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 6, Plugin should be click-to-play");
- });
-
- yield promisePopupNotification("click-to-play-plugins");
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 6, Should have a click-to-play notification");
-
- // simulate "always allow"
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
- yield promiseForCondition(() => notificationBox.getNotificationWithValue("plugin-hidden") === null);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 7, plugin should be activated");
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js b/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js
deleted file mode 100644
index ccb4d11d7..000000000
--- a/browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js
+++ /dev/null
@@ -1,120 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!popupNotification, "Test 1, Should not have a click-to-play notification");
-});
-
-// Test that the click-to-play overlay is not hidden for elements
-// partially or fully outside the viewport.
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let doc = content.document;
- let p = doc.createElement('embed');
-
- p.setAttribute('id', 'test');
- p.setAttribute('type', 'application/x-test');
- p.style.left = "0";
- p.style.bottom = "200px";
-
- doc.getElementById('container').appendChild(p);
- });
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- let doc = content.document;
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 2, overlay should be visible.");
- });
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let doc = content.document;
- let p = doc.createElement('embed');
-
- p.setAttribute('id', 'test');
- p.setAttribute('type', 'application/x-test');
- p.style.left = "0";
- p.style.bottom = "-410px";
-
- doc.getElementById('container').appendChild(p);
- });
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let plugin = content.document.getElementById("test");
- let doc = content.document;
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 3, overlay should be visible.");
- });
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_outsideScrollArea.html");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let doc = content.document;
- let p = doc.createElement('embed');
-
- p.setAttribute('id', 'test');
- p.setAttribute('type', 'application/x-test');
- p.style.left = "-600px";
- p.style.bottom = "0";
-
- doc.getElementById('container').appendChild(p);
- });
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let plugin = content.document.getElementById("test");
- let doc = content.document;
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!(overlay && overlay.classList.contains("visible")),
- "Test 4, overlay should be hidden.");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_remove_navigate.js b/browser/base/content/test/plugins/browser_CTP_remove_navigate.js
deleted file mode 100644
index 8ee1c5b5a..000000000
--- a/browser/base/content/test/plugins/browser_CTP_remove_navigate.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const gTestRoot = getRootDirectory(gTestPath);
-const gHttpTestRoot = gTestRoot.replace("chrome://mochitests/content/",
- "http://127.0.0.1:8888/");
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- });
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-});
-
-/**
- * Tests that if a plugin is removed just as we transition to
- * a different page, that we don't show the hidden plugin
- * notification bar on the new page.
- */
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
-
- // Load up a page with a plugin...
- let notificationPromise = waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser);
- yield promiseTabLoadEvent(gBrowser.selectedTab, gHttpTestRoot + "plugin_small.html");
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
- yield notificationPromise;
-
- // Trigger the PluginRemoved event to be fired, and then immediately
- // browse to a new page.
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.remove();
- });
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "about:mozilla");
-
- // There should be no hidden plugin notification bar at about:mozilla.
- let notificationBox = gBrowser.getNotificationBox(gBrowser.selectedBrowser);
- is(notificationBox.getNotificationWithValue("plugin-hidden"), null,
- "Expected no notification box");
-});
-
-/**
- * Tests that if a plugin is removed just as we transition to
- * a different page with a plugin, that we show the right notification
- * for the new page.
- */
-add_task(function* () {
- // Load up a page with a plugin...
- let notificationPromise = waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser);
- yield promiseTabLoadEvent(gBrowser.selectedTab, gHttpTestRoot + "plugin_small.html");
- yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
- yield notificationPromise;
-
- // Trigger the PluginRemoved event to be fired, and then immediately
- // browse to a new page.
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.remove();
- });
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gHttpTestRoot + "plugin_small_2.html");
- let notification = yield waitForNotificationBar("plugin-hidden", gBrowser.selectedBrowser);
- ok(notification, "There should be a notification shown for the new page.");
- // Ensure that the notification is showing information about
- // the x-second-test plugin.
- let label = notification.label;
- ok(label.includes("Second Test"), "Should mention the second plugin");
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_resize.js b/browser/base/content/test/plugins/browser_CTP_resize.js
deleted file mode 100644
index 9b2a2cd82..000000000
--- a/browser/base/content/test/plugins/browser_CTP_resize.js
+++ /dev/null
@@ -1,130 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!popupNotification, "Test 1, Should not have a click-to-play notification");
-
- yield promiseTabLoadEvent(newTab, gTestRoot + "plugin_small.html"); // 10x10 plugin
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-});
-
-// Test that the overlay is hidden for "small" plugin elements and is shown
-// once they are resized to a size that can hold the overlay
-add_task(function* () {
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "Test 2, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!(overlay && overlay.classList.contains("visible")),
- "Test 2, overlay should be hidden.");
- });
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.style.width = "300px";
- });
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!(overlay && overlay.classList.contains("visible")),
- "Test 3, overlay should be hidden.");
- });
-});
-
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.style.height = "300px";
- });
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- content.document.getElementById("test").clientTop;
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 4, overlay should be visible.");
- });
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.style.width = "10px";
- plugin.style.height = "10px";
- });
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- content.document.getElementById("test").clientTop;
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!(overlay && overlay.classList.contains("visible")),
- "Test 5, overlay should be hidden.");
- });
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- plugin.style.height = "300px";
- plugin.style.width = "300px";
- });
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- content.document.getElementById("test").clientTop;
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 6, overlay should be visible.");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_CTP_zoom.js b/browser/base/content/test/plugins/browser_CTP_zoom.js
deleted file mode 100644
index 8b353232d..000000000
--- a/browser/base/content/test/plugins/browser_CTP_zoom.js
+++ /dev/null
@@ -1,62 +0,0 @@
-"use strict";
-
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- FullZoom.reset(); // must be called before closing the tab we zoomed!
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!popupNotification, "Test 1, Should not have a click-to-play notification");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_zoom.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-});
-
-// Enlarges the zoom level 4 times and tests that the overlay is
-// visible after each enlargement.
-add_task(function* () {
- for (let count = 0; count < 4; count++) {
-
- FullZoom.enlarge();
-
- // Reload the page
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_zoom.html");
- yield promiseUpdatePluginBindings(gTestBrowser);
- yield ContentTask.spawn(gTestBrowser, { count }, function* (args) {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Overlay should be visible for zoom change count " + args.count);
- });
- }
-});
-
-
diff --git a/browser/base/content/test/plugins/browser_blocking.js b/browser/base/content/test/plugins/browser_blocking.js
deleted file mode 100644
index 334ed9f2e..000000000
--- a/browser/base/content/test/plugins/browser_blocking.js
+++ /dev/null
@@ -1,349 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-function updateAllTestPlugins(aState) {
- setTestPluginEnabledState(aState, "Test Plug-in");
- setTestPluginEnabledState(aState, "Second Test Plug-in");
-}
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_ENABLED);
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- }));
-});
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- // Prime the content process
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>hi</html>");
-
- // Make sure the blocklist service(s) are running
- Components.classes["@mozilla.org/extensions/blocklist;1"]
- .getService(Components.interfaces.nsIBlocklistService);
- let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser);
- ok(!exmsg, "exception: " + exmsg);
-});
-
-add_task(function* () {
- // enable hard blocklisting for the next test
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginHard.xml", gTestBrowser);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins");
- ok(notification.dismissed, "Test 5: The plugin notification should be dismissed by default");
-
- yield promiseForNotificationShown(notification);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED, "Test 5, plugin fallback type should be PLUGIN_BLOCKLISTED");
-
- is(notification.options.pluginData.size, 1, "Test 5: Only the blocked plugin should be present in the notification");
- ok(PopupNotifications.panel.firstChild._buttonContainer.hidden, "Part 5: The blocked plugins notification should not have any buttons visible.");
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-});
-
-// Tests a vulnerable, updatable plugin
-
-add_task(function* () {
- // enable hard blocklisting of test
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableUpdatable.xml", gTestBrowser);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE,
- "Test 18a, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE");
- ok(!pluginInfo.activated, "Test 18a, Plugin should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 18a, Plugin overlay should exist, not be hidden");
-
- let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink");
- Assert.ok(updateLink.style.visibility != "hidden",
- "Test 18a, Plugin should have an update link");
- });
-
- let promise = waitForEvent(gBrowser.tabContainer, "TabOpen", null, true);
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink");
- let bounds = updateLink.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
- yield promise;
-
- promise = waitForEvent(gBrowser.tabContainer, "TabClose", null, true);
- gBrowser.removeCurrentTab();
- yield promise;
-});
-
-add_task(function* () {
- // clicking the update link should not activate the plugin
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE,
- "Test 18a, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE");
- ok(!pluginInfo.activated, "Test 18b, Plugin should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 18b, Plugin overlay should exist, not be hidden");
- });
-});
-
-// Tests a vulnerable plugin with no update
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableNoUpdate.xml", gTestBrowser);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 18c, Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE,
- "Test 18c, plugin fallback type should be PLUGIN_VULNERABLE_NO_UPDATE");
- ok(!pluginInfo.activated, "Test 18c, Plugin should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(overlay && overlay.classList.contains("visible"),
- "Test 18c, Plugin overlay should exist, not be hidden");
-
- let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink");
- Assert.ok(updateLink && updateLink.style.display != "block",
- "Test 18c, Plugin should not have an update link");
- });
-
- // check that click "Always allow" works with blocked plugins
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE,
- "Test 18c, plugin fallback type should be PLUGIN_VULNERABLE_NO_UPDATE");
- ok(pluginInfo.activated, "Test 18c, Plugin should be activated");
- let enabledState = getTestPluginEnabledState();
- ok(enabledState, "Test 18c, Plugin enabled state should be STATE_CLICKTOPLAY");
-});
-
-// continue testing "Always allow", make sure it sticks.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 18d, Waited too long for plugin to activate");
-
- clearAllPluginPermissions();
-});
-
-// clicking the in-content overlay of a vulnerable plugin should bring
-// up the notification and not directly activate the plugin
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 18f, Should have a click-to-play notification");
- ok(notification.dismissed, "Test 18f, notification should start dismissed");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 18f, Waited too long for plugin to activate");
-
- var oldEventCallback = notification.options.eventCallback;
- let promise = promiseForCondition(() => oldEventCallback == null);
- notification.options.eventCallback = function() {
- if (oldEventCallback) {
- oldEventCallback();
- }
- oldEventCallback = null;
- };
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
- yield promise;
-
- ok(notification, "Test 18g, Should have a click-to-play notification");
- ok(!notification.dismissed, "Test 18g, notification should be open");
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated");
-});
-
-// Test that "always allow"-ing a plugin will not allow it when it becomes
-// blocklisted.
-add_task(function* () {
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 24a, Should have a click-to-play notification");
-
- // Plugin should start as CTP
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 24a, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
- ok(!pluginInfo.activated, "Test 24a, Plugin should not be active.");
-
- // simulate "always allow"
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 24a, Plugin should be active.");
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableUpdatable.xml", gTestBrowser);
-});
-
-// the plugin is now blocklisted, so it should not automatically load
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 24b, Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE,
- "Test 24b, plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE");
- ok(!pluginInfo.activated, "Test 24b, Plugin should not be active.");
-
- // simulate "always allow"
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 24b, Plugin should be active.");
-
- clearAllPluginPermissions();
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-});
-
-// Plugin sync removal test. Note this test produces a notification drop down since
-// the plugin we add has zero dims.
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_syncRemoved.html");
-
- // Maybe there some better trick here, we need to wait for the page load, then
- // wait for the js to execute in the page.
- yield waitForMs(500);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins");
- ok(notification, "Test 25: There should be a plugin notification even if the plugin was immediately removed");
- ok(notification.dismissed, "Test 25: The notification should be dismissed by default");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>hi</html>");
-});
-
-// Tests a page with a blocked plugin in it and make sure the infoURL property
-// the blocklist file gets used.
-add_task(function* () {
- clearAllPluginPermissions();
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginInfoURL.xml", gTestBrowser);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins");
-
- // Since the plugin notification is dismissed by default, reshow it.
- yield promiseForNotificationShown(notification);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED,
- "Test 26, plugin fallback type should be PLUGIN_BLOCKLISTED");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(!objLoadingContent.activated, "Plugin should not be activated.");
- });
-
- const testUrl = "http://test.url.com/";
-
- let firstPanelChild = PopupNotifications.panel.firstChild;
- let infoLink = document.getAnonymousElementByAttribute(firstPanelChild, "anonid",
- "click-to-play-plugins-notification-link");
- is(infoLink.href, testUrl,
- "Test 26, the notification URL needs to match the infoURL from the blocklist file.");
-});
-
diff --git a/browser/base/content/test/plugins/browser_blocklist_content.js b/browser/base/content/test/plugins/browser_blocklist_content.js
deleted file mode 100644
index bf4e159bc..000000000
--- a/browser/base/content/test/plugins/browser_blocklist_content.js
+++ /dev/null
@@ -1,104 +0,0 @@
-var gTestBrowser = null;
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gChromeRoot = getRootDirectory(gTestPath);
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- }));
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
-
- // Prime the blocklist service, the remote service doesn't launch on startup.
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html></html>");
- let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser);
- ok(!exmsg, "exception: " + exmsg);
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let test = content.document.getElementById("test");
- Assert.ok(test.activated, "task 1a: test plugin should be activated!");
- });
-});
-
-// Load a fresh page, load a new plugin blocklist, then load the same page again.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>GO!</html>");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginHard.xml", gTestBrowser);
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let test = content.document.getElementById("test");
- ok(!test.activated, "task 2a: test plugin shouldn't activate!");
- });
-});
-
-// Unload the block list and lets do this again, only this time lets
-// hack around in the content blocklist service maliciously.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>GO!</html>");
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-
- // Hack the planet! Load our blocklist shim, so we can mess with blocklist
- // return results in the content process. Active until we close our tab.
- let mm = gTestBrowser.messageManager;
- info("test 3a: loading " + gChromeRoot + "blocklist_proxy.js" + "\n");
- mm.loadFrameScript(gChromeRoot + "blocklist_proxy.js", true);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let test = content.document.getElementById("test");
- Assert.ok(test.activated, "task 3a: test plugin should be activated!");
- });
-});
-
-// Load a fresh page, load a new plugin blocklist, then load the same page again.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>GO!</html>");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginHard.xml", gTestBrowser);
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let test = content.document.getElementById("test");
- Assert.ok(!test.activated, "task 4a: test plugin shouldn't activate!");
- });
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-});
diff --git a/browser/base/content/test/plugins/browser_bug743421.js b/browser/base/content/test/plugins/browser_bug743421.js
deleted file mode 100644
index 966e7b012..000000000
--- a/browser/base/content/test/plugins/browser_bug743421.js
+++ /dev/null
@@ -1,119 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- }));
-});
-
-add_task(function* () {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-
- // Prime the blocklist service, the remote service doesn't launch on startup.
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html></html>");
-
- let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser);
- ok(!exmsg, "exception: " + exmsg);
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-});
-
-// Tests that navigation within the page and the window.history API doesn't break click-to-play state.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_add_dynamically.html");
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!notification, "Test 1a, Should not have a click-to-play notification");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin());
- });
-
- yield promisePopupNotification("click-to-play-plugins");
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementsByTagName("embed")[0];
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated");
- });
-
- // Click the activate button on doorhanger to make sure it works
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
-
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementsByTagName("embed")[0];
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
- });
-});
-
-add_task(function* () {
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 1c, Should still have a click-to-play notification");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin());
- let plugin = content.document.getElementsByTagName("embed")[1];
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(objLoadingContent.activated,
- "Test 1c, Newly inserted plugin in activated page should be activated");
- });
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementsByTagName("embed")[1];
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(objLoadingContent.activated, "Test 1d, Plugin should be activated");
-
- let promise = ContentTaskUtils.waitForEvent(content, "hashchange");
- content.location += "#anchorNavigation";
- yield promise;
- });
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin());
- let plugin = content.document.getElementsByTagName("embed")[2];
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(objLoadingContent.activated, "Test 1e, Plugin should be activated");
- });
-});
-
-add_task(function* () {
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementsByTagName("embed")[2];
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(objLoadingContent.activated, "Test 1f, Plugin should be activated");
-
- content.history.replaceState({}, "", "replacedState");
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin());
- plugin = content.document.getElementsByTagName("embed")[3];
- objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- Assert.ok(objLoadingContent.activated, "Test 1g, Plugin should be activated");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_bug744745.js b/browser/base/content/test/plugins/browser_bug744745.js
deleted file mode 100644
index c9f552a4e..000000000
--- a/browser/base/content/test/plugins/browser_bug744745.js
+++ /dev/null
@@ -1,50 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var gNumPluginBindingsAttached = 0;
-
-function pluginBindingAttached() {
- gNumPluginBindingsAttached++;
- if (gNumPluginBindingsAttached != 1) {
- ok(false, "if we've gotten here, something is quite wrong");
- }
-}
-
-add_task(function* () {
- registerCleanupFunction(function () {
- gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
-
- let testRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
- yield promiseTabLoadEvent(gBrowser.selectedTab, testRoot + "plugin_bug744745.html");
-
- yield promiseForCondition(function () { return gNumPluginBindingsAttached == 1; });
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("test");
- if (!plugin) {
- Assert.ok(false, "plugin element not available.");
- return;
- }
- // We can't use MochiKit's routine
- let style = content.getComputedStyle(plugin);
- Assert.ok(("opacity" in style) && style.opacity == 1, "plugin style properly configured.");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_bug787619.js b/browser/base/content/test/plugins/browser_bug787619.js
deleted file mode 100644
index bfd52258c..000000000
--- a/browser/base/content/test/plugins/browser_bug787619.js
+++ /dev/null
@@ -1,65 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var gWrapperClickCount = 0;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- let testRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
- yield promiseTabLoadEvent(gBrowser.selectedTab, testRoot + "plugin_bug787619.html");
-
- // Due to layout being async, "PluginBindAttached" may trigger later.
- // This forces a layout flush, thus triggering it, and schedules the
- // test so it is definitely executed afterwards.
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // check plugin state
- let pluginInfo = yield promiseForPluginInfo("plugin");
- ok(!pluginInfo.activated, "1a plugin should not be activated");
-
- // click the overlay to prompt
- let promise = promisePopupNotification("click-to-play-plugins");
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- let plugin = content.document.getElementById("plugin");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
- yield promise;
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("plugin");
- ok(!pluginInfo.activated, "1b plugin should not be activated");
-
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
- PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- // check plugin state
- pluginInfo = yield promiseForPluginInfo("plugin");
- ok(pluginInfo.activated, "plugin should be activated");
-
- is(gWrapperClickCount, 0, 'wrapper should not have received any clicks');
-});
diff --git a/browser/base/content/test/plugins/browser_bug797677.js b/browser/base/content/test/plugins/browser_bug797677.js
deleted file mode 100644
index 1ae9f5047..000000000
--- a/browser/base/content/test/plugins/browser_bug797677.js
+++ /dev/null
@@ -1,43 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var gConsoleErrors = 0;
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- consoleService.unregisterListener(errorListener);
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- let consoleService = Cc["@mozilla.org/consoleservice;1"]
- .getService(Ci.nsIConsoleService);
- let errorListener = {
- observe: function(aMessage) {
- if (aMessage.message.includes("NS_ERROR_FAILURE"))
- gConsoleErrors++;
- }
- };
- consoleService.registerListener(errorListener);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug797677.html");
-
- let pluginInfo = yield promiseForPluginInfo("plugin");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED, "plugin should not have been found.");
-
- // simple cpows
- yield ContentTask.spawn(gTestBrowser, null, function() {
- let plugin = content.document.getElementById("plugin");
- ok(plugin, "plugin should be in the page");
- });
- is(gConsoleErrors, 0, "should have no console errors");
-});
diff --git a/browser/base/content/test/plugins/browser_bug812562.js b/browser/base/content/test/plugins/browser_bug812562.js
deleted file mode 100644
index be7b00b22..000000000
--- a/browser/base/content/test/plugins/browser_bug812562.js
+++ /dev/null
@@ -1,80 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- Services.prefs.clearUserPref("plugins.click_to_play");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- }));
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- // Prime the blocklist service, the remote service doesn't launch on startup.
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html></html>");
- let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser);
- ok(!exmsg, "exception: " + exmsg);
-});
-
-// Tests that the going back will reshow the notification for click-to-play
-// blocklisted plugins
-add_task(function* () {
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginVulnerableUpdatable.xml", gTestBrowser);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "test part 1: Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "plugin should be marked as VULNERABLE");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- Assert.ok(!!content.document.getElementById("test"),
- "test part 1: plugin should not be activated");
- });
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html></html>");
-});
-
-add_task(function* () {
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!popupNotification, "test part 2: Should not have a click-to-play notification");
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- Assert.ok(!content.document.getElementById("test"),
- "test part 2: plugin should not be activated");
- });
-
- let obsPromise = TestUtils.topicObserved("PopupNotifications-updateNotShowing");
- let overlayPromise = promisePopupNotification("click-to-play-plugins");
- gTestBrowser.goBack();
- yield obsPromise;
- yield overlayPromise;
-});
-
-add_task(function* () {
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "test part 3: Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "plugin should be marked as VULNERABLE");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- Assert.ok(!!content.document.getElementById("test"),
- "test part 3: plugin should not be activated");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_bug818118.js b/browser/base/content/test/plugins/browser_bug818118.js
deleted file mode 100644
index 9dd6e22e7..000000000
--- a/browser/base/content/test/plugins/browser_bug818118.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_both.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "plugin should be click to play");
- ok(!pluginInfo.activated, "plugin should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, () => {
- let unknown = content.document.getElementById("unknown");
- ok(unknown, "should have unknown plugin in page");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_bug820497.js b/browser/base/content/test/plugins/browser_bug820497.js
deleted file mode 100644
index b2e0f5268..000000000
--- a/browser/base/content/test/plugins/browser_bug820497.js
+++ /dev/null
@@ -1,71 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var gNumPluginBindingsAttached = 0;
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-
- gTestBrowser.addEventListener("PluginBindingAttached", function () { gNumPluginBindingsAttached++ }, true, true);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug820497.html");
-
- yield promiseForCondition(function () { return gNumPluginBindingsAttached == 1; });
-
- yield ContentTask.spawn(gTestBrowser, null, () => {
- // Note we add the second plugin in the code farther down, so there's
- // no way we got here with anything but one plugin loaded.
- let doc = content.document;
- let testplugin = doc.getElementById("test");
- ok(testplugin, "should have test plugin");
- let secondtestplugin = doc.getElementById("secondtest");
- ok(!secondtestplugin, "should not yet have second test plugin");
- });
-
- yield promisePopupNotification("click-to-play-plugins");
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "should have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- is(notification.options.pluginData.size, 1, "should be 1 type of plugin in the popup notification");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- XPCNativeWrapper.unwrap(content).addSecondPlugin();
- });
-
- yield promiseForCondition(function () { return gNumPluginBindingsAttached == 2; });
-
- yield ContentTask.spawn(gTestBrowser, null, () => {
- let doc = content.document;
- let testplugin = doc.getElementById("test");
- ok(testplugin, "should have test plugin");
- let secondtestplugin = doc.getElementById("secondtest");
- ok(secondtestplugin, "should have second test plugin");
- });
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
-
- ok(notification, "should have popup notification");
-
- yield promiseForNotificationShown(notification);
-
- is(notification.options.pluginData.size, 2, "aited too long for 2 types of plugins in popup notification");
-});
diff --git a/browser/base/content/test/plugins/browser_clearplugindata.html b/browser/base/content/test/plugins/browser_clearplugindata.html
deleted file mode 100644
index 243350ba4..000000000
--- a/browser/base/content/test/plugins/browser_clearplugindata.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/
--->
-<html>
- <head>
- <title>Plugin Clear Site Data sanitize test</title>
-
- <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
-
- <script type="application/javascript">
- function testSteps()
- {
- // Make sure clearing by timerange is supported.
- var p = document.getElementById("plugin1");
- p.setSitesWithDataCapabilities(true);
-
- p.setSitesWithData(
- "foo.com:0:5," +
- "bar.com:0:100," +
- "baz.com:1:5," +
- "qux.com:1:100"
- );
- }
- </script>
- </head>
-
- <body onload="testSteps();"></body>
-
-</html>
diff --git a/browser/base/content/test/plugins/browser_clearplugindata.js b/browser/base/content/test/plugins/browser_clearplugindata.js
deleted file mode 100644
index 69d474fed..000000000
--- a/browser/base/content/test/plugins/browser_clearplugindata.js
+++ /dev/null
@@ -1,127 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-var gTestBrowser = null;
-
-// Test clearing plugin data using sanitize.js.
-const testURL1 = gTestRoot + "browser_clearplugindata.html";
-const testURL2 = gTestRoot + "browser_clearplugindata_noage.html";
-
-var tempScope = {};
-Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
-var Sanitizer = tempScope.Sanitizer;
-
-const pluginHostIface = Ci.nsIPluginHost;
-var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
-pluginHost.QueryInterface(pluginHostIface);
-
-var pluginTag = getTestPlugin();
-var sanitizer = null;
-
-function stored(needles) {
- let something = pluginHost.siteHasData(this.pluginTag, null);
- if (!needles)
- return something;
-
- if (!something)
- return false;
-
- for (let i = 0; i < needles.length; ++i) {
- if (!pluginHost.siteHasData(this.pluginTag, needles[i]))
- return false;
- }
- return true;
-}
-
-add_task(function* () {
- registerCleanupFunction(function () {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- if (gTestBrowser) {
- gBrowser.removeCurrentTab();
- }
- window.focus();
- gTestBrowser = null;
- });
-});
-
-add_task(function* () {
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
-
- sanitizer = new Sanitizer();
- sanitizer.ignoreTimespan = false;
- sanitizer.prefDomain = "privacy.cpd.";
- let itemPrefs = gPrefService.getBranch(sanitizer.prefDomain);
- itemPrefs.setBoolPref("history", false);
- itemPrefs.setBoolPref("downloads", false);
- itemPrefs.setBoolPref("cache", false);
- itemPrefs.setBoolPref("cookies", true); // plugin data
- itemPrefs.setBoolPref("formdata", false);
- itemPrefs.setBoolPref("offlineApps", false);
- itemPrefs.setBoolPref("passwords", false);
- itemPrefs.setBoolPref("sessions", false);
- itemPrefs.setBoolPref("siteSettings", false);
-});
-
-add_task(function* () {
- // Load page to set data for the plugin.
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, testURL1);
-
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- ok(stored(["foo.com", "bar.com", "baz.com", "qux.com"]),
- "Data stored for sites");
-
- // Clear 20 seconds ago
- let now_uSec = Date.now() * 1000;
- sanitizer.range = [now_uSec - 20*1000000, now_uSec];
- yield sanitizer.sanitize();
-
- ok(stored(["bar.com", "qux.com"]), "Data stored for sites");
- ok(!stored(["foo.com"]), "Data cleared for foo.com");
- ok(!stored(["baz.com"]), "Data cleared for baz.com");
-
- // Clear everything
- sanitizer.range = null;
- yield sanitizer.sanitize();
-
- ok(!stored(null), "All data cleared");
-
- gBrowser.removeCurrentTab();
- gTestBrowser = null;
-});
-
-add_task(function* () {
- // Load page to set data for the plugin.
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, testURL2);
-
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- ok(stored(["foo.com", "bar.com", "baz.com", "qux.com"]),
- "Data stored for sites");
-
- // Attempt to clear 20 seconds ago. The plugin will throw
- // NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, which should result in us
- // clearing all data regardless of age.
- let now_uSec = Date.now() * 1000;
- sanitizer.range = [now_uSec - 20*1000000, now_uSec];
- yield sanitizer.sanitize();
-
- ok(!stored(null), "All data cleared");
-
- gBrowser.removeCurrentTab();
- gTestBrowser = null;
-});
-
diff --git a/browser/base/content/test/plugins/browser_clearplugindata_noage.html b/browser/base/content/test/plugins/browser_clearplugindata_noage.html
deleted file mode 100644
index 820979541..000000000
--- a/browser/base/content/test/plugins/browser_clearplugindata_noage.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/
--->
-<html>
- <head>
- <title>Plugin Clear Site Data sanitize test without age</title>
-
- <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
-
- <script type="application/javascript">
- function testSteps()
- {
- // Make sure clearing by timerange is disabled.
- var p = document.getElementById("plugin1");
- p.setSitesWithDataCapabilities(false);
-
- p.setSitesWithData(
- "foo.com:0:5," +
- "bar.com:0:100," +
- "baz.com:1:5," +
- "qux.com:1:100"
- );
- }
- </script>
- </head>
-
- <body onload="testSteps();"></body>
-
-</html>
diff --git a/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js b/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js
deleted file mode 100644
index bdca32e70..000000000
--- a/browser/base/content/test/plugins/browser_globalplugin_crashinfobar.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Test that the notification bar for crashed GMPs works.
- */
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:blank",
- }, function* (browser) {
- yield ContentTask.spawn(browser, null, function* () {
- const GMP_CRASH_EVENT = {
- pluginID: 1,
- pluginName: "GlobalTestPlugin",
- submittedCrashReport: false,
- bubbles: true,
- cancelable: true,
- gmpPlugin: true,
- };
-
- let crashEvent = new content.PluginCrashedEvent("PluginCrashed",
- GMP_CRASH_EVENT);
- content.dispatchEvent(crashEvent);
- });
-
- let notification = yield waitForNotificationBar("plugin-crashed", browser);
-
- let notificationBox = gBrowser.getNotificationBox(browser);
- ok(notification, "Infobar was shown.");
- is(notification.priority, notificationBox.PRIORITY_WARNING_MEDIUM,
- "Correct priority.");
- is(notification.getAttribute("label"),
- "The GlobalTestPlugin plugin has crashed.",
- "Correct message.");
- });
-});
diff --git a/browser/base/content/test/plugins/browser_pageInfo_plugins.js b/browser/base/content/test/plugins/browser_pageInfo_plugins.js
deleted file mode 100644
index 0d941e0fa..000000000
--- a/browser/base/content/test/plugins/browser_pageInfo_plugins.js
+++ /dev/null
@@ -1,191 +0,0 @@
-var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPageInfo = null;
-var gNextTest = null;
-var gTestBrowser = null;
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"]
- .getService(Components.interfaces.nsIPluginHost);
-var gPermissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
- .getService(Components.interfaces.nsIPermissionManager);
-var gTestPermissionString = gPluginHost.getPermissionStringForType("application/x-test");
-var gSecondTestPermissionString = gPluginHost.getPermissionStringForType("application/x-second-test");
-
-function doOnPageLoad(url, continuation) {
- gNextTest = continuation;
- gTestBrowser.addEventListener("load", pageLoad, true);
- gTestBrowser.contentWindow.location = url;
-}
-
-function pageLoad() {
- gTestBrowser.removeEventListener("load", pageLoad);
- // The plugin events are async dispatched and can come after the load event
- // This just allows the events to fire before we then go on to test the states
- executeSoon(gNextTest);
-}
-
-function doOnOpenPageInfo(continuation) {
- Services.obs.addObserver(pageInfoObserve, "page-info-dialog-loaded", false);
- gNextTest = continuation;
- // An explanation: it looks like the test harness complains about leaked
- // windows if we don't keep a reference to every window we've opened.
- // So, don't reuse pointers to opened Page Info windows - simply append
- // to this list.
- gPageInfo = BrowserPageInfo(null, "permTab");
-}
-
-function pageInfoObserve(win, topic, data) {
- Services.obs.removeObserver(pageInfoObserve, "page-info-dialog-loaded");
- gPageInfo.onFinished.push(() => executeSoon(gNextTest));
-}
-
-function finishTest() {
- gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gTestPermissionString);
- gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gSecondTestPermissionString);
- Services.prefs.clearUserPref("plugins.click_to_play");
- gBrowser.removeCurrentTab();
-
- gPageInfo = null;
- gNextTest = null;
- gTestBrowser = null;
- gPluginHost = null;
- gPermissionManager = null;
-
- executeSoon(finish);
-}
-
-function test() {
- waitForExplicitFinish();
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
- gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gTestPermissionString);
- gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gSecondTestPermissionString);
- doOnPageLoad(gHttpTestRoot + "plugin_two_types.html", testPart1a);
-}
-
-// The first test plugin is CtP and the second test plugin is enabled.
-function testPart1a() {
- let test = gTestBrowser.contentDocument.getElementById("test");
- let objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
- ok(!objLoadingContent.activated, "part 1a: Test plugin should not be activated");
- let secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
- objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
- ok(objLoadingContent.activated, "part 1a: Second Test plugin should be activated");
-
- doOnOpenPageInfo(testPart1b);
-}
-
-function testPart1b() {
- let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup");
- let testRadioDefault = gPageInfo.document.getElementById(gTestPermissionString + "#0");
-
- is(testRadioGroup.selectedItem, testRadioDefault, "part 1b: Test radio group should be set to 'Default'");
- let testRadioAllow = gPageInfo.document.getElementById(gTestPermissionString + "#1");
- testRadioGroup.selectedItem = testRadioAllow;
- testRadioAllow.doCommand();
-
- let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup");
- let secondtestRadioDefault = gPageInfo.document.getElementById(gSecondTestPermissionString + "#0");
- is(secondtestRadioGroup.selectedItem, secondtestRadioDefault, "part 1b: Second Test radio group should be set to 'Default'");
- let secondtestRadioAsk = gPageInfo.document.getElementById(gSecondTestPermissionString + "#3");
- secondtestRadioGroup.selectedItem = secondtestRadioAsk;
- secondtestRadioAsk.doCommand();
-
- doOnPageLoad(gHttpTestRoot + "plugin_two_types.html", testPart2);
-}
-
-// Now, the Test plugin should be allowed, and the Test2 plugin should be CtP
-function testPart2() {
- let test = gTestBrowser.contentDocument.getElementById("test").
- QueryInterface(Ci.nsIObjectLoadingContent);
- ok(test.activated, "part 2: Test plugin should be activated");
-
- let secondtest = gTestBrowser.contentDocument.getElementById("secondtestA").
- QueryInterface(Ci.nsIObjectLoadingContent);
- ok(!secondtest.activated, "part 2: Second Test plugin should not be activated");
- is(secondtest.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "part 2: Second test plugin should be click-to-play.");
-
- let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup");
- let testRadioAllow = gPageInfo.document.getElementById(gTestPermissionString + "#1");
- is(testRadioGroup.selectedItem, testRadioAllow, "part 2: Test radio group should be set to 'Allow'");
- let testRadioBlock = gPageInfo.document.getElementById(gTestPermissionString + "#2");
- testRadioGroup.selectedItem = testRadioBlock;
- testRadioBlock.doCommand();
-
- let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup");
- let secondtestRadioAsk = gPageInfo.document.getElementById(gSecondTestPermissionString + "#3");
- is(secondtestRadioGroup.selectedItem, secondtestRadioAsk, "part 2: Second Test radio group should be set to 'Always Ask'");
- let secondtestRadioBlock = gPageInfo.document.getElementById(gSecondTestPermissionString + "#2");
- secondtestRadioGroup.selectedItem = secondtestRadioBlock;
- secondtestRadioBlock.doCommand();
-
- doOnPageLoad(gHttpTestRoot + "plugin_two_types.html", testPart3);
-}
-
-// Now, all the things should be blocked
-function testPart3() {
- let test = gTestBrowser.contentDocument.getElementById("test").
- QueryInterface(Ci.nsIObjectLoadingContent);
- ok(!test.activated, "part 3: Test plugin should not be activated");
- is(test.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED,
- "part 3: Test plugin should be marked as PLUGIN_DISABLED");
-
- let secondtest = gTestBrowser.contentDocument.getElementById("secondtestA").
- QueryInterface(Ci.nsIObjectLoadingContent);
-
- ok(!secondtest.activated, "part 3: Second Test plugin should not be activated");
- is(secondtest.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED,
- "part 3: Second test plugin should be marked as PLUGIN_DISABLED");
-
- // reset permissions
- gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gTestPermissionString);
- gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gSecondTestPermissionString);
- // check that changing the permissions affects the radio state in the
- // open Page Info window
- let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup");
- let testRadioDefault = gPageInfo.document.getElementById(gTestPermissionString + "#0");
- is(testRadioGroup.selectedItem, testRadioDefault, "part 3: Test radio group should be set to 'Default'");
- let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup");
- let secondtestRadioDefault = gPageInfo.document.getElementById(gSecondTestPermissionString + "#0");
- is(secondtestRadioGroup.selectedItem, secondtestRadioDefault, "part 3: Second Test radio group should be set to 'Default'");
-
- doOnPageLoad(gHttpTestRoot + "plugin_two_types.html", testPart4a);
-}
-
-// Now test that setting permission directly (as from the popup notification)
-// immediately influences Page Info.
-function testPart4a() {
- // simulate "allow" from the doorhanger
- gPermissionManager.add(gTestBrowser.currentURI, gTestPermissionString, Ci.nsIPermissionManager.ALLOW_ACTION);
- gPermissionManager.add(gTestBrowser.currentURI, gSecondTestPermissionString, Ci.nsIPermissionManager.ALLOW_ACTION);
-
- // check (again) that changing the permissions affects the radio state in the
- // open Page Info window
- let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup");
- let testRadioAllow = gPageInfo.document.getElementById(gTestPermissionString + "#1");
- is(testRadioGroup.selectedItem, testRadioAllow, "part 4a: Test radio group should be set to 'Allow'");
- let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup");
- let secondtestRadioAllow = gPageInfo.document.getElementById(gSecondTestPermissionString + "#1");
- is(secondtestRadioGroup.selectedItem, secondtestRadioAllow, "part 4a: Second Test radio group should be set to 'Always Allow'");
-
- // now close Page Info and see that it opens with the right settings
- gPageInfo.close();
- doOnOpenPageInfo(testPart4b);
-}
-
-// check that "always allow" resulted in the radio buttons getting set to allow
-function testPart4b() {
- let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup");
- let testRadioAllow = gPageInfo.document.getElementById(gTestPermissionString + "#1");
- is(testRadioGroup.selectedItem, testRadioAllow, "part 4b: Test radio group should be set to 'Allow'");
-
- let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup");
- let secondtestRadioAllow = gPageInfo.document.getElementById(gSecondTestPermissionString + "#1");
- is(secondtestRadioGroup.selectedItem, secondtestRadioAllow, "part 4b: Second Test radio group should be set to 'Allow'");
-
- Services.prefs.setBoolPref("plugins.click_to_play", false);
- gPageInfo.close();
- finishTest();
-}
diff --git a/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
deleted file mode 100644
index ab4743f6f..000000000
--- a/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
+++ /dev/null
@@ -1,207 +0,0 @@
-Cu.import("resource://gre/modules/CrashSubmit.jsm", this);
-
-const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
-
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gTestBrowser = null;
-var config = {};
-
-add_task(function* () {
- // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
- // crash reports. This test needs them enabled. The test also needs a mock
- // report server, and fortunately one is already set up by toolkit/
- // crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
- // which CrashSubmit.jsm uses as a server override.
- let env = Components.classes["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
- let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
- let serverUrl = env.get("MOZ_CRASHREPORTER_URL");
- env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
- env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
-
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- // Crash immediately
- Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", 0);
-
- registerCleanupFunction(Task.async(function*() {
- Services.prefs.clearUserPref("dom.ipc.plugins.timeoutSecs");
- env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
- env.set("MOZ_CRASHREPORTER_URL", serverUrl);
- env = null;
- config = null;
- gTestBrowser = null;
- gBrowser.removeCurrentTab();
- window.focus();
- }));
-});
-
-add_task(function* () {
- config = {
- shouldSubmissionUIBeVisible: true,
- comment: "",
- urlOptIn: false
- };
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-
- let pluginCrashed = promisePluginCrashed();
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_crashCommentAndURL.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // Wait for the plugin to crash
- yield pluginCrashed;
-
- let crashReportStatus = TestUtils.topicObserved("crash-report-status", onSubmitStatus);
-
- // Test that the crash submission UI is actually visible and submit the crash report.
- yield ContentTask.spawn(gTestBrowser, config, function* (aConfig) {
- let doc = content.document;
- let plugin = doc.getElementById("plugin");
- let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
- let submitButton = doc.getAnonymousElementByAttribute(plugin, "anonid", "submitButton");
- // Test that we don't send the URL when urlOptIn is false.
- doc.getAnonymousElementByAttribute(plugin, "anonid", "submitURLOptIn").checked = aConfig.urlOptIn;
- submitButton.click();
- Assert.equal(content.getComputedStyle(pleaseSubmit).display == "block",
- aConfig.shouldSubmissionUIBeVisible, "The crash UI should be visible");
- });
-
- yield crashReportStatus;
-});
-
-add_task(function* () {
- config = {
- shouldSubmissionUIBeVisible: true,
- comment: "a test comment",
- urlOptIn: true
- };
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-
- let pluginCrashed = promisePluginCrashed();
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_crashCommentAndURL.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // Wait for the plugin to crash
- yield pluginCrashed;
-
- let crashReportStatus = TestUtils.topicObserved("crash-report-status", onSubmitStatus);
-
- // Test that the crash submission UI is actually visible and submit the crash report.
- yield ContentTask.spawn(gTestBrowser, config, function* (aConfig) {
- let doc = content.document;
- let plugin = doc.getElementById("plugin");
- let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
- let submitButton = doc.getAnonymousElementByAttribute(plugin, "anonid", "submitButton");
- // Test that we send the URL when urlOptIn is true.
- doc.getAnonymousElementByAttribute(plugin, "anonid", "submitURLOptIn").checked = aConfig.urlOptIn;
- doc.getAnonymousElementByAttribute(plugin, "anonid", "submitComment").value = aConfig.comment;
- submitButton.click();
- Assert.equal(content.getComputedStyle(pleaseSubmit).display == "block",
- aConfig.shouldSubmissionUIBeVisible, "The crash UI should be visible");
- });
-
- yield crashReportStatus;
-});
-
-add_task(function* () {
- config = {
- shouldSubmissionUIBeVisible: false,
- comment: "",
- urlOptIn: true
- };
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-
- let pluginCrashed = promisePluginCrashed();
-
- // Make sure that the plugin container is too small to display the crash submission UI
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_crashCommentAndURL.html?" +
- encodeURIComponent(JSON.stringify({width: 300, height: 300})));
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- // Wait for the plugin to crash
- yield pluginCrashed;
-
- // Test that the crash submission UI is not visible and do not submit a crash report.
- yield ContentTask.spawn(gTestBrowser, config, function* (aConfig) {
- let doc = content.document;
- let plugin = doc.getElementById("plugin");
- let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
- Assert.equal(!!pleaseSubmit && content.getComputedStyle(pleaseSubmit).display == "block",
- aConfig.shouldSubmissionUIBeVisible, "Plugin crash UI should not be visible");
- });
-});
-
-function promisePluginCrashed() {
- return new ContentTask.spawn(gTestBrowser, {}, function* () {
- yield new Promise((resolve) => {
- addEventListener("PluginCrashReporterDisplayed", function onPluginCrashed() {
- removeEventListener("PluginCrashReporterDisplayed", onPluginCrashed);
- resolve();
- });
- });
- })
-}
-
-function onSubmitStatus(aSubject, aData) {
- // Wait for success or failed, doesn't matter which.
- if (aData != "success" && aData != "failed")
- return false;
-
- let propBag = aSubject.QueryInterface(Ci.nsIPropertyBag);
- if (aData == "success") {
- let remoteID = getPropertyBagValue(propBag, "serverCrashID");
- ok(!!remoteID, "serverCrashID should be set");
-
- // Remove the submitted report file.
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
- file.initWithPath(Services.crashmanager._submittedDumpsDir);
- file.append(remoteID + ".txt");
- ok(file.exists(), "Submitted report file should exist");
- file.remove(false);
- }
-
- let extra = getPropertyBagValue(propBag, "extra");
- ok(extra instanceof Ci.nsIPropertyBag, "Extra data should be property bag");
-
- let val = getPropertyBagValue(extra, "PluginUserComment");
- if (config.comment)
- is(val, config.comment,
- "Comment in extra data should match comment in textbox");
- else
- ok(val === undefined,
- "Comment should be absent from extra data when textbox is empty");
-
- val = getPropertyBagValue(extra, "PluginContentURL");
- if (config.urlOptIn)
- is(val, gBrowser.currentURI.spec,
- "URL in extra data should match browser URL when opt-in checked");
- else
- ok(val === undefined,
- "URL should be absent from extra data when opt-in not checked");
-
- return true;
-}
-
-function getPropertyBagValue(bag, key) {
- try {
- var val = bag.getProperty(key);
- }
- catch (e) {
- if (e.result != Cr.NS_ERROR_FAILURE) {
- throw e;
- }
- }
- return val;
-}
diff --git a/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js b/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js
deleted file mode 100644
index 42ef57314..000000000
--- a/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * With e10s, plugins must run in their own process. This means we have
- * three processes at a minimum when we're running a plugin:
- *
- * 1) The main browser, or "chrome" process
- * 2) The content process hosting the plugin instance
- * 3) The plugin process
- *
- * If the plugin process crashes, we cannot be sure if the chrome process
- * will hear about it first, or the content process will hear about it
- * first. Because of how IPC works, that's really up to the operating system,
- * and we assume any guarantees about it, so we have to account for both
- * possibilities.
- *
- * This test exercises the browser's reaction to both possibilities.
- */
-
-const CRASH_URL = "http://example.com/browser/browser/base/content/test/plugins/plugin_crashCommentAndURL.html";
-const CRASHED_MESSAGE = "BrowserPlugins:NPAPIPluginProcessCrashed";
-
-/**
- * In order for our test to work, we need to be able to put a plugin
- * in a very specific state. Specifically, we need it to match the
- * :-moz-handler-crashed pseudoselector. The only way I can find to
- * do that is by actually crashing the plugin. So we wait for the
- * plugin to crash and show the "please" state (since that will
- * only show if both the message from the parent has been received
- * AND the PluginCrashed event has fired).
- *
- * Once in that state, we try to rewind the clock a little bit - we clear
- * out the crashData cache in the PluginContent with a message, and we also
- * override the pluginFallbackState of the <object> to fool PluginContent
- * into believing that the plugin is in a particular state.
- *
- * @param browser
- * The browser that has loaded the CRASH_URL that we need to
- * prepare to be in the special state.
- * @param pluginFallbackState
- * The value we should override the <object>'s pluginFallbackState
- * with.
- * @return Promise
- * The Promise resolves when the plugin has officially been put into
- * the crash reporter state, and then "rewound" to have the "status"
- * attribute of the statusDiv removed. The resolved Promise returns
- * the run ID for the crashed plugin. It rejects if we never get into
- * the crash reporter state.
- */
-function preparePlugin(browser, pluginFallbackState) {
- return ContentTask.spawn(browser, pluginFallbackState, function* (pluginFallbackState) {
- let plugin = content.document.getElementById("plugin");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- // CRASH_URL will load a plugin that crashes immediately. We
- // wait until the plugin has finished being put into the crash
- // state.
- let statusDiv;
- yield ContentTaskUtils.waitForCondition(() => {
- statusDiv = plugin.ownerDocument
- .getAnonymousElementByAttribute(plugin, "anonid",
- "submitStatus");
- return statusDiv && statusDiv.getAttribute("status") == "please";
- }, "Timed out waiting for plugin to be in crash report state");
-
- // "Rewind", by wiping out the status attribute...
- statusDiv.removeAttribute("status");
- // Somehow, I'm able to get away with overriding the getter for
- // this XPCOM object. Probably because I've got chrome privledges.
- Object.defineProperty(plugin, "pluginFallbackType", {
- get: function() {
- return pluginFallbackState;
- }
- });
- return plugin.runID;
- }).then((runID) => {
- browser.messageManager.sendAsyncMessage("BrowserPlugins:Test:ClearCrashData");
- return runID;
- });
-}
-
-add_task(function* setup() {
- // Bypass click-to-play
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
-
- // Clear out any minidumps we create from plugins - we really don't care
- // about them.
- let crashObserver = (subject, topic, data) => {
- if (topic != "plugin-crashed") {
- return;
- }
-
- let propBag = subject.QueryInterface(Ci.nsIPropertyBag2);
- let minidumpID = propBag.getPropertyAsAString("pluginDumpID");
-
- let minidumpDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
- minidumpDir.append("minidumps");
-
- let pluginDumpFile = minidumpDir.clone();
- pluginDumpFile.append(minidumpID + ".dmp");
-
- let extraFile = minidumpDir.clone();
- extraFile.append(minidumpID + ".extra");
-
- ok(pluginDumpFile.exists(), "Found minidump");
- ok(extraFile.exists(), "Found extra file");
-
- pluginDumpFile.remove(false);
- extraFile.remove(false);
- };
-
- Services.obs.addObserver(crashObserver, "plugin-crashed", false);
- // plugins.testmode will make BrowserPlugins:Test:ClearCrashData work.
- Services.prefs.setBoolPref("plugins.testmode", true);
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("plugins.testmode");
- Services.obs.removeObserver(crashObserver, "plugin-crashed");
- });
-});
-
-/**
- * In this case, the chrome process hears about the crash first.
- */
-add_task(function* testChromeHearsPluginCrashFirst() {
- // Open a remote window so that we can run this test even if e10s is not
- // enabled by default.
- let win = yield BrowserTestUtils.openNewBrowserWindow({remote: true});
- let browser = win.gBrowser.selectedBrowser;
-
- browser.loadURI(CRASH_URL);
- yield BrowserTestUtils.browserLoaded(browser);
-
- // In this case, we want the <object> to match the -moz-handler-crashed
- // pseudoselector, but we want it to seem still active, because the
- // content process is not yet supposed to know that the plugin has
- // crashed.
- let runID = yield preparePlugin(browser,
- Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE);
-
- // Send the message down to PluginContent.jsm saying that the plugin has
- // crashed, and that we have a crash report.
- let mm = browser.messageManager;
- mm.sendAsyncMessage(CRASHED_MESSAGE,
- { pluginName: "", runID, state: "please" });
-
- yield ContentTask.spawn(browser, null, function* () {
- // At this point, the content process should have heard the
- // plugin crash message from the parent, and we are OK to emit
- // the PluginCrashed event.
- let plugin = content.document.getElementById("plugin");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- let statusDiv = plugin.ownerDocument
- .getAnonymousElementByAttribute(plugin, "anonid",
- "submitStatus");
-
- if (statusDiv.getAttribute("status") == "please") {
- Assert.ok(false, "Did not expect plugin to be in crash report mode yet.");
- return;
- }
-
- // Now we need the plugin to seem crashed to PluginContent.jsm, without
- // actually crashing the plugin again. We hack around this by overriding
- // the pluginFallbackType again.
- Object.defineProperty(plugin, "pluginFallbackType", {
- get: function() {
- return Ci.nsIObjectLoadingContent.PLUGIN_CRASHED;
- },
- });
-
- let event = new content.PluginCrashedEvent("PluginCrashed", {
- pluginName: "",
- pluginDumpID: "",
- browserDumpID: "",
- submittedCrashReport: false,
- bubbles: true,
- cancelable: true,
- });
-
- plugin.dispatchEvent(event);
- Assert.equal(statusDiv.getAttribute("status"), "please",
- "Should have been showing crash report UI");
- });
- yield BrowserTestUtils.closeWindow(win);
-});
-
-/**
- * In this case, the content process hears about the crash first.
- */
-add_task(function* testContentHearsCrashFirst() {
- // Open a remote window so that we can run this test even if e10s is not
- // enabled by default.
- let win = yield BrowserTestUtils.openNewBrowserWindow({remote: true});
- let browser = win.gBrowser.selectedBrowser;
-
- browser.loadURI(CRASH_URL);
- yield BrowserTestUtils.browserLoaded(browser);
-
- // In this case, we want the <object> to match the -moz-handler-crashed
- // pseudoselector, and we want the plugin to seem crashed, since the
- // content process in this case has heard about the crash first.
- let runID = yield preparePlugin(browser,
- Ci.nsIObjectLoadingContent.PLUGIN_CRASHED);
-
- yield ContentTask.spawn(browser, null, function* () {
- // At this point, the content process has not yet heard from the
- // parent about the crash report. Let's ensure that by making sure
- // we're not showing the plugin crash report UI.
- let plugin = content.document.getElementById("plugin");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- let statusDiv = plugin.ownerDocument
- .getAnonymousElementByAttribute(plugin, "anonid",
- "submitStatus");
-
- if (statusDiv.getAttribute("status") == "please") {
- Assert.ok(false, "Did not expect plugin to be in crash report mode yet.");
- }
-
- let event = new content.PluginCrashedEvent("PluginCrashed", {
- pluginName: "",
- pluginDumpID: "",
- browserDumpID: "",
- submittedCrashReport: false,
- bubbles: true,
- cancelable: true,
- });
-
- plugin.dispatchEvent(event);
-
- Assert.notEqual(statusDiv.getAttribute("status"), "please",
- "Should not yet be showing crash report UI");
- });
-
- // Now send the message down to PluginContent.jsm that the plugin has
- // crashed...
- let mm = browser.messageManager;
- mm.sendAsyncMessage(CRASHED_MESSAGE,
- { pluginName: "", runID, state: "please"});
-
- yield ContentTask.spawn(browser, null, function* () {
- // At this point, the content process will have heard the message
- // from the parent and reacted to it. We should be showing the plugin
- // crash report UI now.
- let plugin = content.document.getElementById("plugin");
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- let statusDiv = plugin.ownerDocument
- .getAnonymousElementByAttribute(plugin, "anonid",
- "submitStatus");
-
- Assert.equal(statusDiv.getAttribute("status"), "please",
- "Should have been showing crash report UI");
- });
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/base/content/test/plugins/browser_plugin_reloading.js b/browser/base/content/test/plugins/browser_plugin_reloading.js
deleted file mode 100644
index 7327d4cf9..000000000
--- a/browser/base/content/test/plugins/browser_plugin_reloading.js
+++ /dev/null
@@ -1,85 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-var gTestBrowser = null;
-
-function updateAllTestPlugins(aState) {
- setTestPluginEnabledState(aState, "Test Plug-in");
- setTestPluginEnabledState(aState, "Second Test Plug-in");
-}
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- gTestBrowser = null;
- gBrowser.removeCurrentTab();
- window.focus();
- }));
-});
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- // Prime the blocklist service, the remote service doesn't launch on startup.
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html></html>");
- let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser);
- ok(!exmsg, "exception: " + exmsg);
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-});
-
-// Tests that a click-to-play plugin retains its activated state upon reloading
-add_task(function* () {
- clearAllPluginPermissions();
-
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 1, Should have a click-to-play notification");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 2, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
-
- // run the plugin
- yield promisePlayObject("test");
-
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 3, plugin should have started");
- ok(pluginInfo.activated, "Test 4, plugin node should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let plugin = content.document.getElementById("test");
- let npobj1 = Components.utils.waiveXrays(plugin).getObjectValue();
- plugin.src = plugin.src;
- let pluginsDiffer = false;
- try {
- Components.utils.waiveXrays(plugin).checkObjectValue(npobj1);
- } catch (e) {
- pluginsDiffer = true;
- }
-
- Assert.ok(pluginsDiffer, "Test 5, plugins differ.");
- });
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 6, Plugin should have retained activated state.");
- is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_PLUGIN, "Test 7, plugin should have started");
-});
diff --git a/browser/base/content/test/plugins/browser_pluginnotification.js b/browser/base/content/test/plugins/browser_pluginnotification.js
deleted file mode 100644
index bf32f37a4..000000000
--- a/browser/base/content/test/plugins/browser_pluginnotification.js
+++ /dev/null
@@ -1,626 +0,0 @@
-var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-var gTestBrowser = null;
-
-function updateAllTestPlugins(aState) {
- setTestPluginEnabledState(aState, "Test Plug-in");
- setTestPluginEnabledState(aState, "Second Test Plug-in");
-}
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- gTestBrowser = null;
- gBrowser.removeCurrentTab();
- window.focus();
- }));
-});
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab();
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- // Prime the blocklist service, the remote service doesn't launch on startup.
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html></html>");
- let exmsg = yield promiseInitContentBlocklistSvc(gBrowser.selectedBrowser);
- ok(!exmsg, "exception: " + exmsg);
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-});
-
-// Tests a page with an unknown plugin in it.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_unknown.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let pluginInfo = yield promiseForPluginInfo("unknown");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED,
- "Test 1a, plugin fallback type should be PLUGIN_UNSUPPORTED");
-});
-
-// Test that the doorhanger is shown when the user clicks on the overlay
-// after having previously blocked the plugin.
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Plugin should not be activated");
-
- // Simulate clicking the "Allow Now" button.
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
-
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._secondaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Plugin should be activated");
-
- // Simulate clicking the "Block" button.
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Plugin should not be activated");
-
- // Simulate clicking the overlay
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let bounds = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
-
- ok(!notification.dismissed, "A plugin notification should be shown.");
-
- clearAllPluginPermissions();
-});
-
-// Tests that going back will reshow the notification for click-to-play plugins
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>hi</html>");
-
- // make sure the notification is gone
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!notification, "Test 11b, Should not have a click-to-play notification");
-
- gTestBrowser.webNavigation.goBack();
-
- yield promisePopupNotification("click-to-play-plugins");
-});
-
-// Tests that the "Allow Always" permission works for click-to-play plugins
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 12a, Plugin should not be activated");
-
- // Simulate clicking the "Allow Always" button.
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
-
- yield promiseForNotificationShown(notification);
-
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 12a, Plugin should be activated");
-});
-
-// Test that the "Always" permission, when set for just the Test plugin,
-// does not also allow the Second Test plugin.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- yield promisePopupNotification("click-to-play-plugins");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let test = content.document.getElementById("test");
- let secondtestA = content.document.getElementById("secondtestA");
- let secondtestB = content.document.getElementById("secondtestB");
- Assert.ok(test.activated && !secondtestA.activated && !secondtestB.activated,
- "Content plugins are set up");
- });
-
- clearAllPluginPermissions();
-});
-
-// Tests that the plugin's "activated" property is true for working plugins
-// with click-to-play disabled.
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_ENABLED);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test2.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let pluginInfo = yield promiseForPluginInfo("test1");
- ok(pluginInfo.activated, "Test 14, Plugin should be activated");
-});
-
-// Tests that the overlay is shown instead of alternate content when
-// plugins are click to play.
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_alternate_content.html");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!!mainBox, "Test 15, Plugin overlay should exist");
- });
-});
-
-// Tests that mContentType is used for click-to-play plugins, and not the
-// inspected type.
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug749455.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 17, Should have a click-to-play notification");
-});
-
-// Tests that clicking the icon of the overlay activates the doorhanger
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated");
-
- ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed,
- "Test 19a, Doorhanger should start out dismissed");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let icon = doc.getAnonymousElementByAttribute(plugin, "class", "icon");
- let bounds = icon.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
-
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
- yield promiseForCondition(condition);
-});
-
-// Tests that clicking the text of the overlay activates the plugin
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated");
-
- ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed,
- "Test 19c, Doorhanger should start out dismissed");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let text = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
- let bounds = text.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
-
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
- yield promiseForCondition(condition);
-});
-
-// Tests that clicking the box of the overlay activates the doorhanger
-// (just to be thorough)
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated");
-
- ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed,
- "Test 19e, Doorhanger should start out dismissed");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", 50, 50, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", 50, 50, 0, 1, 0, false, 0, 0);
- });
-
- let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
- PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 19e, Plugin should not be activated");
-
- clearAllPluginPermissions();
-});
-
-// Tests that a plugin in a div that goes from style="display: none" to
-// "display: block" can be clicked to activate.
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_hidden_to_visible.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 20a, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- Assert.ok(!!overlay, "Test 20a, Plugin overlay should exist");
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- let overlayRect = mainBox.getBoundingClientRect();
- Assert.ok(overlayRect.width == 0 && overlayRect.height == 0,
- "Test 20a, plugin should have an overlay with 0px width and height");
- });
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 20b, plugin should not be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let div = doc.getElementById("container");
- Assert.equal(div.style.display, "none",
- "Test 20b, container div should be display: none");
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let div = doc.getElementById("container");
- div.style.display = "block";
- });
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let mainBox = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- let overlayRect = mainBox.getBoundingClientRect();
- Assert.ok(overlayRect.width == 200 && overlayRect.height == 200,
- "Test 20c, plugin should have overlay dims of 200px");
- });
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(!pluginInfo.activated, "Test 20b, plugin should not be activated");
-
- ok(notification.dismissed, "Test 20c, Doorhanger should start out dismissed");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let bounds = plugin.getBoundingClientRect();
- let left = (bounds.left + bounds.right) / 2;
- let top = (bounds.top + bounds.bottom) / 2;
- let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
- utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
- });
-
- let condition = () => !notification.dismissed && !!PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 20c, plugin should be activated");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
- Assert.ok(overlayRect.width == 0 && overlayRect.height == 0,
- "Test 20c, plugin should have overlay dims of 0px");
- });
-
- clearAllPluginPermissions();
-});
-
-// Test having multiple different types of plugin on one page
-add_task(function* () {
- // contains three plugins, application/x-test, application/x-second-test x 2
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_two_types.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 21a, Should have a click-to-play notification");
-
- // confirm all three are blocked by ctp at this point
- let ids = ["test", "secondtestA", "secondtestB"];
- for (let id of ids) {
- yield ContentTask.spawn(gTestBrowser, { id }, function* (args) {
- let doc = content.document;
- let plugin = doc.getElementById(args.id);
- let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
- Assert.ok(overlayRect.width == 200 && overlayRect.height == 200,
- "Test 21a, plugin " + args.id + " should have click-to-play overlay with dims");
- });
-
- let pluginInfo = yield promiseForPluginInfo(id);
- ok(!pluginInfo.activated, "Test 21a, Plugin with id=" + id + " should not be activated");
- }
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 21a, Should have a click-to-play notification");
-
- // we have to actually show the panel to get the bindings to instantiate
- yield promiseForNotificationShown(notification);
-
- is(notification.options.pluginData.size, 2, "Test 21a, Should have two types of plugin in the notification");
-
- let centerAction = null;
- for (let action of notification.options.pluginData.values()) {
- if (action.pluginName == "Test") {
- centerAction = action;
- break;
- }
- }
- ok(centerAction, "Test 21b, found center action for the Test plugin");
-
- let centerItem = null;
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- is(item.value, "block", "Test 21b, all plugins should start out blocked");
- if (item.action == centerAction) {
- centerItem = item;
- break;
- }
- }
- ok(centerItem, "Test 21b, found center item for the Test plugin");
-
- // Select the allow now option in the select drop down for Test Plugin
- centerItem.value = "allownow";
-
- // "click" the button to activate the Test plugin
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- let pluginInfo = yield promiseForPluginInfo("test");
- ok(pluginInfo.activated, "Test 21b, plugin should be activated");
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 21b, Should have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- ok(notification.options.pluginData.size == 2, "Test 21c, Should have one type of plugin in the notification");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
- Assert.ok(overlayRect.width == 0 && overlayRect.height == 0,
- "Test 21c, plugin should have overlay dims of 0px");
- });
-
- ids = ["secondtestA", "secondtestB"];
- for (let id of ids) {
- yield ContentTask.spawn(gTestBrowser, { id }, function* (args) {
- let doc = content.document;
- let plugin = doc.getElementById(args.id);
- let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
- Assert.ok(overlayRect.width == 200 && overlayRect.height == 200,
- "Test 21c, plugin " + args.id + " should have click-to-play overlay with zero dims");
- });
-
-
- let pluginInfo = yield promiseForPluginInfo(id);
- ok(!pluginInfo.activated, "Test 21c, Plugin with id=" + id + " should not be activated");
- }
-
- centerAction = null;
- for (let action of notification.options.pluginData.values()) {
- if (action.pluginName == "Second Test") {
- centerAction = action;
- break;
- }
- }
- ok(centerAction, "Test 21d, found center action for the Second Test plugin");
-
- centerItem = null;
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- if (item.action == centerAction) {
- is(item.value, "block", "Test 21d, test plugin 2 should start blocked");
- centerItem = item;
- break;
- }
- else {
- is(item.value, "allownow", "Test 21d, test plugin should be enabled");
- }
- }
- ok(centerItem, "Test 21d, found center item for the Second Test plugin");
-
- // Select the allow now option in the select drop down for Second Test Plguins
- centerItem.value = "allownow";
-
- // "click" the button to activate the Second Test plugins
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 21d, Should have a click-to-play notification");
-
- ids = ["test", "secondtestA", "secondtestB"];
- for (let id of ids) {
- yield ContentTask.spawn(gTestBrowser, { id }, function* (args) {
- let doc = content.document;
- let plugin = doc.getElementById(args.id);
- let overlayRect = doc.getAnonymousElementByAttribute(plugin, "anonid", "main").getBoundingClientRect();
- Assert.ok(overlayRect.width == 0 && overlayRect.height == 0,
- "Test 21d, plugin " + args.id + " should have click-to-play overlay with zero dims");
- });
-
- let pluginInfo = yield promiseForPluginInfo(id);
- ok(pluginInfo.activated, "Test 21d, Plugin with id=" + id + " should not be activated");
- }
-});
-
-// Tests that a click-to-play plugin resets its activated state when changing types
-add_task(function* () {
- clearAllPluginPermissions();
-
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 22, Should have a click-to-play notification");
-
- // Plugin should start as CTP
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- plugin.type = null;
- // We currently don't properly change state just on type change,
- // so rebind the plugin to tree. bug 767631
- plugin.parentNode.appendChild(plugin);
- });
-
- pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, plugin should be TYPE_NULL");
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let doc = content.document;
- let plugin = doc.getElementById("test");
- plugin.type = "application/x-test";
- plugin.parentNode.appendChild(plugin);
- });
-
- pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.displayedType, Ci.nsIObjectLoadingContent.TYPE_NULL, "Test 23, plugin should be TYPE_NULL");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- "Test 23, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
- ok(!pluginInfo.activated, "Test 23, plugin node should not be activated");
-});
-
-// Plugin sync removal test. Note this test produces a notification drop down since
-// the plugin we add has zero dims.
-add_task(function* () {
- updateAllTestPlugins(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_syncRemoved.html");
-
- // Maybe there some better trick here, we need to wait for the page load, then
- // wait for the js to execute in the page.
- yield waitForMs(500);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins");
- ok(notification, "Test 25: There should be a plugin notification even if the plugin was immediately removed");
- ok(notification.dismissed, "Test 25: The notification should be dismissed by default");
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html,<html>hi</html>");
-});
-
-// Tests a page with a blocked plugin in it and make sure the infoURL property
-// the blocklist file gets used.
-add_task(function* () {
- clearAllPluginPermissions();
-
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockPluginInfoURL.xml", gTestBrowser);
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
-
- // Work around for delayed PluginBindingAttached
- yield promiseUpdatePluginBindings(gTestBrowser);
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins");
-
- // Since the plugin notification is dismissed by default, reshow it.
- yield promiseForNotificationShown(notification);
-
- let pluginInfo = yield promiseForPluginInfo("test");
- is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED,
- "Test 26, plugin fallback type should be PLUGIN_BLOCKLISTED");
- ok(!pluginInfo.activated, "Plugin should be activated.");
-
- const testUrl = "http://test.url.com/";
-
- let firstPanelChild = PopupNotifications.panel.firstChild;
- let infoLink = document.getAnonymousElementByAttribute(firstPanelChild, "anonid",
- "click-to-play-plugins-notification-link");
- is(infoLink.href, testUrl,
- "Test 26, the notification URL needs to match the infoURL from the blocklist file.");
-});
diff --git a/browser/base/content/test/plugins/browser_plugins_added_dynamically.js b/browser/base/content/test/plugins/browser_plugins_added_dynamically.js
deleted file mode 100644
index 22077a54d..000000000
--- a/browser/base/content/test/plugins/browser_plugins_added_dynamically.js
+++ /dev/null
@@ -1,137 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/");
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-var gTestBrowser = null;
-
-add_task(function* () {
- registerCleanupFunction(Task.async(function*() {
- clearAllPluginPermissions();
- Services.prefs.clearUserPref("plugins.click_to_play");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
- yield asyncSetAndUpdateBlocklist(gTestRoot + "blockNoPlugins.xml", gTestBrowser);
- resetBlocklist();
- gBrowser.removeCurrentTab();
- window.focus();
- gTestBrowser = null;
- }));
-});
-
-// "Activate" of a given type -> plugins of that type dynamically added should
-// automatically play.
-add_task(function* () {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
-
- Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
- Services.prefs.setBoolPref("plugins.click_to_play", true);
-
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
- setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
-});
-
-add_task(function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_add_dynamically.html");
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!notification, "Test 1a, Should not have a click-to-play notification");
-
- // Add a plugin of type test
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("pluginone", "application/x-test"));
- });
-
- yield promisePopupNotification("click-to-play-plugins");
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 1a, Should not have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- let centerAction = null;
- for (let action of notification.options.pluginData.values()) {
- if (action.pluginName == "Test") {
- centerAction = action;
- break;
- }
- }
- ok(centerAction, "Test 2, found center action for the Test plugin");
-
- let centerItem = null;
- for (let item of PopupNotifications.panel.firstChild.childNodes) {
- is(item.value, "block", "Test 3, all plugins should start out blocked");
- if (item.action == centerAction) {
- centerItem = item;
- break;
- }
- }
- ok(centerItem, "Test 4, found center item for the Test plugin");
-
- // Select the allow now option in the select drop down for Test Plugin
- centerItem.value = "allownow";
-
- // "click" the button to activate the Test plugin
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- let pluginInfo = yield promiseForPluginInfo("pluginone");
- ok(pluginInfo.activated, "Test 5, plugin should be activated");
-
- // Add another plugin of type test
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("plugintwo", "application/x-test"));
- });
-
- pluginInfo = yield promiseForPluginInfo("plugintwo");
- ok(pluginInfo.activated, "Test 6, plugins should be activated");
-});
-
-// "Activate" of a given type -> plugins of other types dynamically added
-// should not automatically play.
-add_task(function* () {
- clearAllPluginPermissions();
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_add_dynamically.html");
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(!notification, "Test 7, Should not have a click-to-play notification");
-
- // Add a plugin of type test
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("pluginone", "application/x-test"));
- });
-
- yield promisePopupNotification("click-to-play-plugins");
-
- notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(notification, "Test 8, Should not have a click-to-play notification");
-
- yield promiseForNotificationShown(notification);
-
- is(notification.options.pluginData.size, 1, "Should be one plugin action");
-
- let pluginInfo = yield promiseForPluginInfo("pluginone");
- ok(!pluginInfo.activated, "Test 8, test plugin should be activated");
-
- let condition = () => !notification.dismissed &&
- PopupNotifications.panel.firstChild;
- yield promiseForCondition(condition);
-
- // "click" the button to activate the Test plugin
- PopupNotifications.panel.firstChild._primaryButton.click();
-
- pluginInfo = yield promiseForPluginInfo("pluginone");
- ok(pluginInfo.activated, "Test 9, test plugin should be activated");
-
- yield ContentTask.spawn(gTestBrowser, {}, function* () {
- new XPCNativeWrapper(XPCNativeWrapper.unwrap(content).addPlugin("plugintwo", "application/x-second-test"));
- });
-
- yield promisePopupNotification("click-to-play-plugins");
-
- pluginInfo = yield promiseForPluginInfo("pluginone");
- ok(pluginInfo.activated, "Test 10, plugins should be activated");
- pluginInfo = yield promiseForPluginInfo("plugintwo");
- ok(!pluginInfo.activated, "Test 11, plugins should be activated");
-});
diff --git a/browser/base/content/test/plugins/browser_private_clicktoplay.js b/browser/base/content/test/plugins/browser_private_clicktoplay.js
deleted file mode 100644
index 785b1bb31..000000000
--- a/browser/base/content/test/plugins/browser_private_clicktoplay.js
+++ /dev/null
@@ -1,216 +0,0 @@
-var rootDir = getRootDirectory(gTestPath);
-const gTestRoot = rootDir;
-const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-
-var gTestBrowser = null;
-var gNextTest = null;
-var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-var gPrivateWindow = null;
-var gPrivateBrowser = null;
-
-function finishTest() {
- clearAllPluginPermissions();
- gBrowser.removeCurrentTab();
- if (gPrivateWindow) {
- gPrivateWindow.close();
- }
- window.focus();
-}
-
-let createPrivateWindow = Task.async(function* createPrivateWindow(url) {
- gPrivateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- ok(!!gPrivateWindow, "should have created a private window.");
- gPrivateBrowser = gPrivateWindow.getBrowser().selectedBrowser;
-
- BrowserTestUtils.loadURI(gPrivateBrowser, url);
- yield BrowserTestUtils.browserLoaded(gPrivateBrowser);
-});
-
-add_task(function* test() {
- registerCleanupFunction(function() {
- clearAllPluginPermissions();
- getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
- getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
- });
-
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- gTestBrowser = gBrowser.selectedBrowser;
- let promise = BrowserTestUtils.browserLoaded(gTestBrowser);
-
- Services.prefs.setBoolPref("plugins.click_to_play", true);
- getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
- getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
- yield promise;
-});
-
-add_task(function* test1a() {
- yield createPrivateWindow(gHttpTestRoot + "plugin_test.html");
-});
-
-add_task(function* test1b() {
- let popupNotification = gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
- ok(popupNotification, "Test 1b, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gPrivateBrowser, null, function() {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated");
- });
-
- // Check the button status
- let promiseShown = BrowserTestUtils.waitForEvent(gPrivateWindow.PopupNotifications.panel,
- "Shown");
- popupNotification.reshow();
-
- yield promiseShown;
- let button1 = gPrivateWindow.PopupNotifications.panel.firstChild._primaryButton;
- let button2 = gPrivateWindow.PopupNotifications.panel.firstChild._secondaryButton;
- is(button1.getAttribute("action"), "_singleActivateNow", "Test 1b, Blocked plugin in private window should have a activate now button");
- ok(button2.hidden, "Test 1b, Blocked plugin in a private window should not have a secondary button")
-
- gPrivateWindow.close();
- BrowserTestUtils.loadURI(gTestBrowser, gHttpTestRoot + "plugin_test.html");
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* test2a() {
- // enable test plugin on this site
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "Test 2a, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- ok(!objLoadingContent.activated, "Test 2a, Plugin should not be activated");
- });
-
- // Simulate clicking the "Allow Now" button.
- let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
- "Shown");
- popupNotification.reshow();
- yield promiseShown;
-
- PopupNotifications.panel.firstChild._secondaryButton.click();
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- let condition = () => objLoadingContent.activated;
- yield ContentTaskUtils.waitForCondition(condition, "Test 2a, Waited too long for plugin to activate");
- });
-});
-
-add_task(function* test2c() {
- let topicObserved = TestUtils.topicObserved("PopupNotifications-updateNotShowing");
- yield createPrivateWindow(gHttpTestRoot + "plugin_test.html");
- yield topicObserved;
-
- let popupNotification = gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
- ok(popupNotification, "Test 2c, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gPrivateBrowser, null, function() {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- ok(objLoadingContent.activated, "Test 2c, Plugin should be activated");
- });
-
- // Check the button status
- let promiseShown = BrowserTestUtils.waitForEvent(gPrivateWindow.PopupNotifications.panel,
- "Shown");
- popupNotification.reshow();
- yield promiseShown;
- let buttonContainer = gPrivateWindow.PopupNotifications.panel.firstChild._buttonContainer;
- ok(buttonContainer.hidden, "Test 2c, Activated plugin in a private window should not have visible buttons");
-
- clearAllPluginPermissions();
- gPrivateWindow.close();
-
- BrowserTestUtils.loadURI(gTestBrowser, gHttpTestRoot + "plugin_test.html");
- yield BrowserTestUtils.browserLoaded(gTestBrowser);
-});
-
-add_task(function* test3a() {
- // enable test plugin on this site
- let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
- ok(popupNotification, "Test 3a, Should have a click-to-play notification");
-
- yield ContentTask.spawn(gTestBrowser, null, function() {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- ok(!objLoadingContent.activated, "Test 3a, Plugin should not be activated");
- });
-
- // Simulate clicking the "Allow Always" button.
- let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
- "Shown");
- popupNotification.reshow();
- yield promiseShown;
- PopupNotifications.panel.firstChild._secondaryButton.click();
-
- yield ContentTask.spawn(gTestBrowser, null, function* () {
- let plugin = content.document.getElementById("test");
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- let condition = () => objLoadingContent.activated;
- yield ContentTaskUtils.waitForCondition(condition, "Test 3a, Waited too long for plugin to activate");
- });
-});
-
-add_task(function* test3c() {
- let topicObserved = TestUtils.topicObserved("PopupNotifications-updateNotShowing");
- yield createPrivateWindow(gHttpTestRoot + "plugin_test.html");
- yield topicObserved;
-
- let popupNotification = gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
- ok(popupNotification, "Test 3c, Should have a click-to-play notification");
-
- // Check the button status
- let promiseShown = BrowserTestUtils.waitForEvent(gPrivateWindow.PopupNotifications.panel,
- "Shown");
- popupNotification.reshow();
- yield promiseShown;
- let buttonContainer = gPrivateWindow.PopupNotifications.panel.firstChild._buttonContainer;
- ok(buttonContainer.hidden, "Test 3c, Activated plugin in a private window should not have visible buttons");
-
- BrowserTestUtils.loadURI(gPrivateBrowser, gHttpTestRoot + "plugin_two_types.html");
- yield BrowserTestUtils.browserLoaded(gPrivateBrowser);
-});
-
-add_task(function* test3d() {
- let popupNotification = gPrivateWindow.PopupNotifications.getNotification("click-to-play-plugins", gPrivateBrowser);
- ok(popupNotification, "Test 3d, Should have a click-to-play notification");
-
- // Check the list item status
- let promiseShown = BrowserTestUtils.waitForEvent(gPrivateWindow.PopupNotifications.panel,
- "Shown");
- popupNotification.reshow();
- yield promiseShown;
- let doc = gPrivateWindow.document;
- for (let item of gPrivateWindow.PopupNotifications.panel.firstChild.childNodes) {
- let allowalways = doc.getAnonymousElementByAttribute(item, "anonid", "allowalways");
- ok(allowalways, "Test 3d, should have list item for allow always");
- let allownow = doc.getAnonymousElementByAttribute(item, "anonid", "allownow");
- ok(allownow, "Test 3d, should have list item for allow now");
- let block = doc.getAnonymousElementByAttribute(item, "anonid", "block");
- ok(block, "Test 3d, should have list item for block");
-
- if (item.action.pluginName === "Test") {
- is(item.value, "allowalways", "Test 3d, Plugin should bet set to 'allow always'");
- ok(!allowalways.hidden, "Test 3d, Plugin set to 'always allow' should have a visible 'always allow' action.");
- ok(allownow.hidden, "Test 3d, Plugin set to 'always allow' should have an invisible 'allow now' action.");
- ok(block.hidden, "Test 3d, Plugin set to 'always allow' should have an invisible 'block' action.");
- } else if (item.action.pluginName === "Second Test") {
- is(item.value, "block", "Test 3d, Second plugin should bet set to 'block'");
- ok(allowalways.hidden, "Test 3d, Plugin set to 'block' should have a visible 'always allow' action.");
- ok(!allownow.hidden, "Test 3d, Plugin set to 'block' should have a visible 'allow now' action.");
- ok(!block.hidden, "Test 3d, Plugin set to 'block' should have a visible 'block' action.");
- } else {
- ok(false, "Test 3d, Unexpected plugin '"+item.action.pluginName+"'");
- }
- }
-
- finishTest();
-});
diff --git a/browser/base/content/test/plugins/head.js b/browser/base/content/test/plugins/head.js
deleted file mode 100644
index 4995c4dc6..000000000
--- a/browser/base/content/test/plugins/head.js
+++ /dev/null
@@ -1,396 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
- "resource://gre/modules/PromiseUtils.jsm");
-
-// The blocklist shim running in the content process does not initialize at
-// start up, so it's not active until we load content that needs to do a
-// check. This helper bypasses the delay to get the svc up and running
-// immediately. Note, call this after remote content has loaded.
-function promiseInitContentBlocklistSvc(aBrowser)
-{
- return ContentTask.spawn(aBrowser, {}, function* () {
- try {
- Cc["@mozilla.org/extensions/blocklist;1"]
- .getService(Ci.nsIBlocklistService);
- } catch (ex) {
- return ex.message;
- }
- return null;
- });
-}
-
-/**
- * Waits a specified number of miliseconds.
- *
- * Usage:
- * let wait = yield waitForMs(2000);
- * ok(wait, "2 seconds should now have elapsed");
- *
- * @param aMs the number of miliseconds to wait for
- * @returns a Promise that resolves to true after the time has elapsed
- */
-function waitForMs(aMs) {
- return new Promise((resolve) => {
- setTimeout(done, aMs);
- function done() {
- resolve(true);
- }
- });
-}
-
-function waitForEvent(subject, eventName, checkFn, useCapture, useUntrusted) {
- return new Promise((resolve, reject) => {
- subject.addEventListener(eventName, function listener(event) {
- try {
- if (checkFn && !checkFn(event)) {
- return;
- }
- subject.removeEventListener(eventName, listener, useCapture);
- resolve(event);
- } catch (ex) {
- try {
- subject.removeEventListener(eventName, listener, useCapture);
- } catch (ex2) {
- // Maybe the provided object does not support removeEventListener.
- }
- reject(ex);
- }
- }, useCapture, useUntrusted);
- });
-}
-
-
-/**
- * Waits for a load (or custom) event to finish in a given tab. If provided
- * load an uri into the tab.
- *
- * @param tab
- * The tab to load into.
- * @param [optional] url
- * The url to load, or the current url.
- * @return {Promise} resolved when the event is handled.
- * @resolves to the received event
- * @rejects if a valid load event is not received within a meaningful interval
- */
-function promiseTabLoadEvent(tab, url) {
- info("Wait tab event: load");
-
- function handle(loadedUrl) {
- if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
- info(`Skipping spurious load event for ${loadedUrl}`);
- return false;
- }
-
- info("Tab event received: load");
- return true;
- }
-
- let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
-
- if (url)
- BrowserTestUtils.loadURI(tab.linkedBrowser, url);
-
- return loaded;
-}
-
-function waitForCondition(condition, nextTest, errorMsg, aTries, aWait) {
- let tries = 0;
- let maxTries = aTries || 100; // 100 tries
- let maxWait = aWait || 100; // 100 msec x 100 tries = ten seconds
- let interval = setInterval(function() {
- if (tries >= maxTries) {
- ok(false, errorMsg);
- moveOn();
- }
- let conditionPassed;
- try {
- conditionPassed = condition();
- } catch (e) {
- ok(false, e + "\n" + e.stack);
- conditionPassed = false;
- }
- if (conditionPassed) {
- moveOn();
- }
- tries++;
- }, maxWait);
- let moveOn = function() { clearInterval(interval); nextTest(); };
-}
-
-// Waits for a conditional function defined by the caller to return true.
-function promiseForCondition(aConditionFn, aMessage, aTries, aWait) {
- return new Promise((resolve) => {
- waitForCondition(aConditionFn, resolve,
- (aMessage || "Condition didn't pass."),
- aTries, aWait);
- });
-}
-
-// Returns the chrome side nsIPluginTag for this plugin
-function getTestPlugin(aName) {
- let pluginName = aName || "Test Plug-in";
- let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
- let tags = ph.getPluginTags();
-
- // Find the test plugin
- for (let i = 0; i < tags.length; i++) {
- if (tags[i].name == pluginName)
- return tags[i];
- }
- ok(false, "Unable to find plugin");
- return null;
-}
-
-// Set the 'enabledState' on the nsIPluginTag stored in the main or chrome
-// process.
-function setTestPluginEnabledState(newEnabledState, pluginName) {
- let name = pluginName || "Test Plug-in";
- let plugin = getTestPlugin(name);
- plugin.enabledState = newEnabledState;
-}
-
-// Get the 'enabledState' on the nsIPluginTag stored in the main or chrome
-// process.
-function getTestPluginEnabledState(pluginName) {
- let name = pluginName || "Test Plug-in";
- let plugin = getTestPlugin(name);
- return plugin.enabledState;
-}
-
-// Returns a promise for nsIObjectLoadingContent props data.
-function promiseForPluginInfo(aId, aBrowser) {
- let browser = aBrowser || gTestBrowser;
- return ContentTask.spawn(browser, aId, function* (aId) {
- let plugin = content.document.getElementById(aId);
- if (!(plugin instanceof Ci.nsIObjectLoadingContent))
- throw new Error("no plugin found");
- return {
- pluginFallbackType: plugin.pluginFallbackType,
- activated: plugin.activated,
- hasRunningPlugin: plugin.hasRunningPlugin,
- displayedType: plugin.displayedType,
- };
- });
-}
-
-// Return a promise and call the plugin's nsIObjectLoadingContent
-// playPlugin() method.
-function promisePlayObject(aId, aBrowser) {
- let browser = aBrowser || gTestBrowser;
- return ContentTask.spawn(browser, aId, function* (aId) {
- let plugin = content.document.getElementById(aId);
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- objLoadingContent.playPlugin();
- });
-}
-
-function promiseCrashObject(aId, aBrowser) {
- let browser = aBrowser || gTestBrowser;
- return ContentTask.spawn(browser, aId, function* (aId) {
- let plugin = content.document.getElementById(aId);
- Components.utils.waiveXrays(plugin).crash();
- });
-}
-
-// Return a promise and call the plugin's getObjectValue() method.
-function promiseObjectValueResult(aId, aBrowser) {
- let browser = aBrowser || gTestBrowser;
- return ContentTask.spawn(browser, aId, function* (aId) {
- let plugin = content.document.getElementById(aId);
- return Components.utils.waiveXrays(plugin).getObjectValue();
- });
-}
-
-// Return a promise and reload the target plugin in the page
-function promiseReloadPlugin(aId, aBrowser) {
- let browser = aBrowser || gTestBrowser;
- return ContentTask.spawn(browser, aId, function* (aId) {
- let plugin = content.document.getElementById(aId);
- plugin.src = plugin.src;
- });
-}
-
-// after a test is done using the plugin doorhanger, we should just clear
-// any permissions that may have crept in
-function clearAllPluginPermissions() {
- let perms = Services.perms.enumerator;
- while (perms.hasMoreElements()) {
- let perm = perms.getNext();
- if (perm.type.startsWith('plugin')) {
- info("removing permission:" + perm.principal.origin + " " + perm.type + "\n");
- Services.perms.removePermission(perm);
- }
- }
-}
-
-function updateBlocklist(aCallback) {
- let blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
- .getService(Ci.nsITimerCallback);
- let observer = function() {
- Services.obs.removeObserver(observer, "blocklist-updated");
- SimpleTest.executeSoon(aCallback);
- };
- Services.obs.addObserver(observer, "blocklist-updated", false);
- blocklistNotifier.notify(null);
-}
-
-var _originalTestBlocklistURL = null;
-function setAndUpdateBlocklist(aURL, aCallback) {
- if (!_originalTestBlocklistURL) {
- _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
- }
- Services.prefs.setCharPref("extensions.blocklist.url", aURL);
- updateBlocklist(aCallback);
-}
-
-// A generator that insures a new blocklist is loaded (in both
-// processes if applicable).
-function* asyncSetAndUpdateBlocklist(aURL, aBrowser) {
- info("*** loading new blocklist: " + aURL);
- let doTestRemote = aBrowser ? aBrowser.isRemoteBrowser : false;
- if (!_originalTestBlocklistURL) {
- _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
- }
- Services.prefs.setCharPref("extensions.blocklist.url", aURL);
- let localPromise = TestUtils.topicObserved("blocklist-updated");
- let remotePromise;
- if (doTestRemote) {
- remotePromise = TestUtils.topicObserved("content-blocklist-updated");
- }
- let blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
- .getService(Ci.nsITimerCallback);
- blocklistNotifier.notify(null);
- info("*** waiting on local load");
- yield localPromise;
- if (doTestRemote) {
- info("*** waiting on remote load");
- yield remotePromise;
- }
- info("*** blocklist loaded.");
-}
-
-// Reset back to the blocklist we had at the start of the test run.
-function resetBlocklist() {
- Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
-}
-
-// Insure there's a popup notification present. This test does not indicate
-// open state. aBrowser can be undefined.
-function promisePopupNotification(aName, aBrowser) {
- return new Promise((resolve) => {
- waitForCondition(() => PopupNotifications.getNotification(aName, aBrowser),
- () => {
- ok(!!PopupNotifications.getNotification(aName, aBrowser),
- aName + " notification appeared");
-
- resolve();
- }, "timeout waiting for popup notification " + aName);
- });
-}
-
-/**
- * Allows setting focus on a window, and waiting for that window to achieve
- * focus.
- *
- * @param aWindow
- * The window to focus and wait for.
- *
- * @return {Promise}
- * @resolves When the window is focused.
- * @rejects Never.
- */
-function promiseWaitForFocus(aWindow) {
- return new Promise((resolve) => {
- waitForFocus(resolve, aWindow);
- });
-}
-
-/**
- * Returns a Promise that resolves when a notification bar
- * for a browser is shown. Alternatively, for old-style callers,
- * can automatically call a callback before it resolves.
- *
- * @param notificationID
- * The ID of the notification to look for.
- * @param browser
- * The browser to check for the notification bar.
- * @param callback (optional)
- * A function to be called just before the Promise resolves.
- *
- * @return Promise
- */
-function waitForNotificationBar(notificationID, browser, callback) {
- return new Promise((resolve, reject) => {
- let notification;
- let notificationBox = gBrowser.getNotificationBox(browser);
- waitForCondition(
- () => (notification = notificationBox.getNotificationWithValue(notificationID)),
- () => {
- ok(notification, `Successfully got the ${notificationID} notification bar`);
- if (callback) {
- callback(notification);
- }
- resolve(notification);
- },
- `Waited too long for the ${notificationID} notification bar`
- );
- });
-}
-
-function promiseForNotificationBar(notificationID, browser) {
- return new Promise((resolve) => {
- waitForNotificationBar(notificationID, browser, resolve);
- });
-}
-
-/**
- * Reshow a notification and call a callback when it is reshown.
- * @param notification
- * The notification to reshow
- * @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);
- callback();
- }, false);
- notification.reshow();
-}
-
-function promiseForNotificationShown(notification) {
- return new Promise((resolve) => {
- waitForNotificationShown(notification, resolve);
- });
-}
-
-/**
- * Due to layout being async, "PluginBindAttached" may trigger later. This
- * returns a Promise that resolves once we've forced a layout flush, which
- * triggers the PluginBindAttached event to fire. This trick only works if
- * there is some sort of plugin in the page.
- * @param browser
- * The browser to force plugin bindings in.
- * @return Promise
- */
-function promiseUpdatePluginBindings(browser) {
- return ContentTask.spawn(browser, {}, function* () {
- let doc = content.document;
- let elems = doc.getElementsByTagName('embed');
- if (!elems || elems.length < 1) {
- elems = doc.getElementsByTagName('object');
- }
- if (elems && elems.length > 0) {
- elems[0].clientTop;
- }
- });
-}
diff --git a/browser/base/content/test/plugins/plugin_add_dynamically.html b/browser/base/content/test/plugins/plugin_add_dynamically.html
deleted file mode 100644
index 863d36e09..000000000
--- a/browser/base/content/test/plugins/plugin_add_dynamically.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<script>
-function addPlugin(aId, aType="application/x-test") {
- var embed = document.createElement("embed");
- embed.setAttribute("id", aId);
- embed.style.width = "200px";
- embed.style.height = "200px";
- embed.setAttribute("type", aType);
- return document.body.appendChild(embed);
-}
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_alternate_content.html b/browser/base/content/test/plugins/plugin_alternate_content.html
deleted file mode 100644
index f8acc833c..000000000
--- a/browser/base/content/test/plugins/plugin_alternate_content.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!-- bug 739575 -->
-<html>
-<head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<object id="test" type="application/x-test" style="height: 200px; width:200px">
-<p><a href="about:blank">you should not see this link when plugins are click-to-play</a></p>
-</object>
-</body></html>
diff --git a/browser/base/content/test/plugins/plugin_big.html b/browser/base/content/test/plugins/plugin_big.html
deleted file mode 100644
index d11506176..000000000
--- a/browser/base/content/test/plugins/plugin_big.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 500px; height: 500px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_both.html b/browser/base/content/test/plugins/plugin_both.html
deleted file mode 100644
index 2335366dc..000000000
--- a/browser/base/content/test/plugins/plugin_both.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="unknown" style="width: 100px; height: 100px" type="application/x-unknown">
-<embed id="test" style="width: 100px; height: 100px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_both2.html b/browser/base/content/test/plugins/plugin_both2.html
deleted file mode 100644
index ba605d6e8..000000000
--- a/browser/base/content/test/plugins/plugin_both2.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 100px; height: 100px" type="application/x-test">
-<embed id="unknown" style="width: 100px; height: 100px" type="application/x-unknown">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_bug744745.html b/browser/base/content/test/plugins/plugin_bug744745.html
deleted file mode 100644
index d0691c9c0..000000000
--- a/browser/base/content/test/plugins/plugin_bug744745.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><meta charset="utf-8"/></head>
-<body>
-<style>
-.x {
- opacity: 0 !important;
-}
-</style>
-<object id="test" class="x" type="application/x-test" width=200 height=200></object>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_bug749455.html b/browser/base/content/test/plugins/plugin_bug749455.html
deleted file mode 100644
index 831dc82f7..000000000
--- a/browser/base/content/test/plugins/plugin_bug749455.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- bug 749455 -->
-<html>
-<head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<embed src="plugin_bug749455.html" type="application/x-test" width="100px" height="100px"></embed>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_bug787619.html b/browser/base/content/test/plugins/plugin_bug787619.html
deleted file mode 100644
index cb91116f0..000000000
--- a/browser/base/content/test/plugins/plugin_bug787619.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><meta charset="utf-8"/></head>
-<body>
- <a id="wrapper">
- <embed id="plugin" style="width: 200px; height: 200px" type="application/x-test">
- </a>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_bug797677.html b/browser/base/content/test/plugins/plugin_bug797677.html
deleted file mode 100644
index 1545f3647..000000000
--- a/browser/base/content/test/plugins/plugin_bug797677.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><meta charset="utf-8"/></head>
-<body><embed id="plugin" type="9000"></embed></body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_bug820497.html b/browser/base/content/test/plugins/plugin_bug820497.html
deleted file mode 100644
index 4884e9dbe..000000000
--- a/browser/base/content/test/plugins/plugin_bug820497.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><meta charset="utf-8"/></head>
-<body>
-<object id="test" type="application/x-test" width=200 height=200></object>
-<script>
- function addSecondPlugin() {
- var object = document.createElement("object");
- object.type = "application/x-second-test";
- object.width = 200;
- object.height = 200;
- object.id = "secondtest";
- document.body.appendChild(object);
- }
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_clickToPlayAllow.html b/browser/base/content/test/plugins/plugin_clickToPlayAllow.html
deleted file mode 100644
index 3f5df1984..000000000
--- a/browser/base/content/test/plugins/plugin_clickToPlayAllow.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 200px; height: 200px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_clickToPlayDeny.html b/browser/base/content/test/plugins/plugin_clickToPlayDeny.html
deleted file mode 100644
index 3f5df1984..000000000
--- a/browser/base/content/test/plugins/plugin_clickToPlayDeny.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 200px; height: 200px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_crashCommentAndURL.html b/browser/base/content/test/plugins/plugin_crashCommentAndURL.html
deleted file mode 100644
index 711a19ed3..000000000
--- a/browser/base/content/test/plugins/plugin_crashCommentAndURL.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <script type="text/javascript">
- function crash() {
- var plugin = document.getElementById("plugin");
- var argStr = decodeURIComponent(window.location.search.substr(1));
- if (argStr) {
- var args = JSON.parse(argStr);
- for (var key in args)
- plugin.setAttribute(key, args[key]);
- }
- try {
- plugin.crash();
- }
- catch (err) {}
- }
- </script>
- </head>
- <body onload="crash();">
- <embed id="plugin" type="application/x-test"
- width="400" height="400"
- drawmode="solid" color="FF00FFFF">
- </embed>
- </body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_data_url.html b/browser/base/content/test/plugins/plugin_data_url.html
deleted file mode 100644
index 77e101144..000000000
--- a/browser/base/content/test/plugins/plugin_data_url.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-<body>
- <a id="data-link-1" href='data:text/html,<embed id="test" style="width: 200px; height: 200px" type="application/x-test"/>'>
- data: with one plugin
- </a><br />
- <a id="data-link-2" href='data:text/html,<embed id="test1" style="width: 200px; height: 200px" type="application/x-test"/><embed id="test2" style="width: 200px; height: 200px" type="application/x-second-test"/>'>
- data: with two plugins
- </a><br />
- <object id="test" style="width: 200px; height: 200px" type="application/x-test"></object>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_hidden_to_visible.html b/browser/base/content/test/plugins/plugin_hidden_to_visible.html
deleted file mode 100644
index eeacc1874..000000000
--- a/browser/base/content/test/plugins/plugin_hidden_to_visible.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
- <div id="container" style="display: none">
- <object id="test" type="application/x-test" style="width: 200px; height: 200px;"></object>
- </div>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_iframe.html b/browser/base/content/test/plugins/plugin_iframe.html
deleted file mode 100644
index 239c9a771..000000000
--- a/browser/base/content/test/plugins/plugin_iframe.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<iframe id="frame" with="400" height="400" src="plugin_test.html">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_outsideScrollArea.html b/browser/base/content/test/plugins/plugin_outsideScrollArea.html
deleted file mode 100644
index c6ef50d5d..000000000
--- a/browser/base/content/test/plugins/plugin_outsideScrollArea.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<style type="text/css">
-#container {
- position: fixed;
- top: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- background: blue;
-}
-
-#test {
- width: 400px;
- height: 400px;
- position: absolute;
-}
-</style>
-</head>
-<body>
- <div id="container"></div>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_overlayed.html b/browser/base/content/test/plugins/plugin_overlayed.html
deleted file mode 100644
index 11c127093..000000000
--- a/browser/base/content/test/plugins/plugin_overlayed.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<head>
- <meta charset="utf-8">
- <style type="text/css">
- .absthing {
- width: 400px;
- height: 400px;
- position: absolute;
- left: 20px;
- top: 20px;
- }
- #d1 {
- z-index: 1;
- }
- #d2 {
- z-index: 2;
- background-color: rgba(0,0,255,0.5);
- border: 1px solid red;
- }
- </style>
-<body>
- <div class="absthing" id="d1">
- <embed id="test" type="application/x-test">
- </div>
- <div class="absthing" id="d2">
- <p>This is overlaying
- </div>
diff --git a/browser/base/content/test/plugins/plugin_positioned.html b/browser/base/content/test/plugins/plugin_positioned.html
deleted file mode 100644
index 1bad7ee46..000000000
--- a/browser/base/content/test/plugins/plugin_positioned.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<head>
- <meta charset="utf-8">
- <style type="text/css">
- #test {
- position: absolute;
- left: -1000px;
- top: -1000px;
- }
- </style>
-<body>
- <embed id="test" type="application/x-test">
diff --git a/browser/base/content/test/plugins/plugin_small.html b/browser/base/content/test/plugins/plugin_small.html
deleted file mode 100644
index f37ee28c7..000000000
--- a/browser/base/content/test/plugins/plugin_small.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 10px; height: 10px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_small_2.html b/browser/base/content/test/plugins/plugin_small_2.html
deleted file mode 100644
index ebc5ffe84..000000000
--- a/browser/base/content/test/plugins/plugin_small_2.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 10px; height: 10px" type="application/x-second-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_syncRemoved.html b/browser/base/content/test/plugins/plugin_syncRemoved.html
deleted file mode 100644
index d97787056..000000000
--- a/browser/base/content/test/plugins/plugin_syncRemoved.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<body>
-<script type="text/javascript">
- // create an embed, insert it in the doc and immediately remove it
- var embed = document.createElement('embed');
- embed.setAttribute("id", "test");
- embed.setAttribute("type", "application/x-test");
- embed.setAttribute("style", "width: 0px; height: 0px;");
- document.body.appendChild(embed);
- window.getComputedStyle(embed, null).top;
- document.body.remove(embed);
-</script>
diff --git a/browser/base/content/test/plugins/plugin_test.html b/browser/base/content/test/plugins/plugin_test.html
deleted file mode 100644
index d4b5b6ca7..000000000
--- a/browser/base/content/test/plugins/plugin_test.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 200px; height: 200px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_test2.html b/browser/base/content/test/plugins/plugin_test2.html
deleted file mode 100644
index 95614c930..000000000
--- a/browser/base/content/test/plugins/plugin_test2.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test1" style="width: 200px; height: 200px" type="application/x-test">
-<embed id="test2" style="width: 200px; height: 200px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_test3.html b/browser/base/content/test/plugins/plugin_test3.html
deleted file mode 100644
index 215c02326..000000000
--- a/browser/base/content/test/plugins/plugin_test3.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="test" style="width: 0px; height: 0px" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_two_types.html b/browser/base/content/test/plugins/plugin_two_types.html
deleted file mode 100644
index 2359d2ec1..000000000
--- a/browser/base/content/test/plugins/plugin_two_types.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><meta charset="utf-8"/></head>
-<body>
-<embed id="test" style="width: 200px; height: 200px" type="application/x-test"/>
-<embed id="secondtestA" style="width: 200px; height: 200px" type="application/x-second-test"/>
-<embed id="secondtestB" style="width: 200px; height: 200px" type="application/x-second-test"/>
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_unknown.html b/browser/base/content/test/plugins/plugin_unknown.html
deleted file mode 100644
index 578f455cc..000000000
--- a/browser/base/content/test/plugins/plugin_unknown.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<embed id="unknown" style="width: 100px; height: 100px" type="application/x-unknown">
-</body>
-</html>
diff --git a/browser/base/content/test/plugins/plugin_zoom.html b/browser/base/content/test/plugins/plugin_zoom.html
deleted file mode 100644
index f9e598658..000000000
--- a/browser/base/content/test/plugins/plugin_zoom.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-</head>
-<body>
-<!-- The odd width and height are here to trigger bug 972237. -->
-<embed id="test" style="width: 99.789%; height: 99.123%" type="application/x-test">
-</body>
-</html>
diff --git a/browser/base/content/test/popupNotifications/.eslintrc.js b/browser/base/content/test/popupNotifications/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/popupNotifications/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/popupNotifications/browser.ini b/browser/base/content/test/popupNotifications/browser.ini
deleted file mode 100644
index 83bb7c517..000000000
--- a/browser/base/content/test/popupNotifications/browser.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
-
-[browser_displayURI.js]
-skip-if = (os == "linux" && (debug || asan))
-[browser_popupNotification.js]
-skip-if = (os == "linux" && (debug || asan))
-[browser_popupNotification_2.js]
-skip-if = (os == "linux" && (debug || asan))
-[browser_popupNotification_3.js]
-skip-if = (os == "linux" && (debug || asan))
-[browser_popupNotification_4.js]
-skip-if = (os == "linux" && (debug || asan))
-[browser_popupNotification_checkbox.js]
-skip-if = (os == "linux" && (debug || asan))
-[browser_reshow_in_background.js]
-skip-if = (os == "linux" && (debug || asan))
diff --git a/browser/base/content/test/popupNotifications/browser_displayURI.js b/browser/base/content/test/popupNotifications/browser_displayURI.js
deleted file mode 100644
index 48222be19..000000000
--- a/browser/base/content/test/popupNotifications/browser_displayURI.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Make sure that the origin is shown for ContentPermissionPrompt
- * consumers e.g. geolocation.
-*/
-
-add_task(function* test_displayURI() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "https://test1.example.com/",
- }, function*(browser) {
- let popupShownPromise = new Promise((resolve, reject) => {
- onPopupEvent("popupshown", function() {
- resolve(this);
- });
- });
- yield ContentTask.spawn(browser, null, function*() {
- content.navigator.geolocation.getCurrentPosition(function (pos) {
- // Do nothing
- });
- });
- let panel = yield popupShownPromise;
- let notification = panel.children[0];
- let body = document.getAnonymousElementByAttribute(notification,
- "class",
- "popup-notification-body");
- ok(body.innerHTML.includes("example.com"), "Check that at least the eTLD+1 is present in the markup");
- });
-});
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification.js b/browser/base/content/test/popupNotifications/browser_popupNotification.js
deleted file mode 100644
index 6be3e4205..000000000
--- a/browser/base/content/test/popupNotifications/browser_popupNotification.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// These are shared between test #4 to #5
-var wrongBrowserNotificationObject = new BasicNotification("wrongBrowser");
-var wrongBrowserNotification;
-
-function test() {
- waitForExplicitFinish();
-
- ok(PopupNotifications, "PopupNotifications object exists");
- ok(PopupNotifications.panel, "PopupNotifications panel exists");
-
- setup();
- goNext();
-}
-
-var tests = [
- { id: "Test#1",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- triggerMainCommand(popup);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.mainActionClicked, "mainAction was clicked");
- ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- { id: "Test#2",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- triggerSecondaryCommand(popup, 0);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked");
- ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- { id: "Test#3",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
- this.notification.remove();
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // test opening a notification for a background browser
- // Note: test 4 to 6 share a tab.
- { id: "Test#4",
- run: function* () {
- let tab = gBrowser.addTab("about:blank");
- isnot(gBrowser.selectedTab, tab, "new tab isn't selected");
- wrongBrowserNotificationObject.browser = gBrowser.getBrowserForTab(tab);
- let promiseTopic = promiseTopicObserved("PopupNotifications-backgroundShow");
- wrongBrowserNotification = showNotification(wrongBrowserNotificationObject);
- yield promiseTopic;
- is(PopupNotifications.isPanelOpen, false, "panel isn't open");
- ok(!wrongBrowserNotificationObject.mainActionClicked, "main action wasn't clicked");
- ok(!wrongBrowserNotificationObject.secondaryActionClicked, "secondary action wasn't clicked");
- ok(!wrongBrowserNotificationObject.dismissalCallbackTriggered, "dismissal callback wasn't called");
- goNext();
- }
- },
- // now select that browser and test to see that the notification appeared
- { id: "Test#5",
- run: function () {
- this.oldSelectedTab = gBrowser.selectedTab;
- gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1];
- },
- onShown: function (popup) {
- checkPopup(popup, wrongBrowserNotificationObject);
- is(PopupNotifications.isPanelOpen, true, "isPanelOpen getter doesn't lie");
-
- // switch back to the old browser
- gBrowser.selectedTab = this.oldSelectedTab;
- },
- onHidden: function (popup) {
- // actually remove the notification to prevent it from reappearing
- ok(wrongBrowserNotificationObject.dismissalCallbackTriggered, "dismissal callback triggered due to tab switch");
- wrongBrowserNotification.remove();
- ok(wrongBrowserNotificationObject.removedCallbackTriggered, "removed callback triggered");
- wrongBrowserNotification = null;
- }
- },
- // test that the removed notification isn't shown on browser re-select
- { id: "Test#6",
- run: function* () {
- let promiseTopic = promiseTopicObserved("PopupNotifications-updateNotShowing");
- gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1];
- yield promiseTopic;
- is(PopupNotifications.isPanelOpen, false, "panel isn't open");
- gBrowser.removeTab(gBrowser.selectedTab);
- goNext();
- }
- },
- // Test that two notifications with the same ID result in a single displayed
- // notification.
- { id: "Test#7",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- // Show the same notification twice
- this.notification1 = showNotification(this.notifyObj);
- this.notification2 = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- this.notification2.remove();
- },
- onHidden: function (popup) {
- ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test that two notifications with different IDs are displayed
- { id: "Test#8",
- run: function () {
- this.testNotif1 = new BasicNotification(this.id);
- this.testNotif1.message += " 1";
- showNotification(this.testNotif1);
- this.testNotif2 = new BasicNotification(this.id);
- this.testNotif2.message += " 2";
- this.testNotif2.id += "-2";
- showNotification(this.testNotif2);
- },
- onShown: function (popup) {
- is(popup.childNodes.length, 2, "two notifications are shown");
- // Trigger the main command for the first notification, and the secondary
- // for the second. Need to do mainCommand first since the secondaryCommand
- // triggering is async.
- triggerMainCommand(popup);
- is(popup.childNodes.length, 1, "only one notification left");
- triggerSecondaryCommand(popup, 0);
- },
- onHidden: function (popup) {
- ok(this.testNotif1.mainActionClicked, "main action #1 was clicked");
- ok(!this.testNotif1.secondaryActionClicked, "secondary action #1 wasn't clicked");
- ok(!this.testNotif1.dismissalCallbackTriggered, "dismissal callback #1 wasn't called");
-
- ok(!this.testNotif2.mainActionClicked, "main action #2 wasn't clicked");
- ok(this.testNotif2.secondaryActionClicked, "secondary action #2 was clicked");
- ok(!this.testNotif2.dismissalCallbackTriggered, "dismissal callback #2 wasn't called");
- }
- },
- // Test notification without mainAction
- { id: "Test#9",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.mainAction = null;
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- this.notification.remove();
- }
- },
- // Test two notifications with different anchors
- { id: "Test#10",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.firstNotification = showNotification(this.notifyObj);
- this.notifyObj2 = new BasicNotification(this.id);
- this.notifyObj2.id += "-2";
- this.notifyObj2.anchorID = "addons-notification-icon";
- // Second showNotification() overrides the first
- this.secondNotification = showNotification(this.notifyObj2);
- },
- onShown: function (popup) {
- // This also checks that only one element is shown.
- checkPopup(popup, this.notifyObj2);
- is(document.getElementById("geo-notification-icon").boxObject.width, 0,
- "geo anchor shouldn't be visible");
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- // Remove the notifications
- this.firstNotification.remove();
- this.secondNotification.remove();
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- ok(this.notifyObj2.removedCallbackTriggered, "removed callback triggered");
- }
- }
-];
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
deleted file mode 100644
index d77098895..000000000
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
+++ /dev/null
@@ -1,266 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- ok(PopupNotifications, "PopupNotifications object exists");
- ok(PopupNotifications.panel, "PopupNotifications panel exists");
-
- setup();
- goNext();
-}
-
-var tests = [
- // Test optional params
- { id: "Test#1",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.secondaryActions = undefined;
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
- this.notification.remove();
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test that icons appear
- { id: "Test#2",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.id = "geolocation";
- this.notifyObj.anchorID = "geo-notification-icon";
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
- "geo anchor should be visible");
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- let icon = document.getElementById("geo-notification-icon");
- isnot(icon.boxObject.width, 0,
- "geo anchor should be visible after dismissal");
- this.notification.remove();
- is(icon.boxObject.width, 0,
- "geo anchor should not be visible after removal");
- }
- },
-
- // Test that persistence allows the notification to persist across reloads
- { id: "Test#3",
- run: function* () {
- this.oldSelectedTab = gBrowser.selectedTab;
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.addOptions({
- persistence: 2
- });
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- this.complete = false;
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/")
- // Next load will remove the notification
- this.complete = true;
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
- },
- onHidden: function (popup) {
- ok(this.complete, "Should only have hidden the notification after 3 page loads");
- ok(this.notifyObj.removedCallbackTriggered, "removal callback triggered");
- gBrowser.removeTab(gBrowser.selectedTab);
- gBrowser.selectedTab = this.oldSelectedTab;
- }
- },
- // Test that a timeout allows the notification to persist across reloads
- { id: "Test#4",
- run: function* () {
- this.oldSelectedTab = gBrowser.selectedTab;
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- this.notifyObj = new BasicNotification(this.id);
- // Set a timeout of 10 minutes that should never be hit
- this.notifyObj.addOptions({
- timeout: Date.now() + 600000
- });
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- this.complete = false;
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- // Next load will hide the notification
- this.notification.options.timeout = Date.now() - 1;
- this.complete = true;
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
- },
- onHidden: function (popup) {
- ok(this.complete, "Should only have hidden the notification after the timeout was passed");
- this.notification.remove();
- gBrowser.removeTab(gBrowser.selectedTab);
- gBrowser.selectedTab = this.oldSelectedTab;
- }
- },
- // Test that setting persistWhileVisible allows a visible notification to
- // persist across location changes
- { id: "Test#5",
- run: function* () {
- this.oldSelectedTab = gBrowser.selectedTab;
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.addOptions({
- persistWhileVisible: true
- });
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- this.complete = false;
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- // Notification should persist across location changes
- this.complete = true;
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- ok(this.complete, "Should only have hidden the notification after it was dismissed");
- this.notification.remove();
- gBrowser.removeTab(gBrowser.selectedTab);
- gBrowser.selectedTab = this.oldSelectedTab;
- }
- },
-
- // Test that nested icon nodes correctly activate popups
- { id: "Test#6",
- run: function() {
- // Add a temporary box as the anchor with a button
- this.box = document.createElement("box");
- PopupNotifications.iconBox.appendChild(this.box);
-
- let button = document.createElement("button");
- button.setAttribute("label", "Please click me!");
- this.box.appendChild(button);
-
- // The notification should open up on the box
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.anchorID = this.box.id = "nested-box";
- this.notifyObj.addOptions({dismissed: true});
- this.notification = showNotification(this.notifyObj);
-
- // This test places a normal button in the notification area, which has
- // standard GTK styling and dimensions. Due to the clip-path, this button
- // gets clipped off, which makes it necessary to synthesize the mouse click
- // a little bit downward. To be safe, I adjusted the x-offset with the same
- // amount.
- EventUtils.synthesizeMouse(button, 4, 4, {});
- },
- onShown: function(popup) {
- checkPopup(popup, this.notifyObj);
- dismissNotification(popup);
- },
- onHidden: function(popup) {
- this.notification.remove();
- this.box.parentNode.removeChild(this.box);
- }
- },
- // Test that popupnotifications without popups have anchor icons shown
- { id: "Test#7",
- run: function* () {
- let notifyObj = new BasicNotification(this.id);
- notifyObj.anchorID = "geo-notification-icon";
- notifyObj.addOptions({neverShow: true});
- let promiseTopic = promiseTopicObserved("PopupNotifications-updateNotShowing");
- showNotification(notifyObj);
- yield promiseTopic;
- isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
- "geo anchor should be visible");
- goNext();
- }
- },
- // Test notification "Not Now" menu item
- { id: "Test#8",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- triggerSecondaryCommand(popup, 1);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
- this.notification.remove();
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test notification close button
- { id: "Test#9",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
- this.notification.remove();
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test notification when chrome is hidden
- { id: "Test#10",
- run: function () {
- window.locationbar.visible = false;
- this.notifyObj = new BasicNotification(this.id);
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- is(popup.anchorNode.className, "tabbrowser-tab", "notification anchored to tab");
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
- this.notification.remove();
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- window.locationbar.visible = true;
- }
- },
- // Test that dismissed popupnotifications can be opened on about:blank
- // (where the rest of the identity block is disabled)
- { id: "Test#11",
- run: function() {
- this.oldSelectedTab = gBrowser.selectedTab;
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
-
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.anchorID = "geo-notification-icon";
- this.notifyObj.addOptions({dismissed: true});
- this.notification = showNotification(this.notifyObj);
-
- EventUtils.synthesizeMouse(document.getElementById("geo-notification-icon"), 0, 0, {});
- },
- onShown: function(popup) {
- checkPopup(popup, this.notifyObj);
- dismissNotification(popup);
- },
- onHidden: function(popup) {
- this.notification.remove();
- gBrowser.removeTab(gBrowser.selectedTab);
- gBrowser.selectedTab = this.oldSelectedTab;
- }
- }
-];
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_3.js b/browser/base/content/test/popupNotifications/browser_popupNotification_3.js
deleted file mode 100644
index 33ec3f714..000000000
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_3.js
+++ /dev/null
@@ -1,305 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- ok(PopupNotifications, "PopupNotifications object exists");
- ok(PopupNotifications.panel, "PopupNotifications panel exists");
-
- setup();
- goNext();
-}
-
-var tests = [
- // Test notification is removed when dismissed if removeOnDismissal is true
- { id: "Test#1",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.addOptions({
- removeOnDismissal: true
- });
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test multiple notification icons are shown
- { id: "Test#2",
- run: function () {
- this.notifyObj1 = new BasicNotification(this.id);
- this.notifyObj1.id += "_1";
- this.notifyObj1.anchorID = "default-notification-icon";
- this.notification1 = showNotification(this.notifyObj1);
-
- this.notifyObj2 = new BasicNotification(this.id);
- this.notifyObj2.id += "_2";
- this.notifyObj2.anchorID = "geo-notification-icon";
- this.notification2 = showNotification(this.notifyObj2);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj2);
-
- // check notifyObj1 anchor icon is showing
- isnot(document.getElementById("default-notification-icon").boxObject.width, 0,
- "default anchor should be visible");
- // check notifyObj2 anchor icon is showing
- isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
- "geo anchor should be visible");
-
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- this.notification1.remove();
- ok(this.notifyObj1.removedCallbackTriggered, "removed callback triggered");
-
- this.notification2.remove();
- ok(this.notifyObj2.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test that multiple notification icons are removed when switching tabs
- { id: "Test#3",
- run: function () {
- // show the notification on old tab.
- this.notifyObjOld = new BasicNotification(this.id);
- this.notifyObjOld.anchorID = "default-notification-icon";
- this.notificationOld = showNotification(this.notifyObjOld);
-
- // switch tab
- this.oldSelectedTab = gBrowser.selectedTab;
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
-
- // show the notification on new tab.
- this.notifyObjNew = new BasicNotification(this.id);
- this.notifyObjNew.anchorID = "geo-notification-icon";
- this.notificationNew = showNotification(this.notifyObjNew);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObjNew);
-
- // check notifyObjOld anchor icon is removed
- is(document.getElementById("default-notification-icon").boxObject.width, 0,
- "default anchor shouldn't be visible");
- // check notifyObjNew anchor icon is showing
- isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
- "geo anchor should be visible");
-
- dismissNotification(popup);
- },
- onHidden: function (popup) {
- this.notificationNew.remove();
- gBrowser.removeTab(gBrowser.selectedTab);
-
- gBrowser.selectedTab = this.oldSelectedTab;
- this.notificationOld.remove();
- }
- },
- // test security delay - too early
- { id: "Test#4",
- run: function () {
- // Set the security delay to 100s
- PopupNotifications.buttonDelay = 100000;
-
- this.notifyObj = new BasicNotification(this.id);
- showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- triggerMainCommand(popup);
-
- // Wait to see if the main command worked
- executeSoon(function delayedDismissal() {
- dismissNotification(popup);
- });
-
- },
- onHidden: function (popup) {
- ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked because it was too soon");
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback was triggered");
- }
- },
- // test security delay - after delay
- { id: "Test#5",
- run: function () {
- // Set the security delay to 10ms
- PopupNotifications.buttonDelay = 10;
-
- this.notifyObj = new BasicNotification(this.id);
- showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
-
- // Wait until after the delay to trigger the main action
- setTimeout(function delayedDismissal() {
- triggerMainCommand(popup);
- }, 500);
-
- },
- onHidden: function (popup) {
- ok(this.notifyObj.mainActionClicked, "mainAction was clicked after the delay");
- ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback was not triggered");
- PopupNotifications.buttonDelay = PREF_SECURITY_DELAY_INITIAL;
- }
- },
- // reload removes notification
- { id: "Test#6",
- run: function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- let notifyObj = new BasicNotification(this.id);
- notifyObj.options.eventCallback = function (eventName) {
- if (eventName == "removed") {
- ok(true, "Notification removed in background tab after reloading");
- goNext();
- }
- };
- showNotification(notifyObj);
- executeSoon(function () {
- gBrowser.selectedBrowser.reload();
- });
- }
- },
- // location change in background tab removes notification
- { id: "Test#7",
- run: function* () {
- let oldSelectedTab = gBrowser.selectedTab;
- let newTab = gBrowser.addTab("about:blank");
- gBrowser.selectedTab = newTab;
-
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- gBrowser.selectedTab = oldSelectedTab;
- let browser = gBrowser.getBrowserForTab(newTab);
-
- let notifyObj = new BasicNotification(this.id);
- notifyObj.browser = browser;
- notifyObj.options.eventCallback = function (eventName) {
- if (eventName == "removed") {
- ok(true, "Notification removed in background tab after reloading");
- executeSoon(function () {
- gBrowser.removeTab(newTab);
- goNext();
- });
- }
- };
- showNotification(notifyObj);
- executeSoon(function () {
- browser.reload();
- });
- }
- },
- // Popup notification anchor shouldn't disappear when a notification with the same ID is re-added in a background tab
- { id: "Test#8",
- run: function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- let originalTab = gBrowser.selectedTab;
- let bgTab = gBrowser.addTab("about:blank");
- gBrowser.selectedTab = bgTab;
- yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
- let anchor = document.createElement("box");
- anchor.id = "test26-anchor";
- anchor.className = "notification-anchor-icon";
- PopupNotifications.iconBox.appendChild(anchor);
-
- gBrowser.selectedTab = originalTab;
-
- let fgNotifyObj = new BasicNotification(this.id);
- fgNotifyObj.anchorID = anchor.id;
- fgNotifyObj.options.dismissed = true;
- let fgNotification = showNotification(fgNotifyObj);
-
- let bgNotifyObj = new BasicNotification(this.id);
- bgNotifyObj.anchorID = anchor.id;
- bgNotifyObj.browser = gBrowser.getBrowserForTab(bgTab);
- // show the notification in the background tab ...
- let bgNotification = showNotification(bgNotifyObj);
- // ... and re-show it
- bgNotification = showNotification(bgNotifyObj);
-
- ok(fgNotification.id, "notification has id");
- is(fgNotification.id, bgNotification.id, "notification ids are the same");
- is(anchor.getAttribute("showing"), "true", "anchor still showing");
-
- fgNotification.remove();
- gBrowser.removeTab(bgTab);
- goNext();
- }
- },
- // location change in an embedded frame should not remove a notification
- { id: "Test#9",
- run: function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "data:text/html;charset=utf8,<iframe%20id='iframe'%20src='http://example.com/'>");
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.eventCallback = function (eventName) {
- if (eventName == "removed") {
- ok(false, "Notification removed from browser when subframe navigated");
- }
- };
- showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- let self = this;
- let progressListener = {
- onLocationChange: function onLocationChange() {
- gBrowser.removeProgressListener(progressListener);
-
- executeSoon(() => {
- let notification = PopupNotifications.getNotification(self.notifyObj.id,
- self.notifyObj.browser);
- ok(notification != null, "Notification remained when subframe navigated");
- self.notifyObj.options.eventCallback = undefined;
-
- notification.remove();
- });
- },
- };
-
- info("Adding progress listener and performing navigation");
- gBrowser.addProgressListener(progressListener);
- ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
- content.document.getElementById("iframe")
- .setAttribute("src", "http://example.org/");
- });
- },
- onHidden: function () {}
- },
- // Popup Notifications should catch exceptions from callbacks
- { id: "Test#10",
- run: function () {
- this.testNotif1 = new BasicNotification(this.id);
- this.testNotif1.message += " 1";
- this.notification1 = showNotification(this.testNotif1);
- this.testNotif1.options.eventCallback = function (eventName) {
- info("notifyObj1.options.eventCallback: " + eventName);
- if (eventName == "dismissed") {
- throw new Error("Oops 1!");
- }
- };
-
- this.testNotif2 = new BasicNotification(this.id);
- this.testNotif2.message += " 2";
- this.testNotif2.id += "-2";
- this.testNotif2.options.eventCallback = function (eventName) {
- info("notifyObj2.options.eventCallback: " + eventName);
- if (eventName == "dismissed") {
- throw new Error("Oops 2!");
- }
- };
- this.notification2 = showNotification(this.testNotif2);
- },
- onShown: function (popup) {
- is(popup.childNodes.length, 2, "two notifications are shown");
- dismissNotification(popup);
- },
- onHidden: function () {
- this.notification1.remove();
- this.notification2.remove();
- }
- }
-];
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js b/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
deleted file mode 100644
index 750ad82fd..000000000
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
+++ /dev/null
@@ -1,294 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- ok(PopupNotifications, "PopupNotifications object exists");
- ok(PopupNotifications.panel, "PopupNotifications panel exists");
-
- setup();
- goNext();
-}
-
-var tests = [
- // Popup Notifications main actions should catch exceptions from callbacks
- { id: "Test#1",
- run: function () {
- this.testNotif = new ErrorNotification();
- showNotification(this.testNotif);
- },
- onShown: function (popup) {
- checkPopup(popup, this.testNotif);
- triggerMainCommand(popup);
- },
- onHidden: function (popup) {
- ok(this.testNotif.mainActionClicked, "main action has been triggered");
- }
- },
- // Popup Notifications secondary actions should catch exceptions from callbacks
- { id: "Test#2",
- run: function () {
- this.testNotif = new ErrorNotification();
- showNotification(this.testNotif);
- },
- onShown: function (popup) {
- checkPopup(popup, this.testNotif);
- triggerSecondaryCommand(popup, 0);
- },
- onHidden: function (popup) {
- ok(this.testNotif.secondaryActionClicked, "secondary action has been triggered");
- }
- },
- // Existing popup notification shouldn't disappear when adding a dismissed notification
- { id: "Test#3",
- run: function () {
- this.notifyObj1 = new BasicNotification(this.id);
- this.notifyObj1.id += "_1";
- this.notifyObj1.anchorID = "default-notification-icon";
- this.notification1 = showNotification(this.notifyObj1);
- },
- onShown: function (popup) {
- // Now show a dismissed notification, and check that it doesn't clobber
- // the showing one.
- this.notifyObj2 = new BasicNotification(this.id);
- this.notifyObj2.id += "_2";
- this.notifyObj2.anchorID = "geo-notification-icon";
- this.notifyObj2.options.dismissed = true;
- this.notification2 = showNotification(this.notifyObj2);
-
- checkPopup(popup, this.notifyObj1);
-
- // check that both anchor icons are showing
- is(document.getElementById("default-notification-icon").getAttribute("showing"), "true",
- "notification1 anchor should be visible");
- is(document.getElementById("geo-notification-icon").getAttribute("showing"), "true",
- "notification2 anchor should be visible");
-
- dismissNotification(popup);
- },
- onHidden: function(popup) {
- this.notification1.remove();
- this.notification2.remove();
- }
- },
- // Showing should be able to modify the popup data
- { id: "Test#4",
- run: function() {
- this.notifyObj = new BasicNotification(this.id);
- let normalCallback = this.notifyObj.options.eventCallback;
- this.notifyObj.options.eventCallback = function (eventName) {
- if (eventName == "showing") {
- this.mainAction.label = "Alternate Label";
- }
- normalCallback.call(this, eventName);
- };
- showNotification(this.notifyObj);
- },
- onShown: function(popup) {
- // checkPopup checks for the matching label. Note that this assumes that
- // this.notifyObj.mainAction is the same as notification.mainAction,
- // which could be a problem if we ever decided to deep-copy.
- checkPopup(popup, this.notifyObj);
- triggerMainCommand(popup);
- },
- onHidden: function() { }
- },
- // Moving a tab to a new window should remove non-swappable notifications.
- { id: "Test#5",
- run: function() {
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- let notifyObj = new BasicNotification(this.id);
- showNotification(notifyObj);
- let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
- whenDelayedStartupFinished(win, function() {
- let anchor = win.document.getElementById("default-notification-icon");
- win.PopupNotifications._reshowNotifications(anchor);
- ok(win.PopupNotifications.panel.childNodes.length == 0,
- "no notification displayed in new window");
- ok(notifyObj.swappingCallbackTriggered, "the swapping callback was triggered");
- ok(notifyObj.removedCallbackTriggered, "the removed callback was triggered");
- win.close();
- goNext();
- });
- }
- },
- // Moving a tab to a new window should preserve swappable notifications.
- { id: "Test#6",
- run: function* () {
- let originalBrowser = gBrowser.selectedBrowser;
- let originalWindow = window;
-
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- let notifyObj = new BasicNotification(this.id);
- let originalCallback = notifyObj.options.eventCallback;
- notifyObj.options.eventCallback = function (eventName) {
- originalCallback(eventName);
- return eventName == "swapping";
- };
-
- let notification = showNotification(notifyObj);
- let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
- yield whenDelayedStartupFinished(win);
-
- yield new Promise(resolve => {
- let originalCallback = notification.options.eventCallback;
- notification.options.eventCallback = function (eventName) {
- originalCallback(eventName);
- if (eventName == "shown") {
- resolve();
- }
- };
- info("Showing the notification again");
- notification.reshow();
- });
-
- checkPopup(win.PopupNotifications.panel, notifyObj);
- ok(notifyObj.swappingCallbackTriggered, "the swapping callback was triggered");
- yield BrowserTestUtils.closeWindow(win);
-
- // These are the same checks that PopupNotifications.jsm makes before it
- // allows a notification to open. Do not go to the next test until we are
- // sure that its attempt to display a notification will not fail.
- yield BrowserTestUtils.waitForCondition(() => originalBrowser.docShellIsActive,
- "The browser should be active");
- let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
- yield BrowserTestUtils.waitForCondition(() => fm.activeWindow == originalWindow,
- "The window should be active")
-
- goNext();
- }
- },
- // the hideNotNow option
- { id: "Test#7",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.hideNotNow = true;
- this.notifyObj.mainAction.dismiss = true;
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- // checkPopup verifies that the Not Now item is hidden, and that no separator is added.
- checkPopup(popup, this.notifyObj);
- triggerMainCommand(popup);
- },
- onHidden: function (popup) {
- this.notification.remove();
- }
- },
- // the main action callback can keep the notification.
- { id: "Test#8",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.mainAction.dismiss = true;
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- triggerMainCommand(popup);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback was triggered");
- ok(!this.notifyObj.removedCallbackTriggered, "removed callback wasn't triggered");
- this.notification.remove();
- }
- },
- // a secondary action callback can keep the notification.
- { id: "Test#9",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.secondaryActions[0].dismiss = true;
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- triggerSecondaryCommand(popup, 0);
- },
- onHidden: function (popup) {
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback was triggered");
- ok(!this.notifyObj.removedCallbackTriggered, "removed callback wasn't triggered");
- this.notification.remove();
- }
- },
- // returning true in the showing callback should dismiss the notification.
- { id: "Test#10",
- run: function() {
- let notifyObj = new BasicNotification(this.id);
- let originalCallback = notifyObj.options.eventCallback;
- notifyObj.options.eventCallback = function (eventName) {
- originalCallback(eventName);
- return eventName == "showing";
- };
-
- let notification = showNotification(notifyObj);
- ok(notifyObj.showingCallbackTriggered, "the showing callback was triggered");
- ok(!notifyObj.shownCallbackTriggered, "the shown callback wasn't triggered");
- notification.remove();
- goNext();
- }
- },
- // panel updates should fire the showing and shown callbacks again.
- { id: "Test#11",
- run: function() {
- this.notifyObj = new BasicNotification(this.id);
- this.notification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
-
- this.notifyObj.showingCallbackTriggered = false;
- this.notifyObj.shownCallbackTriggered = false;
-
- // Force an update of the panel. This is typically called
- // automatically when receiving 'activate' or 'TabSelect' events,
- // but from a setTimeout, which is inconvenient for the test.
- PopupNotifications._update();
-
- checkPopup(popup, this.notifyObj);
-
- this.notification.remove();
- },
- onHidden: function() { }
- },
- // A first dismissed notification shouldn't stop _update from showing a second notification
- { id: "Test#12",
- run: function () {
- this.notifyObj1 = new BasicNotification(this.id);
- this.notifyObj1.id += "_1";
- this.notifyObj1.anchorID = "default-notification-icon";
- this.notifyObj1.options.dismissed = true;
- this.notification1 = showNotification(this.notifyObj1);
-
- this.notifyObj2 = new BasicNotification(this.id);
- this.notifyObj2.id += "_2";
- this.notifyObj2.anchorID = "geo-notification-icon";
- this.notifyObj2.options.dismissed = true;
- this.notification2 = showNotification(this.notifyObj2);
-
- this.notification2.dismissed = false;
- PopupNotifications._update();
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj2);
- this.notification1.remove();
- this.notification2.remove();
- },
- onHidden: function(popup) { }
- },
- // The anchor icon should be shown for notifications in background windows.
- { id: "Test#13",
- run: function() {
- let notifyObj = new BasicNotification(this.id);
- notifyObj.options.dismissed = true;
- let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
- whenDelayedStartupFinished(win, function() {
- showNotification(notifyObj);
- let anchor = document.getElementById("default-notification-icon");
- is(anchor.getAttribute("showing"), "true", "the anchor is shown");
- win.close();
- goNext();
- });
- }
- }
-];
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_checkbox.js b/browser/base/content/test/popupNotifications/browser_popupNotification_checkbox.js
deleted file mode 100644
index bcc51fcd7..000000000
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_checkbox.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- ok(PopupNotifications, "PopupNotifications object exists");
- ok(PopupNotifications.panel, "PopupNotifications panel exists");
-
- setup();
- goNext();
-}
-
-function checkCheckbox(checkbox, label, checked=false, hidden=false) {
- is(checkbox.label, label, "Checkbox should have the correct label");
- is(checkbox.hidden, hidden, "Checkbox should be shown");
- is(checkbox.checked, checked, "Checkbox should be checked by default");
-}
-
-function checkMainAction(notification, disabled=false) {
- let mainAction = notification.button;
- let warningLabel = document.getAnonymousElementByAttribute(notification, "class", "popup-notification-warning");
- is(warningLabel.hidden, !disabled, "Warning label should be shown");
- is(mainAction.disabled, disabled, "MainAction should be disabled");
-}
-
-function promiseElementVisible(element) {
- // HTMLElement.offsetParent is null when the element is not visisble
- // (or if the element has |position: fixed|). See:
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
- return BrowserTestUtils.waitForCondition(() => element.offsetParent !== null,
- "Waiting for element to be visible");
-}
-
-var gNotification;
-
-var tests = [
- // Test that passing the checkbox field shows the checkbox.
- { id: "show_checkbox",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.checkbox = {
- label: "This is a checkbox",
- };
- gNotification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- checkCheckbox(notification.checkbox, "This is a checkbox");
- triggerMainCommand(popup);
- },
- onHidden: function () { }
- },
-
- // Test checkbox being checked by default
- { id: "checkbox_checked",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.checkbox = {
- label: "Check this",
- checked: true,
- };
- gNotification = showNotification(this.notifyObj);
- },
- onShown: function (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- checkCheckbox(notification.checkbox, "Check this", true);
- triggerMainCommand(popup);
- },
- onHidden: function () { }
- },
-
- // Test checkbox passing the checkbox state on mainAction
- { id: "checkbox_passCheckboxChecked_mainAction",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.mainAction.callback = ({checkboxChecked}) => this.mainActionChecked = checkboxChecked;
- this.notifyObj.options.checkbox = {
- label: "This is a checkbox",
- };
- gNotification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- let checkbox = notification.checkbox;
- checkCheckbox(checkbox, "This is a checkbox");
- yield promiseElementVisible(checkbox);
- EventUtils.synthesizeMouseAtCenter(checkbox, {});
- checkCheckbox(checkbox, "This is a checkbox", true);
- triggerMainCommand(popup);
- },
- onHidden: function () {
- is(this.mainActionChecked, true, "mainAction callback is passed the correct checkbox value");
- }
- },
-
- // Test checkbox passing the checkbox state on secondaryAction
- { id: "checkbox_passCheckboxChecked_secondaryAction",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.secondaryActions = [{
- label: "Test Secondary",
- accessKey: "T",
- callback: ({checkboxChecked}) => this.secondaryActionChecked = checkboxChecked,
- }];
- this.notifyObj.options.checkbox = {
- label: "This is a checkbox",
- };
- gNotification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- let checkbox = notification.checkbox;
- checkCheckbox(checkbox, "This is a checkbox");
- yield promiseElementVisible(checkbox);
- EventUtils.synthesizeMouseAtCenter(checkbox, {});
- checkCheckbox(checkbox, "This is a checkbox", true);
- triggerSecondaryCommand(popup, 0);
- },
- onHidden: function () {
- is(this.secondaryActionChecked, true, "secondaryAction callback is passed the correct checkbox value");
- }
- },
-
- // Test checkbox preserving its state through re-opening the doorhanger
- { id: "checkbox_reopen",
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.checkbox = {
- label: "This is a checkbox",
- checkedState: {
- disableMainAction: true,
- warningLabel: "Testing disable",
- },
- };
- gNotification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- let checkbox = notification.checkbox;
- checkCheckbox(checkbox, "This is a checkbox");
- yield promiseElementVisible(checkbox);
- EventUtils.synthesizeMouseAtCenter(checkbox, {});
- dismissNotification(popup);
- },
- onHidden: function* (popup) {
- let icon = document.getElementById("default-notification-icon");
- let shown = waitForNotificationPanel();
- EventUtils.synthesizeMouseAtCenter(icon, {});
- yield shown;
- let notification = popup.childNodes[0];
- let checkbox = notification.checkbox;
- checkCheckbox(checkbox, "This is a checkbox", true);
- checkMainAction(notification, true);
- gNotification.remove();
- }
- },
-];
-
-// Test checkbox disabling the main action in different combinations
-["checkedState", "uncheckedState"].forEach(function (state) {
- [true, false].forEach(function (checked) {
- tests.push(
- { id: `checkbox_disableMainAction_${state}_${checked ? 'checked' : 'unchecked'}`,
- run: function () {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.checkbox = {
- label: "This is a checkbox",
- checked: checked,
- [state]: {
- disableMainAction: true,
- warningLabel: "Testing disable",
- },
- };
- gNotification = showNotification(this.notifyObj);
- },
- onShown: function* (popup) {
- checkPopup(popup, this.notifyObj);
- let notification = popup.childNodes[0];
- let checkbox = notification.checkbox;
- let disabled = (state === "checkedState" && checked) ||
- (state === "uncheckedState" && !checked);
-
- checkCheckbox(checkbox, "This is a checkbox", checked);
- checkMainAction(notification, disabled);
- yield promiseElementVisible(checkbox);
- EventUtils.synthesizeMouseAtCenter(checkbox, {});
- checkCheckbox(checkbox, "This is a checkbox", !checked);
- checkMainAction(notification, !disabled);
- EventUtils.synthesizeMouseAtCenter(checkbox, {});
- checkCheckbox(checkbox, "This is a checkbox", checked);
- checkMainAction(notification, disabled);
-
- // Unblock the main command if it's currently disabled.
- if (disabled) {
- EventUtils.synthesizeMouseAtCenter(checkbox, {});
- }
- triggerMainCommand(popup);
- },
- onHidden: function () { }
- }
- );
- });
-});
-
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js b/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js
deleted file mode 100644
index 0f5b57ced..000000000
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- ok(PopupNotifications, "PopupNotifications object exists");
- ok(PopupNotifications.panel, "PopupNotifications panel exists");
-
- setup();
-}
-
-var tests = [
- // Test that for persistent notifications,
- // the secondary action is triggered by pressing the escape key.
- { id: "Test#1",
- run() {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.options.persistent = true;
- showNotification(this.notifyObj);
- },
- onShown(popup) {
- checkPopup(popup, this.notifyObj);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- },
- onHidden(popup) {
- ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
- ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked");
- ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
- ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
- }
- },
- // Test that for non-persistent notifications, the escape key dismisses the notification.
- { id: "Test#2",
- *run() {
- yield waitForWindowReadyForPopupNotifications(window);
- this.notifyObj = new BasicNotification(this.id);
- this.notification = showNotification(this.notifyObj);
- },
- onShown(popup) {
- checkPopup(popup, this.notifyObj);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- },
- onHidden(popup) {
- ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
- ok(!this.notifyObj.secondaryActionClicked, "secondaryAction was not clicked");
- ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
- ok(!this.notifyObj.removedCallbackTriggered, "removed callback was not triggered");
- this.notification.remove();
- }
- },
- // Test that the space key on an anchor element focuses an active notification
- { id: "Test#3",
- *run() {
- this.notifyObj = new BasicNotification(this.id);
- this.notifyObj.anchorID = "geo-notification-icon";
- this.notifyObj.addOptions({
- persistent: true
- });
- this.notification = showNotification(this.notifyObj);
- },
- *onShown(popup) {
- checkPopup(popup, this.notifyObj);
- let anchor = document.getElementById(this.notifyObj.anchorID);
- anchor.focus();
- is(document.activeElement, anchor);
- EventUtils.synthesizeKey(" ", {});
- is(document.activeElement, popup.childNodes[0].button);
- this.notification.remove();
- },
- onHidden(popup) { }
- },
-];
diff --git a/browser/base/content/test/popupNotifications/browser_reshow_in_background.js b/browser/base/content/test/popupNotifications/browser_reshow_in_background.js
deleted file mode 100644
index 6f415f62e..000000000
--- a/browser/base/content/test/popupNotifications/browser_reshow_in_background.js
+++ /dev/null
@@ -1,52 +0,0 @@
-"use strict";
-
-/**
- * Tests that when PopupNotifications for background tabs are reshown, they
- * don't show up in the foreground tab, but only in the background tab that
- * they belong to.
- */
-add_task(function* test_background_notifications_dont_reshow_in_foreground() {
- // Our initial tab will be A. Let's open two more tabs B and C, but keep
- // A selected. Then, we'll trigger a PopupNotification in C, and then make
- // it reshow.
- let tabB = gBrowser.addTab("about:blank");
- let tabC = gBrowser.addTab("about:blank");
-
- let seenEvents = [];
-
- let options = {
- dismissed: false,
- eventCallback(popupEvent) {
- seenEvents.push(popupEvent);
- },
- };
-
- let notification =
- PopupNotifications.show(tabC.linkedBrowser, "test-notification",
- "", "plugins-notification-icon",
- null, null, options);
- Assert.deepEqual(seenEvents, [], "Should have seen no events yet.");
-
- yield BrowserTestUtils.switchTab(gBrowser, tabB);
- Assert.deepEqual(seenEvents, [], "Should have seen no events yet.");
-
- notification.reshow();
- Assert.deepEqual(seenEvents, [], "Should have seen no events yet.");
-
- let panelShown =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- yield BrowserTestUtils.switchTab(gBrowser, tabC);
- yield panelShown;
-
- Assert.equal(seenEvents.length, 2, "Should have seen two events.");
- Assert.equal(seenEvents[0], "showing", "Should have said popup was showing.");
- Assert.equal(seenEvents[1], "shown", "Should have said popup was shown.");
-
- let panelHidden =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- PopupNotifications.remove(notification);
- yield panelHidden;
-
- yield BrowserTestUtils.removeTab(tabB);
- yield BrowserTestUtils.removeTab(tabC);
-});
diff --git a/browser/base/content/test/popupNotifications/head.js b/browser/base/content/test/popupNotifications/head.js
deleted file mode 100644
index 4a803d6af..000000000
--- a/browser/base/content/test/popupNotifications/head.js
+++ /dev/null
@@ -1,303 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-
-function whenDelayedStartupFinished(aWindow, aCallback) {
- return new Promise(resolve => {
- info("Waiting for delayed startup to finish");
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- if (aCallback) {
- executeSoon(aCallback);
- }
- resolve();
- }
- }, "browser-delayed-startup-finished", false);
- });
-}
-
-/**
- * Allows waiting for an observer notification once.
- *
- * @param topic
- * Notification topic to observe.
- *
- * @return {Promise}
- * @resolves The array [subject, data] from the observed notification.
- * @rejects Never.
- */
-function promiseTopicObserved(topic)
-{
- let deferred = Promise.defer();
- info("Waiting for observer topic " + topic);
- Services.obs.addObserver(function PTO_observe(subject, topic, data) {
- Services.obs.removeObserver(PTO_observe, topic);
- deferred.resolve([subject, data]);
- }, topic, false);
- return deferred.promise;
-}
-
-
-/**
- * Waits for a load (or custom) event to finish in a given tab. If provided
- * load an uri into the tab.
- *
- * @param tab
- * The tab to load into.
- * @param [optional] url
- * The url to load, or the current url.
- * @return {Promise} resolved when the event is handled.
- * @resolves to the received event
- * @rejects if a valid load event is not received within a meaningful interval
- */
-function promiseTabLoadEvent(tab, url)
-{
- let browser = tab.linkedBrowser;
-
- if (url) {
- browser.loadURI(url);
- }
-
- return BrowserTestUtils.browserLoaded(browser, false, url);
-}
-
-const PREF_SECURITY_DELAY_INITIAL = Services.prefs.getIntPref("security.notification_enable_delay");
-
-function setup() {
- // Disable transitions as they slow the test down and we want to click the
- // mouse buttons in a predictable location.
-
- registerCleanupFunction(() => {
- PopupNotifications.buttonDelay = PREF_SECURITY_DELAY_INITIAL;
- });
-}
-
-function goNext() {
- executeSoon(() => executeSoon(Task.async(runNextTest)));
-}
-
-function* runNextTest() {
- if (tests.length == 0) {
- executeSoon(finish);
- return;
- }
-
- let nextTest = tests.shift();
- if (nextTest.onShown) {
- let shownState = false;
- onPopupEvent("popupshowing", function () {
- info("[" + nextTest.id + "] popup showing");
- });
- onPopupEvent("popupshown", function () {
- shownState = true;
- info("[" + nextTest.id + "] popup shown");
- Task.spawn(() => nextTest.onShown(this))
- .then(undefined, ex => Assert.ok(false, "onShown failed: " + ex));
- });
- onPopupEvent("popuphidden", function () {
- info("[" + nextTest.id + "] popup hidden");
- Task.spawn(() => nextTest.onHidden(this))
- .then(() => goNext(), ex => Assert.ok(false, "onHidden failed: " + ex));
- }, () => shownState);
- info("[" + nextTest.id + "] added listeners; panel is open: " + PopupNotifications.isPanelOpen);
- }
-
- info("[" + nextTest.id + "] running test");
- yield nextTest.run();
-}
-
-function showNotification(notifyObj) {
- info("Showing notification " + notifyObj.id);
- return PopupNotifications.show(notifyObj.browser,
- notifyObj.id,
- notifyObj.message,
- notifyObj.anchorID,
- notifyObj.mainAction,
- notifyObj.secondaryActions,
- notifyObj.options);
-}
-
-function dismissNotification(popup) {
- info("Dismissing notification " + popup.childNodes[0].id);
- executeSoon(() => EventUtils.synthesizeKey("VK_ESCAPE", {}));
-}
-
-function BasicNotification(testId) {
- this.browser = gBrowser.selectedBrowser;
- this.id = "test-notification-" + testId;
- this.message = "This is popup notification for " + testId;
- this.anchorID = null;
- this.mainAction = {
- label: "Main Action",
- accessKey: "M",
- callback: () => this.mainActionClicked = true
- };
- this.secondaryActions = [
- {
- label: "Secondary Action",
- accessKey: "S",
- callback: () => this.secondaryActionClicked = true
- }
- ];
- this.options = {
- eventCallback: eventName => {
- switch (eventName) {
- case "dismissed":
- this.dismissalCallbackTriggered = true;
- break;
- case "showing":
- this.showingCallbackTriggered = true;
- break;
- case "shown":
- this.shownCallbackTriggered = true;
- break;
- case "removed":
- this.removedCallbackTriggered = true;
- break;
- case "swapping":
- this.swappingCallbackTriggered = true;
- break;
- }
- }
- };
-}
-
-BasicNotification.prototype.addOptions = function(options) {
- for (let [name, value] of Object.entries(options))
- this.options[name] = value;
-};
-
-function ErrorNotification() {
- this.mainAction.callback = () => {
- this.mainActionClicked = true;
- throw new Error("Oops!");
- };
- this.secondaryActions[0].callback = () => {
- this.secondaryActionClicked = true;
- throw new Error("Oops!");
- };
-}
-
-ErrorNotification.prototype = new BasicNotification();
-ErrorNotification.prototype.constructor = ErrorNotification;
-
-function checkPopup(popup, notifyObj) {
- info("Checking notification " + notifyObj.id);
-
- ok(notifyObj.showingCallbackTriggered, "showing callback was triggered");
- ok(notifyObj.shownCallbackTriggered, "shown callback was triggered");
-
- let notifications = popup.childNodes;
- is(notifications.length, 1, "one notification displayed");
- let notification = notifications[0];
- if (!notification)
- return;
- let icon = document.getAnonymousElementByAttribute(notification, "class",
- "popup-notification-icon");
- if (notifyObj.id == "geolocation") {
- isnot(icon.boxObject.width, 0, "icon for geo displayed");
- ok(popup.anchorNode.classList.contains("notification-anchor-icon"),
- "notification anchored to icon");
- }
- is(notification.getAttribute("label"), notifyObj.message, "message matches");
- is(notification.id, notifyObj.id + "-notification", "id matches");
- if (notifyObj.mainAction) {
- is(notification.getAttribute("buttonlabel"), notifyObj.mainAction.label,
- "main action label matches");
- is(notification.getAttribute("buttonaccesskey"),
- notifyObj.mainAction.accessKey, "main action accesskey matches");
- }
- let actualSecondaryActions =
- Array.filter(notification.childNodes, child => child.nodeName == "menuitem");
- let secondaryActions = notifyObj.secondaryActions || [];
- let actualSecondaryActionsCount = actualSecondaryActions.length;
- if (notifyObj.options.hideNotNow) {
- is(notification.getAttribute("hidenotnow"), "true", "'Not Now' item hidden");
- if (secondaryActions.length)
- is(notification.lastChild.tagName, "menuitem", "no menuseparator");
- }
- else if (secondaryActions.length) {
- is(notification.lastChild.tagName, "menuseparator", "menuseparator exists");
- }
- is(actualSecondaryActionsCount, secondaryActions.length,
- actualSecondaryActions.length + " secondary actions");
- secondaryActions.forEach(function (a, i) {
- is(actualSecondaryActions[i].getAttribute("label"), a.label,
- "label for secondary action " + i + " matches");
- is(actualSecondaryActions[i].getAttribute("accesskey"), a.accessKey,
- "accessKey for secondary action " + i + " matches");
- });
-}
-
-XPCOMUtils.defineLazyGetter(this, "gActiveListeners", () => {
- let listeners = new Map();
- registerCleanupFunction(() => {
- for (let [listener, eventName] of listeners) {
- PopupNotifications.panel.removeEventListener(eventName, listener, false);
- }
- });
- return listeners;
-});
-
-function onPopupEvent(eventName, callback, condition) {
- let listener = event => {
- if (event.target != PopupNotifications.panel ||
- (condition && !condition()))
- return;
- PopupNotifications.panel.removeEventListener(eventName, listener, false);
- gActiveListeners.delete(listener);
- executeSoon(() => callback.call(PopupNotifications.panel));
- }
- gActiveListeners.set(listener, eventName);
- PopupNotifications.panel.addEventListener(eventName, listener, false);
-}
-
-function waitForNotificationPanel() {
- return new Promise(resolve => {
- onPopupEvent("popupshown", function() {
- resolve(this);
- });
- });
-}
-
-function triggerMainCommand(popup) {
- let notifications = popup.childNodes;
- ok(notifications.length > 0, "at least one notification displayed");
- let notification = notifications[0];
- info("Triggering main command for notification " + notification.id);
- // 20, 10 so that the inner button is hit
- EventUtils.synthesizeMouse(notification.button, 20, 10, {});
-}
-
-function triggerSecondaryCommand(popup, index) {
- let notifications = popup.childNodes;
- ok(notifications.length > 0, "at least one notification displayed");
- let notification = notifications[0];
- info("Triggering secondary command for notification " + notification.id);
- // Cancel the arrow panel slide-in transition (bug 767133) such that
- // it won't interfere with us interacting with the dropdown.
- document.getAnonymousNodes(popup)[0].style.transition = "none";
-
- notification.button.focus();
-
- popup.addEventListener("popupshown", function handle() {
- popup.removeEventListener("popupshown", handle, false);
- info("Command popup open for notification " + notification.id);
- // Press down until the desired command is selected
- for (let i = 0; i <= index; i++) {
- EventUtils.synthesizeKey("VK_DOWN", {});
- }
- // Activate
- EventUtils.synthesizeKey("VK_RETURN", {});
- }, false);
-
- // 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") });
-}
diff --git a/browser/base/content/test/popups/browser.ini b/browser/base/content/test/popups/browser.ini
deleted file mode 100644
index 46a32783b..000000000
--- a/browser/base/content/test/popups/browser.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[browser_popupUI.js]
-[browser_popup_blocker.js]
-support-files = popup_blocker.html
-skip-if = (os == 'linux') || (e10s && debug) # Frequent bug 1081925 and bug 1125520 failures
diff --git a/browser/base/content/test/popups/browser_popupUI.js b/browser/base/content/test/popups/browser_popupUI.js
deleted file mode 100644
index 7c6805f60..000000000
--- a/browser/base/content/test/popups/browser_popupUI.js
+++ /dev/null
@@ -1,37 +0,0 @@
-function test() {
- waitForExplicitFinish();
- SpecialPowers.pushPrefEnv({ set: [[ "dom.disable_open_during_load", false ]] });
-
- let popupOpened = BrowserTestUtils.waitForNewWindow(true, "about:blank");
- BrowserTestUtils.openNewForegroundTab(gBrowser,
- "data:text/html,<html><script>popup=open('about:blank','','width=300,height=200')</script>"
- );
- popupOpened.then((win) => testPopupUI(win));
-}
-
-function testPopupUI(win) {
- var doc = win.document;
-
- ok(win.gURLBar, "location bar exists in the popup");
- isnot(win.gURLBar.clientWidth, 0, "location bar is visible in the popup");
- ok(win.gURLBar.readOnly, "location bar is read-only in the popup");
- isnot(doc.getElementById("Browser:OpenLocation").getAttribute("disabled"), "true",
- "'open location' command is not disabled in the popup");
-
- let historyButton = doc.getAnonymousElementByAttribute(win.gURLBar, "anonid",
- "historydropmarker");
- is(historyButton.clientWidth, 0, "history dropdown button is hidden in the popup");
-
- EventUtils.synthesizeKey("t", { accelKey: true }, win);
- is(win.gBrowser.browsers.length, 1, "Accel+T doesn't open a new tab in the popup");
- is(gBrowser.browsers.length, 3, "Accel+T opened a new tab in the parent window");
- gBrowser.removeCurrentTab();
-
- EventUtils.synthesizeKey("w", { accelKey: true }, win);
- ok(win.closed, "Accel+W closes the popup");
-
- if (!win.closed)
- win.close();
- gBrowser.removeCurrentTab();
- finish();
-}
diff --git a/browser/base/content/test/popups/browser_popup_blocker.js b/browser/base/content/test/popups/browser_popup_blocker.js
deleted file mode 100644
index 8cadfea57..000000000
--- a/browser/base/content/test/popups/browser_popup_blocker.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const baseURL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
-
-function clearAllPermissionsByPrefix(aPrefix) {
- let perms = Services.perms.enumerator;
- while (perms.hasMoreElements()) {
- let perm = perms.getNext();
- if (perm.type.startsWith(aPrefix)) {
- Services.perms.removePermission(perm);
- }
- }
-}
-
-add_task(function* test_opening_blocked_popups() {
- // Enable the popup blocker.
- yield SpecialPowers.pushPrefEnv({set: [["dom.disable_open_during_load", true]]});
-
- // Open the test page.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, baseURL + "popup_blocker.html");
-
- // Wait for the popup-blocked notification.
- let notification;
- yield BrowserTestUtils.waitForCondition(() =>
- notification = gBrowser.getNotificationBox().getNotificationWithValue("popup-blocked"));
-
- // Show the menu.
- let popupShown = BrowserTestUtils.waitForEvent(window, "popupshown");
- let popupFilled = BrowserTestUtils.waitForMessage(gBrowser.selectedBrowser.messageManager,
- "PopupBlocking:ReplyGetBlockedPopupList");
- notification.querySelector("button").doCommand();
- let popup_event = yield popupShown;
- let menu = popup_event.target;
- is(menu.id, "blockedPopupOptions", "Blocked popup menu shown");
-
- yield popupFilled;
- // The menu is filled on the same message that we waited for, so let's ensure that it
- // had a chance of running before this test code.
- yield new Promise(resolve => executeSoon(resolve));
-
- // Check the menu contents.
- let sep = menu.querySelector("menuseparator");
- let popupCount = 0;
- for (let i = sep.nextElementSibling; i; i = i.nextElementSibling) {
- popupCount++;
- }
- is(popupCount, 2, "Two popups were blocked");
-
- // Pressing "allow" should open all blocked popups.
- let popupTabs = [];
- function onTabOpen(event) {
- popupTabs.push(event.target);
- }
- gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen);
-
- // Press the button.
- let allow = menu.querySelector("[observes='blockedPopupAllowSite']");
- allow.doCommand();
- yield BrowserTestUtils.waitForCondition(() =>
- popupTabs.length == 2 &&
- popupTabs.every(aTab => aTab.linkedBrowser.currentURI.spec != "about:blank"));
-
- gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen);
-
- is(popupTabs[0].linkedBrowser.currentURI.spec, "data:text/plain;charset=utf-8,a", "Popup a");
- is(popupTabs[1].linkedBrowser.currentURI.spec, "data:text/plain;charset=utf-8,b", "Popup b");
-
- // Clean up.
- gBrowser.removeTab(tab);
- for (let popup of popupTabs) {
- gBrowser.removeTab(popup);
- }
- clearAllPermissionsByPrefix("popup");
- // Ensure the menu closes.
- menu.hidePopup();
-});
-
-add_task(function* check_icon_hides() {
- // Enable the popup blocker.
- yield SpecialPowers.pushPrefEnv({set: [["dom.disable_open_during_load", true]]});
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, baseURL + "popup_blocker.html");
-
- let button = document.getElementById("page-report-button");
- yield BrowserTestUtils.waitForCondition(() =>
- gBrowser.getNotificationBox().getNotificationWithValue("popup-blocked"));
- ok(!button.hidden, "Button should be visible");
-
- let otherPageLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- openLinkIn(baseURL, "current", {});
- yield otherPageLoaded;
- ok(button.hidden, "Button should have hidden again after another page loaded.");
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/popups/popup_blocker.html b/browser/base/content/test/popups/popup_blocker.html
deleted file mode 100644
index 6e2b7db15..000000000
--- a/browser/base/content/test/popups/popup_blocker.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <meta charset="UTF-8">
- <title>Page creating two popups</title>
- </head>
- <body>
- <script type="text/javascript">
- window.open("data:text/plain;charset=utf-8,a", "a");
- window.open("data:text/plain;charset=utf-8,b", "b");
- </script>
- </body>
-</html>
diff --git a/browser/base/content/test/referrer/.eslintrc.js b/browser/base/content/test/referrer/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/referrer/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/referrer/browser.ini b/browser/base/content/test/referrer/browser.ini
deleted file mode 100644
index 13b712850..000000000
--- a/browser/base/content/test/referrer/browser.ini
+++ /dev/null
@@ -1,24 +0,0 @@
-[DEFAULT]
-support-files =
- file_referrer_policyserver.sjs
- file_referrer_policyserver_attr.sjs
- file_referrer_testserver.sjs
- head.js
-
-[browser_referrer_middle_click.js]
-[browser_referrer_middle_click_in_container.js]
-[browser_referrer_open_link_in_private.js]
-skip-if = os == 'linux' # Bug 1145199
-[browser_referrer_open_link_in_tab.js]
-skip-if = os == 'linux' # Bug 1144816
-[browser_referrer_open_link_in_window.js]
-skip-if = os == 'linux' # Bug 1145199
-[browser_referrer_open_link_in_window_in_container.js]
-skip-if = os == 'linux' # Bug 1145199
-[browser_referrer_simple_click.js]
-[browser_referrer_open_link_in_container_tab.js]
-skip-if = os == 'linux' # Bug 1144816
-[browser_referrer_open_link_in_container_tab2.js]
-skip-if = os == 'linux' # Bug 1144816
-[browser_referrer_open_link_in_container_tab3.js]
-skip-if = os == 'linux' # Bug 1144816
diff --git a/browser/base/content/test/referrer/browser_referrer_middle_click.js b/browser/base/content/test/referrer/browser_referrer_middle_click.js
deleted file mode 100644
index e6e01c6a3..000000000
--- a/browser/base/content/test/referrer/browser_referrer_middle_click.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Tests referrer on middle-click navigation.
-// Middle-clicks on the link, which opens it in a new tab.
-
-function startMiddleClickTestCase(aTestNumber) {
- info("browser_referrer_middle_click: " +
- getReferrerTestDescription(aTestNumber));
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- BrowserTestUtils.switchTab(gTestWindow.gBrowser, aNewTab).then(() => {
- checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
- startMiddleClickTestCase);
- });
- });
-
- clickTheLink(gTestWindow, "testlink", {button: 1});
-}
-
-function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startMiddleClickTestCase);
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js b/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js
deleted file mode 100644
index e89b891f3..000000000
--- a/browser/base/content/test/referrer/browser_referrer_middle_click_in_container.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Tests referrer on middle-click navigation.
-// Middle-clicks on the link, which opens it in a new tab, same container.
-
-function startMiddleClickTestCase(aTestNumber) {
- info("browser_referrer_middle_click: " +
- getReferrerTestDescription(aTestNumber));
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- BrowserTestUtils.switchTab(gTestWindow.gBrowser, aNewTab).then(() => {
- checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
- startMiddleClickTestCase,
- { userContextId: 3 });
- });
- });
-
- clickTheLink(gTestWindow, "testlink", {button: 1});
-}
-
-function test() {
- waitForExplicitFinish();
-
- SpecialPowers.pushPrefEnv(
- {set: [["privacy.userContext.enabled", true]]},
- function() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startMiddleClickTestCase, { userContextId: 3 });
- });
-}
diff --git 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
deleted file mode 100644
index deaf90fb9..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Tests referrer on context menu navigation - open link in new container tab.
-// Selects "open link in new container tab" from the context menu.
-
-function getReferrerTest(aTestNumber) {
- let test = _referrerTests[aTestNumber];
- if (test) {
- // We want all the referrer tests to fail!
- test.result = "";
- }
-
- return test;
-}
-
-function startNewTabTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_container_tab: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- gTestWindow.gBrowser.selectedTab = aNewTab;
-
- 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);
-
- 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);
- firstContext.doCommand();
- });
-
- aContextMenu.hidePopup();
- });
-
- menupopup.showPopup();
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- SpecialPowers.pushPrefEnv(
- {set: [["privacy.userContext.enabled", true]]},
- function() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewTabTestCase);
- });
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js
deleted file mode 100644
index 77a5645c6..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab2.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Tests referrer on context menu navigation - open link in new container tab.
-// Selects "open link in new container tab" from the context menu.
-
-// The test runs from a container ID 1.
-// Output: we have the correct referrer policy applied.
-
-function startNewTabTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_container_tab: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- gTestWindow.gBrowser.selectedTab = aNewTab;
-
- checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
- startNewTabTestCase, { userContextId: 1 });
- });
-
- doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkincontainertab");
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- SpecialPowers.pushPrefEnv(
- {set: [["privacy.userContext.enabled", true]]},
- function() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewTabTestCase, { userContextId: 1 });
- });
-}
diff --git 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
deleted file mode 100644
index c0a73d828..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Tests referrer on context menu navigation - open link in new container tab.
-// Selects "open link in new container tab" from the context menu.
-
-// The test runs from a container ID 2.
-// Output: we have no referrer.
-
-function getReferrerTest(aTestNumber) {
- let test = _referrerTests[aTestNumber];
- if (test) {
- // We want all the referrer tests to fail!
- test.result = "";
- }
-
- return test;
-}
-
-function startNewTabTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_container_tab: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- gTestWindow.gBrowser.selectedTab = aNewTab;
-
- 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);
-
- 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);
- firstContext.doCommand();
- });
-
- aContextMenu.hidePopup();
- });
-
- menupopup.showPopup();
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- SpecialPowers.pushPrefEnv(
- {set: [["privacy.userContext.enabled", true]]},
- function() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewTabTestCase, { userContextId: 2 });
- });
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_private.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_private.js
deleted file mode 100644
index 8f12e3824..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_private.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Tests referrer on context menu navigation - open link in new private window.
-// Selects "open link in new private window" from the context menu.
-
-function startNewPrivateWindowTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_private: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- newWindowOpened().then(function(aNewWindow) {
- BrowserTestUtils.firstBrowserLoaded(aNewWindow, false).then(function() {
- checkReferrerAndStartNextTest(aTestNumber, aNewWindow, null,
- startNewPrivateWindowTestCase);
- });
- });
-
- doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkprivate");
- });
-}
-
-function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewPrivateWindowTestCase);
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js
deleted file mode 100644
index 03119cb57..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_tab.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Tests referrer on context menu navigation - open link in new tab.
-// Selects "open link in new tab" from the context menu.
-
-function startNewTabTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_tab: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- someTabLoaded(gTestWindow).then(function(aNewTab) {
- gTestWindow.gBrowser.selectedTab = aNewTab;
- checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
- startNewTabTestCase);
- });
-
- doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkintab");
- });
-}
-
-function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewTabTestCase);
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_window.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_window.js
deleted file mode 100644
index 81e7b2648..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_window.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Tests referrer on context menu navigation - open link in new window.
-// Selects "open link in new window" from the context menu.
-
-function startNewWindowTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_window: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- newWindowOpened().then(function(aNewWindow) {
- BrowserTestUtils.firstBrowserLoaded(aNewWindow, false).then(function() {
- checkReferrerAndStartNextTest(aTestNumber, aNewWindow, null,
- startNewWindowTestCase);
- });
- });
-
- doContextMenuCommand(gTestWindow, aContextMenu, "context-openlink");
- });
-}
-
-function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewWindowTestCase);
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js b/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js
deleted file mode 100644
index d5ce87952..000000000
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_window_in_container.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Tests referrer on context menu navigation - open link in new window.
-// Selects "open link in new window" from the context menu.
-
-// This test runs from a container tab. The new tab/window will be loaded in
-// the same container.
-
-function startNewWindowTestCase(aTestNumber) {
- info("browser_referrer_open_link_in_window: " +
- getReferrerTestDescription(aTestNumber));
- contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
- newWindowOpened().then(function(aNewWindow) {
- BrowserTestUtils.firstBrowserLoaded(aNewWindow, false).then(function() {
- checkReferrerAndStartNextTest(aTestNumber, aNewWindow, null,
- startNewWindowTestCase,
- { userContextId: 1 });
- });
- });
-
- doContextMenuCommand(gTestWindow, aContextMenu, "context-openlink");
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- SpecialPowers.pushPrefEnv(
- {set: [["privacy.userContext.enabled", true]]},
- function() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startNewWindowTestCase, { userContextId: 1 });
- });
-}
diff --git a/browser/base/content/test/referrer/browser_referrer_simple_click.js b/browser/base/content/test/referrer/browser_referrer_simple_click.js
deleted file mode 100644
index 7f3784e64..000000000
--- a/browser/base/content/test/referrer/browser_referrer_simple_click.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Tests referrer on simple click navigation.
-// Clicks on the link, which opens it in the same tab.
-
-function startSimpleClickTestCase(aTestNumber) {
- info("browser_referrer_simple_click: " +
- getReferrerTestDescription(aTestNumber));
- BrowserTestUtils.browserLoaded(gTestWindow.gBrowser.selectedBrowser, false,
- (url) => url.endsWith("file_referrer_testserver.sjs"))
- .then(function() {
- checkReferrerAndStartNextTest(aTestNumber, null, null,
- startSimpleClickTestCase);
- });
-
- clickTheLink(gTestWindow, "testlink", {});
-}
-
-function test() {
- requestLongerTimeout(10); // slowwww shutdown on e10s
- startReferrerTest(startSimpleClickTestCase);
-}
diff --git a/browser/base/content/test/referrer/file_referrer_policyserver.sjs b/browser/base/content/test/referrer/file_referrer_policyserver.sjs
deleted file mode 100644
index e07965675..000000000
--- a/browser/base/content/test/referrer/file_referrer_policyserver.sjs
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Renders a link with the provided referrer policy.
- * Used in browser_referrer_*.js, bug 1113431.
- * Arguments: ?scheme=http://&policy=origin&rel=noreferrer
- */
-function handleRequest(request, response)
-{
- Components.utils.importGlobalProperties(["URLSearchParams"]);
- let query = new URLSearchParams(request.queryString);
-
- let scheme = query.get("scheme");
- let policy = query.get("policy");
- let rel = query.get("rel");
-
- let linkUrl = scheme +
- "test1.example.com/browser/browser/base/content/test/referrer/" +
- "file_referrer_testserver.sjs";
- let metaReferrerTag =
- policy ? `<meta name='referrer' content='${policy}'>` : "";
-
- let html = `<!DOCTYPE HTML>
- <html>
- <head>
- <meta charset='utf-8'>
- ${metaReferrerTag}
- <title>Test referrer</title>
- </head>
- <body>
- <a id='testlink' href='${linkUrl}' ${rel ? ` rel='${rel}'` : ""}>
- referrer test link</a>
- </body>
- </html>`;
-
- response.setHeader("Cache-Control", "no-cache", false);
- response.setHeader("Content-Type", "text/html", false);
- response.write(html);
-}
diff --git a/browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs b/browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs
deleted file mode 100644
index 25a58188a..000000000
--- a/browser/base/content/test/referrer/file_referrer_policyserver_attr.sjs
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Renders a link with the provided referrer policy.
- * Used in browser_referrer_*.js, bug 1113431.
- * Arguments: ?scheme=http://&policy=origin&rel=noreferrer
- */
-function handleRequest(request, response)
-{
- Components.utils.importGlobalProperties(["URLSearchParams"]);
- let query = new URLSearchParams(request.queryString);
-
- let scheme = query.get("scheme");
- let policy = query.get("policy");
- let rel = query.get("rel");
-
- let linkUrl = scheme +
- "test1.example.com/browser/browser/base/content/test/referrer/" +
- "file_referrer_testserver.sjs";
- let referrerPolicy =
- policy ? `referrerpolicy="${policy}"` : "";
-
- let html = `<!DOCTYPE HTML>
- <html>
- <head>
- <meta charset='utf-8'>
- <title>Test referrer</title>
- </head>
- <body>
- <a id='testlink' href='${linkUrl}' ${referrerPolicy} ${rel ? ` rel='${rel}'` : ""}>
- referrer test link</a>
- </body>
- </html>`;
-
- response.setHeader("Cache-Control", "no-cache", false);
- response.setHeader("Content-Type", "text/html", false);
- response.write(html);
-}
diff --git a/browser/base/content/test/referrer/file_referrer_testserver.sjs b/browser/base/content/test/referrer/file_referrer_testserver.sjs
deleted file mode 100644
index 0cfc53b2c..000000000
--- a/browser/base/content/test/referrer/file_referrer_testserver.sjs
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Renders the HTTP Referer header up to the second path slash.
- * Used in browser_referrer_*.js, bug 1113431.
- */
-function handleRequest(request, response)
-{
- let referrer = "";
- try {
- referrer = request.getHeader("referer");
- } catch (e) {
- referrer = "";
- }
-
- // Strip it past the first path slash. Makes tests easier to read.
- referrer = referrer.split("/").slice(0, 4).join("/");
-
- let html = `<!DOCTYPE HTML>
- <html>
- <head>
- <meta charset='utf-8'>
- <title>Test referrer</title>
- </head>
- <body>
- <div id='testdiv'>${referrer}</div>
- </body>
- </html>`;
-
- response.setHeader("Cache-Control", "no-cache", false);
- response.setHeader("Content-Type", "text/html", false);
- response.write(html);
-}
diff --git a/browser/base/content/test/referrer/head.js b/browser/base/content/test/referrer/head.js
deleted file mode 100644
index 1a5d5b051..000000000
--- a/browser/base/content/test/referrer/head.js
+++ /dev/null
@@ -1,265 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "BrowserTestUtils",
- "resource://testing-common/BrowserTestUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ContentTask",
- "resource://testing-common/ContentTask.jsm");
-
-const REFERRER_URL_BASE = "/browser/browser/base/content/test/referrer/";
-const REFERRER_POLICYSERVER_URL =
- "test1.example.com" + REFERRER_URL_BASE + "file_referrer_policyserver.sjs";
-const REFERRER_POLICYSERVER_URL_ATTRIBUTE =
- "test1.example.com" + REFERRER_URL_BASE + "file_referrer_policyserver_attr.sjs";
-
-SpecialPowers.pushPrefEnv({"set": [['network.http.enablePerElementReferrer', true]]});
-
-var gTestWindow = null;
-var rounds = 0;
-
-// We test that the UI code propagates three pieces of state - the referrer URI
-// itself, the referrer policy, and the triggering principal. After that, we
-// trust nsIWebNavigation to do the right thing with the info it's given, which
-// is covered more exhaustively by dom/base/test/test_bug704320.html (which is
-// a faster content-only test). So, here, we limit ourselves to cases that
-// would break when the UI code drops either of these pieces; we don't try to
-// duplicate the entire cross-product test in bug 704320 - that would be slow,
-// especially when we're opening a new window for each case.
-var _referrerTests = [
- // 1. Normal cases - no referrer policy, no special attributes.
- // We expect a full referrer normally, and no referrer on downgrade.
- {
- fromScheme: "http://",
- toScheme: "http://",
- result: "http://test1.example.com/browser" // full referrer
- },
- {
- fromScheme: "https://",
- toScheme: "http://",
- result: "" // no referrer when downgrade
- },
- // 2. Origin referrer policy - we expect an origin referrer,
- // even on downgrade. But rel=noreferrer trumps this.
- {
- fromScheme: "https://",
- toScheme: "http://",
- policy: "origin",
- result: "https://test1.example.com/" // origin, even on downgrade
- },
- {
- fromScheme: "https://",
- toScheme: "http://",
- policy: "origin",
- rel: "noreferrer",
- result: "" // rel=noreferrer trumps meta-referrer
- },
- // 3. XXX: using no-referrer here until we support all attribute values (bug 1178337)
- // Origin-when-cross-origin policy - this depends on the triggering
- // principal. We expect full referrer for same-origin requests,
- // and origin referrer for cross-origin requests.
- {
- fromScheme: "https://",
- toScheme: "https://",
- policy: "no-referrer",
- result: "" // same origin https://test1.example.com/browser
- },
- {
- fromScheme: "http://",
- toScheme: "https://",
- policy: "no-referrer",
- result: "" // cross origin http://test1.example.com
- },
-];
-
-/**
- * Returns the test object for a given test number.
- * @param aTestNumber The test number - 0, 1, 2, ...
- * @return The test object, or undefined if the number is out of range.
- */
-function getReferrerTest(aTestNumber) {
- return _referrerTests[aTestNumber];
-}
-
-/**
- * Returns a brief summary of the test, for logging.
- * @param aTestNumber The test number - 0, 1, 2...
- * @return The test description.
- */
-function getReferrerTestDescription(aTestNumber) {
- let test = getReferrerTest(aTestNumber);
- return "policy=[" + test.policy + "] " +
- "rel=[" + test.rel + "] " +
- test.fromScheme + " -> " + test.toScheme;
-}
-
-/**
- * Clicks the link.
- * @param aWindow The window to click the link in.
- * @param aLinkId The id of the link element.
- * @param aOptions The options for synthesizeMouseAtCenter.
- */
-function clickTheLink(aWindow, aLinkId, aOptions) {
- return BrowserTestUtils.synthesizeMouseAtCenter(
- "#" + aLinkId, aOptions, aWindow.gBrowser.selectedBrowser);
-}
-
-/**
- * Extracts the referrer result from the target window.
- * @param aWindow The window where the referrer target has loaded.
- * @return {Promise}
- * @resolves When extacted, with the text of the (trimmed) referrer.
- */
-function referrerResultExtracted(aWindow) {
- return ContentTask.spawn(aWindow.gBrowser.selectedBrowser, {}, function() {
- return content.document.getElementById("testdiv").textContent;
- });
-}
-
-/**
- * Waits for browser delayed startup to finish.
- * @param aWindow The window to wait for.
- * @return {Promise}
- * @resolves When the window is loaded.
- */
-function delayedStartupFinished(aWindow) {
- return new Promise(function(resolve) {
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- resolve();
- }
- }, "browser-delayed-startup-finished", false);
- });
-}
-
-/**
- * Waits for some (any) tab to load. The caller triggers the load.
- * @param aWindow The window where to wait for a tab to load.
- * @return {Promise}
- * @resolves With the tab once it's loaded.
- */
-function someTabLoaded(aWindow) {
- return BrowserTestUtils.waitForNewTab(gTestWindow.gBrowser).then((tab) => {
- return BrowserTestUtils.browserStopped(tab.linkedBrowser).then(() => tab);
- });
-}
-
-/**
- * Waits for a new window to open and load. The caller triggers the open.
- * @return {Promise}
- * @resolves With the new window once it's open and loaded.
- */
-function newWindowOpened() {
- return TestUtils.topicObserved("browser-delayed-startup-finished")
- .then(([win]) => win);
-}
-
-/**
- * Opens the context menu.
- * @param aWindow The window to open the context menu in.
- * @param aLinkId The id of the link to open the context menu on.
- * @return {Promise}
- * @resolves With the menu popup when the context menu is open.
- */
-function contextMenuOpened(aWindow, aLinkId) {
- let popupShownPromise = BrowserTestUtils.waitForEvent(aWindow.document,
- "popupshown");
- // Simulate right-click.
- clickTheLink(aWindow, aLinkId, { type: "contextmenu", button: 2 });
- return popupShownPromise.then(e => e.target);
-}
-
-/**
- * Performs a context menu command.
- * @param aWindow The window with the already open context menu.
- * @param aMenu The menu popup to hide.
- * @param aItemId The id of the menu item to activate.
- */
-function doContextMenuCommand(aWindow, aMenu, aItemId) {
- let command = aWindow.document.getElementById(aItemId);
- command.doCommand();
- aMenu.hidePopup();
-}
-
-/**
- * Loads a single test case, i.e., a source url into gTestWindow.
- * @param aTestNumber The test case number - 0, 1, 2...
- * @return {Promise}
- * @resolves When the source url for this test case is loaded.
- */
-function referrerTestCaseLoaded(aTestNumber, aParams) {
- let test = getReferrerTest(aTestNumber);
- let server = rounds == 0 ? REFERRER_POLICYSERVER_URL :
- REFERRER_POLICYSERVER_URL_ATTRIBUTE;
- let url = test.fromScheme + server +
- "?scheme=" + escape(test.toScheme) +
- "&policy=" + escape(test.policy || "") +
- "&rel=" + escape(test.rel || "");
- let browser = gTestWindow.gBrowser;
- return BrowserTestUtils.openNewForegroundTab(browser, () => {
- browser.selectedTab = browser.addTab(url, aParams);
- }, false, true);
-}
-
-/**
- * Checks the result of the referrer test, and moves on to the next test.
- * @param aTestNumber The test number - 0, 1, 2, ...
- * @param aNewWindow The new window where the referrer target opened, or null.
- * @param aNewTab The new tab where the referrer target opened, or null.
- * @param aStartTestCase The callback to start the next test, aTestNumber + 1.
- */
-function checkReferrerAndStartNextTest(aTestNumber, aNewWindow, aNewTab,
- aStartTestCase, aParams = {}) {
- referrerResultExtracted(aNewWindow || gTestWindow).then(function(result) {
- // Compare the actual result against the expected one.
- let test = getReferrerTest(aTestNumber);
- let desc = getReferrerTestDescription(aTestNumber);
- is(result, test.result, desc);
-
- // Clean up - close new tab / window, and then the source tab.
- aNewTab && (aNewWindow || gTestWindow).gBrowser.removeTab(aNewTab);
- aNewWindow && aNewWindow.close();
- is(gTestWindow.gBrowser.tabs.length, 2, "two tabs open");
- gTestWindow.gBrowser.removeTab(gTestWindow.gBrowser.tabs[1]);
-
- // Move on to the next test. Or finish if we're done.
- var nextTestNumber = aTestNumber + 1;
- if (getReferrerTest(nextTestNumber)) {
- referrerTestCaseLoaded(nextTestNumber, aParams).then(function() {
- aStartTestCase(nextTestNumber);
- });
- } else if (rounds == 0) {
- nextTestNumber = 0;
- rounds = 1;
- referrerTestCaseLoaded(nextTestNumber, aParams).then(function() {
- aStartTestCase(nextTestNumber);
- });
- } else {
- finish();
- }
- });
-}
-
-/**
- * Fires up the complete referrer test.
- * @param aStartTestCase The callback to start a single test case, called with
- * the test number - 0, 1, 2... Needs to trigger the navigation from the source
- * page, and call checkReferrerAndStartNextTest() when the target is loaded.
- */
-function startReferrerTest(aStartTestCase, params = {}) {
- waitForExplicitFinish();
-
- // Open the window where we'll load the source URLs.
- gTestWindow = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
- registerCleanupFunction(function() {
- gTestWindow && gTestWindow.close();
- });
-
- // Load and start the first test.
- delayedStartupFinished(gTestWindow).then(function() {
- referrerTestCaseLoaded(0, params).then(function() {
- aStartTestCase(0);
- });
- });
-}
diff --git a/browser/base/content/test/siteIdentity/browser.ini b/browser/base/content/test/siteIdentity/browser.ini
deleted file mode 100644
index 6ad3668fd..000000000
--- a/browser/base/content/test/siteIdentity/browser.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
-
-[browser_identityBlock_focus.js]
-skip-if = os == 'mac' # Bug 1334418 (try only)
-support-files = ../general/permissions.html
-[browser_identityPopup_focus.js]
diff --git a/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js b/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js
deleted file mode 100644
index e1e4e537a..000000000
--- a/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Tests that the identity block can be reached via keyboard
- * shortcuts and that it has the correct tab order.
- */
-
-const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
-const PERMISSIONS_PAGE = TEST_PATH + "permissions.html";
-
-function synthesizeKeyAndWaitForFocus(element, keyCode, options) {
- let focused = BrowserTestUtils.waitForEvent(element, "focus");
- EventUtils.synthesizeKey(keyCode, options);
- return focused;
-}
-
-// Checks that the identity block is the next element after the urlbar
-// to be focused if there are no active notification anchors.
-add_task(function* testWithoutNotifications() {
- yield BrowserTestUtils.withNewTab("https://example.com", function*() {
- yield synthesizeKeyAndWaitForFocus(gURLBar, "l", {accelKey: true})
- is(document.activeElement, gURLBar.inputField, "urlbar should be focused");
- yield synthesizeKeyAndWaitForFocus(gIdentityHandler._identityBox, "VK_TAB", {shiftKey: true})
- is(document.activeElement, gIdentityHandler._identityBox,
- "identity block should be focused");
- });
-});
-
-// Checks that when there is a notification anchor, it will receive
-// focus before the identity block.
-add_task(function* testWithoutNotifications() {
-
- yield BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, function*(browser) {
- let popupshown = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Request a permission;
- BrowserTestUtils.synthesizeMouseAtCenter("#geo", {}, browser);
- yield popupshown;
-
- yield synthesizeKeyAndWaitForFocus(gURLBar, "l", {accelKey: true})
- is(document.activeElement, gURLBar.inputField, "urlbar should be focused");
- let geoIcon = document.getElementById("geo-notification-icon");
- yield synthesizeKeyAndWaitForFocus(geoIcon, "VK_TAB", {shiftKey: true})
- is(document.activeElement, geoIcon, "notification anchor should be focused");
- yield synthesizeKeyAndWaitForFocus(gIdentityHandler._identityBox, "VK_TAB", {shiftKey: true})
- is(document.activeElement, gIdentityHandler._identityBox,
- "identity block should be focused");
- });
-});
-
-// Checks that with invalid pageproxystate the identity block is ignored.
-add_task(function* testInvalidPageProxyState() {
- yield BrowserTestUtils.withNewTab("about:blank", function*(browser) {
- // Loading about:blank will automatically focus the urlbar, which, however, can
- // race with the test code. So we only send the shortcut if the urlbar isn't focused yet.
- if (document.activeElement != gURLBar.inputField) {
- yield synthesizeKeyAndWaitForFocus(gURLBar, "l", {accelKey: true})
- }
- is(document.activeElement, gURLBar.inputField, "urlbar should be focused");
- yield synthesizeKeyAndWaitForFocus(gBrowser.getTabForBrowser(browser), "VK_TAB", {shiftKey: true})
- isnot(document.activeElement, gIdentityHandler._identityBox,
- "identity block should not be focused");
- // Restore focus to the url bar.
- gURLBar.focus();
- });
-});
diff --git a/browser/base/content/test/siteIdentity/browser_identityPopup_focus.js b/browser/base/content/test/siteIdentity/browser_identityPopup_focus.js
deleted file mode 100644
index eea06f079..000000000
--- a/browser/base/content/test/siteIdentity/browser_identityPopup_focus.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Tests the focus behavior of the identity popup. */
-
-// Access the identity popup via mouseclick. Focus should not be moved inside.
-add_task(function* testIdentityPopupFocusClick() {
- yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
- yield BrowserTestUtils.withNewTab("https://example.com", function*() {
- let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(gIdentityHandler._identityBox, {});
- yield shown;
- isnot(Services.focus.focusedElement, document.getElementById("identity-popup-security-expander"));
- });
-});
-
-// Access the identity popup via keyboard. Focus should be moved inside.
-add_task(function* testIdentityPopupFocusKeyboard() {
- yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
- yield BrowserTestUtils.withNewTab("https://example.com", function*() {
- let focused = BrowserTestUtils.waitForEvent(gIdentityHandler._identityBox, "focus");
- gIdentityHandler._identityBox.focus();
- yield focused;
- let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
- EventUtils.synthesizeKey(" ", {});
- yield shown;
- is(Services.focus.focusedElement, document.getElementById("identity-popup-security-expander"));
- });
-});
-
diff --git a/browser/base/content/test/siteIdentity/head.js b/browser/base/content/test/siteIdentity/head.js
deleted file mode 100644
index 12a0547ee..000000000
--- a/browser/base/content/test/siteIdentity/head.js
+++ /dev/null
@@ -1,6 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
diff --git a/browser/base/content/test/social/.eslintrc.js b/browser/base/content/test/social/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/social/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/social/blocklist.xml b/browser/base/content/test/social/blocklist.xml
deleted file mode 100644
index 2e3665c36..000000000
--- a/browser/base/content/test/social/blocklist.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
- <emItems>
- <emItem blockID="s1" id="test1.example.com@services.mozilla.org"></emItem>
- </emItems>
-</blocklist>
diff --git a/browser/base/content/test/social/browser.ini b/browser/base/content/test/social/browser.ini
deleted file mode 100644
index 91f931602..000000000
--- a/browser/base/content/test/social/browser.ini
+++ /dev/null
@@ -1,23 +0,0 @@
-[DEFAULT]
-support-files =
- blocklist.xml
- head.js
- opengraph/og_invalid_url.html
- opengraph/opengraph.html
- opengraph/shortlink_linkrel.html
- opengraph/shorturl_link.html
- opengraph/shorturl_linkrel.html
- microformats.html
- share.html
- share_activate.html
- social_activate.html
- social_activate_basic.html
- social_activate_iframe.html
- social_postActivation.html
- !/browser/base/content/test/plugins/blockNoPlugins.xml
-
-[browser_aboutHome_activation.js]
-[browser_addons.js]
-[browser_blocklist.js]
-[browser_share.js]
-[browser_social_activation.js]
diff --git a/browser/base/content/test/social/browser_aboutHome_activation.js b/browser/base/content/test/social/browser_aboutHome_activation.js
deleted file mode 100644
index 37cca53d2..000000000
--- a/browser/base/content/test/social/browser_aboutHome_activation.js
+++ /dev/null
@@ -1,229 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
-
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
- "resource:///modules/AboutHome.jsm");
-
-var snippet =
-' <script>' +
-' var manifest = {' +
-' "name": "Demo Social Service",' +
-' "origin": "https://example.com",' +
-' "iconURL": "chrome://branding/content/icon16.png",' +
-' "icon32URL": "chrome://branding/content/icon32.png",' +
-' "icon64URL": "chrome://branding/content/icon64.png",' +
-' "shareURL": "https://example.com/browser/browser/base/content/test/social/social_share.html",' +
-' "postActivationURL": "https://example.com/browser/browser/base/content/test/social/social_postActivation.html",' +
-' };' +
-' function activateProvider(node) {' +
-' node.setAttribute("data-service", JSON.stringify(manifest));' +
-' var event = new CustomEvent("ActivateSocialFeature");' +
-' node.dispatchEvent(event);' +
-' }' +
-' </script>' +
-' <div id="activationSnippet" onclick="activateProvider(this)">' +
-' <img src="chrome://branding/content/icon32.png"></img>' +
-' </div>';
-
-// enable one-click activation
-var snippet2 =
-' <script>' +
-' var manifest = {' +
-' "name": "Demo Social Service",' +
-' "origin": "https://example.com",' +
-' "iconURL": "chrome://branding/content/icon16.png",' +
-' "icon32URL": "chrome://branding/content/icon32.png",' +
-' "icon64URL": "chrome://branding/content/icon64.png",' +
-' "shareURL": "https://example.com/browser/browser/base/content/test/social/social_share.html",' +
-' "postActivationURL": "https://example.com/browser/browser/base/content/test/social/social_postActivation.html",' +
-' "oneclick": true' +
-' };' +
-' function activateProvider(node) {' +
-' node.setAttribute("data-service", JSON.stringify(manifest));' +
-' var event = new CustomEvent("ActivateSocialFeature");' +
-' node.dispatchEvent(event);' +
-' }' +
-' </script>' +
-' <div id="activationSnippet" onclick="activateProvider(this)">' +
-' <img src="chrome://branding/content/icon32.png"></img>' +
-' </div>';
-
-var gTests = [
-
-{
- desc: "Test activation with enable panel",
- snippet: snippet,
- panel: true
-},
-
-{
- desc: "Test activation bypassing enable panel",
- snippet: snippet2,
- panel: false
-}
-];
-
-function test()
-{
- waitForExplicitFinish();
- requestLongerTimeout(2);
- ignoreAllUncaughtExceptions();
- PopupNotifications.panel.setAttribute("animate", "false");
- registerCleanupFunction(function () {
- PopupNotifications.panel.removeAttribute("animate");
- });
-
- Task.spawn(function* () {
- for (let test of gTests) {
- info(test.desc);
-
- // Create a tab to run the test.
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
-
- // Add an event handler to modify the snippets map once it's ready.
- let snippetsPromise = promiseSetupSnippetsMap(tab, test.snippet);
-
- // Start loading about:home and wait for it to complete, snippets should be loaded
- yield promiseTabLoadEvent(tab, "about:home", "AboutHomeLoadSnippetsCompleted");
-
- yield snippetsPromise;
-
- // ensure our activation snippet is indeed available
- yield ContentTask.spawn(tab.linkedBrowser, {}, function*(arg) {
- ok(!!content.document.getElementById("snippets"), "Found snippets element");
- ok(!!content.document.getElementById("activationSnippet"), "The snippet is present.");
- });
-
- yield new Promise(resolve => {
- activateProvider(tab, test.panel).then(() => {
- checkSocialUI();
- SocialService.uninstallProvider("https://example.com", function () {
- info("provider uninstalled");
- resolve();
- });
- });
- });
-
- // activation opened a post-activation info tab, close it.
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield BrowserTestUtils.removeTab(tab);
- }
- }).then(finish, ex => {
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
-}
-
-/**
- * Starts a load in an existing tab and waits for it to finish (via some event).
- *
- * @param aTab
- * The tab to load into.
- * @param aUrl
- * The url to load.
- * @param aEvent
- * The load event type to wait for. Defaults to "load".
- * @return {Promise} resolved when the event is handled.
- */
-function promiseTabLoadEvent(aTab, aURL, aEventType="load")
-{
- return new Promise(resolve => {
- info("Wait tab event: " + aEventType);
- aTab.linkedBrowser.addEventListener(aEventType, function load(event) {
- if (event.originalTarget != aTab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank") {
- info("skipping spurious load event");
- return;
- }
- aTab.linkedBrowser.removeEventListener(aEventType, load, true);
- info("Tab event received: " + aEventType);
- resolve();
- }, true, true);
- aTab.linkedBrowser.loadURI(aURL);
- });
-}
-
-/**
- * Cleans up snippets and ensures that by default we don't try to check for
- * remote snippets since that may cause network bustage or slowness.
- *
- * @param aTab
- * The tab containing about:home.
- * @param aSetupFn
- * The setup function to be run.
- * @return {Promise} resolved when the snippets are ready. Gets the snippets map.
- */
-function promiseSetupSnippetsMap(aTab, aSnippet)
-{
- info("Waiting for snippets map");
-
- return ContentTask.spawn(aTab.linkedBrowser,
- {snippetsVersion: AboutHomeUtils.snippetsVersion,
- snippet: aSnippet},
- function*(arg) {
- return new Promise(resolve => {
- addEventListener("AboutHomeLoadSnippets", function load(event) {
- removeEventListener("AboutHomeLoadSnippets", load, true);
-
- let cw = content.window.wrappedJSObject;
-
- // The snippets should already be ready by this point. Here we're
- // just obtaining a reference to the snippets map.
- cw.ensureSnippetsMapThen(function (aSnippetsMap) {
- aSnippetsMap = Cu.waiveXrays(aSnippetsMap);
- console.log("Got snippets map: " +
- "{ last-update: " + aSnippetsMap.get("snippets-last-update") +
- ", cached-version: " + aSnippetsMap.get("snippets-cached-version") +
- " }");
- // Don't try to update.
- aSnippetsMap.set("snippets-last-update", Date.now());
- aSnippetsMap.set("snippets-cached-version", arg.snippetsVersion);
- // Clear snippets.
- aSnippetsMap.delete("snippets");
- aSnippetsMap.set("snippets", arg.snippet);
- resolve();
- });
- }, true, true);
- });
- });
-}
-
-
-function sendActivationEvent(tab) {
- // hack Social.lastEventReceived so we don't hit the "too many events" check.
- Social.lastEventReceived = 0;
- let doc = tab.linkedBrowser.contentDocument;
- // if our test has a frame, use it
- if (doc.defaultView.frames[0])
- doc = doc.defaultView.frames[0].document;
- let button = doc.getElementById("activationSnippet");
- BrowserTestUtils.synthesizeMouseAtCenter(button, {}, tab.linkedBrowser);
-}
-
-function activateProvider(tab, expectPanel, aCallback) {
- return new Promise(resolve => {
- if (expectPanel) {
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
- let panel = document.getElementById("servicesInstall-notification");
- panel.button.click();
- });
- }
- waitForProviderLoad().then(() => {
- checkSocialUI();
- resolve();
- });
- sendActivationEvent(tab);
- });
-}
-
-function waitForProviderLoad(cb) {
- return Promise.all([
- promiseObserverNotified("social:provider-enabled"),
- ensureFrameLoaded(gBrowser, "https://example.com/browser/browser/base/content/test/social/social_postActivation.html"),
- ]);
-}
diff --git a/browser/base/content/test/social/browser_addons.js b/browser/base/content/test/social/browser_addons.js
deleted file mode 100644
index 5a75d1d67..000000000
--- a/browser/base/content/test/social/browser_addons.js
+++ /dev/null
@@ -1,217 +0,0 @@
-var AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm", {}).AddonManager;
-var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
-
-var manifest = {
- name: "provider 1",
- origin: "https://example.com",
- shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html",
- iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
-};
-var manifest2 = { // used for testing install
- name: "provider 2",
- origin: "https://test1.example.com",
- shareURL: "https://test1.example.com/browser/browser/base/content/test/social/social_share.html",
- iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png",
- version: "1.0"
-};
-var manifestUpgrade = { // used for testing install
- name: "provider 3",
- origin: "https://test2.example.com",
- shareURL: "https://test2.example.com/browser/browser/base/content/test/social/social_share.html",
- iconURL: "https://test2.example.com/browser/browser/base/content/test/general/moz.png",
- version: "1.0"
-};
-
-function test() {
- waitForExplicitFinish();
- PopupNotifications.panel.setAttribute("animate", "false");
- registerCleanupFunction(function () {
- PopupNotifications.panel.removeAttribute("animate");
- });
-
- let prefname = getManifestPrefname(manifest);
- // ensure that manifest2 is NOT showing as builtin
- is(SocialService.getOriginActivationType(manifest.origin), "foreign", "manifest is foreign");
- is(SocialService.getOriginActivationType(manifest2.origin), "foreign", "manifest2 is foreign");
-
- Services.prefs.setBoolPref("social.remote-install.enabled", true);
- runSocialTests(tests, undefined, undefined, function () {
- Services.prefs.clearUserPref("social.remote-install.enabled");
- ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
- // just in case the tests failed, clear these here as well
- Services.prefs.clearUserPref("social.directories");
- finish();
- });
-}
-
-function installListener(next, aManifest) {
- let expectEvent = "onInstalling";
- let prefname = getManifestPrefname(aManifest);
- // wait for the actual removal to call next
- SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
- if (topic == "provider-disabled") {
- SocialService.unregisterProviderListener(providerListener);
- is(origin, aManifest.origin, "provider disabled");
- executeSoon(next);
- }
- });
-
- return {
- onInstalling: function(addon) {
- is(expectEvent, "onInstalling", "install started");
- is(addon.manifest.origin, aManifest.origin, "provider about to be installed");
- ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
- expectEvent = "onInstalled";
- },
- onInstalled: function(addon) {
- is(addon.manifest.origin, aManifest.origin, "provider installed");
- ok(addon.installDate.getTime() > 0, "addon has installDate");
- ok(addon.updateDate.getTime() > 0, "addon has updateDate");
- ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
- expectEvent = "onUninstalling";
- },
- onUninstalling: function(addon) {
- is(expectEvent, "onUninstalling", "uninstall started");
- is(addon.manifest.origin, aManifest.origin, "provider about to be uninstalled");
- ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
- expectEvent = "onUninstalled";
- },
- onUninstalled: function(addon) {
- is(expectEvent, "onUninstalled", "provider has been uninstalled");
- is(addon.manifest.origin, aManifest.origin, "provider uninstalled");
- ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
- AddonManager.removeAddonListener(this);
- }
- };
-}
-
-var tests = {
- testHTTPInstallFailure: function(next) {
- let installFrom = "http://example.com";
- is(SocialService.getOriginActivationType(installFrom), "foreign", "testing foriegn install");
- let data = {
- origin: installFrom,
- url: installFrom+"/activate",
- manifest: manifest,
- window: window
- }
- Social.installProvider(data, function(addonManifest) {
- ok(!addonManifest, "unable to install provider over http");
- next();
- });
- },
- testAddonEnableToggle: function(next) {
- let expectEvent;
- let prefname = getManifestPrefname(manifest);
- let listener = {
- onEnabled: function(addon) {
- is(expectEvent, "onEnabled", "provider onEnabled");
- ok(!addon.userDisabled, "provider enabled");
- executeSoon(function() {
- expectEvent = "onDisabling";
- addon.userDisabled = true;
- });
- },
- onEnabling: function(addon) {
- is(expectEvent, "onEnabling", "provider onEnabling");
- expectEvent = "onEnabled";
- },
- onDisabled: function(addon) {
- is(expectEvent, "onDisabled", "provider onDisabled");
- ok(addon.userDisabled, "provider disabled");
- AddonManager.removeAddonListener(listener);
- // clear the provider user-level pref
- Services.prefs.clearUserPref(prefname);
- executeSoon(next);
- },
- onDisabling: function(addon) {
- is(expectEvent, "onDisabling", "provider onDisabling");
- expectEvent = "onDisabled";
- }
- };
- AddonManager.addAddonListener(listener);
-
- // we're only testing enable disable, so we quickly set the user-level pref
- // for this provider and test enable/disable toggling
- setManifestPref(prefname, manifest);
- ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
- AddonManager.getAddonsByTypes(["service"], function(addons) {
- for (let addon of addons) {
- if (addon.userDisabled) {
- expectEvent = "onEnabling";
- addon.userDisabled = false;
- // only test with one addon
- return;
- }
- }
- ok(false, "no addons toggled");
- next();
- });
- },
- testProviderEnableToggle: function(next) {
- // enable and disabel a provider from the SocialService interface, check
- // that the addon manager is updated
-
- let expectEvent;
- let prefname = getManifestPrefname(manifest);
-
- let listener = {
- onEnabled: function(addon) {
- is(expectEvent, "onEnabled", "provider onEnabled");
- is(addon.manifest.origin, manifest.origin, "provider enabled");
- ok(!addon.userDisabled, "provider !userDisabled");
- },
- onEnabling: function(addon) {
- is(expectEvent, "onEnabling", "provider onEnabling");
- is(addon.manifest.origin, manifest.origin, "provider about to be enabled");
- expectEvent = "onEnabled";
- },
- onDisabled: function(addon) {
- is(expectEvent, "onDisabled", "provider onDisabled");
- is(addon.manifest.origin, manifest.origin, "provider disabled");
- ok(addon.userDisabled, "provider userDisabled");
- },
- onDisabling: function(addon) {
- is(expectEvent, "onDisabling", "provider onDisabling");
- is(addon.manifest.origin, manifest.origin, "provider about to be disabled");
- expectEvent = "onDisabled";
- }
- };
- AddonManager.addAddonListener(listener);
-
- expectEvent = "onEnabling";
- setManifestPref(prefname, manifest);
- SocialService.enableProvider(manifest.origin, function(provider) {
- expectEvent = "onDisabling";
- SocialService.disableProvider(provider.origin, function() {
- AddonManager.removeAddonListener(listener);
- Services.prefs.clearUserPref(prefname);
- next();
- });
- });
- },
- testDirectoryInstall: function(next) {
- AddonManager.addAddonListener(installListener(next, manifest2));
-
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
- let panel = document.getElementById("servicesInstall-notification");
- info("servicesInstall-notification panel opened");
- panel.button.click();
- });
-
- Services.prefs.setCharPref("social.directories", manifest2.origin);
- is(SocialService.getOriginActivationType(manifest2.origin), "directory", "testing directory install");
- let data = {
- origin: manifest2.origin,
- url: manifest2.origin + "/directory",
- manifest: manifest2,
- window: window
- }
- Social.installProvider(data, function(addonManifest) {
- Services.prefs.clearUserPref("social.directories");
- SocialService.enableProvider(addonManifest.origin, function(provider) {
- Social.uninstallProvider(addonManifest.origin);
- });
- });
- }
-}
diff --git a/browser/base/content/test/social/browser_blocklist.js b/browser/base/content/test/social/browser_blocklist.js
deleted file mode 100644
index b67d5efb3..000000000
--- a/browser/base/content/test/social/browser_blocklist.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// a place for miscellaneous social tests
-
-var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
-
-const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul";
-var blocklistURL = "http://example.com/browser/browser/base/content/test/social/blocklist.xml";
-
-var manifest = { // normal provider
- name: "provider ok",
- origin: "https://example.com",
- shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html",
- iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
-};
-var manifest_bad = { // normal provider
- name: "provider blocked",
- origin: "https://test1.example.com",
- shareURL: "https://test1.example.com/browser/browser/base/content/test/social/social_share.html",
- iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png"
-};
-
-// blocklist testing
-function updateBlocklist() {
- var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
- .getService(Ci.nsITimerCallback);
- let promise = promiseObserverNotified("blocklist-updated");
- blocklistNotifier.notify(null);
- return promise;
-}
-
-var _originalTestBlocklistURL = null;
-function setAndUpdateBlocklist(aURL) {
- if (!_originalTestBlocklistURL)
- _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
- Services.prefs.setCharPref("extensions.blocklist.url", aURL);
- return updateBlocklist();
-}
-
-function resetBlocklist() {
- // XXX - this has "forked" from the head.js helpers in our parent directory :(
- // But let's reuse their blockNoPlugins.xml. Later, we should arrange to
- // use their head.js helpers directly
- let noBlockedURL = "http://example.com/browser/browser/base/content/test/plugins/blockNoPlugins.xml";
- return new Promise(resolve => {
- setAndUpdateBlocklist(noBlockedURL).then(() => {
- Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
- resolve();
- });
- });
-}
-
-function test() {
- waitForExplicitFinish();
- // turn on logging for nsBlocklistService.js
- Services.prefs.setBoolPref("extensions.logging.enabled", true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("extensions.logging.enabled");
- });
-
- runSocialTests(tests, undefined, undefined, function () {
- resetBlocklist().then(finish); // restore to original pref
- });
-}
-
-var tests = {
- testSimpleBlocklist: function(next) {
- // this really just tests adding and clearing our blocklist for later tests
- setAndUpdateBlocklist(blocklistURL).then(() => {
- ok(Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest_bad)), "blocking 'blocked'");
- ok(!Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest)), "not blocking 'good'");
- resetBlocklist().then(() => {
- ok(!Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest_bad)), "blocklist cleared");
- next();
- });
- });
- },
- testAddingNonBlockedProvider: function(next) {
- function finishTest(isgood) {
- ok(isgood, "adding non-blocked provider ok");
- Services.prefs.clearUserPref("social.manifest.good");
- resetBlocklist().then(next);
- }
- setManifestPref("social.manifest.good", manifest);
- setAndUpdateBlocklist(blocklistURL).then(() => {
- try {
- SocialService.addProvider(manifest, function(provider) {
- try {
- SocialService.disableProvider(provider.origin, function() {
- ok(true, "added and removed provider");
- finishTest(true);
- });
- } catch (e) {
- ok(false, "SocialService.disableProvider threw exception: " + e);
- finishTest(false);
- }
- });
- } catch (e) {
- ok(false, "SocialService.addProvider threw exception: " + e);
- finishTest(false);
- }
- });
- },
- testAddingBlockedProvider: function(next) {
- function finishTest(good) {
- ok(good, "Unable to add blocklisted provider");
- Services.prefs.clearUserPref("social.manifest.blocked");
- resetBlocklist().then(next);
- }
- setManifestPref("social.manifest.blocked", manifest_bad);
- setAndUpdateBlocklist(blocklistURL).then(() => {
- try {
- SocialService.addProvider(manifest_bad, function(provider) {
- SocialService.disableProvider(provider.origin, function() {
- ok(false, "SocialService.addProvider should throw blocklist exception");
- finishTest(false);
- });
- });
- } catch (e) {
- ok(true, "SocialService.addProvider should throw blocklist exception: " + e);
- finishTest(true);
- }
- });
- },
- testInstallingBlockedProvider: function(next) {
- function finishTest(good) {
- ok(good, "Unable to install blocklisted provider");
- resetBlocklist().then(next);
- }
- let activationURL = manifest_bad.origin + "/browser/browser/base/content/test/social/social_activate.html"
- setAndUpdateBlocklist(blocklistURL).then(() => {
- try {
- // expecting an exception when attempting to install a hard blocked
- // provider
- let data = {
- origin: manifest_bad.origin,
- url: activationURL,
- manifest: manifest_bad,
- window: window
- }
- Social.installProvider(data, function(addonManifest) {
- finishTest(false);
- });
- } catch (e) {
- finishTest(true);
- }
- });
- },
- testBlockingExistingProvider: function(next) {
- let listener = {
- _window: null,
- onOpenWindow: function(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, false);
-
- domwindow.addEventListener("unload", function _unload() {
- domwindow.removeEventListener("unload", _unload, false);
- info("blocklist window was closed");
- Services.wm.removeListener(listener);
- next();
- }, false);
-
- 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();
- });
- }, false);
- },
- onCloseWindow: function(aXULWindow) { },
- onWindowTitleChange: function(aXULWindow, aNewTitle) { }
- };
-
- Services.wm.addListener(listener);
-
- setManifestPref("social.manifest.blocked", manifest_bad);
- try {
- SocialService.addProvider(manifest_bad, function(provider) {
- // the act of blocking should cause a 'provider-disabled' notification
- // from SocialService.
- SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
- if (topic != "provider-disabled")
- return;
- SocialService.unregisterProviderListener(providerListener);
- is(origin, provider.origin, "provider disabled");
- SocialService.getProvider(provider.origin, function(p) {
- ok(p == null, "blocklisted provider disabled");
- Services.prefs.clearUserPref("social.manifest.blocked");
- resetBlocklist();
- });
- });
- // no callback - the act of updating should cause the listener above
- // to fire.
- setAndUpdateBlocklist(blocklistURL);
- });
- } catch (e) {
- ok(false, "unable to add provider " + e);
- next();
- }
- }
-}
diff --git a/browser/base/content/test/social/browser_share.js b/browser/base/content/test/social/browser_share.js
deleted file mode 100644
index 19dca519b..000000000
--- a/browser/base/content/test/social/browser_share.js
+++ /dev/null
@@ -1,396 +0,0 @@
-
-var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
-
-var baseURL = "https://example.com/browser/browser/base/content/test/social/";
-
-var manifest = { // normal provider
- name: "provider 1",
- origin: "https://example.com",
- iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png",
- shareURL: "https://example.com/browser/browser/base/content/test/social/share.html"
-};
-var activationPage = "https://example.com/browser/browser/base/content/test/social/share_activate.html";
-
-function sendActivationEvent(subframe) {
- // hack Social.lastEventReceived so we don't hit the "too many events" check.
- Social.lastEventReceived = 0;
- let doc = subframe.contentDocument;
- // if our test has a frame, use it
- let button = doc.getElementById("activation");
- ok(!!button, "got the activation button");
- EventUtils.synthesizeMouseAtCenter(button, {}, doc.defaultView);
-}
-
-function test() {
- waitForExplicitFinish();
- Services.prefs.setCharPref("social.shareDirectory", activationPage);
-
- let frameScript = "data:,(" + function frame_script() {
- addEventListener("OpenGraphData", function (aEvent) {
- sendAsyncMessage("sharedata", aEvent.detail);
- }, true, true);
- /* bug 1042991, ensure history is available by calling history.back on close */
- addMessageListener("closeself", function(e) {
- content.history.back();
- content.close();
- }, true);
- /* if text is entered into field, onbeforeunload will cause a modal dialog
- unless dialogs have been disabled for the iframe. */
- content.onbeforeunload = function(e) {
- return 'FAIL.';
- };
- }.toString() + ")();";
- let mm = getGroupMessageManager("social");
- mm.loadFrameScript(frameScript, true);
-
- // Animation on the panel can cause intermittent failures such as bug 1115131.
- SocialShare.panel.setAttribute("animate", "false");
- registerCleanupFunction(function () {
- SocialShare.panel.removeAttribute("animate");
- mm.removeDelayedFrameScript(frameScript);
- Services.prefs.clearUserPref("social.directories");
- Services.prefs.clearUserPref("social.shareDirectory");
- Services.prefs.clearUserPref("social.share.activationPanelEnabled");
- });
- runSocialTests(tests, undefined, function(next) {
- let shareButton = SocialShare.shareButton;
- if (shareButton) {
- CustomizableUI.removeWidgetFromArea("social-share-button", CustomizableUI.AREA_NAVBAR)
- shareButton.remove();
- }
- next();
- });
-}
-
-var corpus = [
- {
- url: baseURL+"opengraph/opengraph.html",
- options: {
- // og:title
- title: ">This is my title<",
- // og:description
- description: "A test corpus file for open graph tags we care about",
- // medium: this.getPageMedium(),
- // source: this.getSourceURL(),
- // og:url
- url: "https://www.mozilla.org/",
- // shortUrl: this.getShortURL(),
- // og:image
- previews:["https://www.mozilla.org/favicon.png"],
- // og:site_name
- siteName: ">My simple test page<"
- }
- },
- {
- // tests that og:url doesn't override the page url if it is bad
- url: baseURL+"opengraph/og_invalid_url.html",
- options: {
- description: "A test corpus file for open graph tags passing a bad url",
- url: baseURL+"opengraph/og_invalid_url.html",
- previews: [],
- siteName: "Evil chrome delivering website"
- }
- },
- {
- url: baseURL+"opengraph/shorturl_link.html",
- options: {
- previews: ["http://example.com/1234/56789.jpg"],
- url: "http://www.example.com/photos/56789/",
- shortUrl: "http://imshort/p/abcde"
- }
- },
- {
- url: baseURL+"opengraph/shorturl_linkrel.html",
- options: {
- previews: ["http://example.com/1234/56789.jpg"],
- url: "http://www.example.com/photos/56789/",
- shortUrl: "http://imshort/p/abcde"
- }
- },
- {
- url: baseURL+"opengraph/shortlink_linkrel.html",
- options: {
- previews: ["http://example.com/1234/56789.jpg"],
- url: "http://www.example.com/photos/56789/",
- shortUrl: "http://imshort/p/abcde"
- }
- }
-];
-
-function hasoptions(testOptions, options) {
- for (let option in testOptions) {
- let data = testOptions[option];
- info("data: "+JSON.stringify(data));
- let message_data = options[option];
- info("message_data: "+JSON.stringify(message_data));
- if (Array.isArray(data)) {
- // the message may have more array elements than we are testing for, this
- // is ok since some of those are hard to test. So we just test that
- // anything in our test data IS in the message.
- ok(Array.every(data, function(item) { return message_data.indexOf(item) >= 0 }), "option "+option);
- } else {
- is(message_data, data, "option "+option);
- }
- }
-}
-
-var tests = {
- testShareDisabledOnActivation: function(next) {
- // starting on about:blank page, share should be visible but disabled when
- // adding provider
- is(gBrowser.currentURI.spec, "about:blank");
-
- // initialize the button into the navbar
- CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
- // ensure correct state
- SocialUI.onCustomizeEnd(window);
-
- SocialService.addProvider(manifest, function(provider) {
- is(SocialUI.enabled, true, "SocialUI is enabled");
- checkSocialUI();
- // share should not be enabled since we only have about:blank page
- let shareButton = SocialShare.shareButton;
- // verify the attribute for proper css
- is(shareButton.getAttribute("disabled"), "true", "share button attribute is disabled");
- // button should be visible
- is(shareButton.hidden, false, "share button is visible");
- SocialService.disableProvider(manifest.origin, next);
- });
- },
- testShareEnabledOnActivation: function(next) {
- // starting from *some* page, share should be visible and enabled when
- // activating provider
- // initialize the button into the navbar
- CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
- // ensure correct state
- SocialUI.onCustomizeEnd(window);
-
- let testData = corpus[0];
- BrowserTestUtils.openNewForegroundTab(gBrowser, testData.url).then(tab => {
- SocialService.addProvider(manifest, function(provider) {
- is(SocialUI.enabled, true, "SocialUI is enabled");
- checkSocialUI();
- // share should not be enabled since we only have about:blank page
- 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");
- BrowserTestUtils.removeTab(tab).then(next);
- });
- });
- },
- testSharePage: function(next) {
- let testTab;
- let testIndex = 0;
- let testData = corpus[testIndex++];
-
- // initialize the button into the navbar
- CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
- // ensure correct state
- SocialUI.onCustomizeEnd(window);
-
- let mm = getGroupMessageManager("social");
- mm.addMessageListener("sharedata", function handler(msg) {
- BrowserTestUtils.removeTab(testTab).then(() => {
- hasoptions(testData.options, JSON.parse(msg.data));
- testData = corpus[testIndex++];
- BrowserTestUtils.waitForCondition(() => { return SocialShare.currentShare == null; }, "share panel closed").then(() => {
- if (testData) {
- runOneTest();
- } else {
- mm.removeMessageListener("sharedata", handler);
- SocialService.disableProvider(manifest.origin, next);
- }
- });
- SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
- });
- });
-
- function runOneTest() {
- BrowserTestUtils.openNewForegroundTab(gBrowser, testData.url).then(tab => {
- testTab = tab;
-
- 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");
-
- SocialShare.sharePage(manifest.origin);
- });
- }
- executeSoon(runOneTest);
- },
- testShareMicroformats: function(next) {
- // initialize the button into the navbar
- CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
- // ensure correct state
- SocialUI.onCustomizeEnd(window);
-
- SocialService.addProvider(manifest, function(provider) {
- let target, testTab;
-
- let expecting = JSON.stringify({
- "url": "https://example.com/browser/browser/base/content/test/social/microformats.html",
- "title": "Raspberry Pi Page",
- "previews": ["https://example.com/someimage.jpg"],
- "microformats": {
- "items": [{
- "type": ["h-product"],
- "properties": {
- "name": ["Raspberry Pi"],
- "photo": ["https://example.com/someimage.jpg"],
- "description": [{
- "value": "The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.",
- "html": "The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming."
- }
- ],
- "url": ["https://example.com/"],
- "price": ["29.95"],
- "review": [{
- "value": "4.5 out of 5",
- "type": ["h-review"],
- "properties": {
- "rating": ["4.5"]
- }
- }
- ],
- "category": ["Computer", "Education"]
- }
- }
- ],
- "rels": {
- "tag": ["https://example.com/wiki/computer", "https://example.com/wiki/education"]
- },
- "rel-urls": {
- "https://example.com/wiki/computer": {
- "text": "Computer",
- "rels": ["tag"]
- },
- "https://example.com/wiki/education": {
- "text": "Education",
- "rels": ["tag"]
- }
- }
- }
- });
-
- let mm = getGroupMessageManager("social");
- mm.addMessageListener("sharedata", function handler(msg) {
- is(msg.data, expecting, "microformats data ok");
- BrowserTestUtils.waitForCondition(() => { return SocialShare.currentShare == null; },
- "share panel closed").then(() => {
- mm.removeMessageListener("sharedata", handler);
- BrowserTestUtils.removeTab(testTab).then(() => {
- SocialService.disableProvider(manifest.origin, next);
- });
- });
- SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
- });
-
- let url = "https://example.com/browser/browser/base/content/test/social/microformats.html"
- BrowserTestUtils.openNewForegroundTab(gBrowser, url).then(tab => {
- testTab = tab;
-
- 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");
-
- let doc = tab.linkedBrowser.contentDocument;
- target = doc.getElementById("simple-hcard");
- SocialShare.sharePage(manifest.origin, null, target);
- });
- });
- },
- testSharePanelActivation: function(next) {
- let testTab;
- // cleared in the cleanup function
- Services.prefs.setCharPref("social.directories", "https://example.com");
- Services.prefs.setBoolPref("social.share.activationPanelEnabled", true);
- // make the iframe so we can wait on the load
- SocialShare._createFrame();
- let iframe = SocialShare.iframe;
-
- // initialize the button into the navbar
- CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
- // ensure correct state
- SocialUI.onCustomizeEnd(window);
-
- ensureFrameLoaded(iframe).then(() => {
- let subframe = iframe.contentDocument.getElementById("activation-frame");
- ensureFrameLoaded(subframe, activationPage).then(() => {
- is(subframe.contentDocument.location.href, activationPage, "activation page loaded");
- promiseObserverNotified("social:provider-enabled").then(() => {
- let mm = getGroupMessageManager("social");
- mm.addMessageListener("sharedata", function handler(msg) {
- ok(true, "share completed");
-
- BrowserTestUtils.waitForCondition(() => { return SocialShare.currentShare == null; },
- "share panel closed").then(() => {
- BrowserTestUtils.removeTab(testTab).then(() => {
- mm.removeMessageListener("sharedata", handler);
- SocialService.uninstallProvider(manifest.origin, next);
- });
- });
- SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
- });
- });
- sendActivationEvent(subframe);
- });
- });
- BrowserTestUtils.openNewForegroundTab(gBrowser, activationPage).then(tab => {
- 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");
-
- testTab = tab;
- SocialShare.sharePage();
- });
- },
- testSharePanelDialog: function(next) {
- let testTab;
- // initialize the button into the navbar
- CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
- // ensure correct state
- SocialUI.onCustomizeEnd(window);
- SocialShare._createFrame();
-
- SocialService.addProvider(manifest, () => {
- BrowserTestUtils.openNewForegroundTab(gBrowser, activationPage).then(tab => {
- 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);
- let topwin = Services.wm.getMostRecentWindow(null);
- is(topwin, window, "no dialog is open");
-
- BrowserTestUtils.removeTab(testTab).then(() => {
- SocialService.disableProvider(manifest.origin, next);
- });
- });
- 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");
-
- testTab = tab;
- SocialShare.sharePage();
- });
- });
- }
-}
diff --git a/browser/base/content/test/social/browser_social_activation.js b/browser/base/content/test/social/browser_social_activation.js
deleted file mode 100644
index 2af0d8021..000000000
--- a/browser/base/content/test/social/browser_social_activation.js
+++ /dev/null
@@ -1,270 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: Assert is null");
-
-
-var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
-
-var tabsToRemove = [];
-
-function removeProvider(provider) {
- return new Promise(resolve => {
- // a full install sets the manifest into a pref, addProvider alone doesn't,
- // make sure we uninstall if the manifest was added.
- if (provider.manifest) {
- SocialService.uninstallProvider(provider.origin, resolve);
- } else {
- SocialService.disableProvider(provider.origin, resolve);
- }
- });
-}
-
-function postTestCleanup(callback) {
- Task.spawn(function* () {
- // any tabs opened by the test.
- for (let tab of tabsToRemove) {
- yield BrowserTestUtils.removeTab(tab);
- }
- tabsToRemove = [];
- // all the providers may have been added.
- while (Social.providers.length > 0) {
- yield removeProvider(Social.providers[0]);
- }
- }).then(callback);
-}
-
-function newTab(url) {
- return new Promise(resolve => {
- BrowserTestUtils.openNewForegroundTab(gBrowser, url).then(tab => {
- tabsToRemove.push(tab);
- resolve(tab);
- });
- });
-}
-
-function sendActivationEvent(tab, callback, nullManifest) {
- // hack Social.lastEventReceived so we don't hit the "too many events" check.
- Social.lastEventReceived = 0;
- BrowserTestUtils.synthesizeMouseAtCenter("#activation", {}, tab.linkedBrowser);
- executeSoon(callback);
-}
-
-function activateProvider(domain, callback, nullManifest) {
- let activationURL = domain+"/browser/browser/base/content/test/social/social_activate_basic.html"
- newTab(activationURL).then(tab => {
- sendActivationEvent(tab, callback, nullManifest);
- });
-}
-
-function activateIFrameProvider(domain, callback) {
- let activationURL = domain+"/browser/browser/base/content/test/social/social_activate_iframe.html"
- newTab(activationURL).then(tab => {
- sendActivationEvent(tab, callback, false);
- });
-}
-
-function waitForProviderLoad(origin) {
- return Promise.all([
- ensureFrameLoaded(gBrowser, origin + "/browser/browser/base/content/test/social/social_postActivation.html"),
- ]);
-}
-
-function getAddonItemInList(aId, aList) {
- var item = aList.firstChild;
- while (item) {
- if ("mAddon" in item && item.mAddon.id == aId) {
- aList.ensureElementIsVisible(item);
- return item;
- }
- item = item.nextSibling;
- }
- return null;
-}
-
-function clickAddonRemoveButton(tab, aCallback) {
- AddonManager.getAddonsByTypes(["service"], function(aAddons) {
- let addon = aAddons[0];
-
- let doc = tab.linkedBrowser.contentDocument;
- let list = doc.getElementById("addon-list");
-
- let item = getAddonItemInList(addon.id, list);
- let button = item._removeBtn;
- isnot(button, null, "Should have a remove button");
- ok(!button.disabled, "Button should not be disabled");
-
- // uninstall happens after about:addons tab is closed, so we wait on
- // disabled
- promiseObserverNotified("social:provider-disabled").then(() => {
- is(item.getAttribute("pending"), "uninstall", "Add-on should be uninstalling");
- executeSoon(function() { aCallback(addon); });
- });
-
- BrowserTestUtils.synthesizeMouseAtCenter(button, {}, tab.linkedBrowser);
- });
-}
-
-function activateOneProvider(manifest, finishActivation, aCallback) {
- info("activating provider "+manifest.name);
- let panel = document.getElementById("servicesInstall-notification");
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
- ok(!panel.hidden, "servicesInstall-notification panel opened");
- if (finishActivation)
- panel.button.click();
- else
- panel.closebutton.click();
- });
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden").then(() => {
- ok(panel.hidden, "servicesInstall-notification panel hidden");
- if (!finishActivation) {
- ok(panel.hidden, "activation panel is not showing");
- executeSoon(aCallback);
- } else {
- waitForProviderLoad(manifest.origin).then(() => {
- checkSocialUI();
- executeSoon(aCallback);
- });
- }
- });
-
- // the test will continue as the popup events fire...
- activateProvider(manifest.origin, function() {
- info("waiting on activation panel to open/close...");
- });
-}
-
-var gTestDomains = ["https://example.com", "https://test1.example.com", "https://test2.example.com"];
-var gProviders = [
- {
- name: "provider 1",
- origin: "https://example.com",
- shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html?provider1",
- iconURL: "chrome://branding/content/icon48.png"
- },
- {
- name: "provider 2",
- origin: "https://test1.example.com",
- shareURL: "https://test1.example.com/browser/browser/base/content/test/social/social_share.html?provider2",
- iconURL: "chrome://branding/content/icon64.png"
- },
- {
- name: "provider 3",
- origin: "https://test2.example.com",
- shareURL: "https://test2.example.com/browser/browser/base/content/test/social/social_share.html?provider2",
- iconURL: "chrome://branding/content/about-logo.png"
- }
-];
-
-
-function test() {
- PopupNotifications.panel.setAttribute("animate", "false");
- registerCleanupFunction(function () {
- PopupNotifications.panel.removeAttribute("animate");
- });
- waitForExplicitFinish();
- SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, () => {
- runSocialTests(tests, undefined, postTestCleanup);
- });
-}
-
-var tests = {
- testActivationWrongOrigin: function(next) {
- // At this stage none of our providers exist, so we expect failure.
- Services.prefs.setBoolPref("social.remote-install.enabled", false);
- activateProvider(gTestDomains[0], function() {
- is(SocialUI.enabled, false, "SocialUI is not enabled");
- let panel = document.getElementById("servicesInstall-notification");
- ok(panel.hidden, "activation panel still hidden");
- checkSocialUI();
- Services.prefs.clearUserPref("social.remote-install.enabled");
- next();
- });
- },
-
- testIFrameActivation: function(next) {
- activateIFrameProvider(gTestDomains[0], function() {
- is(SocialUI.enabled, false, "SocialUI is not enabled");
- let panel = document.getElementById("servicesInstall-notification");
- ok(panel.hidden, "activation panel still hidden");
- checkSocialUI();
- next();
- });
- },
-
- testActivationFirstProvider: function(next) {
- // first up we add a manifest entry for a single provider.
- activateOneProvider(gProviders[0], false, function() {
- // we deactivated leaving no providers left, so Social is disabled.
- checkSocialUI();
- next();
- });
- },
-
- testActivationMultipleProvider: function(next) {
- // The trick with this test is to make sure that Social.providers[1] is
- // the current provider when doing the undo - this makes sure that the
- // Social code doesn't fallback to Social.providers[0], which it will
- // do in some cases (but those cases do not include what this test does)
- // first enable the 2 providers
- SocialService.addProvider(gProviders[0], function() {
- SocialService.addProvider(gProviders[1], function() {
- checkSocialUI();
- // activate the last provider.
- activateOneProvider(gProviders[2], false, function() {
- // we deactivated - the first provider should be enabled.
- checkSocialUI();
- next();
- });
- });
- });
- },
-
- testAddonManagerDoubleInstall: function(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);
- 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(() => {
- tabsToRemove.pop();
- // uninstall the provider
- clickAddonRemoveButton(addonsTab, function(addon) {
- checkSocialUI();
- activateOneProvider(gProviders[0], true, function() {
- info("second 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(() => {
-
- // after closing the addons tab, verify provider is still installed
- AddonManager.getAddonsByTypes(["service"], function(aAddons) {
- is(aAddons.length, 1, "there can be only one");
-
- let doc = addonsTab.linkedBrowser.contentDocument;
- let list = doc.getElementById("addon-list");
- is(list.childNodes.length, 1, "only one addon is displayed");
-
- BrowserTestUtils.removeTab(addonsTab).then(next);
- });
- });
- });
- });
- });
- });
- });
- }, true);
- }
-}
diff --git a/browser/base/content/test/social/head.js b/browser/base/content/test/social/head.js
deleted file mode 100644
index ea175c97a..000000000
--- a/browser/base/content/test/social/head.js
+++ /dev/null
@@ -1,273 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-
-
-function promiseObserverNotified(aTopic) {
- return new Promise(resolve => {
- Services.obs.addObserver(function onNotification(aSubject, aTopic, aData) {
- dump("notification promised "+aTopic);
- Services.obs.removeObserver(onNotification, aTopic);
- TestUtils.executeSoon(() => resolve({subject: aSubject, data: aData}));
- }, aTopic, false);
- });
-}
-
-// Check that a specified (string) URL hasn't been "remembered" (ie, is not
-// in history, will not appear in about:newtab or auto-complete, etc.)
-function promiseSocialUrlNotRemembered(url) {
- return new Promise(resolve => {
- let uri = Services.io.newURI(url, null, null);
- PlacesUtils.asyncHistory.isURIVisited(uri, function(aURI, aIsVisited) {
- ok(!aIsVisited, "social URL " + url + " should not be in global history");
- resolve();
- });
- });
-}
-
-var gURLsNotRemembered = [];
-
-
-function checkProviderPrefsEmpty(isError) {
- let MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
- let prefs = MANIFEST_PREFS.getChildList("", []);
- let c = 0;
- for (let pref of prefs) {
- if (MANIFEST_PREFS.prefHasUserValue(pref)) {
- info("provider [" + pref + "] manifest left installed from previous test");
- c++;
- }
- }
- is(c, 0, "all provider prefs uninstalled from previous test");
- is(Social.providers.length, 0, "all providers uninstalled from previous test " + Social.providers.length);
-}
-
-function defaultFinishChecks() {
- checkProviderPrefsEmpty(true);
- finish();
-}
-
-function runSocialTestWithProvider(manifest, callback, finishcallback) {
-
- let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
-
- let manifests = Array.isArray(manifest) ? manifest : [manifest];
-
- // Check that none of the provider's content ends up in history.
- function* finishCleanUp() {
- for (let i = 0; i < manifests.length; i++) {
- let m = manifests[i];
- for (let what of ['iconURL', 'shareURL']) {
- if (m[what]) {
- yield promiseSocialUrlNotRemembered(m[what]);
- }
- }
- }
- for (let i = 0; i < gURLsNotRemembered.length; i++) {
- yield promiseSocialUrlNotRemembered(gURLsNotRemembered[i]);
- }
- gURLsNotRemembered = [];
- }
-
- info("runSocialTestWithProvider: " + manifests.toSource());
-
- let finishCount = 0;
- function finishIfDone(callFinish) {
- finishCount++;
- if (finishCount == manifests.length)
- Task.spawn(finishCleanUp).then(finishcallback || defaultFinishChecks);
- }
- function removeAddedProviders(cleanup) {
- manifests.forEach(function (m) {
- // If we're "cleaning up", don't call finish when done.
- let callback = cleanup ? function () {} : finishIfDone;
- // Similarly, if we're cleaning up, catch exceptions from removeProvider
- let removeProvider = SocialService.disableProvider.bind(SocialService);
- if (cleanup) {
- removeProvider = function (origin, cb) {
- try {
- SocialService.disableProvider(origin, cb);
- } catch (ex) {
- // Ignore "provider doesn't exist" errors.
- if (ex.message.indexOf("SocialService.disableProvider: no provider with origin") == 0)
- return;
- info("Failed to clean up provider " + origin + ": " + ex);
- }
- }
- }
- removeProvider(m.origin, callback);
- });
- }
- function finishSocialTest(cleanup) {
- removeAddedProviders(cleanup);
- }
-
- let providersAdded = 0;
-
- manifests.forEach(function (m) {
- SocialService.addProvider(m, function(provider) {
-
- providersAdded++;
- info("runSocialTestWithProvider: provider added");
-
- // we want to set the first specified provider as the UI's provider
- if (provider.origin == manifests[0].origin) {
- firstProvider = provider;
- }
-
- // If we've added all the providers we need, call the callback to start
- // the tests (and give it a callback it can call to finish them)
- if (providersAdded == manifests.length) {
- registerCleanupFunction(function () {
- finishSocialTest(true);
- });
- BrowserTestUtils.waitForCondition(() => provider.enabled,
- "providers added and enabled").then(() => {
- info("provider has been enabled");
- callback(finishSocialTest);
- });
- }
- });
- });
-}
-
-function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
- let testIter = (function*() {
- for (let name in tests) {
- if (tests.hasOwnProperty(name)) {
- yield [name, tests[name]];
- }
- }
- })();
- let providersAtStart = Social.providers.length;
- info("runSocialTests: start test run with " + providersAtStart + " providers");
- window.focus();
-
-
- if (cbPreTest === undefined) {
- cbPreTest = function(cb) { cb() };
- }
- if (cbPostTest === undefined) {
- cbPostTest = function(cb) { cb() };
- }
-
- function runNextTest() {
- let result = testIter.next();
- if (result.done) {
- // out of items:
- (cbFinish || defaultFinishChecks)();
- is(providersAtStart, Social.providers.length,
- "runSocialTests: finish test run with " + Social.providers.length + " providers");
- return;
- }
- let [name, func] = result.value;
- // We run on a timeout to help keep the debug messages sane.
- executeSoon(function() {
- function cleanupAndRunNextTest() {
- info("sub-test " + name + " complete");
- cbPostTest(runNextTest);
- }
- cbPreTest(function() {
- info("pre-test: starting with " + Social.providers.length + " providers");
- info("sub-test " + name + " starting");
- try {
- func.call(tests, cleanupAndRunNextTest);
- } catch (ex) {
- ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack);
- cleanupAndRunNextTest();
- }
- })
- });
- }
- runNextTest();
-}
-
-// A fairly large hammer which checks all aspects of the SocialUI for
-// internal consistency.
-function checkSocialUI(win) {
- let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
- // if we have enabled providers, we should also have instances of those
- // providers
- if (SocialService.hasEnabledProviders) {
- ok(Social.providers.length > 0, "providers are enabled");
- } else {
- is(Social.providers.length, 0, "providers are not enabled");
- }
-}
-
-function setManifestPref(name, manifest) {
- let string = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- string.data = JSON.stringify(manifest);
- Services.prefs.setComplexValue(name, Ci.nsISupportsString, string);
-}
-
-function getManifestPrefname(aManifest) {
- // is same as the generated name in SocialServiceInternal.getManifestPrefname
- let originUri = Services.io.newURI(aManifest.origin, null, null);
- return "social.manifest." + originUri.hostPort.replace('.', '-');
-}
-
-function ensureFrameLoaded(frame, uri) {
- return new Promise(resolve => {
- if (frame.contentDocument && frame.contentDocument.readyState == "complete" &&
- (!uri || frame.contentDocument.location.href == uri)) {
- resolve();
- } else {
- frame.addEventListener("load", function handler() {
- if (uri && frame.contentDocument.location.href != uri)
- return;
- frame.removeEventListener("load", handler, true);
- resolve()
- }, true);
- }
- });
-}
-
-// Support for going on and offline.
-// (via browser/base/content/test/browser_bookmark_titles.js)
-var origProxyType = Services.prefs.getIntPref('network.proxy.type');
-
-function toggleOfflineStatus(goOffline) {
- // Bug 968887 fix. when going on/offline, wait for notification before continuing
- return new Promise(resolve => {
- if (!goOffline) {
- Services.prefs.setIntPref('network.proxy.type', origProxyType);
- }
- if (goOffline != Services.io.offline) {
- info("initial offline state " + Services.io.offline);
- let expect = !Services.io.offline;
- Services.obs.addObserver(function offlineChange(subject, topic, data) {
- Services.obs.removeObserver(offlineChange, "network:offline-status-changed");
- info("offline state changed to " + Services.io.offline);
- is(expect, Services.io.offline, "network:offline-status-changed successful toggle");
- resolve();
- }, "network:offline-status-changed", false);
- BrowserOffline.toggleOfflineStatus();
- } else {
- resolve();
- }
- if (goOffline) {
- Services.prefs.setIntPref('network.proxy.type', 0);
- // LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
- Services.cache2.clear();
- }
- });
-}
-
-function goOffline() {
- // Simulate a network outage with offline mode. (Localhost is still
- // accessible in offline mode, so disable the test proxy as well.)
- return toggleOfflineStatus(true);
-}
-
-function goOnline(callback) {
- return toggleOfflineStatus(false);
-}
diff --git a/browser/base/content/test/social/microformats.html b/browser/base/content/test/social/microformats.html
deleted file mode 100644
index 1a0e4436b..000000000
--- a/browser/base/content/test/social/microformats.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
- <body>
- <head><title>Raspberry Pi Page</title></head>
- <div class="hproduct">
- <h2 class="fn">Raspberry Pi</h2>
- <img class="photo" src="https://example.com/someimage.jpg" />
- <p class="description">The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.</p>
- <a class="url" href="https://example.com/">More info about the Raspberry Pi</a>
- <p class="price">29.95</p>
- <p class="review hreview"><span id="test-review" class="rating">4.5</span> out of 5</p>
- <p>Categories:
- <a rel="tag" href="https://example.com/wiki/computer" class="category">Computer</a>,
- <a rel="tag" href="https://example.com/wiki/education" class="category">Education</a>
- </p>
- </div>
- </body>
-</html>
diff --git a/browser/base/content/test/social/moz.png b/browser/base/content/test/social/moz.png
deleted file mode 100644
index 769c63634..000000000
--- a/browser/base/content/test/social/moz.png
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/social/opengraph/og_invalid_url.html b/browser/base/content/test/social/opengraph/og_invalid_url.html
deleted file mode 100644
index ad1dae2be..000000000
--- a/browser/base/content/test/social/opengraph/og_invalid_url.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html xmlns:og="http://ogp.me/ns#">
-<head>
- <meta property="og:url" content="chrome://browser/content/aboutDialog.xul"/>
- <meta property="og:site_name" content="Evil chrome delivering website"/>
- <meta property="og:description"
- content="A test corpus file for open graph tags passing a bad url"/>
-</head>
-<body>
- Open Graph Test Page
-</body>
-</html>
diff --git a/browser/base/content/test/social/opengraph/opengraph.html b/browser/base/content/test/social/opengraph/opengraph.html
deleted file mode 100644
index 50b7703b8..000000000
--- a/browser/base/content/test/social/opengraph/opengraph.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html xmlns:og="http://ogp.me/ns#">
-<head>
- <meta property="og:title" content="&gt;This is my title&lt;"/>
- <meta property="og:url" content="https://www.mozilla.org"/>
- <meta property="og:image" content="https://www.mozilla.org/favicon.png"/>
- <meta property="og:site_name" content="&#62;My simple test page&#60;"/>
- <meta property="og:description"
- content="A test corpus file for open graph tags we care about"/>
-</head>
-<body>
- Open Graph Test Page
-</body>
-</html>
diff --git a/browser/base/content/test/social/opengraph/shortlink_linkrel.html b/browser/base/content/test/social/opengraph/shortlink_linkrel.html
deleted file mode 100644
index 54c40c376..000000000
--- a/browser/base/content/test/social/opengraph/shortlink_linkrel.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<head>
- <link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
- <link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
- <link rel="shortlink" href="http://imshort/p/abcde" />
-</head>
-<body>
- link[rel='shortlink']
-</body>
-</html>
diff --git a/browser/base/content/test/social/opengraph/shorturl_link.html b/browser/base/content/test/social/opengraph/shorturl_link.html
deleted file mode 100644
index 667122cea..000000000
--- a/browser/base/content/test/social/opengraph/shorturl_link.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<head>
- <link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
- <link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
- <link id="shorturl" rev="canonical" type="text/html" href="http://imshort/p/abcde" />
-</head>
-<body>
- link id="shorturl"
-</body>
-</html>
diff --git a/browser/base/content/test/social/opengraph/shorturl_linkrel.html b/browser/base/content/test/social/opengraph/shorturl_linkrel.html
deleted file mode 100644
index 36533528e..000000000
--- a/browser/base/content/test/social/opengraph/shorturl_linkrel.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html>
-<head>
- <title>Test Image</title>
-
- <meta name="description" content="Iron man in a tutu" />
- <meta name="title" content="Test Image" />
-
- <meta name="medium" content="image" />
- <link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
- <link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
- <link id="shorturl" href="http://imshort/p/abcde" />
-
- <meta property="og:title" content="TestImage" />
- <meta property="og:type" content="photos:photo" />
- <meta property="og:url" content="http://www.example.com/photos/56789/" />
- <meta property="og:site_name" content="My Photo Site" />
- <meta property="og:description" content="Iron man in a tutu" />
- <meta property="og:image" content="http://example.com/1234/56789.jpg" />
- <meta property="og:image:width" content="480" />
- <meta property="og:image:height" content="640" />
-</head>
-<body>
- link[rel='shorturl']
-</body>
-</html>
diff --git a/browser/base/content/test/social/share.html b/browser/base/content/test/social/share.html
deleted file mode 100644
index 55cba9844..000000000
--- a/browser/base/content/test/social/share.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
- <head>
- <meta charset="utf-8">
- </head>
- <body onload="document.getElementById('testclose').focus()">
- <p>This is a test social share window.</p>
- <input id="testclose"/>
- </body>
-</html>
diff --git a/browser/base/content/test/social/share_activate.html b/browser/base/content/test/social/share_activate.html
deleted file mode 100644
index 69707e705..000000000
--- a/browser/base/content/test/social/share_activate.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<html>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<head>
- <title>Activation test</title>
-</head>
-<script>
-
-var data = {
- // currently required
- "name": "Demo Social Service",
- // browser_share.js serves this page from "https://example.com"
- "origin": "https://example.com",
- "iconURL": "chrome://branding/content/icon16.png",
- "icon32URL": "chrome://branding/content/favicon32.png",
- "icon64URL": "chrome://branding/content/icon64.png",
- "shareURL": "/browser/browser/base/content/test/social/share.html"
-}
-
-function activate(node) {
- node.setAttribute("data-service", JSON.stringify(data));
- var event = new CustomEvent("ActivateSocialFeature");
- node.dispatchEvent(event);
-}
-
-</script>
-<body>
-
-nothing to see here
-
-<button id="activation" onclick="activate(this, true)">Activate the share provider</button>
-
-</body>
-</html>
diff --git a/browser/base/content/test/social/social_activate.html b/browser/base/content/test/social/social_activate.html
deleted file mode 100644
index 78da597a1..000000000
--- a/browser/base/content/test/social/social_activate.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<html>
-<head>
- <meta charset="utf-8">
- <title>Activation test</title>
-</head>
-<script>
-// icons from http://findicons.com/icon/158311/firefox?id=356182 by ipapun
-var data = {
- // currently required
- "name": "Demo Social Service",
- "iconURL": "chrome://branding/content/icon16.png",
- "icon32URL": "chrome://branding/content/favicon32.png",
- "icon64URL": "chrome://branding/content/icon64.png",
-
- // at least one of these must be defined
- "shareURL": "/browser/browser/base/content/test/social/social_share.html",
- "postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html",
-
- // should be available for display purposes
- "description": "A short paragraph about this provider",
- "author": "Shane Caraveo, Mozilla",
-
- // optional
- "version": "1.0"
-}
-
-function activate(node) {
- node.setAttribute("data-service", JSON.stringify(data));
- var event = new CustomEvent("ActivateSocialFeature");
- node.dispatchEvent(event);
-}
-
-</script>
-<body>
-
-nothing to see here
-
-<button id="activation" onclick="activate(this)">Activate The Demo Provider</button>
-
-</body>
-</html>
diff --git a/browser/base/content/test/social/social_activate_basic.html b/browser/base/content/test/social/social_activate_basic.html
deleted file mode 100644
index 78da597a1..000000000
--- a/browser/base/content/test/social/social_activate_basic.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<html>
-<head>
- <meta charset="utf-8">
- <title>Activation test</title>
-</head>
-<script>
-// icons from http://findicons.com/icon/158311/firefox?id=356182 by ipapun
-var data = {
- // currently required
- "name": "Demo Social Service",
- "iconURL": "chrome://branding/content/icon16.png",
- "icon32URL": "chrome://branding/content/favicon32.png",
- "icon64URL": "chrome://branding/content/icon64.png",
-
- // at least one of these must be defined
- "shareURL": "/browser/browser/base/content/test/social/social_share.html",
- "postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html",
-
- // should be available for display purposes
- "description": "A short paragraph about this provider",
- "author": "Shane Caraveo, Mozilla",
-
- // optional
- "version": "1.0"
-}
-
-function activate(node) {
- node.setAttribute("data-service", JSON.stringify(data));
- var event = new CustomEvent("ActivateSocialFeature");
- node.dispatchEvent(event);
-}
-
-</script>
-<body>
-
-nothing to see here
-
-<button id="activation" onclick="activate(this)">Activate The Demo Provider</button>
-
-</body>
-</html>
diff --git a/browser/base/content/test/social/social_activate_iframe.html b/browser/base/content/test/social/social_activate_iframe.html
deleted file mode 100644
index bde884c9d..000000000
--- a/browser/base/content/test/social/social_activate_iframe.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-<head>
- <title>Activation iframe test</title>
-</head>
-
-<body>
-
-<iframe src="social_activate_basic.html"/>
-
-</body>
-</html>
diff --git a/browser/base/content/test/social/social_crash_content_helper.js b/browser/base/content/test/social/social_crash_content_helper.js
deleted file mode 100644
index 4698b6957..000000000
--- a/browser/base/content/test/social/social_crash_content_helper.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-* http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var Cu = Components.utils;
-
-// Ideally we would use CrashTestUtils.jsm, but that's only available for
-// xpcshell tests - so we just copy a ctypes crasher from it.
-Cu.import("resource://gre/modules/ctypes.jsm");
-var crash = function() { // this will crash when called.
- let zero = new ctypes.intptr_t(8);
- let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
- badptr.contents
-};
-
-
-var TestHelper = {
- init: function() {
- addMessageListener("social-test:crash", this);
- },
-
- receiveMessage: function(msg) {
- switch (msg.name) {
- case "social-test:crash":
- privateNoteIntentionalCrash();
- crash();
- break;
- }
- },
-}
-
-TestHelper.init();
diff --git a/browser/base/content/test/social/social_postActivation.html b/browser/base/content/test/social/social_postActivation.html
deleted file mode 100644
index e0a6acfdf..000000000
--- a/browser/base/content/test/social/social_postActivation.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<html>
-<head>
- <meta charset="utf-8">
- <title>Post-Activation test</title>
-</head>
-
-<body>
-
-Post Activation landing page
-
-</body>
-</html>
diff --git a/browser/base/content/test/tabPrompts/.eslintrc.js b/browser/base/content/test/tabPrompts/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/tabPrompts/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/tabPrompts/browser.ini b/browser/base/content/test/tabPrompts/browser.ini
deleted file mode 100644
index 9b94f14c5..000000000
--- a/browser/base/content/test/tabPrompts/browser.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[browser_closeTabSpecificPanels.js]
-[browser_multiplePrompts.js]
-[browser_openPromptInBackgroundTab.js]
-support-files = openPromptOffTimeout.html
diff --git a/browser/base/content/test/tabPrompts/browser_closeTabSpecificPanels.js b/browser/base/content/test/tabPrompts/browser_closeTabSpecificPanels.js
deleted file mode 100644
index 30c15a56f..000000000
--- a/browser/base/content/test/tabPrompts/browser_closeTabSpecificPanels.js
+++ /dev/null
@@ -1,41 +0,0 @@
-"use strict";
-
-/*
- * This test creates multiple panels, one that has been tagged as specific to its tab's content
- * and one that isn't. When a tab loses focus, panel specific to that tab should close.
- * The non-specific panel should remain open.
- *
- */
-
-add_task(function*() {
- let tab1 = gBrowser.addTab("http://mochi.test:8888/#0");
- let tab2 = gBrowser.addTab("http://mochi.test:8888/#1");
- let specificPanel = document.createElement("panel");
- specificPanel.setAttribute("tabspecific", "true");
- let generalPanel = document.createElement("panel");
- let anchor = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
- anchor.appendChild(specificPanel);
- anchor.appendChild(generalPanel);
- is(specificPanel.state, "closed", "specificPanel starts as closed");
- is(generalPanel.state, "closed", "generalPanel starts as closed");
-
- let specificPanelPromise = BrowserTestUtils.waitForEvent(specificPanel, "popupshown");
- specificPanel.openPopupAtScreen(210, 210);
- yield specificPanelPromise;
- is(specificPanel.state, "open", "specificPanel has been opened");
-
- let generalPanelPromise = BrowserTestUtils.waitForEvent(generalPanel, "popupshown");
- generalPanel.openPopupAtScreen(510, 510);
- yield generalPanelPromise;
- is(generalPanel.state, "open", "generalPanel has been opened");
-
- gBrowser.tabContainer.advanceSelectedTab(-1, true);
- is(specificPanel.state, "closed", "specificPanel panel is closed after its tab loses focus");
- is(generalPanel.state, "open", "generalPanel is still open after tab switch");
-
- specificPanel.remove();
- generalPanel.remove();
- gBrowser.removeTab(tab1);
- gBrowser.removeTab(tab2);
-});
diff --git a/browser/base/content/test/tabPrompts/browser_multiplePrompts.js b/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
deleted file mode 100644
index c548429ea..000000000
--- a/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
+++ /dev/null
@@ -1,72 +0,0 @@
-"use strict";
-
-/*
- * This test triggers multiple alerts on one single tab, because it"s possible
- * for web content to do so. The behavior is described in bug 1266353.
- *
- * We assert the presentation of the multiple alerts, ensuring we show only
- * the oldest one.
- */
-add_task(function*() {
- const PROMPTCOUNT = 5;
-
- let contentScript = function() {
- var i = 5; // contentScript has no access to PROMPTCOUNT.
- window.addEventListener("message", function() {
- i--;
- if (i) {
- window.postMessage("ping", "*");
- }
- alert("Alert countdown #" + i);
- });
- window.postMessage("ping", "*");
- };
- let url = "data:text/html,<script>(" + encodeURIComponent(contentScript.toSource()) + ")();</script>"
-
- let promptsOpenedPromise = new Promise(function(resolve) {
- let unopenedPromptCount = PROMPTCOUNT;
- Services.obs.addObserver(function observer() {
- unopenedPromptCount--;
- if (!unopenedPromptCount) {
- Services.obs.removeObserver(observer, "tabmodal-dialog-loaded");
- info("Prompts opened.");
- resolve();
- }
- }, "tabmodal-dialog-loaded", false);
- });
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url, true);
- info("Tab loaded");
-
- yield promptsOpenedPromise;
-
- let promptsCount = PROMPTCOUNT;
- while (promptsCount--) {
- let prompts = tab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
- is(prompts.length, promptsCount + 1, "There should be " + (promptsCount + 1) + " prompt(s).");
- // The oldest should be the first.
- let i = 0;
- for (let prompt of prompts) {
- is(prompt.Dialog.args.text, "Alert countdown #" + i, "The #" + i + " alert should be labelled as such.");
- if (i !== promptsCount) {
- is(prompt.hidden, true, "This prompt should be hidden.");
- i++;
- continue;
- }
-
- is(prompt.hidden, false, "The last prompt should not be hidden.");
- prompt.onButtonClick(0);
-
- // The click is handled async; wait for an event loop turn for that to
- // happen.
- yield new Promise(function(resolve) {
- Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
- });
- }
- }
-
- let prompts = tab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
- is(prompts.length, 0, "Prompts should all be dismissed.");
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js b/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
deleted file mode 100644
index d244d157a..000000000
--- a/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
+++ /dev/null
@@ -1,66 +0,0 @@
-"use strict";
-
-const ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://example.com/");
-let pageWithAlert = ROOT + "openPromptOffTimeout.html";
-
-registerCleanupFunction(function() {
- Services.perms.removeAll(makeURI(pageWithAlert));
-});
-
-/*
- * This test opens a tab that alerts when it is hidden. We then switch away
- * from the tab, and check that by default the tab is not automatically
- * re-selected. We also check that a checkbox appears in the alert that allows
- * the user to enable this automatically re-selecting. We then check that
- * checking the checkbox does actually enable that behaviour.
- */
-add_task(function*() {
- yield SpecialPowers.pushPrefEnv({"set": [["browser.tabs.dontfocusfordialogs", true]]});
- let firstTab = gBrowser.selectedTab;
- // load page that opens prompt when page is hidden
- let openedTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageWithAlert, true);
- let openedTabGotAttentionPromise = BrowserTestUtils.waitForAttribute("attention", openedTab, "true");
- // switch away from that tab again - this triggers the alert.
- yield BrowserTestUtils.switchTab(gBrowser, firstTab);
- // ... but that's async on e10s...
- yield openedTabGotAttentionPromise;
- // check for attention attribute
- is(openedTab.getAttribute("attention"), "true", "Tab with alert should have 'attention' attribute.");
- ok(!openedTab.selected, "Tab with alert should not be selected");
-
- // switch tab back, and check the checkbox is displayed:
- yield BrowserTestUtils.switchTab(gBrowser, openedTab);
- // check the prompt is there, and the extra row is present
- let prompts = openedTab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
- is(prompts.length, 1, "There should be 1 prompt");
- let ourPrompt = prompts[0];
- let row = ourPrompt.querySelector("row");
- ok(row, "Should have found the row with our checkbox");
- let checkbox = row.querySelector("checkbox[label*='example.com']");
- ok(checkbox, "The checkbox should be there");
- ok(!checkbox.checked, "Checkbox shouldn't be checked");
- // tick box and accept dialog
- checkbox.checked = true;
- ourPrompt.onButtonClick(0);
- // Wait for that click to actually be handled completely.
- yield new Promise(function(resolve) {
- Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
- });
- // check permission is set
- let ps = Services.perms;
- is(ps.ALLOW_ACTION, ps.testPermission(makeURI(pageWithAlert), "focus-tab-by-prompt"),
- "Tab switching should now be allowed");
-
- let openedTabSelectedPromise = BrowserTestUtils.waitForAttribute("selected", openedTab, "true");
- // switch to other tab again
- yield BrowserTestUtils.switchTab(gBrowser, firstTab);
-
- // This is sync in non-e10s, but in e10s we need to wait for this, so yield anyway.
- // Note that the switchTab promise doesn't actually guarantee anything about *which*
- // tab ends up as selected when its event fires, so using that here wouldn't work.
- yield openedTabSelectedPromise;
- // should be switched back
- ok(openedTab.selected, "Ta-dah, the other tab should now be selected again!");
-
- yield BrowserTestUtils.removeTab(openedTab);
-});
diff --git a/browser/base/content/test/tabPrompts/openPromptOffTimeout.html b/browser/base/content/test/tabPrompts/openPromptOffTimeout.html
deleted file mode 100644
index e865c7872..000000000
--- a/browser/base/content/test/tabPrompts/openPromptOffTimeout.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<body>
-This page opens an alert box when the page is hidden.
-<script>
-document.addEventListener("visibilitychange", () => {
- if (document.hidden) {
- alert("You hid my page!");
- }
-}, false);
-</script>
-</body>
diff --git a/browser/base/content/test/tabcrashed/browser.ini b/browser/base/content/test/tabcrashed/browser.ini
deleted file mode 100644
index 051b40d9f..000000000
--- a/browser/base/content/test/tabcrashed/browser.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
-[browser_shown.js]
-skip-if = !e10s || !crashreporter
-[browser_clearEmail.js]
-skip-if = !e10s || !crashreporter
-[browser_showForm.js]
-skip-if = !e10s || !crashreporter
-[browser_withoutDump.js]
-skip-if = !e10s
-[browser_autoSubmitRequest.js]
-skip-if = !e10s || !crashreporter
diff --git a/browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js b/browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
deleted file mode 100644
index 778331814..000000000
--- a/browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
+++ /dev/null
@@ -1,152 +0,0 @@
-"use strict";
-
-const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const AUTOSUBMIT_PREF = "browser.crashReports.unsubmittedCheck.autoSubmit2";
-
-const {TabStateFlusher} =
- Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-// On debug builds, crashing tabs results in much thinking, which
-// slows down the test and results in intermittent test timeouts,
-// so we'll pump up the expected timeout for this test.
-requestLongerTimeout(2);
-
-/**
- * Tests that if the user is not configured to autosubmit
- * backlogged crash reports, that we offer to do that, and
- * that the user can accept that offer.
- */
-add_task(function* test_show_form() {
- yield SpecialPowers.pushPrefEnv({
- set: [[AUTOSUBMIT_PREF, false]],
- })
-
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- // Make sure we've flushed the browser messages so that
- // we can restore it.
- yield TabStateFlusher.flush(browser);
-
- // Now crash the browser.
- yield BrowserTestUtils.crashBrowser(browser);
-
- let doc = browser.contentDocument;
-
- // Ensure the request is visible. We can safely reach into
- // the content since about:tabcrashed is an in-process URL.
- let requestAutoSubmit = doc.getElementById("requestAutoSubmit");
- Assert.ok(!requestAutoSubmit.hidden,
- "Request for autosubmission is visible.");
-
- // Since the pref is set to false, the checkbox should be
- // unchecked.
- let autoSubmit = doc.getElementById("autoSubmit");
- Assert.ok(!autoSubmit.checked,
- "Checkbox for autosubmission is not checked.")
-
- // Check the checkbox, and then restore the tab.
- autoSubmit.checked = true;
- let restoreButton = doc.getElementById("restoreTab");
- restoreButton.click();
-
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
-
- // The autosubmission pref should now be set.
- Assert.ok(Services.prefs.getBoolPref(AUTOSUBMIT_PREF),
- "Autosubmission pref should have been set.");
- });
-});
-
-/**
- * Tests that if the user is autosubmitting backlogged crash reports
- * that we don't make the offer again.
- */
-add_task(function* test_show_form() {
- yield SpecialPowers.pushPrefEnv({
- set: [[AUTOSUBMIT_PREF, true]],
- })
-
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- yield TabStateFlusher.flush(browser);
- // Now crash the browser.
- yield BrowserTestUtils.crashBrowser(browser);
-
- let doc = browser.contentDocument;
-
- // Ensure the request is NOT visible. We can safely reach into
- // the content since about:tabcrashed is an in-process URL.
- let requestAutoSubmit = doc.getElementById("requestAutoSubmit");
- Assert.ok(requestAutoSubmit.hidden,
- "Request for autosubmission is not visible.");
-
- // Restore the tab.
- let restoreButton = doc.getElementById("restoreTab");
- restoreButton.click();
-
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
-
- // The autosubmission pref should still be set to true.
- Assert.ok(Services.prefs.getBoolPref(AUTOSUBMIT_PREF),
- "Autosubmission pref should have been set.");
- });
-});
-
-/**
- * Tests that we properly set the autoSubmit preference if the user is
- * presented with a tabcrashed page without a crash report.
- */
-add_task(function* test_no_offer() {
- // We should default to sending the report.
- Assert.ok(TabCrashHandler.prefs.getBoolPref("sendReport"));
-
- yield SpecialPowers.pushPrefEnv({
- set: [[AUTOSUBMIT_PREF, false]],
- });
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- yield TabStateFlusher.flush(browser);
-
- // Make it so that it seems like no dump is available for the next crash.
- prepareNoDump();
-
- // Now crash the browser.
- yield BrowserTestUtils.crashBrowser(browser);
-
- // eslint-disable-next-line mozilla/no-cpows-in-tests
- let doc = browser.contentDocument;
-
- // Ensure the request to autosubmit is invisible, since there's no report.
- let requestRect = doc.getElementById("requestAutoSubmit")
- .getBoundingClientRect();
- Assert.equal(0, requestRect.height,
- "Request for autosubmission has no height");
- Assert.equal(0, requestRect.width,
- "Request for autosubmission has no width");
-
- // Since the pref is set to false, the checkbox should be
- // unchecked.
- let autoSubmit = doc.getElementById("autoSubmit");
- Assert.ok(!autoSubmit.checked,
- "Checkbox for autosubmission is not checked.");
-
- let restoreButton = doc.getElementById("restoreTab");
- restoreButton.click();
-
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
-
- // The autosubmission pref should now be set.
- Assert.ok(!Services.prefs.getBoolPref(AUTOSUBMIT_PREF),
- "Autosubmission pref should not have changed.");
- });
-
- // We should not have changed the default value for sending the report.
- Assert.ok(TabCrashHandler.prefs.getBoolPref("sendReport"));
-});
diff --git a/browser/base/content/test/tabcrashed/browser_clearEmail.js b/browser/base/content/test/tabcrashed/browser_clearEmail.js
deleted file mode 100644
index 9ec04944f..000000000
--- a/browser/base/content/test/tabcrashed/browser_clearEmail.js
+++ /dev/null
@@ -1,85 +0,0 @@
-"use strict";
-
-const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
-const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const EMAIL = "foo@privacy.com";
-
-/**
- * Sets up the browser to send crash reports to the local crash report
- * testing server.
- */
-add_task(function* setup() {
- // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables crash
- // reports. This test needs them enabled. The test also needs a mock
- // report server, and fortunately one is already set up by toolkit/
- // crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
- // which CrashSubmit.jsm uses as a server override.
- let env = Cc["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
- let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
- let serverUrl = env.get("MOZ_CRASHREPORTER_URL");
- env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
- env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
-
- // By default, requesting the email address of the user is disabled.
- // For the purposes of this test, we turn it back on.
- yield SpecialPowers.pushPrefEnv({
- set: [["browser.tabs.crashReporting.requestEmail", true]],
- });
-
- registerCleanupFunction(function() {
- env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
- env.set("MOZ_CRASHREPORTER_URL", serverUrl);
- });
-});
-
-/**
- * Test that if we have an email address stored in prefs, and we decide
- * not to submit the email address in the next crash report, that we
- * clear the email address.
- */
-add_task(function* test_clear_email() {
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- let prefs = TabCrashHandler.prefs;
- let originalSendReport = prefs.getBoolPref("sendReport");
- let originalEmailMe = prefs.getBoolPref("emailMe");
- let originalIncludeURL = prefs.getBoolPref("includeURL");
- let originalEmail = prefs.getCharPref("email");
-
- // Pretend that we stored an email address from the previous
- // crash
- prefs.setCharPref("email", EMAIL);
- prefs.setBoolPref("emailMe", true);
-
- let tab = gBrowser.getTabForBrowser(browser);
- yield BrowserTestUtils.crashBrowser(browser);
- let doc = browser.contentDocument;
-
- // Since about:tabcrashed will run in the parent process, we can safely
- // manipulate its DOM nodes directly
- let emailMe = doc.getElementById("emailMe");
- emailMe.checked = false;
-
- let crashReport = promiseCrashReport({
- Email: "",
- });
-
- let restoreTab = browser.contentDocument.getElementById("restoreTab");
- restoreTab.click();
- yield BrowserTestUtils.waitForEvent(tab, "SSTabRestored");
- yield crashReport;
-
- is(prefs.getCharPref("email"), "", "No email address should be stored");
-
- // Submitting the crash report may have set some prefs regarding how to
- // send tab crash reports. Let's reset them for the next test.
- prefs.setBoolPref("sendReport", originalSendReport);
- prefs.setBoolPref("emailMe", originalEmailMe);
- prefs.setBoolPref("includeURL", originalIncludeURL);
- prefs.setCharPref("email", originalEmail);
- });
-});
-
diff --git a/browser/base/content/test/tabcrashed/browser_showForm.js b/browser/base/content/test/tabcrashed/browser_showForm.js
deleted file mode 100644
index 780af93fb..000000000
--- a/browser/base/content/test/tabcrashed/browser_showForm.js
+++ /dev/null
@@ -1,40 +0,0 @@
-"use strict";
-
-const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-
-// On debug builds, crashing tabs results in much thinking, which
-// slows down the test and results in intermittent test timeouts,
-// so we'll pump up the expected timeout for this test.
-requestLongerTimeout(2);
-
-/**
- * Tests that we show the about:tabcrashed additional details form
- * if the "submit a crash report" checkbox was checked by default.
- */
-add_task(function* test_show_form() {
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- // Flip the pref so that the checkbox should be checked
- // by default.
- let pref = TabCrashHandler.prefs.root + "sendReport";
- yield SpecialPowers.pushPrefEnv({
- set: [[pref, true]]
- });
-
- // Now crash the browser.
- yield BrowserTestUtils.crashBrowser(browser);
-
- let doc = browser.contentDocument;
-
- // Ensure the checkbox is checked. We can safely reach into
- // the content since about:tabcrashed is an in-process URL.
- let checkbox = doc.getElementById("sendReport");
- ok(checkbox.checked, "Send report checkbox is checked.");
-
- // Ensure the options form is displayed.
- let options = doc.getElementById("options");
- ok(!options.hidden, "Showing the crash report options form.");
- });
-});
diff --git a/browser/base/content/test/tabcrashed/browser_shown.js b/browser/base/content/test/tabcrashed/browser_shown.js
deleted file mode 100644
index d09d9438f..000000000
--- a/browser/base/content/test/tabcrashed/browser_shown.js
+++ /dev/null
@@ -1,203 +0,0 @@
-"use strict";
-
-const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
-const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const COMMENTS = "Here's my test comment!";
-const EMAIL = "foo@privacy.com";
-
-/**
- * Sets up the browser to send crash reports to the local crash report
- * testing server.
- */
-add_task(function* setup() {
- // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables crash
- // reports. This test needs them enabled. The test also needs a mock
- // report server, and fortunately one is already set up by toolkit/
- // crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
- // which CrashSubmit.jsm uses as a server override.
- let env = Cc["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
- let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
- let serverUrl = env.get("MOZ_CRASHREPORTER_URL");
- env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
- env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
-
- // On debug builds, crashing tabs results in much thinking, which
- // slows down the test and results in intermittent test timeouts,
- // so we'll pump up the expected timeout for this test.
- requestLongerTimeout(2);
-
- registerCleanupFunction(function() {
- env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
- env.set("MOZ_CRASHREPORTER_URL", serverUrl);
- });
-});
-
-/**
- * This function returns a Promise that resolves once the following
- * actions have taken place:
- *
- * 1) A new tab is opened up at PAGE
- * 2) The tab is crashed
- * 3) The about:tabcrashed page's fields are set in accordance with
- * fieldValues
- * 4) The tab is restored
- * 5) A crash report is received from the testing server
- * 6) Any tab crash prefs that were overwritten are reset
- *
- * @param fieldValues
- * An Object describing how to set the about:tabcrashed
- * fields. The following properties are accepted:
- *
- * comments (String)
- * The comments to put in the comment textarea
- * email (String)
- * The email address to put in the email address input
- * emailMe (bool)
- * The checked value of the "Email me" checkbox
- * includeURL (bool)
- * The checked value of the "Include URL" checkbox
- *
- * If any of these fields are missing, the defaults from
- * the user preferences are used.
- * @param expectedExtra
- * An Object describing the expected values that the submitted
- * crash report's extra data should contain.
- * @returns Promise
- */
-function crashTabTestHelper(fieldValues, expectedExtra) {
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- let prefs = TabCrashHandler.prefs;
- let originalSendReport = prefs.getBoolPref("sendReport");
- let originalEmailMe = prefs.getBoolPref("emailMe");
- let originalIncludeURL = prefs.getBoolPref("includeURL");
- let originalEmail = prefs.getCharPref("email");
-
- let tab = gBrowser.getTabForBrowser(browser);
- yield BrowserTestUtils.crashBrowser(browser);
- let doc = browser.contentDocument;
-
- // Since about:tabcrashed will run in the parent process, we can safely
- // manipulate its DOM nodes directly
- let comments = doc.getElementById("comments");
- let email = doc.getElementById("email");
- let emailMe = doc.getElementById("emailMe");
- let includeURL = doc.getElementById("includeURL");
-
- if (fieldValues.hasOwnProperty("comments")) {
- comments.value = fieldValues.comments;
- }
-
- if (fieldValues.hasOwnProperty("email")) {
- email.value = fieldValues.email;
- }
-
- if (fieldValues.hasOwnProperty("emailMe")) {
- emailMe.checked = fieldValues.emailMe;
- }
-
- if (fieldValues.hasOwnProperty("includeURL")) {
- includeURL.checked = fieldValues.includeURL;
- }
-
- let crashReport = promiseCrashReport(expectedExtra);
- let restoreTab = browser.contentDocument.getElementById("restoreTab");
- restoreTab.click();
- yield BrowserTestUtils.waitForEvent(tab, "SSTabRestored");
- yield crashReport;
-
- // Submitting the crash report may have set some prefs regarding how to
- // send tab crash reports. Let's reset them for the next test.
- prefs.setBoolPref("sendReport", originalSendReport);
- prefs.setBoolPref("emailMe", originalEmailMe);
- prefs.setBoolPref("includeURL", originalIncludeURL);
- prefs.setCharPref("email", originalEmail);
- });
-}
-
-/**
- * Tests what we send with the crash report by default. By default, we do not
- * send any comments, the URL of the crashing page, or the email address of
- * the user.
- */
-add_task(function* test_default() {
- yield crashTabTestHelper({}, {
- "Comments": null,
- "URL": "",
- "Email": null,
- });
-});
-
-/**
- * Test just sending a comment.
- */
-add_task(function* test_just_a_comment() {
- yield crashTabTestHelper({
- comments: COMMENTS,
- }, {
- "Comments": COMMENTS,
- "URL": "",
- "Email": null,
- });
-});
-
-/**
- * Test that we don't send email if emailMe is unchecked
- */
-add_task(function* test_no_email() {
- yield crashTabTestHelper({
- email: EMAIL,
- emailMe: false,
- }, {
- "Comments": null,
- "URL": "",
- "Email": null,
- });
-});
-
-/**
- * Test that we can send an email address if emailMe is checked
- */
-add_task(function* test_yes_email() {
- yield crashTabTestHelper({
- email: EMAIL,
- emailMe: true,
- }, {
- "Comments": null,
- "URL": "",
- "Email": EMAIL,
- });
-});
-
-/**
- * Test that we will send the URL of the page if includeURL is checked.
- */
-add_task(function* test_send_URL() {
- yield crashTabTestHelper({
- includeURL: true,
- }, {
- "Comments": null,
- "URL": PAGE,
- "Email": null,
- });
-});
-
-/**
- * Test that we can send comments, the email address, and the URL
- */
-add_task(function* test_send_all() {
- yield crashTabTestHelper({
- includeURL: true,
- emailMe: true,
- email: EMAIL,
- comments: COMMENTS,
- }, {
- "Comments": COMMENTS,
- "URL": PAGE,
- "Email": EMAIL,
- });
-});
-
diff --git a/browser/base/content/test/tabcrashed/browser_withoutDump.js b/browser/base/content/test/tabcrashed/browser_withoutDump.js
deleted file mode 100644
index 62557f443..000000000
--- a/browser/base/content/test/tabcrashed/browser_withoutDump.js
+++ /dev/null
@@ -1,36 +0,0 @@
-"use strict";
-
-const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-
-add_task(function* setup() {
- prepareNoDump();
-});
-
-/**
- * Tests tab crash page when a dump is not available.
- */
-add_task(function* test_without_dump() {
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- let tab = gBrowser.getTabForBrowser(browser);
- yield BrowserTestUtils.crashBrowser(browser);
-
- let tabRemovedPromise = BrowserTestUtils.removeTab(tab, { dontRemove: true });
-
- yield ContentTask.spawn(browser, null, function*() {
- let doc = content.document;
- Assert.ok(!doc.documentElement.classList.contains("crashDumpAvailable"),
- "doesn't have crash dump");
-
- let options = doc.getElementById("options");
- Assert.ok(options, "has crash report options");
- Assert.ok(options.hidden, "crash report options are hidden");
-
- doc.getElementById("closeTab").click();
- });
-
- yield tabRemovedPromise;
- });
-});
diff --git a/browser/base/content/test/tabcrashed/head.js b/browser/base/content/test/tabcrashed/head.js
deleted file mode 100644
index 6eee08f13..000000000
--- a/browser/base/content/test/tabcrashed/head.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Returns a Promise that resolves once a crash report has
- * been submitted. This function will also test the crash
- * reports extra data to see if it matches expectedExtra.
- *
- * @param expectedExtra (object)
- * An Object whose key-value pairs will be compared
- * against the key-value pairs in the extra data of the
- * crash report. A test failure will occur if there is
- * a mismatch.
- *
- * If the value of the key-value pair is "null", this will
- * be interpreted as "this key should not be included in the
- * extra data", and will cause a test failure if it is detected
- * in the crash report.
- *
- * Note that this will ignore any keys that are not included
- * in expectedExtra. It's possible that the crash report
- * will contain other extra information that is not
- * compared against.
- * @returns Promise
- */
-function promiseCrashReport(expectedExtra={}) {
- return Task.spawn(function*() {
- info("Starting wait on crash-report-status");
- let [subject, ] =
- yield TestUtils.topicObserved("crash-report-status", (unused, data) => {
- return data == "success";
- });
- info("Topic observed!");
-
- if (!(subject instanceof Ci.nsIPropertyBag2)) {
- throw new Error("Subject was not a Ci.nsIPropertyBag2");
- }
-
- let remoteID = getPropertyBagValue(subject, "serverCrashID");
- if (!remoteID) {
- throw new Error("Report should have a server ID");
- }
-
- let file = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(Services.crashmanager._submittedDumpsDir);
- file.append(remoteID + ".txt");
- if (!file.exists()) {
- throw new Error("Report should have been received by the server");
- }
-
- file.remove(false);
-
- let extra = getPropertyBagValue(subject, "extra");
- if (!(extra instanceof Ci.nsIPropertyBag2)) {
- throw new Error("extra was not a Ci.nsIPropertyBag2");
- }
-
- info("Iterating crash report extra keys");
- let enumerator = extra.enumerator;
- while (enumerator.hasMoreElements()) {
- let key = enumerator.getNext().QueryInterface(Ci.nsIProperty).name;
- let value = extra.getPropertyAsAString(key);
- if (key in expectedExtra) {
- if (expectedExtra[key] == null) {
- ok(false, `Got unexpected key ${key} with value ${value}`);
- } else {
- is(value, expectedExtra[key],
- `Crash report had the right extra value for ${key}`);
- }
- }
- }
- });
-}
-
-
-/**
- * For an nsIPropertyBag, returns the value for a given
- * key.
- *
- * @param bag
- * The nsIPropertyBag to retrieve the value from
- * @param key
- * The key that we want to get the value for from the
- * bag
- * @returns The value corresponding to the key from the bag,
- * or null if the value could not be retrieved (for
- * example, if no value is set at that key).
-*/
-function getPropertyBagValue(bag, key) {
- try {
- let val = bag.getProperty(key);
- return val;
- } catch (e) {
- if (e.result != Cr.NS_ERROR_FAILURE) {
- throw e;
- }
- }
-
- return null;
-}
-
-/**
- * Monkey patches TabCrashHandler.getDumpID to return null in order to test
- * about:tabcrashed when a dump is not available.
- */
-function prepareNoDump() {
- let originalGetDumpID = TabCrashHandler.getDumpID;
- TabCrashHandler.getDumpID = function(browser) { return null; };
- registerCleanupFunction(() => {
- TabCrashHandler.getDumpID = originalGetDumpID;
- });
-}
diff --git a/browser/base/content/test/tabs/.eslintrc.js b/browser/base/content/test/tabs/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/tabs/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/tabs/browser.ini b/browser/base/content/test/tabs/browser.ini
deleted file mode 100644
index 7771e0a6e..000000000
--- a/browser/base/content/test/tabs/browser.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[browser_tabSpinnerProbe.js]
-skip-if = !e10s # Tab spinner is e10s only.
-[browser_tabSwitchPrintPreview.js]
-skip-if = os == 'mac'
diff --git a/browser/base/content/test/tabs/browser_tabSpinnerProbe.js b/browser/base/content/test/tabs/browser_tabSpinnerProbe.js
deleted file mode 100644
index c3569c2b1..000000000
--- a/browser/base/content/test/tabs/browser_tabSpinnerProbe.js
+++ /dev/null
@@ -1,93 +0,0 @@
-"use strict";
-
-/**
- * Tests the FX_TAB_SWITCH_SPINNER_VISIBLE_MS and
- * FX_TAB_SWITCH_SPINNER_VISIBLE_LONG_MS telemetry probes
- */
-let gMinHangTime = 500; // ms
-let gMaxHangTime = 5 * 1000; // ms
-
-/**
- * Make a data URI for a generic webpage with a script that hangs for a given
- * amount of time.
- * @param {?Number} aHangMs Number of milliseconds that the hang should last.
- * Defaults to 0.
- * @return {String} The data URI generated.
- */
-function makeDataURI(aHangMs = 0) {
- return `data:text/html,
- <html>
- <head>
- <meta charset="utf-8"/>
- <title>Tab Spinner Test</title>
- <script>
- function hang() {
- let hangDuration = ${aHangMs};
- if (hangDuration > 0) {
- let startTime = window.performance.now();
- while(window.performance.now() - startTime < hangDuration) {}
- }
- }
- </script>
- </head>
- <body>
- <h1 id='header'>Tab Spinner Test</h1>
- </body>
- </html>`;
-}
-
-/**
- * Returns the sum of all values in an array.
- * @param {Array} aArray An array of integers
- * @return {Number} The sum of the integers in the array
- */
-function sum(aArray) {
- return aArray.reduce(function(previousValue, currentValue) {
- return previousValue + currentValue;
- });
-}
-
-/**
- * A generator intended to be run as a Task. It tests one of the tab spinner
- * telemetry probes.
- * @param {String} aProbe The probe to test. Should be one of:
- * - FX_TAB_SWITCH_SPINNER_VISIBLE_MS
- * - FX_TAB_SWITCH_SPINNER_VISIBLE_LONG_MS
- */
-function* testProbe(aProbe) {
- info(`Testing probe: ${aProbe}`);
- let histogram = Services.telemetry.getHistogramById(aProbe);
- let buckets = histogram.snapshot().ranges.filter(function(value) {
- return (value > gMinHangTime && value < gMaxHangTime);
- });
- let delayTime = buckets[0]; // Pick a bucket arbitrarily
-
- // The tab spinner does not show up instantly. We need to hang for a little
- // bit of extra time to account for the tab spinner delay.
- delayTime += gBrowser.selectedTab.linkedBrowser.getTabBrowser()._getSwitcher().TAB_SWITCH_TIMEOUT;
- let dataURI1 = makeDataURI(delayTime);
- let dataURI2 = makeDataURI();
-
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, dataURI1);
- histogram.clear();
- // Queue a hang in the content process when the
- // event loop breathes next.
- ContentTask.spawn(tab1.linkedBrowser, null, function*() {
- content.wrappedJSObject.hang();
- });
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, dataURI2);
- let snapshot = histogram.snapshot();
- yield BrowserTestUtils.removeTab(tab2);
- yield BrowserTestUtils.removeTab(tab1);
- ok(sum(snapshot.counts) > 0,
- `Spinner probe should now have a value in some bucket`);
-}
-
-add_task(function* setup() {
- yield SpecialPowers.pushPrefEnv({
- set: [["dom.ipc.processCount", 1]]
- });
-});
-
-add_task(testProbe.bind(null, "FX_TAB_SWITCH_SPINNER_VISIBLE_MS"));
-add_task(testProbe.bind(null, "FX_TAB_SWITCH_SPINNER_VISIBLE_LONG_MS"));
diff --git a/browser/base/content/test/tabs/browser_tabSwitchPrintPreview.js b/browser/base/content/test/tabs/browser_tabSwitchPrintPreview.js
deleted file mode 100644
index 4ec36a7cc..000000000
--- a/browser/base/content/test/tabs/browser_tabSwitchPrintPreview.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const kURL1 = "data:text/html,Should I stay or should I go?";
-const kURL2 = "data:text/html,I shouldn't be here!";
-
-add_task(function* setup() {
- yield SpecialPowers.pushPrefEnv({
- set: [["dom.ipc.processCount", 1]]
- });
-});
-
-/**
- * Verify that if we open a new tab and try to make it the selected tab while
- * print preview is up, that doesn't happen.
- */
-add_task(function* () {
- yield BrowserTestUtils.withNewTab(kURL1, function* (browser) {
- let tab = gBrowser.addTab(kURL2);
- document.getElementById("cmd_printPreview").doCommand();
- gBrowser.selectedTab = tab;
- yield BrowserTestUtils.waitForCondition(() => gInPrintPreviewMode, "should be in print preview mode");
- isnot(gBrowser.selectedTab, tab, "Selected tab should not be the tab we added");
- is(gBrowser.selectedTab, PrintPreviewListener._printPreviewTab, "Selected tab should be the print preview tab");
- gBrowser.selectedTab = tab;
- isnot(gBrowser.selectedTab, tab, "Selected tab should still not be the tab we added");
- is(gBrowser.selectedTab, PrintPreviewListener._printPreviewTab, "Selected tab should still be the print preview tab");
- PrintUtils.exitPrintPreview();
- yield BrowserTestUtils.waitForCondition(() => !gInPrintPreviewMode, "should be in print preview mode");
- yield BrowserTestUtils.removeTab(tab);
- });
-});
diff --git a/browser/base/content/test/urlbar/.eslintrc.js b/browser/base/content/test/urlbar/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/urlbar/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/urlbar/authenticate.sjs b/browser/base/content/test/urlbar/authenticate.sjs
deleted file mode 100644
index 58da655cf..000000000
--- a/browser/base/content/test/urlbar/authenticate.sjs
+++ /dev/null
@@ -1,220 +0,0 @@
-function handleRequest(request, response)
-{
- try {
- reallyHandleRequest(request, response);
- } catch (e) {
- response.setStatusLine("1.0", 200, "AlmostOK");
- response.write("Error handling request: " + e);
- }
-}
-
-
-function reallyHandleRequest(request, response) {
- var match;
- var requestAuth = true, requestProxyAuth = true;
-
- // Allow the caller to drive how authentication is processed via the query.
- // Eg, http://localhost:8888/authenticate.sjs?user=foo&realm=bar
- // The extra ? allows the user/pass/realm checks to succeed if the name is
- // at the beginning of the query string.
- var query = "?" + request.queryString;
-
- var expected_user = "", expected_pass = "", realm = "mochitest";
- var proxy_expected_user = "", proxy_expected_pass = "", proxy_realm = "mochi-proxy";
- var huge = false, plugin = false, anonymous = false;
- var authHeaderCount = 1;
- // user=xxx
- match = /[^_]user=([^&]*)/.exec(query);
- if (match)
- expected_user = match[1];
-
- // pass=xxx
- match = /[^_]pass=([^&]*)/.exec(query);
- if (match)
- expected_pass = match[1];
-
- // realm=xxx
- match = /[^_]realm=([^&]*)/.exec(query);
- if (match)
- realm = match[1];
-
- // proxy_user=xxx
- match = /proxy_user=([^&]*)/.exec(query);
- if (match)
- proxy_expected_user = match[1];
-
- // proxy_pass=xxx
- match = /proxy_pass=([^&]*)/.exec(query);
- if (match)
- proxy_expected_pass = match[1];
-
- // proxy_realm=xxx
- match = /proxy_realm=([^&]*)/.exec(query);
- if (match)
- proxy_realm = match[1];
-
- // huge=1
- match = /huge=1/.exec(query);
- if (match)
- huge = true;
-
- // plugin=1
- match = /plugin=1/.exec(query);
- if (match)
- plugin = true;
-
- // multiple=1
- match = /multiple=([^&]*)/.exec(query);
- if (match)
- authHeaderCount = match[1]+0;
-
- // anonymous=1
- match = /anonymous=1/.exec(query);
- if (match)
- anonymous = true;
-
- // Look for an authentication header, if any, in the request.
- //
- // EG: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
- //
- // This test only supports Basic auth. The value sent by the client is
- // "username:password", obscured with base64 encoding.
-
- var actual_user = "", actual_pass = "", authHeader, authPresent = false;
- if (request.hasHeader("Authorization")) {
- authPresent = true;
- authHeader = request.getHeader("Authorization");
- match = /Basic (.+)/.exec(authHeader);
- if (match.length != 2)
- throw "Couldn't parse auth header: " + authHeader;
-
- var userpass = base64ToString(match[1]); // no atob() :-(
- match = /(.*):(.*)/.exec(userpass);
- if (match.length != 3)
- throw "Couldn't decode auth header: " + userpass;
- actual_user = match[1];
- actual_pass = match[2];
- }
-
- var proxy_actual_user = "", proxy_actual_pass = "";
- if (request.hasHeader("Proxy-Authorization")) {
- authHeader = request.getHeader("Proxy-Authorization");
- match = /Basic (.+)/.exec(authHeader);
- if (match.length != 2)
- throw "Couldn't parse auth header: " + authHeader;
-
- var userpass = base64ToString(match[1]); // no atob() :-(
- match = /(.*):(.*)/.exec(userpass);
- if (match.length != 3)
- throw "Couldn't decode auth header: " + userpass;
- proxy_actual_user = match[1];
- proxy_actual_pass = match[2];
- }
-
- // Don't request authentication if the credentials we got were what we
- // expected.
- if (expected_user == actual_user &&
- expected_pass == actual_pass) {
- requestAuth = false;
- }
- if (proxy_expected_user == proxy_actual_user &&
- proxy_expected_pass == proxy_actual_pass) {
- requestProxyAuth = false;
- }
-
- if (anonymous) {
- if (authPresent) {
- response.setStatusLine("1.0", 400, "Unexpected authorization header found");
- } else {
- response.setStatusLine("1.0", 200, "Authorization header not found");
- }
- } else {
- if (requestProxyAuth) {
- response.setStatusLine("1.0", 407, "Proxy authentication required");
- for (i = 0; i < authHeaderCount; ++i)
- response.setHeader("Proxy-Authenticate", "basic realm=\"" + proxy_realm + "\"", true);
- } else if (requestAuth) {
- response.setStatusLine("1.0", 401, "Authentication required");
- for (i = 0; i < authHeaderCount; ++i)
- response.setHeader("WWW-Authenticate", "basic realm=\"" + realm + "\"", true);
- } else {
- response.setStatusLine("1.0", 200, "OK");
- }
- }
-
- response.setHeader("Content-Type", "application/xhtml+xml", false);
- response.write("<html xmlns='http://www.w3.org/1999/xhtml'>");
- response.write("<p>Login: <span id='ok'>" + (requestAuth ? "FAIL" : "PASS") + "</span></p>\n");
- response.write("<p>Proxy: <span id='proxy'>" + (requestProxyAuth ? "FAIL" : "PASS") + "</span></p>\n");
- response.write("<p>Auth: <span id='auth'>" + authHeader + "</span></p>\n");
- response.write("<p>User: <span id='user'>" + actual_user + "</span></p>\n");
- response.write("<p>Pass: <span id='pass'>" + actual_pass + "</span></p>\n");
-
- if (huge) {
- response.write("<div style='display: none'>");
- for (i = 0; i < 100000; i++) {
- response.write("123456789\n");
- }
- response.write("</div>");
- response.write("<span id='footnote'>This is a footnote after the huge content fill</span>");
- }
-
- if (plugin) {
- response.write("<embed id='embedtest' style='width: 400px; height: 100px;' " +
- "type='application/x-test'></embed>\n");
- }
-
- response.write("</html>");
-}
-
-
-// base64 decoder
-//
-// Yoinked from extensions/xml-rpc/src/nsXmlRpcClient.js because btoa()
-// doesn't seem to exist. :-(
-/* Convert Base64 data to a string */
-const toBinaryTable = [
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
- 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
- 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
- -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
- 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
-];
-const base64Pad = '=';
-
-function base64ToString(data) {
-
- var result = '';
- var leftbits = 0; // number of bits decoded, but yet to be appended
- var leftdata = 0; // bits decoded, but yet to be appended
-
- // Convert one by one.
- for (var i = 0; i < data.length; i++) {
- var c = toBinaryTable[data.charCodeAt(i) & 0x7f];
- var padding = (data[i] == base64Pad);
- // Skip illegal characters and whitespace
- if (c == -1) continue;
-
- // Collect data into leftdata, update bitcount
- leftdata = (leftdata << 6) | c;
- leftbits += 6;
-
- // If we have 8 or more bits, append 8 bits to the result
- if (leftbits >= 8) {
- leftbits -= 8;
- // Append if not padding.
- if (!padding)
- result += String.fromCharCode((leftdata >> leftbits) & 0xff);
- leftdata &= (1 << leftbits) - 1;
- }
- }
-
- // If there are any bits left, the base64 string was corrupted
- if (leftbits)
- throw Components.Exception('Corrupted base64 string');
-
- return result;
-}
diff --git a/browser/base/content/test/urlbar/browser.ini b/browser/base/content/test/urlbar/browser.ini
deleted file mode 100644
index 39bc086c9..000000000
--- a/browser/base/content/test/urlbar/browser.ini
+++ /dev/null
@@ -1,101 +0,0 @@
-[DEFAULT]
-support-files =
- dummy_page.html
- head.js
-
-[browser_URLBarSetURI.js]
-skip-if = (os == "linux" || os == "mac") && debug # bug 970052, bug 970053
-[browser_action_keyword.js]
-skip-if = os == "linux" # Bug 1188154
-support-files =
- print_postdata.sjs
-[browser_action_keyword_override.js]
-[browser_action_searchengine.js]
-[browser_action_searchengine_alias.js]
-[browser_autocomplete_a11y_label.js]
-[browser_autocomplete_autoselect.js]
-[browser_autocomplete_cursor.js]
-[browser_autocomplete_edit_completed.js]
-[browser_autocomplete_enter_race.js]
-[browser_autocomplete_no_title.js]
-[browser_autocomplete_tag_star_visibility.js]
-[browser_bug1104165-switchtab-decodeuri.js]
-[browser_bug1003461-switchtab-override.js]
-[browser_bug1024133-switchtab-override-keynav.js]
-[browser_bug1025195_switchToTabHavingURI_aOpenParams.js]
-[browser_bug1070778.js]
-[browser_bug1225194-remotetab.js]
-[browser_bug304198.js]
-[browser_bug556061.js]
-subsuite = clipboard
-[browser_bug562649.js]
-[browser_bug623155.js]
-support-files =
- redirect_bug623155.sjs
-[browser_bug783614.js]
-[browser_canonizeURL.js]
-[browser_dragdropURL.js]
-[browser_locationBarCommand.js]
-[browser_locationBarExternalLoad.js]
-[browser_moz_action_link.js]
-[browser_removeUnsafeProtocolsFromURLBarPaste.js]
-subsuite = clipboard
-[browser_search_favicon.js]
-[browser_tabMatchesInAwesomebar.js]
-support-files =
- moz.png
-[browser_tabMatchesInAwesomebar_perwindowpb.js]
-skip-if = os == 'linux' # Bug 1104755
-[browser_urlbarAboutHomeLoading.js]
-[browser_urlbarAutoFillTrimURLs.js]
-[browser_urlbarCopying.js]
-subsuite = clipboard
-support-files =
- authenticate.sjs
-[browser_urlbarDecode.js]
-[browser_urlbarDelete.js]
-[browser_urlbarEnter.js]
-[browser_urlbarEnterAfterMouseOver.js]
-skip-if = os == "linux" # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
-[browser_urlbarFocusedCmdK.js]
-[browser_urlbarHashChangeProxyState.js]
-[browser_urlbarKeepStateAcrossTabSwitches.js]
-[browser_urlbarOneOffs.js]
-[browser_urlbarPrivateBrowsingWindowChange.js]
-[browser_urlbarRaceWithTabs.js]
-[browser_urlbarRevert.js]
-[browser_urlbarSearchSingleWordNotification.js]
-[browser_urlbarSearchSuggestions.js]
-support-files =
- searchSuggestionEngine.xml
- searchSuggestionEngine.sjs
-[browser_urlbarSearchSuggestionsNotification.js]
-support-files =
- searchSuggestionEngine.xml
- searchSuggestionEngine.sjs
-[browser_urlbarSearchTelemetry.js]
-support-files =
- searchSuggestionEngine.xml
- searchSuggestionEngine.sjs
-[browser_urlbarStop.js]
-[browser_urlbarTrimURLs.js]
-subsuite = clipboard
-[browser_urlbarUpdateForDomainCompletion.js]
-[browser_urlbar_autoFill_backspaced.js]
-[browser_urlbar_blanking.js]
-support-files =
- file_blank_but_not_blank.html
-[browser_urlbar_locationchange_urlbar_edit_dos.js]
-support-files =
- file_urlbar_edit_dos.html
-[browser_urlbar_searchsettings.js]
-[browser_urlbar_stop_pending.js]
-support-files =
- slow-page.sjs
-[browser_urlbar_remoteness_switch.js]
-run-if = e10s
-[browser_urlHighlight.js]
-[browser_wyciwyg_urlbarCopying.js]
-subsuite = clipboard
-support-files =
- test_wyciwyg_copying.html
diff --git a/browser/base/content/test/urlbar/browser_URLBarSetURI.js b/browser/base/content/test/urlbar/browser_URLBarSetURI.js
deleted file mode 100644
index ac8352f1a..000000000
--- a/browser/base/content/test/urlbar/browser_URLBarSetURI.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- // avoid prompting about phishing
- Services.prefs.setIntPref(phishyUserPassPref, 32);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(phishyUserPassPref);
- });
-
- nextTest();
-}
-
-const phishyUserPassPref = "network.http.phishy-userpass-length";
-
-function nextTest() {
- let test = tests.shift();
- if (test) {
- test(function () {
- executeSoon(nextTest);
- });
- } else {
- executeSoon(finish);
- }
-}
-
-var tests = [
- function revert(next) {
- loadTabInWindow(window, function (tab) {
- gURLBar.handleRevert();
- is(gURLBar.textValue, "example.com", "URL bar had user/pass stripped after reverting");
- gBrowser.removeTab(tab);
- next();
- });
- },
- function customize(next) {
- // Need to wait for delayedStartup for the customization part of the test,
- // since that's where BrowserToolboxCustomizeDone is set.
- BrowserTestUtils.openNewBrowserWindow().then(function(win) {
- loadTabInWindow(win, function () {
- openToolbarCustomizationUI(function () {
- closeToolbarCustomizationUI(function () {
- is(win.gURLBar.textValue, "example.com", "URL bar had user/pass stripped after customize");
- win.close();
- next();
- }, win);
- }, win);
- });
- });
- },
- function pageloaderror(next) {
- loadTabInWindow(window, function (tab) {
- // Load a new URL and then immediately stop it, to simulate a page load
- // error.
- tab.linkedBrowser.loadURI("http://test1.example.com");
- tab.linkedBrowser.stop();
- is(gURLBar.textValue, "example.com", "URL bar had user/pass stripped after load error");
- gBrowser.removeTab(tab);
- next();
- });
- }
-];
-
-function loadTabInWindow(win, callback) {
- info("Loading tab");
- let url = "http://user:pass@example.com/";
- let tab = win.gBrowser.selectedTab = win.gBrowser.addTab(url);
- BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url).then(() => {
- info("Tab loaded");
- is(win.gURLBar.textValue, "example.com", "URL bar had user/pass stripped initially");
- callback(tab);
- }, true);
-}
-
-function openToolbarCustomizationUI(aCallback, aBrowserWin) {
- if (!aBrowserWin)
- aBrowserWin = window;
-
- aBrowserWin.gCustomizeMode.enter();
-
- aBrowserWin.gNavToolbox.addEventListener("customizationready", function UI_loaded() {
- aBrowserWin.gNavToolbox.removeEventListener("customizationready", UI_loaded);
- executeSoon(function() {
- aCallback(aBrowserWin)
- });
- });
-}
-
-function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
- aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function unloaded() {
- aBrowserWin.gNavToolbox.removeEventListener("aftercustomization", unloaded);
- executeSoon(aCallback);
- });
-
- aBrowserWin.gCustomizeMode.exit();
-}
-
diff --git a/browser/base/content/test/urlbar/browser_action_keyword.js b/browser/base/content/test/urlbar/browser_action_keyword.js
deleted file mode 100644
index 854a7b82f..000000000
--- a/browser/base/content/test/urlbar/browser_action_keyword.js
+++ /dev/null
@@ -1,119 +0,0 @@
-function* promise_first_result(inputText) {
- yield promiseAutocompleteResultPopup(inputText);
-
- let firstResult = gURLBar.popup.richlistbox.firstChild;
- return firstResult;
-}
-
-const TEST_URL = "http://mochi.test:8888/browser/browser/base/content/test/urlbar/print_postdata.sjs";
-
-add_task(function* setup() {
- yield PlacesUtils.keywords.insert({ keyword: "get",
- url: TEST_URL + "?q=%s" });
- yield PlacesUtils.keywords.insert({ keyword: "post",
- url: TEST_URL,
- postData: "q=%s" });
- registerCleanupFunction(function* () {
- yield PlacesUtils.keywords.remove("get");
- yield PlacesUtils.keywords.remove("post");
- while (gBrowser.tabs.length > 1) {
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- }
- });
-});
-
-add_task(function* get_keyword() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- let result = yield promise_first_result("get something");
- isnot(result, null, "Expect a keyword result");
-
- let types = new Set(result.getAttribute("type").split(/\s+/));
- Assert.ok(types.has("keyword"));
- is(result.getAttribute("actiontype"), "keyword", "Expect correct `actiontype` attribute");
- is(result.getAttribute("title"), "mochi.test:8888", "Expect correct title");
-
- // We need to make a real URI out of this to ensure it's normalised for
- // comparison.
- let uri = NetUtil.newURI(result.getAttribute("url"));
- is(uri.spec, PlacesUtils.mozActionURI("keyword",
- { url: TEST_URL + "?q=something",
- input: "get something"}),
- "Expect correct url");
-
- let titleHbox = result._titleText.parentNode.parentNode;
- ok(titleHbox.classList.contains("ac-title"), "Title hbox element sanity check");
- is_element_visible(titleHbox, "Title element should be visible");
- is(result._titleText.textContent, "mochi.test:8888: something",
- "Node should contain the name of the bookmark and query");
-
- let urlHbox = result._urlText.parentNode.parentNode;
- ok(urlHbox.classList.contains("ac-url"), "URL hbox element sanity check");
- is_element_hidden(urlHbox, "URL element should be hidden");
-
- let actionHbox = result._actionText.parentNode.parentNode;
- ok(actionHbox.classList.contains("ac-action"), "Action hbox element sanity check");
- is_element_visible(actionHbox, "Action element should be visible");
- is(result._actionText.textContent, "", "Action text should be empty");
-
- // Click on the result
- info("Normal click on result");
- let tabPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- EventUtils.synthesizeMouseAtCenter(result, {});
- yield tabPromise;
- is(tab.linkedBrowser.currentURI.spec, TEST_URL + "?q=something",
- "Tab should have loaded from clicking on result");
-
- // Middle-click on the result
- info("Middle-click on result");
- result = yield promise_first_result("get somethingmore");
- isnot(result, null, "Expect a keyword result");
- // We need to make a real URI out of this to ensure it's normalised for
- // comparison.
- uri = NetUtil.newURI(result.getAttribute("url"));
- is(uri.spec, PlacesUtils.mozActionURI("keyword",
- { url: TEST_URL + "?q=somethingmore",
- input: "get somethingmore" }),
- "Expect correct url");
-
- tabPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
- EventUtils.synthesizeMouseAtCenter(result, {button: 1});
- let tabOpenEvent = yield tabPromise;
- let newTab = tabOpenEvent.target;
- yield BrowserTestUtils.browserLoaded(newTab.linkedBrowser);
- is(newTab.linkedBrowser.currentURI.spec,
- TEST_URL + "?q=somethingmore",
- "Tab should have loaded from middle-clicking on result");
-});
-
-
-add_task(function* post_keyword() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- let result = yield promise_first_result("post something");
- isnot(result, null, "Expect a keyword result");
-
- let types = new Set(result.getAttribute("type").split(/\s+/));
- Assert.ok(types.has("keyword"));
- is(result.getAttribute("actiontype"), "keyword", "Expect correct `actiontype` attribute");
- is(result.getAttribute("title"), "mochi.test:8888", "Expect correct title");
-
- is(result.getAttribute("url"),
- PlacesUtils.mozActionURI("keyword", { url: TEST_URL,
- input: "post something",
- "postData": "q=something" }),
- "Expect correct url");
-
- // Click on the result
- info("Normal click on result");
- let tabPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- EventUtils.synthesizeMouseAtCenter(result, {});
- yield tabPromise;
- is(tab.linkedBrowser.currentURI.spec, TEST_URL,
- "Tab should have loaded from clicking on result");
-
- let postData = yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
- return content.document.body.textContent;
- });
- is(postData, "q=something", "post data was submitted correctly");
-});
diff --git a/browser/base/content/test/urlbar/browser_action_keyword_override.js b/browser/base/content/test/urlbar/browser_action_keyword_override.js
deleted file mode 100644
index f5a865678..000000000
--- a/browser/base/content/test/urlbar/browser_action_keyword_override.js
+++ /dev/null
@@ -1,40 +0,0 @@
-add_task(function*() {
- let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "http://example.com/?q=%s",
- title: "test" });
- yield PlacesUtils.keywords.insert({ keyword: "keyword",
- url: "http://example.com/?q=%s" })
-
- registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.remove(bm);
- });
-
- yield promiseAutocompleteResultPopup("keyword search");
- let result = gURLBar.popup.richlistbox.children[0];
-
- info("Before override");
- let titleHbox = result._titleText.parentNode.parentNode;
- ok(titleHbox.classList.contains("ac-title"), "Title hbox element sanity check");
- is_element_visible(titleHbox, "Title element should be visible");
-
- let urlHbox = result._urlText.parentNode.parentNode;
- ok(urlHbox.classList.contains("ac-url"), "URL hbox element sanity check");
- is_element_hidden(urlHbox, "URL element should be hidden");
-
- let actionHbox = result._actionText.parentNode.parentNode;
- ok(actionHbox.classList.contains("ac-action"), "Action hbox element sanity check");
- is_element_visible(actionHbox, "Action element should be visible");
- is(result._actionText.textContent, "", "Action text should be empty");
-
- info("During override");
- EventUtils.synthesizeKey("VK_SHIFT", { type: "keydown" });
- is_element_visible(titleHbox, "Title element should be visible");
- is_element_hidden(urlHbox, "URL element should be hidden");
- is_element_visible(actionHbox, "Action element should be visible");
- is(result._actionText.textContent, "", "Action text should be empty");
-
- EventUtils.synthesizeKey("VK_SHIFT", { type: "keyup" });
-
- gURLBar.popup.hidePopup();
- yield promisePopupHidden(gURLBar.popup);
-});
diff --git a/browser/base/content/test/urlbar/browser_action_searchengine.js b/browser/base/content/test/urlbar/browser_action_searchengine.js
deleted file mode 100644
index d2115abba..000000000
--- a/browser/base/content/test/urlbar/browser_action_searchengine.js
+++ /dev/null
@@ -1,36 +0,0 @@
-add_task(function* () {
- Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- let engine = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- registerCleanupFunction(() => {
- Services.search.currentEngine = originalEngine;
- let engine = Services.search.getEngineByName("MozSearch");
- Services.search.removeEngine(engine);
-
- try {
- gBrowser.removeTab(tab);
- } catch (ex) { /* tab may have already been closed in case of failure */ }
-
- return PlacesTestUtils.clearHistory();
- });
-
- yield promiseAutocompleteResultPopup("open a search");
- let result = gURLBar.popup.richlistbox.firstChild;
-
- isnot(result, null, "Should have a result");
- is(result.getAttribute("url"),
- `moz-action:searchengine,{"engineName":"MozSearch","input":"open%20a%20search","searchQuery":"open%20a%20search"}`,
- "Result should be a moz-action: for the correct search engine");
- is(result.hasAttribute("image"), false, "Result shouldn't have an image attribute");
-
- let tabPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- result.click();
- yield tabPromise;
-
- is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search", "Correct URL should be loaded");
-});
diff --git a/browser/base/content/test/urlbar/browser_action_searchengine_alias.js b/browser/base/content/test/urlbar/browser_action_searchengine_alias.js
deleted file mode 100644
index 1967d178a..000000000
--- a/browser/base/content/test/urlbar/browser_action_searchengine_alias.js
+++ /dev/null
@@ -1,35 +0,0 @@
-add_task(function* () {
- let iconURI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC";
- Services.search.addEngineWithDetails("MozSearch", iconURI, "moz", "", "GET",
- "http://example.com/?q={searchTerms}");
- let engine = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- registerCleanupFunction(() => {
- Services.search.currentEngine = originalEngine;
- let engine = Services.search.getEngineByName("MozSearch");
- Services.search.removeEngine(engine);
-
- try {
- gBrowser.removeTab(tab);
- } catch (ex) { /* tab may have already been closed in case of failure */ }
-
- return PlacesTestUtils.clearHistory();
- });
-
- yield promiseAutocompleteResultPopup("moz open a search");
-
- let result = gURLBar.popup.richlistbox.children[0];
- ok(result.hasAttribute("image"), "Result should have an image attribute");
- ok(result.getAttribute("image") === engine.iconURI.spec,
- "Image attribute should have the search engine's icon");
-
- let tabPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- EventUtils.synthesizeKey("VK_RETURN", { });
- yield tabPromise;
-
- is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search");
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js b/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js
deleted file mode 100644
index a27f9672e..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const SUGGEST_ALL_PREF = "browser.search.suggest.enabled";
-const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-
-add_task(function* switchToTab() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:about");
-
- yield promiseAutocompleteResultPopup("% about");
-
- ok(gURLBar.popup.richlistbox.children.length > 1, "Should get at least 2 results");
- let result = gURLBar.popup.richlistbox.children[1];
- is(result.getAttribute("type"), "switchtab", "Expect right type attribute");
- is(result.label, "about:about about:about Tab", "Result a11y label should be: <title> <url> Tab");
-
- gURLBar.popup.hidePopup();
- yield promisePopupHidden(gURLBar.popup);
- gBrowser.removeTab(tab);
-});
-
-add_task(function* searchSuggestions() {
- let engine = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
- let oldCurrentEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
- registerCleanupFunction(function () {
- Services.search.currentEngine = oldCurrentEngine;
- Services.prefs.clearUserPref(SUGGEST_ALL_PREF);
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
- });
-
- yield promiseAutocompleteResultPopup("foo");
- // Don't assume that the search doesn't match history or bookmarks left around
- // by earlier tests.
- Assert.ok(gURLBar.popup.richlistbox.children.length >= 3,
- "Should get at least heuristic result + two search suggestions");
- // The first expected search is the search term itself since the heuristic
- // result will come before the search suggestions.
- let expectedSearches = [
- "foo",
- "foofoo",
- "foobar",
- ];
- for (let child of gURLBar.popup.richlistbox.children) {
- if (child.getAttribute("type").split(/\s+/).indexOf("searchengine") >= 0) {
- Assert.ok(expectedSearches.length > 0);
- let suggestion = expectedSearches.shift();
- Assert.equal(child.label, suggestion + " browser_searchSuggestionEngine searchSuggestionEngine.xml Search",
- "Result label should be: <search term> <engine name> Search");
- }
- }
- Assert.ok(expectedSearches.length == 0);
- gURLBar.closePopup();
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js b/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js
deleted file mode 100644
index e4e0daa8e..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
-
-function repeat(limit, func) {
- for (let i = 0; i < limit; i++) {
- func(i);
- }
-}
-
-function is_selected(index) {
- is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`);
-
- // This is true because although both the listbox and the one-offs can have
- // selections, the test doesn't check that.
- is(gURLBar.popup.oneOffSearchButtons.selectedButton, null,
- "A result is selected, so the one-offs should not have a selection");
-}
-
-function is_selected_one_off(index) {
- is(gURLBar.popup.oneOffSearchButtons.selectedButtonIndex, index,
- "Expected one-off button should be selected");
-
- // This is true because although both the listbox and the one-offs can have
- // selections, the test doesn't check that.
- is(gURLBar.popup.richlistbox.selectedIndex, -1,
- "A one-off is selected, so the listbox should not have a selection");
-}
-
-add_task(function*() {
- let maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
-
- Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true);
- registerCleanupFunction(function* () {
- yield PlacesTestUtils.clearHistory();
- Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF);
- });
-
- let visits = [];
- repeat(maxResults, i => {
- visits.push({
- uri: makeURI("http://example.com/autocomplete/?" + i),
- });
- });
- yield PlacesTestUtils.addVisits(visits);
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
- yield promiseAutocompleteResultPopup("example.com/autocomplete");
-
- let popup = gURLBar.popup;
- let results = popup.richlistbox.children;
- is(results.length, maxResults,
- "Should get maxResults=" + maxResults + " results");
- is_selected(0);
-
- info("Key Down to select the next item");
- EventUtils.synthesizeKey("VK_DOWN", {});
- is_selected(1);
-
- info("Key Down maxResults-1 times should select the first one-off");
- repeat(maxResults - 1, () => EventUtils.synthesizeKey("VK_DOWN", {}));
- is_selected_one_off(0);
-
- info("Key Down numButtons-1 should select the last one-off");
- let numButtons =
- gURLBar.popup.oneOffSearchButtons.getSelectableButtons(true).length;
- repeat(numButtons - 1, () => EventUtils.synthesizeKey("VK_DOWN", {}));
- is_selected_one_off(numButtons - 1);
-
- info("Key Down twice more should select the second result");
- repeat(2, () => EventUtils.synthesizeKey("VK_DOWN", {}));
- is_selected(1);
-
- info("Key Down maxResults + numButtons times should wrap around");
- repeat(maxResults + numButtons,
- () => EventUtils.synthesizeKey("VK_DOWN", {}));
- is_selected(1);
-
- info("Key Up maxResults + numButtons times should wrap around the other way");
- repeat(maxResults + numButtons, () => EventUtils.synthesizeKey("VK_UP", {}));
- is_selected(1);
-
- info("Page Up will go up the list, but not wrap");
- EventUtils.synthesizeKey("VK_PAGE_UP", {})
- is_selected(0);
-
- info("Page Up again will wrap around to the end of the list");
- EventUtils.synthesizeKey("VK_PAGE_UP", {})
- is_selected(maxResults - 1);
-
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promisePopupHidden(gURLBar.popup);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_cursor.js b/browser/base/content/test/urlbar/browser_autocomplete_cursor.js
deleted file mode 100644
index 9cc2c6eac..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_cursor.js
+++ /dev/null
@@ -1,17 +0,0 @@
-add_task(function*() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
- yield promiseAutocompleteResultPopup("www.mozilla.org");
-
- gURLBar.selectTextRange(4, 4);
-
- is(gURLBar.popup.state, "open", "Popup should be open");
- is(gURLBar.popup.richlistbox.selectedIndex, 0, "Should have selected something");
-
- EventUtils.synthesizeKey("VK_RIGHT", {});
- yield promisePopupHidden(gURLBar.popup);
-
- is(gURLBar.selectionStart, 5, "Should have moved the cursor");
- is(gURLBar.selectionEnd, 5, "And not selected anything");
-
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js b/browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js
deleted file mode 100644
index 19db1a368..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_edit_completed.js
+++ /dev/null
@@ -1,48 +0,0 @@
-add_task(function*() {
- yield PlacesTestUtils.clearHistory();
-
- yield PlacesTestUtils.addVisits([
- { uri: makeURI("http://example.com/foo") },
- { uri: makeURI("http://example.com/foo/bar") },
- ]);
-
- registerCleanupFunction(function* () {
- yield PlacesTestUtils.clearHistory();
- });
-
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- gURLBar.focus();
-
- yield promiseAutocompleteResultPopup("http://example.com");
-
- let popup = gURLBar.popup;
- let list = popup.richlistbox;
- let initialIndex = list.selectedIndex;
-
- info("Key Down to select the next item.");
- EventUtils.synthesizeKey("VK_DOWN", {});
-
- let nextIndex = initialIndex + 1;
- let nextValue = gURLBar.controller.getFinalCompleteValueAt(nextIndex);
- is(list.selectedIndex, nextIndex, "The next item is selected.");
- is(gURLBar.value, nextValue, "The selected URL is completed.");
-
- info("Press backspace");
- EventUtils.synthesizeKey("VK_BACK_SPACE", {});
- yield promiseSearchComplete();
-
- let editedValue = gURLBar.textValue;
- is(list.selectedIndex, initialIndex, "The initial index is selected again.");
- isnot(editedValue, nextValue, "The URL has changed.");
-
- let docLoad = waitForDocLoadAndStopIt("http://" + editedValue);
-
- info("Press return to load edited URL.");
- EventUtils.synthesizeKey("VK_RETURN", {});
- yield Promise.all([
- promisePopupHidden(gURLBar.popup),
- docLoad,
- ]);
-
- gBrowser.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js b/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
deleted file mode 100644
index 4e3c8943c..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// The order of these tests matters!
-
-add_task(function* setup () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "http://example.com/?q=%s",
- title: "test" });
- registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.remove(bm);
- yield BrowserTestUtils.removeTab(tab);
- });
- yield PlacesUtils.keywords.insert({ keyword: "keyword",
- url: "http://example.com/?q=%s" });
- // Needs at least one success.
- ok(true, "Setup complete");
-});
-
-add_task(function* test_keyword() {
- yield promiseAutocompleteResultPopup("keyword bear");
- gURLBar.focus();
- EventUtils.synthesizeKey("d", {});
- EventUtils.synthesizeKey("VK_RETURN", {});
- info("wait for the page to load");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedTab.linkedBrowser,
- false, "http://example.com/?q=beard");
-});
-
-add_task(function* test_sametext() {
- yield promiseAutocompleteResultPopup("example.com", window, true);
-
- // Simulate re-entering the same text searched the last time. This may happen
- // through a copy paste, but clipboard handling is not much reliable, so just
- // fire an input event.
- info("synthesize input event");
- let event = document.createEvent("Events");
- event.initEvent("input", true, true);
- gURLBar.dispatchEvent(event);
- EventUtils.synthesizeKey("VK_RETURN", {});
-
- info("wait for the page to load");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedTab.linkedBrowser,
- false, "http://example.com/");
-});
-
-add_task(function* test_after_empty_search() {
- yield promiseAutocompleteResultPopup("");
- gURLBar.focus();
- gURLBar.value = "e";
- EventUtils.synthesizeKey("x", {});
- EventUtils.synthesizeKey("VK_RETURN", {});
-
- info("wait for the page to load");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedTab.linkedBrowser,
- false, "http://example.com/");
-});
-
-add_task(function* test_disabled_ac() {
- // Disable autocomplete.
- let suggestHistory = Preferences.get("browser.urlbar.suggest.history");
- Preferences.set("browser.urlbar.suggest.history", false);
- let suggestBookmarks = Preferences.get("browser.urlbar.suggest.bookmark");
- Preferences.set("browser.urlbar.suggest.bookmark", false);
- let suggestOpenPages = Preferences.get("browser.urlbar.suggest.openpage");
- Preferences.set("browser.urlbar.suggest.openpages", false);
-
- Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- let engine = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- function* cleanup() {
- Preferences.set("browser.urlbar.suggest.history", suggestHistory);
- Preferences.set("browser.urlbar.suggest.bookmark", suggestBookmarks);
- Preferences.set("browser.urlbar.suggest.openpage", suggestOpenPages);
-
- Services.search.currentEngine = originalEngine;
- let engine = Services.search.getEngineByName("MozSearch");
- if (engine) {
- Services.search.removeEngine(engine);
- }
- }
- registerCleanupFunction(cleanup);
-
- gURLBar.focus();
- gURLBar.value = "e";
- EventUtils.synthesizeKey("x", {});
- EventUtils.synthesizeKey("VK_RETURN", {});
-
- info("wait for the page to load");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedTab.linkedBrowser,
- false, "http://example.com/?q=ex");
- yield cleanup();
-});
-
-add_task(function* test_delay() {
- const TIMEOUT = 10000;
- // Set a large delay.
- let delay = Preferences.get("browser.urlbar.delay");
- Preferences.set("browser.urlbar.delay", TIMEOUT);
-
- registerCleanupFunction(function* () {
- Preferences.set("browser.urlbar.delay", delay);
- });
-
- // This is needed to clear the current value, otherwise autocomplete may think
- // the user removed text from the end.
- let start = Date.now();
- yield promiseAutocompleteResultPopup("");
- Assert.ok((Date.now() - start) < TIMEOUT);
-
- start = Date.now();
- gURLBar.closePopup();
- gURLBar.focus();
- gURLBar.value = "e";
- EventUtils.synthesizeKey("x", {});
- EventUtils.synthesizeKey("VK_RETURN", {});
- info("wait for the page to load");
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedTab.linkedBrowser,
- false, "http://example.com/");
- Assert.ok((Date.now() - start) < TIMEOUT);
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_no_title.js b/browser/base/content/test/urlbar/browser_autocomplete_no_title.js
deleted file mode 100644
index 8d608550b..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_no_title.js
+++ /dev/null
@@ -1,15 +0,0 @@
-add_task(function*() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- let uri = NetUtil.newURI("http://bug1060642.example.com/beards/are/pretty/great");
- yield PlacesTestUtils.addVisits([{uri: uri, title: ""}]);
-
- yield promiseAutocompleteResultPopup("bug1060642");
- ok(gURLBar.popup.richlistbox.children.length > 1, "Should get at least 2 results");
- let result = gURLBar.popup.richlistbox.children[1];
- is(result._titleText.textContent, "bug1060642.example.com", "Result title should be as expected");
-
- gURLBar.popup.hidePopup();
- yield promisePopupHidden(gURLBar.popup);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js b/browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js
deleted file mode 100644
index 8a69b4b44..000000000
--- a/browser/base/content/test/urlbar/browser_autocomplete_tag_star_visibility.js
+++ /dev/null
@@ -1,102 +0,0 @@
-add_task(function*() {
- registerCleanupFunction(() => {
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- });
-
- function* addTagItem(tagName) {
- let uri = NetUtil.newURI(`http://example.com/this/is/tagged/${tagName}`);
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- uri,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- `test ${tagName}`);
- PlacesUtils.tagging.tagURI(uri, [tagName]);
- yield PlacesTestUtils.addVisits([{uri: uri, title: `Test page with tag ${tagName}`}]);
- }
-
- // We use different tags for each part of the test, as otherwise the
- // autocomplete code tries to be smart by using the previously cached element
- // without updating it (since all parameters it knows about are the same).
-
- let testcases = [{
- description: "Test with suggest.bookmark=true",
- tagName: "tagtest1",
- prefs: {
- "suggest.bookmark": true,
- },
- input: "tagtest1",
- expected: {
- type: "bookmark",
- typeImageVisible: true,
- },
- }, {
- description: "Test with suggest.bookmark=false",
- tagName: "tagtest2",
- prefs: {
- "suggest.bookmark": false,
- },
- input: "tagtest2",
- expected: {
- type: "tag",
- typeImageVisible: false,
- },
- }, {
- description: "Test with suggest.bookmark=true (again)",
- tagName: "tagtest3",
- prefs: {
- "suggest.bookmark": true,
- },
- input: "tagtest3",
- expected: {
- type: "bookmark",
- typeImageVisible: true,
- },
- }, {
- description: "Test with bookmark restriction token",
- tagName: "tagtest4",
- prefs: {
- "suggest.bookmark": true,
- },
- input: "* tagtest4",
- expected: {
- type: "bookmark",
- typeImageVisible: true,
- },
- }, {
- description: "Test with history restriction token",
- tagName: "tagtest5",
- prefs: {
- "suggest.bookmark": true,
- },
- input: "^ tagtest5",
- expected: {
- type: "tag",
- typeImageVisible: false,
- },
- }];
-
- for (let testcase of testcases) {
- info(`Test case: ${testcase.description}`);
-
- yield addTagItem(testcase.tagName);
- for (let prefName of Object.keys(testcase.prefs)) {
- Services.prefs.setBoolPref(`browser.urlbar.${prefName}`, testcase.prefs[prefName]);
- }
-
- yield promiseAutocompleteResultPopup(testcase.input);
- let result = gURLBar.popup.richlistbox.children[1];
- ok(result && !result.collasped, "Should have result");
-
- is(result.getAttribute("type"), testcase.expected.type, "Result should have expected type");
-
- let typeIconStyle = window.getComputedStyle(result._typeIcon);
- let imageURL = typeIconStyle.listStyleImage;
- if (testcase.expected.typeImageVisible) {
- ok(/^url\(.+\)$/.test(imageURL), "Type image should be visible");
- } else {
- is(imageURL, "none", "Type image should be hidden");
- }
-
- gURLBar.popup.hidePopup();
- yield promisePopupHidden(gURLBar.popup);
- }
-});
diff --git a/browser/base/content/test/urlbar/browser_bug1003461-switchtab-override.js b/browser/base/content/test/urlbar/browser_bug1003461-switchtab-override.js
deleted file mode 100644
index 89f604491..000000000
--- a/browser/base/content/test/urlbar/browser_bug1003461-switchtab-override.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test_switchtab_override() {
- let testURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
-
- info("Opening first tab");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
-
- info("Opening and selecting second tab");
- let secondTab = gBrowser.selectedTab = gBrowser.addTab();
- registerCleanupFunction(() => {
- try {
- gBrowser.removeTab(tab);
- gBrowser.removeTab(secondTab);
- } catch (ex) { /* tabs may have already been closed in case of failure */ }
- });
-
- info("Wait for autocomplete")
- let deferred = Promise.defer();
- let onSearchComplete = gURLBar.onSearchComplete;
- registerCleanupFunction(() => {
- gURLBar.onSearchComplete = onSearchComplete;
- });
- gURLBar.onSearchComplete = function () {
- ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
- onSearchComplete.apply(gURLBar);
- deferred.resolve();
- }
-
- gURLBar.focus();
- gURLBar.value = "dummy_pag";
- EventUtils.synthesizeKey("e", {});
- yield deferred.promise;
-
- info("Select second autocomplete popup entry");
- EventUtils.synthesizeKey("VK_DOWN", {});
- ok(/moz-action:switchtab/.test(gURLBar.value), "switch to tab entry found");
-
- info("Override switch-to-tab");
- deferred = Promise.defer();
- // In case of failure this would switch tab.
- let onTabSelect = event => {
- deferred.reject(new Error("Should have overridden switch to tab"));
- };
- gBrowser.tabContainer.addEventListener("TabSelect", onTabSelect, false);
- registerCleanupFunction(() => {
- gBrowser.tabContainer.removeEventListener("TabSelect", onTabSelect, false);
- });
- // Otherwise it would load the page.
- BrowserTestUtils.browserLoaded(secondTab.linkedBrowser).then(deferred.resolve);
-
- EventUtils.synthesizeKey("VK_SHIFT", { type: "keydown" });
- EventUtils.synthesizeKey("VK_RETURN", { });
- info(`gURLBar.value = ${gURLBar.value}`);
- EventUtils.synthesizeKey("VK_SHIFT", { type: "keyup" });
- yield deferred.promise;
-
- yield PlacesTestUtils.clearHistory();
-});
diff --git a/browser/base/content/test/urlbar/browser_bug1024133-switchtab-override-keynav.js b/browser/base/content/test/urlbar/browser_bug1024133-switchtab-override-keynav.js
deleted file mode 100644
index 2d97ea07b..000000000
--- a/browser/base/content/test/urlbar/browser_bug1024133-switchtab-override-keynav.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test_switchtab_override_keynav() {
- let testURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
-
- info("Opening first tab");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
-
- info("Opening and selecting second tab");
- let secondTab = gBrowser.selectedTab = gBrowser.addTab();
- registerCleanupFunction(() => {
- try {
- gBrowser.removeTab(tab);
- gBrowser.removeTab(secondTab);
- } catch (ex) { /* tabs may have already been closed in case of failure */ }
- return PlacesTestUtils.clearHistory();
- });
-
- gURLBar.focus();
- gURLBar.value = "dummy_pag";
- EventUtils.synthesizeKey("e", {});
- yield promiseSearchComplete();
-
- info("Select second autocomplete popup entry");
- EventUtils.synthesizeKey("VK_DOWN", {});
- ok(/moz-action:switchtab/.test(gURLBar.value), "switch to tab entry found");
-
- info("Shift+left on switch-to-tab entry");
-
- EventUtils.synthesizeKey("VK_SHIFT", { type: "keydown" });
- EventUtils.synthesizeKey("VK_LEFT", { shiftKey: true });
- EventUtils.synthesizeKey("VK_SHIFT", { type: "keyup" });
-
- ok(!/moz-action:switchtab/.test(gURLBar.inputField.value), "switch to tab should be hidden");
-});
diff --git a/browser/base/content/test/urlbar/browser_bug1025195_switchToTabHavingURI_aOpenParams.js b/browser/base/content/test/urlbar/browser_bug1025195_switchToTabHavingURI_aOpenParams.js
deleted file mode 100644
index 9e779ade1..000000000
--- a/browser/base/content/test/urlbar/browser_bug1025195_switchToTabHavingURI_aOpenParams.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test_ignoreFragment() {
- let tabRefAboutHome =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home#1");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
- let numTabsAtStart = gBrowser.tabs.length;
-
- switchTab("about:home#1", true);
- switchTab("about:mozilla", true);
-
- let hashChangePromise = ContentTask.spawn(tabRefAboutHome.linkedBrowser, null, function* () {
- yield ContentTaskUtils.waitForEvent(this, "hashchange", false);
- });
- switchTab("about:home#2", true, { ignoreFragment: "whenComparingAndReplace" });
- is(tabRefAboutHome, gBrowser.selectedTab, "The same about:home tab should be switched to");
- yield hashChangePromise;
- is(gBrowser.currentURI.ref, "2", "The ref should be updated to the new ref");
- switchTab("about:mozilla", true);
- switchTab("about:home#3", true, { ignoreFragment: "whenComparing" });
- is(tabRefAboutHome, gBrowser.selectedTab, "The same about:home tab should be switched to");
- is(gBrowser.currentURI.ref, "2", "The ref should be unchanged since the fragment is only ignored when comparing");
- switchTab("about:mozilla", true);
- switchTab("about:home#1", false);
- isnot(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should not be initial about:blank tab");
- is(gBrowser.tabs.length, numTabsAtStart + 1, "Should have one new tab opened");
- switchTab("about:mozilla", true);
- switchTab("about:home", true, {ignoreFragment: "whenComparingAndReplace"});
- yield BrowserTestUtils.waitForCondition(function() {
- return tabRefAboutHome.linkedBrowser.currentURI.spec == "about:home";
- });
- is(tabRefAboutHome.linkedBrowser.currentURI.spec, "about:home", "about:home shouldn't have hash");
- switchTab("about:about", false, { ignoreFragment: "whenComparingAndReplace" });
- cleanupTestTabs();
-});
-
-add_task(function* test_ignoreQueryString() {
- let tabRefAboutHome =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home?hello=firefox");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- switchTab("about:home?hello=firefox", true);
- switchTab("about:home?hello=firefoxos", false);
- // Remove the last opened tab to test ignoreQueryString option.
- gBrowser.removeCurrentTab();
- switchTab("about:home?hello=firefoxos", true, { ignoreQueryString: true });
- is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
- is(gBrowser.currentURI.spec, "about:home?hello=firefox", "The spec should NOT be updated to the new query string");
- cleanupTestTabs();
-});
-
-add_task(function* test_replaceQueryString() {
- let tabRefAboutHome =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home?hello=firefox");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- switchTab("about:home", false);
- switchTab("about:home?hello=firefox", true);
- switchTab("about:home?hello=firefoxos", false);
- // Remove the last opened tab to test replaceQueryString option.
- gBrowser.removeCurrentTab();
- switchTab("about:home?hello=firefoxos", true, { replaceQueryString: true });
- is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
- // Wait for the tab to load the new URI spec.
- yield BrowserTestUtils.browserLoaded(tabRefAboutHome.linkedBrowser);
- is(gBrowser.currentURI.spec, "about:home?hello=firefoxos", "The spec should be updated to the new spec");
- cleanupTestTabs();
-});
-
-add_task(function* test_replaceQueryStringAndFragment() {
- let tabRefAboutHome =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home?hello=firefox#aaa");
- let tabRefAboutMozilla =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla?hello=firefoxos#aaa");
-
- switchTab("about:home", false);
- gBrowser.removeCurrentTab();
- switchTab("about:home?hello=firefox#aaa", true);
- is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
- switchTab("about:mozilla?hello=firefox#bbb", true, { replaceQueryString: true, ignoreFragment: "whenComparingAndReplace" });
- is(tabRefAboutMozilla, gBrowser.selectedTab, "Selected tab should be the initial about:mozilla tab");
- switchTab("about:home?hello=firefoxos#bbb", true, { ignoreQueryString: true, ignoreFragment: "whenComparingAndReplace" });
- is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
- cleanupTestTabs();
-});
-
-add_task(function* test_ignoreQueryStringIgnoresFragment() {
- let tabRefAboutHome =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home?hello=firefox#aaa");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla?hello=firefoxos#aaa");
-
- switchTab("about:home?hello=firefox#bbb", false, { ignoreQueryString: true });
- gBrowser.removeCurrentTab();
- switchTab("about:home?hello=firefoxos#aaa", true, { ignoreQueryString: true });
- is(tabRefAboutHome, gBrowser.selectedTab, "Selected tab should be the initial about:home tab");
- cleanupTestTabs();
-});
-
-// Begin helpers
-
-function cleanupTestTabs() {
- while (gBrowser.tabs.length > 1)
- gBrowser.removeCurrentTab();
-}
-
-function switchTab(aURI, aShouldFindExistingTab, aOpenParams = {}) {
- // Build the description before switchToTabHavingURI deletes the object properties.
- let msg = `Should switch to existing ${aURI} tab if one existed, ` +
- `${(aOpenParams.ignoreFragment ? "ignoring" : "including")} fragment portion, `;
- if (aOpenParams.replaceQueryString) {
- msg += "replacing";
- } else if (aOpenParams.ignoreQueryString) {
- msg += "ignoring";
- } else {
- msg += "including";
- }
- msg += " query string.";
- let tabFound = switchToTabHavingURI(aURI, true, aOpenParams);
- is(tabFound, aShouldFindExistingTab, msg);
-}
-
-registerCleanupFunction(cleanupTestTabs);
diff --git a/browser/base/content/test/urlbar/browser_bug1070778.js b/browser/base/content/test/urlbar/browser_bug1070778.js
deleted file mode 100644
index ab88d04d8..000000000
--- a/browser/base/content/test/urlbar/browser_bug1070778.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function is_selected(index) {
- is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`);
-}
-
-add_task(function*() {
- let bookmarks = [];
- bookmarks.push((yield PlacesUtils.bookmarks
- .insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "http://example.com/?q=%s",
- title: "test" })));
- yield PlacesUtils.keywords.insert({ keyword: "keyword",
- url: "http://example.com/?q=%s" });
-
- // This item only needed so we can select the keyword item, select something
- // else, then select the keyword item again.
- bookmarks.push((yield PlacesUtils.bookmarks
- .insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "http://example.com/keyword",
- title: "keyword abc" })));
-
- registerCleanupFunction(function* () {
- for (let bm of bookmarks) {
- yield PlacesUtils.bookmarks.remove(bm);
- }
- });
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
- yield promiseAutocompleteResultPopup("keyword a");
-
- // First item should already be selected
- is_selected(0);
- // Select next one (important!)
- EventUtils.synthesizeKey("VK_DOWN", {});
- is_selected(1);
- // Re-select keyword item
- EventUtils.synthesizeKey("VK_UP", {});
- is_selected(0);
-
- EventUtils.synthesizeKey("b", {});
- yield promiseSearchComplete();
-
- is(gURLBar.textValue, "keyword ab", "urlbar should have expected input");
-
- let result = gURLBar.popup.richlistbox.firstChild;
- isnot(result, null, "Should have first item");
- let uri = NetUtil.newURI(result.getAttribute("url"));
- is(uri.spec, PlacesUtils.mozActionURI("keyword", {url: "http://example.com/?q=ab", input: "keyword ab"}), "Expect correct url");
-
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promisePopupHidden(gURLBar.popup);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js b/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js
deleted file mode 100644
index d165d7304..000000000
--- a/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js
+++ /dev/null
@@ -1,29 +0,0 @@
-add_task(function* test_switchtab_decodeuri() {
- info("Opening first tab");
- const TEST_URL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html#test%7C1";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
-
- info("Opening and selecting second tab");
- gBrowser.selectedTab = gBrowser.addTab();
-
- info("Wait for autocomplete")
- yield promiseAutocompleteResultPopup("dummy_page");
-
- 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, false);
- is(gBrowser.selectedTab, tab, "Should have switched to the right tab");
- resolve();
- }, false);
- EventUtils.synthesizeKey("VK_RETURN", { });
- });
-
- gBrowser.removeCurrentTab();
- yield PlacesTestUtils.clearHistory();
-});
diff --git a/browser/base/content/test/urlbar/browser_bug1225194-remotetab.js b/browser/base/content/test/urlbar/browser_bug1225194-remotetab.js
deleted file mode 100644
index 3b4a44e76..000000000
--- a/browser/base/content/test/urlbar/browser_bug1225194-remotetab.js
+++ /dev/null
@@ -1,16 +0,0 @@
-add_task(function* test_remotetab_opens() {
- const url = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
- yield BrowserTestUtils.withNewTab({url: "about:robots", gBrowser}, function* () {
- // Set the urlbar to include the moz-action
- gURLBar.value = "moz-action:remotetab," + JSON.stringify({ url });
- // Focus the urlbar so we can press enter
- gURLBar.focus();
-
- // The URL is going to open in the current tab as it is currently about:blank
- let promiseTabLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- EventUtils.synthesizeKey("VK_RETURN", {});
- yield promiseTabLoaded;
-
- Assert.equal(gBrowser.selectedTab.linkedBrowser.currentURI.spec, url, "correct URL loaded");
- });
-});
diff --git a/browser/base/content/test/urlbar/browser_bug304198.js b/browser/base/content/test/urlbar/browser_bug304198.js
deleted file mode 100644
index dc8d39fae..000000000
--- a/browser/base/content/test/urlbar/browser_bug304198.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* () {
- let charsToDelete, deletedURLTab, fullURLTab, partialURLTab, testPartialURL, testURL;
-
- charsToDelete = 5;
- deletedURLTab = gBrowser.addTab();
- fullURLTab = gBrowser.addTab();
- partialURLTab = gBrowser.addTab();
- testURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
-
- let loaded1 = BrowserTestUtils.browserLoaded(deletedURLTab.linkedBrowser, testURL);
- let loaded2 = BrowserTestUtils.browserLoaded(fullURLTab.linkedBrowser, testURL);
- let loaded3 = BrowserTestUtils.browserLoaded(partialURLTab.linkedBrowser, testURL);
- deletedURLTab.linkedBrowser.loadURI(testURL);
- fullURLTab.linkedBrowser.loadURI(testURL);
- partialURLTab.linkedBrowser.loadURI(testURL);
- yield Promise.all([loaded1, loaded2, loaded3]);
-
- testURL = gURLBar.trimValue(testURL);
- testPartialURL = testURL.substr(0, (testURL.length - charsToDelete));
-
- function cleanUp() {
- gBrowser.removeTab(fullURLTab);
- gBrowser.removeTab(partialURLTab);
- gBrowser.removeTab(deletedURLTab);
- }
-
- function* cycleTabs() {
- yield BrowserTestUtils.switchTab(gBrowser, fullURLTab);
- is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after switching back to fullURLTab');
-
- yield BrowserTestUtils.switchTab(gBrowser, partialURLTab);
- is(gURLBar.textValue, testPartialURL, 'gURLBar.textValue should be testPartialURL after switching back to partialURLTab');
- yield BrowserTestUtils.switchTab(gBrowser, deletedURLTab);
- is(gURLBar.textValue, '', 'gURLBar.textValue should be "" after switching back to deletedURLTab');
-
- 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, false);
- resolve();
- }, false);
- gURLBar.focus();
- if (gURLBar.selectionStart == gURLBar.selectionEnd) {
- gURLBar.selectionStart = gURLBar.selectionEnd = gURLBar.textValue.length;
- }
- 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');
-
- // simulate the user removing the whole url from the location bar
- gPrefService.setBoolPref("browser.urlbar.clickSelectsAll", true);
-
- yield urlbarBackspace();
- is(gURLBar.textValue, "", 'gURLBar.textValue should be "" (just set)');
- if (gPrefService.prefHasUserValue("browser.urlbar.clickSelectsAll")) {
- gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
- }
- }
-
- function* prepareFullURLTab() {
- yield BrowserTestUtils.switchTab(gBrowser, fullURLTab);
- is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after initial switch to fullURLTab');
- }
-
- function* preparePartialURLTab() {
- yield BrowserTestUtils.switchTab(gBrowser, partialURLTab);
- is(gURLBar.textValue, testURL, 'gURLBar.textValue should be testURL after initial switch to partialURLTab');
-
- // simulate the user removing part of the url from the location bar
- gPrefService.setBoolPref("browser.urlbar.clickSelectsAll", false);
-
- let deleted = 0;
- while (deleted < charsToDelete) {
- yield urlbarBackspace(arguments.callee);
- deleted++;
- }
-
- is(gURLBar.textValue, testPartialURL, "gURLBar.textValue should be testPartialURL (just set)");
- if (gPrefService.prefHasUserValue("browser.urlbar.clickSelectsAll")) {
- gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
- }
- }
-
- // prepare the three tabs required by this test
-
- // First tab
- yield* prepareFullURLTab();
- yield* preparePartialURLTab();
- yield* prepareDeletedURLTab();
-
- // now cycle the tabs and make sure everything looks good
- yield* cycleTabs();
- cleanUp();
-});
-
-
diff --git a/browser/base/content/test/urlbar/browser_bug556061.js b/browser/base/content/test/urlbar/browser_bug556061.js
deleted file mode 100644
index 4c6ac5bf5..000000000
--- a/browser/base/content/test/urlbar/browser_bug556061.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var testURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
-var testActionURL = "moz-action:switchtab," + JSON.stringify({url: testURL});
-testURL = gURLBar.trimValue(testURL);
-var testTab;
-
-function runNextTest() {
- if (tests.length) {
- let t = tests.shift();
- waitForClipboard(t.expected, t.setup, function() {
- t.success();
- runNextTest();
- }, cleanup);
- }
- else {
- cleanup();
- }
-}
-
-function cleanup() {
- gBrowser.removeTab(testTab);
- finish();
-}
-
-var tests = [
- {
- expected: testURL,
- setup: function() {
- gURLBar.value = testActionURL;
- gURLBar.valueIsTyped = true;
- is(gURLBar.value, testActionURL, "gURLBar starts with the correct real value");
- is(gURLBar.textValue, testURL, "gURLBar starts with the correct display value");
-
- // Focus the urlbar so we can select it all & copy
- gURLBar.focus();
- gURLBar.select();
- goDoCommand("cmd_copy");
- },
- success: function() {
- is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
- }
- },
- {
- expected: testURL.substring(0, 10),
- setup: function() {
- // Set selectionStart/End manually and make sure it matches the substring
- gURLBar.selectionStart = 0;
- gURLBar.selectionEnd = 10;
- goDoCommand("cmd_copy");
- },
- success: function() {
- is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
- }
- },
- {
- expected: testURL,
- setup: function() {
- // Setup for cut test...
- // Select all
- gURLBar.select();
- goDoCommand("cmd_cut");
- },
- success: function() {
- is(gURLBar.value, "", "gURLBar.value is now empty");
- }
- },
- {
- expected: testURL.substring(testURL.length - 10, testURL.length),
- setup: function() {
- // Reset urlbar value
- gURLBar.value = testActionURL;
- gURLBar.valueIsTyped = true;
- // Sanity check that we have the right value
- is(gURLBar.value, testActionURL, "gURLBar starts with the correct real value");
- is(gURLBar.textValue, testURL, "gURLBar starts with the correct display value");
-
- // Now just select part of the value & cut that.
- gURLBar.selectionStart = testURL.length - 10;
- gURLBar.selectionEnd = testURL.length;
- goDoCommand("cmd_cut");
- },
- success: function() {
- is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value");
- }
- }
-];
-
-function test() {
- waitForExplicitFinish();
- testTab = gBrowser.addTab();
- gBrowser.selectedTab = testTab;
-
- // Kick off the testing
- runNextTest();
-}
diff --git a/browser/base/content/test/urlbar/browser_bug562649.js b/browser/base/content/test/urlbar/browser_bug562649.js
deleted file mode 100644
index f56e430ee..000000000
--- a/browser/base/content/test/urlbar/browser_bug562649.js
+++ /dev/null
@@ -1,24 +0,0 @@
-function test() {
- const URI = "data:text/plain,bug562649";
- browserDOMWindow.openURI(makeURI(URI),
- null,
- Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
- Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
-
- is(gBrowser.userTypedValue, URI, "userTypedValue matches test URI");
- is(gURLBar.value, URI, "location bar value matches test URI");
-
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.removeCurrentTab({ skipPermitUnload: true });
- is(gBrowser.userTypedValue, URI, "userTypedValue matches test URI after switching tabs");
- is(gURLBar.value, URI, "location bar value matches test URI after switching tabs");
-
- waitForExplicitFinish();
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
- is(gBrowser.userTypedValue, null, "userTypedValue is null as the page has loaded");
- is(gURLBar.value, URI, "location bar value matches test URI as the page has loaded");
-
- gBrowser.removeCurrentTab({ skipPermitUnload: true });
- finish();
- });
-}
diff --git a/browser/base/content/test/urlbar/browser_bug623155.js b/browser/base/content/test/urlbar/browser_bug623155.js
deleted file mode 100644
index dd6ff8c85..000000000
--- a/browser/base/content/test/urlbar/browser_bug623155.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const REDIRECT_FROM = "https://example.com/browser/browser/base/content/test/urlbar/" +
- "redirect_bug623155.sjs";
-
-const REDIRECT_TO = "https://www.bank1.com/"; // Bad-cert host.
-
-function isRedirectedURISpec(aURISpec) {
- return isRedirectedURI(Services.io.newURI(aURISpec, null, null));
-}
-
-function isRedirectedURI(aURI) {
- // Compare only their before-hash portion.
- return Services.io.newURI(REDIRECT_TO, null, null)
- .equalsExceptRef(aURI);
-}
-
-/*
- Test.
-
-1. Load
-https://example.com/browser/browser/base/content/test/urlbar/redirect_bug623155.sjs#BG
- in a background tab.
-
-2. The redirected URI is <https://www.bank1.com/#BG>, which displayes a cert
- error page.
-
-3. Switch the tab to foreground.
-
-4. Check the URLbar's value, expecting <https://www.bank1.com/#BG>
-
-5. Load
-https://example.com/browser/browser/base/content/test/urlbar/redirect_bug623155.sjs#FG
- in the foreground tab.
-
-6. The redirected URI is <https://www.bank1.com/#FG>. And this is also
- a cert-error page.
-
-7. Check the URLbar's value, expecting <https://www.bank1.com/#FG>
-
-8. End.
-
- */
-
-var gNewTab;
-
-function test() {
- waitForExplicitFinish();
-
- // Load a URI in the background.
- gNewTab = gBrowser.addTab(REDIRECT_FROM + "#BG");
- gBrowser.getBrowserForTab(gNewTab)
- .webProgress
- .addProgressListener(gWebProgressListener,
- Components.interfaces.nsIWebProgress
- .NOTIFY_LOCATION);
-}
-
-var gWebProgressListener = {
- QueryInterface: function(aIID) {
- if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
- aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_NOINTERFACE;
- },
-
- // ---------------------------------------------------------------------------
- // NOTIFY_LOCATION mode should work fine without these methods.
- //
- // onStateChange: function() {},
- // onStatusChange: function() {},
- // onProgressChange: function() {},
- // onSecurityChange: function() {},
- // ----------------------------------------------------------------------------
-
- onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
- if (!aRequest) {
- // This is bug 673752, or maybe initial "about:blank".
- return;
- }
-
- ok(gNewTab, "There is a new tab.");
- ok(isRedirectedURI(aLocation),
- "onLocationChange catches only redirected URI.");
-
- if (aLocation.ref == "BG") {
- // This is background tab's request.
- isnot(gNewTab, gBrowser.selectedTab, "This is a background tab.");
- } else if (aLocation.ref == "FG") {
- // This is foreground tab's request.
- is(gNewTab, gBrowser.selectedTab, "This is a foreground tab.");
- }
- else {
- // We shonuld not reach here.
- ok(false, "This URI hash is not expected:" + aLocation.ref);
- }
-
- let isSelectedTab = gNewTab.selected;
- setTimeout(delayed, 0, isSelectedTab);
- }
-};
-
-function delayed(aIsSelectedTab) {
- // Switch tab and confirm URL bar.
- if (!aIsSelectedTab) {
- gBrowser.selectedTab = gNewTab;
- }
-
- let currentURI = gBrowser.selectedBrowser.currentURI.spec;
- ok(isRedirectedURISpec(currentURI),
- "The content area is redirected. aIsSelectedTab:" + aIsSelectedTab);
- is(gURLBar.value, currentURI,
- "The URL bar shows the content URI. aIsSelectedTab:" + aIsSelectedTab);
-
- if (!aIsSelectedTab) {
- // If this was a background request, go on a foreground request.
- gBrowser.selectedBrowser.loadURI(REDIRECT_FROM + "#FG");
- }
- else {
- // Othrewise, nothing to do remains.
- finish();
- }
-}
-
-/* Cleanup */
-registerCleanupFunction(function() {
- if (gNewTab) {
- gBrowser.getBrowserForTab(gNewTab)
- .webProgress
- .removeProgressListener(gWebProgressListener);
-
- gBrowser.removeTab(gNewTab);
- }
- gNewTab = null;
-});
diff --git a/browser/base/content/test/urlbar/browser_bug783614.js b/browser/base/content/test/urlbar/browser_bug783614.js
deleted file mode 100644
index ebc62e8fa..000000000
--- a/browser/base/content/test/urlbar/browser_bug783614.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- gURLBar.focus();
- gURLBar.inputField.value = "https://example.com/";
- gURLBar.selectionStart = 4;
- gURLBar.selectionEnd = 5;
- goDoCommand("cmd_cut");
- is(gURLBar.inputField.value, "http://example.com/", "location bar value after cutting 's' from https");
- gURLBar.handleRevert();
-}
diff --git a/browser/base/content/test/urlbar/browser_canonizeURL.js b/browser/base/content/test/urlbar/browser_canonizeURL.js
deleted file mode 100644
index 59ab54ca0..000000000
--- a/browser/base/content/test/urlbar/browser_canonizeURL.js
+++ /dev/null
@@ -1,42 +0,0 @@
-add_task(function*() {
- let testcases = [
- ["example", "http://www.example.net/", { shiftKey: true }],
- // Check that a direct load is not overwritten by a previous canonization.
- ["http://example.com/test/", "http://example.com/test/", {}],
- ["ex-ample", "http://www.ex-ample.net/", { shiftKey: true }],
- [" example ", "http://www.example.net/", { shiftKey: true }],
- [" example/foo ", "http://www.example.net/foo", { shiftKey: true }],
- [" example/foo bar ", "http://www.example.net/foo%20bar", { shiftKey: true }],
- ["example.net", "http://example.net/", { shiftKey: true }],
- ["http://example", "http://example/", { shiftKey: true }],
- ["example:8080", "http://example:8080/", { shiftKey: true }],
- ["ex-ample.foo", "http://ex-ample.foo/", { shiftKey: true }],
- ["example.foo/bar ", "http://example.foo/bar", { shiftKey: true }],
- ["1.1.1.1", "http://1.1.1.1/", { shiftKey: true }],
- ["ftp://example", "ftp://example/", { shiftKey: true }],
- ["ftp.example.bar", "http://ftp.example.bar/", { shiftKey: true }],
- ["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { shiftKey: true }],
- ];
-
- // Disable autoFill for this test, since it could mess up the results.
- let autoFill = Preferences.get("browser.urlbar.autoFill");
- Preferences.set("browser.urlbar.autoFill", false);
- registerCleanupFunction(() => {
- Preferences.set("browser.urlbar.autoFill", autoFill);
- });
-
- for (let [inputValue, expectedURL, options] of testcases) {
- let promiseLoad = waitForDocLoadAndStopIt(expectedURL);
- gURLBar.focus();
- if (Object.keys(options).length > 0) {
- gURLBar.selectionStart = gURLBar.selectionEnd =
- gURLBar.inputField.value.length;
- gURLBar.inputField.value = inputValue.slice(0, -1);
- EventUtils.synthesizeKey(inputValue.slice(-1), {});
- } else {
- gURLBar.textValue = inputValue;
- }
- EventUtils.synthesizeKey("VK_RETURN", options);
- yield promiseLoad;
- }
-});
diff --git a/browser/base/content/test/urlbar/browser_dragdropURL.js b/browser/base/content/test/urlbar/browser_dragdropURL.js
deleted file mode 100644
index ec2906700..000000000
--- a/browser/base/content/test/urlbar/browser_dragdropURL.js
+++ /dev/null
@@ -1,15 +0,0 @@
-"use strict";
-
-const TEST_URL = "data:text/html,a test page";
-const DRAG_URL = "http://www.example.com/";
-
-add_task(function* checkURLBarUpdateForDrag() {
- yield BrowserTestUtils.withNewTab(TEST_URL, function* (browser) {
- // Have to use something other than the URL bar as a source, so picking the
- // downloads button somewhat arbitrarily:
- EventUtils.synthesizeDrop(document.getElementById("downloads-button"), gURLBar,
- [[{type: "text/plain", data: DRAG_URL}]], "copy", window);
- is(gURLBar.value, TEST_URL, "URL bar value should not have changed");
- is(gBrowser.selectedBrowser.userTypedValue, null, "Stored URL bar value should not have changed");
- });
-});
diff --git a/browser/base/content/test/urlbar/browser_locationBarCommand.js b/browser/base/content/test/urlbar/browser_locationBarCommand.js
deleted file mode 100644
index 935bdf758..000000000
--- a/browser/base/content/test/urlbar/browser_locationBarCommand.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const TEST_VALUE = "example.com";
-const START_VALUE = "example.org";
-
-add_task(function* setup() {
- Services.prefs.setBoolPref("browser.altClickSave", true);
-
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.altClickSave");
- });
-});
-
-add_task(function* alt_left_click_test() {
- info("Running test: Alt left click");
-
- // Monkey patch saveURL() to avoid dealing with file save code paths.
- let oldSaveURL = saveURL;
- let saveURLPromise = new Promise(resolve => {
- saveURL = () => {
- // Restore old saveURL() value.
- saveURL = oldSaveURL;
- resolve();
- };
- });
-
- triggerCommand(true, {altKey: true});
-
- yield saveURLPromise;
- ok(true, "SaveURL was called");
- is(gURLBar.value, "", "Urlbar reverted to original value");
-});
-
-add_task(function* shift_left_click_test() {
- info("Running test: Shift left click");
-
- let newWindowPromise = BrowserTestUtils.waitForNewWindow();
- triggerCommand(true, {shiftKey: true});
- let win = yield newWindowPromise;
-
- // Wait for the initial browser to load.
- let browser = win.gBrowser.selectedBrowser;
- let destinationURL = "http://" + TEST_VALUE + "/";
- yield Promise.all([
- BrowserTestUtils.browserLoaded(browser),
- BrowserTestUtils.waitForLocationChange(win.gBrowser, destinationURL)
- ]);
-
- info("URL should be loaded in a new window");
- is(gURLBar.value, "", "Urlbar reverted to original value");
- yield promiseCheckChildNoFocusedElement(gBrowser.selectedBrowser);
- is(document.activeElement, gBrowser.selectedBrowser, "Content window should be focused");
- is(win.gURLBar.textValue, TEST_VALUE, "New URL is loaded in new window");
-
- // Cleanup.
- yield BrowserTestUtils.closeWindow(win);
-});
-
-add_task(function* right_click_test() {
- info("Running test: Right click on go button");
-
- // Add a new tab.
- yield* promiseOpenNewTab();
-
- triggerCommand(true, {button: 2});
-
- // Right click should do nothing (context menu will be shown).
- is(gURLBar.value, TEST_VALUE, "Urlbar still has the value we entered");
-
- // Cleanup.
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* shift_accel_left_click_test() {
- info("Running test: Shift+Ctrl/Cmd left click on go button");
-
- // Add a new tab.
- let tab = yield* promiseOpenNewTab();
-
- let loadStartedPromise = promiseLoadStarted();
- triggerCommand(true, {accelKey: true, shiftKey: true});
- yield loadStartedPromise;
-
- // Check the load occurred in a new background tab.
- info("URL should be loaded in a new background tab");
- is(gURLBar.value, "", "Urlbar reverted to original value");
- ok(!gURLBar.focused, "Urlbar is no longer focused after urlbar command");
- is(gBrowser.selectedTab, tab, "Focus did not change to the new tab");
-
- // Select the new background tab
- gBrowser.selectedTab = gBrowser.selectedTab.nextSibling;
- is(gURLBar.value, TEST_VALUE, "New URL is loaded in new tab");
-
- // Cleanup.
- gBrowser.removeCurrentTab();
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* load_in_current_tab_test() {
- let tests = [
- {desc: "Simple return keypress"},
- {desc: "Left click on go button", click: true},
- {desc: "Ctrl/Cmd+Return keypress", event: {accelKey: true}},
- {desc: "Alt+Return keypress in a blank tab", event: {altKey: true}}
- ];
-
- for (let test of tests) {
- info(`Running test: ${test.desc}`);
-
- // Add a new tab.
- let tab = yield* promiseOpenNewTab();
-
- // Trigger a load and check it occurs in the current tab.
- let loadStartedPromise = promiseLoadStarted();
- triggerCommand(test.click || false, test.event || {});
- yield loadStartedPromise;
-
- info("URL should be loaded in the current tab");
- is(gURLBar.value, TEST_VALUE, "Urlbar still has the value we entered");
- yield promiseCheckChildNoFocusedElement(gBrowser.selectedBrowser);
- is(document.activeElement, gBrowser.selectedBrowser, "Content window should be focused");
- is(gBrowser.selectedTab, tab, "New URL was loaded in the current tab");
-
- // Cleanup.
- gBrowser.removeCurrentTab();
- }
-});
-
-add_task(function* load_in_new_tab_test() {
- let tests = [
- {desc: "Ctrl/Cmd left click on go button", click: true, event: {accelKey: true}},
- {desc: "Alt+Return keypress in a dirty tab", event: {altKey: true}, url: START_VALUE}
- ];
-
- for (let test of tests) {
- info(`Running test: ${test.desc}`);
-
- // Add a new tab.
- let tab = yield* promiseOpenNewTab(test.url || "about:blank");
-
- // Trigger a load and check it occurs in the current tab.
- let tabSwitchedPromise = promiseNewTabSwitched();
- triggerCommand(test.click || false, test.event || {});
- yield tabSwitchedPromise;
-
- // Check the load occurred in a new tab.
- info("URL should be loaded in a new focused tab");
- is(gURLBar.inputField.value, TEST_VALUE, "Urlbar still has the value we entered");
- yield promiseCheckChildNoFocusedElement(gBrowser.selectedBrowser);
- is(document.activeElement, gBrowser.selectedBrowser, "Content window should be focused");
- isnot(gBrowser.selectedTab, tab, "New URL was loaded in a new tab");
-
- // Cleanup.
- gBrowser.removeCurrentTab();
- gBrowser.removeCurrentTab();
- }
-});
-
-function triggerCommand(shouldClick, event) {
- gURLBar.value = TEST_VALUE;
- gURLBar.focus();
-
- if (shouldClick) {
- is(gURLBar.getAttribute("pageproxystate"), "invalid",
- "page proxy state must be invalid for go button to be visible");
-
- let goButton = document.getElementById("urlbar-go-button");
- EventUtils.synthesizeMouseAtCenter(goButton, event);
- } else {
- EventUtils.synthesizeKey("VK_RETURN", event);
- }
-}
-
-function promiseLoadStarted() {
- return new Promise(resolve => {
- gBrowser.addTabsProgressListener({
- onStateChange(browser, webProgress, req, flags, status) {
- if (flags & Ci.nsIWebProgressListener.STATE_START) {
- gBrowser.removeTabsProgressListener(this);
- resolve();
- }
- }
- });
- });
-}
-
-function* promiseOpenNewTab(url = "about:blank") {
- let tab = gBrowser.addTab(url);
- let tabSwitchPromise = promiseNewTabSwitched(tab);
- 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);
- executeSoon(resolve);
- });
- });
-}
-
-function promiseCheckChildNoFocusedElement(browser)
-{
- if (!gMultiProcessBrowser) {
- Assert.equal(Services.focus.focusedElement, null, "There should be no focused element");
- return null;
- }
-
- return ContentTask.spawn(browser, { }, function* () {
- const fm = Components.classes["@mozilla.org/focus-manager;1"].
- getService(Components.interfaces.nsIFocusManager);
- Assert.equal(fm.focusedElement, null, "There should be no focused element");
- });
-}
diff --git a/browser/base/content/test/urlbar/browser_locationBarExternalLoad.js b/browser/base/content/test/urlbar/browser_locationBarExternalLoad.js
deleted file mode 100644
index 31fc84768..000000000
--- a/browser/base/content/test/urlbar/browser_locationBarExternalLoad.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const url = "data:text/html,<body>hi";
-
-add_task(function*() {
- yield* testURL(url, urlEnter);
- yield* testURL(url, urlClick);
-});
-
-function urlEnter(url) {
- gURLBar.value = url;
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
-}
-
-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);
- executeSoon(resolve);
- });
- });
-}
-
-function* testURL(url, loadFunc, endFunc) {
- let tabSwitchedPromise = promiseNewTabSwitched();
- let tab = gBrowser.selectedTab = gBrowser.addTab();
- let browser = gBrowser.selectedBrowser;
-
- let pageshowPromise = BrowserTestUtils.waitForContentEvent(browser, "pageshow");
-
- yield tabSwitchedPromise;
- yield pageshowPromise;
-
- let pagePrincipal = gBrowser.contentPrincipal;
- loadFunc(url);
-
- yield BrowserTestUtils.waitForContentEvent(browser, "pageshow");
-
- yield ContentTask.spawn(browser, { isRemote: gMultiProcessBrowser },
- function* (arg) {
- const fm = Components.classes["@mozilla.org/focus-manager;1"].
- getService(Components.interfaces.nsIFocusManager);
- Assert.equal(fm.focusedElement, null, "focusedElement not null");
-
- if (arg.isRemote) {
- Assert.equal(fm.activeWindow, content, "activeWindow not correct");
- }
- });
-
- is(document.activeElement, browser, "content window should be focused");
-
- ok(!gBrowser.contentPrincipal.equals(pagePrincipal),
- "load of " + url + " by " + loadFunc.name + " should produce a page with a different principal");
-
- gBrowser.removeTab(tab);
-}
diff --git a/browser/base/content/test/urlbar/browser_moz_action_link.js b/browser/base/content/test/urlbar/browser_moz_action_link.js
deleted file mode 100644
index ed2d36ee5..000000000
--- a/browser/base/content/test/urlbar/browser_moz_action_link.js
+++ /dev/null
@@ -1,31 +0,0 @@
-"use strict";
-
-const kURIs = [
- "moz-action:foo,",
- "moz-action:foo",
-];
-
-add_task(function*() {
- for (let uri of kURIs) {
- let dataURI = `data:text/html,<a id=a href="${uri}" target=_blank>Link</a>`;
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, dataURI);
-
- let tabSwitchPromise = BrowserTestUtils.switchTab(gBrowser, function() {});
- yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
- content.document.getElementById("a").click();
- });
- yield tabSwitchPromise;
- isnot(gBrowser.selectedTab, tab, "Switched to new tab!");
- is(gURLBar.value, "about:blank", "URL bar should be displaying about:blank");
- let newTab = gBrowser.selectedTab;
- yield BrowserTestUtils.switchTab(gBrowser, tab);
- yield BrowserTestUtils.switchTab(gBrowser, newTab);
- is(gBrowser.selectedTab, newTab, "Switched to new tab again!");
- is(gURLBar.value, "about:blank", "URL bar should be displaying about:blank after tab switch");
- // Finally, check that directly setting it produces the right results, too:
- URLBarSetURI(makeURI(uri));
- is(gURLBar.value, "about:blank", "URL bar should still be displaying about:blank");
- yield BrowserTestUtils.removeTab(newTab);
- yield BrowserTestUtils.removeTab(tab);
- }
-});
diff --git a/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js b/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js
deleted file mode 100644
index e9ba8d989..000000000
--- a/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js
+++ /dev/null
@@ -1,49 +0,0 @@
-function test() {
- waitForExplicitFinish();
- testNext();
-}
-
-var pairs = [
- ["javascript:", ""],
- ["javascript:1+1", "1+1"],
- ["javascript:document.domain", "document.domain"],
- ["data:text/html,<body>hi</body>", "data:text/html,<body>hi</body>"],
- // Nested things get confusing because some things don't parse as URIs:
- ["javascript:javascript:alert('hi!')", "alert('hi!')"],
- ["data:data:text/html,<body>hi</body>", "data:data:text/html,<body>hi</body>"],
- ["javascript:data:javascript:alert('hi!')", "data:javascript:alert('hi!')"],
- ["javascript:data:text/html,javascript:alert('hi!')", "data:text/html,javascript:alert('hi!')"],
- ["data:data:text/html,javascript:alert('hi!')", "data:data:text/html,javascript:alert('hi!')"],
-];
-
-var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
-
-function paste(input, cb) {
- waitForClipboard(input, function() {
- clipboardHelper.copyString(input);
- }, function() {
- document.commandDispatcher.getControllerForCommand("cmd_paste").doCommand("cmd_paste");
- cb();
- }, function() {
- ok(false, "Failed to copy string '" + input + "' to clipboard");
- cb();
- });
-}
-
-function testNext() {
- gURLBar.value = '';
- if (!pairs.length) {
- finish();
- return;
- }
-
- let [inputValue, expectedURL] = pairs.shift();
-
- gURLBar.focus();
- paste(inputValue, function() {
- is(gURLBar.textValue, expectedURL, "entering '" + inputValue + "' strips relevant bits.");
-
- setTimeout(testNext, 0);
- });
-}
-
diff --git a/browser/base/content/test/urlbar/browser_search_favicon.js b/browser/base/content/test/urlbar/browser_search_favicon.js
deleted file mode 100644
index a8e6dbbcd..000000000
--- a/browser/base/content/test/urlbar/browser_search_favicon.js
+++ /dev/null
@@ -1,52 +0,0 @@
-var gOriginalEngine;
-var gEngine;
-var gRestyleSearchesPref = "browser.urlbar.restyleSearches";
-
-registerCleanupFunction(() => {
- Services.prefs.clearUserPref(gRestyleSearchesPref);
- Services.search.currentEngine = gOriginalEngine;
- Services.search.removeEngine(gEngine);
- return PlacesTestUtils.clearHistory();
-});
-
-add_task(function*() {
- Services.prefs.setBoolPref(gRestyleSearchesPref, true);
-});
-
-add_task(function*() {
-
- Services.search.addEngineWithDetails("SearchEngine", "", "", "",
- "GET", "http://s.example.com/search");
- gEngine = Services.search.getEngineByName("SearchEngine");
- gEngine.addParam("q", "{searchTerms}", null);
- gOriginalEngine = Services.search.currentEngine;
- Services.search.currentEngine = gEngine;
-
- let uri = NetUtil.newURI("http://s.example.com/search?q=foo&client=1");
- yield PlacesTestUtils.addVisits({ uri: uri, title: "Foo - SearchEngine Search" });
-
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
-
- // The first autocomplete result has the action searchengine, while
- // the second result is the "search favicon" element.
- yield promiseAutocompleteResultPopup("foo");
- let result = gURLBar.popup.richlistbox.children[1];
-
- isnot(result, null, "Expect a search result");
- is(result.getAttribute("type"), "searchengine", "Expect correct `type` attribute");
-
- let titleHbox = result._titleText.parentNode.parentNode;
- ok(titleHbox.classList.contains("ac-title"), "Title hbox sanity check");
- is_element_visible(titleHbox, "Title element should be visible");
-
- let urlHbox = result._urlText.parentNode.parentNode;
- ok(urlHbox.classList.contains("ac-url"), "URL hbox sanity check");
- is_element_hidden(urlHbox, "URL element should be hidden");
-
- let actionHbox = result._actionText.parentNode.parentNode;
- ok(actionHbox.classList.contains("ac-action"), "Action hbox sanity check");
- is_element_hidden(actionHbox, "Action element should be hidden because it is not selected");
- is(result._actionText.textContent, "Search with SearchEngine", "Action text should be as expected");
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar.js b/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar.js
deleted file mode 100644
index d207092d4..000000000
--- a/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar.js
+++ /dev/null
@@ -1,216 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-requestLongerTimeout(2);
-
-const TEST_URL_BASES = [
- "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html#tabmatch",
- "http://example.org/browser/browser/base/content/test/urlbar/moz.png#tabmatch"
-];
-
-var gController = Cc["@mozilla.org/autocomplete/controller;1"].
- getService(Ci.nsIAutoCompleteController);
-
-var gTabCounter = 0;
-
-add_task(function* step_1() {
- info("Running step 1");
- let maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
- let promises = [];
- for (let i = 0; i < maxResults - 1; i++) {
- let tab = gBrowser.addTab();
- promises.push(loadTab(tab, TEST_URL_BASES[0] + (++gTabCounter)));
- }
-
- yield Promise.all(promises);
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* step_2() {
- info("Running step 2");
- gBrowser.selectTabAtIndex(1);
- gBrowser.removeCurrentTab();
- gBrowser.selectTabAtIndex(1);
- gBrowser.removeCurrentTab();
-
- let promises = [];
- for (let i = 1; i < gBrowser.tabs.length; i++)
- promises.push(loadTab(gBrowser.tabs[i], TEST_URL_BASES[1] + (++gTabCounter)));
-
- yield Promise.all(promises);
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* step_3() {
- info("Running step 3");
- let promises = [];
- for (let i = 1; i < gBrowser.tabs.length; i++)
- promises.push(loadTab(gBrowser.tabs[i], TEST_URL_BASES[0] + gTabCounter));
-
- yield Promise.all(promises);
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* step_4() {
- info("Running step 4 - ensure we don't register subframes as open pages");
- let tab = gBrowser.addTab();
- tab.linkedBrowser.loadURI('data:text/html,<body><iframe src=""></iframe></body>');
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
- let iframe_loaded = ContentTaskUtils.waitForEvent(content.document, "load", true);
- content.document.querySelector("iframe").src = "http://test2.example.org/";
- yield iframe_loaded;
- });
-
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* step_5() {
- info("Running step 5 - remove tab immediately");
- let tab = gBrowser.addTab("about:logo");
- yield BrowserTestUtils.removeTab(tab);
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* step_6() {
- info("Running step 6 - check swapBrowsersAndCloseOther preserves registered switch-to-tab result");
- let tabToKeep = gBrowser.addTab();
- let tab = gBrowser.addTab();
- tab.linkedBrowser.loadURI("about:mozilla");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- gBrowser.updateBrowserRemoteness(tabToKeep.linkedBrowser, tab.linkedBrowser.isRemoteBrowser);
- gBrowser.swapBrowsersAndCloseOther(tabToKeep, tab);
-
- yield ensure_opentabs_match_db()
-
- yield BrowserTestUtils.removeTab(tabToKeep);
-
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* step_7() {
- info("Running step 7 - close all tabs");
-
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
-
- gBrowser.addTab("about:blank", {skipAnimation: true});
- while (gBrowser.tabs.length > 1) {
- info("Removing tab: " + gBrowser.tabs[0].linkedBrowser.currentURI.spec);
- gBrowser.selectTabAtIndex(0);
- gBrowser.removeCurrentTab();
- }
-
- yield ensure_opentabs_match_db();
-});
-
-add_task(function* cleanup() {
- info("Cleaning up");
-
- yield PlacesTestUtils.clearHistory();
-});
-
-function loadTab(tab, url) {
- // Because adding visits is async, we will not be notified immediately.
- let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- let visited = new Promise(resolve => {
- Services.obs.addObserver(
- function observer(aSubject, aTopic, aData) {
- if (url != aSubject.QueryInterface(Ci.nsIURI).spec)
- return;
- Services.obs.removeObserver(observer, aTopic);
- resolve();
- },
- "uri-visit-saved",
- false
- );
- });
-
- info("Loading page: " + url);
- tab.linkedBrowser.loadURI(url);
- return Promise.all([ loaded, visited ]);
-}
-
-function ensure_opentabs_match_db() {
- var tabs = {};
-
- var winEnum = Services.wm.getEnumerator("navigator:browser");
- while (winEnum.hasMoreElements()) {
- let browserWin = winEnum.getNext();
- // skip closed-but-not-destroyed windows
- if (browserWin.closed)
- continue;
-
- for (let i = 0; i < browserWin.gBrowser.tabContainer.childElementCount; i++) {
- let browser = browserWin.gBrowser.getBrowserAtIndex(i);
- let url = browser.currentURI.spec;
- if (browserWin.isBlankPageURL(url))
- continue;
- if (!(url in tabs))
- tabs[url] = 1;
- else
- tabs[url]++;
- }
- }
-
- return new Promise(resolve => {
- checkAutocompleteResults(tabs, resolve);
- });
-}
-
-function checkAutocompleteResults(aExpected, aCallback)
-{
- gController.input = {
- timeout: 10,
- textValue: "",
- searches: ["unifiedcomplete"],
- searchParam: "enable-actions",
- popupOpen: false,
- minResultsForPopup: 0,
- invalidate: function() {},
- disableAutoComplete: false,
- completeDefaultIndex: false,
- get popup() { return this; },
- onSearchBegin: function() {},
- onSearchComplete: function ()
- {
- info("Found " + gController.matchCount + " matches.");
- // Check to see the expected uris and titles match up (in any order)
- for (let i = 0; i < gController.matchCount; i++) {
- if (gController.getStyleAt(i).includes("heuristic")) {
- info("Skip heuristic match");
- continue;
- }
- let action = gURLBar.popup.input._parseActionUrl(gController.getValueAt(i));
- let uri = action.params.url;
-
- info("Search for '" + uri + "' in open tabs.");
- let expected = uri in aExpected;
- ok(expected, uri + " was found in autocomplete, was " + (expected ? "" : "not ") + "expected");
- // Remove the found entry from expected results.
- delete aExpected[uri];
- }
-
- // Make sure there is no reported open page that is not open.
- for (let entry in aExpected) {
- ok(false, "'" + entry + "' should be found in autocomplete");
- }
-
- executeSoon(aCallback);
- },
- setSelectedIndex: function() {},
- get searchCount() { return this.searches.length; },
- getSearchAt: function(aIndex) { return this.searches[aIndex]; },
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIAutoCompleteInput,
- Ci.nsIAutoCompletePopup,
- ])
- };
-
- info("Searching open pages.");
- gController.startSearch(Services.prefs.getCharPref("browser.urlbar.restrict.openpage"));
-}
diff --git a/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar_perwindowpb.js b/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar_perwindowpb.js
deleted file mode 100644
index 08a18b38a..000000000
--- a/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar_perwindowpb.js
+++ /dev/null
@@ -1,84 +0,0 @@
-let testURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
-
-add_task(function*() {
- let normalWindow = yield BrowserTestUtils.openNewBrowserWindow();
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield runTest(normalWindow, privateWindow, false);
- yield BrowserTestUtils.closeWindow(normalWindow);
- yield BrowserTestUtils.closeWindow(privateWindow);
-
- normalWindow = yield BrowserTestUtils.openNewBrowserWindow();
- privateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield runTest(privateWindow, normalWindow, false);
- yield BrowserTestUtils.closeWindow(normalWindow);
- yield BrowserTestUtils.closeWindow(privateWindow);
-
- privateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield runTest(privateWindow, privateWindow, false);
- yield BrowserTestUtils.closeWindow(privateWindow);
-
- normalWindow = yield BrowserTestUtils.openNewBrowserWindow();
- yield runTest(normalWindow, normalWindow, true);
- yield BrowserTestUtils.closeWindow(normalWindow);
-});
-
-function* runTest(aSourceWindow, aDestWindow, aExpectSwitch, aCallback) {
- yield BrowserTestUtils.openNewForegroundTab(aSourceWindow.gBrowser, testURL);
- let testTab = yield BrowserTestUtils.openNewForegroundTab(aDestWindow.gBrowser);
-
- info("waiting for focus on the window");
- yield SimpleTest.promiseFocus(aDestWindow);
- info("got focus on the window");
-
- // Select the testTab
- aDestWindow.gBrowser.selectedTab = testTab;
-
- // Ensure that this tab has no history entries
- let sessionHistoryCount = yield new Promise(resolve => {
- SessionStore.getSessionHistory(gBrowser.selectedTab, function(sessionHistory) {
- resolve(sessionHistory.entries.length);
- });
- });
-
- ok(sessionHistoryCount < 2,
- `The test tab has 1 or fewer history entries. sessionHistoryCount=${sessionHistoryCount}`);
- // Ensure that this tab is on about:blank
- is(testTab.linkedBrowser.currentURI.spec, "about:blank",
- "The test tab is on about:blank");
- // Ensure that this tab's document has no child nodes
- yield ContentTask.spawn(testTab.linkedBrowser, null, function*() {
- ok(!content.document.body.hasChildNodes(),
- "The test tab has no child nodes");
- });
- ok(!testTab.hasAttribute("busy"),
- "The test tab doesn't have the busy attribute");
-
- // Wait for the Awesomebar popup to appear.
- yield promiseAutocompleteResultPopup(testURL, aDestWindow);
-
- info(`awesomebar popup appeared. aExpectSwitch: ${aExpectSwitch}`);
- // Make sure the last match is selected.
- let {controller, popup} = aDestWindow.gURLBar;
- while (popup.selectedIndex < controller.matchCount - 1) {
- info("handling key navigation for DOM_VK_DOWN key");
- controller.handleKeyNavigation(KeyEvent.DOM_VK_DOWN);
- }
-
- let awaitTabSwitch;
- if (aExpectSwitch) {
- awaitTabSwitch = BrowserTestUtils.removeTab(testTab, {dontRemove: true})
- }
-
- // Execute the selected action.
- controller.handleEnter(true);
- info("sent Enter command to the controller");
-
- if (aExpectSwitch) {
- // If we expect a tab switch then the current tab
- // will be closed and we switch to the other tab.
- yield awaitTabSwitch;
- } else {
- // If we don't expect a tab switch then wait for the tab to load.
- yield BrowserTestUtils.browserLoaded(testTab.linkedBrowser);
- }
-}
diff --git a/browser/base/content/test/urlbar/browser_urlHighlight.js b/browser/base/content/test/urlbar/browser_urlHighlight.js
deleted file mode 100644
index ba1537d91..000000000
--- a/browser/base/content/test/urlbar/browser_urlHighlight.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-function testVal(aExpected) {
- gURLBar.value = aExpected.replace(/[<>]/g, "");
-
- let selectionController = gURLBar.editor.selectionController;
- let selection = selectionController.getSelection(selectionController.SELECTION_URLSECONDARY);
- let value = gURLBar.editor.rootElement.textContent;
- let result = "";
- for (let i = 0; i < selection.rangeCount; i++) {
- let range = selection.getRangeAt(i).toString();
- let pos = value.indexOf(range);
- result += value.substring(0, pos) + "<" + range + ">";
- value = value.substring(pos + range.length);
- }
- result += value;
- is(result, aExpected,
- "Correct part of the urlbar contents is highlighted");
-}
-
-function test() {
- const prefname = "browser.urlbar.formatting.enabled";
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(prefname);
- URLBarSetURI();
- });
-
- Services.prefs.setBoolPref(prefname, true);
-
- gURLBar.focus();
-
- testVal("https://mozilla.org");
-
- gBrowser.selectedBrowser.focus();
-
- testVal("<https://>mozilla.org");
- testVal("<https://>mözilla.org");
- testVal("<https://>mozilla.imaginatory");
-
- testVal("<https://www.>mozilla.org");
- testVal("<https://sub.>mozilla.org");
- testVal("<https://sub1.sub2.sub3.>mozilla.org");
- testVal("<www.>mozilla.org");
- testVal("<sub.>mozilla.org");
- testVal("<sub1.sub2.sub3.>mozilla.org");
- testVal("<mozilla.com.>mozilla.com");
- testVal("<https://mozilla.com:mozilla.com@>mozilla.com");
- testVal("<mozilla.com:mozilla.com@>mozilla.com");
-
- testVal("<ftp.>mozilla.org");
- testVal("<ftp://ftp.>mozilla.org");
-
- testVal("<https://sub.>mozilla.org");
- testVal("<https://sub1.sub2.sub3.>mozilla.org");
- testVal("<https://user:pass@sub1.sub2.sub3.>mozilla.org");
- testVal("<https://user:pass@>mozilla.org");
- testVal("<user:pass@sub1.sub2.sub3.>mozilla.org");
- testVal("<user:pass@>mozilla.org");
-
- testVal("<https://>mozilla.org< >");
- testVal("mozilla.org< >");
-
- testVal("<https://>mozilla.org</file.ext>");
- testVal("<https://>mozilla.org</sub/file.ext>");
- testVal("<https://>mozilla.org</sub/file.ext?foo>");
- testVal("<https://>mozilla.org</sub/file.ext?foo&bar>");
- testVal("<https://>mozilla.org</sub/file.ext?foo&bar#top>");
- testVal("<https://>mozilla.org</sub/file.ext?foo&bar#top>");
- testVal("foo.bar<?q=test>");
- testVal("foo.bar<#mozilla.org>");
- testVal("foo.bar<?somewhere.mozilla.org>");
- testVal("foo.bar<?@mozilla.org>");
- testVal("foo.bar<#x@mozilla.org>");
- testVal("foo.bar<#@x@mozilla.org>");
- testVal("foo.bar<?x@mozilla.org>");
- testVal("foo.bar<?@x@mozilla.org>");
- testVal("<foo.bar@x@>mozilla.org");
- testVal("<foo.bar@:baz@>mozilla.org");
- testVal("<foo.bar:@baz@>mozilla.org");
- testVal("<foo.bar@:ba:z@>mozilla.org");
- testVal("<foo.:bar:@baz@>mozilla.org");
-
- testVal("<https://sub.>mozilla.org<:666/file.ext>");
- testVal("<sub.>mozilla.org<:666/file.ext>");
- testVal("localhost<:666/file.ext>");
-
- let IPs = ["192.168.1.1",
- "[::]",
- "[::1]",
- "[1::]",
- "[::]",
- "[::1]",
- "[1::]",
- "[1:2:3:4:5:6:7::]",
- "[::1:2:3:4:5:6:7]",
- "[1:2:a:B:c:D:e:F]",
- "[1::8]",
- "[1:2::8]",
- "[fe80::222:19ff:fe11:8c76]",
- "[0000:0123:4567:89AB:CDEF:abcd:ef00:0000]",
- "[::192.168.1.1]",
- "[1::0.0.0.0]",
- "[1:2::255.255.255.255]",
- "[1:2:3::255.255.255.255]",
- "[1:2:3:4::255.255.255.255]",
- "[1:2:3:4:5::255.255.255.255]",
- "[1:2:3:4:5:6:255.255.255.255]"];
- IPs.forEach(function (IP) {
- testVal(IP);
- testVal(IP + "</file.ext>");
- testVal(IP + "<:666/file.ext>");
- testVal("<https://>" + IP);
- testVal("<https://>" + IP + "</file.ext>");
- testVal("<https://user:pass@>" + IP + "<:666/file.ext>");
- testVal("<user:pass@>" + IP + "<:666/file.ext>");
- });
-
- testVal("mailto:admin@mozilla.org");
- testVal("gopher://mozilla.org/");
- testVal("about:config");
- testVal("jar:http://mozilla.org/example.jar!/");
- testVal("view-source:http://mozilla.org/");
- testVal("foo9://mozilla.org/");
- testVal("foo+://mozilla.org/");
- testVal("foo.://mozilla.org/");
- testVal("foo-://mozilla.org/");
-
- Services.prefs.setBoolPref(prefname, false);
-
- testVal("https://mozilla.org");
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js b/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
deleted file mode 100644
index 792826eb1..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
+++ /dev/null
@@ -1,104 +0,0 @@
-"use strict";
-
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-/**
- * 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);
- resolve(gBrowser.selectedTab);
- }, 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);
- resolve(gBrowser.selectedTab);
- }, 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);
-});
-
-/**
- * Load about:home directly from an about:newtab page. Because it is an
- * 'initial' page, we need to treat this specially if the user actually
- * loads a page like this from the URL bar.
- */
-add_task(function* clearURLBarAfterManuallyLoadingAboutHome() {
- let promiseTabOpenedAndSwitchedTo = BrowserTestUtils.switchTab(gBrowser, () => {});
- // This opens about:newtab:
- BrowserOpenTab();
- let tab = yield promiseTabOpenedAndSwitchedTo;
- is(gURLBar.value, "", "URL bar should be empty");
- is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
-
- gURLBar.value = "about:home";
- gURLBar.select();
- let aboutHomeLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, "about:home");
- EventUtils.sendKey("return");
- yield aboutHomeLoaded;
-
- is(gURLBar.value, "", "URL bar should be empty");
- is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
- yield BrowserTestUtils.removeTab(tab);
-});
-
-/**
- * Ensure we don't show 'about:home' in the URL bar temporarily in new tabs
- * while we're switching remoteness (when the URL we're loading and the
- * default content principal are different).
- */
-add_task(function* dontTemporarilyShowAboutHome() {
- yield SpecialPowers.pushPrefEnv({set: [["browser.startup.page", 1]]});
- let windowOpenedPromise = BrowserTestUtils.waitForNewWindow();
- let win = OpenBrowserWindow();
- yield windowOpenedPromise;
- let promiseTabSwitch = BrowserTestUtils.switchTab(win.gBrowser, () => {});
- win.BrowserOpenTab();
- yield promiseTabSwitch;
- yield TabStateFlusher.flush(win.gBrowser.selectedBrowser);
- yield BrowserTestUtils.closeWindow(win);
- ok(SessionStore.getClosedWindowCount(), "Should have a closed window");
-
- windowOpenedPromise = BrowserTestUtils.waitForNewWindow();
- win = SessionStore.undoCloseWindow(0);
- yield windowOpenedPromise;
- let wpl = {
- onLocationChange(wpl, request, location, flags) {
- is(win.gURLBar.value, "", "URL bar value should stay empty.");
- },
- };
- win.gBrowser.addProgressListener(wpl);
- let otherTab = win.gBrowser.selectedTab.previousSibling;
- let tabLoaded = BrowserTestUtils.browserLoaded(otherTab.linkedBrowser, false, "about:home");
- yield BrowserTestUtils.switchTab(win.gBrowser, otherTab);
- yield tabLoaded;
- win.gBrowser.removeProgressListener(wpl);
- is(win.gURLBar.value, "", "URL bar value should be empty.");
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarAutoFillTrimURLs.js b/browser/base/content/test/urlbar/browser_urlbarAutoFillTrimURLs.js
deleted file mode 100644
index 8101c101d..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarAutoFillTrimURLs.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// This test ensures that autoFilled values are not trimmed, unless the user
-// selects from the autocomplete popup.
-
-add_task(function* setup() {
- const PREF_TRIMURL = "browser.urlbar.trimURLs";
- const PREF_AUTOFILL = "browser.urlbar.autoFill";
-
- registerCleanupFunction(function* () {
- Services.prefs.clearUserPref(PREF_TRIMURL);
- Services.prefs.clearUserPref(PREF_AUTOFILL);
- yield PlacesTestUtils.clearHistory();
- gURLBar.handleRevert();
- });
- Services.prefs.setBoolPref(PREF_TRIMURL, true);
- Services.prefs.setBoolPref(PREF_AUTOFILL, true);
-
- // Adding a tab would hit switch-to-tab, so it's safer to just add a visit.
- yield PlacesTestUtils.addVisits({
- uri: "http://www.autofilltrimurl.com/whatever",
- transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
- });
-});
-
-function* promiseSearch(searchtext) {
- gURLBar.focus();
- gURLBar.inputField.value = searchtext.substr(0, searchtext.length -1);
- EventUtils.synthesizeKey(searchtext.substr(-1, 1), {});
- yield promiseSearchComplete();
-}
-
-add_task(function* () {
- yield promiseSearch("http://");
- is(gURLBar.inputField.value, "http://", "Autofilled value is as expected");
-});
-
-add_task(function* () {
- yield promiseSearch("http://au");
- is(gURLBar.inputField.value, "http://autofilltrimurl.com/", "Autofilled value is as expected");
-});
-
-add_task(function* () {
- yield promiseSearch("http://www.autofilltrimurl.com");
- is(gURLBar.inputField.value, "http://www.autofilltrimurl.com/", "Autofilled value is as expected");
-
- // Now ensure selecting from the popup correctly trims.
- is(gURLBar.controller.matchCount, 2, "Found the expected number of matches");
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(gURLBar.inputField.value, "www.autofilltrimurl.com/whatever", "trim was applied correctly");
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarCopying.js b/browser/base/content/test/urlbar/browser_urlbarCopying.js
deleted file mode 100644
index 8d5562b61..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarCopying.js
+++ /dev/null
@@ -1,232 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const trimPref = "browser.urlbar.trimURLs";
-const phishyUserPassPref = "network.http.phishy-userpass-length";
-
-function toUnicode(input) {
- let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Ci.nsIScriptableUnicodeConverter);
- converter.charset = "UTF-8";
-
- return converter.ConvertToUnicode(input);
-}
-
-function test() {
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- registerCleanupFunction(function () {
- gBrowser.removeTab(tab);
- Services.prefs.clearUserPref(trimPref);
- Services.prefs.clearUserPref(phishyUserPassPref);
- URLBarSetURI();
- });
-
- Services.prefs.setBoolPref(trimPref, true);
- Services.prefs.setIntPref(phishyUserPassPref, 32); // avoid prompting about phishing
-
- waitForExplicitFinish();
-
- nextTest();
-}
-
-var tests = [
- // pageproxystate="invalid"
- {
- setURL: "http://example.com/",
- expectedURL: "example.com",
- copyExpected: "example.com"
- },
- {
- copyVal: "<e>xample.com",
- copyExpected: "e"
- },
-
- // pageproxystate="valid" from this point on (due to the load)
- {
- loadURL: "http://example.com/",
- expectedURL: "example.com",
- copyExpected: "http://example.com/"
- },
- {
- copyVal: "<example.co>m",
- copyExpected: "example.co"
- },
- {
- copyVal: "e<x>ample.com",
- copyExpected: "x"
- },
- {
- copyVal: "<e>xample.com",
- copyExpected: "e"
- },
-
- {
- loadURL: "http://example.com/foo",
- expectedURL: "example.com/foo",
- copyExpected: "http://example.com/foo"
- },
- {
- copyVal: "<example.com>/foo",
- copyExpected: "http://example.com"
- },
- {
- copyVal: "<example>.com/foo",
- copyExpected: "example"
- },
-
- // Test that userPass is stripped out
- {
- loadURL: "http://user:pass@mochi.test:8888/browser/browser/base/content/test/urlbar/authenticate.sjs?user=user&pass=pass",
- expectedURL: "mochi.test:8888/browser/browser/base/content/test/urlbar/authenticate.sjs?user=user&pass=pass",
- copyExpected: "http://mochi.test:8888/browser/browser/base/content/test/urlbar/authenticate.sjs?user=user&pass=pass"
- },
-
- // Test escaping
- {
- loadURL: "http://example.com/()%28%29%C3%A9",
- expectedURL: "example.com/()()\xe9",
- copyExpected: "http://example.com/()%28%29%C3%A9"
- },
- {
- copyVal: "<example.com/(>)()\xe9",
- copyExpected: "http://example.com/("
- },
- {
- copyVal: "e<xample.com/(>)()\xe9",
- copyExpected: "xample.com/("
- },
-
- {
- loadURL: "http://example.com/%C3%A9%C3%A9",
- expectedURL: "example.com/\xe9\xe9",
- copyExpected: "http://example.com/%C3%A9%C3%A9"
- },
- {
- copyVal: "e<xample.com/\xe9>\xe9",
- copyExpected: "xample.com/\xe9"
- },
- {
- copyVal: "<example.com/\xe9>\xe9",
- copyExpected: "http://example.com/\xe9"
- },
-
- {
- loadURL: "http://example.com/?%C3%B7%C3%B7",
- expectedURL: "example.com/?\xf7\xf7",
- copyExpected: "http://example.com/?%C3%B7%C3%B7"
- },
- {
- copyVal: "e<xample.com/?\xf7>\xf7",
- copyExpected: "xample.com/?\xf7"
- },
- {
- copyVal: "<example.com/?\xf7>\xf7",
- copyExpected: "http://example.com/?\xf7"
- },
- {
- loadURL: "http://example.com/a%20test",
- expectedURL: "example.com/a test",
- copyExpected: "http://example.com/a%20test"
- },
- {
- loadURL: "http://example.com/a%E3%80%80test",
- expectedURL: toUnicode("example.com/a test"),
- copyExpected: "http://example.com/a%E3%80%80test"
- },
- {
- loadURL: "http://example.com/a%20%C2%A0test",
- expectedURL: "example.com/a%20%C2%A0test",
- copyExpected: "http://example.com/a%20%C2%A0test"
- },
- {
- loadURL: "http://example.com/%20%20%20",
- expectedURL: "example.com/%20%20%20",
- copyExpected: "http://example.com/%20%20%20"
- },
- {
- loadURL: "http://example.com/%E3%80%80%E3%80%80",
- expectedURL: "example.com/%E3%80%80%E3%80%80",
- copyExpected: "http://example.com/%E3%80%80%E3%80%80"
- },
-
- // data: and javsacript: URIs shouldn't be encoded
- {
- loadURL: "javascript:('%C3%A9%20%25%50')",
- expectedURL: "javascript:('%C3%A9 %25P')",
- copyExpected: "javascript:('%C3%A9 %25P')"
- },
- {
- copyVal: "<javascript:(>'%C3%A9 %25P')",
- copyExpected: "javascript:("
- },
-
- {
- loadURL: "data:text/html,(%C3%A9%20%25%50)",
- expectedURL: "data:text/html,(%C3%A9 %25P)",
- copyExpected: "data:text/html,(%C3%A9 %25P)",
- },
- {
- copyVal: "<data:text/html,(>%C3%A9 %25P)",
- copyExpected: "data:text/html,("
- },
- {
- copyVal: "<data:text/html,(%C3%A9 %25P>)",
- copyExpected: "data:text/html,(%C3%A9 %25P",
- }
-];
-
-function nextTest() {
- let test = tests.shift();
- if (tests.length == 0)
- runTest(test, finish);
- else
- runTest(test, nextTest);
-}
-
-function runTest(test, cb) {
- function doCheck() {
- if (test.setURL || test.loadURL) {
- gURLBar.valueIsTyped = !!test.setURL;
- is(gURLBar.textValue, test.expectedURL, "url bar value set");
- }
-
- testCopy(test.copyVal, test.copyExpected, cb);
- }
-
- if (test.loadURL) {
- loadURL(test.loadURL, doCheck);
- } else {
- if (test.setURL)
- gURLBar.value = test.setURL;
- doCheck();
- }
-}
-
-function testCopy(copyVal, targetValue, cb) {
- info("Expecting copy of: " + targetValue);
- waitForClipboard(targetValue, function () {
- gURLBar.focus();
- if (copyVal) {
- let startBracket = copyVal.indexOf("<");
- let endBracket = copyVal.indexOf(">");
- if (startBracket == -1 || endBracket == -1 ||
- startBracket > endBracket ||
- copyVal.replace("<", "").replace(">", "") != gURLBar.textValue) {
- ok(false, "invalid copyVal: " + copyVal);
- }
- gURLBar.selectionStart = startBracket;
- gURLBar.selectionEnd = endBracket - 1;
- } else {
- gURLBar.select();
- }
-
- goDoCommand("cmd_copy");
- }, cb, cb);
-}
-
-function loadURL(aURL, aCB) {
- BrowserTestUtils.loadURI(gBrowser.selectedBrowser, aURL);
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, aURL).then(aCB);
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarDecode.js b/browser/base/content/test/urlbar/browser_urlbarDecode.js
deleted file mode 100644
index 6a2c421ef..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarDecode.js
+++ /dev/null
@@ -1,97 +0,0 @@
-"use strict";
-
-// This test makes sure (1) you can't break the urlbar by typing particular JSON
-// or JS fragments into it, (2) urlbar.textValue shows URLs unescaped, and (3)
-// the urlbar also shows the URLs embedded in action URIs unescaped. See bug
-// 1233672.
-
-add_task(function* injectJSON() {
- let inputStrs = [
- 'http://example.com/ ", "url": "bar',
- 'http://example.com/\\',
- 'http://example.com/"',
- 'http://example.com/","url":"evil.com',
- 'http://mozilla.org/\\u0020',
- 'http://www.mozilla.org/","url":1e6,"some-key":"foo',
- 'http://www.mozilla.org/","url":null,"some-key":"foo',
- 'http://www.mozilla.org/","url":["foo","bar"],"some-key":"foo',
- ];
- for (let inputStr of inputStrs) {
- yield checkInput(inputStr);
- }
- gURLBar.value = "";
- gURLBar.handleRevert();
- gURLBar.blur();
-});
-
-add_task(function losslessDecode() {
- let urlNoScheme = "example.com/\u30a2\u30a4\u30a6\u30a8\u30aa";
- let url = "http://" + urlNoScheme;
- gURLBar.textValue = url;
- // Since this is directly setting textValue, it is expected to be trimmed.
- Assert.equal(gURLBar.inputField.value, urlNoScheme,
- "The string displayed in the textbox should not be escaped");
- gURLBar.value = "";
- gURLBar.handleRevert();
- gURLBar.blur();
-});
-
-add_task(function* actionURILosslessDecode() {
- let urlNoScheme = "example.com/\u30a2\u30a4\u30a6\u30a8\u30aa";
- let url = "http://" + urlNoScheme;
- yield promiseAutocompleteResultPopup(url);
-
- // At this point the heuristic result is selected but the urlbar's value is
- // simply `url`. Key down and back around until the heuristic result is
- // selected again, and at that point the urlbar's value should be a visiturl
- // moz-action.
-
- do {
- gURLBar.controller.handleKeyNavigation(KeyEvent.DOM_VK_DOWN);
- } while (gURLBar.popup.selectedIndex != 0);
-
- let [, type, ] = gURLBar.value.match(/^moz-action:([^,]+),(.*)$/);
- Assert.equal(type, "visiturl",
- "visiturl action URI should be in the urlbar");
-
- Assert.equal(gURLBar.inputField.value, urlNoScheme,
- "The string displayed in the textbox should not be escaped");
-
- gURLBar.value = "";
- gURLBar.handleRevert();
- gURLBar.blur();
-});
-
-function* checkInput(inputStr) {
- yield promiseAutocompleteResultPopup(inputStr);
-
- let item = gURLBar.popup.richlistbox.firstChild;
- Assert.ok(item, "Should have a result");
-
- // visiturl matches have their param.urls fixed up.
- let fixupInfo = Services.uriFixup.getFixupURIInfo(inputStr,
- Ci.nsIURIFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS |
- Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
- );
- let expectedVisitURL = fixupInfo.fixedURI.spec;
-
- let type = "visiturl";
- let params = {
- url: expectedVisitURL,
- input: inputStr,
- };
- for (let key in params) {
- params[key] = encodeURIComponent(params[key]);
- }
- let expectedURL = "moz-action:" + type + "," + JSON.stringify(params);
- Assert.equal(item.getAttribute("url"), expectedURL, "url");
-
- Assert.equal(item.getAttribute("title"), inputStr.replace("\\", "/"), "title");
- Assert.equal(item.getAttribute("text"), inputStr, "text");
-
- let itemType = item.getAttribute("type");
- Assert.equal(itemType, "visiturl");
-
- Assert.equal(item._titleText.textContent, inputStr.replace("\\", "/"), "Visible title");
- Assert.equal(item._actionText.textContent, "Visit", "Visible action");
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarDelete.js b/browser/base/content/test/urlbar/browser_urlbarDelete.js
deleted file mode 100644
index d4eb6c856..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarDelete.js
+++ /dev/null
@@ -1,39 +0,0 @@
-add_task(function*() {
- let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "http://bug1105244.example.com/",
- title: "test" });
-
- registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.remove(bm);
- });
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, testDelete);
-});
-
-function sendHome() {
- // unclear why VK_HOME doesn't work on Mac, but it doesn't...
- if (Services.appinfo.OS == "Darwin") {
- EventUtils.synthesizeKey("VK_LEFT", { altKey: true });
- } else {
- EventUtils.synthesizeKey("VK_HOME", {});
- }
-}
-
-function sendDelete() {
- EventUtils.synthesizeKey("VK_DELETE", {});
-}
-
-function* testDelete() {
- yield promiseAutocompleteResultPopup("bug1105244");
-
- // move to the start.
- sendHome();
- // delete the first few chars - each delete should operate on the input field.
- sendDelete();
- Assert.equal(gURLBar.inputField.value, "ug1105244");
-
- yield promisePopupShown(gURLBar.popup);
-
- sendDelete();
- Assert.equal(gURLBar.inputField.value, "g1105244");
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarEnter.js b/browser/base/content/test/urlbar/browser_urlbarEnter.js
deleted file mode 100644
index 32cbaf2be..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarEnter.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const TEST_VALUE = "example.com/\xF7?\xF7";
-const START_VALUE = "example.com/%C3%B7?%C3%B7";
-
-add_task(function* () {
- info("Simple return keypress");
- let tab = gBrowser.selectedTab = gBrowser.addTab(START_VALUE);
-
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-
- // Check url bar and selected tab.
- is(gURLBar.textValue, TEST_VALUE, "Urlbar should preserve the value on return keypress");
- is(gBrowser.selectedTab, tab, "New URL was loaded in the current tab");
-
- // Cleanup.
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_task(function* () {
- info("Alt+Return keypress");
- // due to bug 691608, we must wait for the load event, else isTabEmpty() will
- // return true on e10s for this tab, so it will be reused even with altKey.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, START_VALUE);
-
- let tabOpenPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {altKey: true});
-
- // wait for the new tab to appear.
- yield tabOpenPromise;
-
- // Check url bar and selected tab.
- is(gURLBar.textValue, TEST_VALUE, "Urlbar should preserve the value on return keypress");
- isnot(gBrowser.selectedTab, tab, "New URL was loaded in a new tab");
-
- // Cleanup.
- yield BrowserTestUtils.removeTab(tab);
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarEnterAfterMouseOver.js b/browser/base/content/test/urlbar/browser_urlbarEnterAfterMouseOver.js
deleted file mode 100644
index 22e336f91..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarEnterAfterMouseOver.js
+++ /dev/null
@@ -1,69 +0,0 @@
-function repeat(limit, func) {
- for (let i = 0; i < limit; i++) {
- func(i);
- }
-}
-
-function* promiseAutoComplete(inputText) {
- gURLBar.focus();
- gURLBar.value = inputText.slice(0, -1);
- EventUtils.synthesizeKey(inputText.slice(-1), {});
- yield promiseSearchComplete();
-}
-
-function is_selected(index) {
- is(gURLBar.popup.richlistbox.selectedIndex, index, `Item ${index + 1} should be selected`);
-}
-
-let gMaxResults;
-
-add_task(function*() {
- registerCleanupFunction(function* () {
- yield PlacesTestUtils.clearHistory();
- });
-
- yield PlacesTestUtils.clearHistory();
-
- gMaxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
-
- let visits = [];
- repeat(gMaxResults, i => {
- visits.push({
- uri: makeURI("http://example.com/autocomplete/?" + i),
- });
- });
- yield PlacesTestUtils.addVisits(visits);
-
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield promiseAutoComplete("http://example.com/autocomplete/");
-
- let popup = gURLBar.popup;
- let results = popup.richlistbox.children;
- is(results.length, gMaxResults,
- "Should get gMaxResults=" + gMaxResults + " results");
-
- let initiallySelected = gURLBar.popup.richlistbox.selectedIndex;
-
- info("Key Down to select the next item");
- EventUtils.synthesizeKey("VK_DOWN", {});
- is_selected(initiallySelected + 1);
- let expectedURL = gURLBar.controller.getFinalCompleteValueAt(initiallySelected + 1);
-
- is(gURLBar.value, gURLBar.controller.getValueAt(initiallySelected + 1),
- "Value in the URL bar should be updated by keyboard selection");
-
- // Verify that what we're about to do changes the selectedIndex:
- isnot(initiallySelected + 1, 3, "Shouldn't be changing the selectedIndex to the same index we keyboard-selected.");
-
- // Would love to use a synthetic mousemove event here, but that doesn't seem to do anything.
- // EventUtils.synthesizeMouseAtCenter(results[3], {type: "mousemove"});
- gURLBar.popup.richlistbox.selectedIndex = 3;
- is_selected(3);
-
- let autocompletePopupHidden = promisePopupHidden(gURLBar.popup);
- let openedExpectedPage = waitForDocLoadAndStopIt(expectedURL);
- EventUtils.synthesizeKey("VK_RETURN", {});
- yield Promise.all([autocompletePopupHidden, openedExpectedPage]);
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarFocusedCmdK.js b/browser/base/content/test/urlbar/browser_urlbarFocusedCmdK.js
deleted file mode 100644
index 8c9e2c9f2..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarFocusedCmdK.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-* http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function*() {
- // Remove the search bar from toolbar
- CustomizableUI.removeWidgetFromArea("search-container");
-
- // Test that Ctrl/Cmd + K will focus the url bar
- let focusPromise = BrowserTestUtils.waitForEvent(gURLBar, "focus");
- EventUtils.synthesizeKey("k", { accelKey: true });
- yield focusPromise;
- Assert.equal(document.activeElement, gURLBar.inputField, "URL Bar should be focused");
-
- // Reset changes made to toolbar
- CustomizableUI.reset();
-});
-
diff --git a/browser/base/content/test/urlbar/browser_urlbarHashChangeProxyState.js b/browser/base/content/test/urlbar/browser_urlbarHashChangeProxyState.js
deleted file mode 100644
index 152106dad..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarHashChangeProxyState.js
+++ /dev/null
@@ -1,111 +0,0 @@
-"use strict";
-
-/**
- * Check that navigating through both the URL bar and using in-page hash- or ref-
- * based links and back or forward navigation updates the URL bar and identity block correctly.
- */
-add_task(function* () {
- let baseURL = "https://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
- let url = baseURL + "#foo";
- yield BrowserTestUtils.withNewTab({ gBrowser, url }, function*(browser) {
- let identityBox = document.getElementById("identity-box");
- let expectedURL = url;
-
- let verifyURLBarState = testType => {
- is(gURLBar.textValue, expectedURL, "URL bar visible value should be correct " + testType);
- is(gURLBar.value, expectedURL, "URL bar value should be correct " + testType);
- ok(identityBox.classList.contains("verifiedDomain"), "Identity box should know we're doing SSL " + testType);
- is(gURLBar.getAttribute("pageproxystate"), "valid", "URL bar is in valid page proxy state");
- };
-
- verifyURLBarState("at the beginning");
-
- let locationChangePromise;
- let resolveLocationChangePromise;
- let expectURL = url => {
- expectedURL = url;
- locationChangePromise = new Promise(r => resolveLocationChangePromise = r);
- };
- let wpl = {
- onLocationChange(wpl, request, location, flags) {
- is(location.spec, expectedURL, "Got the expected URL");
- resolveLocationChangePromise();
- },
- };
- gBrowser.addProgressListener(wpl);
-
- expectURL(baseURL + "#foo");
- gURLBar.select();
- EventUtils.sendKey("return");
-
- yield locationChangePromise;
- verifyURLBarState("after hitting enter on the same URL a second time");
-
- expectURL(baseURL + "#bar");
- gURLBar.value = expectedURL;
- gURLBar.select();
- EventUtils.sendKey("return");
-
- yield locationChangePromise;
- verifyURLBarState("after a URL bar hash navigation");
-
- expectURL(baseURL + "#foo");
- yield ContentTask.spawn(browser, null, function() {
- let a = content.document.createElement("a");
- a.href = "#foo";
- a.textContent = "Foo Link";
- content.document.body.appendChild(a);
- a.click();
- });
-
- yield locationChangePromise;
- verifyURLBarState("after a page link hash navigation");
-
- expectURL(baseURL + "#bar");
- gBrowser.goBack();
-
- yield locationChangePromise;
- verifyURLBarState("after going back");
-
- expectURL(baseURL + "#foo");
- gBrowser.goForward();
-
- yield locationChangePromise;
- verifyURLBarState("after going forward");
-
- expectURL(baseURL + "#foo");
- gURLBar.select();
- EventUtils.sendKey("return");
-
- yield locationChangePromise;
- verifyURLBarState("after hitting enter on the same URL");
-
- gBrowser.removeProgressListener(wpl);
- });
-});
-
-/**
- * Check that initial secure loads that swap remoteness
- * get the correct page icon when finished.
- */
-add_task(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
- // NB: CPOW usage because new tab pages can be preloaded, in which case no
- // load events fire.
- yield BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
- let url = "https://example.org/browser/browser/base/content/test/urlbar/dummy_page.html#foo";
- gURLBar.value = url;
- gURLBar.select();
- EventUtils.sendKey("return");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- is(gURLBar.textValue, url, "URL bar visible value should be correct when the page loads from about:newtab");
- is(gURLBar.value, url, "URL bar value should be correct when the page loads from about:newtab");
- let identityBox = document.getElementById("identity-box");
- ok(identityBox.classList.contains("verifiedDomain"),
- "Identity box should know we're doing SSL when the page loads from about:newtab");
- is(gURLBar.getAttribute("pageproxystate"), "valid",
- "URL bar is in valid page proxy state when SSL page with hash loads from about:newtab");
- yield BrowserTestUtils.removeTab(tab);
-});
-
diff --git a/browser/base/content/test/urlbar/browser_urlbarKeepStateAcrossTabSwitches.js b/browser/base/content/test/urlbar/browser_urlbarKeepStateAcrossTabSwitches.js
deleted file mode 100644
index 9c8996059..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarKeepStateAcrossTabSwitches.js
+++ /dev/null
@@ -1,49 +0,0 @@
-"use strict";
-
-/**
- * Verify user typed text remains in the URL bar when tab switching, even when
- * loads fail.
- */
-add_task(function* () {
- let input = "i-definitely-dont-exist.example.com";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
- // NB: CPOW usage because new tab pages can be preloaded, in which case no
- // load events fire.
- yield BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
- let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
- gURLBar.value = input;
- gURLBar.select();
- EventUtils.sendKey("return");
- yield errorPageLoaded;
- is(gURLBar.textValue, input, "Text is still in URL bar");
- yield BrowserTestUtils.switchTab(gBrowser, tab.previousSibling);
- yield BrowserTestUtils.switchTab(gBrowser, tab);
- is(gURLBar.textValue, input, "Text is still in URL bar after tab switch");
- yield BrowserTestUtils.removeTab(tab);
-});
-
-/**
- * Invalid URIs fail differently (that is, immediately, in the loadURI call)
- * if keyword searches are turned off. Test that this works, too.
- */
-add_task(function* () {
- let input = "To be or not to be-that is the question";
- yield new Promise(resolve => SpecialPowers.pushPrefEnv({set: [["keyword.enabled", false]]}, resolve));
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
- // NB: CPOW usage because new tab pages can be preloaded, in which case no
- // load events fire.
- yield BrowserTestUtils.waitForCondition(() => !tab.linkedBrowser.contentDocument.hidden)
- let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
- gURLBar.value = input;
- gURLBar.select();
- EventUtils.sendKey("return");
- yield errorPageLoaded;
- is(gURLBar.textValue, input, "Text is still in URL bar");
- is(tab.linkedBrowser.userTypedValue, input, "Text still stored on browser");
- yield BrowserTestUtils.switchTab(gBrowser, tab.previousSibling);
- yield BrowserTestUtils.switchTab(gBrowser, tab);
- is(gURLBar.textValue, input, "Text is still in URL bar after tab switch");
- is(tab.linkedBrowser.userTypedValue, input, "Text still stored on browser");
- yield BrowserTestUtils.removeTab(tab);
-});
-
diff --git a/browser/base/content/test/urlbar/browser_urlbarOneOffs.js b/browser/base/content/test/urlbar/browser_urlbarOneOffs.js
deleted file mode 100644
index 1f58b8edd..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarOneOffs.js
+++ /dev/null
@@ -1,232 +0,0 @@
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-
-let gMaxResults;
-
-add_task(function* init() {
- Services.prefs.setBoolPref("browser.urlbar.oneOffSearches", true);
- gMaxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
-
- // Add a search suggestion engine and move it to the front so that it appears
- // as the first one-off.
- let engine = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
- Services.search.moveEngine(engine, 0);
-
- registerCleanupFunction(function* () {
- yield hidePopup();
- yield PlacesTestUtils.clearHistory();
- });
-
- yield PlacesTestUtils.clearHistory();
-
- let visits = [];
- for (let i = 0; i < gMaxResults; i++) {
- visits.push({
- uri: makeURI("http://example.com/browser_urlbarOneOffs.js/?" + i),
- // TYPED so that the visit shows up when the urlbar's drop-down arrow is
- // pressed.
- transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
- });
- }
- yield PlacesTestUtils.addVisits(visits);
-});
-
-// Keys up and down through the history panel, i.e., the panel that's shown when
-// there's no text in the textbox.
-add_task(function* history() {
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_DOWN", {})
- yield promisePopupShown(gURLBar.popup);
-
- assertState(-1, -1, "");
-
- // Key down through each result.
- for (let i = 0; i < gMaxResults; i++) {
- EventUtils.synthesizeKey("VK_DOWN", {})
- assertState(i, -1,
- "example.com/browser_urlbarOneOffs.js/?" + (gMaxResults - i - 1));
- }
-
- // Key down through each one-off.
- let numButtons =
- gURLBar.popup.oneOffSearchButtons.getSelectableButtons(true).length;
- for (let i = 0; i < numButtons; i++) {
- EventUtils.synthesizeKey("VK_DOWN", {})
- assertState(-1, i, "");
- }
-
- // Key down once more. Nothing should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {})
- assertState(-1, -1, "");
-
- // Once more. The first result should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {})
- assertState(0, -1,
- "example.com/browser_urlbarOneOffs.js/?" + (gMaxResults - 1));
-
- // Now key up. Nothing should be selected again.
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(-1, -1, "");
-
- // Key up through each one-off.
- for (let i = numButtons - 1; i >= 0; i--) {
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(-1, i, "");
- }
-
- // Key up through each result.
- for (let i = gMaxResults - 1; i >= 0; i--) {
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(i, -1,
- "example.com/browser_urlbarOneOffs.js/?" + (gMaxResults - i - 1));
- }
-
- // Key up once more. Nothing should be selected.
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(-1, -1, "");
-
- yield hidePopup();
-});
-
-// Keys up and down through the non-history panel, i.e., the panel that's shown
-// when you type something in the textbox.
-add_task(function* typedValue() {
- // Use a typed value that returns the visits added above but that doesn't
- // trigger autofill since that would complicate the test.
- let typedValue = "browser_urlbarOneOffs";
- yield promiseAutocompleteResultPopup(typedValue, window, true);
-
- assertState(0, -1, typedValue);
-
- // Key down through each result. The first result is already selected, which
- // is why gMaxResults - 1 is the correct number of times to do this.
- for (let i = 0; i < gMaxResults - 1; i++) {
- EventUtils.synthesizeKey("VK_DOWN", {})
- // i starts at zero so that the textValue passed to assertState is correct.
- // But that means that i + 1 is the expected selected index, since initially
- // (when this loop starts) the first result is selected.
- assertState(i + 1, -1,
- "example.com/browser_urlbarOneOffs.js/?" + (gMaxResults - i - 1));
- }
-
- // Key down through each one-off.
- let numButtons =
- gURLBar.popup.oneOffSearchButtons.getSelectableButtons(true).length;
- for (let i = 0; i < numButtons; i++) {
- EventUtils.synthesizeKey("VK_DOWN", {})
- assertState(-1, i, typedValue);
- }
-
- // Key down once more. The selection should wrap around to the first result.
- EventUtils.synthesizeKey("VK_DOWN", {})
- assertState(0, -1, typedValue);
-
- // Now key up. The selection should wrap back around to the one-offs. Key
- // up through all the one-offs.
- for (let i = numButtons - 1; i >= 0; i--) {
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(-1, i, typedValue);
- }
-
- // Key up through each non-heuristic result.
- for (let i = gMaxResults - 2; i >= 0; i--) {
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(i + 1, -1,
- "example.com/browser_urlbarOneOffs.js/?" + (gMaxResults - i - 1));
- }
-
- // Key up once more. The heuristic result should be selected.
- EventUtils.synthesizeKey("VK_UP", {})
- assertState(0, -1, typedValue);
-
- yield hidePopup();
-});
-
-// Checks that "Search with Current Search Engine" items are updated to "Search
-// with One-Off Engine" when a one-off is selected.
-add_task(function* searchWith() {
- let typedValue = "foo";
- yield promiseAutocompleteResultPopup(typedValue);
-
- assertState(0, -1, typedValue);
-
- let item = gURLBar.popup.richlistbox.firstChild;
- Assert.equal(item._actionText.textContent,
- "Search with " + Services.search.currentEngine.name,
- "Sanity check: first result's action text");
-
- // Alt+Down to the first one-off. Now the first result and the first one-off
- // should both be selected.
- EventUtils.synthesizeKey("VK_DOWN", { altKey: true })
- assertState(0, 0, typedValue);
-
- let engineName = gURLBar.popup.oneOffSearchButtons.selectedButton.engine.name;
- Assert.notEqual(engineName, Services.search.currentEngine.name,
- "Sanity check: First one-off engine should not be " +
- "the current engine");
- Assert.equal(item._actionText.textContent,
- "Search with " + engineName,
- "First result's action text should be updated");
-
- yield hidePopup();
-});
-
-// Clicks a one-off.
-add_task(function* oneOffClick() {
- gBrowser.selectedTab = gBrowser.addTab();
-
- // We are explicitly using something that looks like a url, to make the test
- // stricter. Even if it looks like a url, we should search.
- let typedValue = "foo.bar";
- yield promiseAutocompleteResultPopup(typedValue);
-
- assertState(0, -1, typedValue);
-
- let oneOffs = gURLBar.popup.oneOffSearchButtons.getSelectableButtons(true);
- let resultsPromise =
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false,
- "http://mochi.test:8888/");
- EventUtils.synthesizeMouseAtCenter(oneOffs[0], {});
- yield resultsPromise;
-
- gBrowser.removeTab(gBrowser.selectedTab);
-});
-
-// Presses the Return key when a one-off is selected.
-add_task(function* oneOffReturn() {
- gBrowser.selectedTab = gBrowser.addTab();
-
- // We are explicitly using something that looks like a url, to make the test
- // stricter. Even if it looks like a url, we should search.
- let typedValue = "foo.bar";
- yield promiseAutocompleteResultPopup(typedValue, window, true);
-
- assertState(0, -1, typedValue);
-
- // Alt+Down to select the first one-off.
- EventUtils.synthesizeKey("VK_DOWN", { altKey: true })
- assertState(0, 0, typedValue);
-
- let resultsPromise =
- BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false,
- "http://mochi.test:8888/");
- EventUtils.synthesizeKey("VK_RETURN", {})
- yield resultsPromise;
-
- gBrowser.removeTab(gBrowser.selectedTab);
-});
-
-
-function assertState(result, oneOff, textValue = undefined) {
- Assert.equal(gURLBar.popup.selectedIndex, result,
- "Expected result should be selected");
- Assert.equal(gURLBar.popup.oneOffSearchButtons.selectedButtonIndex, oneOff,
- "Expected one-off should be selected");
- if (textValue !== undefined) {
- Assert.equal(gURLBar.textValue, textValue, "Expected textValue");
- }
-}
-
-function* hidePopup() {
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promisePopupHidden(gURLBar.popup);
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarPrivateBrowsingWindowChange.js b/browser/base/content/test/urlbar/browser_urlbarPrivateBrowsingWindowChange.js
deleted file mode 100644
index 5db0f0ea6..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarPrivateBrowsingWindowChange.js
+++ /dev/null
@@ -1,41 +0,0 @@
-"use strict";
-
-/**
- * Test that when opening a private browsing window and typing in it before about:privatebrowsing
- * loads, we don't clear the URL bar.
- */
-add_task(function*() {
- let urlbarTestValue = "Mary had a little lamb";
- let win = OpenBrowserWindow({private: true});
- yield BrowserTestUtils.waitForEvent(win, "load");
- let urlbar = win.document.getElementById("urlbar");
- urlbar.value = urlbarTestValue;
- // Need this so the autocomplete controller attaches:
- let focusEv = new FocusEvent("focus", {});
- urlbar.dispatchEvent(focusEv);
- // And so we know input happened:
- let inputEv = new InputEvent("input", {data: "", view: win, bubbles: true});
- urlbar.onInput(inputEv);
- // Check it worked:
- is(urlbar.value, urlbarTestValue, "URL bar value should be there");
- is(win.gBrowser.selectedBrowser.userTypedValue, urlbarTestValue, "browser object should know the url bar value");
-
- let continueTest;
- let continuePromise = new Promise(resolve => continueTest = resolve);
- let wpl = {
- onLocationChange(aWebProgress, aRequest, aLocation) {
- if (aLocation && aLocation.spec == "about:privatebrowsing") {
- continueTest();
- }
- },
- };
- win.gBrowser.addProgressListener(wpl);
-
- yield continuePromise;
- is(urlbar.value, urlbarTestValue,
- "URL bar value should be the same once about:privatebrowsing has loaded");
- is(win.gBrowser.selectedBrowser.userTypedValue, urlbarTestValue,
- "browser object should still know url bar value once about:privatebrowsing has loaded");
- win.gBrowser.removeProgressListener(wpl);
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarRaceWithTabs.js b/browser/base/content/test/urlbar/browser_urlbarRaceWithTabs.js
deleted file mode 100644
index d66514c5a..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarRaceWithTabs.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const kURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
-
-function* addBookmark(bookmark) {
- if (bookmark.keyword) {
- yield PlacesUtils.keywords.insert({
- keyword: bookmark.keyword,
- url: bookmark.url,
- });
- }
-
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: bookmark.url,
- title: bookmark.title,
- });
-
- registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.remove(bm);
- if (bookmark.keyword) {
- yield PlacesUtils.keywords.remove(bookmark.keyword);
- }
- });
-}
-
-/**
- * Check that if the user hits enter and ctrl-t at the same time, we open the URL in the right tab.
- */
-add_task(function* hitEnterLoadInRightTab() {
- info("Opening new tab");
- let oldTabCreatedPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
- BrowserOpenTab();
- let oldTab = (yield oldTabCreatedPromise).target;
- let oldTabLoadedPromise = BrowserTestUtils.browserLoaded(oldTab.linkedBrowser, false, kURL);
- oldTabLoadedPromise.then(() => info("Old tab loaded"));
- let newTabCreatedPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
-
- info("Creating bookmark and keyword");
- yield addBookmark({title: "Test for keyword bookmark and URL", url: kURL, keyword: "urlbarkeyword"});
- info("Filling URL bar, sending <return> and opening a tab");
- gURLBar.value = "urlbarkeyword";
- gURLBar.select();
- EventUtils.sendKey("return");
- BrowserOpenTab();
- info("Waiting for new tab");
- let newTab = (yield newTabCreatedPromise).target;
- info("Created new tab; waiting for either tab to load");
- let newTabLoadedPromise = BrowserTestUtils.browserLoaded(newTab.linkedBrowser, false, kURL);
- newTabLoadedPromise.then(() => info("New tab loaded"));
- yield Promise.race([newTabLoadedPromise, oldTabLoadedPromise]);
- is(newTab.linkedBrowser.currentURI.spec, "about:newtab", "New tab still has about:newtab");
- is(oldTab.linkedBrowser.currentURI.spec, kURL, "Old tab loaded URL");
- info("Closing new tab");
- yield BrowserTestUtils.removeTab(newTab);
- info("Closing old tab");
- yield BrowserTestUtils.removeTab(oldTab);
- info("Finished");
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarRevert.js b/browser/base/content/test/urlbar/browser_urlbarRevert.js
deleted file mode 100644
index 0ce3c8fac..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarRevert.js
+++ /dev/null
@@ -1,37 +0,0 @@
-var tab = null;
-
-function test() {
- waitForExplicitFinish();
-
- let pageLoaded = {
- onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
- if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
- gBrowser.removeProgressListener(this);
- executeSoon(checkURLBarRevert);
- }
- }
- }
-
- gBrowser.addProgressListener(pageLoaded);
- tab = gBrowser.addTab("http://example.com");
- gBrowser.selectedTab = tab;
-}
-
-function checkURLBarRevert() {
- let originalValue = gURLBar.value;
-
- gBrowser.userTypedValue = "foobar";
- gBrowser.selectedTab = gBrowser.tabs[0];
- gBrowser.selectedTab = tab;
- is(gURLBar.value, "foobar", "location bar displays typed value");
-
- gURLBar.focus();
-
- EventUtils.synthesizeKey("VK_ESCAPE", {});
-
- is(gURLBar.value, originalValue, "ESC reverted the location bar value");
-
- gBrowser.removeTab(tab);
- finish();
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarSearchSingleWordNotification.js b/browser/base/content/test/urlbar/browser_urlbarSearchSingleWordNotification.js
deleted file mode 100644
index ee0342055..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSingleWordNotification.js
+++ /dev/null
@@ -1,198 +0,0 @@
-"use strict";
-
-var notificationObserver;
-registerCleanupFunction(function() {
- Services.prefs.clearUserPref("browser.fixup.domainwhitelist.localhost");
- if (notificationObserver) {
- notificationObserver.disconnect();
- }
-});
-
-function promiseNotification(aBrowser, value, expected, input) {
- let deferred = Promise.defer();
- let notificationBox = aBrowser.getNotificationBox(aBrowser.selectedBrowser);
- if (expected) {
- info("Waiting for " + value + " notification");
- let checkForNotification = function() {
- if (notificationBox.getNotificationWithValue(value)) {
- info("Saw the notification");
- notificationObserver.disconnect();
- notificationObserver = null;
- deferred.resolve();
- }
- }
- if (notificationObserver) {
- notificationObserver.disconnect();
- }
- notificationObserver = new MutationObserver(checkForNotification);
- notificationObserver.observe(notificationBox, {childList: true});
- } else {
- setTimeout(() => {
- is(notificationBox.getNotificationWithValue(value), null,
- `We are expecting to not get a notification for ${input}`);
- deferred.resolve();
- }, 1000);
- }
- return deferred.promise;
-}
-
-function* runURLBarSearchTest({valueToOpen, expectSearch, expectNotification, aWindow=window}) {
- aWindow.gURLBar.value = valueToOpen;
- let expectedURI;
- if (!expectSearch) {
- expectedURI = "http://" + valueToOpen + "/";
- } else {
- yield new Promise(resolve => {
- Services.search.init(resolve);
- });
- expectedURI = Services.search.defaultEngine.getSubmission(valueToOpen, null, "keyword").uri.spec;
- }
- aWindow.gURLBar.focus();
- let docLoadPromise = waitForDocLoadAndStopIt(expectedURI, aWindow.gBrowser.selectedBrowser);
- EventUtils.synthesizeKey("VK_RETURN", {}, aWindow);
-
- yield Promise.all([
- docLoadPromise,
- promiseNotification(aWindow.gBrowser, "keyword-uri-fixup", expectNotification, valueToOpen)
- ]);
-}
-
-add_task(function* test_navigate_full_domain() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "www.mozilla.org",
- expectSearch: false,
- expectNotification: false,
- });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_navigate_decimal_ip() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "1234",
- expectSearch: true,
- expectNotification: false,
- });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_navigate_decimal_ip_with_path() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "1234/12",
- expectSearch: true,
- expectNotification: false,
- });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_navigate_large_number() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "123456789012345",
- expectSearch: true,
- expectNotification: false
- });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_navigate_small_hex_number() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "0x1f00ffff",
- expectSearch: true,
- expectNotification: false
- });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_navigate_large_hex_number() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "0x7f0000017f000001",
- expectSearch: true,
- expectNotification: false
- });
- gBrowser.removeTab(tab);
-});
-
-function get_test_function_for_localhost_with_hostname(hostName, isPrivate) {
- return function* test_navigate_single_host() {
- const pref = "browser.fixup.domainwhitelist.localhost";
- let win;
- if (isPrivate) {
- let promiseWin = BrowserTestUtils.waitForNewWindow();
- win = OpenBrowserWindow({private: true});
- yield promiseWin;
- let deferredOpenFocus = Promise.defer();
- waitForFocus(deferredOpenFocus.resolve, win);
- yield deferredOpenFocus.promise;
- } else {
- win = window;
- }
- let browser = win.gBrowser;
- let tab = yield BrowserTestUtils.openNewForegroundTab(browser);
-
- Services.prefs.setBoolPref(pref, false);
- yield* runURLBarSearchTest({
- valueToOpen: hostName,
- expectSearch: true,
- expectNotification: true,
- aWindow: win,
- });
-
- let notificationBox = browser.getNotificationBox(tab.linkedBrowser);
- let notification = notificationBox.getNotificationWithValue("keyword-uri-fixup");
- let docLoadPromise = waitForDocLoadAndStopIt("http://" + hostName + "/", tab.linkedBrowser);
- notification.querySelector(".notification-button-default").click();
-
- // check pref value
- let prefValue = Services.prefs.getBoolPref(pref);
- is(prefValue, !isPrivate, "Pref should have the correct state.");
-
- yield docLoadPromise;
- browser.removeTab(tab);
-
- // Now try again with the pref set.
- tab = browser.selectedTab = browser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- // In a private window, the notification should appear again.
- yield* runURLBarSearchTest({
- valueToOpen: hostName,
- expectSearch: isPrivate,
- expectNotification: isPrivate,
- aWindow: win,
- });
- browser.removeTab(tab);
- if (isPrivate) {
- info("Waiting for private window to close");
- yield BrowserTestUtils.closeWindow(win);
- let deferredFocus = Promise.defer();
- info("Waiting for focus");
- waitForFocus(deferredFocus.resolve, window);
- yield deferredFocus.promise;
- }
- }
-}
-
-add_task(get_test_function_for_localhost_with_hostname("localhost"));
-add_task(get_test_function_for_localhost_with_hostname("localhost."));
-add_task(get_test_function_for_localhost_with_hostname("localhost", true));
-
-add_task(function* test_navigate_invalid_url() {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield* runURLBarSearchTest({
- valueToOpen: "mozilla is awesome",
- expectSearch: true,
- expectNotification: false,
- });
- gBrowser.removeTab(tab);
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js
deleted file mode 100644
index 5146ba98c..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-
-// Must run first.
-add_task(function* prepare() {
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
- let engine = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
- let oldCurrentEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- registerCleanupFunction(function* () {
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
- Services.search.currentEngine = oldCurrentEngine;
-
- // Clicking suggestions causes visits to search results pages, so clear that
- // history now.
- yield PlacesTestUtils.clearHistory();
-
- // Make sure the popup is closed for the next test.
- gURLBar.blur();
- Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
- });
-});
-
-add_task(function* clickSuggestion() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("foo");
- let [idx, suggestion, engineName] = yield promiseFirstSuggestion();
- Assert.equal(engineName,
- "browser_searchSuggestionEngine%20searchSuggestionEngine.xml",
- "Expected suggestion engine");
- let item = gURLBar.popup.richlistbox.getItemAtIndex(idx);
-
- let uri = Services.search.currentEngine.getSubmission(suggestion).uri;
- let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser,
- false, uri.spec);
- item.click();
- yield loadPromise;
- yield BrowserTestUtils.removeTab(tab);
-});
-
-function getFirstSuggestion() {
- let controller = gURLBar.popup.input.controller;
- let matchCount = controller.matchCount;
- for (let i = 0; i < matchCount; i++) {
- let url = controller.getValueAt(i);
- let mozActionMatch = url.match(/^moz-action:([^,]+),(.*)$/);
- if (mozActionMatch) {
- let [, type, paramStr] = mozActionMatch;
- let params = JSON.parse(paramStr);
- if (type == "searchengine" && "searchSuggestion" in params) {
- return [i, params.searchSuggestion, params.engineName];
- }
- }
- }
- return [-1, null, null];
-}
-
-function* promiseFirstSuggestion() {
- let tuple = [-1, null, null];
- yield BrowserTestUtils.waitForCondition(() => {
- tuple = getFirstSuggestion();
- return tuple[0] >= 0;
- });
- return tuple;
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js
deleted file mode 100644
index 94ae8a3ff..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js
+++ /dev/null
@@ -1,254 +0,0 @@
-const SUGGEST_ALL_PREF = "browser.search.suggest.enabled";
-const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
-const CHOICE_PREF = "browser.urlbar.userMadeSearchSuggestionsChoice";
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-
-// Must run first.
-add_task(function* prepare() {
- let engine = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
- let oldCurrentEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- registerCleanupFunction(function* () {
- Services.search.currentEngine = oldCurrentEngine;
- Services.prefs.clearUserPref(SUGGEST_ALL_PREF);
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
-
- // Disable the notification for future tests so it doesn't interfere with
- // them. clearUserPref() won't work because by default the pref is false.
- yield setUserMadeChoicePref(true);
-
- // Make sure the popup is closed for the next test.
- gURLBar.blur();
- Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
- });
-});
-
-add_task(function* focus() {
- // Focusing the urlbar used to open the popup in order to show the
- // notification, but it doesn't anymore. Make sure it does not.
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- yield setUserMadeChoicePref(false);
- gURLBar.blur();
- gURLBar.focus();
- Assert.ok(!gURLBar.popup.popupOpen, "popup should remain closed");
-});
-
-add_task(function* dismissWithoutResults() {
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- yield setUserMadeChoicePref(false);
- gURLBar.blur();
- gURLBar.focus();
- let popupPromise = promisePopupShown(gURLBar.popup);
- gURLBar.openPopup();
- yield popupPromise;
- Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
- assertVisible(true);
- Assert.equal(gURLBar.popup._matchCount, 0, "popup should have no results");
- let disableButton = document.getAnonymousElementByAttribute(
- gURLBar.popup, "anonid", "search-suggestions-notification-disable"
- );
- let transitionPromise = promiseTransition();
- disableButton.click();
- yield transitionPromise;
- Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
- gURLBar.blur();
- gURLBar.focus();
- Assert.ok(!gURLBar.popup.popupOpen, "popup should remain closed");
- yield promiseAutocompleteResultPopup("foo");
- Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
- assertVisible(false);
-});
-
-add_task(function* dismissWithResults() {
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- yield setUserMadeChoicePref(false);
- gURLBar.blur();
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("foo");
- Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
- assertVisible(true);
- Assert.ok(gURLBar.popup._matchCount > 0, "popup should have results");
- let disableButton = document.getAnonymousElementByAttribute(
- gURLBar.popup, "anonid", "search-suggestions-notification-disable"
- );
- let transitionPromise = promiseTransition();
- disableButton.click();
- yield transitionPromise;
- Assert.ok(gURLBar.popup.popupOpen, "popup should remain open");
- gURLBar.blur();
- gURLBar.focus();
- Assert.ok(!gURLBar.popup.popupOpen, "popup should remain closed");
- yield promiseAutocompleteResultPopup("foo");
- Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
- assertVisible(false);
-});
-
-add_task(function* disable() {
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- yield setUserMadeChoicePref(false);
- gURLBar.blur();
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("foo");
- Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
- assertVisible(true);
- let disableButton = document.getAnonymousElementByAttribute(
- gURLBar.popup, "anonid", "search-suggestions-notification-disable"
- );
- let transitionPromise = promiseTransition();
- disableButton.click();
- yield transitionPromise;
- gURLBar.blur();
- yield promiseAutocompleteResultPopup("foo");
- Assert.ok(!suggestionsPresent());
-});
-
-add_task(function* enable() {
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, false);
- yield setUserMadeChoicePref(false);
- gURLBar.blur();
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("foo");
- assertVisible(true);
- Assert.ok(!suggestionsPresent());
- let enableButton = document.getAnonymousElementByAttribute(
- gURLBar.popup, "anonid", "search-suggestions-notification-enable"
- );
- let searchPromise = BrowserTestUtils.waitForCondition(suggestionsPresent,
- "waiting for suggestions");
- enableButton.click();
- yield searchPromise;
- // Clicking Yes should trigger a new search so that suggestions appear
- // immediately.
- Assert.ok(suggestionsPresent());
- gURLBar.blur();
- gURLBar.focus();
- // Suggestions should still be present in a new search of course.
- yield promiseAutocompleteResultPopup("bar");
- Assert.ok(suggestionsPresent());
-});
-
-add_task(function* privateWindow() {
- // Since suggestions are disabled in private windows, the notification should
- // not appear even when suggestions are otherwise enabled.
- let win = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- win.gURLBar.blur();
- win.gURLBar.focus();
- yield promiseAutocompleteResultPopup("foo", win);
- assertVisible(false, win);
- win.gURLBar.blur();
- yield BrowserTestUtils.closeWindow(win);
-});
-
-add_task(function* multipleWindows() {
- // Opening multiple windows, using their urlbars, and then dismissing the
- // notification in one should dismiss the notification in all.
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, false);
- yield setUserMadeChoicePref(false);
-
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("win1");
- assertVisible(true);
-
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
- win2.gURLBar.focus();
- yield promiseAutocompleteResultPopup("win2", win2);
- assertVisible(true, win2);
-
- let win3 = yield BrowserTestUtils.openNewBrowserWindow();
- win3.gURLBar.focus();
- yield promiseAutocompleteResultPopup("win3", win3);
- assertVisible(true, win3);
-
- let enableButton = win3.document.getAnonymousElementByAttribute(
- win3.gURLBar.popup, "anonid", "search-suggestions-notification-enable"
- );
- let transitionPromise = promiseTransition(win3);
- enableButton.click();
- yield transitionPromise;
- assertVisible(false, win3);
-
- win2.gURLBar.focus();
- yield promiseAutocompleteResultPopup("win2done", win2);
- assertVisible(false, win2);
-
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("win1done");
- assertVisible(false);
-
- yield BrowserTestUtils.closeWindow(win2);
- yield BrowserTestUtils.closeWindow(win3);
-});
-
-add_task(function* enableOutsideNotification() {
- // Setting the suggest.searches pref outside the notification (e.g., by
- // ticking the checkbox in the preferences window) should hide it.
- Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true);
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, false);
- yield setUserMadeChoicePref(false);
-
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("foo");
- assertVisible(false);
-});
-
-/**
- * Setting the choice pref triggers a pref observer in the urlbar, which hides
- * the notification if it's present. This function returns a promise that's
- * resolved once the observer fires.
- *
- * @param userMadeChoice A boolean, the pref's new value.
- * @return A Promise that's resolved when the observer fires -- or, if the pref
- * is currently the given value, that's resolved immediately.
- */
-function setUserMadeChoicePref(userMadeChoice) {
- return new Promise(resolve => {
- let currentUserMadeChoice = Services.prefs.getBoolPref(CHOICE_PREF);
- if (currentUserMadeChoice != userMadeChoice) {
- Services.prefs.addObserver(CHOICE_PREF, function obs(subj, topic, data) {
- Services.prefs.removeObserver(CHOICE_PREF, obs);
- resolve();
- }, false);
- }
- Services.prefs.setBoolPref(CHOICE_PREF, userMadeChoice);
- if (currentUserMadeChoice == userMadeChoice) {
- resolve();
- }
- });
-}
-
-function suggestionsPresent() {
- let controller = gURLBar.popup.input.controller;
- let matchCount = controller.matchCount;
- for (let i = 0; i < matchCount; i++) {
- let url = controller.getValueAt(i);
- let mozActionMatch = url.match(/^moz-action:([^,]+),(.*)$/);
- if (mozActionMatch) {
- let [, type, paramStr] = mozActionMatch;
- let params = JSON.parse(paramStr);
- if (type == "searchengine" && "searchSuggestion" in params) {
- return true;
- }
- }
- }
- return false;
-}
-
-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);
- // 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);
- });
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarSearchTelemetry.js b/browser/base/content/test/urlbar/browser_urlbarSearchTelemetry.js
deleted file mode 100644
index 8c28401ea..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarSearchTelemetry.js
+++ /dev/null
@@ -1,216 +0,0 @@
-"use strict";
-
-Cu.import("resource:///modules/BrowserUITelemetry.jsm");
-
-const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-
-// Must run first.
-add_task(function* prepare() {
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
- let engine = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
- let oldCurrentEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- registerCleanupFunction(function* () {
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
- Services.search.currentEngine = oldCurrentEngine;
-
- // Clicking urlbar results causes visits to their associated pages, so clear
- // that history now.
- yield PlacesTestUtils.clearHistory();
-
- // Make sure the popup is closed for the next test.
- gURLBar.blur();
- Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
- });
-
- // Move the mouse away from the urlbar one-offs so that a one-off engine is
- // not inadvertently selected.
- yield new Promise(resolve => {
- EventUtils.synthesizeNativeMouseMove(window.document.documentElement, 0, 0,
- resolve);
- });
-});
-
-add_task(function* heuristicResultMouse() {
- yield compareCounts(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("heuristicResult");
- let action = getActionAtIndex(0);
- Assert.ok(!!action, "there should be an action at index 0");
- Assert.equal(action.type, "searchengine", "type should be searchengine");
- let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- gURLBar.popup.richlistbox.getItemAtIndex(0).click();
- yield loadPromise;
- yield BrowserTestUtils.removeTab(tab);
- });
-});
-
-add_task(function* heuristicResultKeyboard() {
- yield compareCounts(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("heuristicResult");
- let action = getActionAtIndex(0);
- Assert.ok(!!action, "there should be an action at index 0");
- Assert.equal(action.type, "searchengine", "type should be searchengine");
- let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- EventUtils.sendKey("return");
- yield loadPromise;
- yield BrowserTestUtils.removeTab(tab);
- });
-});
-
-add_task(function* searchSuggestionMouse() {
- yield compareCounts(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("searchSuggestion");
- let idx = getFirstSuggestionIndex();
- Assert.ok(idx >= 0, "there should be a first suggestion");
- let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- gURLBar.popup.richlistbox.getItemAtIndex(idx).click();
- yield loadPromise;
- yield BrowserTestUtils.removeTab(tab);
- });
-});
-
-add_task(function* searchSuggestionKeyboard() {
- yield compareCounts(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- gURLBar.focus();
- yield promiseAutocompleteResultPopup("searchSuggestion");
- let idx = getFirstSuggestionIndex();
- Assert.ok(idx >= 0, "there should be a first suggestion");
- let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- while (idx--) {
- EventUtils.sendKey("down");
- }
- EventUtils.sendKey("return");
- yield loadPromise;
- yield BrowserTestUtils.removeTab(tab);
- });
-});
-
-/**
- * This does three things: gets current telemetry/FHR counts, calls
- * clickCallback, gets telemetry/FHR counts again to compare them to the old
- * counts.
- *
- * @param clickCallback Use this to open the urlbar popup and choose and click a
- * result.
- */
-function* compareCounts(clickCallback) {
- // Search events triggered by clicks (not the Return key in the urlbar) are
- // recorded in three places:
- // * BrowserUITelemetry
- // * Telemetry histogram named "SEARCH_COUNTS"
- // * FHR
-
- let engine = Services.search.currentEngine;
- let engineID = "org.mozilla.testsearchsuggestions";
-
- // First, get the current counts.
-
- // BrowserUITelemetry
- let uiTelemCount = 0;
- let bucket = BrowserUITelemetry.currentBucket;
- let events = BrowserUITelemetry.getToolbarMeasures().countableEvents;
- if (events[bucket] &&
- events[bucket].search &&
- events[bucket].search.urlbar) {
- uiTelemCount = events[bucket].search.urlbar;
- }
-
- // telemetry histogram SEARCH_COUNTS
- let histogramCount = 0;
- let histogramKey = engineID + ".urlbar";
- let histogram;
- try {
- histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
- } catch (ex) {
- // No searches performed yet, not a problem.
- }
- if (histogram) {
- let snapshot = histogram.snapshot();
- if (histogramKey in snapshot) {
- histogramCount = snapshot[histogramKey].sum;
- }
- }
-
- // FHR -- first make sure the engine has an identifier so that FHR is happy.
- Object.defineProperty(engine.wrappedJSObject, "identifier",
- { value: engineID });
-
- gURLBar.focus();
- yield clickCallback();
-
- // Now get the new counts and compare them to the old.
-
- // BrowserUITelemetry
- events = BrowserUITelemetry.getToolbarMeasures().countableEvents;
- Assert.ok(bucket in events, "bucket should be recorded");
- events = events[bucket];
- Assert.ok("search" in events, "search should be recorded");
- events = events.search;
- Assert.ok("urlbar" in events, "urlbar should be recorded");
- Assert.equal(events.urlbar, uiTelemCount + 1,
- "clicked suggestion should be recorded");
-
- // telemetry histogram SEARCH_COUNTS
- histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
- let snapshot = histogram.snapshot();
- Assert.ok(histogramKey in snapshot, "histogram with key should be recorded");
- Assert.equal(snapshot[histogramKey].sum, histogramCount + 1,
- "histogram sum should be incremented");
-}
-
-/**
- * Returns the "action" object at the given index in the urlbar results:
- * { type, params: {}}
- *
- * @param index The index in the urlbar results.
- * @return An action object, or null if index >= number of results.
- */
-function getActionAtIndex(index) {
- let controller = gURLBar.popup.input.controller;
- if (controller.matchCount <= index) {
- return null;
- }
- let url = controller.getValueAt(index);
- let mozActionMatch = url.match(/^moz-action:([^,]+),(.*)$/);
- if (!mozActionMatch) {
- let msg = "result at index " + index + " is not a moz-action: " + url;
- Assert.ok(false, msg);
- throw new Error(msg);
- }
- let [, type, paramStr] = mozActionMatch;
- return {
- type: type,
- params: JSON.parse(paramStr),
- };
-}
-
-/**
- * Returns the index of the first search suggestion in the urlbar results.
- *
- * @return An index, or -1 if there are no search suggestions.
- */
-function getFirstSuggestionIndex() {
- let controller = gURLBar.popup.input.controller;
- let matchCount = controller.matchCount;
- for (let i = 0; i < matchCount; i++) {
- let url = controller.getValueAt(i);
- let mozActionMatch = url.match(/^moz-action:([^,]+),(.*)$/);
- if (mozActionMatch) {
- let [, type, paramStr] = mozActionMatch;
- let params = JSON.parse(paramStr);
- if (type == "searchengine" && "searchSuggestion" in params) {
- return i;
- }
- }
- }
- return -1;
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarStop.js b/browser/base/content/test/urlbar/browser_urlbarStop.js
deleted file mode 100644
index 8cf9d8017..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarStop.js
+++ /dev/null
@@ -1,30 +0,0 @@
-"use strict";
-
-const goodURL = "http://mochi.test:8888/";
-const badURL = "http://mochi.test:8888/whatever.html";
-
-add_task(function* () {
- gBrowser.selectedTab = gBrowser.addTab(goodURL);
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- is(gURLBar.textValue, gURLBar.trimValue(goodURL), "location bar reflects loaded page");
-
- yield typeAndSubmitAndStop(badURL);
- is(gURLBar.textValue, gURLBar.trimValue(goodURL), "location bar reflects loaded page after stop()");
- gBrowser.removeCurrentTab();
-
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- is(gURLBar.textValue, "", "location bar is empty");
-
- yield typeAndSubmitAndStop(badURL);
- is(gURLBar.textValue, gURLBar.trimValue(badURL), "location bar reflects stopped page in an empty tab");
- gBrowser.removeCurrentTab();
-});
-
-function* typeAndSubmitAndStop(url) {
- yield promiseAutocompleteResultPopup(url, window, true);
- is(gURLBar.textValue, gURLBar.trimValue(url), "location bar reflects loading page");
-
- let promise = waitForDocLoadAndStopIt(url, gBrowser.selectedBrowser, false);
- gURLBar.handleCommand();
- yield promise;
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarTrimURLs.js b/browser/base/content/test/urlbar/browser_urlbarTrimURLs.js
deleted file mode 100644
index 913e99a8e..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarTrimURLs.js
+++ /dev/null
@@ -1,98 +0,0 @@
-add_task(function* () {
- const PREF_TRIMURLS = "browser.urlbar.trimURLs";
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
-
- registerCleanupFunction(function* () {
- yield BrowserTestUtils.removeTab(tab);
- Services.prefs.clearUserPref(PREF_TRIMURLS);
- URLBarSetURI();
- });
-
- Services.prefs.setBoolPref(PREF_TRIMURLS, true);
-
- testVal("http://mozilla.org/", "mozilla.org");
- testVal("https://mozilla.org/", "https://mozilla.org");
- testVal("http://mözilla.org/", "mözilla.org");
- testVal("http://mozilla.imaginatory/", "mozilla.imaginatory");
- testVal("http://www.mozilla.org/", "www.mozilla.org");
- testVal("http://sub.mozilla.org/", "sub.mozilla.org");
- testVal("http://sub1.sub2.sub3.mozilla.org/", "sub1.sub2.sub3.mozilla.org");
- testVal("http://mozilla.org/file.ext", "mozilla.org/file.ext");
- testVal("http://mozilla.org/sub/", "mozilla.org/sub/");
-
- testVal("http://ftp.mozilla.org/", "ftp.mozilla.org");
- testVal("http://ftp1.mozilla.org/", "ftp1.mozilla.org");
- testVal("http://ftp42.mozilla.org/", "ftp42.mozilla.org");
- testVal("http://ftpx.mozilla.org/", "ftpx.mozilla.org");
- testVal("ftp://ftp.mozilla.org/", "ftp://ftp.mozilla.org");
- testVal("ftp://ftp1.mozilla.org/", "ftp://ftp1.mozilla.org");
- testVal("ftp://ftp42.mozilla.org/", "ftp://ftp42.mozilla.org");
- testVal("ftp://ftpx.mozilla.org/", "ftp://ftpx.mozilla.org");
-
- testVal("https://user:pass@mozilla.org/", "https://user:pass@mozilla.org");
- testVal("https://user@mozilla.org/", "https://user@mozilla.org");
- testVal("http://user:pass@mozilla.org/", "user:pass@mozilla.org");
- testVal("http://user@mozilla.org/", "user@mozilla.org");
- testVal("http://sub.mozilla.org:666/", "sub.mozilla.org:666");
-
- testVal("https://[fe80::222:19ff:fe11:8c76]/file.ext");
- testVal("http://[fe80::222:19ff:fe11:8c76]/", "[fe80::222:19ff:fe11:8c76]");
- testVal("https://user:pass@[fe80::222:19ff:fe11:8c76]:666/file.ext");
- testVal("http://user:pass@[fe80::222:19ff:fe11:8c76]:666/file.ext", "user:pass@[fe80::222:19ff:fe11:8c76]:666/file.ext");
-
- testVal("mailto:admin@mozilla.org");
- testVal("gopher://mozilla.org/");
- testVal("about:config");
- testVal("jar:http://mozilla.org/example.jar!/");
- testVal("view-source:http://mozilla.org/");
-
- // Behaviour for hosts with no dots depends on the whitelist:
- let fixupWhitelistPref = "browser.fixup.domainwhitelist.localhost";
- Services.prefs.setBoolPref(fixupWhitelistPref, false);
- testVal("http://localhost");
- Services.prefs.setBoolPref(fixupWhitelistPref, true);
- testVal("http://localhost", "localhost");
- Services.prefs.clearUserPref(fixupWhitelistPref);
-
- testVal("http:// invalid url");
-
- testVal("http://someotherhostwithnodots");
- testVal("http://localhost/ foo bar baz");
- testVal("http://localhost.localdomain/ foo bar baz", "localhost.localdomain/ foo bar baz");
-
- Services.prefs.setBoolPref(PREF_TRIMURLS, false);
-
- testVal("http://mozilla.org/");
-
- Services.prefs.setBoolPref(PREF_TRIMURLS, true);
-
- let promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser,
- false, "http://example.com/");
- gBrowser.loadURI("http://example.com/");
- yield promiseLoaded;
-
- yield testCopy("example.com", "http://example.com/")
-
- SetPageProxyState("invalid");
- gURLBar.valueIsTyped = true;
- yield testCopy("example.com", "example.com");
-});
-
-function testVal(originalValue, targetValue) {
- gURLBar.value = originalValue;
- gURLBar.valueIsTyped = false;
- is(gURLBar.textValue, targetValue || originalValue, "url bar value set");
-}
-
-function testCopy(originalValue, targetValue) {
- return new Promise((resolve, reject) => {
- waitForClipboard(targetValue, function () {
- is(gURLBar.textValue, originalValue, "url bar copy value set");
-
- gURLBar.focus();
- gURLBar.select();
- goDoCommand("cmd_copy");
- }, resolve, reject);
- });
-}
diff --git a/browser/base/content/test/urlbar/browser_urlbarUpdateForDomainCompletion.js b/browser/base/content/test/urlbar/browser_urlbarUpdateForDomainCompletion.js
deleted file mode 100644
index c3cdf507f..000000000
--- a/browser/base/content/test/urlbar/browser_urlbarUpdateForDomainCompletion.js
+++ /dev/null
@@ -1,17 +0,0 @@
-"use strict";
-
-/**
- * Disable keyword.enabled (so no keyword search), and check that when you type in
- * "example" and hit enter, the browser loads and the URL bar is updated accordingly.
- */
-add_task(function* () {
- yield new Promise(resolve => SpecialPowers.pushPrefEnv({set: [["keyword.enabled", false]]}, resolve));
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
- gURLBar.value = "example";
- gURLBar.select();
- let loadPromise = BrowserTestUtils.browserLoaded(browser, false, url => url == "http://www.example.com/");
- EventUtils.sendKey("return");
- yield loadPromise;
- is(gURLBar.textValue, "www.example.com");
- });
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbar_autoFill_backspaced.js b/browser/base/content/test/urlbar/browser_urlbar_autoFill_backspaced.js
deleted file mode 100644
index 7fefd3f77..000000000
--- a/browser/base/content/test/urlbar/browser_urlbar_autoFill_backspaced.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* This test ensures that backspacing autoFilled values still allows to
- * confirm the remaining value.
- */
-
-function* test_autocomplete(data) {
- let {desc, typed, autofilled, modified, keys, action, onAutoFill} = data;
- info(desc);
-
- yield promiseAutocompleteResultPopup(typed);
- is(gURLBar.textValue, autofilled, "autofilled value is as expected");
- if (onAutoFill)
- onAutoFill()
-
- keys.forEach(key => EventUtils.synthesizeKey(key, {}));
-
- is(gURLBar.textValue, modified, "backspaced value is as expected");
-
- yield promiseSearchComplete();
-
- ok(gURLBar.popup.richlistbox.children.length > 0, "Should get at least 1 result");
- let result = gURLBar.popup.richlistbox.children[0];
- let type = result.getAttribute("type");
- let types = type.split(/\s+/);
- ok(types.indexOf(action) >= 0, `The type attribute "${type}" includes the expected action "${action}"`);
-
- gURLBar.popup.hidePopup();
- yield promisePopupHidden(gURLBar.popup);
- gURLBar.blur();
-}
-
-add_task(function* () {
- registerCleanupFunction(function* () {
- Services.prefs.clearUserPref("browser.urlbar.autoFill");
- gURLBar.handleRevert();
- yield PlacesTestUtils.clearHistory();
- });
- Services.prefs.setBoolPref("browser.urlbar.autoFill", true);
-
- // Add a typed visit, so it will be autofilled.
- yield PlacesTestUtils.addVisits({
- uri: NetUtil.newURI("http://example.com/"),
- transition: Ci.nsINavHistoryService.TRANSITION_TYPED
- });
-
- yield test_autocomplete({ desc: "DELETE the autofilled part should search",
- typed: "exam",
- autofilled: "example.com/",
- modified: "exam",
- keys: ["VK_DELETE"],
- action: "searchengine"
- });
- yield test_autocomplete({ desc: "DELETE the final slash should visit",
- typed: "example.com",
- autofilled: "example.com/",
- modified: "example.com",
- keys: ["VK_DELETE"],
- action: "visiturl"
- });
-
- yield test_autocomplete({ desc: "BACK_SPACE the autofilled part should search",
- typed: "exam",
- autofilled: "example.com/",
- modified: "exam",
- keys: ["VK_BACK_SPACE"],
- action: "searchengine"
- });
- yield test_autocomplete({ desc: "BACK_SPACE the final slash should visit",
- typed: "example.com",
- autofilled: "example.com/",
- modified: "example.com",
- keys: ["VK_BACK_SPACE"],
- action: "visiturl"
- });
-
- yield test_autocomplete({ desc: "DELETE the autofilled part, then BACK_SPACE, should search",
- typed: "exam",
- autofilled: "example.com/",
- modified: "exa",
- keys: ["VK_DELETE", "VK_BACK_SPACE"],
- action: "searchengine"
- });
- yield test_autocomplete({ desc: "DELETE the final slash, then BACK_SPACE, should search",
- typed: "example.com",
- autofilled: "example.com/",
- modified: "example.co",
- keys: ["VK_DELETE", "VK_BACK_SPACE"],
- action: "visiturl"
- });
-
- yield test_autocomplete({ desc: "BACK_SPACE the autofilled part, then BACK_SPACE, should search",
- typed: "exam",
- autofilled: "example.com/",
- modified: "exa",
- keys: ["VK_BACK_SPACE", "VK_BACK_SPACE"],
- action: "searchengine"
- });
- yield test_autocomplete({ desc: "BACK_SPACE the final slash, then BACK_SPACE, should search",
- typed: "example.com",
- autofilled: "example.com/",
- modified: "example.co",
- keys: ["VK_BACK_SPACE", "VK_BACK_SPACE"],
- action: "visiturl"
- });
-
- yield test_autocomplete({ desc: "BACK_SPACE after blur should search",
- typed: "ex",
- autofilled: "example.com/",
- modified: "e",
- keys: ["VK_BACK_SPACE"],
- action: "searchengine",
- onAutoFill: () => {
- gURLBar.blur();
- gURLBar.focus();
- gURLBar.selectionStart = 1;
- gURLBar.selectionEnd = 12;
- }
- });
- yield test_autocomplete({ desc: "DELETE after blur should search",
- typed: "ex",
- autofilled: "example.com/",
- modified: "e",
- keys: ["VK_DELETE"],
- action: "searchengine",
- onAutoFill: () => {
- gURLBar.blur();
- gURLBar.focus();
- gURLBar.selectionStart = 1;
- gURLBar.selectionEnd = 12;
- }
- });
- yield test_autocomplete({ desc: "double BACK_SPACE after blur should search",
- typed: "ex",
- autofilled: "example.com/",
- modified: "e",
- keys: ["VK_BACK_SPACE", "VK_BACK_SPACE"],
- action: "searchengine",
- onAutoFill: () => {
- gURLBar.blur();
- gURLBar.focus();
- gURLBar.selectionStart = 2;
- gURLBar.selectionEnd = 12;
- }
- });
-
- yield PlacesTestUtils.clearHistory();
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbar_blanking.js b/browser/base/content/test/urlbar/browser_urlbar_blanking.js
deleted file mode 100644
index 13660edab..000000000
--- a/browser/base/content/test/urlbar/browser_urlbar_blanking.js
+++ /dev/null
@@ -1,35 +0,0 @@
-"use strict";
-
-add_task(function*() {
- for (let page of gInitialPages) {
- if (page == "about:newtab") {
- // New tab preloading makes this a pain to test, so skip
- continue;
- }
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, page);
- ok(!gURLBar.value, "The URL bar should be empty if we load a plain " + page + " page.");
- yield BrowserTestUtils.removeTab(tab);
- }
-});
-
-add_task(function*() {
- const URI = "http://www.example.com/browser/browser/base/content/test/urlbar/file_blank_but_not_blank.html";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URI);
- is(gURLBar.value, URI, "The URL bar should match the URI");
- let browserLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- ContentTask.spawn(tab.linkedBrowser, null, function() {
- content.document.querySelector('a').click();
- });
- yield browserLoaded;
- ok(gURLBar.value.startsWith("javascript"), "The URL bar should have the JS URI");
- // When reloading, the javascript: uri we're using will throw an exception.
- // That's deliberate, so we need to tell mochitest to ignore it:
- SimpleTest.expectUncaughtException(true);
- yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
- // This is sync, so by the time we return we should have changed the URL bar.
- content.location.reload();
- });
- ok(!!gURLBar.value, "URL bar should not be blank.");
- yield BrowserTestUtils.removeTab(tab);
- SimpleTest.expectUncaughtException(false);
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbar_locationchange_urlbar_edit_dos.js b/browser/base/content/test/urlbar/browser_urlbar_locationchange_urlbar_edit_dos.js
deleted file mode 100644
index 63ed58a62..000000000
--- a/browser/base/content/test/urlbar/browser_urlbar_locationchange_urlbar_edit_dos.js
+++ /dev/null
@@ -1,41 +0,0 @@
-"use strict";
-
-function* checkURLBarValueStays(browser) {
- gURLBar.select();
- EventUtils.synthesizeKey("a", {});
- is(gURLBar.value, "a", "URL bar value should match after sending a key");
- yield new Promise(resolve => {
- let listener = {
- onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
- ok(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT,
- "Should only get a same document location change");
- gBrowser.selectedBrowser.removeProgressListener(filter);
- filter = null;
- resolve();
- },
- };
- let filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
- .createInstance(Ci.nsIWebProgress);
- filter.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL);
- gBrowser.selectedBrowser.addProgressListener(filter);
- });
- is(gURLBar.value, "a", "URL bar should not have been changed by location changes.");
-}
-
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com/browser/browser/base/content/test/urlbar/file_urlbar_edit_dos.html"
- }, function*(browser) {
- yield ContentTask.spawn(browser, "", function() {
- content.wrappedJSObject.dos_hash();
- });
- yield checkURLBarValueStays(browser);
- yield ContentTask.spawn(browser, "", function() {
- content.clearTimeout(content.wrappedJSObject.dos_timeout);
- content.wrappedJSObject.dos_pushState();
- });
- yield checkURLBarValueStays(browser);
- });
-});
-
diff --git a/browser/base/content/test/urlbar/browser_urlbar_remoteness_switch.js b/browser/base/content/test/urlbar/browser_urlbar_remoteness_switch.js
deleted file mode 100644
index 9a1df0505..000000000
--- a/browser/base/content/test/urlbar/browser_urlbar_remoteness_switch.js
+++ /dev/null
@@ -1,39 +0,0 @@
-"use strict";
-
-/**
- * Verify that when loading and going back/forward through history between URLs
- * loaded in the content process, and URLs loaded in the parent process, we
- * don't set the URL for the tab to about:blank inbetween the loads.
- */
-add_task(function*() {
- let url = "http://www.example.com/foo.html";
- yield BrowserTestUtils.withNewTab({gBrowser, url}, function*(browser) {
- let wpl = {
- onLocationChange(wpl, request, location, flags) {
- if (location.schemeIs("about")) {
- is(location.spec, "about:config", "Only about: location change should be for about:preferences");
- } else {
- is(location.spec, url, "Only non-about: location change should be for the http URL we're dealing with.");
- }
- },
- };
- gBrowser.addProgressListener(wpl);
-
- let didLoad = BrowserTestUtils.browserLoaded(browser, null, function(loadedURL) {
- return loadedURL == "about:config";
- });
- yield BrowserTestUtils.loadURI(browser, "about:config");
- yield didLoad;
-
- gBrowser.goBack();
- yield BrowserTestUtils.browserLoaded(browser, null, function(loadedURL) {
- return url == loadedURL;
- });
- gBrowser.goForward();
- yield BrowserTestUtils.browserLoaded(browser, null, function(loadedURL) {
- return loadedURL == "about:config";
- });
- gBrowser.removeProgressListener(wpl);
- });
-});
-
diff --git a/browser/base/content/test/urlbar/browser_urlbar_searchsettings.js b/browser/base/content/test/urlbar/browser_urlbar_searchsettings.js
deleted file mode 100644
index 04b1c508b..000000000
--- a/browser/base/content/test/urlbar/browser_urlbar_searchsettings.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-add_task(function*() {
- let button = document.getElementById("urlbar-search-settings");
- if (!button) {
- ok("Skipping test");
- return;
- }
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* () {
- let popupopened = BrowserTestUtils.waitForEvent(gURLBar.popup, "popupshown");
-
- gURLBar.focus();
- EventUtils.synthesizeKey("a", {});
- yield popupopened;
-
- // Since the current tab is blank the preferences pane will load there
- let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- let popupclosed = BrowserTestUtils.waitForEvent(gURLBar.popup, "popuphidden");
- EventUtils.synthesizeMouseAtCenter(button, {});
- yield loaded;
- yield popupclosed;
-
- is(gBrowser.selectedBrowser.currentURI.spec, "about:preferences#search",
- "Should have loaded the right page");
- });
-});
diff --git a/browser/base/content/test/urlbar/browser_urlbar_stop_pending.js b/browser/base/content/test/urlbar/browser_urlbar_stop_pending.js
deleted file mode 100644
index 6b6a10ea3..000000000
--- a/browser/base/content/test/urlbar/browser_urlbar_stop_pending.js
+++ /dev/null
@@ -1,138 +0,0 @@
-"use strict";
-
-const SLOW_PAGE = "http://www.example.com/browser/browser/base/content/test/urlbar/slow-page.sjs";
-const SLOW_PAGE2 = "http://mochi.test:8888/browser/browser/base/content/test/urlbar/slow-page.sjs?faster";
-
-/**
- * Check that if we:
- * 1) have a loaded page
- * 2) load a separate URL
- * 3) before the URL for step 2 has finished loading, load a third URL
- * we don't revert to the URL from (1).
- */
-add_task(function*() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com", true, true);
-
- let expectedURLBarChange = SLOW_PAGE;
- let sawChange = false;
- let handler = e => {
- sawChange = true;
- is(gURLBar.value, expectedURLBarChange, "Should not change URL bar value!");
- };
-
- let obs = new MutationObserver(handler);
-
- obs.observe(gURLBar, {attributes: true});
- gURLBar.value = SLOW_PAGE;
- gURLBar.handleCommand();
-
- // If this ever starts going intermittent, we've broken this.
- yield new Promise(resolve => setTimeout(resolve, 200));
- expectedURLBarChange = SLOW_PAGE2;
- let pageLoadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- gURLBar.value = expectedURLBarChange;
- gURLBar.handleCommand();
- is(gURLBar.value, expectedURLBarChange, "Should not have changed URL bar value synchronously.");
- yield pageLoadPromise;
- ok(sawChange, "The URL bar change handler should have been called by the time the page was loaded");
- obs.disconnect();
- obs = null;
- yield BrowserTestUtils.removeTab(tab);
-});
-
-/**
- * Check that if we:
- * 1) middle-click a link to a separate page whose server doesn't respond
- * 2) we switch to that tab and stop the request
- *
- * The URL bar continues to contain the URL of the page we wanted to visit.
- */
-add_task(function*() {
- let socket = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
- socket.init(-1, true, -1);
- const PORT = socket.port;
- registerCleanupFunction(() => { socket.close(); });
-
- const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
- const BASE_PAGE = TEST_PATH + "dummy_page.html";
- const SLOW_HOST = `https://localhost:${PORT}/`;
- info("Using URLs: " + SLOW_HOST);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, BASE_PAGE);
- info("opened tab");
- yield ContentTask.spawn(tab.linkedBrowser, SLOW_HOST, URL => {
- let link = content.document.createElement("a");
- link.href = URL;
- link.textContent = "click me to open a slow page";
- link.id = "clickme"
- content.document.body.appendChild(link);
- });
- info("added link");
- let newTabPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
- // Middle click the link:
- yield BrowserTestUtils.synthesizeMouseAtCenter("#clickme", { button: 1 }, tab.linkedBrowser);
- // get new tab, switch to it
- let newTab = (yield newTabPromise).target;
- yield BrowserTestUtils.switchTab(gBrowser, newTab);
- is(gURLBar.value, SLOW_HOST, "Should have slow page in URL bar");
- let browserStoppedPromise = BrowserTestUtils.browserStopped(newTab.linkedBrowser);
- BrowserStop();
- yield browserStoppedPromise;
-
- is(gURLBar.value, SLOW_HOST, "Should still have slow page in URL bar after stop");
- yield BrowserTestUtils.removeTab(newTab);
- yield BrowserTestUtils.removeTab(tab);
-});
-/**
- * Check that if we:
- * 1) middle-click a link to a separate page whose server doesn't respond
- * 2) we alter the URL on that page to some other server that doesn't respond
- * 3) we stop the request
- *
- * The URL bar continues to contain the second URL.
- */
-add_task(function*() {
- let socket = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
- socket.init(-1, true, -1);
- const PORT1 = socket.port;
- let socket2 = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
- socket2.init(-1, true, -1);
- const PORT2 = socket2.port;
- registerCleanupFunction(() => { socket.close(); socket2.close(); });
-
- const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
- const BASE_PAGE = TEST_PATH + "dummy_page.html";
- const SLOW_HOST1 = `https://localhost:${PORT1}/`;
- const SLOW_HOST2 = `https://localhost:${PORT2}/`;
- info("Using URLs: " + SLOW_HOST1 + " and " + SLOW_HOST2);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, BASE_PAGE);
- info("opened tab");
- yield ContentTask.spawn(tab.linkedBrowser, SLOW_HOST1, URL => {
- let link = content.document.createElement("a");
- link.href = URL;
- link.textContent = "click me to open a slow page";
- link.id = "clickme"
- content.document.body.appendChild(link);
- });
- info("added link");
- let newTabPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
- // Middle click the link:
- yield BrowserTestUtils.synthesizeMouseAtCenter("#clickme", { button: 1 }, tab.linkedBrowser);
- // get new tab, switch to it
- let newTab = (yield newTabPromise).target;
- yield BrowserTestUtils.switchTab(gBrowser, newTab);
- is(gURLBar.value, SLOW_HOST1, "Should have slow page in URL bar");
- let browserStoppedPromise = BrowserTestUtils.browserStopped(newTab.linkedBrowser);
- gURLBar.value = SLOW_HOST2;
- gURLBar.handleCommand();
- yield browserStoppedPromise;
-
- is(gURLBar.value, SLOW_HOST2, "Should have second slow page in URL bar");
- browserStoppedPromise = BrowserTestUtils.browserStopped(newTab.linkedBrowser);
- BrowserStop();
- yield browserStoppedPromise;
-
- is(gURLBar.value, SLOW_HOST2, "Should still have second slow page in URL bar after stop");
- yield BrowserTestUtils.removeTab(newTab);
- yield BrowserTestUtils.removeTab(tab);
-});
-
diff --git a/browser/base/content/test/urlbar/browser_wyciwyg_urlbarCopying.js b/browser/base/content/test/urlbar/browser_wyciwyg_urlbarCopying.js
deleted file mode 100644
index 54b174aa8..000000000
--- a/browser/base/content/test/urlbar/browser_wyciwyg_urlbarCopying.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function testURLBarCopy(targetValue) {
- return new Promise((resolve, reject) => {
- info("Expecting copy of: " + targetValue);
- waitForClipboard(targetValue, function () {
- gURLBar.focus();
- gURLBar.select();
-
- goDoCommand("cmd_copy");
- }, resolve, () => {
- ok(false, "Clipboard copy failed");
- reject();
- });
- });
-}
-
-add_task(function* () {
- const url = "http://mochi.test:8888/browser/browser/base/content/test/urlbar/test_wyciwyg_copying.html";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#btn", {}, tab.linkedBrowser);
- let currentURL = gBrowser.currentURI.spec;
- ok(/^wyciwyg:\/\//i.test(currentURL), currentURL + " is a wyciwyg URI");
-
- yield testURLBarCopy(url);
-
- while (gBrowser.tabs.length > 1)
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/base/content/test/urlbar/dummy_page.html b/browser/base/content/test/urlbar/dummy_page.html
deleted file mode 100644
index 1a87e2840..000000000
--- a/browser/base/content/test/urlbar/dummy_page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>Dummy test page</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<p>Dummy test page</p>
-</body>
-</html>
diff --git a/browser/base/content/test/urlbar/file_blank_but_not_blank.html b/browser/base/content/test/urlbar/file_blank_but_not_blank.html
deleted file mode 100644
index 1f5fea8dc..000000000
--- a/browser/base/content/test/urlbar/file_blank_but_not_blank.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<script>var q = "1";</script>
-<a href="javascript:q">Click me</a>
diff --git a/browser/base/content/test/urlbar/file_urlbar_edit_dos.html b/browser/base/content/test/urlbar/file_urlbar_edit_dos.html
deleted file mode 100644
index 5a6e7d109..000000000
--- a/browser/base/content/test/urlbar/file_urlbar_edit_dos.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Try editing the URL bar</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<script>
-var dos_timeout = null;
-function dos_hash() {
- dos_timeout = setTimeout(function() {
- location.hash = "#";
- }, 50);
-}
-
-function dos_pushState() {
- dos_timeout = setTimeout(function() {
- history.pushState({}, "Some title", "");
- }, 50);
-}
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/urlbar/head.js b/browser/base/content/test/urlbar/head.js
deleted file mode 100644
index 427dba080..000000000
--- a/browser/base/content/test/urlbar/head.js
+++ /dev/null
@@ -1,205 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
- "resource://gre/modules/Preferences.jsm");
-
-/**
- * Waits for the next top-level document load in the current browser. The URI
- * of the document is compared against aExpectedURL. The load is then stopped
- * before it actually starts.
- *
- * @param aExpectedURL
- * The URL of the document that is expected to load.
- * @param aStopFromProgressListener
- * Whether to cancel the load directly from the progress listener. Defaults to true.
- * If you're using this method to avoid hitting the network, you want the default (true).
- * However, the browser UI will behave differently for loads stopped directly from
- * the progress listener (effectively in the middle of a call to loadURI) and so there
- * are cases where you may want to avoid stopping the load directly from within the
- * progress listener callback.
- * @return promise
- */
-function waitForDocLoadAndStopIt(aExpectedURL, aBrowser=gBrowser.selectedBrowser, aStopFromProgressListener=true) {
- function content_script(aStopFromProgressListener) {
- let { interfaces: Ci, utils: Cu } = Components;
- Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
- let wp = docShell.QueryInterface(Ci.nsIWebProgress);
-
- function stopContent(now, uri) {
- if (now) {
- /* Hammer time. */
- content.stop();
-
- /* Let the parent know we're done. */
- sendAsyncMessage("Test:WaitForDocLoadAndStopIt", { uri });
- } else {
- setTimeout(stopContent.bind(null, true, uri), 0);
- }
- }
-
- let progressListener = {
- onStateChange: function (webProgress, req, flags, status) {
- dump("waitForDocLoadAndStopIt: onStateChange " + flags.toString(16) + ": " + req.name + "\n");
-
- if (webProgress.isTopLevel &&
- flags & Ci.nsIWebProgressListener.STATE_START) {
- wp.removeProgressListener(progressListener);
-
- let chan = req.QueryInterface(Ci.nsIChannel);
- dump(`waitForDocLoadAndStopIt: Document start: ${chan.URI.spec}\n`);
-
- stopContent(aStopFromProgressListener, chan.originalURI.spec);
- }
- },
- QueryInterface: XPCOMUtils.generateQI(["nsISupportsWeakReference"])
- };
- wp.addProgressListener(progressListener, wp.NOTIFY_STATE_WINDOW);
-
- /**
- * As |this| is undefined and we can't extend |docShell|, adding an unload
- * event handler is the easiest way to ensure the weakly referenced
- * progress listener is kept alive as long as necessary.
- */
- addEventListener("unload", function () {
- try {
- wp.removeProgressListener(progressListener);
- } catch (e) { /* Will most likely fail. */ }
- });
- }
-
- return new Promise((resolve, reject) => {
- function complete({ data }) {
- is(data.uri, aExpectedURL, "waitForDocLoadAndStopIt: The expected URL was loaded");
- mm.removeMessageListener("Test:WaitForDocLoadAndStopIt", complete);
- resolve();
- }
-
- let mm = aBrowser.messageManager;
- mm.loadFrameScript("data:,(" + content_script.toString() + ")(" + aStopFromProgressListener + ");", true);
- mm.addMessageListener("Test:WaitForDocLoadAndStopIt", complete);
- info("waitForDocLoadAndStopIt: Waiting for URL: " + aExpectedURL);
- });
-}
-
-function is_hidden(element) {
- var style = element.ownerGlobal.getComputedStyle(element);
- if (style.display == "none")
- return true;
- if (style.visibility != "visible")
- return true;
- if (style.display == "-moz-popup")
- return ["hiding", "closed"].indexOf(element.state) != -1;
-
- // Hiding a parent element will hide all its children
- if (element.parentNode != element.ownerDocument)
- return is_hidden(element.parentNode);
-
- return false;
-}
-
-function is_visible(element) {
- var style = element.ownerGlobal.getComputedStyle(element);
- if (style.display == "none")
- return false;
- if (style.visibility != "visible")
- return false;
- if (style.display == "-moz-popup" && element.state != "open")
- return false;
-
- // Hiding a parent element will hide all its children
- if (element.parentNode != element.ownerDocument)
- return is_visible(element.parentNode);
-
- return true;
-}
-
-function is_element_visible(element, msg) {
- isnot(element, null, "Element should not be null, when checking visibility");
- ok(is_visible(element), msg || "Element should be visible");
-}
-
-function is_element_hidden(element, msg) {
- isnot(element, null, "Element should not be null, when checking visibility");
- ok(is_hidden(element), msg || "Element should be hidden");
-}
-
-function promisePopupEvent(popup, eventSuffix) {
- let endState = {shown: "open", hidden: "closed"}[eventSuffix];
-
- if (popup.state == endState)
- return Promise.resolve();
-
- let eventType = "popup" + eventSuffix;
- let deferred = Promise.defer();
- popup.addEventListener(eventType, function onPopupShown(event) {
- popup.removeEventListener(eventType, onPopupShown);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
-function promisePopupShown(popup) {
- return promisePopupEvent(popup, "shown");
-}
-
-function promisePopupHidden(popup) {
- return promisePopupEvent(popup, "hidden");
-}
-
-function promiseSearchComplete(win = window) {
- return promisePopupShown(win.gURLBar.popup).then(() => {
- function searchIsComplete() {
- return win.gURLBar.controller.searchStatus >=
- Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH;
- }
-
- // Wait until there are at least two matches.
- return BrowserTestUtils.waitForCondition(searchIsComplete, "waiting urlbar search to complete");
- });
-}
-
-function promiseAutocompleteResultPopup(inputText,
- win = window,
- fireInputEvent = false) {
- waitForFocus(() => {
- win.gURLBar.focus();
- win.gURLBar.value = inputText;
- if (fireInputEvent) {
- // This is necessary to get the urlbar to set gBrowser.userTypedValue.
- let event = document.createEvent("Events");
- event.initEvent("input", true, true);
- win.gURLBar.dispatchEvent(event);
- }
- win.gURLBar.controller.startSearch(inputText);
- }, win);
-
- return promiseSearchComplete(win);
-}
-
-function promiseNewSearchEngine(basename) {
- return new Promise((resolve, reject) => {
- info("Waiting for engine to be added: " + basename);
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- registerCleanupFunction(() => Services.search.removeEngine(engine));
- resolve(engine);
- },
- onError: function (errCode) {
- Assert.ok(false, "addEngine failed with error code " + errCode);
- reject();
- },
- });
- });
-}
-
diff --git a/browser/base/content/test/urlbar/moz.png b/browser/base/content/test/urlbar/moz.png
deleted file mode 100644
index 769c63634..000000000
--- a/browser/base/content/test/urlbar/moz.png
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/urlbar/print_postdata.sjs b/browser/base/content/test/urlbar/print_postdata.sjs
deleted file mode 100644
index 4175a2480..000000000
--- a/browser/base/content/test/urlbar/print_postdata.sjs
+++ /dev/null
@@ -1,22 +0,0 @@
-const CC = Components.Constructor;
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-
-function handleRequest(request, response) {
- response.setHeader("Content-Type", "text/plain", false);
- if (request.method == "GET") {
- response.write(request.queryString);
- } else {
- var body = new BinaryInputStream(request.bodyInputStream);
-
- var avail;
- var bytes = [];
-
- while ((avail = body.available()) > 0)
- Array.prototype.push.apply(bytes, body.readByteArray(avail));
-
- var data = String.fromCharCode.apply(null, bytes);
- response.bodyOutputStream.write(data, data.length);
- }
-}
diff --git a/browser/base/content/test/urlbar/redirect_bug623155.sjs b/browser/base/content/test/urlbar/redirect_bug623155.sjs
deleted file mode 100644
index 64c6f143b..000000000
--- a/browser/base/content/test/urlbar/redirect_bug623155.sjs
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const REDIRECT_TO = "https://www.bank1.com/"; // Bad-cert host.
-
-function handleRequest(aRequest, aResponse) {
- // Set HTTP Status
- aResponse.setStatusLine(aRequest.httpVersion, 301, "Moved Permanently");
-
- // Set redirect URI, mirroring the hash value.
- let hash = (/\#.+/.test(aRequest.path))?
- "#" + aRequest.path.split("#")[1]:
- "";
- aResponse.setHeader("Location", REDIRECT_TO + hash);
-}
diff --git a/browser/base/content/test/urlbar/searchSuggestionEngine.sjs b/browser/base/content/test/urlbar/searchSuggestionEngine.sjs
deleted file mode 100644
index 1978b4f66..000000000
--- a/browser/base/content/test/urlbar/searchSuggestionEngine.sjs
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function handleRequest(req, resp) {
- let suffixes = ["foo", "bar"];
- let data = [req.queryString, suffixes.map(s => req.queryString + s)];
- resp.setHeader("Content-Type", "application/json", false);
- resp.write(JSON.stringify(data));
-}
diff --git a/browser/base/content/test/urlbar/searchSuggestionEngine.xml b/browser/base/content/test/urlbar/searchSuggestionEngine.xml
deleted file mode 100644
index a5659792e..000000000
--- a/browser/base/content/test/urlbar/searchSuggestionEngine.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_searchSuggestionEngine searchSuggestionEngine.xml</ShortName>
-<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/base/content/test/urlbar/searchSuggestionEngine.sjs?{searchTerms}"/>
-<Url type="text/html" method="GET" template="http://mochi.test:8888/" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/base/content/test/urlbar/slow-page.sjs b/browser/base/content/test/urlbar/slow-page.sjs
deleted file mode 100644
index f428d66e4..000000000
--- a/browser/base/content/test/urlbar/slow-page.sjs
+++ /dev/null
@@ -1,22 +0,0 @@
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-let timer;
-
-const DELAY_MS = 5000;
-function handleRequest(request, response) {
- if (request.queryString.endsWith("faster")) {
- response.setHeader("Content-Type", "text/html", false);
- response.write("<body>Not so slow!</body>");
- return;
- }
- response.processAsync();
- timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.init(() => {
- response.setHeader("Content-Type", "text/html", false);
- response.write("<body>This was the slow load. You should never see this.</body>");
- response.finish();
- }, DELAY_MS, Ci.nsITimer.TYPE_ONE_SHOT);
-}
diff --git a/browser/base/content/test/urlbar/test_wyciwyg_copying.html b/browser/base/content/test/urlbar/test_wyciwyg_copying.html
deleted file mode 100644
index 3a8c3a150..000000000
--- a/browser/base/content/test/urlbar/test_wyciwyg_copying.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
-<body>
-<script>
- function go() {
- var w = window.open();
- w.document.open();
- w.document.write("<html><body>test document</body></html>");
- w.document.close();
- }
-</script>
-<button id="btn" onclick="go();">test</button>
-</body>
-</html>
diff --git a/browser/base/content/test/webrtc/.eslintrc.js b/browser/base/content/test/webrtc/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/base/content/test/webrtc/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/base/content/test/webrtc/browser.ini b/browser/base/content/test/webrtc/browser.ini
deleted file mode 100644
index 8830989ad..000000000
--- a/browser/base/content/test/webrtc/browser.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-support-files =
- get_user_media.html
- get_user_media_content_script.js
- head.js
-
-[browser_devices_get_user_media.js]
-skip-if = (os == "linux" && debug) # linux: bug 976544
-[browser_devices_get_user_media_anim.js]
-[browser_devices_get_user_media_in_frame.js]
-[browser_devices_get_user_media_tear_off_tab.js]
diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media.js b/browser/base/content/test/webrtc/browser_devices_get_user_media.js
deleted file mode 100644
index 3681a810b..000000000
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media.js
+++ /dev/null
@@ -1,554 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-requestLongerTimeout(2);
-
-registerCleanupFunction(function() {
- gBrowser.removeCurrentTab();
-});
-
-const permissionError = "error: NotAllowedError: The request is not allowed " +
- "by the user agent or the platform in the current context.";
-
-var gTests = [
-
-{
- desc: "getUserMedia audio+video",
- run: function* checkAudioVideo() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
- "webRTC-shareDevices-notification-icon", "anchored to device icon");
- checkDeviceSelectors(true, true);
- let iconclass =
- PopupNotifications.panel.firstChild.getAttribute("iconclass");
- ok(iconclass.includes("camera-icon"), "panel using devices icon");
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({audio: true, video: true});
- yield closeStream();
- }
-},
-
-{
- desc: "getUserMedia audio only",
- run: function* checkAudioOnly() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
- "webRTC-shareMicrophone-notification-icon", "anchored to mic icon");
- checkDeviceSelectors(true);
- let iconclass =
- PopupNotifications.panel.firstChild.getAttribute("iconclass");
- ok(iconclass.includes("microphone-icon"), "panel using microphone icon");
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "Microphone",
- "expected microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({audio: true});
- yield closeStream();
- }
-},
-
-{
- desc: "getUserMedia video only",
- run: function* checkVideoOnly() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(false, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
- "webRTC-shareDevices-notification-icon", "anchored to device icon");
- checkDeviceSelectors(false, true);
- let iconclass =
- PopupNotifications.panel.firstChild.getAttribute("iconclass");
- ok(iconclass.includes("camera-icon"), "panel using devices icon");
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "Camera", "expected camera to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true});
- yield closeStream();
- }
-},
-
-{
- desc: "getUserMedia audio+video, user clicks \"Don't Share\"",
- run: function* checkDontShare() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- yield promiseMessage(permissionError, () => {
- activateSecondaryAction(kActionDeny);
- });
-
- yield expectObserverCalled("getUserMedia:response:deny");
- yield expectObserverCalled("recording-window-ended");
- yield checkNotSharing();
- }
-},
-
-{
- desc: "getUserMedia audio+video: stop sharing",
- run: function* checkStopSharing() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true, audio: true});
-
- yield stopSharing();
-
- // the stream is already closed, but this will do some cleanup anyway
- yield closeStream(true);
- }
-},
-
-{
- desc: "getUserMedia audio+video: reloading the page removes all gUM UI",
- run: function* checkReloading() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true, audio: true});
-
- info("reloading the web page");
- promise = promiseObserverCalled("recording-device-events");
- content.location.reload();
- yield promise;
-
- yield expectObserverCalled("recording-window-ended");
- yield expectNoObserverCalled();
- yield checkNotSharing();
- }
-},
-
-{
- desc: "getUserMedia prompt: Always/Never Share",
- run: function* checkRememberCheckbox() {
- let elt = id => document.getElementById(id);
-
- function* checkPerm(aRequestAudio, aRequestVideo,
- aExpectedAudioPerm, aExpectedVideoPerm, aNever) {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(aRequestAudio, aRequestVideo);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- is(elt("webRTC-selectMicrophone").hidden, !aRequestAudio,
- "microphone selector expected to be " + (aRequestAudio ? "visible" : "hidden"));
-
- is(elt("webRTC-selectCamera").hidden, !aRequestVideo,
- "camera selector expected to be " + (aRequestVideo ? "visible" : "hidden"));
-
- let expectedMessage = aNever ? permissionError : "ok";
- yield promiseMessage(expectedMessage, () => {
- activateSecondaryAction(aNever ? kActionNever : kActionAlways);
- });
- let expected = [];
- if (expectedMessage == "ok") {
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- if (aRequestVideo)
- expected.push("Camera");
- if (aRequestAudio)
- expected.push("Microphone");
- expected = expected.join("And");
- }
- else {
- yield expectObserverCalled("getUserMedia:response:deny");
- yield expectObserverCalled("recording-window-ended");
- expected = "none";
- }
- is((yield getMediaCaptureState()), expected,
- "expected " + expected + " to be shared");
-
- function checkDevicePermissions(aDevice, aExpected) {
- let Perms = Services.perms;
- let uri = gBrowser.selectedBrowser.documentURI;
- let devicePerms = Perms.testExactPermission(uri, aDevice);
- if (aExpected === undefined)
- is(devicePerms, Perms.UNKNOWN_ACTION, "no " + aDevice + " persistent permissions");
- else {
- is(devicePerms, aExpected ? Perms.ALLOW_ACTION : Perms.DENY_ACTION,
- aDevice + " persistently " + (aExpected ? "allowed" : "denied"));
- }
- Perms.remove(uri, aDevice);
- }
- checkDevicePermissions("microphone", aExpectedAudioPerm);
- checkDevicePermissions("camera", aExpectedVideoPerm);
-
- if (expectedMessage == "ok")
- yield closeStream();
- }
-
- // 3 cases where the user accepts the device prompt.
- info("audio+video, user grants, expect both perms set to allow");
- yield checkPerm(true, true, true, true);
- info("audio only, user grants, check audio perm set to allow, video perm not set");
- yield checkPerm(true, false, true, undefined);
- info("video only, user grants, check video perm set to allow, audio perm not set");
- yield checkPerm(false, true, undefined, true);
-
- // 3 cases where the user rejects the device request by using 'Never Share'.
- info("audio only, user denies, expect audio perm set to deny, video not set");
- yield checkPerm(true, false, false, undefined, true);
- info("video only, user denies, expect video perm set to deny, audio perm not set");
- yield checkPerm(false, true, undefined, false, true);
- info("audio+video, user denies, expect both perms set to deny");
- yield checkPerm(true, true, false, false, true);
- }
-},
-
-{
- desc: "getUserMedia without prompt: use persistent permissions",
- run: function* checkUsePersistentPermissions() {
- function* usePerm(aAllowAudio, aAllowVideo, aRequestAudio, aRequestVideo,
- aExpectStream) {
- let Perms = Services.perms;
- let uri = gBrowser.selectedBrowser.documentURI;
-
- if (aAllowAudio !== undefined) {
- Perms.add(uri, "microphone", aAllowAudio ? Perms.ALLOW_ACTION
- : Perms.DENY_ACTION);
- }
- if (aAllowVideo !== undefined) {
- Perms.add(uri, "camera", aAllowVideo ? Perms.ALLOW_ACTION
- : Perms.DENY_ACTION);
- }
-
- if (aExpectStream === undefined) {
- // Check that we get a prompt.
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(aRequestAudio, aRequestVideo);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- // Deny the request to cleanup...
- yield promiseMessage(permissionError, () => {
- activateSecondaryAction(kActionDeny);
- });
- yield expectObserverCalled("getUserMedia:response:deny");
- yield expectObserverCalled("recording-window-ended");
- }
- else {
- let expectedMessage = aExpectStream ? "ok" : permissionError;
- let promise = promiseMessage(expectedMessage);
- yield promiseRequestDevice(aRequestAudio, aRequestVideo);
- yield promise;
-
- if (expectedMessage == "ok") {
- yield expectObserverCalled("getUserMedia:request");
- yield promiseNoPopupNotification("webRTC-shareDevices");
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
-
- // Check what's actually shared.
- let expected = [];
- if (aAllowVideo && aRequestVideo)
- expected.push("Camera");
- if (aAllowAudio && aRequestAudio)
- expected.push("Microphone");
- expected = expected.join("And");
- is((yield getMediaCaptureState()), expected,
- "expected " + expected + " to be shared");
-
- yield closeStream();
- }
- else {
- yield expectObserverCalled("recording-window-ended");
- }
- }
-
- Perms.remove(uri, "camera");
- Perms.remove(uri, "microphone");
- }
-
- // Set both permissions identically
- info("allow audio+video, request audio+video, expect ok (audio+video)");
- yield usePerm(true, true, true, true, true);
- info("deny audio+video, request audio+video, expect denied");
- yield usePerm(false, false, true, true, false);
-
- // Allow audio, deny video.
- info("allow audio, deny video, request audio+video, expect denied");
- yield usePerm(true, false, true, true, false);
- info("allow audio, deny video, request audio, expect ok (audio)");
- yield usePerm(true, false, true, false, true);
- info("allow audio, deny video, request video, expect denied");
- yield usePerm(true, false, false, true, false);
-
- // Deny audio, allow video.
- info("deny audio, allow video, request audio+video, expect denied");
- yield usePerm(false, true, true, true, false);
- info("deny audio, allow video, request audio, expect denied");
- yield usePerm(false, true, true, false, false);
- info("deny audio, allow video, request video, expect ok (video)");
- yield usePerm(false, true, false, true, true);
-
- // Allow audio, video not set.
- info("allow audio, request audio+video, expect prompt");
- yield usePerm(true, undefined, true, true, undefined);
- info("allow audio, request audio, expect ok (audio)");
- yield usePerm(true, undefined, true, false, true);
- info("allow audio, request video, expect prompt");
- yield usePerm(true, undefined, false, true, undefined);
-
- // Deny audio, video not set.
- info("deny audio, request audio+video, expect denied");
- yield usePerm(false, undefined, true, true, false);
- info("deny audio, request audio, expect denied");
- yield usePerm(false, undefined, true, false, false);
- info("deny audio, request video, expect prompt");
- yield usePerm(false, undefined, false, true, undefined);
-
- // Allow video, audio not set.
- info("allow video, request audio+video, expect prompt");
- yield usePerm(undefined, true, true, true, undefined);
- info("allow video, request audio, expect prompt");
- yield usePerm(undefined, true, true, false, undefined);
- info("allow video, request video, expect ok (video)");
- yield usePerm(undefined, true, false, true, true);
-
- // Deny video, audio not set.
- info("deny video, request audio+video, expect denied");
- yield usePerm(undefined, false, true, true, false);
- info("deny video, request audio, expect prompt");
- yield usePerm(undefined, false, true, false, undefined);
- info("deny video, request video, expect denied");
- yield usePerm(undefined, false, false, true, false);
- }
-},
-
-{
- desc: "Stop Sharing removes persistent permissions",
- run: function* checkStopSharingRemovesPersistentPermissions() {
- function* stopAndCheckPerm(aRequestAudio, aRequestVideo) {
- let Perms = Services.perms;
- let uri = gBrowser.selectedBrowser.documentURI;
-
- // Initially set both permissions to 'allow'.
- Perms.add(uri, "microphone", Perms.ALLOW_ACTION);
- Perms.add(uri, "camera", Perms.ALLOW_ACTION);
-
- let indicator = promiseIndicatorWindow();
- // Start sharing what's been requested.
- let promise = promiseMessage("ok");
- yield promiseRequestDevice(aRequestAudio, aRequestVideo);
- yield promise;
-
- yield expectObserverCalled("getUserMedia:request");
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- yield indicator;
- yield checkSharingUI({video: aRequestVideo, audio: aRequestAudio});
-
- yield stopSharing(aRequestVideo ? "camera" : "microphone");
-
- // Check that permissions have been removed as expected.
- let audioPerm = Perms.testExactPermission(uri, "microphone");
- if (aRequestAudio)
- is(audioPerm, Perms.UNKNOWN_ACTION, "microphone permissions removed");
- else
- is(audioPerm, Perms.ALLOW_ACTION, "microphone permissions untouched");
-
- let videoPerm = Perms.testExactPermission(uri, "camera");
- if (aRequestVideo)
- is(videoPerm, Perms.UNKNOWN_ACTION, "camera permissions removed");
- else
- is(videoPerm, Perms.ALLOW_ACTION, "camera permissions untouched");
-
- // Cleanup.
- yield closeStream(true);
-
- Perms.remove(uri, "camera");
- Perms.remove(uri, "microphone");
- }
-
- info("request audio+video, stop sharing resets both");
- yield stopAndCheckPerm(true, true);
- info("request audio, stop sharing resets audio only");
- yield stopAndCheckPerm(true, false);
- info("request video, stop sharing resets video only");
- yield stopAndCheckPerm(false, true);
- }
-},
-
-{
- desc: "test showControlCenter",
- run: function* checkShowControlCenter() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(false, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(false, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "Camera", "expected camera to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true});
-
- ok(gIdentityHandler._identityPopup.hidden, "control center should be hidden");
- if ("nsISystemStatusBar" in Ci) {
- let activeStreams = webrtcUI.getActiveStreams(true, false, false);
- webrtcUI.showSharingDoorhanger(activeStreams[0], "Devices");
- }
- else {
- let win =
- Services.wm.getMostRecentWindow("Browser:WebRTCGlobalIndicator");
- let elt = win.document.getElementById("audioVideoButton");
- EventUtils.synthesizeMouseAtCenter(elt, {}, win);
- yield promiseWaitForCondition(() => !gIdentityHandler._identityPopup.hidden);
- }
- ok(!gIdentityHandler._identityPopup.hidden, "control center should be open");
-
- gIdentityHandler._identityPopup.hidden = true;
- yield expectNoObserverCalled();
-
- yield closeStream();
- }
-},
-
-{
- desc: "'Always Allow' ignored and not shown on http pages",
- run: function* checkNoAlwaysOnHttp() {
- // Load an http page instead of the https version.
- let browser = gBrowser.selectedBrowser;
- browser.loadURI(browser.documentURI.spec.replace("https://", "http://"));
- yield BrowserTestUtils.browserLoaded(browser);
-
- // Initially set both permissions to 'allow'.
- let Perms = Services.perms;
- let uri = browser.documentURI;
- Perms.add(uri, "microphone", Perms.ALLOW_ACTION);
- Perms.add(uri, "camera", Perms.ALLOW_ACTION);
-
- // Request devices and expect a prompt despite the saved 'Allow' permission,
- // because the connection isn't secure.
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- // Ensure that the 'Always Allow' action isn't shown.
- let alwaysLabel = gNavigatorBundle.getString("getUserMedia.always.label");
- ok(!!alwaysLabel, "found the 'Always Allow' localized label");
- let labels = [];
- let notification = PopupNotifications.panel.firstChild;
- for (let node of notification.childNodes) {
- if (node.localName == "menuitem")
- labels.push(node.getAttribute("label"));
- }
- is(labels.indexOf(alwaysLabel), -1, "The 'Always Allow' item isn't shown");
-
- // Cleanup.
- yield closeStream(true);
- Perms.remove(uri, "camera");
- Perms.remove(uri, "microphone");
- }
-}
-
-];
-
-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);
-
- 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]]});
-
- for (let test of gTests) {
- info(test.desc);
- yield test.run();
-
- // Cleanup before the next test
- yield expectNoObserverCalled();
- }
- }).then(finish, ex => {
- Cu.reportError(ex);
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
- }, true);
- let rootDir = getRootDirectory(gTestPath);
- rootDir = rootDir.replace("chrome://mochitests/content/",
- "https://example.com/");
- content.location = rootDir + "get_user_media.html";
-}
diff --git 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
deleted file mode 100644
index f407061a7..000000000
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-registerCleanupFunction(function() {
- gBrowser.removeCurrentTab();
-});
-
-var gTests = [
-
-{
- desc: "device sharing animation on background tabs",
- run: function* checkAudioVideo() {
- function* getStreamAndCheckBackgroundAnim(aAudio, aVideo, aSharing) {
- // Get a stream
- let popupPromise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(aAudio, aVideo);
- yield popupPromise;
- yield expectObserverCalled("getUserMedia:request");
-
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- let expected = [];
- if (aVideo)
- expected.push("Camera");
- if (aAudio)
- expected.push("Microphone");
- is((yield getMediaCaptureState()), expected.join("And"),
- "expected stream to be shared");
-
- // Check the attribute on the tab, and check there's no visible
- // sharing icon on the tab
- let tab = gBrowser.selectedTab;
- is(tab.getAttribute("sharing"), aSharing,
- "the tab has the attribute to show the " + aSharing + " icon");
- let icon =
- document.getAnonymousElementByAttribute(tab, "anonid", "sharing-icon");
- is(window.getComputedStyle(icon).display, "none",
- "the animated sharing icon of the tab is hidden");
-
- // After selecting a new tab, check the attribute is still there,
- // and the icon is now visible.
- yield BrowserTestUtils.switchTab(gBrowser, gBrowser.addTab());
- is(gBrowser.selectedTab.getAttribute("sharing"), "",
- "the new tab doesn't have the 'sharing' attribute");
- is(tab.getAttribute("sharing"), aSharing,
- "the tab still has the 'sharing' attribute");
- isnot(window.getComputedStyle(icon).display, "none",
- "the animated sharing icon of the tab is now visible");
-
- // Ensure the icon disappears when selecting the tab.
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- ok(tab.selected, "the tab with ongoing sharing is selected again");
- is(window.getComputedStyle(icon).display, "none",
- "the animated sharing icon is gone after selecting the tab again");
-
- // And finally verify the attribute is removed when closing the stream.
- yield closeStream();
-
- // TODO(Bug 1304997): Fix the race in closeStream() and remove this
- // promiseWaitForCondition().
- yield promiseWaitForCondition(() => !tab.getAttribute("sharing"));
- is(tab.getAttribute("sharing"), "",
- "the tab no longer has the 'sharing' attribute after closing the stream");
- }
-
- yield getStreamAndCheckBackgroundAnim(true, true, "camera");
- yield getStreamAndCheckBackgroundAnim(false, true, "camera");
- yield getStreamAndCheckBackgroundAnim(true, false, "microphone");
- }
-}
-
-];
-
-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);
-
- 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 test of gTests) {
- info(test.desc);
- yield test.run();
- }
- }).then(finish, ex => {
- Cu.reportError(ex);
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
- }, true);
- let rootDir = getRootDirectory(gTestPath);
- rootDir = rootDir.replace("chrome://mochitests/content/",
- "https://example.com/");
- content.location = rootDir + "get_user_media.html";
-}
diff --git 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
deleted file mode 100644
index 01a544aae..000000000
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_in_frame.js
+++ /dev/null
@@ -1,266 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-registerCleanupFunction(function() {
- gBrowser.removeCurrentTab();
-});
-
-function promiseReloadFrame(aFrameId) {
- return ContentTask.spawn(gBrowser.selectedBrowser, aFrameId, function*(aFrameId) {
- content.wrappedJSObject.document.getElementById(aFrameId).contentWindow.location.reload();
- });
-}
-
-var gTests = [
-
-{
- desc: "getUserMedia audio+video",
- run: function* checkAudioVideo() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true, "frame1");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
-
- is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
- "webRTC-shareDevices-notification-icon", "anchored to device icon");
- checkDeviceSelectors(true, true);
- is(PopupNotifications.panel.firstChild.getAttribute("popupid"),
- "webRTC-shareDevices", "panel using devices icon");
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({audio: true, video: true});
- yield closeStream(false, "frame1");
- }
-},
-
-{
- desc: "getUserMedia audio+video: stop sharing",
- run: function* checkStopSharing() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true, "frame1");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- activateSecondaryAction(kActionAlways);
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true, audio: true});
-
- let Perms = Services.perms;
- let uri = Services.io.newURI("https://example.com/", null, null);
- is(Perms.testExactPermission(uri, "microphone"), Perms.ALLOW_ACTION,
- "microphone persistently allowed");
- is(Perms.testExactPermission(uri, "camera"), Perms.ALLOW_ACTION,
- "camera persistently allowed");
-
- yield stopSharing();
-
- // The persistent permissions for the frame should have been removed.
- is(Perms.testExactPermission(uri, "microphone"), Perms.UNKNOWN_ACTION,
- "microphone not persistently allowed");
- is(Perms.testExactPermission(uri, "camera"), Perms.UNKNOWN_ACTION,
- "camera not persistently allowed");
-
- // the stream is already closed, but this will do some cleanup anyway
- yield closeStream(true, "frame1");
- }
-},
-
-{
- desc: "getUserMedia audio+video: reloading the frame removes all sharing UI",
- run: function* checkReloading() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true, "frame1");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true, audio: true});
-
- info("reloading the frame");
- promise = promiseObserverCalled("recording-device-events");
- yield promiseReloadFrame("frame1");
- yield promise;
-
- yield expectObserverCalled("recording-window-ended");
- yield expectNoObserverCalled();
- yield checkNotSharing();
- }
-},
-
-{
- desc: "getUserMedia audio+video: reloading the frame removes prompts",
- run: function* checkReloadingRemovesPrompts() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true, "frame1");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- info("reloading the frame");
- promise = promiseObserverCalled("recording-window-ended");
- yield promiseReloadFrame("frame1");
- yield promise;
- yield promiseNoPopupNotification("webRTC-shareDevices");
-
- yield expectNoObserverCalled();
- yield checkNotSharing();
- }
-},
-
-{
- desc: "getUserMedia audio+video: reloading a frame updates the sharing UI",
- run: function* checkUpdateWhenReloading() {
- // We'll share only the mic in the first frame, then share both in the
- // second frame, then reload the second frame. After each step, we'll check
- // the UI is in the correct state.
-
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, false, "frame1");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, false);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "Microphone", "microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: false, audio: true});
- yield expectNoObserverCalled();
-
- promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true, "frame2");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield checkSharingUI({video: true, audio: true});
- yield expectNoObserverCalled();
-
- info("reloading the second frame");
- promise = promiseObserverCalled("recording-device-events");
- yield promiseReloadFrame("frame2");
- yield promise;
-
- yield expectObserverCalled("recording-window-ended");
- yield checkSharingUI({video: false, audio: true});
- yield expectNoObserverCalled();
-
- yield closeStream(false, "frame1");
- yield expectNoObserverCalled();
- yield checkNotSharing();
- }
-},
-
-{
- desc: "getUserMedia audio+video: reloading the top level page removes all sharing UI",
- run: function* checkReloading() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true, "frame1");
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true, audio: true});
-
- info("reloading the web page");
- promise = promiseObserverCalled("recording-device-events");
- content.location.reload();
- yield promise;
-
- yield expectObserverCalled("recording-window-ended");
- yield expectNoObserverCalled();
- yield checkNotSharing();
- }
-}
-
-];
-
-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);
-
- 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 test of gTests) {
- info(test.desc);
- yield test.run();
-
- // Cleanup before the next test
- yield expectNoObserverCalled();
- }
- }).then(finish, ex => {
- Cu.reportError(ex);
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
- }, 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>'
-}
diff --git 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
deleted file mode 100644
index b19065371..000000000
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_tear_off_tab.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-registerCleanupFunction(function() {
- gBrowser.removeCurrentTab();
-});
-
-var gTests = [
-
-{
- desc: "getUserMedia: tearing-off a tab keeps sharing indicators",
- run: function* checkTearingOff() {
- let promise = promisePopupNotificationShown("webRTC-shareDevices");
- yield promiseRequestDevice(true, true);
- yield promise;
- yield expectObserverCalled("getUserMedia:request");
- checkDeviceSelectors(true, true);
-
- let indicator = promiseIndicatorWindow();
- yield promiseMessage("ok", () => {
- PopupNotifications.panel.firstChild.button.click();
- });
- yield expectObserverCalled("getUserMedia:response:allow");
- yield expectObserverCalled("recording-device-events");
- is((yield getMediaCaptureState()), "CameraAndMicrophone",
- "expected camera and microphone to be shared");
-
- yield indicator;
- yield checkSharingUI({video: true, audio: true});
-
- info("tearing off the tab");
- let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
- yield whenDelayedStartupFinished(win);
- yield checkSharingUI({audio: true, video: true}, win);
-
- // Clicking the global sharing indicator should open the control center in
- // the second window.
- ok(win.gIdentityHandler._identityPopup.hidden, "control center should be hidden");
- let activeStreams = webrtcUI.getActiveStreams(true, false, false);
- webrtcUI.showSharingDoorhanger(activeStreams[0], "Devices");
- ok(!win.gIdentityHandler._identityPopup.hidden,
- "control center should be open in the second window");
- ok(gIdentityHandler._identityPopup.hidden,
- "control center should be hidden in the first window");
- win.gIdentityHandler._identityPopup.hidden = true;
-
- // Closing the new window should remove all sharing indicators.
- // We need to load the content script in the first window so that we can
- // catch the notifications fired globally when closing the second window.
- gBrowser.selectedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
-
- let promises = [promiseObserverCalled("recording-device-events"),
- promiseObserverCalled("recording-window-ended")];
- yield BrowserTestUtils.closeWindow(win);
- yield Promise.all(promises);
-
- yield expectNoObserverCalled();
- yield checkNotSharing();
- }
-}
-
-];
-
-function test() {
- waitForExplicitFinish();
- SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, runTest);
-}
-
-function runTest() {
- // An empty tab where we can load the content script without leaving it
- // behind at the end of the test.
- 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);
-
- 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]]});
-
- for (let test of gTests) {
- info(test.desc);
- yield test.run();
-
- // Cleanup before the next test
- yield expectNoObserverCalled();
- }
- }).then(finish, ex => {
- Cu.reportError(ex);
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
- }, true);
- let rootDir = getRootDirectory(gTestPath);
- rootDir = rootDir.replace("chrome://mochitests/content/",
- "https://example.com/");
- content.location = rootDir + "get_user_media.html";
-}
diff --git a/browser/base/content/test/webrtc/get_user_media.html b/browser/base/content/test/webrtc/get_user_media.html
deleted file mode 100644
index 16303c62d..000000000
--- a/browser/base/content/test/webrtc/get_user_media.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><meta charset="UTF-8"></head>
-<body>
-<div id="message"></div>
-<script>
-// Specifies whether we are using fake streams to run this automation
-var useFakeStreams = true;
-try {
- var audioDevice = SpecialPowers.getCharPref("media.audio_loopback_dev");
- var videoDevice = SpecialPowers.getCharPref("media.video_loopback_dev");
- dump("TEST DEVICES: Using media devices:\n");
- dump("audio: " + audioDevice + "\nvideo: " + videoDevice + "\n");
- useFakeStreams = false;
-} catch (e) {
- dump("TEST DEVICES: No test devices found (in media.{audio,video}_loopback_dev, using fake streams.\n");
- useFakeStreams = true;
-}
-
-function message(m) {
- document.getElementById("message").innerHTML = m;
- window.parent.postMessage(m, "*");
-}
-
-var gStream;
-
-function requestDevice(aAudio, aVideo, aShare) {
- var opts = {video: aVideo, audio: aAudio};
- if (aShare) {
- opts.video = {
- mozMediaSource: aShare,
- mediaSource: aShare
- }
- } else if (useFakeStreams) {
- opts.fake = true;
- }
-
- window.navigator.mediaDevices.getUserMedia(opts)
- .then(stream => {
- gStream = stream;
- message("ok");
- }, err => message("error: " + err));
-}
-message("pending");
-
-function closeStream() {
- if (!gStream)
- return;
- gStream.getTracks().forEach(t => t.stop());
- gStream = null;
- message("closed");
-}
-</script>
-</body>
-</html>
diff --git a/browser/base/content/test/webrtc/get_user_media_content_script.js b/browser/base/content/test/webrtc/get_user_media_content_script.js
deleted file mode 100644
index 71b68d826..000000000
--- a/browser/base/content/test/webrtc/get_user_media_content_script.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
- "@mozilla.org/mediaManagerService;1",
- "nsIMediaManagerService");
-
-const kObservedTopics = [
- "getUserMedia:response:allow",
- "getUserMedia:revoke",
- "getUserMedia:response:deny",
- "getUserMedia:request",
- "recording-device-events",
- "recording-window-ended"
-];
-
-var gObservedTopics = {};
-function observer(aSubject, aTopic, aData) {
- if (!(aTopic in gObservedTopics))
- gObservedTopics[aTopic] = 1;
- else
- ++gObservedTopics[aTopic];
-}
-
-kObservedTopics.forEach(topic => {
- Services.obs.addObserver(observer, topic, false);
-});
-
-addMessageListener("Test:ExpectObserverCalled", ({data}) => {
- sendAsyncMessage("Test:ExpectObserverCalled:Reply",
- {count: gObservedTopics[data]});
- if (data in gObservedTopics)
- --gObservedTopics[data];
-});
-
-addMessageListener("Test:ExpectNoObserverCalled", data => {
- sendAsyncMessage("Test:ExpectNoObserverCalled:Reply", gObservedTopics);
- gObservedTopics = {};
-});
-
-function _getMediaCaptureState() {
- let hasVideo = {};
- let hasAudio = {};
- let hasScreenShare = {};
- let hasWindowShare = {};
- MediaManagerService.mediaCaptureWindowState(content, hasVideo, hasAudio,
- hasScreenShare, hasWindowShare);
- if (hasVideo.value && hasAudio.value)
- return "CameraAndMicrophone";
- if (hasVideo.value)
- return "Camera";
- if (hasAudio.value)
- return "Microphone";
- if (hasScreenShare.value)
- return "Screen";
- if (hasWindowShare.value)
- return "Window";
- return "none";
-}
-
-addMessageListener("Test:GetMediaCaptureState", data => {
- sendAsyncMessage("Test:MediaCaptureState", _getMediaCaptureState());
-});
-
-addMessageListener("Test:WaitForObserverCall", ({data}) => {
- let topic = data;
- Services.obs.addObserver(function observer() {
- sendAsyncMessage("Test:ObserverCalled", topic);
- Services.obs.removeObserver(observer, topic);
-
- if (kObservedTopics.indexOf(topic) != -1) {
- if (!(topic in gObservedTopics))
- gObservedTopics[topic] = -1;
- else
- --gObservedTopics[topic];
- }
- }, topic, false);
-});
-
-addMessageListener("Test:WaitForMessage", () => {
- content.addEventListener("message", ({data}) => {
- sendAsyncMessage("Test:MessageReceived", data);
- }, {once: true});
-});
diff --git a/browser/base/content/test/webrtc/head.js b/browser/base/content/test/webrtc/head.js
deleted file mode 100644
index 70b183773..000000000
--- a/browser/base/content/test/webrtc/head.js
+++ /dev/null
@@ -1,453 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-
-const PREF_PERMISSION_FAKE = "media.navigator.permission.fake";
-const CONTENT_SCRIPT_HELPER = getRootDirectory(gTestPath) + "get_user_media_content_script.js";
-
-function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
- retryTimes = typeof retryTimes !== 'undefined' ? retryTimes : 30;
- var tries = 0;
- var interval = setInterval(function() {
- if (tries >= retryTimes) {
- ok(false, errorMsg);
- moveOn();
- }
- var conditionPassed;
- try {
- conditionPassed = condition();
- } catch (e) {
- ok(false, e + "\n" + e.stack);
- conditionPassed = false;
- }
- if (conditionPassed) {
- moveOn();
- }
- tries++;
- }, 100);
- var moveOn = function() { clearInterval(interval); nextTest(); };
-}
-
-function promiseWaitForCondition(aConditionFn) {
- let deferred = Promise.defer();
- waitForCondition(aConditionFn, deferred.resolve, "Condition didn't pass.");
- return deferred.promise;
-}
-
-/**
- * Waits for a window with the given URL to exist.
- *
- * @param url
- * The url of the window.
- * @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);
-
- if (win.location.href !== url) {
- info("ignoring a window with this url: " + win.location.href);
- return;
- }
-
- Services.obs.removeObserver(obs, "domwindowopened");
- resolve(win);
- });
- }, "domwindowopened", false);
- });
-}
-
-function whenDelayedStartupFinished(aWindow) {
- return new Promise(resolve => {
- info("Waiting for delayed startup to finish");
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- resolve();
- }
- }, "browser-delayed-startup-finished", false);
- });
-}
-
-function promiseIndicatorWindow() {
- // We don't show the indicator window on Mac.
- if ("nsISystemStatusBar" in Ci)
- return Promise.resolve();
-
- return promiseWindow("chrome://browser/content/webrtcIndicator.xul");
-}
-
-function* assertWebRTCIndicatorStatus(expected) {
- let ui = Cu.import("resource:///modules/webrtcUI.jsm", {}).webrtcUI;
- let expectedState = expected ? "visible" : "hidden";
- let msg = "WebRTC indicator " + expectedState;
- if (!expected && ui.showGlobalIndicator) {
- // It seems the global indicator is not always removed synchronously
- // in some cases.
- info("waiting for the global indicator to be hidden");
- yield promiseWaitForCondition(() => !ui.showGlobalIndicator);
- }
- is(ui.showGlobalIndicator, !!expected, msg);
-
- let expectVideo = false, expectAudio = false, expectScreen = false;
- if (expected) {
- if (expected.video)
- expectVideo = true;
- if (expected.audio)
- expectAudio = true;
- if (expected.screen)
- expectScreen = true;
- }
- is(ui.showCameraIndicator, expectVideo, "camera global indicator as expected");
- is(ui.showMicrophoneIndicator, expectAudio, "microphone global indicator as expected");
- is(ui.showScreenSharingIndicator, expectScreen, "screen global indicator as expected");
-
- let windows = Services.wm.getEnumerator("navigator:browser");
- while (windows.hasMoreElements()) {
- let win = windows.getNext();
- let menu = win.document.getElementById("tabSharingMenu");
- is(menu && !menu.hidden, !!expected, "WebRTC menu should be " + expectedState);
- }
-
- if (!("nsISystemStatusBar" in Ci)) {
- if (!expected) {
- let win = Services.wm.getMostRecentWindow("Browser:WebRTCGlobalIndicator");
- if (win) {
- yield new Promise((resolve, reject) => {
- win.addEventListener("unload", function listener(e) {
- if (e.target == win.document) {
- win.removeEventListener("unload", listener);
- resolve();
- }
- }, false);
- });
- }
- }
- let indicator = Services.wm.getEnumerator("Browser:WebRTCGlobalIndicator");
- let hasWindow = indicator.hasMoreElements();
- is(hasWindow, !!expected, "popup " + msg);
- if (hasWindow) {
- let document = indicator.getNext().document;
- let docElt = document.documentElement;
-
- if (document.readyState != "complete") {
- info("Waiting for the sharing indicator's document to load");
- let deferred = Promise.defer();
- document.addEventListener("readystatechange",
- function onReadyStateChange() {
- if (document.readyState != "complete")
- return;
- document.removeEventListener("readystatechange", onReadyStateChange);
- deferred.resolve();
- });
- yield deferred.promise;
- }
-
- for (let item of ["video", "audio", "screen"]) {
- let expectedValue = (expected && expected[item]) ? "true" : "";
- is(docElt.getAttribute("sharing" + item), expectedValue,
- item + " global indicator attribute as expected");
- }
-
- ok(!indicator.hasMoreElements(), "only one global indicator window");
- }
- }
-}
-
-function promisePopupEvent(popup, eventSuffix) {
- let endState = {shown: "open", hidden: "closed"}[eventSuffix];
-
- if (popup.state == endState)
- return Promise.resolve();
-
- let eventType = "popup" + eventSuffix;
- let deferred = Promise.defer();
- popup.addEventListener(eventType, function onPopupShown(event) {
- popup.removeEventListener(eventType, onPopupShown);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
-function promiseNotificationShown(notification) {
- let win = notification.browser.ownerGlobal;
- if (win.PopupNotifications.panel.state == "open") {
- return Promise.resolve();
- }
- let panelPromise = promisePopupEvent(win.PopupNotifications.panel, "shown");
- notification.reshow();
- return panelPromise;
-}
-
-function _mm() {
- return gBrowser.selectedBrowser.messageManager;
-}
-
-function promiseObserverCalled(aTopic) {
- return new Promise(resolve => {
- let mm = _mm();
- mm.addMessageListener("Test:ObserverCalled", function listener({data}) {
- if (data == aTopic) {
- ok(true, "got " + aTopic + " notification");
- mm.removeMessageListener("Test:ObserverCalled", listener);
- resolve();
- }
- });
- mm.sendAsyncMessage("Test:WaitForObserverCall", aTopic);
- });
-}
-
-function expectObserverCalled(aTopic) {
- return new Promise(resolve => {
- let mm = _mm();
- mm.addMessageListener("Test:ExpectObserverCalled:Reply",
- function listener({data}) {
- is(data.count, 1, "expected notification " + aTopic);
- mm.removeMessageListener("Test:ExpectObserverCalled:Reply", listener);
- resolve();
- });
- mm.sendAsyncMessage("Test:ExpectObserverCalled", aTopic);
- });
-}
-
-function expectNoObserverCalled() {
- return new Promise(resolve => {
- let mm = _mm();
- mm.addMessageListener("Test:ExpectNoObserverCalled:Reply",
- function listener({data}) {
- mm.removeMessageListener("Test:ExpectNoObserverCalled:Reply", listener);
- for (let topic in data) {
- if (data[topic])
- is(data[topic], 0, topic + " notification unexpected");
- }
- resolve();
- });
- mm.sendAsyncMessage("Test:ExpectNoObserverCalled");
- });
-}
-
-function promiseMessage(aMessage, aAction) {
- let promise = new Promise((resolve, reject) => {
- let mm = _mm();
- mm.addMessageListener("Test:MessageReceived", function listener({data}) {
- is(data, aMessage, "received " + aMessage);
- if (data == aMessage)
- resolve();
- else
- reject();
- mm.removeMessageListener("Test:MessageReceived", listener);
- });
- mm.sendAsyncMessage("Test:WaitForMessage");
- });
-
- if (aAction)
- aAction();
-
- return promise;
-}
-
-function promisePopupNotificationShown(aName, aAction) {
- let deferred = Promise.defer();
-
- PopupNotifications.panel.addEventListener("popupshown", function popupNotifShown() {
- PopupNotifications.panel.removeEventListener("popupshown", popupNotifShown);
-
- ok(!!PopupNotifications.getNotification(aName), aName + " notification shown");
- ok(PopupNotifications.isPanelOpen, "notification panel open");
- ok(!!PopupNotifications.panel.firstChild, "notification panel populated");
-
- deferred.resolve();
- });
-
- if (aAction)
- aAction();
-
- return deferred.promise;
-}
-
-function promisePopupNotification(aName) {
- let deferred = Promise.defer();
-
- waitForCondition(() => PopupNotifications.getNotification(aName),
- () => {
- ok(!!PopupNotifications.getNotification(aName),
- aName + " notification appeared");
-
- deferred.resolve();
- }, "timeout waiting for popup notification " + aName);
-
- return deferred.promise;
-}
-
-function promiseNoPopupNotification(aName) {
- let deferred = Promise.defer();
-
- waitForCondition(() => !PopupNotifications.getNotification(aName),
- () => {
- ok(!PopupNotifications.getNotification(aName),
- aName + " notification removed");
- deferred.resolve();
- }, "timeout waiting for popup notification " + aName + " to disappear");
-
- return deferred.promise;
-}
-
-const kActionAlways = 1;
-const kActionDeny = 2;
-const kActionNever = 3;
-
-function activateSecondaryAction(aAction) {
- let notification = PopupNotifications.panel.firstChild;
- notification.button.focus();
- let popup = notification.menupopup;
- popup.addEventListener("popupshown", function () {
- popup.removeEventListener("popupshown", arguments.callee, false);
-
- // Press 'down' as many time as needed to select the requested action.
- while (aAction--)
- EventUtils.synthesizeKey("VK_DOWN", {});
-
- // Activate
- EventUtils.synthesizeKey("VK_RETURN", {});
- }, false);
-
- // One down event to open the popup
- EventUtils.synthesizeKey("VK_DOWN",
- { altKey: !navigator.platform.includes("Mac") });
-}
-
-function getMediaCaptureState() {
- return new Promise(resolve => {
- let mm = _mm();
- mm.addMessageListener("Test:MediaCaptureState", ({data}) => {
- resolve(data);
- });
- mm.sendAsyncMessage("Test:GetMediaCaptureState");
- });
-}
-
-function* stopSharing(aType = "camera") {
- let promiseRecordingEvent = promiseObserverCalled("recording-device-events");
- gIdentityHandler._identityBox.click();
- let permissions = document.getElementById("identity-popup-permission-list");
- let cancelButton =
- permissions.querySelector(".identity-popup-permission-icon." + aType + "-icon ~ " +
- ".identity-popup-permission-remove-button");
- cancelButton.click();
- gIdentityHandler._identityPopup.hidden = true;
- yield promiseRecordingEvent;
- yield expectObserverCalled("getUserMedia:revoke");
- yield expectObserverCalled("recording-window-ended");
- yield expectNoObserverCalled();
- yield* checkNotSharing();
-}
-
-function promiseRequestDevice(aRequestAudio, aRequestVideo, aFrameId, aType) {
- info("requesting devices");
- return ContentTask.spawn(gBrowser.selectedBrowser,
- {aRequestAudio, aRequestVideo, aFrameId, aType},
- function*(args) {
- let global = content.wrappedJSObject;
- if (args.aFrameId)
- global = global.document.getElementById(args.aFrameId).contentWindow;
- global.requestDevice(args.aRequestAudio, args.aRequestVideo, args.aType);
- });
-}
-
-function* closeStream(aAlreadyClosed, aFrameId) {
- yield expectNoObserverCalled();
-
- let promises;
- if (!aAlreadyClosed) {
- promises = [promiseObserverCalled("recording-device-events"),
- promiseObserverCalled("recording-window-ended")];
- }
-
- info("closing the stream");
- yield ContentTask.spawn(gBrowser.selectedBrowser, aFrameId, function*(aFrameId) {
- let global = content.wrappedJSObject;
- if (aFrameId)
- global = global.document.getElementById(aFrameId).contentWindow;
- global.closeStream();
- });
-
- if (promises)
- yield Promise.all(promises);
-
- yield* assertWebRTCIndicatorStatus(null);
-}
-
-function checkDeviceSelectors(aAudio, aVideo) {
- let micSelector = document.getElementById("webRTC-selectMicrophone");
- if (aAudio)
- ok(!micSelector.hidden, "microphone selector visible");
- else
- ok(micSelector.hidden, "microphone selector hidden");
-
- let cameraSelector = document.getElementById("webRTC-selectCamera");
- if (aVideo)
- ok(!cameraSelector.hidden, "camera selector visible");
- else
- ok(cameraSelector.hidden, "camera selector hidden");
-}
-
-function* checkSharingUI(aExpected, aWin = window) {
- let doc = aWin.document;
- // First check the icon above the control center (i) icon.
- let identityBox = doc.getElementById("identity-box");
- ok(identityBox.hasAttribute("sharing"), "sharing attribute is set");
- let sharing = identityBox.getAttribute("sharing");
- if (aExpected.video)
- is(sharing, "camera", "showing camera icon on the control center icon");
- else if (aExpected.audio)
- is(sharing, "microphone", "showing mic icon on the control center icon");
-
- // Then check the sharing indicators inside the control center panel.
- identityBox.click();
- let permissions = doc.getElementById("identity-popup-permission-list");
- for (let id of ["microphone", "camera", "screen"]) {
- let convertId = id => {
- if (id == "camera")
- return "video";
- if (id == "microphone")
- return "audio";
- return id;
- };
- let expected = aExpected[convertId(id)];
- is(!!aWin.gIdentityHandler._sharingState[id], !!expected,
- "sharing state for " + id + " as expected");
- let icon = permissions.querySelectorAll(
- ".identity-popup-permission-icon." + id + "-icon");
- if (expected) {
- is(icon.length, 1, "should show " + id + " icon in control center panel");
- ok(icon[0].classList.contains("in-use"), "icon should have the in-use class");
- } else if (!icon.length) {
- ok(true, "should not show " + id + " icon in the control center panel");
- } else {
- // This will happen if there are persistent permissions set.
- ok(!icon[0].classList.contains("in-use"),
- "if shown, the " + id + " icon should not have the in-use class");
- is(icon.length, 1, "should not show more than 1 " + id + " icon");
- }
- }
- aWin.gIdentityHandler._identityPopup.hidden = true;
-
- // Check the global indicators.
- yield* assertWebRTCIndicatorStatus(aExpected);
-}
-
-function* checkNotSharing() {
- is((yield getMediaCaptureState()), "none", "expected nothing to be shared");
-
- ok(!document.getElementById("identity-box").hasAttribute("sharing"),
- "no sharing indicator on the control center icon");
-
- yield* assertWebRTCIndicatorStatus(null);
-}
diff --git a/browser/base/moz.build b/browser/base/moz.build
index 466349992..b21c0ac29 100644
--- a/browser/base/moz.build
+++ b/browser/base/moz.build
@@ -4,34 +4,6 @@
# 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/.
-SPHINX_TREES['sslerrorreport'] = 'content/docs/sslerrorreport'
-
-MOCHITEST_MANIFESTS += [
- 'content/test/general/mochitest.ini',
-]
-
-MOCHITEST_CHROME_MANIFESTS += [
- 'content/test/chrome/chrome.ini',
-]
-
-BROWSER_CHROME_MANIFESTS += [
- 'content/test/alerts/browser.ini',
- 'content/test/captivePortal/browser.ini',
- 'content/test/general/browser.ini',
- 'content/test/newtab/browser.ini',
- 'content/test/plugins/browser.ini',
- 'content/test/popupNotifications/browser.ini',
- 'content/test/popups/browser.ini',
- 'content/test/referrer/browser.ini',
- 'content/test/siteIdentity/browser.ini',
- 'content/test/social/browser.ini',
- 'content/test/tabcrashed/browser.ini',
- 'content/test/tabPrompts/browser.ini',
- 'content/test/tabs/browser.ini',
- 'content/test/urlbar/browser.ini',
- 'content/test/webrtc/browser.ini',
-]
-
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
diff --git a/browser/branding/official/pref/firefox-branding.js b/browser/branding/official/pref/firefox-branding.js
index 52aaa4f50..35be87314 100644
--- a/browser/branding/official/pref/firefox-branding.js
+++ b/browser/branding/official/pref/firefox-branding.js
@@ -32,3 +32,5 @@ pref("app.update.badgeWaitTime", 0);
// Number of usages of the web console or scratchpad.
// If this is less than 5, then pasting code into the web console or scratchpad is disabled
pref("devtools.selfxss.count", 0);
+
+pref("app.update.enabled", false);
diff --git a/browser/components/contextualidentity/moz.build b/browser/components/contextualidentity/moz.build
index 62d333db8..aac3a838c 100644
--- a/browser/components/contextualidentity/moz.build
+++ b/browser/components/contextualidentity/moz.build
@@ -4,11 +4,4 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser/browser.ini',
-]
-
JAR_MANIFESTS += ['jar.mn']
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Contextual Identity')
diff --git a/browser/components/contextualidentity/test/browser/.eslintrc.js b/browser/components/contextualidentity/test/browser/.eslintrc.js
deleted file mode 100644
index e25a6863e..000000000
--- a/browser/components/contextualidentity/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,11 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ],
-
- "rules": {
- "no-undef": "error"
- }
-};
diff --git a/browser/components/contextualidentity/test/browser/browser.ini b/browser/components/contextualidentity/test/browser/browser.ini
deleted file mode 100644
index 55083f8d2..000000000
--- a/browser/components/contextualidentity/test/browser/browser.ini
+++ /dev/null
@@ -1,30 +0,0 @@
-[DEFAULT]
-support-files =
- empty_file.html
- file_reflect_cookie_into_title.html
- favicon-normal32.png
- file_set_storages.html
- serviceworker.html
- worker.js
-
-[browser_aboutURLs.js]
-[browser_eme.js]
-[browser_favicon.js]
-[browser_forgetaboutsite.js]
-[browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js]
-[browser_forgetAPI_EME_forgetThisSite.js]
-[browser_forgetAPI_quota_clearStoragesForPrincipal.js]
-[browser_newtabButton.js]
-[browser_usercontext.js]
-[browser_usercontextid_tabdrop.js]
-skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276
-[browser_windowName.js]
-tags = openwindow
-[browser_windowOpen.js]
-tags = openwindow
-[browser_serviceworkers.js]
-[browser_broadcastchannel.js]
-[browser_blobUrl.js]
-[browser_middleClick.js]
-[browser_imageCache.js]
-[browser_count_and_remove.js]
diff --git a/browser/components/contextualidentity/test/browser/browser_aboutURLs.js b/browser/components/contextualidentity/test/browser/browser_aboutURLs.js
deleted file mode 100644
index 586bca37f..000000000
--- a/browser/components/contextualidentity/test/browser/browser_aboutURLs.js
+++ /dev/null
@@ -1,49 +0,0 @@
-"use strict";
-
-// For some about: URLs, they will take more time to load and cause timeout.
-// See Bug 1270998.
-requestLongerTimeout(2);
-
-add_task(function* () {
- let aboutURLs = [];
-
- // List of about: URLs that will initiate network requests.
- let networkURLs = [
- "credits",
- "telemetry" // about:telemetry will fetch Telemetry asynchrounously and takes
- // longer, we skip this for now.
- ];
-
- let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- for (let cid in Cc) {
- let result = cid.match(/@mozilla.org\/network\/protocol\/about;1\?what\=(.*)$/);
- if (!result) {
- continue;
- }
-
- let aboutType = result[1];
- let contract = "@mozilla.org/network/protocol/about;1?what=" + aboutType;
- try {
- let am = Cc[contract].getService(Ci.nsIAboutModule);
- let uri = ios.newURI("about:"+aboutType, null, null);
- let flags = am.getURIFlags(uri);
- if (!(flags & Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT) &&
- networkURLs.indexOf(aboutType) == -1) {
- aboutURLs.push(aboutType);
- }
- } catch (e) {
- // getService might have thrown if the component doesn't actually
- // implement nsIAboutModule
- }
- }
-
- for (let url of aboutURLs) {
- info("Loading about:" + url);
- let tab = gBrowser.addTab("about:"+url, {userContextId: 1});
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- ok(true, "Done loading about:" + url);
-
- yield BrowserTestUtils.removeTab(tab);
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_blobUrl.js b/browser/components/contextualidentity/test/browser/browser_blobUrl.js
deleted file mode 100644
index 8a441311e..000000000
--- a/browser/components/contextualidentity/test/browser/browser_blobUrl.js
+++ /dev/null
@@ -1,78 +0,0 @@
-"use strict";
-
-// Here we want to test that blob URLs are not available cross containers.
-
-const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
- + "contextualidentity/test/browser/empty_file.html";
-
-add_task(function* setup() {
- yield new Promise((resolve) => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]}, resolve);
- });
-});
-
-
-add_task(function* test() {
- info("Creating a tab with UCI = 1...");
- let tab1 = gBrowser.addTab(BASE_URI, {userContextId: 1});
- is(tab1.getAttribute('usercontextid'), 1, "New tab has UCI equal 1");
-
- let browser1 = gBrowser.getBrowserForTab(tab1);
- yield BrowserTestUtils.browserLoaded(browser1);
-
- let blobURL;
-
- info("Creating a blob URL...");
- yield ContentTask.spawn(browser1, null, function() {
- return Promise.resolve(content.window.URL.createObjectURL(new content.window.Blob([123])));
- }).then(newURL => { blobURL = newURL });
-
- info("Blob URL: " + blobURL);
-
- info("Creating a tab with UCI = 2...");
- let tab2 = gBrowser.addTab(BASE_URI, {userContextId: 2});
- is(tab2.getAttribute('usercontextid'), 2, "New tab has UCI equal 2");
-
- let browser2 = gBrowser.getBrowserForTab(tab2);
- yield BrowserTestUtils.browserLoaded(browser2);
-
- yield ContentTask.spawn(browser2, blobURL, function(url) {
- return new Promise(resolve => {
- var xhr = new content.window.XMLHttpRequest();
- xhr.onerror = function() { resolve("SendErrored"); }
- xhr.onload = function() { resolve("SendLoaded"); }
- xhr.open("GET", url);
- xhr.send();
- });
- }).then(status => {
- is(status, "SendErrored", "Using a blob URI from one user context id in another should not work");
- });
-
- info("Creating a tab with UCI = 1...");
- let tab3 = gBrowser.addTab(BASE_URI, {userContextId: 1});
- is(tab3.getAttribute('usercontextid'), 1, "New tab has UCI equal 1");
-
- let browser3 = gBrowser.getBrowserForTab(tab3);
- yield BrowserTestUtils.browserLoaded(browser3);
-
- yield ContentTask.spawn(browser3, blobURL, function(url) {
- return new Promise(resolve => {
- var xhr = new content.window.XMLHttpRequest();
- xhr.open("GET", url);
- try {
- xhr.send();
- resolve("SendSucceeded");
- } catch (e) {
- resolve("SendThrew");
- }
- });
- }).then(status => {
- is(status, "SendSucceeded", "Using a blob URI within a single user context id should work");
- });
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
- yield BrowserTestUtils.removeTab(tab3);
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_broadcastchannel.js b/browser/components/contextualidentity/test/browser/browser_broadcastchannel.js
deleted file mode 100644
index a821ce96b..000000000
--- a/browser/components/contextualidentity/test/browser/browser_broadcastchannel.js
+++ /dev/null
@@ -1,80 +0,0 @@
-let { classes: Cc, interfaces: Ci } = Components;
-
-const BASE_ORIGIN = "http://example.com";
-const URI = BASE_ORIGIN +
- "/browser/browser/components/contextualidentity/test/browser/empty_file.html";
-
-// opens `uri' in a new tab with the provided userContextId and focuses it.
-// returns the newly opened tab
-function* openTabInUserContext(uri, userContextId) {
- // open the tab in the correct userContextId
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // select tab and make sure its browser is focused
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]}, resolve);
- });
-});
-
-add_task(function* test() {
- let receiver = yield* openTabInUserContext(URI, 2);
-
- let channelName = "contextualidentity-broadcastchannel";
-
- // reflect the received message on title
- yield ContentTask.spawn(receiver.browser, channelName,
- function (name) {
- content.window.testPromise = new content.window.Promise(resolve => {
- content.window.bc = new content.window.BroadcastChannel(name);
- content.window.bc.onmessage = function (e) {
- content.document.title += e.data;
- resolve();
- }
- });
- }
- );
-
- let sender1 = yield* openTabInUserContext(URI, 1);
- let sender2 = yield* openTabInUserContext(URI, 2);
- sender1.message = "Message from user context #1";
- sender2.message = "Message from user context #2";
-
- // send a message from a tab in different user context first
- // then send a message from a tab in the same user context
- for (let sender of [sender1, sender2]) {
- yield ContentTask.spawn(
- sender.browser,
- { name: channelName, message: sender.message },
- function (opts) {
- let bc = new content.window.BroadcastChannel(opts.name);
- bc.postMessage(opts.message);
- });
- }
-
- // Since sender1 sends before sender2, if the title is exactly
- // sender2's message, sender1's message must've been blocked
- yield ContentTask.spawn(receiver.browser, sender2.message,
- function* (message) {
- yield content.window.testPromise.then(function() {
- is(content.document.title, message,
- "should only receive messages from the same user context");
- });
- }
- );
-
- gBrowser.removeTab(sender1.tab);
- gBrowser.removeTab(sender2.tab);
- gBrowser.removeTab(receiver.tab);
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_count_and_remove.js b/browser/components/contextualidentity/test/browser/browser_count_and_remove.js
deleted file mode 100644
index 23b7e948a..000000000
--- a/browser/components/contextualidentity/test/browser/browser_count_and_remove.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/ContextualIdentityService.jsm");
-
-function openTabInUserContext(userContextId) {
- let tab = gBrowser.addTab("about:blank", {userContextId});
- gBrowser.selectedTab = tab;
-}
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]});
-});
-
-add_task(function* test() {
- is(ContextualIdentityService.countContainerTabs(), 0, "0 container tabs by default.");
-
- openTabInUserContext(1);
- is(ContextualIdentityService.countContainerTabs(), 1, "1 container tab created");
-
- openTabInUserContext(1);
- is(ContextualIdentityService.countContainerTabs(), 2, "2 container tab created");
-
- openTabInUserContext(2);
- is(ContextualIdentityService.countContainerTabs(), 3, "3 container tab created");
-
- ContextualIdentityService.closeAllContainerTabs();
- is(ContextualIdentityService.countContainerTabs(), 0, "0 container tab at the end.");
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_eme.js b/browser/components/contextualidentity/test/browser/browser_eme.js
deleted file mode 100644
index 557648d60..000000000
--- a/browser/components/contextualidentity/test/browser/browser_eme.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Bug 1283325 - A test case to test the EME is originAttributes aware or not.
- */
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-const TEST_HOST = "example.com";
-const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
-
-const TESTKEY = {
- initDataType: 'keyids',
- initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"], "type":"persistent-license"}',
- kid: "LwVHf8JLtPrv2GUXFW2v_A",
- key: "97b9ddc459c8d5ff23c1f2754c95abe8",
- sessionType: 'persistent-license',
-};
-
-const USER_ID_DEFAULT = 0;
-const USER_ID_PERSONAL = 1;
-
-function* openTabInUserContext(uri, userContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerDocument.defaultView.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-function HexToBase64(hex)
-{
- var bin = "";
- for (var i = 0; i < hex.length; i += 2) {
- bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
- }
- return window.btoa(bin).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
-}
-
-function Base64ToHex(str)
-{
- var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/"));
- var res = "";
- for (var i = 0; i < bin.length; i++) {
- res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
- }
- return res;
-}
-
-function ByteArrayToHex(array) {
- let bin = String.fromCharCode.apply(null, new Uint8Array(array));
- let res = "";
-
- for (let i = 0; i < bin.length; i++) {
- res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
- }
-
- return res;
-}
-
-function generateKeyObject(aKid, aKey) {
- let keyObj = {
- kty: 'oct',
- kid: aKid,
- k: HexToBase64(aKey),
- };
-
- return new TextEncoder().encode(JSON.stringify({
- keys: [keyObj]
- }));
-}
-
-function generateKeyInfo(aData) {
- let keyInfo = {
- initDataType: aData.initDataType,
- initData: new TextEncoder().encode(aData.initData),
- sessionType: aData.sessionType,
- keyObj: generateKeyObject(aData.kid, aData.key),
- };
-
- return keyInfo;
-}
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- [ "privacy.userContext.enabled", true ],
- [ "media.mediasource.enabled", true ],
- [ "media.eme.apiVisible", true ],
- [ "media.mediasource.webm.enabled", true ],
- [ "media.clearkey.persistent-license.enabled", true ],
- ]}, resolve);
- });
-});
-
-add_task(function* test() {
- // Open a tab with the default container.
- let defaultContainer = yield openTabInUserContext(TEST_URL + "empty_file.html", USER_ID_DEFAULT);
-
- // Generate the key info for the default container.
- let keyInfo = generateKeyInfo(TESTKEY);
-
- // Update the media key for the default container.
- let result = yield ContentTask.spawn(defaultContainer.browser, keyInfo, function* (aKeyInfo) {
- let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
- [{
- initDataTypes: [aKeyInfo.initDataType],
- videoCapabilities: [{contentType: 'video/webm'}],
- sessionTypes: ['persistent-license'],
- persistentState: 'required',
- }]);
- let mediaKeys = yield access.createMediaKeys();
- let session = mediaKeys.createSession(aKeyInfo.sessionType);
- let res = {};
-
- // Insert the media key.
- yield new Promise(resolve => {
- session.addEventListener("message", function(event) {
- session.update(aKeyInfo.keyObj).then(
- () => { resolve(); }
- ).catch(
- () => {
- ok(false, "Update the media key fail.");
- resolve();
- }
- );
- });
-
- session.generateRequest(aKeyInfo.initDataType, aKeyInfo.initData);
- });
-
- let map = session.keyStatuses;
-
- is(map.size, 1, "One media key has been added.");
-
- if (map.size === 1) {
- res.keyId = map.keys().next().value;
- res.sessionId = session.sessionId;
- }
-
- // Close the session.
- session.close();
- yield session.closed;
-
- return res;
- });
-
- // Check the media key ID.
- is(ByteArrayToHex(result.keyId), Base64ToHex(TESTKEY.kid), "The key Id of the default container is correct.");
-
- // Store the sessionId for the further checking.
- keyInfo.sessionId = result.sessionId;
-
- // Open a tab with personal container.
- let personalContainer = yield openTabInUserContext(TEST_URL + "empty_file.html", USER_ID_PERSONAL);
-
- yield ContentTask.spawn(personalContainer.browser, keyInfo, function* (aKeyInfo) {
- let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
- [{
- initDataTypes: [aKeyInfo.initDataType],
- videoCapabilities: [{contentType: 'video/webm'}],
- sessionTypes: ['persistent-license'],
- persistentState: 'required',
- }]);
- let mediaKeys = yield access.createMediaKeys();
- let session = mediaKeys.createSession(aKeyInfo.sessionType);
-
- // First, load the session to check that mediakeys do not share with
- // default container.
- yield session.load(aKeyInfo.sessionId);
-
- let map = session.keyStatuses;
-
- // Check that there is no media key here.
- is(map.size, 0, "No media key should be here for the personal container.");
- });
-
- // Close default container tab.
- yield BrowserTestUtils.removeTab(defaultContainer.tab);
-
- // Close personal container tab.
- yield BrowserTestUtils.removeTab(personalContainer.tab);
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_favicon.js b/browser/components/contextualidentity/test/browser/browser_favicon.js
deleted file mode 100644
index a0a7eb208..000000000
--- a/browser/components/contextualidentity/test/browser/browser_favicon.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Bug 1270678 - A test case to test does the favicon obey originAttributes.
- */
-let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/PlacesUtils.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
-
-const USER_CONTEXTS = [
- "default",
- "personal",
- "work",
-];
-
-let gHttpServer = null;
-let gUserContextId;
-let gFaviconData;
-
-function getIconFile() {
- new Promise(resolve => {
- NetUtil.asyncFetch({
- uri: "http://www.example.com/browser/browser/components/contextualidentity/test/browser/favicon-normal32.png",
- loadUsingSystemPrincipal: true,
- contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE_FAVICON
- }, function(inputStream, status) {
- let size = inputStream.available();
- gFaviconData = NetUtil.readInputStreamToString(inputStream, size);
- resolve();
- });
- });
-}
-
-function* openTabInUserContext(uri, userContextId) {
- // open the tab in the correct userContextId
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // select tab and make sure its browser is focused
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-function loadIndexHandler(metadata, response) {
- response.setStatusLine(metadata.httpVersion, 200, "Ok");
- response.setHeader("Content-Type", "text/html", false);
- let body = `
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset='utf-8'>
- <title>Favicon Test</title>
- </head>
- <body>
- Favicon!!
- </body>
- </html>`;
- response.bodyOutputStream.write(body, body.length);
-}
-
-function loadFaviconHandler(metadata, response) {
- let expectedCookie = "userContext=" + USER_CONTEXTS[gUserContextId];
-
- if (metadata.hasHeader("Cookie")) {
- is(metadata.getHeader("Cookie"), expectedCookie, "The cookie has matched with the expected cookie.");
- } else {
- ok(false, "The request should have a cookie.");
- }
-
- response.setStatusLine(metadata.httpVersion, 200, "Ok");
- response.setHeader("Content-Type", "image/png", false);
- response.bodyOutputStream.write(gFaviconData, gFaviconData.length);
-}
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]}, resolve);
- });
-
- // Create a http server for the image cache test.
- if (!gHttpServer) {
- gHttpServer = new HttpServer();
- gHttpServer.registerPathHandler('/', loadIndexHandler);
- gHttpServer.registerPathHandler('/favicon.png', loadFaviconHandler);
- gHttpServer.start(-1);
- }
-});
-
-registerCleanupFunction(() => {
- gHttpServer.stop(() => {
- gHttpServer = null;
- });
-});
-
-add_task(function* test() {
- waitForExplicitFinish();
-
- // First, get the icon data.
- yield getIconFile();
-
- let serverPort = gHttpServer.identity.primaryPort;
- let testURL = "http://localhost:" + serverPort + "/";
- let testFaviconURL = "http://localhost:" + serverPort + "/favicon.png";
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- gUserContextId = userContextId;
-
- // Load the page in 3 different contexts and set a cookie
- // which should only be visible in that context.
-
- // Open our tab in the given user context.
- let tabInfo = yield* openTabInUserContext(testURL, userContextId);
-
- // Write a cookie according to the userContext.
- yield ContentTask.spawn(tabInfo.browser, { userContext: USER_CONTEXTS[userContextId] }, function (arg) {
- content.document.cookie = "userContext=" + arg.userContext;
- });
-
- let pageURI = NetUtil.newURI(testURL);
- let favIconURI = NetUtil.newURI(testFaviconURL);
-
- yield new Promise(resolve => {
- PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, favIconURI,
- true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, {
- onComplete() {
- resolve();
- },
- },
- tabInfo.browser.contentPrincipal);
- });
-
- yield BrowserTestUtils.removeTab(tabInfo.tab);
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js b/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js
deleted file mode 100644
index 1a97448c0..000000000
--- a/browser/components/contextualidentity/test/browser/browser_forgetAPI_EME_forgetThisSite.js
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Bug 1278037 - A Test case for checking whether forgetting APIs are working for the media key.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-const TEST_HOST = "example.com";
-const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
-
-const USER_CONTEXTS = [
- "default",
- "personal",
-];
-
-const TEST_EME_KEY = {
- initDataType: 'keyids',
- initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"], "type":"persistent-license"}',
- kid: "LwVHf8JLtPrv2GUXFW2v_A",
- key: "97b9ddc459c8d5ff23c1f2754c95abe8",
- sessionType: 'persistent-license',
-};
-
-//
-// Support functions.
-//
-
-function* openTabInUserContext(uri, userContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-function HexToBase64(hex) {
- var bin = "";
- for (var i = 0; i < hex.length; i += 2) {
- bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
- }
- return window.btoa(bin).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
-}
-
-function Base64ToHex(str) {
- var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/"));
- var res = "";
- for (var i = 0; i < bin.length; i++) {
- res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
- }
- return res;
-}
-
-function ByteArrayToHex(array) {
- let bin = String.fromCharCode.apply(null, new Uint8Array(array));
- let res = "";
-
- for (let i = 0; i < bin.length; i++) {
- res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
- }
-
- return res;
-}
-
-function generateKeyObject(aKid, aKey) {
- let keyObj = {
- kty: 'oct',
- kid: aKid,
- k: HexToBase64(aKey),
- };
-
- return new TextEncoder().encode(JSON.stringify({
- keys: [keyObj]
- }));
-}
-
-function generateKeyInfo(aData) {
- let keyInfo = {
- initDataType: aData.initDataType,
- initData: new TextEncoder().encode(aData.initData),
- sessionType: aData.sessionType,
- keyObj: generateKeyObject(aData.kid, aData.key),
- };
-
- return keyInfo;
-}
-
-// Setup a EME key for the given browser, and return the sessionId.
-function* setupEMEKey(browser) {
- // Generate the key info.
- let keyInfo = generateKeyInfo(TEST_EME_KEY);
-
- // Setup the EME key.
- let result = yield ContentTask.spawn(browser, keyInfo, function* (aKeyInfo) {
- let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
- [{
- initDataTypes: [aKeyInfo.initDataType],
- videoCapabilities: [{contentType: 'video/webm'}],
- sessionTypes: ['persistent-license'],
- persistentState: 'required',
- }]);
- let mediaKeys = yield access.createMediaKeys();
- let session = mediaKeys.createSession(aKeyInfo.sessionType);
- let res = {};
-
- // Insert the EME key.
- yield new Promise(resolve => {
- session.addEventListener("message", function(event) {
- session.update(aKeyInfo.keyObj).then(
- () => { resolve(); }
- ).catch(
- () => {
- ok(false, "Update the EME key fail.");
- resolve();
- }
- );
- });
-
- session.generateRequest(aKeyInfo.initDataType, aKeyInfo.initData);
- });
-
- let map = session.keyStatuses;
-
- is(map.size, 1, "One EME key has been added.");
-
- if (map.size === 1) {
- res.keyId = map.keys().next().value;
- res.sessionId = session.sessionId;
- }
-
- // Close the session.
- session.close();
- yield session.closed;
-
- return res;
- });
-
- // Check the EME key ID.
- is(ByteArrayToHex(result.keyId), Base64ToHex(TEST_EME_KEY.kid), "The key Id is correct.");
- return result.sessionId;
-}
-
-// Check whether the EME key has been cleared.
-function* checkEMEKey(browser, emeSessionId) {
- // Generate the key info.
- let keyInfo = generateKeyInfo(TEST_EME_KEY);
- keyInfo.sessionId = emeSessionId;
-
- yield ContentTask.spawn(browser, keyInfo, function* (aKeyInfo) {
- let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
- [{
- initDataTypes: [aKeyInfo.initDataType],
- videoCapabilities: [{contentType: 'video/webm'}],
- sessionTypes: ['persistent-license'],
- persistentState: 'required',
- }]);
- let mediaKeys = yield access.createMediaKeys();
- let session = mediaKeys.createSession(aKeyInfo.sessionType);
-
- // First, load the session with the sessionId.
- yield session.load(aKeyInfo.sessionId);
-
- let map = session.keyStatuses;
-
- // Check that there is no media key here.
- is(map.size, 0, "No media key should be here after forgetThisSite() was called.");
- });
-}
-
-//
-// Test functions.
-//
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [
- [ "privacy.userContext.enabled", true ],
- [ "media.mediasource.enabled", true ],
- [ "media.eme.apiVisible", true ],
- [ "media.mediasource.webm.enabled", true ],
- [ "media.clearkey.persistent-license.enabled", true ],
- ]});
-});
-
-add_task(function* test_EME_forgetThisSite() {
- let tabs = [];
- let emeSessionIds = [];
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context.
- tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
-
- // Setup EME Key.
- emeSessionIds[userContextId] = yield setupEMEKey(tabs[userContextId].browser);
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-
- // Clear all EME data for a given domain with originAttributes pattern.
- let mps = Cc["@mozilla.org/gecko-media-plugin-service;1"].
- getService(Ci.mozIGeckoMediaPluginChromeService);
- mps.forgetThisSite(TEST_HOST, JSON.stringify({}));
-
- // Open tabs again to check EME keys have been cleared.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context.
- tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
-
- // Check whether EME Key has been cleared.
- yield checkEMEKey(tabs[userContextId].browser, emeSessionIds[userContextId]);
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js b/browser/components/contextualidentity/test/browser/browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js
deleted file mode 100644
index 1d9024d25..000000000
--- a/browser/components/contextualidentity/test/browser/browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Bug 1278037 - A Test case for checking whether forgetting APIs are working for cookies.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-const TEST_HOST = "example.com";
-const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
-
-const USER_CONTEXTS = [
- "default",
- "personal",
-];
-
-//
-// Support functions.
-//
-
-function* openTabInUserContext(uri, userContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-function getCookiesForOA(host, userContextId) {
- return Services.cookies.getCookiesFromHost(host, {userContextId});
-}
-
-//
-// Test functions.
-//
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [
- [ "privacy.userContext.enabled", true ],
- ]});
-});
-
-add_task(function* test_cookie_getCookiesWithOriginAttributes() {
- let tabs = [];
- let cookieName = "userContextId";
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Load the page in 2 different contexts and set a cookie
- // which should only be visible in that context.
- let value = USER_CONTEXTS[userContextId];
-
- // Open our tab in the given user context.
- tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "file_reflect_cookie_into_title.html?" + value, userContextId);
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-
- // Check that cookies have been set properly.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- let enumerator = getCookiesForOA(TEST_HOST, userContextId);
- ok(enumerator.hasMoreElements(), "Cookies available");
-
- let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
- is(foundCookie["name"], cookieName, "Check cookie name");
- is(foundCookie["value"], USER_CONTEXTS[userContextId], "Check cookie value");
- }
-
- // Using getCookiesWithOriginAttributes() to get all cookies for a certain
- // domain by using the originAttributes pattern, and clear all these cookies.
- let enumerator = Services.cookies.getCookiesWithOriginAttributes(JSON.stringify({}), TEST_HOST);
- while (enumerator.hasMoreElements()) {
- let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
- Services.cookies.remove(cookie.host, cookie.name, cookie.path, false, cookie.originAttributes);
- }
-
- // Check that whether cookies has been cleared.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- let enumerator = getCookiesForOA(TEST_HOST, userContextId);
- ok(!enumerator.hasMoreElements(), "No Cookie should be here");
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_forgetAPI_quota_clearStoragesForPrincipal.js b/browser/components/contextualidentity/test/browser/browser_forgetAPI_quota_clearStoragesForPrincipal.js
deleted file mode 100644
index 6a4b37c55..000000000
--- a/browser/components/contextualidentity/test/browser/browser_forgetAPI_quota_clearStoragesForPrincipal.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Bug 1278037 - A Test case for checking whether forgetting APIs are working for the quota manager.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-const TEST_HOST = "example.com";
-const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
-
-const USER_CONTEXTS = [
- "default",
- "personal",
-];
-
-//
-// Support functions.
-//
-
-function* openTabInUserContext(uri, userContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-// Setup an entry for the indexedDB.
-function* setupIndexedDB(browser) {
- yield ContentTask.spawn(browser, { input: "TestForgetAPIs" }, function* (arg) {
- let request = content.indexedDB.open("idb", 1);
-
- request.onerror = function() {
- throw new Error("error opening db connection");
- };
-
- request.onupgradeneeded = event => {
- let db = event.target.result;
- let store = db.createObjectStore("obj", { keyPath: "id" });
- store.createIndex("userContext", "userContext", { unique: false });
- };
-
- let db = yield new Promise(resolve => {
- request.onsuccess = event => {
- resolve(event.target.result);
- };
- });
-
- // Add an entry into the indexedDB.
- let transaction = db.transaction(["obj"], "readwrite");
- let store = transaction.objectStore("obj");
- store.add({id: 1, userContext: arg.input});
-
- yield new Promise(resolve => {
- transaction.oncomplete = () => {
- resolve();
- };
- });
-
- // Check the indexedDB has been set properly.
- transaction = db.transaction(["obj"], "readonly");
- store = transaction.objectStore("obj");
- let getRequest = store.get(1);
- yield new Promise(resolve => {
- getRequest.onsuccess = () => {
- let res = getRequest.result;
- is(res.userContext, arg.input, "Check the indexedDB value");
- resolve();
- };
- });
- });
-}
-
-// Check whether the indexedDB has been cleared.
-function* checkIndexedDB(browser) {
- yield ContentTask.spawn(browser, null, function* () {
- let request = content.indexedDB.open("idb", 1);
-
- let db = yield new Promise(done => {
- request.onsuccess = event => {
- done(event.target.result);
- };
- });
-
- try {
- db.transaction(["obj"], "readonly");
- ok(false, "The indexedDB should not exist");
- } catch (e) {
- is(e.name, "NotFoundError", "The indexedDB does not exist as expected");
- }
- });
-}
-
-//
-// Test functions.
-//
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [
- [ "privacy.userContext.enabled", true ],
- ]});
-});
-
-add_task(function* test_quota_clearStoragesForPrincipal() {
- let tabs = [];
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context.
- tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
-
- // Setup an entry for the indexedDB.
- yield setupIndexedDB(tabs[userContextId].browser);
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-
- // Using quota manager to clear all indexed DB for a given domain.
- let qms = Cc["@mozilla.org/dom/quota-manager-service;1"].
- getService(Ci.nsIQuotaManagerService);
-
- let caUtils = {};
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- scriptLoader.loadSubScript("chrome://global/content/contentAreaUtils.js",
- caUtils);
- let httpURI = caUtils.makeURI("http://" + TEST_HOST);
- let httpPrincipal = Services.scriptSecurityManager
- .createCodebasePrincipal(httpURI, {});
- qms.clearStoragesForPrincipal(httpPrincipal, null, true);
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context.
- tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "empty_file.html", userContextId);
-
- // Check whether indexed DB has been cleared.
- yield checkIndexedDB(tabs[userContextId].browser);
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_forgetaboutsite.js b/browser/components/contextualidentity/test/browser/browser_forgetaboutsite.js
deleted file mode 100644
index 9efc86e0c..000000000
--- a/browser/components/contextualidentity/test/browser/browser_forgetaboutsite.js
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Bug 1238183 - Test cases for forgetAboutSite with userContextId.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
-let LoadContextInfo = Cc["@mozilla.org/load-context-info-factory;1"]
- .getService(Ci.nsILoadContextInfoFactory);
-let css = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
-
-const USER_CONTEXTS = [
- "default",
- "personal",
-];
-const TEST_HOST = "example.com";
-const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
-const COOKIE_NAME = "userContextId";
-
-// Counter for image load hits.
-let gHits = 0;
-
-let gHttpServer = null;
-
-function imageHandler(metadata, response) {
- // A 1x1 PNG image.
- // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
- const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
- "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
- gHits++;
- response.setHeader("Cache-Control", "max-age=10000", false);
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "image/png", false);
- response.write(IMAGE);
-}
-
-function loadImagePageHandler(metadata, response) {
- response.setHeader("Cache-Control", "max-age=10000", false);
- response.setStatusLine(metadata.httpVersion, 200, "Ok");
- response.setHeader("Content-Type", "text/html", false);
- let body = "<!DOCTYPE HTML>\
- <html>\
- <head>\
- <meta charset='utf-8'>\
- <title>Load Image</title>\
- </head>\
- <body>\
- <img src='image.png'>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
-}
-
-function* openTabInUserContext(uri, userContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-function getCookiesForOA(host, userContextId) {
- return Services.cookies.getCookiesFromHost(host, {userContextId});
-}
-
-function createURI(uri)
-{
- let ioServ = Cc["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- return ioServ.newURI(uri, null, null);
-}
-
-function getCacheStorage(where, lci, appcache)
-{
- if (!lci) lci = LoadContextInfo.default;
- switch (where) {
- case "disk": return css.diskCacheStorage(lci, false);
- case "memory": return css.memoryCacheStorage(lci);
- case "appcache": return css.appCacheStorage(lci, appcache);
- case "pin": return css.pinningCacheStorage(lci);
- }
- return null;
-}
-
-function OpenCacheEntry(key, where, flags, lci)
-{
- return new Promise(resolve => {
- key = createURI(key);
- function CacheListener() { }
- CacheListener.prototype = {
- _appCache: null,
-
- QueryInterface: function (iid) {
- if (iid.equals(Components.interfaces.nsICacheEntryOpenCallback) ||
- iid.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_ERROR_NO_INTERFACE;
- },
-
- onCacheEntryCheck: function(entry, appCache) {
- return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
- },
-
- onCacheEntryAvailable: function (entry, isnew, appCache, status) {
- resolve();
- },
-
- run: function () {
- let storage = getCacheStorage(where, lci, this._appCache);
- storage.asyncOpenURI(key, "", flags, this);
- }
- };
-
- (new CacheListener()).run();
- });
-}
-
-//
-// Test functions.
-//
-
-// Cookies
-function* test_cookie_cleared() {
- let tabs = [];
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Load the page in 2 different contexts and set a cookie
- // which should only be visible in that context.
- let value = USER_CONTEXTS[userContextId];
-
- // Open our tab in the given user context.
- tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "file_reflect_cookie_into_title.html?" + value, userContextId);
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
- // Check that cookies have been set properly.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- let enumerator = getCookiesForOA(TEST_HOST, userContextId);
- ok(enumerator.hasMoreElements(), "Cookies available");
-
- let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
- Assert.equal(foundCookie["name"], COOKIE_NAME, "Check cookie name");
- Assert.equal(foundCookie["value"], USER_CONTEXTS[userContextId], "Check cookie value");
- }
-
- // Forget the site.
- ForgetAboutSite.removeDataFromDomain(TEST_HOST);
-
- // Check that whether cookies has been cleared or not.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- let enumerator = getCookiesForOA(TEST_HOST, userContextId);
- ok(!enumerator.hasMoreElements(), "No Cookie should be here");
- }
-}
-
-// Cache
-function* test_cache_cleared() {
- // First, add some caches.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- yield OpenCacheEntry("http://" + TEST_HOST + "/",
- "disk",
- Ci.nsICacheStorage.OPEN_NORMALLY,
- LoadContextInfo.custom(false, {userContextId}));
-
- yield OpenCacheEntry("http://" + TEST_HOST + "/",
- "memory",
- Ci.nsICacheStorage.OPEN_NORMALLY,
- LoadContextInfo.custom(false, {userContextId}));
- }
-
-
- // Check that caches have been set correctly.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- let mem = getCacheStorage("memory", LoadContextInfo.custom(false, {userContextId}));
- let disk = getCacheStorage("disk", LoadContextInfo.custom(false, {userContextId}));
-
- Assert.ok(mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache has been set correctly");
- Assert.ok(disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache has been set correctly");
- }
-
- // Forget the site.
- ForgetAboutSite.removeDataFromDomain(TEST_HOST);
-
- // Check that do caches be removed or not?
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- let mem = getCacheStorage("memory", LoadContextInfo.custom(false, {userContextId}));
- let disk = getCacheStorage("disk", LoadContextInfo.custom(false, {userContextId}));
-
- Assert.ok(!mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache is cleared");
- Assert.ok(!disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache is cleared");
- }
-}
-
-// Image Cache
-function* test_image_cache_cleared() {
- let tabs = [];
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context to cache image.
- tabs[userContextId] = yield* openTabInUserContext('http://localhost:' + gHttpServer.identity.primaryPort + '/loadImage.html',
- userContextId);
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-
- let expectedHits = USER_CONTEXTS.length;
-
- // Check that image cache works with the userContextId.
- is(gHits, expectedHits, "The image should be loaded" + expectedHits + "times.");
-
- // Reset the cache count.
- gHits = 0;
-
- // Forget the site.
- ForgetAboutSite.removeDataFromDomain("localhost:" + gHttpServer.identity.primaryPort + "/");
-
- // Load again.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context to cache image.
- tabs[userContextId] = yield* openTabInUserContext('http://localhost:' + gHttpServer.identity.primaryPort + '/loadImage.html',
- userContextId);
- yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
- }
-
- // Check that image cache was cleared and the server gets another two hits.
- is(gHits, expectedHits, "The image should be loaded" + expectedHits + "times.");
-}
-
-// Offline Storage
-function* test_storage_cleared() {
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Load the page in 2 different contexts and set the local storage
- // which should only be visible in that context.
- let value = USER_CONTEXTS[userContextId];
-
- // Open our tab in the given user context.
- let tabInfo = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html?" + value, userContextId);
-
- // Check that the storages has been set correctly.
- yield ContentTask.spawn(tabInfo.browser, { userContext: USER_CONTEXTS[userContextId] }, function* (arg) {
- // Check that the local storage has been set correctly.
- Assert.equal(content.localStorage.getItem("userContext"), arg.userContext, "Check the local storage value");
-
- // Check that the session storage has been set correctly.
- Assert.equal(content.sessionStorage.getItem("userContext"), arg.userContext, "Check the session storage value");
-
- // Check that the indexedDB has been set correctly.
- let request = content.indexedDB.open("idb", 1);
-
- let db = yield new Promise(done => {
- request.onsuccess = event => {
- done(event.target.result);
- };
- });
-
- let transaction = db.transaction(["obj"], "readonly");
- let store = transaction.objectStore("obj");
- let storeRequest = store.get(1);
-
- yield new Promise(done => {
- storeRequest.onsuccess = event => {
- let res = storeRequest.result;
- Assert.equal(res.userContext, arg.userContext, "Check the indexedDB value");
- done();
- };
- });
- });
-
- // Close this tab.
- yield BrowserTestUtils.removeTab(tabInfo.tab);
- }
-
- // Forget the site.
- ForgetAboutSite.removeDataFromDomain(TEST_HOST);
-
- // Open the tab again without setting the localStorage and check that the
- // local storage has been cleared or not.
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Open our tab in the given user context without setting local storage.
- let tabInfo = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html", userContextId);
-
- // Check that do storages be cleared or not.
- yield ContentTask.spawn(tabInfo.browser, null, function* () {
- // Check that does the local storage be cleared or not.
- Assert.ok(!content.localStorage.getItem("userContext"), "The local storage has been cleared");
-
- // Check that does the session storage be cleared or not.
- Assert.ok(!content.sessionStorage.getItem("userContext"), "The session storage has been cleared");
-
- // Check that does the indexedDB be cleared or not.
- let request = content.indexedDB.open("idb", 1);
-
- let db = yield new Promise(done => {
- request.onsuccess = event => {
- done(event.target.result);
- };
- });
- try {
- db.transaction(["obj"], "readonly");
- Assert.ok(false, "The indexedDB should not exist");
- } catch (e) {
- Assert.equal(e.name, "NotFoundError", "The indexedDB does not exist as expected");
- }
- });
-
- // Close the tab.
- yield BrowserTestUtils.removeTab(tabInfo.tab);
- }
-}
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]}, resolve);
- });
-
- // Create a http server for the image cache test.
- if (!gHttpServer) {
- gHttpServer = new HttpServer();
- gHttpServer.registerPathHandler('/image.png', imageHandler);
- gHttpServer.registerPathHandler('/loadImage.html', loadImagePageHandler);
- gHttpServer.start(-1);
- }
-});
-
-let tests = [
- test_cookie_cleared,
- test_cache_cleared,
- test_image_cache_cleared,
- test_storage_cleared,
-];
-
-add_task(function* test() {
- for (let i = 0; i < tests.length; i++)
- add_task(tests[i]);
-});
-
-registerCleanupFunction(() => {
- gHttpServer.stop(() => {
- gHttpServer = null;
- });
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_imageCache.js b/browser/components/contextualidentity/test/browser/browser_imageCache.js
deleted file mode 100644
index df36d44c1..000000000
--- a/browser/components/contextualidentity/test/browser/browser_imageCache.js
+++ /dev/null
@@ -1,59 +0,0 @@
-let Cu = Components.utils;
-let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
-
-const NUM_USER_CONTEXTS = 3;
-
-let gHits = 0;
-
-let server = new HttpServer();
-server.registerPathHandler('/image.png', imageHandler);
-server.registerPathHandler('/file.html', fileHandler);
-server.start(-1);
-
-let BASE_URI = 'http://localhost:' + server.identity.primaryPort;
-let IMAGE_URI = BASE_URI + '/image.png';
-let FILE_URI = BASE_URI + '/file.html';
-
-function imageHandler(metadata, response) {
- gHits++;
- response.setHeader("Cache-Control", "max-age=10000", false);
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "image/png", false);
- var body = "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
- response.bodyOutputStream.write(body, body.length);
-}
-
-function fileHandler(metadata, response) {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/html", false);
- let body = `<html><body><image src=${IMAGE_URI}></body></html>`;
- response.bodyOutputStream.write(body, body.length);
-}
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [["privacy.userContext.enabled", true]]});
-});
-
-// opens `uri' in a new tab with the provided userContextId and focuses it.
-// returns the newly opened tab
-function* openTabInUserContext(uri, userContextId) {
- // open the tab in the correct userContextId
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // select tab and make sure its browser is focused
- gBrowser.selectedTab = tab;
- tab.ownerDocument.defaultView.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return tab;
-}
-
-add_task(function* test() {
- for (let userContextId = 0; userContextId < NUM_USER_CONTEXTS; userContextId++) {
- let tab = yield* openTabInUserContext(FILE_URI, userContextId);
- gBrowser.removeTab(tab);
- }
- is(gHits, NUM_USER_CONTEXTS, "should get an image request for each user contexts");
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_middleClick.js b/browser/components/contextualidentity/test/browser/browser_middleClick.js
deleted file mode 100644
index f3bed2b53..000000000
--- a/browser/components/contextualidentity/test/browser/browser_middleClick.js
+++ /dev/null
@@ -1,41 +0,0 @@
-"use strict";
-
-const BASE_ORIGIN = "http://example.com";
-const URI = BASE_ORIGIN +
- "/browser/browser/components/contextualidentity/test/browser/empty_file.html";
-
-add_task(function* () {
- info("Opening a new container tab...");
-
- let tab = gBrowser.addTab(URI, { userContextId: 1 });
- gBrowser.selectedTab = tab;
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
-
- info("Create a HTMLAnchorElement...");
- yield ContentTask.spawn(browser, URI,
- function(URI) {
- let anchor = content.document.createElement("a");
- anchor.setAttribute('id', 'clickMe');
- 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);
- resolve(openEvent.target);
- })
-
- BrowserTestUtils.synthesizeMouseAtCenter("#clickMe", { button: 1 }, browser);
- });
-
- is(newTab.getAttribute("usercontextid"), 1, "Correct UserContextId?");
-
- yield BrowserTestUtils.removeTab(tab);
- yield BrowserTestUtils.removeTab(newTab);
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_newtabButton.js b/browser/components/contextualidentity/test/browser/browser_newtabButton.js
deleted file mode 100644
index 228e6f971..000000000
--- a/browser/components/contextualidentity/test/browser/browser_newtabButton.js
+++ /dev/null
@@ -1,35 +0,0 @@
-"use strict";
-
-// Testing that when the user opens the add tab menu and clicks menu items
-// the correct context id is opened
-
-add_task(function* test() {
- yield SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]});
-
- let newTab = document.getElementById('tabbrowser-tabs');
- let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
- ok(newTabButton, "New tab button exists");
- ok(!newTabButton.hidden, "New tab button is visible");
- yield BrowserTestUtils.waitForCondition(() => !!document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup"), "Wait for popup to exist");
- let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
-
- for (let i = 1; i <= 4; i++) {
- let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
-
- yield popupShownPromise;
- let contextIdItem = popup.querySelector(`menuitem[data-usercontextid="${i}"]`);
-
- ok(contextIdItem, `User context id ${i} exists`);
-
- let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
- EventUtils.synthesizeMouseAtCenter(contextIdItem, {});
-
- let tab = yield waitForTabPromise;
-
- is(tab.getAttribute('usercontextid'), i, `New tab has UCI equal ${i}`);
- yield BrowserTestUtils.removeTab(tab);
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_serviceworkers.js b/browser/components/contextualidentity/test/browser/browser_serviceworkers.js
deleted file mode 100644
index b074b91ac..000000000
--- a/browser/components/contextualidentity/test/browser/browser_serviceworkers.js
+++ /dev/null
@@ -1,108 +0,0 @@
-let { classes: Cc, interfaces: Ci } = Components;
-
-let swm = Cc["@mozilla.org/serviceworkers/manager;1"].
- getService(Ci.nsIServiceWorkerManager);
-
-const BASE_ORIGIN = "https://example.com";
-const URI = BASE_ORIGIN +
- "/browser/browser/components/contextualidentity/test/browser/serviceworker.html";
-const NUM_USER_CONTEXTS = 3;
-
-// opens `uri' in a new tab with the provided userContextId and focuses it.
-// returns the newly opened tab
-function openTabInUserContext(uri, userContextId) {
- // open the tab in the correct userContextId
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // select tab and make sure its browser is focused
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- return tab;
-}
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true],
- ["dom.serviceWorkers.enabled", true],
- ["dom.serviceWorkers.openWindow.enabled", true],
- ["dom.ipc.processCount", 1]
- ]}, resolve);
- });
-});
-
-let infos = [];
-
-add_task(function* test() {
- // Open the same URI in multiple user contexts, and make sure we have a
- // separate service worker in each of the contexts
- for (let userContextId = 0; userContextId < NUM_USER_CONTEXTS; userContextId++) {
- // Open a tab in given user contexts
- let tab = openTabInUserContext(URI, userContextId);
-
- // wait for tab load
- yield BrowserTestUtils.browserLoaded(gBrowser.getBrowserForTab(tab));
-
- // remove the tab
- gBrowser.removeTab(tab);
- }
-
- if (!allRegistered()) {
- yield promiseAllRegistered();
- }
- ok(true, "all service workers are registered");
-
- // Unregistered all service workers added in this test
- for (let info of infos) {
- yield promiseUnregister(info);
- }
-});
-
-function allRegistered() {
- let results = [];
- let registrations = swm.getAllRegistrations();
- for (let i = 0; i < registrations.length; i++) {
- let info = registrations.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
- let principal = info.principal;
- if (principal.originNoSuffix === BASE_ORIGIN) {
- results[principal.userContextId] = true;
- infos[principal.userContextId] = info;
- }
- }
- for (let userContextId = 0; userContextId < NUM_USER_CONTEXTS; userContextId++) {
- if (!results[userContextId]) {
- return false;
- }
- }
- return true;
-}
-
-function promiseAllRegistered() {
- return new Promise(function(resolve) {
- let listener = {
- onRegister: function() {
- if (allRegistered()) {
- swm.removeListener(listener);
- resolve();
- }
- }
- }
- swm.addListener(listener);
- });
-}
-
-function promiseUnregister(info) {
- return new Promise(function(resolve) {
- swm.unregister(info.principal, {
- unregisterSucceeded: function(aState) {
- ok(aState, "ServiceWorkerRegistration exists");
- resolve();
- },
- unregisterFailed: function(aState) {
- ok(false, "unregister should succeed");
- }
- }, info.scope);
- });
-}
diff --git a/browser/components/contextualidentity/test/browser/browser_usercontext.js b/browser/components/contextualidentity/test/browser/browser_usercontext.js
deleted file mode 100644
index e0e785d3f..000000000
--- a/browser/components/contextualidentity/test/browser/browser_usercontext.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-const USER_CONTEXTS = [
- "default",
- "personal",
- "work",
-];
-
-const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
- + "contextualidentity/test/browser/file_reflect_cookie_into_title.html";
-
-
-// opens `uri' in a new tab with the provided userContextId and focuses it.
-// returns the newly opened tab
-function openTabInUserContext(uri, userContextId) {
- // open the tab in the correct userContextId
- let tab = gBrowser.addTab(uri, {userContextId});
-
- // select tab and make sure its browser is focused
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- return tab;
-}
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true],
- ["dom.ipc.processCount", 1]
- ]}, resolve);
- });
-});
-
-add_task(function* test() {
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // load the page in 3 different contexts and set a cookie
- // which should only be visible in that context
- let cookie = USER_CONTEXTS[userContextId];
-
- // open our tab in the given user context
- let tab = openTabInUserContext(BASE_URI+"?"+cookie, userContextId);
-
- // wait for tab load
- yield BrowserTestUtils.browserLoaded(gBrowser.getBrowserForTab(tab));
-
- // remove the tab
- gBrowser.removeTab(tab);
- }
-
- {
- // Set a cookie in a different context so we can detect if that affects
- // cross-context properly. If we don't do that, we get an UNEXPECTED-PASS
- // for the localStorage case for the last tab we set.
- let tab = openTabInUserContext(BASE_URI+"?foo", 9999);
- yield BrowserTestUtils.browserLoaded(gBrowser.getBrowserForTab(tab));
- gBrowser.removeTab(tab);
- }
-
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Load the page without setting the cookie this time
- let expectedContext = USER_CONTEXTS[userContextId];
-
- let tab = openTabInUserContext(BASE_URI, userContextId);
-
- // wait for load
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
-
- // get the title
- let title = browser.contentDocument.title.trim().split("|");
-
- // check each item in the title and validate it meets expectatations
- for (let part of title) {
- let [storageMethodName, value] = part.split("=");
- is(value, expectedContext,
- "the title reflects the expected contextual identity of " +
- expectedContext + " for method " + storageMethodName + ": " + value);
- }
-
- gBrowser.removeTab(tab);
- }
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_usercontextid_tabdrop.js b/browser/components/contextualidentity/test/browser/browser_usercontextid_tabdrop.js
deleted file mode 100644
index 6a8fbc591..000000000
--- a/browser/components/contextualidentity/test/browser/browser_usercontextid_tabdrop.js
+++ /dev/null
@@ -1,134 +0,0 @@
-"use strict";
-
-let EventUtils = {};
-Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
-/**
- * Dragging an URL to a tab without userContextId set.
- */
-add_task(function* () {
- let tab = gBrowser.addTab("http://example.com/");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- let awaitDrop = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "drop");
- let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "http://test1.example.com/");
-
- // A drop type of "link" onto an existing tab would normally trigger a
- // load in that same tab, but tabbrowser code in _getDragTargetTab treats
- // drops on the outer edges of a tab differently (loading a new tab
- // instead). Make events created by synthesizeDrop have all of their
- // coordinates set to 0 (screenX/screenY), so they're treated as drops
- // on the outer edge of the tab, thus they open new tabs.
- let event = {
- clientX: 0,
- clientY: 0,
- screenX: 0,
- screenY: 0,
- };
- EventUtils.synthesizeDrop(tab, tab, [[{type: "text/plain", data: "http://test1.example.com/"}]], "link", window, undefined, event);
-
- yield awaitDrop;
-
- let tab2 = yield newTabPromise;
- Assert.ok(!tab2.hasAttribute("usercontextid"), "Tab shouldn't have usercontextid attribute");
-
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
-
- yield ContentTask.spawn(tab2.linkedBrowser, {}, function* () {
- Assert.equal(content.document.documentURI, "http://test1.example.com/");
- Assert.equal(content.document.nodePrincipal.originAttributes.userContextId, 0);
-
- // referrer is empty when urls are dragged to new or existing tabs.
- // If this changes in the future, it would be okay to send the referrer
- // in this case because we are creating a new tab with the default
- // usercontextid as the original tab.
- Assert.equal(content.document.referrer, "", "referrer should be empty");
- });
-
- yield BrowserTestUtils.removeTab(tab);
- yield BrowserTestUtils.removeTab(tab2);
-});
-
-/**
- * When dragging an URL to a new tab, the new tab should have the same
- * userContextId as the original tab.
- */
-add_task(function* () {
- let tab = gBrowser.addTab("http://example.com/", {userContextId: 1});
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- let awaitDrop = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "drop");
- let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "http://test1.example.com/");
-
- // A drop type of "link" onto an existing tab would normally trigger a
- // load in that same tab, but tabbrowser code in _getDragTargetTab treats
- // drops on the outer edges of a tab differently (loading a new tab
- // instead). Make events created by synthesizeDrop have all of their
- // coordinates set to 0 (screenX/screenY), so they're treated as drops
- // on the outer edge of the tab, thus they open new tabs.
- let event = {
- clientX: 0,
- clientY: 0,
- screenX: 0,
- screenY: 0,
- };
- EventUtils.synthesizeDrop(tab, tab, [[{type: "text/plain", data: "http://test1.example.com/"}]], "link", window, undefined, event);
-
- yield awaitDrop;
-
- let tab2 = yield newTabPromise;
- Assert.equal(tab2.getAttribute("usercontextid"), 1);
-
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
-
- yield ContentTask.spawn(tab2.linkedBrowser, {}, function* () {
- Assert.equal(content.document.documentURI, "http://test1.example.com/");
- Assert.equal(content.document.nodePrincipal.originAttributes.userContextId, 1);
-
- // referrer is empty when urls are dragged to new or existing tabs.
- // If this changes in the future, it would be okay to send the referrer
- // in this case because we are creating a new tab with the same
- // usercontextid as the original tab.
- Assert.equal(content.document.referrer, "", "referrer should be empty");
- });
-
- yield BrowserTestUtils.removeTab(tab);
- yield BrowserTestUtils.removeTab(tab2);
-});
-
-/**
- * When dragging a URL from one tab or link on a tab to an existing tab, the
- * existing tab should not change its userContextId.
- * Ex: if you drag a link from tab 1 with userContext 1 to tab 2 with
- * userContext 2, the link will open in tab 2 with userContext 2.
- */
-add_task(function* () {
- let tab = gBrowser.addTab("http://example.com/", {userContextId: 1});
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- let tab2 = gBrowser.addTab("http://example.org/", {userContextId: 2});
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
-
- let awaitDrop = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "drop");
-
- EventUtils.synthesizeDrop(tab, tab2, [[{type: "text/plain", data: "http://test1.example.com/"}]], "link", window);
-
- yield awaitDrop;
- Assert.equal(tab2.getAttribute("usercontextid"), 2);
-
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
-
- yield ContentTask.spawn(tab2.linkedBrowser, {}, function* () {
- Assert.equal(content.document.documentURI, "http://test1.example.com/");
- Assert.equal(content.document.nodePrincipal.originAttributes.userContextId, 2);
-
- // referrer is empty when urls are dragged to new or existing tabs.
- // If this changes in the future, we should ensure that we are not sending
- // a referrer for this case! When opening links across user contexts, we
- // don't want the referrer to follow the user from one context to another.
- Assert.equal(content.document.referrer, "", "referrer should be empty");
- });
-
- yield BrowserTestUtils.removeTab(tab);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_windowName.js b/browser/components/contextualidentity/test/browser/browser_windowName.js
deleted file mode 100644
index 555c421ce..000000000
--- a/browser/components/contextualidentity/test/browser/browser_windowName.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-const USER_CONTEXTS = [
- "default",
- "personal",
- "work",
-];
-
-const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
- + "contextualidentity/test/browser/empty_file.html";
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true],
- ["browser.link.open_newwindow", 3],
- ]}, resolve);
- });
-});
-
-add_task(function* test() {
- info("Creating first tab...");
- let tab1 = gBrowser.addTab(BASE_URI + '?old', {userContextId: 1});
- let browser1 = gBrowser.getBrowserForTab(tab1);
- yield BrowserTestUtils.browserLoaded(browser1);
- yield ContentTask.spawn(browser1, null, function(opts) {
- content.window.name = 'tab-1';
- });
-
- info("Creating second tab...");
- let tab2 = gBrowser.addTab(BASE_URI + '?old', {userContextId: 2});
- let browser2 = gBrowser.getBrowserForTab(tab2);
- yield BrowserTestUtils.browserLoaded(browser2);
- yield ContentTask.spawn(browser2, null, function(opts) {
- content.window.name = 'tab-2';
- });
-
- // Let's try to open a window from tab1 with a name 'tab-2'.
- info("Opening a window from the first tab...");
- yield ContentTask.spawn(browser1, { url: BASE_URI + '?new' }, function* (opts) {
- yield (new content.window.wrappedJSObject.Promise(resolve => {
- let w = content.window.wrappedJSObject.open(opts.url, 'tab-2');
- w.onload = function() { resolve(); }
- }));
- });
-
- is(browser1.contentTitle, '?old', "Tab1 title must be 'old'");
- is(browser1.contentPrincipal.userContextId, 1, "Tab1 UCI must be 1");
-
- is(browser2.contentTitle, '?old', "Tab2 title must be 'old'");
- is(browser2.contentPrincipal.userContextId, 2, "Tab2 UCI must be 2");
-
- let found = false;
- for (let i = 0; i < gBrowser.tabContainer.childNodes.length; ++i) {
- let tab = gBrowser.tabContainer.childNodes[i];
- let browser = gBrowser.getBrowserForTab(tab);
- if (browser.contentTitle == '?new') {
- is(browser.contentPrincipal.userContextId, 1, "Tab3 UCI must be 1");
- isnot(browser, browser1, "Tab3 is not browser 1");
- isnot(browser, browser2, "Tab3 is not browser 2");
- gBrowser.removeTab(tab);
- found = true;
- break;
- }
- }
-
- ok(found, "We have tab3");
-
- gBrowser.removeTab(tab1);
- gBrowser.removeTab(tab2);
-});
diff --git a/browser/components/contextualidentity/test/browser/browser_windowOpen.js b/browser/components/contextualidentity/test/browser/browser_windowOpen.js
deleted file mode 100644
index 00c6e0aa0..000000000
--- a/browser/components/contextualidentity/test/browser/browser_windowOpen.js
+++ /dev/null
@@ -1,41 +0,0 @@
-"use strict";
-
-// Here we want to test that a new opened window shows the same UI of the
-// parent one if this has been loaded from a particular container.
-
-const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
- + "contextualidentity/test/browser/empty_file.html";
-
-add_task(function* setup() {
- yield new Promise((resolve) => {
- SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true],
- ["browser.link.open_newwindow", 2],
- ]}, resolve);
- });
-});
-
-
-add_task(function* test() {
- info("Creating a tab with UCI = 1...");
- let tab = gBrowser.addTab(BASE_URI, {userContextId: 1});
- is(tab.getAttribute('usercontextid'), 1, "New tab has UCI equal 1");
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
-
- info("Opening a new window from this tab...");
- ContentTask.spawn(browser, BASE_URI, function(url) {
- content.window.newWindow = content.window.open(url, "_blank");
- });
-
- let newWin = yield BrowserTestUtils.waitForNewWindow();
- let newTab = newWin.gBrowser.selectedTab;
-
- yield BrowserTestUtils.browserLoaded(newTab.linkedBrowser);
- is(newTab.getAttribute('usercontextid'), 1, "New tab has UCI equal 1");
-
- info("Closing the new window and tab...");
- yield BrowserTestUtils.closeWindow(newWin);
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/contextualidentity/test/browser/empty_file.html b/browser/components/contextualidentity/test/browser/empty_file.html
deleted file mode 100644
index c6d11dcd5..000000000
--- a/browser/components/contextualidentity/test/browser/empty_file.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html><body>
-<script>
-document.title = window.location.search;
-</script>
-</body></html>
diff --git a/browser/components/contextualidentity/test/browser/favicon-normal32.png b/browser/components/contextualidentity/test/browser/favicon-normal32.png
deleted file mode 100644
index 5535363c9..000000000
--- a/browser/components/contextualidentity/test/browser/favicon-normal32.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html b/browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html
deleted file mode 100644
index b04f3fd5c..000000000
--- a/browser/components/contextualidentity/test/browser/file_reflect_cookie_into_title.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html>
- <head>
- <meta charset="UTF-8">
- <title>title not set</title>
- <script>
- // if we have a query string, use it to set the cookie and localStorage
- if (window.location.search.length > 0) {
- let context_name = window.location.search.substr(1);
- document.cookie = "userContextId=" + context_name;
- localStorage.setItem("userContext", context_name);
- }
-
- // get the cookie
- let [name, val] = document.cookie.split("=");
-
- // set the title to reflect the cookie and local storage values we find
- document.title = "cookie=" + val + "|"
- + "local=" + localStorage.getItem("userContext");
- </script>
- </head>
- <body></body>
-</html>
-
diff --git a/browser/components/contextualidentity/test/browser/file_set_storages.html b/browser/components/contextualidentity/test/browser/file_set_storages.html
deleted file mode 100644
index c6adcbdde..000000000
--- a/browser/components/contextualidentity/test/browser/file_set_storages.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<html>
- <head>
- <meta charset="UTF-8">
- <title>Bug 1238183</title>
- </head>
- <body>
- <script type="application/javascript;version=1.7">
- "use strict";
-
- // if we have a query string, use it to set storages
- if (window.location.search.length > 0) {
- let context_name = window.location.search.substr(1);
- localStorage.setItem("userContext", context_name);
- sessionStorage.setItem("userContext", context_name);
-
- let request = indexedDB.open("idb", 1);
-
- request.onerror = function() {
- throw new Error("error opening db connection");
- };
-
- request.onupgradeneeded = event => {
- let db = event.target.result;
- let store = db.createObjectStore("obj", { keyPath: "id" });
- store.createIndex("userContext", "userContext", { unique: false });
- };
-
- request.onsuccess = event => {
- let db = request.result;
- let transaction = db.transaction(["obj"], "readwrite");
- let store = transaction.objectStore("obj");
- store.add({id: 1, userContext: context_name});
-
- transaction.oncomplete = () => {
- db.close();
- };
- };
- }
- </script>
- </body>
-</html>
diff --git a/browser/components/contextualidentity/test/browser/serviceworker.html b/browser/components/contextualidentity/test/browser/serviceworker.html
deleted file mode 100644
index 11edd001a..000000000
--- a/browser/components/contextualidentity/test/browser/serviceworker.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <script>
- navigator.serviceWorker.register("worker.js");
- </script>
- </head>
- <body>
- This is a test page.
- </body>
-<html>
diff --git a/browser/components/contextualidentity/test/browser/worker.js b/browser/components/contextualidentity/test/browser/worker.js
deleted file mode 100644
index 2aba167d1..000000000
--- a/browser/components/contextualidentity/test/browser/worker.js
+++ /dev/null
@@ -1 +0,0 @@
-// empty worker, always succeed!
diff --git a/browser/components/customizableui/moz.build b/browser/components/customizableui/moz.build
index 72ec391d8..034630dc9 100644
--- a/browser/components/customizableui/moz.build
+++ b/browser/components/customizableui/moz.build
@@ -8,8 +8,6 @@ DIRS += [
'content',
]
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
-
EXTRA_JS_MODULES += [
'CustomizableUI.jsm',
'CustomizableWidgets.jsm',
@@ -21,6 +19,3 @@ EXTRA_JS_MODULES += [
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Toolbars and Customization')
diff --git a/browser/components/customizableui/test/.eslintrc.js b/browser/components/customizableui/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/customizableui/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/customizableui/test/browser.ini b/browser/components/customizableui/test/browser.ini
deleted file mode 100644
index 1c1f30498..000000000
--- a/browser/components/customizableui/test/browser.ini
+++ /dev/null
@@ -1,154 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
- support/test_967000_charEncoding_page.html
- support/feeds_test_page.html
- support/test-feed.xml
-
-[browser_873501_handle_specials.js]
-[browser_876926_customize_mode_wrapping.js]
-[browser_876944_customize_mode_create_destroy.js]
-[browser_877006_missing_view.js]
-[browser_877178_unregisterArea.js]
-[browser_877447_skip_missing_ids.js]
-[browser_878452_drag_to_panel.js]
-[browser_880164_customization_context_menus.js]
-[browser_880382_drag_wide_widgets_in_panel.js]
-[browser_884402_customize_from_overflow.js]
-skip-if = os == "linux"
-[browser_885052_customize_mode_observers_disabed.js]
-tags = fullscreen
-# Bug 951403 - Disabled on OSX for frequent failures
-skip-if = os == "mac"
-
-[browser_885530_showInPrivateBrowsing.js]
-[browser_886323_buildArea_removable_nodes.js]
-[browser_887438_currentset_shim.js]
-[browser_888817_currentset_updating.js]
-[browser_890140_orphaned_placeholders.js]
-[browser_890262_destroyWidget_after_add_to_panel.js]
-[browser_892955_isWidgetRemovable_for_removed_widgets.js]
-[browser_892956_destroyWidget_defaultPlacements.js]
-[browser_909779_overflow_toolbars_new_window.js]
-skip-if = os == "linux"
-
-[browser_901207_searchbar_in_panel.js]
-[browser_913972_currentset_overflow.js]
-skip-if = os == "linux"
-
-[browser_914138_widget_API_overflowable_toolbar.js]
-skip-if = os == "linux"
-
-[browser_914863_disabled_help_quit_buttons.js]
-[browser_918049_skipintoolbarset_dnd.js]
-[browser_923857_customize_mode_event_wrapping_during_reset.js]
-[browser_927717_customize_drag_empty_toolbar.js]
-
-# Bug 1163231 - Causes failures on Developer Edition on Windows 7.
-# [browser_932928_show_notice_when_palette_empty.js]
-
-[browser_934113_menubar_removable.js]
-# Because this test is about the menubar, it can't be run on mac
-skip-if = os == "mac"
-
-[browser_934951_zoom_in_toolbar.js]
-[browser_938980_navbar_collapsed.js]
-[browser_938995_indefaultstate_nonremovable.js]
-[browser_940013_registerToolbarNode_calls_registerArea.js]
-[browser_940307_panel_click_closure_handling.js]
-[browser_940946_removable_from_navbar_customizemode.js]
-[browser_941083_invalidate_wrapper_cache_createWidget.js]
-[browser_942581_unregisterArea_keeps_placements.js]
-[browser_943683_migration_test.js]
-[browser_944887_destroyWidget_should_destroy_in_palette.js]
-[browser_945739_showInPrivateBrowsing_customize_mode.js]
-[browser_947914_button_addons.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_copy.js]
-subsuite = clipboard
-skip-if = os == "linux" # Intermittent failures on Linux
-[browser_947914_button_cut.js]
-subsuite = clipboard
-skip-if = os == "linux" # Intermittent failures on Linux
-[browser_947914_button_find.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_history.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_newPrivateWindow.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_newWindow.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_paste.js]
-subsuite = clipboard
-skip-if = os == "linux" # Intermittent failures on Linux
-[browser_947914_button_print.js]
-skip-if = os == "linux" # Intermittent failures on Linux
-[browser_947914_button_savePage.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_zoomIn.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_zoomOut.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947914_button_zoomReset.js]
-skip-if = os == "linux" # Intermittent failures
-[browser_947987_removable_default.js]
-[browser_948985_non_removable_defaultArea.js]
-[browser_952963_areaType_getter_no_area.js]
-[browser_956602_remove_special_widget.js]
-[browser_962069_drag_to_overflow_chevron.js]
-[browser_962884_opt_in_disable_hyphens.js]
-[browser_963639_customizing_attribute_non_customizable_toolbar.js]
-[browser_967000_button_charEncoding.js]
-[browser_967000_button_feeds.js]
-[browser_967000_button_sync.js]
-[browser_968447_bookmarks_toolbar_items_in_panel.js]
-skip-if = os == "linux" # Intemittent failures - bug 979207
-[browser_968565_insert_before_hidden_items.js]
-[browser_969427_recreate_destroyed_widget_after_reset.js]
-[browser_969661_character_encoding_navbar_disabled.js]
-[browser_970511_undo_restore_default.js]
-[browser_972267_customizationchange_events.js]
-[browser_973641_button_addon.js]
-[browser_973932_addonbar_currentset.js]
-[browser_975719_customtoolbars_behaviour.js]
-[browser_976792_insertNodeInWindow.js]
-skip-if = os == "linux"
-[browser_978084_dragEnd_after_move.js]
-[browser_980155_add_overflow_toolbar.js]
-[browser_981305_separator_insertion.js]
-[browser_981418-widget-onbeforecreated-handler.js]
-[browser_982656_restore_defaults_builtin_widgets.js]
-[browser_984455_bookmarks_items_reparenting.js]
-skip-if = os == "linux"
-[browser_985815_propagate_setToolbarVisibility.js]
-[browser_987177_destroyWidget_xul.js]
-[browser_987177_xul_wrapper_updating.js]
-[browser_987185_syncButton.js]
-[browser_987492_window_api.js]
-[browser_987640_charEncoding.js]
-[browser_988072_sidebar_events.js]
-[browser_989338_saved_placements_not_resaved.js]
-[browser_989751_subviewbutton_class.js]
-[browser_992747_toggle_noncustomizable_toolbar.js]
-[browser_993322_widget_notoolbar.js]
-[browser_995164_registerArea_during_customize_mode.js]
-[browser_996364_registerArea_different_properties.js]
-[browser_996635_remove_non_widgets.js]
-[browser_1003588_no_specials_in_panel.js]
-[browser_1007336_lwthemes_in_customize_mode.js]
-skip-if = os == "linux" # crashing on Linux due to bug 1271683
-[browser_1008559_anchor_undo_restore.js]
-[browser_1042100_default_placements_update.js]
-[browser_1058573_showToolbarsDropdown.js]
-[browser_1087303_button_fullscreen.js]
-tags = fullscreen
-skip-if = os == "mac"
-[browser_1087303_button_preferences.js]
-[browser_1089591_still_customizable_after_reset.js]
-[browser_1096763_seen_widgets_post_reset.js]
-[browser_1161838_inserted_new_default_buttons.js]
-[browser_bootstrapped_custom_toolbar.js]
-[browser_customizemode_contextmenu_menubuttonstate.js]
-[browser_panel_toggle.js]
-[browser_switch_to_customize_mode.js]
-[browser_check_tooltips_in_navbar.js]
diff --git a/browser/components/customizableui/test/browser_1003588_no_specials_in_panel.js b/browser/components/customizableui/test/browser_1003588_no_specials_in_panel.js
deleted file mode 100644
index 22fbb5c0c..000000000
--- a/browser/components/customizableui/test/browser_1003588_no_specials_in_panel.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-function simulateItemDragAndEnd(aToDrag, aTarget) {
- var ds = Components.classes["@mozilla.org/widget/dragservice;1"].
- getService(Components.interfaces.nsIDragService);
-
- ds.startDragSession();
- try {
- var [result, dataTransfer] = EventUtils.synthesizeDragOver(aToDrag.parentNode, aTarget);
- EventUtils.synthesizeDropAfterDragOver(result, dataTransfer, aTarget);
- // Send dragend to move dragging item back to initial place.
- EventUtils.sendDragEvent({ type: "dragend", dataTransfer: dataTransfer },
- aToDrag.parentNode);
- } finally {
- ds.endDragSession(true);
- }
-}
-
-add_task(function* checkNoAddingToPanel() {
- let area = CustomizableUI.AREA_PANEL;
- let previousPlacements = getAreaWidgetIds(area);
- CustomizableUI.addWidgetToArea("separator", area);
- CustomizableUI.addWidgetToArea("spring", area);
- CustomizableUI.addWidgetToArea("spacer", area);
- assertAreaPlacements(area, previousPlacements);
-
- let oldNumberOfItems = previousPlacements.length;
- if (getAreaWidgetIds(area).length != oldNumberOfItems) {
- CustomizableUI.reset();
- }
-});
-
-add_task(function* checkAddingToToolbar() {
- let area = CustomizableUI.AREA_NAVBAR;
- let previousPlacements = getAreaWidgetIds(area);
- CustomizableUI.addWidgetToArea("separator", area);
- CustomizableUI.addWidgetToArea("spring", area);
- CustomizableUI.addWidgetToArea("spacer", area);
- let expectedPlacements = [...previousPlacements].concat([
- /separator/,
- /spring/,
- /spacer/
- ]);
- assertAreaPlacements(area, expectedPlacements);
-
- let newlyAddedElements = getAreaWidgetIds(area).slice(-3);
- while (newlyAddedElements.length) {
- CustomizableUI.removeWidgetFromArea(newlyAddedElements.shift());
- }
-
- assertAreaPlacements(area, previousPlacements);
-
- let oldNumberOfItems = previousPlacements.length;
- if (getAreaWidgetIds(area).length != oldNumberOfItems) {
- CustomizableUI.reset();
- }
-});
-
-
-add_task(function* checkDragging() {
- let startArea = CustomizableUI.AREA_NAVBAR;
- let targetArea = CustomizableUI.AREA_PANEL;
- let startingToolbarPlacements = getAreaWidgetIds(startArea);
- let startingTargetPlacements = getAreaWidgetIds(targetArea);
-
- CustomizableUI.addWidgetToArea("separator", startArea);
- CustomizableUI.addWidgetToArea("spring", startArea);
- CustomizableUI.addWidgetToArea("spacer", startArea);
-
- let placementsWithSpecials = getAreaWidgetIds(startArea);
- let elementsToMove = [];
- for (let id of placementsWithSpecials) {
- if (CustomizableUI.isSpecialWidget(id)) {
- elementsToMove.push(id);
- }
- }
- is(elementsToMove.length, 3, "Should have 3 elements to try and drag.");
-
- yield startCustomizing();
- for (let id of elementsToMove) {
- simulateItemDragAndEnd(document.getElementById(id), PanelUI.contents);
- }
-
- assertAreaPlacements(startArea, placementsWithSpecials);
- assertAreaPlacements(targetArea, startingTargetPlacements);
-
- for (let id of elementsToMove) {
- simulateItemDrag(document.getElementById(id), gCustomizeMode.visiblePalette);
- }
-
- assertAreaPlacements(startArea, startingToolbarPlacements);
- assertAreaPlacements(targetArea, startingTargetPlacements);
-
- ok(!gCustomizeMode.visiblePalette.querySelector("toolbarspring,toolbarseparator,toolbarspacer"),
- "No specials should make it to the palette alive.");
- yield endCustomizing();
-});
-
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- CustomizableUI.reset();
-});
-
diff --git a/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js b/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
deleted file mode 100644
index db4f88e6d..000000000
--- a/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
-const {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
-
-add_task(function* () {
- Services.prefs.clearUserPref("lightweightThemes.usedThemes");
- Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
- LightweightThemeManager.clearBuiltInThemes();
-
- yield startCustomizing();
-
- let themesButton = document.getElementById("customization-lwtheme-button");
- let popup = document.getElementById("customization-lwtheme-menu");
-
- let popupShownPromise = popupShown(popup);
- EventUtils.synthesizeMouseAtCenter(themesButton, {});
- info("Clicked on themes button");
- yield popupShownPromise;
-
- // close current tab and re-open Customize menu to confirm correct number of Themes
- yield endCustomizing();
- info("Exited customize mode");
- yield startCustomizing();
- info("Started customizing a second time");
- popupShownPromise = popupShown(popup);
- EventUtils.synthesizeMouseAtCenter(themesButton, {});
- info("Clicked on themes button a second time");
- yield popupShownPromise;
-
- let header = document.getElementById("customization-lwtheme-menu-header");
- let recommendedHeader = document.getElementById("customization-lwtheme-menu-recommended");
-
- is(header.nextSibling.nextSibling, recommendedHeader,
- "There should only be one theme (default) in the 'My Themes' section by default");
- is(header.nextSibling.theme.id, DEFAULT_THEME_ID, "That theme should be the default theme");
-
- let firstLWTheme = recommendedHeader.nextSibling;
- let firstLWThemeId = firstLWTheme.theme.id;
- let themeChangedPromise = promiseObserverNotified("lightweight-theme-changed");
- firstLWTheme.doCommand();
- info("Clicked on first theme");
- yield themeChangedPromise;
-
- popupShownPromise = popupShown(popup);
- EventUtils.synthesizeMouseAtCenter(themesButton, {});
- info("Clicked on themes button");
- yield popupShownPromise;
-
- is(header.nextSibling.theme.id, DEFAULT_THEME_ID, "The first theme should be the Default theme");
- let installedThemeId = header.nextSibling.nextSibling.theme.id;
- ok(installedThemeId.startsWith(firstLWThemeId),
- "The second theme in the 'My Themes' section should be the newly installed theme: " +
- "Installed theme id: " + installedThemeId + "; First theme ID: " + firstLWThemeId);
- is(header.nextSibling.nextSibling.nextSibling, recommendedHeader,
- "There should be two themes in the 'My Themes' section");
-
- let defaultTheme = header.nextSibling;
- defaultTheme.doCommand();
- is(Services.prefs.getCharPref("lightweightThemes.selectedThemeID"), "", "No lwtheme should be selected");
-
- // ensure current theme isn't set to "Default"
- popupShownPromise = popupShown(popup);
- EventUtils.synthesizeMouseAtCenter(themesButton, {});
- info("Clicked on themes button a second time");
- yield popupShownPromise;
-
- firstLWTheme = recommendedHeader.nextSibling;
- themeChangedPromise = promiseObserverNotified("lightweight-theme-changed");
- firstLWTheme.doCommand();
- info("Clicked on first theme again");
- yield themeChangedPromise;
-
- // check that "Restore Defaults" button resets theme
- yield gCustomizeMode.reset();
- is(LightweightThemeManager.currentTheme, null, "Current theme reset to default");
-
- yield endCustomizing();
- Services.prefs.setCharPref("lightweightThemes.usedThemes", "[]");
- Services.prefs.setCharPref("lightweightThemes.recommendedThemes", "[]");
- info("Removed all recommended themes");
- yield startCustomizing();
- popupShownPromise = popupShown(popup);
- EventUtils.synthesizeMouseAtCenter(themesButton, {});
- info("Clicked on themes button a second time");
- yield popupShownPromise;
- header = document.getElementById("customization-lwtheme-menu-header");
- is(header.hidden, false, "Header should never be hidden");
- is(header.nextSibling.theme.id, DEFAULT_THEME_ID, "The first theme should be the Default theme");
- is(header.nextSibling.hidden, false, "The default theme should never be hidden");
- recommendedHeader = document.getElementById("customization-lwtheme-menu-recommended");
- is(header.nextSibling.nextSibling, recommendedHeader,
- "There should only be one theme (default) in the 'My Themes' section by default");
- let footer = document.getElementById("customization-lwtheme-menu-footer");
- is(recommendedHeader.nextSibling.id, footer.id, "There should be no recommended themes in the menu");
- is(recommendedHeader.hidden, true, "The recommendedHeader should be hidden since there are no recommended themes");
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
-
- Services.prefs.clearUserPref("lightweightThemes.usedThemes");
- Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
-});
diff --git a/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js b/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js
deleted file mode 100644
index 56657914b..000000000
--- a/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const kAnchorAttribute = "cui-anchorid";
-
-/**
- * Check that anchor gets set correctly when moving an item from the panel to the toolbar
- * using 'undo'
- */
-add_task(function*() {
- yield startCustomizing();
- let button = document.getElementById("history-panelmenu");
- is(button.getAttribute(kAnchorAttribute), "PanelUI-menu-button",
- "Button (" + button.id + ") starts out with correct anchor");
-
- let navbar = document.getElementById("nav-bar").customizationTarget;
- simulateItemDrag(button, navbar);
- is(CustomizableUI.getPlacementOfWidget(button.id).area, "nav-bar",
- "Button (" + button.id + ") ends up in nav-bar");
-
- ok(!button.hasAttribute(kAnchorAttribute),
- "Button (" + button.id + ") has no anchor in toolbar");
-
- let resetButton = document.getElementById("customization-reset-button");
- ok(!resetButton.hasAttribute("disabled"), "Should be able to reset now.");
- yield gCustomizeMode.reset();
-
- is(button.getAttribute(kAnchorAttribute), "PanelUI-menu-button",
- "Button (" + button.id + ") has anchor again");
-
- let undoButton = document.getElementById("customization-undo-reset-button");
- ok(!undoButton.hasAttribute("disabled"), "Should be able to undo now.");
- yield gCustomizeMode.undoReset();
-
- ok(!button.hasAttribute(kAnchorAttribute),
- "Button (" + button.id + ") once again has no anchor in toolbar");
-
- yield gCustomizeMode.reset();
-
- yield endCustomizing();
-});
-
-
-/**
- * Check that anchor gets set correctly when moving an item from the panel to the toolbar
- * using 'reset'
- */
-add_task(function*() {
- yield startCustomizing();
- let button = document.getElementById("bookmarks-menu-button");
- ok(!button.hasAttribute(kAnchorAttribute),
- "Button (" + button.id + ") has no anchor in toolbar");
-
- let panel = document.getElementById("PanelUI-contents");
- simulateItemDrag(button, panel);
- is(CustomizableUI.getPlacementOfWidget(button.id).area, "PanelUI-contents",
- "Button (" + button.id + ") ends up in panel");
- is(button.getAttribute(kAnchorAttribute), "PanelUI-menu-button",
- "Button (" + button.id + ") has correct anchor in the panel");
-
- let resetButton = document.getElementById("customization-reset-button");
- ok(!resetButton.hasAttribute("disabled"), "Should be able to reset now.");
- yield gCustomizeMode.reset();
-
- ok(!button.hasAttribute(kAnchorAttribute),
- "Button (" + button.id + ") once again has no anchor in toolbar");
-
- yield endCustomizing();
-});
diff --git a/browser/components/customizableui/test/browser_1042100_default_placements_update.js b/browser/components/customizableui/test/browser_1042100_default_placements_update.js
deleted file mode 100644
index 129dbd754..000000000
--- a/browser/components/customizableui/test/browser_1042100_default_placements_update.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// NB: This uses some ugly hacks to get into the CUI module from elsewhere...
-// don't try this at home, kids.
-function test() {
- // Customize something to make sure stuff changed:
- CustomizableUI.addWidgetToArea("feed-button", CustomizableUI.AREA_NAVBAR);
-
- // Check what version we're on:
- let CustomizableUIBSPass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
-
- is(CustomizableUIBSPass.gFuturePlacements.size, 0,
- "All future placements should be dealt with by now.");
-
- let {CustomizableUIInternal, gFuturePlacements, gPalette} = CustomizableUIBSPass;
- CustomizableUIInternal._introduceNewBuiltinWidgets();
- is(gFuturePlacements.size, 0,
- "No change to future placements initially.");
-
- let currentVersion = CustomizableUIBSPass.kVersion;
-
-
- // Add our widget to the defaults:
- let testWidgetNew = {
- id: "test-messing-with-default-placements-new",
- label: "Test messing with default placements - should be inserted",
- defaultArea: CustomizableUI.AREA_NAVBAR,
- introducedInVersion: currentVersion + 1,
- };
-
- let normalizedWidget = CustomizableUIInternal.normalizeWidget(testWidgetNew,
- CustomizableUI.SOURCE_BUILTIN);
- ok(normalizedWidget, "Widget should be normalizable");
- if (!normalizedWidget) {
- return;
- }
- CustomizableUIBSPass.gPalette.set(testWidgetNew.id, normalizedWidget);
-
- let testWidgetOld = {
- id: "test-messing-with-default-placements-old",
- label: "Test messing with default placements - should NOT be inserted",
- defaultArea: CustomizableUI.AREA_NAVBAR,
- introducedInVersion: currentVersion,
- };
-
- normalizedWidget = CustomizableUIInternal.normalizeWidget(testWidgetOld,
- CustomizableUI.SOURCE_BUILTIN);
- ok(normalizedWidget, "Widget should be normalizable");
- if (!normalizedWidget) {
- return;
- }
- CustomizableUIBSPass.gPalette.set(testWidgetOld.id, normalizedWidget);
-
-
- // Now increase the version in the module:
- CustomizableUIBSPass.kVersion++;
-
- let hadSavedState = !!CustomizableUIBSPass.gSavedState
- if (!hadSavedState) {
- CustomizableUIBSPass.gSavedState = {currentVersion: CustomizableUIBSPass.kVersion - 1};
- }
-
- // Then call the re-init routine so we re-add the builtin widgets
- CustomizableUIInternal._introduceNewBuiltinWidgets();
- is(gFuturePlacements.size, 1,
- "Should have 1 more future placement");
- let haveNavbarPlacements = gFuturePlacements.has(CustomizableUI.AREA_NAVBAR);
- ok(haveNavbarPlacements, "Should have placements for nav-bar");
- if (haveNavbarPlacements) {
- let placements = [...gFuturePlacements.get(CustomizableUI.AREA_NAVBAR)];
-
- // Ignore widgets that are placed using the pref facility and not the
- // versioned facility. They're independent of kVersion and the saved
- // state's current version, so they may be present in the placements.
- for (let i = 0; i < placements.length; ) {
- if (placements[i] == testWidgetNew.id) {
- i++;
- continue;
- }
- let pref = "browser.toolbarbuttons.introduced." + placements[i];
- let introduced = false;
- try {
- introduced = Services.prefs.getBoolPref(pref);
- } catch (ex) {}
- if (!introduced) {
- i++;
- continue;
- }
- placements.splice(i, 1);
- }
-
- is(placements.length, 1, "Should have 1 newly placed widget in nav-bar");
- is(placements[0], testWidgetNew.id, "Should have our test widget to be placed in nav-bar");
- }
-
- gFuturePlacements.delete(CustomizableUI.AREA_NAVBAR);
- CustomizableUIBSPass.kVersion--;
- gPalette.delete(testWidgetNew.id);
- gPalette.delete(testWidgetOld.id);
- if (!hadSavedState) {
- CustomizableUIBSPass.gSavedState = null;
- }
-}
-
diff --git a/browser/components/customizableui/test/browser_1058573_showToolbarsDropdown.js b/browser/components/customizableui/test/browser_1058573_showToolbarsDropdown.js
deleted file mode 100644
index 42a032ff8..000000000
--- a/browser/components/customizableui/test/browser_1058573_showToolbarsDropdown.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check that toggleable toolbars dropdown in always shown");
-
- info("Remove all possible custom toolbars");
- yield removeCustomToolbars();
-
- info("Enter customization mode");
- yield startCustomizing();
-
- let toolbarsToggle = document.getElementById("customization-toolbar-visibility-button");
- ok(toolbarsToggle, "The toolbars toggle dropdown exists");
- ok(!toolbarsToggle.hasAttribute("hidden"),
- "The toolbars toggle dropdown is displayed");
-});
-
-add_task(function* asyncCleanup() {
- info("Exit customization mode");
- yield endCustomizing();
-});
diff --git a/browser/components/customizableui/test/browser_1087303_button_fullscreen.js b/browser/components/customizableui/test/browser_1087303_button_fullscreen.js
deleted file mode 100644
index c6b87d6ab..000000000
--- a/browser/components/customizableui/test/browser_1087303_button_fullscreen.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check fullscreen button existence and functionality");
-
- yield PanelUI.show();
-
- let fullscreenButton = document.getElementById("fullscreen-button");
- ok(fullscreenButton, "Fullscreen button appears in Panel Menu");
-
- let fullscreenPromise = promiseFullscreenChange();
- fullscreenButton.click();
- yield fullscreenPromise;
-
- ok(window.fullScreen, "Fullscreen mode was opened");
-
- // exit full screen mode
- fullscreenPromise = promiseFullscreenChange();
- window.fullScreen = !window.fullScreen;
- yield fullscreenPromise;
-
- ok(!window.fullScreen, "Successfully exited fullscreen");
-});
-
-function promiseFullscreenChange() {
- let deferred = Promise.defer();
- info("Wait for fullscreen change");
-
- let timeoutId = setTimeout(() => {
- window.removeEventListener("fullscreen", onFullscreenChange, true);
- deferred.reject("Fullscreen change did not happen within " + 20000 + "ms");
- }, 20000);
-
- function onFullscreenChange(event) {
- clearTimeout(timeoutId);
- window.removeEventListener("fullscreen", onFullscreenChange, true);
- info("Fullscreen event received");
- deferred.resolve();
- }
- window.addEventListener("fullscreen", onFullscreenChange, true);
- return deferred.promise;
-}
diff --git a/browser/components/customizableui/test/browser_1087303_button_preferences.js b/browser/components/customizableui/test/browser_1087303_button_preferences.js
deleted file mode 100644
index b1fdb85b6..000000000
--- a/browser/components/customizableui/test/browser_1087303_button_preferences.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var newTab = null;
-
-add_task(function*() {
- info("Check preferences button existence and functionality");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let preferencesButton = document.getElementById("preferences-button");
- ok(preferencesButton, "Preferences button exists in Panel Menu");
- preferencesButton.click();
-
- newTab = gBrowser.selectedTab;
- yield waitForPageLoad(newTab);
-
- let openedPage = gBrowser.currentURI.spec;
- is(openedPage, "about:preferences", "Preferences page was opened");
-});
-
-add_task(function asyncCleanup() {
- if (gBrowser.tabs.length == 1)
- gBrowser.addTab("about:blank");
-
- gBrowser.removeTab(gBrowser.selectedTab);
- info("Tabs were restored");
-});
-
-function waitForPageLoad(aTab) {
- let deferred = Promise.defer();
-
- let timeoutId = setTimeout(() => {
- aTab.linkedBrowser.removeEventListener("load", onTabLoad, true);
- deferred.reject("Page didn't load within " + 20000 + "ms");
- }, 20000);
-
- function onTabLoad(event) {
- clearTimeout(timeoutId);
- aTab.linkedBrowser.removeEventListener("load", onTabLoad, true);
- info("Tab event received: " + "load");
- deferred.resolve();
- }
- aTab.linkedBrowser.addEventListener("load", onTabLoad, true, true);
- return deferred.promise;
-}
diff --git a/browser/components/customizableui/test/browser_1089591_still_customizable_after_reset.js b/browser/components/customizableui/test/browser_1089591_still_customizable_after_reset.js
deleted file mode 100644
index 1f502e8e2..000000000
--- a/browser/components/customizableui/test/browser_1089591_still_customizable_after_reset.js
+++ /dev/null
@@ -1,24 +0,0 @@
-"use strict";
-
-// Dragging the elements again after a reset should work
-add_task(function* () {
- yield startCustomizing();
- let historyButton = document.getElementById("wrapper-history-panelmenu");
- let devButton = document.getElementById("wrapper-developer-button");
-
- ok(historyButton && devButton, "Draggable elements should exist");
- simulateItemDrag(historyButton, devButton);
- yield gCustomizeMode.reset();
- ok(CustomizableUI.inDefaultState, "Should be back in default state");
-
- historyButton = document.getElementById("wrapper-history-panelmenu");
- devButton = document.getElementById("wrapper-developer-button");
- ok(historyButton && devButton, "Draggable elements should exist");
- simulateItemDrag(historyButton, devButton);
-
- yield endCustomizing();
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js b/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js
deleted file mode 100644
index b5a325afb..000000000
--- a/browser/components/customizableui/test/browser_1096763_seen_widgets_post_reset.js
+++ /dev/null
@@ -1,31 +0,0 @@
-"use strict";
-
-const BUTTONID = "test-seenwidget-post-reset";
-
-add_task(function*() {
- CustomizableUI.createWidget({
- id: BUTTONID,
- label: "Test widget seen post reset",
- defaultArea: CustomizableUI.AREA_NAVBAR
- });
-
- const kPrefCustomizationState = "browser.uiCustomization.state";
- let bsPass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
- ok(bsPass.gSeenWidgets.has(BUTTONID), "Widget should be seen after createWidget is called.");
- CustomizableUI.reset();
- ok(bsPass.gSeenWidgets.has(BUTTONID), "Widget should still be seen after reset.");
- ok(!Services.prefs.prefHasUserValue(kPrefCustomizationState), "Pref shouldn't be set right now, because that'd break undo.");
- CustomizableUI.addWidgetToArea(BUTTONID, CustomizableUI.AREA_NAVBAR);
- gCustomizeMode.removeFromArea(document.getElementById(BUTTONID));
- let hasUserValue = Services.prefs.prefHasUserValue(kPrefCustomizationState);
- ok(hasUserValue, "Pref should be set right now.");
- if (hasUserValue) {
- let seenArray = JSON.parse(Services.prefs.getCharPref(kPrefCustomizationState)).seen;
- isnot(seenArray.indexOf(BUTTONID), -1, "Widget should be in saved 'seen' list.");
- }
-});
-
-registerCleanupFunction(function() {
- CustomizableUI.destroyWidget(BUTTONID);
- CustomizableUI.reset();
-});
diff --git a/browser/components/customizableui/test/browser_1161838_inserted_new_default_buttons.js b/browser/components/customizableui/test/browser_1161838_inserted_new_default_buttons.js
deleted file mode 100644
index 42768debf..000000000
--- a/browser/components/customizableui/test/browser_1161838_inserted_new_default_buttons.js
+++ /dev/null
@@ -1,78 +0,0 @@
-"use strict";
-
-// NB: This uses some ugly hacks to get into the CUI module from elsewhere...
-// don't try this at home, kids.
-function test() {
- // Customize something to make sure stuff changed:
- CustomizableUI.addWidgetToArea("feed-button", CustomizableUI.AREA_NAVBAR);
-
- let CustomizableUIBSPass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
-
- is(CustomizableUIBSPass.gFuturePlacements.size, 0,
- "All future placements should be dealt with by now.");
-
- let {CustomizableUIInternal, gFuturePlacements, gPalette} = CustomizableUIBSPass;
-
- // Force us to have a saved state:
- CustomizableUIInternal.saveState();
- CustomizableUIInternal.loadSavedState();
-
- CustomizableUIInternal._introduceNewBuiltinWidgets();
- is(gFuturePlacements.size, 0,
- "No change to future placements initially.");
-
- // Add our widget to the defaults:
- let testWidgetNew = {
- id: "test-messing-with-default-placements-new-pref",
- label: "Test messing with default placements - pref-based",
- defaultArea: CustomizableUI.AREA_NAVBAR,
- introducedInVersion: "pref",
- };
-
- let normalizedWidget = CustomizableUIInternal.normalizeWidget(testWidgetNew,
- CustomizableUI.SOURCE_BUILTIN);
- ok(normalizedWidget, "Widget should be normalizable");
- if (!normalizedWidget) {
- return;
- }
- CustomizableUIBSPass.gPalette.set(testWidgetNew.id, normalizedWidget);
-
- // Now adjust default placements for area:
- let navbarArea = CustomizableUIBSPass.gAreas.get(CustomizableUI.AREA_NAVBAR);
- let navbarPlacements = navbarArea.get("defaultPlacements");
- navbarPlacements.splice(navbarPlacements.indexOf("bookmarks-menu-button") + 1, 0, testWidgetNew.id);
-
- let savedPlacements = CustomizableUIBSPass.gSavedState.placements[CustomizableUI.AREA_NAVBAR];
- // Then call the re-init routine so we re-add the builtin widgets
- CustomizableUIInternal._introduceNewBuiltinWidgets();
- is(gFuturePlacements.size, 1,
- "Should have 1 more future placement");
- let futureNavbarPlacements = gFuturePlacements.get(CustomizableUI.AREA_NAVBAR);
- ok(futureNavbarPlacements, "Should have placements for nav-bar");
- if (futureNavbarPlacements) {
- ok(futureNavbarPlacements.has(testWidgetNew.id), "widget should be in future placements");
- }
- CustomizableUIInternal._placeNewDefaultWidgetsInArea(CustomizableUI.AREA_NAVBAR);
-
- let indexInSavedPlacements = savedPlacements.indexOf(testWidgetNew.id);
- info("Saved placements: " + savedPlacements.join(', '));
- isnot(indexInSavedPlacements, -1, "Widget should have been inserted");
- is(indexInSavedPlacements, savedPlacements.indexOf("bookmarks-menu-button") + 1,
- "Widget should be in the right place.");
-
- if (futureNavbarPlacements) {
- ok(!futureNavbarPlacements.has(testWidgetNew.id), "widget should be out of future placements");
- }
-
- if (indexInSavedPlacements != -1) {
- savedPlacements.splice(indexInSavedPlacements, 1);
- }
-
- gFuturePlacements.delete(CustomizableUI.AREA_NAVBAR);
- let indexInDefaultPlacements = navbarPlacements.indexOf(testWidgetNew.id);
- if (indexInDefaultPlacements != -1) {
- navbarPlacements.splice(indexInDefaultPlacements, 1);
- }
- gPalette.delete(testWidgetNew.id);
- CustomizableUI.reset();
-}
diff --git a/browser/components/customizableui/test/browser_873501_handle_specials.js b/browser/components/customizableui/test/browser_873501_handle_specials.js
deleted file mode 100644
index b07c8e0d7..000000000
--- a/browser/components/customizableui/test/browser_873501_handle_specials.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbarName = "test-specials-toolbar";
-
-registerCleanupFunction(removeCustomToolbars);
-
-// Add a toolbar with two springs and the downloads button.
-add_task(function* addToolbarWith2SpringsAndDownloadsButton() {
- // Create the toolbar with a single spring:
- createToolbarWithPlacements(kToolbarName, ["spring"]);
- ok(document.getElementById(kToolbarName), "Toolbar should be created.");
-
- // Check it's there with a generated ID:
- assertAreaPlacements(kToolbarName, [/customizableui-special-spring\d+/]);
- let [springId] = getAreaWidgetIds(kToolbarName);
-
- // Add a second spring, check if that's there and doesn't share IDs
- CustomizableUI.addWidgetToArea("spring", kToolbarName);
- assertAreaPlacements(kToolbarName, [springId,
- /customizableui-special-spring\d+/]);
- let [, spring2Id] = getAreaWidgetIds(kToolbarName);
-
- isnot(springId, spring2Id, "Springs shouldn't have identical IDs.");
-
- // Try moving the downloads button to this new toolbar, between the two springs:
- CustomizableUI.addWidgetToArea("downloads-button", kToolbarName, 1);
- assertAreaPlacements(kToolbarName, [springId, "downloads-button", spring2Id]);
- yield removeCustomToolbars();
-});
-
-// Add separators around the downloads button.
-add_task(function* addSeparatorsAroundDownloadsButton() {
- createToolbarWithPlacements(kToolbarName, ["separator"]);
- ok(document.getElementById(kToolbarName), "Toolbar should be created.");
-
- // Check it's there with a generated ID:
- assertAreaPlacements(kToolbarName, [/customizableui-special-separator\d+/]);
- let [separatorId] = getAreaWidgetIds(kToolbarName);
-
- CustomizableUI.addWidgetToArea("separator", kToolbarName);
- assertAreaPlacements(kToolbarName, [separatorId,
- /customizableui-special-separator\d+/]);
- let [, separator2Id] = getAreaWidgetIds(kToolbarName);
-
- isnot(separatorId, separator2Id, "Separator ids shouldn't be equal.");
-
- CustomizableUI.addWidgetToArea("downloads-button", kToolbarName, 1);
- assertAreaPlacements(kToolbarName, [separatorId, "downloads-button", separator2Id]);
- yield removeCustomToolbars();
-});
-
-// Add spacers around the downloads button.
-add_task(function* addSpacersAroundDownloadsButton() {
- createToolbarWithPlacements(kToolbarName, ["spacer"]);
- ok(document.getElementById(kToolbarName), "Toolbar should be created.");
-
- // Check it's there with a generated ID:
- assertAreaPlacements(kToolbarName, [/customizableui-special-spacer\d+/]);
- let [spacerId] = getAreaWidgetIds(kToolbarName);
-
- CustomizableUI.addWidgetToArea("spacer", kToolbarName);
- assertAreaPlacements(kToolbarName, [spacerId,
- /customizableui-special-spacer\d+/]);
- let [, spacer2Id] = getAreaWidgetIds(kToolbarName);
-
- isnot(spacerId, spacer2Id, "Spacer ids shouldn't be equal.");
-
- CustomizableUI.addWidgetToArea("downloads-button", kToolbarName, 1);
- assertAreaPlacements(kToolbarName, [spacerId, "downloads-button", spacer2Id]);
- yield removeCustomToolbars();
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
deleted file mode 100644
index a3204c271..000000000
--- a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kXULWidgetId = "a-test-button"; // we'll create a button with this ID.
-const kAPIWidgetId = "feed-button";
-const kPanel = CustomizableUI.AREA_PANEL;
-const kToolbar = CustomizableUI.AREA_NAVBAR;
-const kVisiblePalette = "customization-palette";
-const kPlaceholderClass = "panel-customization-placeholder";
-
-function checkWrapper(id) {
- is(document.querySelectorAll("#wrapper-" + id).length, 1, "There should be exactly 1 wrapper for " + id + " in the customizing window.");
-}
-
-var move = {
- "drag": function(id, target) {
- let targetNode = document.getElementById(target);
- if (targetNode.customizationTarget) {
- targetNode = targetNode.customizationTarget;
- }
- simulateItemDrag(document.getElementById(id), targetNode);
- },
- "dragToItem": function(id, target) {
- let targetNode = document.getElementById(target);
- if (targetNode.customizationTarget) {
- targetNode = targetNode.customizationTarget;
- }
- let items = targetNode.querySelectorAll("toolbarpaletteitem:not(." + kPlaceholderClass + ")");
- if (target == kPanel) {
- targetNode = items[items.length - 1];
- } else {
- targetNode = items[0];
- }
- simulateItemDrag(document.getElementById(id), targetNode);
- },
- "API": function(id, target) {
- if (target == kVisiblePalette) {
- return CustomizableUI.removeWidgetFromArea(id);
- }
- return CustomizableUI.addWidgetToArea(id, target, null);
- }
-};
-
-function isLast(containerId, defaultPlacements, id) {
- assertAreaPlacements(containerId, defaultPlacements.concat([id]));
- is(document.getElementById(containerId).customizationTarget.lastChild.firstChild.id, id,
- "Widget " + id + " should be in " + containerId + " in customizing window.");
- is(otherWin.document.getElementById(containerId).customizationTarget.lastChild.id, id,
- "Widget " + id + " should be in " + containerId + " in other window.");
-}
-
-function getLastVisibleNodeInToolbar(containerId, win=window) {
- let container = win.document.getElementById(containerId).customizationTarget;
- let rv = container.lastChild;
- while (rv && (rv.getAttribute('hidden') == 'true' || (rv.firstChild && rv.firstChild.getAttribute('hidden') == 'true'))) {
- rv = rv.previousSibling;
- }
- return rv;
-}
-
-function isLastVisibleInToolbar(containerId, defaultPlacements, id) {
- let newPlacements;
- for (let i = defaultPlacements.length - 1; i >= 0; i--) {
- let el = document.getElementById(defaultPlacements[i]);
- if (el && el.getAttribute('hidden') != 'true') {
- newPlacements = [...defaultPlacements];
- newPlacements.splice(i + 1, 0, id);
- break;
- }
- }
- if (!newPlacements) {
- assertAreaPlacements(containerId, defaultPlacements.concat([id]));
- } else {
- assertAreaPlacements(containerId, newPlacements);
- }
- is(getLastVisibleNodeInToolbar(containerId).firstChild.id, id,
- "Widget " + id + " should be in " + containerId + " in customizing window.");
- is(getLastVisibleNodeInToolbar(containerId, otherWin).id, id,
- "Widget " + id + " should be in " + containerId + " in other window.");
-}
-
-function isFirst(containerId, defaultPlacements, id) {
- assertAreaPlacements(containerId, [id].concat(defaultPlacements));
- is(document.getElementById(containerId).customizationTarget.firstChild.firstChild.id, id,
- "Widget " + id + " should be in " + containerId + " in customizing window.");
- is(otherWin.document.getElementById(containerId).customizationTarget.firstChild.id, id,
- "Widget " + id + " should be in " + containerId + " in other window.");
-}
-
-function checkToolbar(id, method) {
- // Place at start of the toolbar:
- let toolbarPlacements = getAreaWidgetIds(kToolbar);
- move[method](id, kToolbar);
- if (method == "dragToItem") {
- isFirst(kToolbar, toolbarPlacements, id);
- } else if (method == "drag") {
- isLastVisibleInToolbar(kToolbar, toolbarPlacements, id);
- } else {
- isLast(kToolbar, toolbarPlacements, id);
- }
- checkWrapper(id);
-}
-
-function checkPanel(id, method) {
- let panelPlacements = getAreaWidgetIds(kPanel);
- move[method](id, kPanel);
- let children = document.getElementById(kPanel).querySelectorAll("toolbarpaletteitem:not(." + kPlaceholderClass + ")");
- let otherChildren = otherWin.document.getElementById(kPanel).children;
- let newPlacements = panelPlacements.concat([id]);
- // Relative position of the new item from the end:
- let position = -1;
- // For the drag to item case, we drag to the last item, making the dragged item the
- // penultimate item. We can't well use the first item because the panel has complicated
- // rules about rearranging wide items (which, by default, the first two items are).
- if (method == "dragToItem") {
- newPlacements.pop();
- newPlacements.splice(panelPlacements.length - 1, 0, id);
- position = -2;
- }
- assertAreaPlacements(kPanel, newPlacements);
- is(children[children.length + position].firstChild.id, id,
- "Widget " + id + " should be in " + kPanel + " in customizing window.");
- is(otherChildren[otherChildren.length + position].id, id,
- "Widget " + id + " should be in " + kPanel + " in other window.");
- checkWrapper(id);
-}
-
-function checkPalette(id, method) {
- // Move back to palette:
- move[method](id, kVisiblePalette);
- ok(CustomizableUI.inDefaultState, "Should end in default state");
- let visibleChildren = gCustomizeMode.visiblePalette.children;
- let expectedChild = method == "dragToItem" ? visibleChildren[0] : visibleChildren[visibleChildren.length - 1];
- is(expectedChild.firstChild.id, id, "Widget " + id + " was moved using " + method + " and should now be wrapped in palette in customizing window.");
- if (id == kXULWidgetId) {
- ok(otherWin.gNavToolbox.palette.querySelector("#" + id), "Widget " + id + " should be in invisible palette in other window.");
- }
- checkWrapper(id);
-}
-
-// This test needs a XUL button that's in the palette by default. No such
-// button currently exists, so we create a simple one.
-function createXULButtonForWindow(win) {
- createDummyXULButton(kXULWidgetId, "test-button", win);
-}
-
-function removeXULButtonForWindow(win) {
- win.gNavToolbox.palette.querySelector(`#${kXULWidgetId}`).remove();
-}
-
-var otherWin;
-
-// Moving widgets in two windows, one with customize mode and one without, should work.
-add_task(function* MoveWidgetsInTwoWindows() {
- yield startCustomizing();
- otherWin = yield openAndLoadWindow(null, true);
- yield otherWin.PanelUI.ensureReady();
- // Create the XUL button to use in the test in both windows.
- createXULButtonForWindow(window);
- createXULButtonForWindow(otherWin);
- ok(CustomizableUI.inDefaultState, "Should start in default state");
-
- for (let widgetId of [kXULWidgetId, kAPIWidgetId]) {
- for (let method of ["API", "drag", "dragToItem"]) {
- info("Moving widget " + widgetId + " using " + method);
- checkToolbar(widgetId, method);
- checkPanel(widgetId, method);
- checkPalette(widgetId, method);
- checkPanel(widgetId, method);
- checkToolbar(widgetId, method);
- checkPalette(widgetId, method);
- }
- }
- yield promiseWindowClosed(otherWin);
- otherWin = null;
- yield endCustomizing();
- removeXULButtonForWindow(window);
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_876944_customize_mode_create_destroy.js b/browser/components/customizableui/test/browser_876944_customize_mode_create_destroy.js
deleted file mode 100644
index ec454dc8d..000000000
--- a/browser/components/customizableui/test/browser_876944_customize_mode_create_destroy.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kTestWidget1 = "test-customize-mode-create-destroy1";
-const kTestWidget2 = "test-customize-mode-create-destroy2";
-
-// Creating and destroying a widget should correctly wrap/unwrap stuff
-add_task(function* testWrapUnwrap() {
- yield startCustomizing();
- CustomizableUI.createWidget({id: kTestWidget1, label: 'Pretty label', tooltiptext: 'Pretty tooltip'});
- let elem = document.getElementById(kTestWidget1);
- let wrapper = document.getElementById("wrapper-" + kTestWidget1);
- ok(elem, "There should be an item");
- ok(wrapper, "There should be a wrapper");
- is(wrapper.firstChild.id, kTestWidget1, "Wrapper should have test widget");
- is(wrapper.parentNode.id, "customization-palette", "Wrapper should be in palette");
- CustomizableUI.destroyWidget(kTestWidget1);
- wrapper = document.getElementById("wrapper-" + kTestWidget1);
- ok(!wrapper, "There should be a wrapper");
- let item = document.getElementById(kTestWidget1);
- ok(!item, "There should no longer be an item");
-});
-
-// Creating and destroying a widget should correctly deal with panel placeholders
-add_task(function* testPanelPlaceholders() {
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- // The value of expectedPlaceholders depends on the default palette layout.
- // Bug 1229236 is for these tests to be smarter so the test doesn't need to
- // change when the default placements change.
- let expectedPlaceholders = 1 + (isInDevEdition() ? 1 : 0);
- is(panel.querySelectorAll(".panel-customization-placeholder").length, expectedPlaceholders, "The number of placeholders should be correct.");
- CustomizableUI.createWidget({id: kTestWidget2, label: 'Pretty label', tooltiptext: 'Pretty tooltip', defaultArea: CustomizableUI.AREA_PANEL});
- let elem = document.getElementById(kTestWidget2);
- let wrapper = document.getElementById("wrapper-" + kTestWidget2);
- ok(elem, "There should be an item");
- ok(wrapper, "There should be a wrapper");
- is(wrapper.firstChild.id, kTestWidget2, "Wrapper should have test widget");
- is(wrapper.parentNode, panel, "Wrapper should be in panel");
- expectedPlaceholders = isInDevEdition() ? 1 : 3;
- is(panel.querySelectorAll(".panel-customization-placeholder").length, expectedPlaceholders, "The number of placeholders should be correct.");
- CustomizableUI.destroyWidget(kTestWidget2);
- wrapper = document.getElementById("wrapper-" + kTestWidget2);
- ok(!wrapper, "There should be a wrapper");
- let item = document.getElementById(kTestWidget2);
- ok(!item, "There should no longer be an item");
- yield endCustomizing();
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- try {
- CustomizableUI.destroyWidget(kTestWidget1);
- } catch (ex) {}
- try {
- CustomizableUI.destroyWidget(kTestWidget2);
- } catch (ex) {}
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_877006_missing_view.js b/browser/components/customizableui/test/browser_877006_missing_view.js
deleted file mode 100644
index a1495c1fe..000000000
--- a/browser/components/customizableui/test/browser_877006_missing_view.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Should be able to add broken view widget
-add_task(function testAddbrokenViewWidget() {
- const kWidgetId = 'test-877006-broken-widget';
- let widgetSpec = {
- id: kWidgetId,
- type: 'view',
- viewId: 'idontexist',
- /* Empty handler so we try to attach it maybe? */
- onViewShowing: function() {
- }
- };
-
- let noError = true;
- try {
- CustomizableUI.createWidget(widgetSpec);
- CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_NAVBAR);
- } catch (ex) {
- Cu.reportError(ex);
- noError = false;
- }
- ok(noError, "Should not throw an exception trying to add a broken view widget.");
-
- noError = true;
- try {
- CustomizableUI.destroyWidget(kWidgetId);
- } catch (ex) {
- Cu.reportError(ex);
- noError = false;
- }
- ok(noError, "Should not throw an exception trying to remove the broken view widget.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_877178_unregisterArea.js b/browser/components/customizableui/test/browser_877178_unregisterArea.js
deleted file mode 100644
index 28037787b..000000000
--- a/browser/components/customizableui/test/browser_877178_unregisterArea.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-registerCleanupFunction(removeCustomToolbars);
-
-// Sanity checks
-add_task(function sanityChecks() {
- SimpleTest.doesThrow(() => CustomizableUI.registerArea("@foo"),
- "Registering areas with an invalid ID should throw.");
-
- SimpleTest.doesThrow(() => CustomizableUI.registerArea([]),
- "Registering areas with an invalid ID should throw.");
-
- SimpleTest.doesThrow(() => CustomizableUI.unregisterArea("@foo"),
- "Unregistering areas with an invalid ID should throw.");
-
- SimpleTest.doesThrow(() => CustomizableUI.unregisterArea([]),
- "Unregistering areas with an invalid ID should throw.");
-
- SimpleTest.doesThrow(() => CustomizableUI.unregisterArea("unknown"),
- "Unregistering an area that's not registered should throw.");
-});
-
-// Check areas are loaded with their default placements.
-add_task(function checkLoadedAres() {
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
-});
-
-// Check registering and unregistering a new area.
-add_task(function checkRegisteringAndUnregistering() {
- const kToolbarId = "test-registration-toolbar";
- const kButtonId = "test-registration-button";
- createDummyXULButton(kButtonId);
- createToolbarWithPlacements(kToolbarId, ["spring", kButtonId, "spring"]);
- assertAreaPlacements(kToolbarId,
- [/customizableui-special-spring\d+/,
- kButtonId,
- /customizableui-special-spring\d+/]);
- ok(!CustomizableUI.inDefaultState, "With a new toolbar it is no longer in a default state.");
- removeCustomToolbars(); // Will call unregisterArea for us
- ok(CustomizableUI.inDefaultState, "When the toolbar is unregistered, " +
- "everything will return to the default state.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_877447_skip_missing_ids.js b/browser/components/customizableui/test/browser_877447_skip_missing_ids.js
deleted file mode 100644
index 0cba7ae4f..000000000
--- a/browser/components/customizableui/test/browser_877447_skip_missing_ids.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-registerCleanupFunction(removeCustomToolbars);
-
-add_task(function skipMissingIDS() {
- const kButtonId = "look-at-me-disappear-button";
- CustomizableUI.reset();
- ok(CustomizableUI.inDefaultState, "Should be in the default state.");
- let btn = createDummyXULButton(kButtonId, "Gone!");
- CustomizableUI.addWidgetToArea(kButtonId, CustomizableUI.AREA_NAVBAR);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in the default state.");
- is(btn.parentNode.parentNode.id, CustomizableUI.AREA_NAVBAR, "Button should be in navbar");
- btn.remove();
- is(btn.parentNode, null, "Button is no longer in the navbar");
- ok(CustomizableUI.inDefaultState, "Should be back in the default state, " +
- "despite unknown button ID in placements.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_878452_drag_to_panel.js b/browser/components/customizableui/test/browser_878452_drag_to_panel.js
deleted file mode 100644
index 8a8d82294..000000000
--- a/browser/components/customizableui/test/browser_878452_drag_to_panel.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Dragging an item from the palette to another button in the panel should work.
-add_task(function*() {
- yield startCustomizing();
- let btn = document.getElementById("feed-button");
- let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
-
- let lastButtonIndex = placements.length - 1;
- let lastButton = placements[lastButtonIndex];
- let placementsAfterInsert = placements.slice(0, lastButtonIndex).concat(["feed-button", lastButton]);
- let lastButtonNode = document.getElementById(lastButton);
- simulateItemDrag(btn, lastButtonNode);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterInsert);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let palette = document.getElementById("customization-palette");
- simulateItemDrag(btn, palette);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging an item from the palette to the panel itself should also work.
-add_task(function*() {
- yield startCustomizing();
- let btn = document.getElementById("feed-button");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
-
- let placementsAfterAppend = placements.concat(["feed-button"]);
- simulateItemDrag(btn, panel);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let palette = document.getElementById("customization-palette");
- simulateItemDrag(btn, palette);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging an item from the palette to an empty panel should also work.
-add_task(function*() {
- let widgetIds = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
- while (widgetIds.length) {
- CustomizableUI.removeWidgetFromArea(widgetIds.shift());
- }
- yield startCustomizing();
- let btn = document.getElementById("feed-button");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
-
- assertAreaPlacements(panel.id, []);
-
- let placementsAfterAppend = ["feed-button"];
- simulateItemDrag(btn, panel);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let palette = document.getElementById("customization-palette");
- simulateItemDrag(btn, palette);
- assertAreaPlacements(panel.id, []);
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_880164_customization_context_menus.js b/browser/components/customizableui/test/browser_880164_customization_context_menus.js
deleted file mode 100644
index 57a0db773..000000000
--- a/browser/components/customizableui/test/browser_880164_customization_context_menus.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-const isOSX = (Services.appinfo.OS === "Darwin");
-
-// Right-click on the home button should
-// show a context menu with options to move it.
-add_task(function*() {
- let contextMenu = document.getElementById("toolbar-context-menu");
- let shownPromise = popupShown(contextMenu);
- let homeButton = document.getElementById("home-button");
- EventUtils.synthesizeMouse(homeButton, 2, 2, {type: "contextmenu", button: 2 });
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToPanel", true],
- [".customize-context-removeFromToolbar", true],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenPromise;
-});
-
-// Right-click on an empty bit of tabstrip should
-// show a context menu without options to move it,
-// but with tab-specific options instead.
-add_task(function*() {
- // ensure there are tabs to reload/bookmark:
- let extraTab = gBrowser.selectedTab = gBrowser.addTab();
- yield promiseTabLoadEvent(extraTab, "http://example.com/");
- let contextMenu = document.getElementById("toolbar-context-menu");
- let shownPromise = popupShown(contextMenu);
- let tabstrip = document.getElementById("tabbrowser-tabs");
- let rect = tabstrip.getBoundingClientRect();
- EventUtils.synthesizeMouse(tabstrip, rect.width - 2, 2, {type: "contextmenu", button: 2 });
- yield shownPromise;
-
- let closedTabsAvailable = SessionStore.getClosedTabCount(window) == 0;
- info("Closed tabs: " + closedTabsAvailable);
- let expectedEntries = [
- ["#toolbar-context-reloadAllTabs", true],
- ["#toolbar-context-bookmarkAllTabs", true],
- ["#toolbar-context-undoCloseTab", !closedTabsAvailable],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenPromise;
- gBrowser.removeTab(extraTab);
-});
-
-// Right-click on an empty bit of extra toolbar should
-// show a context menu with moving options disabled,
-// and a toggle option for the extra toolbar
-add_task(function*() {
- let contextMenu = document.getElementById("toolbar-context-menu");
- let shownPromise = popupShown(contextMenu);
- let toolbar = createToolbarWithPlacements("880164_empty_toolbar", []);
- toolbar.setAttribute("context", "toolbar-context-menu");
- toolbar.setAttribute("toolbarname", "Fancy Toolbar for Context Menu");
- EventUtils.synthesizeMouseAtCenter(toolbar, {type: "contextmenu", button: 2 });
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToPanel", false],
- [".customize-context-removeFromToolbar", false],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["#toggle_880164_empty_toolbar", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenPromise;
- removeCustomToolbars();
-});
-
-
-// Right-click on the urlbar-container should
-// show a context menu with disabled options to move it.
-add_task(function*() {
- let contextMenu = document.getElementById("toolbar-context-menu");
- let shownPromise = popupShown(contextMenu);
- let urlBarContainer = document.getElementById("urlbar-container");
- // Need to make sure not to click within an edit field.
- EventUtils.synthesizeMouse(urlBarContainer, 100, 1, {type: "contextmenu", button: 2 });
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToPanel", false],
- [".customize-context-removeFromToolbar", false],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenPromise;
-});
-
-// Right-click on the searchbar and moving it to the menu
-// and back should move the search-container instead.
-add_task(function*() {
- let searchbar = document.getElementById("searchbar");
- gCustomizeMode.addToPanel(searchbar);
- let placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
-
- let shownPanelPromise = promisePanelShown(window);
- PanelUI.toggle({type: "command"});
- yield shownPanelPromise;
- let hiddenPanelPromise = promisePanelHidden(window);
- PanelUI.toggle({type: "command"});
- yield hiddenPanelPromise;
-
- gCustomizeMode.addToToolbar(searchbar);
- placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_NAVBAR, "Should be in navbar");
- gCustomizeMode.removeFromArea(searchbar);
- placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement, null, "Should be in palette");
- CustomizableUI.reset();
- placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_NAVBAR, "Should be in navbar");
-});
-
-// Right-click on an item within the menu panel should
-// show a context menu with options to move it.
-add_task(function*() {
- let shownPanelPromise = promisePanelShown(window);
- PanelUI.toggle({type: "command"});
- yield shownPanelPromise;
-
- let contextMenu = document.getElementById("customizationPanelItemContextMenu");
- let shownContextPromise = popupShown(contextMenu);
- let newWindowButton = document.getElementById("new-window-button");
- ok(newWindowButton, "new-window-button was found");
- EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownContextPromise;
-
- is(PanelUI.panel.state, "open", "The PanelUI should still be open.");
-
- let expectedEntries = [
- [".customize-context-moveToToolbar", true],
- [".customize-context-removeFromPanel", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- ];
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
-
- let hiddenPromise = promisePanelHidden(window);
- PanelUI.toggle({type: "command"});
- yield hiddenPromise;
-});
-
-// Right-click on the home button while in customization mode
-// should show a context menu with options to move it.
-add_task(function*() {
- yield startCustomizing();
- let contextMenu = document.getElementById("toolbar-context-menu");
- let shownPromise = popupShown(contextMenu);
- let homeButton = document.getElementById("wrapper-home-button");
- EventUtils.synthesizeMouse(homeButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToPanel", true],
- [".customize-context-removeFromToolbar", true],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["---"],
- [".viewCustomizeToolbar", false]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
-});
-
-// Right-click on an item in the palette should
-// show a context menu with options to move it.
-add_task(function*() {
- let contextMenu = document.getElementById("customizationPaletteItemContextMenu");
- let shownPromise = popupShown(contextMenu);
- let openFileButton = document.getElementById("wrapper-open-file-button");
- EventUtils.synthesizeMouse(openFileButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-addToToolbar", true],
- [".customize-context-addToPanel", true]
- ];
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
-});
-
-// Right-click on an item in the panel while in customization mode
-// should show a context menu with options to move it.
-add_task(function*() {
- let contextMenu = document.getElementById("customizationPanelItemContextMenu");
- let shownPromise = popupShown(contextMenu);
- let newWindowButton = document.getElementById("wrapper-new-window-button");
- EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToToolbar", true],
- [".customize-context-removeFromPanel", true],
- ["---"],
- [".viewCustomizeToolbar", false]
- ];
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
- yield endCustomizing();
-});
-
-// Test the toolbarbutton panel context menu in customization mode
-// without opening the panel before customization mode
-add_task(function*() {
- this.otherWin = yield openAndLoadWindow(null, true);
-
- yield new Promise(resolve => waitForFocus(resolve, this.otherWin));
-
- yield startCustomizing(this.otherWin);
-
- let contextMenu = this.otherWin.document.getElementById("customizationPanelItemContextMenu");
- let shownPromise = popupShown(contextMenu);
- let newWindowButton = this.otherWin.document.getElementById("wrapper-new-window-button");
- EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2}, this.otherWin);
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToToolbar", true],
- [".customize-context-removeFromPanel", true],
- ["---"],
- [".viewCustomizeToolbar", false]
- ];
- checkContextMenu(contextMenu, expectedEntries, this.otherWin);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
- yield endCustomizing(this.otherWin);
- yield promiseWindowClosed(this.otherWin);
- this.otherWin = null;
-
- yield new Promise(resolve => waitForFocus(resolve, window));
-});
-
-// Bug 945191 - Combined buttons show wrong context menu options
-// when they are in the toolbar.
-add_task(function*() {
- yield startCustomizing();
- let contextMenu = document.getElementById("customizationPanelItemContextMenu");
- let shownPromise = popupShown(contextMenu);
- let zoomControls = document.getElementById("wrapper-zoom-controls");
- EventUtils.synthesizeMouse(zoomControls, 2, 2, {type: "contextmenu", button: 2});
- yield shownPromise;
- // Execute the command to move the item from the panel to the toolbar.
- contextMenu.childNodes[0].doCommand();
- let hiddenPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenPromise;
- yield endCustomizing();
-
- zoomControls = document.getElementById("zoom-controls");
- is(zoomControls.parentNode.id, "nav-bar-customization-target", "Zoom-controls should be on the nav-bar");
-
- contextMenu = document.getElementById("toolbar-context-menu");
- shownPromise = popupShown(contextMenu);
- EventUtils.synthesizeMouse(zoomControls, 2, 2, {type: "contextmenu", button: 2});
- yield shownPromise;
-
- let expectedEntries = [
- [".customize-context-moveToPanel", true],
- [".customize-context-removeFromToolbar", true],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- hiddenPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenPromise;
- yield resetCustomization();
-});
-
-// Bug 947586 - After customization, panel items show wrong context menu options
-add_task(function*() {
- yield startCustomizing();
- yield endCustomizing();
-
- yield PanelUI.show();
-
- let contextMenu = document.getElementById("customizationPanelItemContextMenu");
- let shownContextPromise = popupShown(contextMenu);
- let newWindowButton = document.getElementById("new-window-button");
- ok(newWindowButton, "new-window-button was found");
- EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownContextPromise;
-
- is(PanelUI.panel.state, "open", "The PanelUI should still be open.");
-
- let expectedEntries = [
- [".customize-context-moveToToolbar", true],
- [".customize-context-removeFromPanel", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- ];
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
-
- let hiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield hiddenPromise;
-});
-
-
-// Bug 982027 - moving icon around removes custom context menu.
-add_task(function*() {
- let widgetId = "custom-context-menu-toolbarbutton";
- let expectedContext = "myfancycontext";
- let widget = createDummyXULButton(widgetId, "Test ctxt menu");
- widget.setAttribute("context", expectedContext);
- CustomizableUI.addWidgetToArea(widgetId, CustomizableUI.AREA_NAVBAR);
- is(widget.getAttribute("context"), expectedContext, "Should have context menu when added to the toolbar.");
-
- yield startCustomizing();
- is(widget.getAttribute("context"), "", "Should not have own context menu in the toolbar now that we're customizing.");
- is(widget.getAttribute("wrapped-context"), expectedContext, "Should keep own context menu wrapped when in toolbar.");
-
- let panel = PanelUI.contents;
- simulateItemDrag(widget, panel);
- is(widget.getAttribute("context"), "", "Should not have own context menu when in the panel.");
- is(widget.getAttribute("wrapped-context"), expectedContext, "Should keep own context menu wrapped now that we're in the panel.");
-
- simulateItemDrag(widget, document.getElementById("nav-bar").customizationTarget);
- is(widget.getAttribute("context"), "", "Should not have own context menu when back in toolbar because we're still customizing.");
- is(widget.getAttribute("wrapped-context"), expectedContext, "Should keep own context menu wrapped now that we're back in the toolbar.");
-
- yield endCustomizing();
- is(widget.getAttribute("context"), expectedContext, "Should have context menu again now that we're out of customize mode.");
- CustomizableUI.removeWidgetFromArea(widgetId);
- widget.remove();
- ok(CustomizableUI.inDefaultState, "Should be in default state after removing button.");
-});
diff --git a/browser/components/customizableui/test/browser_880382_drag_wide_widgets_in_panel.js b/browser/components/customizableui/test/browser_880382_drag_wide_widgets_in_panel.js
deleted file mode 100644
index 9057d0557..000000000
--- a/browser/components/customizableui/test/browser_880382_drag_wide_widgets_in_panel.js
+++ /dev/null
@@ -1,497 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(5);
-
-// Dragging the zoom controls to be before the print button should not move any controls.
-add_task(function*() {
- yield startCustomizing();
- let zoomControls = document.getElementById("zoom-controls");
- let printButton = document.getElementById("print-button");
- let placementsAfterMove = ["edit-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "zoom-controls",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(zoomControls, printButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let newWindowButton = document.getElementById("new-window-button");
- simulateItemDrag(zoomControls, newWindowButton);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging the zoom controls to be before the save button should not move any controls.
-add_task(function*() {
- yield startCustomizing();
- let zoomControls = document.getElementById("zoom-controls");
- let savePageButton = document.getElementById("save-page-button");
- let placementsAfterMove = ["edit-controls",
- "zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(zoomControls, savePageButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- ok(CustomizableUI.inDefaultState, "Should be in default state.");
-});
-
-
-// Dragging the zoom controls to be before the new-window button should not move any widgets.
-add_task(function*() {
- yield startCustomizing();
- let zoomControls = document.getElementById("zoom-controls");
- let newWindowButton = document.getElementById("new-window-button");
- let placementsAfterMove = ["edit-controls",
- "zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(zoomControls, newWindowButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the zoom controls to be before the history-panelmenu should move the zoom-controls in to the row higher than the history-panelmenu.
-add_task(function*() {
- yield startCustomizing();
- let zoomControls = document.getElementById("zoom-controls");
- let historyPanelMenu = document.getElementById("history-panelmenu");
- let placementsAfterMove = ["edit-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "zoom-controls",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(zoomControls, historyPanelMenu);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let newWindowButton = document.getElementById("new-window-button");
- simulateItemDrag(zoomControls, newWindowButton);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging the zoom controls to be before the preferences-button should move the zoom-controls
-// in to the row higher than the preferences-button.
-add_task(function*() {
- yield startCustomizing();
- let zoomControls = document.getElementById("zoom-controls");
- let preferencesButton = document.getElementById("preferences-button");
- let placementsAfterMove = ["edit-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "zoom-controls",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(zoomControls, preferencesButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let newWindowButton = document.getElementById("new-window-button");
- simulateItemDrag(zoomControls, newWindowButton);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging an item from the palette to before the zoom-controls should move it and two other buttons before the zoom controls.
-add_task(function*() {
- yield startCustomizing();
- let openFileButton = document.getElementById("open-file-button");
- let zoomControls = document.getElementById("zoom-controls");
- let placementsAfterInsert = ["edit-controls",
- "open-file-button",
- "new-window-button",
- "privatebrowsing-button",
- "zoom-controls",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterInsert);
- simulateItemDrag(openFileButton, zoomControls);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterInsert);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let palette = document.getElementById("customization-palette");
- // Check that the palette items are re-wrapped correctly.
- let feedWrapper = document.getElementById("wrapper-feed-button");
- let feedButton = document.getElementById("feed-button");
- is(feedButton.parentNode, feedWrapper,
- "feed-button should be a child of wrapper-feed-button");
- is(feedWrapper.getAttribute("place"), "palette",
- "The feed-button wrapper should have it's place set to 'palette'");
- simulateItemDrag(openFileButton, palette);
- is(openFileButton.parentNode.tagName, "toolbarpaletteitem",
- "The open-file-button should be wrapped by a toolbarpaletteitem");
- let newWindowButton = document.getElementById("new-window-button");
- simulateItemDrag(zoomControls, newWindowButton);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging an item from the palette to before the edit-controls
-// should move it and two other buttons before the edit and zoom controls.
-add_task(function*() {
- yield startCustomizing();
- let openFileButton = document.getElementById("open-file-button");
- let editControls = document.getElementById("edit-controls");
- let placementsAfterInsert = ["open-file-button",
- "new-window-button",
- "privatebrowsing-button",
- "edit-controls",
- "zoom-controls",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterInsert);
- simulateItemDrag(openFileButton, editControls);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterInsert);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- let palette = document.getElementById("customization-palette");
- // Check that the palette items are re-wrapped correctly.
- let feedWrapper = document.getElementById("wrapper-feed-button");
- let feedButton = document.getElementById("feed-button");
- is(feedButton.parentNode, feedWrapper,
- "feed-button should be a child of wrapper-feed-button");
- is(feedWrapper.getAttribute("place"), "palette",
- "The feed-button wrapper should have it's place set to 'palette'");
- simulateItemDrag(openFileButton, palette);
- is(openFileButton.parentNode.tagName, "toolbarpaletteitem",
- "The open-file-button should be wrapped by a toolbarpaletteitem");
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Dragging the edit-controls to be before the zoom-controls button
-// should not move any widgets.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let zoomControls = document.getElementById("zoom-controls");
- let placementsAfterMove = ["edit-controls",
- "zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, zoomControls);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the edit-controls to be before the new-window-button should
-// move the zoom-controls before the edit-controls.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let newWindowButton = document.getElementById("new-window-button");
- let placementsAfterMove = ["zoom-controls",
- "edit-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, newWindowButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(editControls, zoomControls);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the edit-controls to be before the privatebrowsing-button
-// should move the edit-controls in to the row higher than the
-// privatebrowsing-button.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let privateBrowsingButton = document.getElementById("privatebrowsing-button");
- let placementsAfterMove = ["zoom-controls",
- "edit-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, privateBrowsingButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(editControls, zoomControls);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the edit-controls to be before the save-page-button
-// should move the edit-controls in to the row higher than the
-// save-page-button.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let savePageButton = document.getElementById("save-page-button");
- let placementsAfterMove = ["zoom-controls",
- "edit-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, savePageButton);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(editControls, zoomControls);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the edit-controls to the panel itself should append
-// the edit controls to the bottom of the panel.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let placementsAfterMove = ["zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "edit-controls",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, panel);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(editControls, zoomControls);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the edit-controls to the customization-palette and
-// back should work.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let palette = document.getElementById("customization-palette");
- let placementsAfterMove = ["zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "developer-button",
- "sync-button",
- ];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- let paletteChildElementCount = palette.childElementCount;
- simulateItemDrag(editControls, palette);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- is(paletteChildElementCount + 1, palette.childElementCount,
- "The palette should have a new child, congratulations!");
- is(editControls.parentNode.id, "wrapper-edit-controls",
- "The edit-controls should be properly wrapped.");
- is(editControls.parentNode.getAttribute("place"), "palette",
- "The edit-controls should have the place of 'palette'.");
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(editControls, zoomControls);
- is(paletteChildElementCount, palette.childElementCount,
- "The palette child count should have returned to its prior value.");
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging the edit-controls to each of the panel placeholders
-// should append the edit-controls to the bottom of the panel.
-add_task(function*() {
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let numPlaceholders = 2;
- for (let i = 0; i < numPlaceholders; i++) {
- // This test relies on there being a specific number of widgets in the
- // panel. The addition of sync-button screwed this up, so we remove it
- // here. We should either fix the tests to not rely on the specific layout,
- // or fix bug 1007910 which would change the placeholder logic in different
- // ways. Bug 1229236 is for these tests to be smarter.
- CustomizableUI.removeWidgetFromArea("sync-button");
- // NB: We can't just iterate over all of the placeholders
- // because each drag-drop action recreates them.
- let placeholder = panel.getElementsByClassName("panel-customization-placeholder")[i];
- let placementsAfterMove = ["zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "edit-controls",
- "developer-button"];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, placeholder);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(editControls, zoomControls);
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
- }
-});
-
-// Dragging the open-file-button back on to itself should work.
-add_task(function*() {
- yield startCustomizing();
- let openFileButton = document.getElementById("open-file-button");
- is(openFileButton.parentNode.tagName, "toolbarpaletteitem",
- "open-file-button should be wrapped by a toolbarpaletteitem");
- simulateItemDrag(openFileButton, openFileButton);
- is(openFileButton.parentNode.tagName, "toolbarpaletteitem",
- "open-file-button should be wrapped by a toolbarpaletteitem");
- let editControls = document.getElementById("edit-controls");
- is(editControls.parentNode.tagName, "toolbarpaletteitem",
- "edit-controls should be wrapped by a toolbarpaletteitem");
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-// Dragging a small button onto the last big button should work.
-add_task(function*() {
- // Bug 1007910 requires there be a placeholder on the final row for this
- // test to work as written. The addition of sync-button meant that's not true
- // so we remove it from here. Bug 1229236 is for these tests to be smarter.
- CustomizableUI.removeWidgetFromArea("sync-button");
- yield startCustomizing();
- let editControls = document.getElementById("edit-controls");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let target = panel.getElementsByClassName("panel-customization-placeholder")[0];
- let placementsAfterMove = ["zoom-controls",
- "new-window-button",
- "privatebrowsing-button",
- "save-page-button",
- "print-button",
- "history-panelmenu",
- "fullscreen-button",
- "find-button",
- "preferences-button",
- "add-ons-button",
- "edit-controls",
- "developer-button"];
- removeDeveloperButtonIfDevEdition(placementsAfterMove);
- simulateItemDrag(editControls, target);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
- let itemToDrag = "email-link-button"; // any button in the palette by default.
- let button = document.getElementById(itemToDrag);
- placementsAfterMove.splice(11, 0, itemToDrag);
- simulateItemDrag(button, editControls);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
-
- // Put stuff back:
- let palette = document.getElementById("customization-palette");
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(button, palette);
- simulateItemDrag(editControls, zoomControls);
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_884402_customize_from_overflow.js b/browser/components/customizableui/test/browser_884402_customize_from_overflow.js
deleted file mode 100644
index f50767c06..000000000
--- a/browser/components/customizableui/test/browser_884402_customize_from_overflow.js
+++ /dev/null
@@ -1,81 +0,0 @@
-"use strict";
-
-var overflowPanel = document.getElementById("widget-overflow");
-
-const isOSX = (Services.appinfo.OS === "Darwin");
-
-var originalWindowWidth;
-registerCleanupFunction(function() {
- overflowPanel.removeAttribute("animate");
- window.resizeTo(originalWindowWidth, window.outerHeight);
-});
-
-// Right-click on an item within the overflow panel should
-// show a context menu with options to move it.
-add_task(function*() {
-
- overflowPanel.setAttribute("animate", "false");
-
- originalWindowWidth = window.outerWidth;
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- window.resizeTo(400, window.outerHeight);
-
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- let chevron = document.getElementById("nav-bar-overflow-button");
- let shownPanelPromise = promisePanelElementShown(window, overflowPanel);
- chevron.click();
- yield shownPanelPromise;
-
- let contextMenu = document.getElementById("toolbar-context-menu");
- let shownContextPromise = popupShown(contextMenu);
- let homeButton = document.getElementById("home-button");
- ok(homeButton, "home-button was found");
- is(homeButton.getAttribute("overflowedItem"), "true", "Home button is overflowing");
- EventUtils.synthesizeMouse(homeButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownContextPromise;
-
- is(overflowPanel.state, "open", "The widget overflow panel should still be open.");
-
- let expectedEntries = [
- [".customize-context-moveToPanel", true],
- [".customize-context-removeFromToolbar", true],
- ["---"]
- ];
- if (!isOSX) {
- expectedEntries.push(["#toggle_toolbar-menubar", true]);
- }
- expectedEntries.push(
- ["#toggle_PersonalToolbar", true],
- ["---"],
- [".viewCustomizeToolbar", true]
- );
- checkContextMenu(contextMenu, expectedEntries);
-
- let hiddenContextPromise = popupHidden(contextMenu);
- let hiddenPromise = promisePanelElementHidden(window, overflowPanel);
- let moveToPanel = contextMenu.querySelector(".customize-context-moveToPanel");
- if (moveToPanel) {
- moveToPanel.click();
- }
- contextMenu.hidePopup();
- yield hiddenContextPromise;
- yield hiddenPromise;
-
- let homeButtonPlacement = CustomizableUI.getPlacementOfWidget("home-button");
- ok(homeButtonPlacement, "Home button should still have a placement");
- is(homeButtonPlacement && homeButtonPlacement.area, "PanelUI-contents", "Home button should be in the panel now");
- CustomizableUI.reset();
-
- // In some cases, it can take a tick for the navbar to overflow again. Wait for it:
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- homeButtonPlacement = CustomizableUI.getPlacementOfWidget("home-button");
- ok(homeButtonPlacement, "Home button should still have a placement");
- is(homeButtonPlacement && homeButtonPlacement.area, "nav-bar", "Home button should be back in the navbar now");
-
- is(homeButton.getAttribute("overflowedItem"), "true", "Home button should still be overflowed");
-});
diff --git a/browser/components/customizableui/test/browser_885052_customize_mode_observers_disabed.js b/browser/components/customizableui/test/browser_885052_customize_mode_observers_disabed.js
deleted file mode 100644
index ea6f5a4e3..000000000
--- a/browser/components/customizableui/test/browser_885052_customize_mode_observers_disabed.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-function isFullscreenSizeMode() {
- let sizemode = document.documentElement.getAttribute("sizemode");
- return sizemode == "fullscreen";
-}
-
-// Observers should be disabled when in customization mode.
-add_task(function*() {
- // Open and close the panel to make sure that the
- // area is generated before getting a child of the area.
- let shownPanelPromise = promisePanelShown(window);
- PanelUI.toggle({type: "command"});
- yield shownPanelPromise;
- let hiddenPanelPromise = promisePanelHidden(window);
- PanelUI.toggle({type: "command"});
- yield hiddenPanelPromise;
-
- let fullscreenButton = document.getElementById("fullscreen-button");
- ok(!fullscreenButton.checked, "Fullscreen button should not be checked when not in fullscreen.")
- ok(!isFullscreenSizeMode(), "Should not be in fullscreen sizemode before we enter fullscreen.");
-
- BrowserFullScreen();
- yield waitForCondition(() => isFullscreenSizeMode());
- ok(fullscreenButton.checked, "Fullscreen button should be checked when in fullscreen.")
-
- yield startCustomizing();
-
- let fullscreenButtonWrapper = document.getElementById("wrapper-fullscreen-button");
- ok(fullscreenButtonWrapper.hasAttribute("itemobserves"), "Observer should be moved to wrapper");
- fullscreenButton = document.getElementById("fullscreen-button");
- ok(!fullscreenButton.hasAttribute("observes"), "Observer should be removed from button");
- ok(!fullscreenButton.checked, "Fullscreen button should no longer be checked during customization mode");
-
- yield endCustomizing();
-
- BrowserFullScreen();
- fullscreenButton = document.getElementById("fullscreen-button");
- yield waitForCondition(() => !isFullscreenSizeMode());
- ok(!fullscreenButton.checked, "Fullscreen button should not be checked when not in fullscreen.")
-});
diff --git a/browser/components/customizableui/test/browser_885530_showInPrivateBrowsing.js b/browser/components/customizableui/test/browser_885530_showInPrivateBrowsing.js
deleted file mode 100644
index e55c21862..000000000
--- a/browser/components/customizableui/test/browser_885530_showInPrivateBrowsing.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "some-widget";
-
-function assertWidgetExists(aWindow, aExists) {
- if (aExists) {
- ok(aWindow.document.getElementById(kWidgetId),
- "Should have found test widget in the window");
- } else {
- is(aWindow.document.getElementById(kWidgetId), null,
- "Should not have found test widget in the window");
- }
-}
-
-// A widget that is created with showInPrivateBrowsing undefined should
-// have that value default to true.
-add_task(function() {
- let wrapper = CustomizableUI.createWidget({
- id: kWidgetId
- });
- ok(wrapper.showInPrivateBrowsing,
- "showInPrivateBrowsing should have defaulted to true.");
- CustomizableUI.destroyWidget(kWidgetId);
-});
-
-// Add a widget via the API with showInPrivateBrowsing set to false
-// and ensure it does not appear in pre-existing or newly created
-// private windows.
-add_task(function*() {
- let plain1 = yield openAndLoadWindow();
- let private1 = yield openAndLoadWindow({private: true});
- CustomizableUI.createWidget({
- id: kWidgetId,
- removable: true,
- showInPrivateBrowsing: false
- });
- CustomizableUI.addWidgetToArea(kWidgetId,
- CustomizableUI.AREA_NAVBAR);
- assertWidgetExists(plain1, true);
- assertWidgetExists(private1, false);
-
- // Now open up some new windows. The widget should exist in the new
- // plain window, but not the new private window.
- let plain2 = yield openAndLoadWindow();
- let private2 = yield openAndLoadWindow({private: true});
- assertWidgetExists(plain2, true);
- assertWidgetExists(private2, false);
-
- // Try moving the widget around and make sure it doesn't get added
- // to the private windows. We'll start by appending it to the tabstrip.
- CustomizableUI.addWidgetToArea(kWidgetId,
- CustomizableUI.AREA_TABSTRIP);
- assertWidgetExists(plain1, true);
- assertWidgetExists(plain2, true);
- assertWidgetExists(private1, false);
- assertWidgetExists(private2, false);
-
- // And then move it to the beginning of the tabstrip.
- CustomizableUI.moveWidgetWithinArea(kWidgetId, 0);
- assertWidgetExists(plain1, true);
- assertWidgetExists(plain2, true);
- assertWidgetExists(private1, false);
- assertWidgetExists(private2, false);
-
- CustomizableUI.removeWidgetFromArea("some-widget");
- assertWidgetExists(plain1, false);
- assertWidgetExists(plain2, false);
- assertWidgetExists(private1, false);
- assertWidgetExists(private2, false);
-
- yield Promise.all([plain1, plain2, private1, private2].map(promiseWindowClosed));
-
- CustomizableUI.destroyWidget("some-widget");
-});
-
-// Add a widget via the API with showInPrivateBrowsing set to true,
-// and ensure that it appears in pre-existing or newly created
-// private browsing windows.
-add_task(function*() {
- let plain1 = yield openAndLoadWindow();
- let private1 = yield openAndLoadWindow({private: true});
-
- CustomizableUI.createWidget({
- id: kWidgetId,
- removable: true,
- showInPrivateBrowsing: true
- });
- CustomizableUI.addWidgetToArea(kWidgetId,
- CustomizableUI.AREA_NAVBAR);
- assertWidgetExists(plain1, true);
- assertWidgetExists(private1, true);
-
- // Now open up some new windows. The widget should exist in the new
- // plain window, but not the new private window.
- let plain2 = yield openAndLoadWindow();
- let private2 = yield openAndLoadWindow({private: true});
-
- assertWidgetExists(plain2, true);
- assertWidgetExists(private2, true);
-
- // Try moving the widget around and make sure it doesn't get added
- // to the private windows. We'll start by appending it to the tabstrip.
- CustomizableUI.addWidgetToArea(kWidgetId,
- CustomizableUI.AREA_TABSTRIP);
- assertWidgetExists(plain1, true);
- assertWidgetExists(plain2, true);
- assertWidgetExists(private1, true);
- assertWidgetExists(private2, true);
-
- // And then move it to the beginning of the tabstrip.
- CustomizableUI.moveWidgetWithinArea(kWidgetId, 0);
- assertWidgetExists(plain1, true);
- assertWidgetExists(plain2, true);
- assertWidgetExists(private1, true);
- assertWidgetExists(private2, true);
-
- CustomizableUI.removeWidgetFromArea("some-widget");
- assertWidgetExists(plain1, false);
- assertWidgetExists(plain2, false);
- assertWidgetExists(private1, false);
- assertWidgetExists(private2, false);
-
- yield Promise.all([plain1, plain2, private1, private2].map(promiseWindowClosed));
-
- CustomizableUI.destroyWidget("some-widget");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js b/browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js
deleted file mode 100644
index f46141c4f..000000000
--- a/browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kButtonId = "test-886323-removable-moved-node";
-const kLazyAreaId = "test-886323-lazy-area-for-removability-testing";
-
-var gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-var gLazyArea;
-
-// Removable nodes shouldn't be moved by buildArea
-add_task(function*() {
- let dummyBtn = createDummyXULButton(kButtonId, "Dummy");
- dummyBtn.setAttribute("removable", "true");
- gNavBar.customizationTarget.appendChild(dummyBtn);
- let popupSet = document.getElementById("mainPopupSet");
- gLazyArea = document.createElementNS(kNSXUL, "panel");
- gLazyArea.id = kLazyAreaId;
- gLazyArea.setAttribute("hidden", "true");
- popupSet.appendChild(gLazyArea);
- CustomizableUI.registerArea(kLazyAreaId, {
- type: CustomizableUI.TYPE_MENU_PANEL,
- defaultPlacements: []
- });
- CustomizableUI.addWidgetToArea(kButtonId, kLazyAreaId);
- assertAreaPlacements(kLazyAreaId, [kButtonId],
- "Placements should have changed because widget is removable.");
- let btn = document.getElementById(kButtonId);
- btn.setAttribute("removable", "false");
- gLazyArea.customizationTarget = gLazyArea;
- CustomizableUI.registerToolbarNode(gLazyArea, []);
- assertAreaPlacements(kLazyAreaId, [], "Placements should no longer include widget.");
- is(btn.parentNode.id, gNavBar.customizationTarget.id,
- "Button shouldn't actually have moved as it's not removable");
- btn = document.getElementById(kButtonId);
- if (btn) btn.remove();
- CustomizableUI.removeWidgetFromArea(kButtonId);
- CustomizableUI.unregisterArea(kLazyAreaId);
- gLazyArea.remove();
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_887438_currentset_shim.js b/browser/components/customizableui/test/browser_887438_currentset_shim.js
deleted file mode 100644
index a04299819..000000000
--- a/browser/components/customizableui/test/browser_887438_currentset_shim.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var navbar = document.getElementById("nav-bar");
-var navbarCT = navbar.customizationTarget;
-var overflowPanelList = document.getElementById("widget-overflow-list");
-
-// Reading currentset
-add_task(function() {
- let nodeIds = [];
- for (let node of navbarCT.childNodes) {
- if (node.getAttribute("skipintoolbarset") != "true") {
- nodeIds.push(node.id);
- }
- }
- for (let node of overflowPanelList.childNodes) {
- if (node.getAttribute("skipintoolbarset") != "true") {
- nodeIds.push(node.id);
- }
- }
- let currentSet = navbar.currentSet;
- is(currentSet.split(',').length, nodeIds.length, "Should be just as many nodes as there are.");
- is(currentSet, nodeIds.join(','), "Current set and node IDs should match.");
-});
-
-// Insert, then remove items
-add_task(function() {
- let currentSet = navbar.currentSet;
- let newCurrentSet = currentSet.replace('home-button', 'feed-button,sync-button,home-button');
- navbar.currentSet = newCurrentSet;
- is(newCurrentSet, navbar.currentSet, "Current set should match expected current set.");
- let feedBtn = document.getElementById("feed-button");
- let syncBtn = document.getElementById("sync-button");
- ok(feedBtn, "Feed button should have been added.");
- ok(syncBtn, "Sync button should have been added.");
- if (feedBtn && syncBtn) {
- let feedParent = feedBtn.parentNode;
- let syncParent = syncBtn.parentNode;
- ok(feedParent == navbarCT || feedParent == overflowPanelList,
- "Feed button should be in navbar or overflow");
- ok(syncParent == navbarCT || syncParent == overflowPanelList,
- "Feed button should be in navbar or overflow");
- is(feedBtn.nextElementSibling, syncBtn, "Feed button should be next to sync button.");
- let homeBtn = document.getElementById("home-button");
- is(syncBtn.nextElementSibling, homeBtn, "Sync button should be next to home button.");
- }
- navbar.currentSet = currentSet;
- is(currentSet, navbar.currentSet, "Should be able to remove the added items.");
-});
-
-// Simultaneous insert/remove:
-add_task(function() {
- let currentSet = navbar.currentSet;
- let newCurrentSet = currentSet.replace('home-button', 'feed-button');
- navbar.currentSet = newCurrentSet;
- is(newCurrentSet, navbar.currentSet, "Current set should match expected current set.");
- let feedBtn = document.getElementById("feed-button");
- ok(feedBtn, "Feed button should have been added.");
- let homeBtn = document.getElementById("home-button");
- ok(!homeBtn, "Home button should have been removed.");
- if (feedBtn) {
- let feedParent = feedBtn.parentNode;
- ok(feedParent == navbarCT || feedParent == overflowPanelList,
- "Feed button should be in navbar or overflow");
- }
- navbar.currentSet = currentSet;
- is(currentSet, navbar.currentSet, "Should be able to return to original state.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_888817_currentset_updating.js b/browser/components/customizableui/test/browser_888817_currentset_updating.js
deleted file mode 100644
index 6e7c4e95a..000000000
--- a/browser/components/customizableui/test/browser_888817_currentset_updating.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Adding, moving and removing items should update the relevant currentset attributes
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Should be in the default state when we start");
- let personalbar = document.getElementById(CustomizableUI.AREA_BOOKMARKS);
- setToolbarVisibility(personalbar, true);
- ok(!CustomizableUI.inDefaultState, "Making the bookmarks toolbar visible takes it out of the default state");
-
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- personalbar = document.getElementById(CustomizableUI.AREA_BOOKMARKS);
- let navbarCurrentset = navbar.getAttribute("currentset") || navbar.currentSet;
- let personalbarCurrentset = personalbar.getAttribute("currentset") || personalbar.currentSet;
-
- let otherWin = yield openAndLoadWindow();
- let otherNavbar = otherWin.document.getElementById(CustomizableUI.AREA_NAVBAR);
- let otherPersonalbar = otherWin.document.getElementById(CustomizableUI.AREA_BOOKMARKS);
-
- CustomizableUI.moveWidgetWithinArea("home-button", 0);
- navbarCurrentset = "home-button," + navbarCurrentset.replace(",home-button", "");
- is(navbar.getAttribute("currentset"), navbarCurrentset,
- "Should have updated currentSet after move.");
- is(otherNavbar.getAttribute("currentset"), navbarCurrentset,
- "Should have updated other window's currentSet after move.");
-
- CustomizableUI.addWidgetToArea("home-button", CustomizableUI.AREA_BOOKMARKS);
- navbarCurrentset = navbarCurrentset.replace("home-button,", "");
- personalbarCurrentset = personalbarCurrentset + ",home-button";
- is(navbar.getAttribute("currentset"), navbarCurrentset,
- "Should have updated navbar currentSet after implied remove.");
- is(otherNavbar.getAttribute("currentset"), navbarCurrentset,
- "Should have updated other window's navbar currentSet after implied remove.");
- is(personalbar.getAttribute("currentset"), personalbarCurrentset,
- "Should have updated personalbar currentSet after add.");
- is(otherPersonalbar.getAttribute("currentset"), personalbarCurrentset,
- "Should have updated other window's personalbar currentSet after add.");
-
- CustomizableUI.removeWidgetFromArea("home-button");
- personalbarCurrentset = personalbarCurrentset.replace(",home-button", "");
- is(personalbar.getAttribute("currentset"), personalbarCurrentset,
- "Should have updated currentSet after remove.");
- is(otherPersonalbar.getAttribute("currentset"), personalbarCurrentset,
- "Should have updated other window's currentSet after remove.");
-
- yield promiseWindowClosed(otherWin);
- // Reset in asyncCleanup will put our button back for us.
-});
-
-add_task(function* asyncCleanup() {
- let personalbar = document.getElementById(CustomizableUI.AREA_BOOKMARKS);
- setToolbarVisibility(personalbar, false);
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_890140_orphaned_placeholders.js b/browser/components/customizableui/test/browser_890140_orphaned_placeholders.js
deleted file mode 100644
index 84b126a9b..000000000
--- a/browser/components/customizableui/test/browser_890140_orphaned_placeholders.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// One orphaned item should have two placeholders next to it.
-add_task(function*() {
- yield startCustomizing();
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_PANEL);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- }
- if (!isInDevEdition()) {
- ok(CustomizableUI.inDefaultState, "Should be in default state.");
- } else {
- ok(!CustomizableUI.inDefaultState, "Should not be in default state if on DevEdition.");
- }
-
- // This test relies on an exact number of widgets being in the panel.
- // Remove the sync-button to satisfy that. (bug 1229236)
- CustomizableUI.removeWidgetFromArea("sync-button");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
-
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placements);
- is(getVisiblePlaceholderCount(panel), 2, "Should only have 2 visible placeholders before exiting");
-
- yield endCustomizing();
- yield startCustomizing();
- is(getVisiblePlaceholderCount(panel), 2, "Should only have 2 visible placeholders after re-entering");
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_NAVBAR, 2);
- }
-
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Two orphaned items should have one placeholder next to them (case 1).
-add_task(function*() {
- yield startCustomizing();
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_PANEL);
- }
-
- // This test relies on an exact number of widgets being in the panel.
- // Remove the sync-button to satisfy that. (bug 1229236)
- CustomizableUI.removeWidgetFromArea("sync-button");
-
- let btn = document.getElementById("open-file-button");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
- let placementsAfterAppend = placements;
-
- placementsAfterAppend = placements.concat(["open-file-button"]);
- simulateItemDrag(btn, panel);
-
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
-
- ok(!CustomizableUI.inDefaultState, "Should not be in default state.");
-
- is(getVisiblePlaceholderCount(panel), 1, "Should only have 1 visible placeholder before exiting");
-
- yield endCustomizing();
- yield startCustomizing();
- is(getVisiblePlaceholderCount(panel), 1, "Should only have 1 visible placeholder after re-entering");
-
- let palette = document.getElementById("customization-palette");
- simulateItemDrag(btn, palette);
-
- btn = document.getElementById("open-file-button");
- simulateItemDrag(btn, palette);
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_NAVBAR, 2);
- }
-
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// Two orphaned items should have one placeholder next to them (case 2).
-add_task(function*() {
- yield startCustomizing();
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_PANEL);
- }
- // This test relies on an exact number of widgets being in the panel.
- // Remove the sync-button to satisfy that. (bug 1229236)
- CustomizableUI.removeWidgetFromArea("sync-button");
-
- let btn = document.getElementById("add-ons-button");
- let btn2 = document.getElementById("developer-button");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let palette = document.getElementById("customization-palette");
- let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
-
- let placementsAfterAppend = placements.filter(p => p != btn.id && p != btn2.id);
- simulateItemDrag(btn, palette);
- simulateItemDrag(btn2, palette);
-
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- is(getVisiblePlaceholderCount(panel), 1, "Should only have 1 visible placeholder before exiting");
-
- yield endCustomizing();
- yield startCustomizing();
- is(getVisiblePlaceholderCount(panel), 1, "Should only have 1 visible placeholder after re-entering");
-
- simulateItemDrag(btn, panel);
- simulateItemDrag(btn2, panel);
-
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placements);
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_NAVBAR, 2);
- }
-
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// A wide widget at the bottom of the panel should have three placeholders after it.
-add_task(function*() {
- yield startCustomizing();
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_PANEL);
- }
-
- // This test relies on an exact number of widgets being in the panel.
- // Remove the sync-button to satisfy that. (bug 1229236)
- CustomizableUI.removeWidgetFromArea("sync-button");
-
- let btn = document.getElementById("edit-controls");
- let btn2 = document.getElementById("developer-button");
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- let palette = document.getElementById("customization-palette");
- let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
-
- placements.pop();
- simulateItemDrag(btn2, palette);
-
- let placementsAfterAppend = placements.concat([placements.shift()]);
- simulateItemDrag(btn, panel);
- assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
- is(getVisiblePlaceholderCount(panel), 3, "Should have 3 visible placeholders before exiting");
-
- yield endCustomizing();
- yield startCustomizing();
- is(getVisiblePlaceholderCount(panel), 3, "Should have 3 visible placeholders after re-entering");
-
- simulateItemDrag(btn2, panel);
-
- let zoomControls = document.getElementById("zoom-controls");
- simulateItemDrag(btn, zoomControls);
-
- if (isInDevEdition()) {
- CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_NAVBAR, 2);
- }
-
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should be in default state again.");
-});
-
-// The default placements should have two placeholders at the bottom (or 1 in win8).
-add_task(function*() {
- yield startCustomizing();
- let numPlaceholders = -1;
-
- if (isInDevEdition()) {
- numPlaceholders = 3;
- } else {
- numPlaceholders = 2;
- }
-
- let panel = document.getElementById(CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should be in default state.");
-
- // This test relies on an exact number of widgets being in the panel.
- // Remove the sync-button to satisfy that. (bug 1229236)
- CustomizableUI.removeWidgetFromArea("sync-button");
-
- is(getVisiblePlaceholderCount(panel), numPlaceholders, "Should have " + numPlaceholders + " visible placeholders before exiting");
-
- yield endCustomizing();
- yield startCustomizing();
- is(getVisiblePlaceholderCount(panel), numPlaceholders, "Should have " + numPlaceholders + " visible placeholders after re-entering");
-
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- ok(CustomizableUI.inDefaultState, "Should still be in default state.");
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
-
-function getVisiblePlaceholderCount(aPanel) {
- let visiblePlaceholders = aPanel.querySelectorAll(".panel-customization-placeholder:not([hidden=true])");
- return visiblePlaceholders.length;
-}
diff --git a/browser/components/customizableui/test/browser_890262_destroyWidget_after_add_to_panel.js b/browser/components/customizableui/test/browser_890262_destroyWidget_after_add_to_panel.js
deleted file mode 100644
index 13f2bd7ba..000000000
--- a/browser/components/customizableui/test/browser_890262_destroyWidget_after_add_to_panel.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kLazyAreaId = "test-890262-lazy-area";
-const kWidget1Id = "test-890262-widget1";
-const kWidget2Id = "test-890262-widget2";
-
-setupArea();
-
-// Destroying a widget after defaulting it to a non-legacy area should work.
-add_task(function() {
- CustomizableUI.createWidget({
- id: kWidget1Id,
- removable: true,
- defaultArea: kLazyAreaId
- });
- let noError = true;
- try {
- CustomizableUI.destroyWidget(kWidget1Id);
- } catch (ex) {
- Cu.reportError(ex);
- noError = false;
- }
- ok(noError, "Shouldn't throw an exception for a widget that was created in a not-yet-constructed area");
-});
-
-// Destroying a widget after moving it to a non-legacy area should work.
-add_task(function() {
- CustomizableUI.createWidget({
- id: kWidget2Id,
- removable: true,
- defaultArea: CustomizableUI.AREA_NAVBAR
- });
-
- CustomizableUI.addWidgetToArea(kWidget2Id, kLazyAreaId);
- let noError = true;
- try {
- CustomizableUI.destroyWidget(kWidget2Id);
- } catch (ex) {
- Cu.reportError(ex);
- noError = false;
- }
- ok(noError, "Shouldn't throw an exception for a widget that was added to a not-yet-constructed area");
-});
-
-add_task(function* asyncCleanup() {
- let lazyArea = document.getElementById(kLazyAreaId);
- if (lazyArea) {
- lazyArea.remove();
- }
- try {
- CustomizableUI.unregisterArea(kLazyAreaId);
- } catch (ex) {} // If we didn't register successfully for some reason
- yield resetCustomization();
-});
-
-function setupArea() {
- let lazyArea = document.createElementNS(kNSXUL, "hbox");
- lazyArea.id = kLazyAreaId;
- document.getElementById("nav-bar").appendChild(lazyArea);
- CustomizableUI.registerArea(kLazyAreaId, {
- type: CustomizableUI.TYPE_TOOLBAR,
- defaultPlacements: []
- });
-}
diff --git a/browser/components/customizableui/test/browser_892955_isWidgetRemovable_for_removed_widgets.js b/browser/components/customizableui/test/browser_892955_isWidgetRemovable_for_removed_widgets.js
deleted file mode 100644
index 67ef82b82..000000000
--- a/browser/components/customizableui/test/browser_892955_isWidgetRemovable_for_removed_widgets.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "test-892955-remove-widget";
-
-// Removing a destroyed widget should work.
-add_task(function*() {
- let widgetSpec = {
- id: kWidgetId,
- defaultArea: CustomizableUI.AREA_NAVBAR
- };
-
- CustomizableUI.createWidget(widgetSpec);
- CustomizableUI.destroyWidget(kWidgetId);
- let noError = true;
- try {
- CustomizableUI.removeWidgetFromArea(kWidgetId);
- } catch (ex) {
- noError = false;
- Cu.reportError(ex);
- }
- ok(noError, "Shouldn't throw an error removing a destroyed widget.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_892956_destroyWidget_defaultPlacements.js b/browser/components/customizableui/test/browser_892956_destroyWidget_defaultPlacements.js
deleted file mode 100644
index c7047c797..000000000
--- a/browser/components/customizableui/test/browser_892956_destroyWidget_defaultPlacements.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "test-892956-destroyWidget-defaultPlacement";
-
-// destroyWidget should clean up defaultPlacements if the widget had a defaultArea
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Should be in the default state when we start");
-
- let widgetSpec = {
- id: kWidgetId,
- defaultArea: CustomizableUI.AREA_NAVBAR
- };
- CustomizableUI.createWidget(widgetSpec);
- CustomizableUI.destroyWidget(kWidgetId);
- ok(CustomizableUI.inDefaultState, "Should be in the default state when we finish");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_901207_searchbar_in_panel.js b/browser/components/customizableui/test/browser_901207_searchbar_in_panel.js
deleted file mode 100644
index 3bc449add..000000000
--- a/browser/components/customizableui/test/browser_901207_searchbar_in_panel.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-logActiveElement();
-
-function* waitForSearchBarFocus()
-{
- let searchbar = document.getElementById("searchbar");
- yield waitForCondition(function () {
- logActiveElement();
- return document.activeElement === searchbar.textbox.inputField;
- });
-}
-
-// Ctrl+K should open the menu panel and focus the search bar if the search bar is in the panel.
-add_task(function*() {
- let searchbar = document.getElementById("searchbar");
- gCustomizeMode.addToPanel(searchbar);
- let placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
-
- let shownPanelPromise = promisePanelShown(window);
- sendWebSearchKeyCommand();
- yield shownPanelPromise;
-
- yield waitForSearchBarFocus();
-
- let hiddenPanelPromise = promisePanelHidden(window);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield hiddenPanelPromise;
- CustomizableUI.reset();
-});
-
-// Ctrl+K should give focus to the searchbar when the searchbar is in the menupanel and the panel is already opened.
-add_task(function*() {
- let searchbar = document.getElementById("searchbar");
- gCustomizeMode.addToPanel(searchbar);
- let placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
-
- let shownPanelPromise = promisePanelShown(window);
- PanelUI.toggle({type: "command"});
- yield shownPanelPromise;
-
- sendWebSearchKeyCommand();
-
- yield waitForSearchBarFocus();
-
- let hiddenPanelPromise = promisePanelHidden(window);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield hiddenPanelPromise;
- CustomizableUI.reset();
-});
-
-// Ctrl+K should open the overflow panel and focus the search bar if the search bar is overflowed.
-add_task(function*() {
- this.originalWindowWidth = window.outerWidth;
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
-
- window.resizeTo(360, window.outerHeight);
- yield waitForCondition(() => navbar.getAttribute("overflowing") == "true");
- ok(!navbar.querySelector("#search-container"), "Search container should be overflowing");
-
- let shownPanelPromise = promiseOverflowShown(window);
- sendWebSearchKeyCommand();
- yield shownPanelPromise;
-
- let chevron = document.getElementById("nav-bar-overflow-button");
- yield waitForCondition(() => chevron.open);
-
- yield waitForSearchBarFocus();
-
- let hiddenPanelPromise = promiseOverflowHidden(window);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield hiddenPanelPromise;
- navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- window.resizeTo(this.originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
- ok(!navbar.hasAttribute("overflowing"), "Should not have an overflowing toolbar.");
-});
-
-// Ctrl+K should focus the search bar if it is in the navbar and not overflowing.
-add_task(function*() {
- let placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_NAVBAR, "Should be in nav-bar");
-
- sendWebSearchKeyCommand();
-
- yield waitForSearchBarFocus();
-});
-
-
-function sendWebSearchKeyCommand() {
- if (Services.appinfo.OS === "Darwin")
- EventUtils.synthesizeKey("k", { accelKey: true });
- else
- EventUtils.synthesizeKey("k", { ctrlKey: true });
-}
-
-function logActiveElement() {
- let element = document.activeElement;
- let str = "";
- while (element && element.parentNode) {
- str = " (" + element.localName + "#" + element.id + "." + [...element.classList].join(".") + ") >" + str;
- element = element.parentNode;
- }
- info("Active element: " + element ? str : "null");
-}
diff --git a/browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js b/browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js
deleted file mode 100644
index f39d13ff4..000000000
--- a/browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Resize to a small window, open a new window, check that new window handles overflow properly
-add_task(function*() {
- let originalWindowWidth = window.outerWidth;
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- let oldChildCount = navbar.customizationTarget.childElementCount;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- ok(navbar.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
- let newWindow = yield openAndLoadWindow();
- let otherNavBar = newWindow.document.getElementById(CustomizableUI.AREA_NAVBAR);
- yield waitForCondition(() => otherNavBar.hasAttribute("overflowing"));
- ok(otherNavBar.hasAttribute("overflowing"), "Other window should have an overflowing toolbar.");
- yield promiseWindowClosed(newWindow);
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
- ok(!navbar.hasAttribute("overflowing"), "Should no longer have an overflowing toolbar.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_913972_currentset_overflow.js b/browser/components/customizableui/test/browser_913972_currentset_overflow.js
deleted file mode 100644
index 7d754d79b..000000000
--- a/browser/components/customizableui/test/browser_913972_currentset_overflow.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
-// Resize to a small window, resize back, shouldn't affect currentSet
-add_task(function*() {
- let originalWindowWidth = window.outerWidth;
- let oldCurrentSet = navbar.currentSet;
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
- let oldChildCount = navbar.customizationTarget.childElementCount;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
- is(navbar.currentSet, oldCurrentSet, "Currentset should be the same when overflowing.");
- ok(CustomizableUI.inDefaultState, "Should still be in default state when overflowing.");
- ok(navbar.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
- ok(!navbar.hasAttribute("overflowing"), "Should no longer have an overflowing toolbar.");
- is(navbar.currentSet, oldCurrentSet, "Currentset should still be the same now we're no longer overflowing.");
- ok(CustomizableUI.inDefaultState, "Should still be in default state now we're no longer overflowing.");
-
- // Verify actual physical placements match those of the placement array:
- let placementCounter = 0;
- let placements = CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_NAVBAR);
- for (let node of navbar.customizationTarget.childNodes) {
- if (node.getAttribute("skipintoolbarset") == "true") {
- continue;
- }
- is(placements[placementCounter++], node.id, "Nodes should match after overflow");
- }
- is(placements.length, placementCounter, "Should have as many nodes as expected");
- is(navbar.customizationTarget.childElementCount, oldChildCount, "Number of nodes should match");
-});
-
-// Enter and exit customization mode, check that currentSet works
-add_task(function*() {
- let oldCurrentSet = navbar.currentSet;
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
- yield startCustomizing();
- ok(CustomizableUI.inDefaultState, "Should be in default state in customization mode.");
- is(navbar.currentSet, oldCurrentSet, "Currentset should be the same in customization mode.");
- yield endCustomizing();
- ok(CustomizableUI.inDefaultState, "Should be in default state after customization mode.");
- is(navbar.currentSet, oldCurrentSet, "Currentset should be the same after customization mode.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_914138_widget_API_overflowable_toolbar.js b/browser/components/customizableui/test/browser_914138_widget_API_overflowable_toolbar.js
deleted file mode 100644
index 35ba79bec..000000000
--- a/browser/components/customizableui/test/browser_914138_widget_API_overflowable_toolbar.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-var overflowList = document.getElementById(navbar.getAttribute("overflowtarget"));
-
-const kTestBtn1 = "test-addWidgetToArea-overflow";
-const kTestBtn2 = "test-removeWidgetFromArea-overflow";
-const kTestBtn3 = "test-createWidget-overflow";
-const kHomeBtn = "home-button";
-const kDownloadsBtn = "downloads-button";
-const kSearchBox = "search-container";
-const kStarBtn = "bookmarks-menu-button";
-
-var originalWindowWidth;
-
-// Adding a widget should add it next to the widget it's being inserted next to.
-add_task(function*() {
- originalWindowWidth = window.outerWidth;
- createDummyXULButton(kTestBtn1, "Test");
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
-
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
- ok(!navbar.querySelector("#" + kHomeBtn), "Home button should no longer be in the navbar");
- let homeBtnNode = overflowList.querySelector("#" + kHomeBtn);
- ok(homeBtnNode, "Home button should be overflowing");
- ok(homeBtnNode && homeBtnNode.getAttribute("overflowedItem") == "true", "Home button should have overflowedItem attribute");
-
- let placementOfHomeButton = CustomizableUI.getWidgetIdsInArea(navbar.id).indexOf(kHomeBtn);
- CustomizableUI.addWidgetToArea(kTestBtn1, navbar.id, placementOfHomeButton);
- ok(!navbar.querySelector("#" + kTestBtn1), "New button should not be in the navbar");
- let newButtonNode = overflowList.querySelector("#" + kTestBtn1);
- ok(newButtonNode, "New button should be overflowing");
- ok(newButtonNode && newButtonNode.getAttribute("overflowedItem") == "true", "New button should have overflowedItem attribute");
- let nextEl = newButtonNode && newButtonNode.nextSibling;
- is(nextEl && nextEl.id, kHomeBtn, "Test button should be next to home button.");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
- ok(!navbar.hasAttribute("overflowing"), "Should not have an overflowing toolbar.");
- ok(navbar.querySelector("#" + kHomeBtn), "Home button should be in the navbar");
- ok(homeBtnNode && (homeBtnNode.getAttribute("overflowedItem") != "true"), "Home button should no longer have overflowedItem attribute");
- ok(!overflowList.querySelector("#" + kHomeBtn), "Home button should no longer be overflowing");
- ok(navbar.querySelector("#" + kTestBtn1), "Test button should be in the navbar");
- ok(!overflowList.querySelector("#" + kTestBtn1), "Test button should no longer be overflowing");
- ok(newButtonNode && (newButtonNode.getAttribute("overflowedItem") != "true"), "New button should no longer have overflowedItem attribute");
- let el = document.getElementById(kTestBtn1);
- if (el) {
- CustomizableUI.removeWidgetFromArea(kTestBtn1);
- el.remove();
- }
- window.resizeTo(originalWindowWidth, window.outerHeight);
-});
-
-// Removing a widget should remove it from the overflow list if that is where it is, and update it accordingly.
-add_task(function*() {
- createDummyXULButton(kTestBtn2, "Test");
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
- CustomizableUI.addWidgetToArea(kTestBtn2, navbar.id);
- ok(!navbar.hasAttribute("overflowing"), "Should still have a non-overflowing toolbar.");
-
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
- ok(!navbar.querySelector("#" + kTestBtn2), "Test button should not be in the navbar");
- ok(overflowList.querySelector("#" + kTestBtn2), "Test button should be overflowing");
-
- CustomizableUI.removeWidgetFromArea(kTestBtn2);
-
- ok(!overflowList.querySelector("#" + kTestBtn2), "Test button should not be overflowing.");
- ok(!navbar.querySelector("#" + kTestBtn2), "Test button should not be in the navbar");
- ok(gNavToolbox.palette.querySelector("#" + kTestBtn2), "Test button should be in the palette");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
- ok(!navbar.hasAttribute("overflowing"), "Should not have an overflowing toolbar.");
- let el = document.getElementById(kTestBtn2);
- if (el) {
- CustomizableUI.removeWidgetFromArea(kTestBtn2);
- el.remove();
- }
- window.resizeTo(originalWindowWidth, window.outerHeight);
-});
-
-// Constructing a widget while overflown should set the right class on it.
-add_task(function*() {
- originalWindowWidth = window.outerWidth;
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
-
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
- ok(!navbar.querySelector("#" + kHomeBtn), "Home button should no longer be in the navbar");
- let homeBtnNode = overflowList.querySelector("#" + kHomeBtn);
- ok(homeBtnNode, "Home button should be overflowing");
- ok(homeBtnNode && homeBtnNode.getAttribute("overflowedItem") == "true", "Home button should have overflowedItem class");
-
- let testBtnSpec = {id: kTestBtn3, label: "Overflowable widget test", defaultArea: "nav-bar"};
- CustomizableUI.createWidget(testBtnSpec);
- let testNode = overflowList.querySelector("#" + kTestBtn3);
- ok(testNode, "Test button should be overflowing");
- ok(testNode && testNode.getAttribute("overflowedItem") == "true", "Test button should have overflowedItem class");
-
- CustomizableUI.destroyWidget(kTestBtn3);
- testNode = document.getElementById(kTestBtn3);
- ok(!testNode, "Test button should be gone");
-
- CustomizableUI.createWidget(testBtnSpec);
- testNode = overflowList.querySelector("#" + kTestBtn3);
- ok(testNode, "Test button should be overflowing");
- ok(testNode && testNode.getAttribute("overflowedItem") == "true", "Test button should have overflowedItem class");
-
- CustomizableUI.removeWidgetFromArea(kTestBtn3);
- testNode = document.getElementById(kTestBtn3);
- ok(!testNode, "Test button should be gone");
- CustomizableUI.destroyWidget(kTestBtn3);
- window.resizeTo(originalWindowWidth, window.outerHeight);
-});
-
-add_task(function* asyncCleanup() {
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_914863_disabled_help_quit_buttons.js b/browser/components/customizableui/test/browser_914863_disabled_help_quit_buttons.js
deleted file mode 100644
index b5757eabb..000000000
--- a/browser/components/customizableui/test/browser_914863_disabled_help_quit_buttons.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Entering then exiting customization mode should reenable the Help and Exit buttons.
-add_task(function*() {
- yield startCustomizing();
- let helpButton = document.getElementById("PanelUI-help");
- let quitButton = document.getElementById("PanelUI-quit");
- ok(helpButton.getAttribute("disabled") == "true", "Help button should be disabled while in customization mode.");
- ok(quitButton.getAttribute("disabled") == "true", "Quit button should be disabled while in customization mode.");
- yield endCustomizing();
-
- ok(!helpButton.hasAttribute("disabled"), "Help button should not be disabled.");
- ok(!quitButton.hasAttribute("disabled"), "Quit button should not be disabled.");
-});
diff --git a/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js b/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
deleted file mode 100644
index dffe388dc..000000000
--- a/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var navbar;
-var skippedItem;
-
-// Attempting to drag a skipintoolbarset item should work.
-add_task(function*() {
- navbar = document.getElementById("nav-bar");
- skippedItem = document.createElement("toolbarbutton");
- skippedItem.id = "test-skipintoolbarset-item";
- skippedItem.setAttribute("label", "Test");
- skippedItem.setAttribute("skipintoolbarset", "true");
- skippedItem.setAttribute("removable", "true");
- navbar.customizationTarget.appendChild(skippedItem);
- let downloadsButton = document.getElementById("downloads-button");
- yield startCustomizing();
- ok(CustomizableUI.inDefaultState, "Should still be in default state");
- simulateItemDrag(skippedItem, downloadsButton);
- ok(CustomizableUI.inDefaultState, "Should still be in default state");
- let skippedItemWrapper = skippedItem.parentNode;
- is(skippedItemWrapper.nextSibling && skippedItemWrapper.nextSibling.id,
- downloadsButton.parentNode.id, "Should be next to downloads button");
- simulateItemDrag(downloadsButton, skippedItem);
- let downloadWrapper = downloadsButton.parentNode;
- is(downloadWrapper.nextSibling && downloadWrapper.nextSibling.id,
- skippedItem.parentNode.id, "Should be next to skipintoolbarset item");
- ok(CustomizableUI.inDefaultState, "Should still be in default state");
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- skippedItem.remove();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_923857_customize_mode_event_wrapping_during_reset.js b/browser/components/customizableui/test/browser_923857_customize_mode_event_wrapping_during_reset.js
deleted file mode 100644
index 87aca51eb..000000000
--- a/browser/components/customizableui/test/browser_923857_customize_mode_event_wrapping_during_reset.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Customize mode reset button should revert correctly
-add_task(function*() {
- yield startCustomizing();
- let devButton = document.getElementById("developer-button");
- let downloadsButton = document.getElementById("downloads-button");
- let searchBox = document.getElementById("search-container");
- let palette = document.getElementById("customization-palette");
- ok(devButton && downloadsButton && searchBox && palette, "Stuff should exist");
- simulateItemDrag(devButton, downloadsButton);
- simulateItemDrag(searchBox, palette);
- yield gCustomizeMode.reset();
- ok(CustomizableUI.inDefaultState, "Should be back in default state");
- yield endCustomizing();
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_927717_customize_drag_empty_toolbar.js b/browser/components/customizableui/test/browser_927717_customize_drag_empty_toolbar.js
deleted file mode 100644
index d79f6e364..000000000
--- a/browser/components/customizableui/test/browser_927717_customize_drag_empty_toolbar.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kTestToolbarId = "test-empty-drag";
-
-// Attempting to drag an item to an empty container should work.
-add_task(function*() {
- yield createToolbarWithPlacements(kTestToolbarId, []);
- yield startCustomizing();
- let downloadButton = document.getElementById("downloads-button");
- let customToolbar = document.getElementById(kTestToolbarId);
- simulateItemDrag(downloadButton, customToolbar);
- assertAreaPlacements(kTestToolbarId, ["downloads-button"]);
- ok(downloadButton.parentNode && downloadButton.parentNode.parentNode == customToolbar,
- "Button should really be in toolbar");
- yield endCustomizing();
- removeCustomToolbars();
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_932928_show_notice_when_palette_empty.js b/browser/components/customizableui/test/browser_932928_show_notice_when_palette_empty.js
deleted file mode 100644
index 3cbf6be42..000000000
--- a/browser/components/customizableui/test/browser_932928_show_notice_when_palette_empty.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// There should be an advert to get more addons when the palette is empty.
-add_task(function*() {
- yield startCustomizing();
- let visiblePalette = document.getElementById("customization-palette");
- let emptyPaletteNotice = document.getElementById("customization-empty");
- is(emptyPaletteNotice.hidden, true, "The empty palette notice should not be shown when there are items in the palette.");
-
- while (visiblePalette.childElementCount) {
- gCustomizeMode.addToToolbar(visiblePalette.children[0]);
- }
- is(visiblePalette.childElementCount, 0, "There shouldn't be any items remaining in the visible palette.");
- is(emptyPaletteNotice.hidden, false, "The empty palette notice should be shown when there are no items in the palette.");
-
- yield endCustomizing();
- yield startCustomizing();
- visiblePalette = document.getElementById("customization-palette");
- emptyPaletteNotice = document.getElementById("customization-empty");
- is(emptyPaletteNotice.hidden, false,
- "The empty palette notice should be shown when there are no items in the palette and cust. mode is re-entered.");
-
- gCustomizeMode.removeFromArea(document.getElementById("wrapper-home-button"));
- is(emptyPaletteNotice.hidden, true,
- "The empty palette notice should not be shown when there is at least one item in the palette.");
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_934113_menubar_removable.js b/browser/components/customizableui/test/browser_934113_menubar_removable.js
deleted file mode 100644
index 1d788bced..000000000
--- a/browser/components/customizableui/test/browser_934113_menubar_removable.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Attempting to drag the menubar to the navbar shouldn't work.
-add_task(function*() {
- yield startCustomizing();
- let menuItems = document.getElementById("menubar-items");
- let navbar = document.getElementById("nav-bar");
- let menubar = document.getElementById("toolbar-menubar");
- // Force the menu to be shown.
- const kAutohide = menubar.getAttribute("autohide");
- menubar.setAttribute("autohide", "false");
- simulateItemDrag(menuItems, navbar.customizationTarget);
-
- is(getAreaWidgetIds("nav-bar").indexOf("menubar-items"), -1, "Menu bar shouldn't be in the navbar.");
- ok(!navbar.querySelector("#menubar-items"), "Shouldn't find menubar items in the navbar.");
- ok(menubar.querySelector("#menubar-items"), "Should find menubar items in the menubar.");
- isnot(getAreaWidgetIds("toolbar-menubar").indexOf("menubar-items"), -1,
- "Menubar items shouldn't be missing from the navbar.");
- menubar.setAttribute("autohide", kAutohide);
- yield endCustomizing();
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js b/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
deleted file mode 100644
index dcc183051..000000000
--- a/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kTimeoutInMS = 20000;
-
-// Bug 934951 - Zoom controls percentage label doesn't update when it's in the toolbar and you navigate.
-add_task(function*() {
- CustomizableUI.addWidgetToArea("zoom-controls", CustomizableUI.AREA_NAVBAR);
- let tab1 = gBrowser.addTab("about:mozilla");
- yield BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
- let tab2 = gBrowser.addTab("about:robots");
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
- gBrowser.selectedTab = tab1;
- let zoomResetButton = document.getElementById("zoom-reset-button");
-
- registerCleanupFunction(() => {
- info("Cleaning up.");
- CustomizableUI.reset();
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab1);
- });
-
- is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla");
- let zoomChangePromise = promiseObserverNotification("browser-fullZoom:zoomChange");
- FullZoom.enlarge();
- yield zoomChangePromise;
- is(parseInt(zoomResetButton.label, 10), 110, "Zoom is changed to 110% for about:mozilla");
-
- let tabSelectPromise = promiseTabSelect();
- gBrowser.selectedTab = tab2;
- yield tabSelectPromise;
- is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:robots");
-
- gBrowser.selectedTab = tab1;
- let zoomResetPromise = promiseObserverNotification("browser-fullZoom:zoomReset");
- FullZoom.reset();
- yield zoomResetPromise;
- is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla");
-
- // Test zoom label updates while navigating pages in the same tab.
- FullZoom.enlarge();
- yield zoomChangePromise;
- is(parseInt(zoomResetButton.label, 10), 110, "Zoom is changed to 110% for about:mozilla");
- let attributeChangePromise = promiseAttributeMutation(zoomResetButton, "label", (v) => {
- return parseInt(v, 10) == 100;
- });
- yield promiseTabLoadEvent(tab1, "about:home");
- yield attributeChangePromise;
- is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:home");
- yield promiseTabHistoryNavigation(-1, function() {
- return parseInt(zoomResetButton.label, 10) == 110;
- });
- is(parseInt(zoomResetButton.label, 10), 110, "Zoom is still 110% for about:mozilla");
- FullZoom.reset();
-});
-
-function promiseObserverNotification(aObserver) {
- let deferred = Promise.defer();
- function notificationCallback(e) {
- Services.obs.removeObserver(notificationCallback, aObserver, false);
- clearTimeout(timeoutId);
- deferred.resolve();
- }
- let timeoutId = setTimeout(() => {
- Services.obs.removeObserver(notificationCallback, aObserver, false);
- deferred.reject("Notification '" + aObserver + "' did not happen within 20 seconds.");
- }, kTimeoutInMS);
- Services.obs.addObserver(notificationCallback, aObserver, false);
- return deferred.promise;
-}
-
-function promiseTabSelect() {
- let deferred = Promise.defer();
- let container = window.gBrowser.tabContainer;
- let timeoutId = setTimeout(() => {
- container.removeEventListener("TabSelect", callback);
- deferred.reject("TabSelect did not happen within 20 seconds");
- }, kTimeoutInMS);
- function callback(e) {
- container.removeEventListener("TabSelect", callback);
- clearTimeout(timeoutId);
- executeSoon(deferred.resolve);
- }
- container.addEventListener("TabSelect", callback);
- return deferred.promise;
-}
diff --git a/browser/components/customizableui/test/browser_938980_navbar_collapsed.js b/browser/components/customizableui/test/browser_938980_navbar_collapsed.js
deleted file mode 100644
index fc7fa1a0a..000000000
--- a/browser/components/customizableui/test/browser_938980_navbar_collapsed.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-var bookmarksToolbar = document.getElementById("PersonalToolbar");
-var navbar = document.getElementById("nav-bar");
-var tabsToolbar = document.getElementById("TabsToolbar");
-
-// Customization reset should restore visibility to default-visible toolbars.
-add_task(function*() {
- is(navbar.collapsed, false, "Test should start with navbar visible");
- setToolbarVisibility(navbar, false);
- is(navbar.collapsed, true, "navbar should be hidden now");
-
- yield resetCustomization();
-
- is(navbar.collapsed, false, "Customization reset should restore visibility to the navbar");
-});
-
-// Customization reset should restore collapsed-state to default-collapsed toolbars.
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state");
-
- is(bookmarksToolbar.collapsed, true, "Test should start with bookmarks toolbar collapsed");
- ok(bookmarksToolbar.collapsed, "bookmarksToolbar should be collapsed");
- ok(!tabsToolbar.collapsed, "TabsToolbar should not be collapsed");
- is(navbar.collapsed, false, "The nav-bar should be shown by default");
-
- setToolbarVisibility(bookmarksToolbar, true);
- setToolbarVisibility(navbar, false);
- ok(!bookmarksToolbar.collapsed, "bookmarksToolbar should be visible now");
- ok(navbar.collapsed, "navbar should be collapsed");
- is(CustomizableUI.inDefaultState, false, "Should no longer be in default state");
-
- yield startCustomizing();
- yield gCustomizeMode.reset();
- yield endCustomizing();
-
- is(bookmarksToolbar.collapsed, true, "Customization reset should restore collapsed-state to the bookmarks toolbar");
- ok(!tabsToolbar.collapsed, "TabsToolbar should not be collapsed");
- ok(bookmarksToolbar.collapsed, "The bookmarksToolbar should be collapsed after reset");
- ok(CustomizableUI.inDefaultState, "Everything should be back to default state");
-});
-
-// Check that the menubar will be collapsed by resetting, if the platform supports it.
-add_task(function*() {
- let menubar = document.getElementById("toolbar-menubar");
- const canMenubarCollapse = CustomizableUI.isToolbarDefaultCollapsed(menubar.id);
- if (!canMenubarCollapse) {
- return;
- }
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state");
-
- is(menubar.getBoundingClientRect().height, 0, "menubar should be hidden by default");
- setToolbarVisibility(menubar, true);
- isnot(menubar.getBoundingClientRect().height, 0, "menubar should be visible now");
-
- yield startCustomizing();
- yield gCustomizeMode.reset();
-
- is(menubar.getAttribute("autohide"), "true", "The menubar should have autohide=true after reset in customization mode");
- is(menubar.getBoundingClientRect().height, 0, "The menubar should have height=0 after reset in customization mode");
-
- yield endCustomizing();
-
- is(menubar.getAttribute("autohide"), "true", "The menubar should have autohide=true after reset");
- is(menubar.getBoundingClientRect().height, 0, "The menubar should have height=0 after reset");
-});
-
-// Customization reset should restore collapsed-state to default-collapsed toolbars.
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state");
- ok(bookmarksToolbar.collapsed, "bookmarksToolbar should be collapsed");
- ok(!tabsToolbar.collapsed, "TabsToolbar should not be collapsed");
-
- setToolbarVisibility(bookmarksToolbar, true);
- ok(!bookmarksToolbar.collapsed, "bookmarksToolbar should be visible now");
- is(CustomizableUI.inDefaultState, false, "Should no longer be in default state");
-
- yield startCustomizing();
-
- ok(!bookmarksToolbar.collapsed, "The bookmarksToolbar should be visible before reset");
- ok(!navbar.collapsed, "The navbar should be visible before reset");
- ok(!tabsToolbar.collapsed, "TabsToolbar should not be collapsed");
-
- yield gCustomizeMode.reset();
-
- ok(bookmarksToolbar.collapsed, "The bookmarksToolbar should be collapsed after reset");
- ok(!tabsToolbar.collapsed, "TabsToolbar should not be collapsed");
- ok(!navbar.collapsed, "The navbar should still be visible after reset");
- ok(CustomizableUI.inDefaultState, "Everything should be back to default state");
- yield endCustomizing();
-});
-
-// Check that the menubar will be collapsed by resetting, if the platform supports it.
-add_task(function*() {
- let menubar = document.getElementById("toolbar-menubar");
- const canMenubarCollapse = CustomizableUI.isToolbarDefaultCollapsed(menubar.id);
- if (!canMenubarCollapse) {
- return;
- }
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state");
- yield startCustomizing();
- let resetButton = document.getElementById("customization-reset-button");
- is(resetButton.disabled, true, "The reset button should be disabled when in default state");
-
- setToolbarVisibility(menubar, true);
- is(resetButton.disabled, false, "The reset button should be enabled when not in default state")
- ok(!CustomizableUI.inDefaultState, "No longer in default state when the menubar is shown");
-
- yield gCustomizeMode.reset();
-
- is(resetButton.disabled, true, "The reset button should be disabled when in default state");
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state");
-
- yield endCustomizing();
-});
diff --git a/browser/components/customizableui/test/browser_938995_indefaultstate_nonremovable.js b/browser/components/customizableui/test/browser_938995_indefaultstate_nonremovable.js
deleted file mode 100644
index 1f06c1aac..000000000
--- a/browser/components/customizableui/test/browser_938995_indefaultstate_nonremovable.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "test-non-removable-widget";
-
-// Adding non-removable items to a toolbar or the panel shouldn't change inDefaultState
-add_task(function() {
- ok(CustomizableUI.inDefaultState, "Should start in default state");
-
- let button = createDummyXULButton(kWidgetId, "Test non-removable inDefaultState handling");
- CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_NAVBAR);
- button.setAttribute("removable", "false");
- ok(CustomizableUI.inDefaultState, "Should still be in default state after navbar addition");
- button.remove();
-
- button = createDummyXULButton(kWidgetId, "Test non-removable inDefaultState handling");
- CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_PANEL);
- button.setAttribute("removable", "false");
- ok(CustomizableUI.inDefaultState, "Should still be in default state after panel addition");
- button.remove();
- ok(CustomizableUI.inDefaultState, "Should be in default state after destroying both widgets");
-});
diff --git a/browser/components/customizableui/test/browser_940013_registerToolbarNode_calls_registerArea.js b/browser/components/customizableui/test/browser_940013_registerToolbarNode_calls_registerArea.js
deleted file mode 100644
index c554bffab..000000000
--- a/browser/components/customizableui/test/browser_940013_registerToolbarNode_calls_registerArea.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbarId = "test-registerToolbarNode-toolbar";
-const kButtonId = "test-registerToolbarNode-button";
-registerCleanupFunction(cleanup);
-
-// Registering a toolbar with defaultset attribute should work
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
- let btn = createDummyXULButton(kButtonId);
- let toolbar = document.createElement("toolbar");
- toolbar.id = kToolbarId;
- toolbar.setAttribute("customizable", true);
- toolbar.setAttribute("defaultset", kButtonId);
- gNavToolbox.appendChild(toolbar);
- ok(CustomizableUI.areas.indexOf(kToolbarId) != -1,
- "Toolbar should have been registered automatically.");
- is(CustomizableUI.getAreaType(kToolbarId), CustomizableUI.TYPE_TOOLBAR,
- "Area should be registered as toolbar");
- assertAreaPlacements(kToolbarId, [kButtonId]);
- ok(!CustomizableUI.inDefaultState, "No longer in default state after toolbar is registered and visible.");
- CustomizableUI.unregisterArea(kToolbarId, true);
- toolbar.remove();
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
- btn.remove();
-});
-
-// Registering a toolbar without a defaultset attribute should
-// wait for the registerArea call
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
- let btn = createDummyXULButton(kButtonId);
- let toolbar = document.createElement("toolbar");
- toolbar.id = kToolbarId;
- toolbar.setAttribute("customizable", true);
- gNavToolbox.appendChild(toolbar);
- ok(CustomizableUI.areas.indexOf(kToolbarId) == -1,
- "Toolbar should not yet have been registered automatically.");
- CustomizableUI.registerArea(kToolbarId, {defaultPlacements: [kButtonId]});
- ok(CustomizableUI.areas.indexOf(kToolbarId) != -1,
- "Toolbar should have been registered now.");
- is(CustomizableUI.getAreaType(kToolbarId), CustomizableUI.TYPE_TOOLBAR,
- "Area should be registered as toolbar");
- assertAreaPlacements(kToolbarId, [kButtonId]);
- ok(!CustomizableUI.inDefaultState, "No longer in default state after toolbar is registered and visible.");
- CustomizableUI.unregisterArea(kToolbarId, true);
- toolbar.remove();
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
- btn.remove();
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
-
-function cleanup() {
- let toolbar = document.getElementById(kToolbarId);
- if (toolbar) {
- toolbar.remove();
- }
- let btn = document.getElementById(kButtonId) ||
- gNavToolbox.querySelector("#" + kButtonId);
- if (btn) {
- btn.remove();
- }
-}
diff --git a/browser/components/customizableui/test/browser_940307_panel_click_closure_handling.js b/browser/components/customizableui/test/browser_940307_panel_click_closure_handling.js
deleted file mode 100644
index 944879a1b..000000000
--- a/browser/components/customizableui/test/browser_940307_panel_click_closure_handling.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var button, menuButton;
-/* Clicking a button should close the panel */
-add_task(function*() {
- button = document.createElement("toolbarbutton");
- button.id = "browser_940307_button";
- button.setAttribute("label", "Button");
- PanelUI.contents.appendChild(button);
- yield PanelUI.show();
- let hiddenAgain = promisePanelHidden(window);
- EventUtils.synthesizeMouseAtCenter(button, {});
- yield hiddenAgain;
- button.remove();
-});
-
-/* Clicking a menu button should close the panel, opening the popup shouldn't. */
-add_task(function*() {
- menuButton = document.createElement("toolbarbutton");
- menuButton.setAttribute("type", "menu-button");
- menuButton.id = "browser_940307_menubutton";
- menuButton.setAttribute("label", "Menu button");
-
- let menuPopup = document.createElement("menupopup");
- menuPopup.id = "browser_940307_menupopup";
-
- let menuItem = document.createElement("menuitem");
- menuItem.setAttribute("label", "Menu item");
- menuItem.id = "browser_940307_menuitem";
-
- menuPopup.appendChild(menuItem);
- menuButton.appendChild(menuPopup);
- PanelUI.contents.appendChild(menuButton);
-
- yield PanelUI.show();
- let hiddenAgain = promisePanelHidden(window);
- let innerButton = document.getAnonymousElementByAttribute(menuButton, "anonid", "button");
- EventUtils.synthesizeMouseAtCenter(innerButton, {});
- yield hiddenAgain;
-
- // Now click the dropmarker to show the menu
- yield PanelUI.show();
- hiddenAgain = promisePanelHidden(window);
- let menuShown = promisePanelElementShown(window, menuPopup);
- let dropmarker = document.getAnonymousElementByAttribute(menuButton, "type", "menu-button");
- EventUtils.synthesizeMouseAtCenter(dropmarker, {});
- yield menuShown;
- // Panel should stay open:
- ok(isPanelUIOpen(), "Panel should still be open");
- let menuHidden = promisePanelElementHidden(window, menuPopup);
- // Then click the menu item to close all the things
- EventUtils.synthesizeMouseAtCenter(menuItem, {});
- yield menuHidden;
- yield hiddenAgain;
- menuButton.remove();
-});
-
-add_task(function*() {
- let searchbar = document.getElementById("searchbar");
- gCustomizeMode.addToPanel(searchbar);
- let placement = CustomizableUI.getPlacementOfWidget("search-container");
- is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
- yield PanelUI.show();
- yield waitForCondition(() => "value" in searchbar && searchbar.value === "");
-
- // Focusing a non-empty searchbox will cause us to open the
- // autocomplete panel and search for suggestions, which would
- // trigger network requests. Temporarily disable suggestions.
- yield SpecialPowers.pushPrefEnv({set: [["browser.search.suggest.enabled", false]]});
-
- searchbar.value = "foo";
- searchbar.focus();
- // Reaching into this context menu is pretty evil, but hey... it's a test.
- let textbox = document.getAnonymousElementByAttribute(searchbar.textbox, "anonid", "textbox-input-box");
- let contextmenu = document.getAnonymousElementByAttribute(textbox, "anonid", "input-box-contextmenu");
- let contextMenuShown = promisePanelElementShown(window, contextmenu);
- EventUtils.synthesizeMouseAtCenter(searchbar, {type: "contextmenu", button: 2});
- yield contextMenuShown;
-
- ok(isPanelUIOpen(), "Panel should still be open");
-
- let selectAll = contextmenu.querySelector("[cmd='cmd_selectAll']");
- let contextMenuHidden = promisePanelElementHidden(window, contextmenu);
- EventUtils.synthesizeMouseAtCenter(selectAll, {});
- yield contextMenuHidden;
-
- // Hide the suggestion panel.
- searchbar.textbox.popup.hidePopup();
-
- ok(isPanelUIOpen(), "Panel should still be open");
-
- let hiddenPanelPromise = promisePanelHidden(window);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield hiddenPanelPromise;
- ok(!isPanelUIOpen(), "Panel should no longer be open");
-
- // We focused the search bar earlier - ensure we don't keep doing that.
- gURLBar.select();
-
- CustomizableUI.reset();
-});
-
-add_task(function*() {
- button = document.createElement("toolbarbutton");
- button.id = "browser_946166_button_disabled";
- button.setAttribute("disabled", "true");
- button.setAttribute("label", "Button");
- PanelUI.contents.appendChild(button);
- yield PanelUI.show();
- EventUtils.synthesizeMouseAtCenter(button, {});
- is(PanelUI.panel.state, "open", "Popup stays open");
- button.removeAttribute("disabled");
- let hiddenAgain = promisePanelHidden(window);
- EventUtils.synthesizeMouseAtCenter(button, {});
- yield hiddenAgain;
- button.remove();
-});
-
-registerCleanupFunction(function() {
- if (button && button.parentNode) {
- button.remove();
- }
- if (menuButton && menuButton.parentNode) {
- menuButton.remove();
- }
- // Sadly this isn't task.jsm-enabled, so we can't wait for this to happen. But we should
- // definitely close it here and hope it won't interfere with other tests.
- // Of course, all the tests are meant to do this themselves, but if they fail...
- if (isPanelUIOpen()) {
- PanelUI.hide();
- }
-});
diff --git a/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js b/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js
deleted file mode 100644
index c81b004c1..000000000
--- a/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kTestBtnId = "test-removable-navbar-customize-mode";
-
-// Items without the removable attribute in the navbar should be considered non-removable
-add_task(function*() {
- let btn = createDummyXULButton(kTestBtnId, "Test removable in navbar in customize mode");
- document.getElementById("nav-bar").customizationTarget.appendChild(btn);
- yield startCustomizing();
- ok(!CustomizableUI.isWidgetRemovable(kTestBtnId), "Widget should not be considered removable");
- yield endCustomizing();
- document.getElementById(kTestBtnId).remove();
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js b/browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js
deleted file mode 100644
index 1d7f86fd2..000000000
--- a/browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=941083
-
-const kWidgetId = "test-invalidate-wrapper-cache";
-
-// Check createWidget invalidates the widget cache
-add_task(function() {
- let groupWrapper = CustomizableUI.getWidget(kWidgetId);
- ok(groupWrapper, "Should get group wrapper.");
- let singleWrapper = groupWrapper.forWindow(window);
- ok(singleWrapper, "Should get single wrapper.");
-
- CustomizableUI.createWidget({id: kWidgetId, label: "Test invalidating widgets caching"});
-
- let newGroupWrapper = CustomizableUI.getWidget(kWidgetId);
- ok(newGroupWrapper, "Should get a group wrapper again.");
- isnot(newGroupWrapper, groupWrapper, "Wrappers shouldn't be the same.");
- isnot(newGroupWrapper.provider, groupWrapper.provider, "Wrapper providers shouldn't be the same.");
-
- let newSingleWrapper = newGroupWrapper.forWindow(window);
- isnot(newSingleWrapper, singleWrapper, "Single wrappers shouldn't be the same.");
- isnot(newSingleWrapper.provider, singleWrapper.provider, "Single wrapper providers shouldn't be the same.");
-
- CustomizableUI.destroyWidget(kWidgetId);
- ok(!CustomizableUI.getWidget(kWidgetId), "Shouldn't get a wrapper after destroying the widget.");
-});
diff --git a/browser/components/customizableui/test/browser_942581_unregisterArea_keeps_placements.js b/browser/components/customizableui/test/browser_942581_unregisterArea_keeps_placements.js
deleted file mode 100644
index 61adac982..000000000
--- a/browser/components/customizableui/test/browser_942581_unregisterArea_keeps_placements.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbarName = "test-unregisterArea-placements-toolbar";
-const kTestWidgetPfx = "test-widget-for-unregisterArea-placements-";
-const kTestWidgetCount = 3;
-registerCleanupFunction(removeCustomToolbars);
-
-// unregisterArea should keep placements by default and restore them when re-adding the area
-add_task(function*() {
- let widgetIds = [];
- for (let i = 0; i < kTestWidgetCount; i++) {
- let id = kTestWidgetPfx + i;
- widgetIds.push(id);
- let spec = {id: id, type: 'button', removable: true, label: "unregisterArea test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- }
- for (let i = kTestWidgetCount; i < kTestWidgetCount * 2; i++) {
- let id = kTestWidgetPfx + i;
- widgetIds.push(id);
- createDummyXULButton(id, "unregisterArea XUL test " + i);
- }
- let toolbarNode = createToolbarWithPlacements(kToolbarName, widgetIds);
- checkAbstractAndRealPlacements(toolbarNode, widgetIds);
-
- // Now move one of them:
- CustomizableUI.moveWidgetWithinArea(kTestWidgetPfx + kTestWidgetCount, 0);
- // Clone the array so we know this is the modified one:
- let modifiedWidgetIds = [...widgetIds];
- let movedWidget = modifiedWidgetIds.splice(kTestWidgetCount, 1)[0];
- modifiedWidgetIds.unshift(movedWidget);
-
- // Check it:
- checkAbstractAndRealPlacements(toolbarNode, modifiedWidgetIds);
-
- // Then unregister
- CustomizableUI.unregisterArea(kToolbarName);
-
- // Check we tell the outside world no dangerous things:
- checkWidgetFates(widgetIds);
- // Only then remove the real node
- toolbarNode.remove();
-
- // Now move one of the items to the palette, and another to the navbar:
- let lastWidget = modifiedWidgetIds.pop();
- CustomizableUI.removeWidgetFromArea(lastWidget);
- lastWidget = modifiedWidgetIds.pop();
- CustomizableUI.addWidgetToArea(lastWidget, CustomizableUI.AREA_NAVBAR);
-
- // Recreate ourselves with the default placements being the same:
- toolbarNode = createToolbarWithPlacements(kToolbarName, widgetIds);
- // Then check that after doing this, our actual placements match
- // the modified list, not the default one.
- checkAbstractAndRealPlacements(toolbarNode, modifiedWidgetIds);
-
- // Now remove completely:
- CustomizableUI.unregisterArea(kToolbarName, true);
- checkWidgetFates(modifiedWidgetIds);
- toolbarNode.remove();
-
- // One more time:
- // Recreate ourselves with the default placements being the same:
- toolbarNode = createToolbarWithPlacements(kToolbarName, widgetIds);
- // Should now be back to default:
- checkAbstractAndRealPlacements(toolbarNode, widgetIds);
- CustomizableUI.unregisterArea(kToolbarName, true);
- checkWidgetFates(widgetIds);
- toolbarNode.remove();
-
- // XXXgijs: ensure cleanup function doesn't barf:
- gAddedToolbars.delete(kToolbarName);
-
- // Remove all the XUL widgets, destroy the others:
- for (let widget of widgetIds) {
- let widgetWrapper = CustomizableUI.getWidget(widget);
- if (widgetWrapper.provider == CustomizableUI.PROVIDER_XUL) {
- gNavToolbox.palette.querySelector("#" + widget).remove();
- } else {
- CustomizableUI.destroyWidget(widget);
- }
- }
-});
-
-function checkAbstractAndRealPlacements(aNode, aExpectedPlacements) {
- assertAreaPlacements(kToolbarName, aExpectedPlacements);
- let physicalWidgetIds = Array.from(aNode.childNodes, (node) => node.id);
- placementArraysEqual(aNode.id, physicalWidgetIds, aExpectedPlacements);
-}
-
-function checkWidgetFates(aWidgetIds) {
- for (let widget of aWidgetIds) {
- ok(!CustomizableUI.getPlacementOfWidget(widget), "Widget should be in palette");
- ok(!document.getElementById(widget), "Widget should not be in the DOM");
- let widgetInPalette = !!gNavToolbox.palette.querySelector("#" + widget);
- let widgetProvider = CustomizableUI.getWidget(widget).provider;
- let widgetIsXULWidget = widgetProvider == CustomizableUI.PROVIDER_XUL;
- is(widgetInPalette, widgetIsXULWidget, "Just XUL Widgets should be in the palette");
- }
-}
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_943683_migration_test.js b/browser/components/customizableui/test/browser_943683_migration_test.js
deleted file mode 100644
index fe30df9e3..000000000
--- a/browser/components/customizableui/test/browser_943683_migration_test.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "test-addonbar-migration";
-const kWidgetId2 = "test-addonbar-migration2";
-
-var addonbar = document.getElementById(CustomizableUI.AREA_ADDONBAR);
-var navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
-var btn;
-var btn2;
-
-// Check we migrate normal stuff to the navbar
-add_task(function*() {
- btn = createDummyXULButton(kWidgetId, "Test");
- btn2 = createDummyXULButton(kWidgetId2, "Test2");
- addonbar.insertItem(btn.id);
- ok(btn.parentNode == navbar.customizationTarget, "Button should end up in navbar");
- let migrationArray = addonbar.getMigratedItems();
- is(migrationArray.length, 1, "Should have migrated 1 item");
- is(migrationArray[0], kWidgetId, "Should have migrated our 1 item");
-
- addonbar.currentSet = addonbar.currentSet + "," + kWidgetId2;
- ok(btn2.parentNode == navbar.customizationTarget, "Second button should end up in the navbar");
- migrationArray = addonbar.getMigratedItems();
- is(migrationArray.length, 2, "Should have migrated 2 items");
- isnot(migrationArray.indexOf(kWidgetId2), -1, "Should have migrated our second item");
-
- let otherWindow = yield openAndLoadWindow(undefined, true);
- try {
- let addonBar = otherWindow.document.getElementById("addon-bar");
- let otherMigrationArray = addonBar.getMigratedItems();
- is(migrationArray.length, otherMigrationArray.length,
- "Other window should have the same number of migrated items.");
- if (migrationArray.length == otherMigrationArray.length) {
- for (let widget of migrationArray) {
- isnot(otherMigrationArray.indexOf(widget), -1,
- "Migrated widget " + widget + " should also be listed as migrated in the other window.");
- }
- }
- } finally {
- yield promiseWindowClosed(otherWindow);
- }
- btn.remove();
- btn2.remove();
- CustomizableUI.reset();
-});
diff --git a/browser/components/customizableui/test/browser_944887_destroyWidget_should_destroy_in_palette.js b/browser/components/customizableui/test/browser_944887_destroyWidget_should_destroy_in_palette.js
deleted file mode 100644
index a724b0c7f..000000000
--- a/browser/components/customizableui/test/browser_944887_destroyWidget_should_destroy_in_palette.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "test-destroy-in-palette";
-
-// Check destroyWidget destroys the node if it's in the palette
-add_task(function*() {
- CustomizableUI.createWidget({id: kWidgetId, label: "Test destroying widgets in palette."});
- yield startCustomizing();
- yield endCustomizing();
- ok(gNavToolbox.palette.querySelector("#" + kWidgetId), "Widget still exists in palette.");
- CustomizableUI.destroyWidget(kWidgetId);
- ok(!gNavToolbox.palette.querySelector("#" + kWidgetId), "Widget no longer exists in palette.");
-});
diff --git a/browser/components/customizableui/test/browser_945739_showInPrivateBrowsing_customize_mode.js b/browser/components/customizableui/test/browser_945739_showInPrivateBrowsing_customize_mode.js
deleted file mode 100644
index 6b8acbee0..000000000
--- a/browser/components/customizableui/test/browser_945739_showInPrivateBrowsing_customize_mode.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kWidgetId = "test-private-browsing-customize-mode-widget";
-
-// Add a widget via the API with showInPrivateBrowsing set to false
-// and ensure it does not appear in the list of unused widgets in private
-// windows.
-add_task(function* testPrivateBrowsingCustomizeModeWidget() {
- CustomizableUI.createWidget({
- id: kWidgetId,
- showInPrivateBrowsing: false
- });
-
- let normalWidgetArray = CustomizableUI.getUnusedWidgets(gNavToolbox.palette);
- normalWidgetArray = normalWidgetArray.map((w) => w.id);
- ok(normalWidgetArray.indexOf(kWidgetId) > -1,
- "Widget should appear as unused in non-private window");
-
- let privateWindow = yield openAndLoadWindow({private: true});
- let privateWidgetArray = CustomizableUI.getUnusedWidgets(privateWindow.gNavToolbox.palette);
- privateWidgetArray = privateWidgetArray.map((w) => w.id);
- is(privateWidgetArray.indexOf(kWidgetId), -1,
- "Widget should not appear as unused in private window");
- yield promiseWindowClosed(privateWindow);
-
- CustomizableUI.destroyWidget(kWidgetId);
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_addons.js b/browser/components/customizableui/test/browser_947914_button_addons.js
deleted file mode 100644
index b942ee771..000000000
--- a/browser/components/customizableui/test/browser_947914_button_addons.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialLocation = gBrowser.currentURI.spec;
-var newTab = null;
-
-add_task(function*() {
- info("Check addons button existence and functionality");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let addonsButton = document.getElementById("add-ons-button");
- ok(addonsButton, "Add-ons button exists in Panel Menu");
- addonsButton.click();
-
- newTab = gBrowser.selectedTab;
- yield waitForCondition(() => gBrowser.currentURI &&
- gBrowser.currentURI.spec == "about:addons");
-
- let addonsPage = gBrowser.selectedBrowser.contentWindow.document.
- getElementById("addons-page");
- ok(addonsPage, "Add-ons page was opened");
-});
-
-add_task(function* asyncCleanup() {
- gBrowser.addTab(initialLocation);
- gBrowser.removeTab(gBrowser.selectedTab);
- info("Tabs were restored");
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_copy.js b/browser/components/customizableui/test/browser_947914_button_copy.js
deleted file mode 100644
index c778c956f..000000000
--- a/browser/components/customizableui/test/browser_947914_button_copy.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialLocation = gBrowser.currentURI.spec;
-var globalClipboard;
-
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({gBrowser, url: "about:blank"}, function*() {
- info("Check copy button existence and functionality");
-
- let testText = "copy text test";
-
- gURLBar.focus();
- info("The URL bar was focused");
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let copyButton = document.getElementById("copy-button");
- ok(copyButton, "Copy button exists in Panel Menu");
- ok(copyButton.getAttribute("disabled"), "Copy button is initially disabled");
-
- // copy text from URL bar
- gURLBar.value = testText;
- gURLBar.focus();
- gURLBar.select();
- yield PanelUI.show();
- info("Menu panel was opened");
-
- ok(!copyButton.hasAttribute("disabled"), "Copy button is enabled when selecting");
-
- copyButton.click();
- is(gURLBar.value, testText, "Selected text is unaltered when clicking copy");
-
- // check that the text was added to the clipboard
- let clipboard = Services.clipboard;
- let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
- globalClipboard = clipboard.kGlobalClipboard;
-
- transferable.init(null);
- transferable.addDataFlavor("text/unicode");
- clipboard.getData(transferable, globalClipboard);
- let str = {}, strLength = {};
- transferable.getTransferData("text/unicode", str, strLength);
- let clipboardValue = "";
-
- if (str.value) {
- str.value.QueryInterface(Ci.nsISupportsString);
- clipboardValue = str.value.data;
- }
- is(clipboardValue, testText, "Data was copied to the clipboard.");
- });
-});
-
-registerCleanupFunction(function cleanup() {
- Services.clipboard.emptyClipboard(globalClipboard);
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_cut.js b/browser/components/customizableui/test/browser_947914_button_cut.js
deleted file mode 100644
index e6e614368..000000000
--- a/browser/components/customizableui/test/browser_947914_button_cut.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialLocation = gBrowser.currentURI.spec;
-var globalClipboard;
-
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({gBrowser, url: "about:blank"}, function*() {
- info("Check cut button existence and functionality");
-
- let testText = "cut text test";
-
- gURLBar.focus();
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let cutButton = document.getElementById("cut-button");
- ok(cutButton, "Cut button exists in Panel Menu");
- ok(cutButton.hasAttribute("disabled"), "Cut button is disabled");
-
- // cut text from URL bar
- gURLBar.value = testText;
- gURLBar.focus();
- gURLBar.select();
- yield PanelUI.show();
- info("Menu panel was opened");
-
- ok(!cutButton.hasAttribute("disabled"), "Cut button is enabled when selecting");
- cutButton.click();
- is(gURLBar.value, "", "Selected text is removed from source when clicking on cut");
-
- // check that the text was added to the clipboard
- let clipboard = Services.clipboard;
- let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
- globalClipboard = clipboard.kGlobalClipboard;
-
- transferable.init(null);
- transferable.addDataFlavor("text/unicode");
- clipboard.getData(transferable, globalClipboard);
- let str = {}, strLength = {};
- transferable.getTransferData("text/unicode", str, strLength);
- let clipboardValue = "";
-
- if (str.value) {
- str.value.QueryInterface(Ci.nsISupportsString);
- clipboardValue = str.value.data;
- }
- is(clipboardValue, testText, "Data was copied to the clipboard.");
- });
-});
-
-registerCleanupFunction(function cleanup() {
- Services.clipboard.emptyClipboard(globalClipboard);
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_find.js b/browser/components/customizableui/test/browser_947914_button_find.js
deleted file mode 100644
index cf3b79e34..000000000
--- a/browser/components/customizableui/test/browser_947914_button_find.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check find button existence and functionality");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let findButton = document.getElementById("find-button");
- ok(findButton, "Find button exists in Panel Menu");
-
- findButton.click();
- ok(!gFindBar.hasAttribute("hidden"), "Findbar opened successfully");
-
- // close find bar
- gFindBar.close();
- info("Findbar was closed");
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_history.js b/browser/components/customizableui/test/browser_947914_button_history.js
deleted file mode 100644
index 64080fcc3..000000000
--- a/browser/components/customizableui/test/browser_947914_button_history.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check history button existence and functionality");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let historyButton = document.getElementById("history-panelmenu");
- ok(historyButton, "History button appears in Panel Menu");
-
- historyButton.click();
- let historyPanel = document.getElementById("PanelUI-history");
- ok(historyPanel.getAttribute("current"), "History Panel is in view");
-
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise
- info("Menu panel was closed");
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js b/browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js
deleted file mode 100644
index c2006bef0..000000000
--- a/browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check private browsing button existence and functionality");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let windowWasHandled = false;
- let privateWindow = null;
-
- let observerWindowOpened = {
- observe: function(aSubject, aTopic, aData) {
- if (aTopic == "domwindowopened") {
- privateWindow = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
- privateWindow.addEventListener("load", function newWindowHandler() {
- privateWindow.removeEventListener("load", newWindowHandler, false);
- is(privateWindow.location.href, "chrome://browser/content/browser.xul",
- "A new browser window was opened");
- ok(PrivateBrowsingUtils.isWindowPrivate(privateWindow), "Window is private");
- windowWasHandled = true;
- }, false);
- }
- }
- }
-
- Services.ww.registerNotification(observerWindowOpened);
-
- let privateBrowsingButton = document.getElementById("privatebrowsing-button");
- ok(privateBrowsingButton, "Private browsing button exists in Panel Menu");
- privateBrowsingButton.click();
-
- try {
- yield waitForCondition(() => windowWasHandled);
- yield promiseWindowClosed(privateWindow);
- info("The new private window was closed");
- }
- catch (e) {
- ok(false, "The new private browser window was not properly handled");
- }
- finally {
- Services.ww.unregisterNotification(observerWindowOpened);
- }
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_newWindow.js b/browser/components/customizableui/test/browser_947914_button_newWindow.js
deleted file mode 100644
index 47162ee86..000000000
--- a/browser/components/customizableui/test/browser_947914_button_newWindow.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check new window button existence and functionality");
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let windowWasHandled = false;
- let newWindow = null;
-
- let observerWindowOpened = {
- observe: function(aSubject, aTopic, aData) {
- if (aTopic == "domwindowopened") {
- newWindow = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
- newWindow.addEventListener("load", function newWindowHandler() {
- newWindow.removeEventListener("load", newWindowHandler, false);
- 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;
- }, false);
- }
- }
- }
-
- Services.ww.registerNotification(observerWindowOpened);
-
- let newWindowButton = document.getElementById("new-window-button");
- ok(newWindowButton, "New Window button exists in Panel Menu");
- newWindowButton.click();
-
- try {
- yield waitForCondition(() => windowWasHandled);
- yield promiseWindowClosed(newWindow);
- info("The new window was closed");
- }
- catch (e) {
- ok(false, "The new browser window was not properly handled");
- }
- finally {
- Services.ww.unregisterNotification(observerWindowOpened);
- }
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_paste.js b/browser/components/customizableui/test/browser_947914_button_paste.js
deleted file mode 100644
index fc83ead56..000000000
--- a/browser/components/customizableui/test/browser_947914_button_paste.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialLocation = gBrowser.currentURI.spec;
-var globalClipboard;
-
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({gBrowser, url: "about:blank"}, function*() {
- info("Check paste button existence and functionality");
-
- let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
- globalClipboard = Services.clipboard.kGlobalClipboard;
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let pasteButton = document.getElementById("paste-button");
- ok(pasteButton, "Paste button exists in Panel Menu");
-
- // add text to clipboard
- let text = "Sample text for testing";
- clipboard.copyString(text);
-
- // test paste button by pasting text to URL bar
- gURLBar.focus();
- yield PanelUI.show();
- info("Menu panel was opened");
-
- ok(!pasteButton.hasAttribute("disabled"), "Paste button is enabled");
- pasteButton.click();
-
- is(gURLBar.value, text, "Text pasted successfully");
- });
-});
-
-registerCleanupFunction(function cleanup() {
- Services.clipboard.emptyClipboard(globalClipboard);
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_print.js b/browser/components/customizableui/test/browser_947914_button_print.js
deleted file mode 100644
index af7abcaeb..000000000
--- a/browser/components/customizableui/test/browser_947914_button_print.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const isOSX = (Services.appinfo.OS === "Darwin");
-
-add_task(function*() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com/",
- }, function* () {
- info("Check print button existence and functionality");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- yield waitForCondition(() => document.getElementById("print-button") != null);
-
- let printButton = document.getElementById("print-button");
- ok(printButton, "Print button exists in Panel Menu");
-
- if (isOSX) {
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
- info("Menu panel was closed");
- }
- else {
- printButton.click();
- yield waitForCondition(() => gInPrintPreviewMode);
-
- ok(gInPrintPreviewMode, "Entered print preview mode");
-
- // close print preview
- if (gInPrintPreviewMode) {
- PrintUtils.exitPrintPreview();
- yield waitForCondition(() => !window.gInPrintPreviewMode);
- info("Exited print preview")
- }
- }
- });
-});
-
diff --git a/browser/components/customizableui/test/browser_947914_button_savePage.js b/browser/components/customizableui/test/browser_947914_button_savePage.js
deleted file mode 100644
index 543ff3ca6..000000000
--- a/browser/components/customizableui/test/browser_947914_button_savePage.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- info("Check save page button existence");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let savePageButton = document.getElementById("save-page-button");
- ok(savePageButton, "Save Page button exists in Panel Menu");
-
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
- info("Menu panel was closed");
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_zoomIn.js b/browser/components/customizableui/test/browser_947914_button_zoomIn.js
deleted file mode 100644
index 4463d87d6..000000000
--- a/browser/components/customizableui/test/browser_947914_button_zoomIn.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialPageZoom = ZoomManager.zoom;
-
-add_task(function*() {
- info("Check zoom in button existence and functionality");
-
- is(initialPageZoom, 1, "Initial zoom factor should be 1");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let zoomInButton = document.getElementById("zoom-in-button");
- ok(zoomInButton, "Zoom in button exists in Panel Menu");
-
- zoomInButton.click();
- let pageZoomLevel = parseInt(ZoomManager.zoom * 100);
- let zoomResetButton = document.getElementById("zoom-reset-button");
- let expectedZoomLevel = parseInt(zoomResetButton.getAttribute("label"), 10);
- ok(pageZoomLevel > 100 && pageZoomLevel == expectedZoomLevel, "Page zoomed in correctly");
-
- // close the Panel
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
- info("Menu panel was closed");
-});
-
-add_task(function* asyncCleanup() {
- // reset zoom level
- ZoomManager.zoom = initialPageZoom;
- info("Zoom level was restored");
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_zoomOut.js b/browser/components/customizableui/test/browser_947914_button_zoomOut.js
deleted file mode 100644
index f9f51ac9a..000000000
--- a/browser/components/customizableui/test/browser_947914_button_zoomOut.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialPageZoom = ZoomManager.zoom;
-
-add_task(function*() {
- info("Check zoom out button existence and functionality");
-
- is(initialPageZoom, 1, "Initial zoom factor should be 1");
-
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let zoomOutButton = document.getElementById("zoom-out-button");
- ok(zoomOutButton, "Zoom out button exists in Panel Menu");
-
- zoomOutButton.click();
- let pageZoomLevel = Math.round(ZoomManager.zoom * 100);
-
- let zoomResetButton = document.getElementById("zoom-reset-button");
- let expectedZoomLevel = parseInt(zoomResetButton.getAttribute("label"), 10);
- ok(pageZoomLevel < 100 && pageZoomLevel == expectedZoomLevel, "Page zoomed out correctly");
-
- // close the panel
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
- info("Menu panel was closed");
-});
-
-add_task(function* asyncCleanup() {
- // reset zoom level
- ZoomManager.zoom = initialPageZoom;
- info("Zoom level was restored");
-});
diff --git a/browser/components/customizableui/test/browser_947914_button_zoomReset.js b/browser/components/customizableui/test/browser_947914_button_zoomReset.js
deleted file mode 100644
index 372097665..000000000
--- a/browser/components/customizableui/test/browser_947914_button_zoomReset.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialPageZoom = ZoomManager.zoom;
-
-add_task(function*() {
- info("Check zoom reset button existence and functionality");
-
- is(initialPageZoom, 1, "Page zoom reset correctly");
- ZoomManager.zoom = 0.5;
- yield PanelUI.show();
- info("Menu panel was opened");
-
- let zoomResetButton = document.getElementById("zoom-reset-button");
- ok(zoomResetButton, "Zoom reset button exists in Panel Menu");
-
- zoomResetButton.click();
- yield new Promise(SimpleTest.executeSoon);
-
- let pageZoomLevel = Math.floor(ZoomManager.zoom * 100);
- let expectedZoomLevel = 100;
- let buttonZoomLevel = parseInt(zoomResetButton.getAttribute("label"), 10);
- is(pageZoomLevel, expectedZoomLevel, "Page zoom reset correctly");
- is(pageZoomLevel, buttonZoomLevel, "Button displays the correct zoom level");
-
- // close the panel
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
- info("Menu panel was closed");
-});
-
-add_task(function* asyncCleanup() {
- // reset zoom level
- ZoomManager.zoom = initialPageZoom;
- info("Zoom level was restored");
-});
diff --git a/browser/components/customizableui/test/browser_947987_removable_default.js b/browser/components/customizableui/test/browser_947987_removable_default.js
deleted file mode 100644
index 98325ec2a..000000000
--- a/browser/components/customizableui/test/browser_947987_removable_default.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var kWidgetId = "test-removable-widget-default";
-const kNavBar = CustomizableUI.AREA_NAVBAR;
-var widgetCounter = 0;
-
-registerCleanupFunction(removeCustomToolbars);
-
-// Sanity checks
-add_task(function() {
- let brokenSpec = {id: kWidgetId + (widgetCounter++), removable: false};
- SimpleTest.doesThrow(() => CustomizableUI.createWidget(brokenSpec),
- "Creating non-removable widget without defaultArea should throw.");
-
- // Widget without removable set should be removable:
- let wrapper = CustomizableUI.createWidget({id: kWidgetId + (widgetCounter++)});
- ok(CustomizableUI.isWidgetRemovable(wrapper.id), "Should be removable by default.");
- CustomizableUI.destroyWidget(wrapper.id);
-});
-
-// Test non-removable widget with defaultArea
-add_task(function*() {
- // Non-removable widget with defaultArea should work:
- let spec = {id: kWidgetId + (widgetCounter++), removable: false,
- defaultArea: kNavBar};
- let widgetWrapper;
- try {
- widgetWrapper = CustomizableUI.createWidget(spec);
- } catch (ex) {
- ok(false, "Creating a non-removable widget with a default area should not throw.");
- return;
- }
-
- let placement = CustomizableUI.getPlacementOfWidget(spec.id);
- ok(placement, "Widget should be placed.");
- is(placement.area, kNavBar, "Widget should be in navbar");
- let singleWrapper = widgetWrapper.forWindow(window);
- ok(singleWrapper, "Widget should exist in window.");
- ok(singleWrapper.node, "Widget node should exist in window.");
- let expectedParent = CustomizableUI.getCustomizeTargetForArea(kNavBar, window);
- is(singleWrapper.node.parentNode, expectedParent, "Widget should be in navbar.");
-
- let otherWin = yield openAndLoadWindow(true);
- placement = CustomizableUI.getPlacementOfWidget(spec.id);
- ok(placement, "Widget should be placed.");
- is(placement && placement.area, kNavBar, "Widget should be in navbar");
-
- singleWrapper = widgetWrapper.forWindow(otherWin);
- ok(singleWrapper, "Widget should exist in other window.");
- if (singleWrapper) {
- ok(singleWrapper.node, "Widget node should exist in other window.");
- if (singleWrapper.node) {
- let expectedParent = CustomizableUI.getCustomizeTargetForArea(kNavBar, otherWin);
- is(singleWrapper.node.parentNode, expectedParent,
- "Widget should be in navbar in other window.");
- }
- }
- CustomizableUI.destroyWidget(spec.id);
- yield promiseWindowClosed(otherWin);
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_948985_non_removable_defaultArea.js b/browser/components/customizableui/test/browser_948985_non_removable_defaultArea.js
deleted file mode 100644
index 456c9ed02..000000000
--- a/browser/components/customizableui/test/browser_948985_non_removable_defaultArea.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const kWidgetId = "test-destroy-non-removable-defaultArea";
-
-add_task(function() {
- let spec = {id: kWidgetId, label: "Test non-removable defaultArea re-adding.",
- removable: false, defaultArea: CustomizableUI.AREA_NAVBAR};
- CustomizableUI.createWidget(spec);
- let placement = CustomizableUI.getPlacementOfWidget(kWidgetId);
- ok(placement, "Should have placed the widget.");
- is(placement && placement.area, CustomizableUI.AREA_NAVBAR, "Widget should be in navbar");
- CustomizableUI.destroyWidget(kWidgetId);
- CustomizableUI.removeWidgetFromArea(kWidgetId);
-
- CustomizableUI.createWidget(spec);
- ok(placement, "Should have placed the widget.");
- is(placement && placement.area, CustomizableUI.AREA_NAVBAR, "Widget should be in navbar");
- CustomizableUI.destroyWidget(kWidgetId);
- CustomizableUI.removeWidgetFromArea(kWidgetId);
-
- const kPrefCustomizationAutoAdd = "browser.uiCustomization.autoAdd";
- Services.prefs.setBoolPref(kPrefCustomizationAutoAdd, false);
- CustomizableUI.createWidget(spec);
- ok(placement, "Should have placed the widget.");
- is(placement && placement.area, CustomizableUI.AREA_NAVBAR, "Widget should be in navbar");
- CustomizableUI.destroyWidget(kWidgetId);
- CustomizableUI.removeWidgetFromArea(kWidgetId);
- Services.prefs.clearUserPref(kPrefCustomizationAutoAdd);
-});
-
diff --git a/browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js b/browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js
deleted file mode 100644
index fc05a99fd..000000000
--- a/browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbarName = "test-unregisterArea-areaType";
-const kUnregisterAreaTestWidget = "test-widget-for-unregisterArea-areaType";
-const kTestWidget = "test-widget-no-area-areaType";
-registerCleanupFunction(removeCustomToolbars);
-
-function checkAreaType(widget) {
- try {
- is(widget.areaType, null, "areaType should be null");
- } catch (ex) {
- info("Fetching areaType threw: " + ex);
- ok(false, "areaType getter shouldn't throw.");
- }
-}
-
-// widget wrappers in unregisterArea'd areas and nowhere shouldn't throw when checking areaTypes.
-add_task(function*() {
- // Using the ID before it's been created will imply a XUL wrapper; we'll test
- // an API-based wrapper below
- let toolbarNode = createToolbarWithPlacements(kToolbarName, [kUnregisterAreaTestWidget]);
- CustomizableUI.unregisterArea(kToolbarName);
- toolbarNode.remove();
-
- let w = CustomizableUI.getWidget(kUnregisterAreaTestWidget);
- checkAreaType(w);
-
- w = CustomizableUI.getWidget(kTestWidget);
- checkAreaType(w);
-
- let spec = {id: kUnregisterAreaTestWidget, type: 'button', removable: true,
- label: "areaType test", tooltiptext: "areaType test"};
- CustomizableUI.createWidget(spec);
- toolbarNode = createToolbarWithPlacements(kToolbarName, [kUnregisterAreaTestWidget]);
- CustomizableUI.unregisterArea(kToolbarName);
- toolbarNode.remove();
- w = CustomizableUI.getWidget(spec.id);
- checkAreaType(w);
- CustomizableUI.removeWidgetFromArea(kUnregisterAreaTestWidget);
- checkAreaType(w);
- // XXXgijs: ensure cleanup function doesn't barf:
- gAddedToolbars.delete(kToolbarName);
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
-
diff --git a/browser/components/customizableui/test/browser_956602_remove_special_widget.js b/browser/components/customizableui/test/browser_956602_remove_special_widget.js
deleted file mode 100644
index f87b2e4c8..000000000
--- a/browser/components/customizableui/test/browser_956602_remove_special_widget.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-
-// Adding a separator and then dragging it out of the navbar shouldn't throw
-add_task(function*() {
- try {
- let navbar = document.getElementById("nav-bar");
- let separatorSelector = "toolbarseparator[id^=customizableui-special-separator]";
- ok(!navbar.querySelector(separatorSelector), "Shouldn't be a separator in the navbar");
- CustomizableUI.addWidgetToArea('separator', 'nav-bar');
- yield startCustomizing();
- let separator = navbar.querySelector(separatorSelector);
- ok(separator, "There should be a separator in the navbar now.");
- let palette = document.getElementById("customization-palette");
- simulateItemDrag(separator, palette);
- ok(!palette.querySelector(separatorSelector), "No separator in the palette.");
- } catch (ex) {
- Cu.reportError(ex);
- ok(false, "Shouldn't throw an exception moving an item to the navbar.");
- } finally {
- yield endCustomizing();
- }
-});
-
-add_task(function* asyncCleanup() {
- resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_962069_drag_to_overflow_chevron.js b/browser/components/customizableui/test/browser_962069_drag_to_overflow_chevron.js
deleted file mode 100644
index 7c4f6cfa4..000000000
--- a/browser/components/customizableui/test/browser_962069_drag_to_overflow_chevron.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var originalWindowWidth;
-
-// Drag to overflow chevron should open the overflow panel.
-add_task(function*() {
- originalWindowWidth = window.outerWidth;
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
- ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- let widgetOverflowPanel = document.getElementById("widget-overflow");
- let panelShownPromise = promisePanelElementShown(window, widgetOverflowPanel);
- let identityBox = document.getElementById("identity-box");
- let overflowChevron = document.getElementById("nav-bar-overflow-button");
-
- // Listen for hiding immediately so we don't miss the event because of the
- // async-ness of the 'shown' yield...
- let panelHiddenPromise = promisePanelElementHidden(window, widgetOverflowPanel);
-
- var ds = Components.classes["@mozilla.org/widget/dragservice;1"].
- getService(Components.interfaces.nsIDragService);
-
- ds.startDragSession();
- try {
- var [result, dataTransfer] = EventUtils.synthesizeDragOver(identityBox, overflowChevron);
-
- // Wait for showing panel before ending drag session.
- yield panelShownPromise;
-
- EventUtils.synthesizeDropAfterDragOver(result, dataTransfer, overflowChevron);
- } finally {
- ds.endDragSession(true);
- }
-
- info("Overflow panel is shown.");
-
- widgetOverflowPanel.hidePopup();
- yield panelHiddenPromise;
-});
-
-add_task(function*() {
- window.resizeTo(originalWindowWidth, window.outerHeight);
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
- ok(!navbar.hasAttribute("overflowing"), "Should not have an overflowing toolbar.");
-});
diff --git a/browser/components/customizableui/test/browser_962884_opt_in_disable_hyphens.js b/browser/components/customizableui/test/browser_962884_opt_in_disable_hyphens.js
deleted file mode 100644
index cf2603999..000000000
--- a/browser/components/customizableui/test/browser_962884_opt_in_disable_hyphens.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- const kNormalLabel = "Character Encoding";
- CustomizableUI.addWidgetToArea("characterencoding-button", CustomizableUI.AREA_NAVBAR);
- let characterEncoding = document.getElementById("characterencoding-button");
- const kOriginalLabel = characterEncoding.getAttribute("label");
- characterEncoding.setAttribute("label", "\u00ad" + kNormalLabel);
- CustomizableUI.addWidgetToArea("characterencoding-button", CustomizableUI.AREA_PANEL);
-
- yield PanelUI.show();
-
- is(characterEncoding.getAttribute("auto-hyphens"), "off",
- "Hyphens should be disabled if the &shy; character is present in the label");
- let multilineText = document.getAnonymousElementByAttribute(characterEncoding, "class", "toolbarbutton-multiline-text");
- let multilineTextCS = getComputedStyle(multilineText);
- is(multilineTextCS.MozHyphens, "manual", "-moz-hyphens should be set to manual when the &shy; character is present.")
-
- let hiddenPanelPromise = promisePanelHidden(window);
- PanelUI.toggle();
- yield hiddenPanelPromise;
-
- characterEncoding.setAttribute("label", kNormalLabel);
-
- yield PanelUI.show();
-
- isnot(characterEncoding.getAttribute("auto-hyphens"), "off",
- "Hyphens should not be disabled if the &shy; character is not present in the label");
- multilineText = document.getAnonymousElementByAttribute(characterEncoding, "class", "toolbarbutton-multiline-text");
- multilineTextCS = getComputedStyle(multilineText);
- is(multilineTextCS.MozHyphens, "auto", "-moz-hyphens should be set to auto by default.")
-
- hiddenPanelPromise = promisePanelHidden(window);
- PanelUI.toggle();
- yield hiddenPanelPromise;
-
- characterEncoding.setAttribute("label", "\u00ad" + kNormalLabel);
- CustomizableUI.removeWidgetFromArea("characterencoding-button");
- yield startCustomizing();
-
- isnot(characterEncoding.getAttribute("auto-hyphens"), "off",
- "Hyphens should not be disabled when the widget is in the palette");
-
- gCustomizeMode.addToPanel(characterEncoding);
- is(characterEncoding.getAttribute("auto-hyphens"), "off",
- "Hyphens should be disabled if the &shy; character is present in the label in customization mode");
- multilineText = document.getAnonymousElementByAttribute(characterEncoding, "class", "toolbarbutton-multiline-text");
- multilineTextCS = getComputedStyle(multilineText);
- is(multilineTextCS.MozHyphens, "manual", "-moz-hyphens should be set to manual when the &shy; character is present in customization mode.")
-
- yield endCustomizing();
-
- CustomizableUI.addWidgetToArea("characterencoding-button", CustomizableUI.AREA_NAVBAR);
- ok(!characterEncoding.hasAttribute("auto-hyphens"),
- "Removing the widget from the panel should remove the auto-hyphens attribute");
-
- characterEncoding.setAttribute("label", kOriginalLabel);
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_963639_customizing_attribute_non_customizable_toolbar.js b/browser/components/customizableui/test/browser_963639_customizing_attribute_non_customizable_toolbar.js
deleted file mode 100644
index e5710c50a..000000000
--- a/browser/components/customizableui/test/browser_963639_customizing_attribute_non_customizable_toolbar.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbar = "test-toolbar-963639-non-customizable-customizing-attribute";
-
-add_task(function*() {
- info("Test for Bug 963639 - CustomizeMode _onToolbarVisibilityChange sets @customizing on non-customizable toolbars");
-
- let toolbar = document.createElement("toolbar");
- toolbar.id = kToolbar;
- gNavToolbox.appendChild(toolbar);
-
- let testToolbar = document.getElementById(kToolbar)
- ok(testToolbar, "Toolbar was created.");
- is(gNavToolbox.getElementsByAttribute("id", kToolbar).length, 1,
- "Toolbar was added to the navigator toolbox");
-
- toolbar.setAttribute("toolbarname", "NonCustomizableToolbarCustomizingAttribute");
- toolbar.setAttribute("collapsed", "true");
-
- yield startCustomizing();
- window.setToolbarVisibility(toolbar, "true");
- isnot(toolbar.getAttribute("customizing"), "true",
- "Toolbar doesn't have the customizing attribute");
-
- yield endCustomizing();
- gNavToolbox.removeChild(toolbar);
-
- is(gNavToolbox.getElementsByAttribute("id", kToolbar).length, 0,
- "Toolbar was removed from the navigator toolbox");
-});
diff --git a/browser/components/customizableui/test/browser_967000_button_charEncoding.js b/browser/components/customizableui/test/browser_967000_button_charEncoding.js
deleted file mode 100644
index 0688ebbd6..000000000
--- a/browser/components/customizableui/test/browser_967000_button_charEncoding.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test_967000_charEncoding_page.html";
-
-add_task(function*() {
- info("Check Character Encoding button functionality");
-
- // add the Character Encoding button to the panel
- CustomizableUI.addWidgetToArea("characterencoding-button",
- CustomizableUI.AREA_PANEL);
-
- // check the button's functionality
- yield PanelUI.show();
-
- let charEncodingButton = document.getElementById("characterencoding-button");
- ok(charEncodingButton, "The Character Encoding button was added to the Panel Menu");
- is(charEncodingButton.getAttribute("disabled"), "true",
- "The Character encoding button is initially disabled");
-
- let panelHidePromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidePromise;
-
- let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE, true, true);
-
- yield PanelUI.show();
- ok(!charEncodingButton.hasAttribute("disabled"), "The Character encoding button gets enabled");
- let characterEncodingView = document.getElementById("PanelUI-characterEncodingView");
- let subviewShownPromise = subviewShown(characterEncodingView);
- charEncodingButton.click();
- yield subviewShownPromise;
-
- ok(characterEncodingView.hasAttribute("current"), "The Character encoding panel is displayed");
-
- let pinnedEncodings = document.getElementById("PanelUI-characterEncodingView-pinned");
- let charsetsList = document.getElementById("PanelUI-characterEncodingView-charsets");
- ok(pinnedEncodings, "Pinned charsets are available");
- ok(charsetsList, "Charsets list is available");
-
- let checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
- is(checkedButtons.length, 2, "There should be 2 checked items (1 charset, 1 detector).");
- is(checkedButtons[0].getAttribute("label"), "Unicode", "The unicode encoding is correctly selected");
- is(characterEncodingView.querySelectorAll("#PanelUI-characterEncodingView-autodetect toolbarbutton[checked='true']").length,
- 1,
- "There should be 1 checked detector.");
-
- panelHidePromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidePromise;
-
- yield BrowserTestUtils.removeTab(newTab);
-});
-
-add_task(function* asyncCleanup() {
- // reset the panel to the default state
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
-});
diff --git a/browser/components/customizableui/test/browser_967000_button_feeds.js b/browser/components/customizableui/test/browser_967000_button_feeds.js
deleted file mode 100644
index 8f391941a..000000000
--- a/browser/components/customizableui/test/browser_967000_button_feeds.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/feeds_test_page.html";
-const TEST_FEED = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test-feed.xml"
-
-var newTab = null;
-var initialLocation = gBrowser.currentURI.spec;
-
-add_task(function*() {
- info("Check Subscribe button functionality");
-
- // add the Subscribe button to the panel
- CustomizableUI.addWidgetToArea("feed-button",
- CustomizableUI.AREA_PANEL);
-
- // check the button's functionality
- yield PanelUI.show();
-
- let feedButton = document.getElementById("feed-button");
- ok(feedButton, "The Subscribe button was added to the Panel Menu");
- is(feedButton.getAttribute("disabled"), "true", "The Subscribe button is initially disabled");
-
- let panelHidePromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidePromise;
-
- newTab = gBrowser.selectedTab;
- yield promiseTabLoadEvent(newTab, TEST_PAGE);
-
- yield PanelUI.show();
-
- yield waitForCondition(() => !feedButton.hasAttribute("disabled"));
- ok(!feedButton.hasAttribute("disabled"), "The Subscribe button gets enabled");
-
- feedButton.click();
- yield promiseTabLoadEvent(newTab, TEST_FEED);
-
- is(gBrowser.currentURI.spec, TEST_FEED, "Subscribe page opened");
- ok(!isPanelUIOpen(), "Panel is closed");
-
- if (isPanelUIOpen()) {
- panelHidePromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidePromise;
- }
-});
-
-add_task(function* asyncCleanup() {
- // reset the panel UI to the default state
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
-
- // restore the initial location
- gBrowser.addTab(initialLocation);
- gBrowser.removeTab(newTab);
-});
diff --git a/browser/components/customizableui/test/browser_967000_button_sync.js b/browser/components/customizableui/test/browser_967000_button_sync.js
deleted file mode 100644
index 15a3235e0..000000000
--- a/browser/components/customizableui/test/browser_967000_button_sync.js
+++ /dev/null
@@ -1,335 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-let {SyncedTabs} = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
-
-XPCOMUtils.defineLazyModuleGetter(this, "UITour", "resource:///modules/UITour.jsm");
-
-// These are available on the widget implementation, but it seems impossible
-// to grab that impl at runtime.
-const DECKINDEX_TABS = 0;
-const DECKINDEX_TABSDISABLED = 1;
-const DECKINDEX_FETCHING = 2;
-const DECKINDEX_NOCLIENTS = 3;
-
-var initialLocation = gBrowser.currentURI.spec;
-var newTab = null;
-
-// A helper to notify there are new tabs. Returns a promise that is resolved
-// once the UI has been updated.
-function updateTabsPanel() {
- let promiseTabsUpdated = promiseObserverNotified("synced-tabs-menu:test:tabs-updated");
- Services.obs.notifyObservers(null, SyncedTabs.TOPIC_TABS_CHANGED, null);
- return promiseTabsUpdated;
-}
-
-// This is the mock we use for SyncedTabs.jsm - tests may override various
-// functions.
-let mockedInternal = {
- get isConfiguredToSyncTabs() { return true; },
- getTabClients() { return []; },
- syncTabs() {},
- hasSyncedThisSession: false,
-};
-
-
-add_task(function* setup() {
- let oldInternal = SyncedTabs._internal;
- SyncedTabs._internal = mockedInternal;
-
- registerCleanupFunction(() => {
- SyncedTabs._internal = oldInternal;
- });
-});
-
-// The test expects the about:preferences#sync page to open in the current tab
-function* openPrefsFromMenuPanel(expectedPanelId, entryPoint) {
- info("Check Sync button functionality");
- Services.prefs.setCharPref("identity.fxaccounts.remote.signup.uri", "http://example.com/");
-
- // add the Sync button to the panel
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
-
- // check the button's functionality
- yield PanelUI.show();
-
- if (entryPoint == "uitour") {
- UITour.tourBrowsersByWindow.set(window, new Set());
- UITour.tourBrowsersByWindow.get(window).add(gBrowser.selectedBrowser);
- }
-
- let syncButton = document.getElementById("sync-button");
- ok(syncButton, "The Sync button was added to the Panel Menu");
-
- syncButton.click();
- let syncPanel = document.getElementById("PanelUI-remotetabs");
- ok(syncPanel.getAttribute("current"), "Sync Panel is in view");
-
- // Sync is not configured - verify that state is reflected.
- let subpanel = document.getElementById(expectedPanelId)
- ok(!subpanel.hidden, "sync setup element is visible");
-
- // Find and click the "setup" button.
- let setupButton = subpanel.querySelector(".PanelUI-remotetabs-prefs-button");
- setupButton.click();
-
- let deferred = Promise.defer();
- let handler = (e) => {
- if (e.originalTarget != gBrowser.selectedBrowser.contentDocument ||
- e.target.location.href == "about:blank") {
- info("Skipping spurious 'load' event for " + e.target.location.href);
- return;
- }
- gBrowser.selectedBrowser.removeEventListener("load", handler, true);
- deferred.resolve();
- }
- gBrowser.selectedBrowser.addEventListener("load", handler, true);
-
- yield deferred.promise;
- newTab = gBrowser.selectedTab;
-
- is(gBrowser.currentURI.spec, "about:preferences?entrypoint=" + entryPoint + "#sync",
- "Firefox Sync preference page opened with `menupanel` entrypoint");
- ok(!isPanelUIOpen(), "The panel closed");
-
- if (isPanelUIOpen()) {
- let panelHidePromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidePromise;
- }
-}
-
-function* asyncCleanup() {
- Services.prefs.clearUserPref("identity.fxaccounts.remote.signup.uri");
- // reset the panel UI to the default state
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "The panel UI is in default state again.");
-
- // restore the tabs
- gBrowser.addTab(initialLocation);
- gBrowser.removeTab(newTab);
- UITour.tourBrowsersByWindow.delete(window);
-}
-
-// When Sync is not setup.
-add_task(() => openPrefsFromMenuPanel("PanelUI-remotetabs-setupsync", "synced-tabs"));
-add_task(asyncCleanup);
-
-// When Sync is configured in a "needs reauthentication" state.
-add_task(function* () {
- // configure our broadcasters so we are in the right state.
- document.getElementById("sync-reauth-state").hidden = false;
- document.getElementById("sync-setup-state").hidden = true;
- document.getElementById("sync-syncnow-state").hidden = true;
- yield openPrefsFromMenuPanel("PanelUI-remotetabs-reauthsync", "synced-tabs")
-});
-
-// Test the mobile promo links
-add_task(function* () {
- // change the preferences for the mobile links.
- Services.prefs.setCharPref("identity.mobilepromo.android", "http://example.com/?os=android&tail=");
- Services.prefs.setCharPref("identity.mobilepromo.ios", "http://example.com/?os=ios&tail=");
-
- mockedInternal.getTabClients = () => [];
- mockedInternal.syncTabs = () => Promise.resolve();
-
- document.getElementById("sync-reauth-state").hidden = true;
- document.getElementById("sync-setup-state").hidden = true;
- document.getElementById("sync-syncnow-state").hidden = false;
-
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
-
- let syncPanel = document.getElementById("PanelUI-remotetabs");
- let links = syncPanel.querySelectorAll(".remotetabs-promo-link");
-
- is(links.length, 2, "found 2 links as expected");
-
- // test each link and left and middle mouse buttons
- for (let link of links) {
- for (let button = 0; button < 2; button++) {
- 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);
- resolve();
- }, 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");
- let expectedUrl = `http://example.com/?os=${os}&tail=synced-tabs`;
- is(gBrowser.selectedBrowser.currentURI.spec, expectedUrl, "correct URL");
- gBrowser.removeTab(gBrowser.selectedTab);
- }
- }
-
- // test each link and right mouse button - should be a noop.
- yield PanelUI.show();
- for (let link of links) {
- EventUtils.sendMouseEvent({ type: "click", button: 2 }, link, window);
- // the panel should still be open
- ok(isPanelUIOpen(), "panel remains open after right-click");
- is(gBrowser.tabs.length, 1, "no new tab was opened");
- }
- PanelUI.hide();
-
- Services.prefs.clearUserPref("identity.mobilepromo.android");
- Services.prefs.clearUserPref("identity.mobilepromo.ios");
-});
-
-// Test the "Sync Now" button
-add_task(function* () {
- mockedInternal.getTabClients = () => [];
- mockedInternal.syncTabs = () => {
- return Promise.resolve();
- }
-
- // configure our broadcasters so we are in the right state.
- document.getElementById("sync-reauth-state").hidden = true;
- document.getElementById("sync-setup-state").hidden = true;
- document.getElementById("sync-syncnow-state").hidden = false;
-
- // add the Sync button to the panel
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- yield PanelUI.show();
- document.getElementById("sync-button").click();
- let syncPanel = document.getElementById("PanelUI-remotetabs");
- ok(syncPanel.getAttribute("current"), "Sync Panel is in view");
-
- let subpanel = document.getElementById("PanelUI-remotetabs-main")
- ok(!subpanel.hidden, "main pane is visible");
- let deck = document.getElementById("PanelUI-remotetabs-deck");
-
- // The widget is still fetching tabs, as we've neutered everything that
- // provides them
- is(deck.selectedIndex, DECKINDEX_FETCHING, "first deck entry is visible");
-
- let syncNowButton = document.getElementById("PanelUI-remotetabs-syncnow");
-
- let didSync = false;
- let oldDoSync = gSyncUI.doSync;
- gSyncUI.doSync = function() {
- didSync = true;
- mockedInternal.hasSyncedThisSession = true;
- gSyncUI.doSync = oldDoSync;
- }
- syncNowButton.click();
- ok(didSync, "clicking the button called the correct function");
-
- // Tell the widget there are tabs available, but with zero clients.
- mockedInternal.getTabClients = () => {
- return Promise.resolve([]);
- }
- yield updateTabsPanel();
- // The UI should be showing the "no clients" pane.
- is(deck.selectedIndex, DECKINDEX_NOCLIENTS, "no-clients deck entry is visible");
-
- // Tell the widget there are tabs available - we have 3 clients, one with no
- // tabs.
- mockedInternal.getTabClients = () => {
- return Promise.resolve([
- {
- id: "guid_mobile",
- type: "client",
- name: "My Phone",
- tabs: [],
- },
- {
- id: "guid_desktop",
- type: "client",
- name: "My Desktop",
- tabs: [
- {
- title: "http://example.com/10",
- lastUsed: 10, // the most recent
- },
- {
- title: "http://example.com/1",
- lastUsed: 1, // the least recent.
- },
- {
- title: "http://example.com/5",
- lastUsed: 5,
- },
- ],
- },
- {
- id: "guid_second_desktop",
- name: "My Other Desktop",
- tabs: [
- {
- title: "http://example.com/6",
- lastUsed: 6,
- }
- ],
- },
- ]);
- };
- yield updateTabsPanel();
-
- // The UI should be showing tabs!
- is(deck.selectedIndex, DECKINDEX_TABS, "no-clients deck entry is visible");
- let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
- let node = tabList.firstChild;
- // First entry should be the client with the most-recent tab.
- is(node.getAttribute("itemtype"), "client", "node is a client entry");
- is(node.textContent, "My Desktop", "correct client");
- // Next entry is the most-recent tab
- node = node.nextSibling;
- is(node.getAttribute("itemtype"), "tab", "node is a tab");
- is(node.getAttribute("label"), "http://example.com/10");
-
- // Next entry is the next-most-recent tab
- node = node.nextSibling;
- is(node.getAttribute("itemtype"), "tab", "node is a tab");
- is(node.getAttribute("label"), "http://example.com/5");
-
- // Next entry is the least-recent tab from the first client.
- node = node.nextSibling;
- is(node.getAttribute("itemtype"), "tab", "node is a tab");
- is(node.getAttribute("label"), "http://example.com/1");
-
- // Next is a menuseparator between the clients.
- node = node.nextSibling;
- is(node.nodeName, "menuseparator");
-
- // Next is the client with 1 tab.
- node = node.nextSibling;
- is(node.getAttribute("itemtype"), "client", "node is a client entry");
- is(node.textContent, "My Other Desktop", "correct client");
- // Its single tab
- node = node.nextSibling;
- is(node.getAttribute("itemtype"), "tab", "node is a tab");
- is(node.getAttribute("label"), "http://example.com/6");
-
- // Next is a menuseparator between the clients.
- node = node.nextSibling;
- is(node.nodeName, "menuseparator");
-
- // Next is the client with no tab.
- node = node.nextSibling;
- is(node.getAttribute("itemtype"), "client", "node is a client entry");
- is(node.textContent, "My Phone", "correct client");
- // There is a single node saying there's no tabs for the client.
- node = node.nextSibling;
- is(node.nodeName, "label", "node is a label");
- is(node.getAttribute("itemtype"), "", "node is neither a tab nor a client");
-
- node = node.nextSibling;
- is(node, null, "no more entries");
-});
diff --git a/browser/components/customizableui/test/browser_968447_bookmarks_toolbar_items_in_panel.js b/browser/components/customizableui/test/browser_968447_bookmarks_toolbar_items_in_panel.js
deleted file mode 100644
index 88c30bf81..000000000
--- a/browser/components/customizableui/test/browser_968447_bookmarks_toolbar_items_in_panel.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Bug 968447 - The Bookmarks Toolbar Items doesn't appear as a
-// normal menu panel button in new windows.
-add_task(function*() {
- const buttonId = "bookmarks-toolbar-placeholder";
- yield startCustomizing();
- CustomizableUI.addWidgetToArea("personal-bookmarks", CustomizableUI.AREA_PANEL);
- yield endCustomizing();
-
- yield PanelUI.show();
-
- let bookmarksToolbarPlaceholder = document.getElementById(buttonId);
- ok(bookmarksToolbarPlaceholder.classList.contains("toolbarbutton-1"),
- "Button should have toolbarbutton-1 class");
- is(bookmarksToolbarPlaceholder.getAttribute("wrap"), "true",
- "Button should have the 'wrap' attribute");
-
- info("Waiting for panel to close");
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
-
- info("Waiting for window to open");
- let newWin = yield openAndLoadWindow({}, true);
-
- info("Waiting for panel in new window to open");
- let hideTrace = function() {
- info(new Error().stack);
- info("Panel was hidden.");
- };
- newWin.PanelUI.panel.addEventListener("popuphidden", hideTrace);
-
- yield newWin.PanelUI.show();
- let newWinBookmarksToolbarPlaceholder = newWin.document.getElementById(buttonId);
- ok(newWinBookmarksToolbarPlaceholder.classList.contains("toolbarbutton-1"),
- "Button in new window should have toolbarbutton-1 class");
- is(newWinBookmarksToolbarPlaceholder.getAttribute("wrap"), "true",
- "Button in new window should have 'wrap' attribute");
-
- newWin.PanelUI.panel.removeEventListener("popuphidden", hideTrace);
- // XXXgijs on Linux, we're sometimes seeing the panel being hidden early
- // in the newly created window, probably because something else steals focus.
- if (newWin.PanelUI.panel.state != "closed") {
- info("Panel is still open in new window, waiting for it to close");
- panelHiddenPromise = promisePanelHidden(newWin);
- newWin.PanelUI.hide();
- yield panelHiddenPromise;
- } else {
- info("panel was already closed");
- }
-
- info("Waiting for new window to close");
- yield promiseWindowClosed(newWin);
-});
-
-add_task(function* asyncCleanUp() {
- yield endCustomizing();
- CustomizableUI.reset();
-});
-
diff --git a/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js b/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
deleted file mode 100644
index f7504fc41..000000000
--- a/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kHidden1Id = "test-hidden-button-1";
-const kHidden2Id = "test-hidden-button-2";
-
-var navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
-// When we drag an item onto a customizable area, and not over a specific target, we
-// should assume that we're appending them to the area. If doing so, we should scan
-// backwards over any hidden items and insert the item before those hidden items.
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Should be in the default state");
-
- // Iterate backwards over the items in the nav-bar until we find the first
- // one that is not hidden.
- let placements = CustomizableUI.getWidgetsInArea(CustomizableUI.AREA_NAVBAR);
- let lastVisible = null;
- for (let widgetGroup of placements.reverse()) {
- let widget = widgetGroup.forWindow(window);
- if (widget && widget.node && !widget.node.hidden) {
- lastVisible = widget.node;
- break;
- }
- }
-
- if (!lastVisible) {
- ok(false, "Apparently, there are no visible items in the nav-bar.");
- }
-
- info("The last visible item in the nav-bar has ID: " + lastVisible.id);
-
- let hidden1 = createDummyXULButton(kHidden1Id, "You can't see me");
- let hidden2 = createDummyXULButton(kHidden2Id, "You can't see me either.");
- hidden1.hidden = hidden2.hidden = true;
-
- // Make sure we have some hidden items at the end of the nav-bar.
- navbar.insertItem(hidden1.id);
- navbar.insertItem(hidden2.id);
-
- // Drag an item and drop it onto the nav-bar customization target, but
- // not over a particular item.
- yield startCustomizing();
- let downloadsButton = document.getElementById("downloads-button");
- simulateItemDrag(downloadsButton, navbar.customizationTarget);
-
- yield endCustomizing();
-
- is(downloadsButton.previousSibling.id, lastVisible.id,
- "The downloads button should be placed after the last visible item.");
-
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_969427_recreate_destroyed_widget_after_reset.js b/browser/components/customizableui/test/browser_969427_recreate_destroyed_widget_after_reset.js
deleted file mode 100644
index b5479fcb7..000000000
--- a/browser/components/customizableui/test/browser_969427_recreate_destroyed_widget_after_reset.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-function getPlacementArea(id) {
- let placement = CustomizableUI.getPlacementOfWidget(id);
- return placement && placement.area;
-}
-
-// Check that a destroyed widget recreated after a reset call goes to
-// the navigation bar.
-add_task(function() {
- const kWidgetId = "test-recreate-after-reset";
- let spec = {id: kWidgetId, label: "Test re-create after reset.",
- removable: true, defaultArea: CustomizableUI.AREA_NAVBAR};
-
- CustomizableUI.createWidget(spec);
- is(getPlacementArea(kWidgetId), CustomizableUI.AREA_NAVBAR,
- "widget is in the navigation bar");
-
- CustomizableUI.destroyWidget(kWidgetId);
- isnot(getPlacementArea(kWidgetId), CustomizableUI.AREA_NAVBAR,
- "widget removed from the navigation bar");
-
- CustomizableUI.reset();
-
- CustomizableUI.createWidget(spec);
- is(getPlacementArea(kWidgetId), CustomizableUI.AREA_NAVBAR,
- "widget recreated and added back to the nav bar");
-
- CustomizableUI.destroyWidget(kWidgetId);
-});
diff --git a/browser/components/customizableui/test/browser_969661_character_encoding_navbar_disabled.js b/browser/components/customizableui/test/browser_969661_character_encoding_navbar_disabled.js
deleted file mode 100644
index 6f057a100..000000000
--- a/browser/components/customizableui/test/browser_969661_character_encoding_navbar_disabled.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-
-// Adding the character encoding menu to the panel, exiting customize mode,
-// and moving it to the nav-bar should have it enabled, not disabled.
-add_task(function*() {
- yield startCustomizing();
- CustomizableUI.addWidgetToArea("characterencoding-button", "PanelUI-contents");
- yield endCustomizing();
- yield PanelUI.show();
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
- CustomizableUI.addWidgetToArea("characterencoding-button", 'nav-bar');
- let button = document.getElementById("characterencoding-button");
- ok(!button.hasAttribute("disabled"), "Button shouldn't be disabled");
-});
-
-add_task(function asyncCleanup() {
- resetCustomization();
-});
-
diff --git a/browser/components/customizableui/test/browser_970511_undo_restore_default.js b/browser/components/customizableui/test/browser_970511_undo_restore_default.js
deleted file mode 100644
index e7b3ca674..000000000
--- a/browser/components/customizableui/test/browser_970511_undo_restore_default.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-// Restoring default should reset theme and show an "undo" option which undoes the restoring operation.
-add_task(function*() {
- let homeButtonId = "home-button";
- CustomizableUI.removeWidgetFromArea(homeButtonId);
- yield startCustomizing();
- ok(!CustomizableUI.inDefaultState, "Not in default state to begin with");
- is(CustomizableUI.getPlacementOfWidget(homeButtonId), null, "Home button is in palette");
- let undoResetButton = document.getElementById("customization-undo-reset-button");
- is(undoResetButton.hidden, true, "The undo button is hidden before reset");
-
- let themesButton = document.getElementById("customization-lwtheme-button");
- let popup = document.getElementById("customization-lwtheme-menu");
- let popupShownPromise = popupShown(popup);
- EventUtils.synthesizeMouseAtCenter(themesButton, {});
- info("Clicked on themes button");
- yield popupShownPromise;
-
- let recommendedHeader = document.getElementById("customization-lwtheme-menu-recommended");
- let firstLWTheme = recommendedHeader.nextSibling;
- let firstLWThemeId = firstLWTheme.theme.id;
- let themeChangedPromise = promiseObserverNotified("lightweight-theme-changed");
- firstLWTheme.doCommand();
- info("Clicked on first theme");
- yield themeChangedPromise;
-
- is(LightweightThemeManager.currentTheme.id, firstLWThemeId, "Theme changed to first option");
-
- yield gCustomizeMode.reset();
-
- ok(CustomizableUI.inDefaultState, "In default state after reset");
- is(undoResetButton.hidden, false, "The undo button is visible after reset");
- is(LightweightThemeManager.currentTheme, null, "Theme reset to default");
-
- yield gCustomizeMode.undoReset()
-
- is(LightweightThemeManager.currentTheme.id, firstLWThemeId, "Theme has been reset from default to original choice");
- ok(!CustomizableUI.inDefaultState, "Not in default state after undo-reset");
- is(undoResetButton.hidden, true, "The undo button is hidden after clicking on the undo button");
- is(CustomizableUI.getPlacementOfWidget(homeButtonId), null, "Home button is in palette");
-
- yield gCustomizeMode.reset();
-});
-
-// Performing an action after a reset will hide the reset button.
-add_task(function*() {
- let homeButtonId = "home-button";
- CustomizableUI.removeWidgetFromArea(homeButtonId);
- ok(!CustomizableUI.inDefaultState, "Not in default state to begin with");
- is(CustomizableUI.getPlacementOfWidget(homeButtonId), null, "Home button is in palette");
- let undoResetButton = document.getElementById("customization-undo-reset-button");
- is(undoResetButton.hidden, true, "The undo button is hidden before reset");
-
- yield gCustomizeMode.reset();
-
- ok(CustomizableUI.inDefaultState, "In default state after reset");
- is(undoResetButton.hidden, false, "The undo button is visible after reset");
-
- CustomizableUI.addWidgetToArea(homeButtonId, CustomizableUI.AREA_PANEL);
- is(undoResetButton.hidden, true, "The undo button is hidden after another change");
-});
-
-// "Restore defaults", exiting customize, and re-entering shouldn't show the Undo button
-add_task(function*() {
- let undoResetButton = document.getElementById("customization-undo-reset-button");
- is(undoResetButton.hidden, true, "The undo button is hidden before a reset");
- ok(!CustomizableUI.inDefaultState, "The browser should not be in default state");
- yield gCustomizeMode.reset();
-
- is(undoResetButton.hidden, false, "The undo button is visible after a reset");
- yield endCustomizing();
- yield startCustomizing();
- is(undoResetButton.hidden, true, "The undo reset button should be hidden after entering customization mode");
-});
-
-// Bug 971626 - Restore Defaults should collapse the Title Bar
-add_task(function*() {
- if (Services.appinfo.OS != "WINNT" &&
- Services.appinfo.OS != "Darwin") {
- return;
- }
- let prefName = "browser.tabs.drawInTitlebar";
- let defaultValue = Services.prefs.getBoolPref(prefName);
- let restoreDefaultsButton = document.getElementById("customization-reset-button");
- let titleBarButton = document.getElementById("customization-titlebar-visibility-button");
- let undoResetButton = document.getElementById("customization-undo-reset-button");
- ok(CustomizableUI.inDefaultState, "Should be in default state at start of test");
- ok(restoreDefaultsButton.disabled, "Restore defaults button should be disabled when in default state");
- is(titleBarButton.hasAttribute("checked"), !defaultValue, "Title bar button should reflect pref value");
- is(undoResetButton.hidden, true, "Undo reset button should be hidden at start of test");
-
- Services.prefs.setBoolPref(prefName, !defaultValue);
- ok(!restoreDefaultsButton.disabled, "Restore defaults button should be enabled when pref changed");
- is(titleBarButton.hasAttribute("checked"), defaultValue, "Title bar button should reflect changed pref value");
- ok(!CustomizableUI.inDefaultState, "With titlebar flipped, no longer default");
- is(undoResetButton.hidden, true, "Undo reset button should be hidden after pref change");
-
- yield gCustomizeMode.reset();
- ok(restoreDefaultsButton.disabled, "Restore defaults button should be disabled after reset");
- is(titleBarButton.hasAttribute("checked"), !defaultValue, "Title bar button should reflect default value after reset");
- is(Services.prefs.getBoolPref(prefName), defaultValue, "Reset should reset drawInTitlebar");
- ok(CustomizableUI.inDefaultState, "In default state after titlebar reset");
- is(undoResetButton.hidden, false, "Undo reset button should be visible after reset");
- ok(!undoResetButton.disabled, "Undo reset button should be enabled after reset");
-
- yield gCustomizeMode.undoReset();
- ok(!restoreDefaultsButton.disabled, "Restore defaults button should be enabled after undo-reset");
- is(titleBarButton.hasAttribute("checked"), defaultValue, "Title bar button should reflect undo-reset value");
- ok(!CustomizableUI.inDefaultState, "No longer in default state after undo");
- is(Services.prefs.getBoolPref(prefName), !defaultValue, "Undo-reset goes back to previous pref value");
- is(undoResetButton.hidden, true, "Undo reset button should be hidden after undo-reset clicked");
-
- Services.prefs.clearUserPref(prefName);
- ok(CustomizableUI.inDefaultState, "In default state after pref cleared");
- is(undoResetButton.hidden, true, "Undo reset button should be hidden at end of test");
-});
-
-add_task(function* asyncCleanup() {
- yield gCustomizeMode.reset();
- yield endCustomizing();
-});
diff --git a/browser/components/customizableui/test/browser_972267_customizationchange_events.js b/browser/components/customizableui/test/browser_972267_customizationchange_events.js
deleted file mode 100644
index b37dbe954..000000000
--- a/browser/components/customizableui/test/browser_972267_customizationchange_events.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Create a new window, then move the home button to the menu and check both windows have
-// customizationchange events fire on the toolbox:
-add_task(function*() {
- let newWindow = yield openAndLoadWindow();
- let otherToolbox = newWindow.gNavToolbox;
-
- let handlerCalledCount = 0;
- let handler = (ev) => {
- handlerCalledCount++;
- };
-
- let homeButton = document.getElementById("home-button");
-
- gNavToolbox.addEventListener("customizationchange", handler);
- otherToolbox.addEventListener("customizationchange", handler);
-
- gCustomizeMode.addToPanel(homeButton);
-
- is(handlerCalledCount, 2, "Should be called for both windows.");
-
- // If the test is run in isolation and the panel has never been open,
- // the button will be in the palette. Deal with this case:
- if (homeButton.parentNode.id == "BrowserToolbarPalette") {
- yield PanelUI.ensureReady();
- isnot(homeButton.parentNode.id, "BrowserToolbarPalette", "Home button should now be in panel");
- }
-
- handlerCalledCount = 0;
- gCustomizeMode.addToToolbar(homeButton);
- is(handlerCalledCount, 2, "Should be called for both windows.");
-
- gNavToolbox.removeEventListener("customizationchange", handler);
- otherToolbox.removeEventListener("customizationchange", handler);
-
- yield promiseWindowClosed(newWindow);
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_973641_button_addon.js b/browser/components/customizableui/test/browser_973641_button_addon.js
deleted file mode 100755
index 796bf3d0e..000000000
--- a/browser/components/customizableui/test/browser_973641_button_addon.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kButton = "test_button_for_addon";
-var initialLocation = gBrowser.currentURI.spec;
-
-add_task(function*() {
- info("Check addon button functionality");
-
- // create mocked addon button on the navigation bar
- let widgetSpec = {
- id: kButton,
- type: 'button',
- onClick: function() {
- gBrowser.selectedTab = gBrowser.addTab("about:addons");
- }
- };
- CustomizableUI.createWidget(widgetSpec);
- CustomizableUI.addWidgetToArea(kButton, CustomizableUI.AREA_NAVBAR);
-
- // check the button's functionality in navigation bar
- let addonButton = document.getElementById(kButton);
- let navBar = document.getElementById("nav-bar");
- ok(addonButton, "Addon button exists");
- ok(navBar.contains(addonButton), "Addon button is in the navbar");
- yield checkButtonFunctionality(addonButton);
-
- resetTabs();
-
- // move the add-on button in the Panel Menu
- CustomizableUI.addWidgetToArea(kButton, CustomizableUI.AREA_PANEL);
- ok(!navBar.contains(addonButton), "Addon button was removed from the browser bar");
-
- // check the addon button's functionality in the Panel Menu
- yield PanelUI.show();
- var panelMenu = document.getElementById("PanelUI-mainView");
- let addonButtonInPanel = panelMenu.getElementsByAttribute("id", kButton);
- ok(panelMenu.contains(addonButton), "Addon button was added to the Panel Menu");
- yield checkButtonFunctionality(addonButtonInPanel[0]);
-});
-
-add_task(function* asyncCleanup() {
- resetTabs();
-
- // reset the UI to the default state
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
-
- // destroy the widget
- CustomizableUI.destroyWidget(kButton);
-});
-
-function resetTabs() {
- // close all opened tabs
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeTab(gBrowser.selectedTab);
- }
-
- // restore the initial tab
- gBrowser.addTab(initialLocation);
- gBrowser.removeTab(gBrowser.selectedTab);
-}
-
-function* checkButtonFunctionality(aButton) {
- aButton.click();
- yield waitForCondition(() => gBrowser.currentURI &&
- gBrowser.currentURI.spec == "about:addons");
-}
diff --git a/browser/components/customizableui/test/browser_973932_addonbar_currentset.js b/browser/components/customizableui/test/browser_973932_addonbar_currentset.js
deleted file mode 100644
index 66fa6ef47..000000000
--- a/browser/components/customizableui/test/browser_973932_addonbar_currentset.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var addonbarID = CustomizableUI.AREA_ADDONBAR;
-var addonbar = document.getElementById(addonbarID);
-
-// Check that currentset is correctly updated after a reset:
-add_task(function*() {
- let placements = CustomizableUI.getWidgetIdsInArea(addonbarID);
- is(placements.join(','), addonbar.getAttribute("currentset"), "Addon-bar currentset should match default placements");
- ok(CustomizableUI.inDefaultState, "Should be in default state");
- info("Adding a spring to add-on bar shim");
- CustomizableUI.addWidgetToArea("spring", addonbarID, 1);
- ok(addonbar.getElementsByTagName("toolbarspring").length, "There should be a spring in the toolbar");
- ok(!CustomizableUI.inDefaultState, "Should no longer be in default state");
- placements = CustomizableUI.getWidgetIdsInArea(addonbarID);
- is(placements.join(','), addonbar.getAttribute("currentset"), "Addon-bar currentset should match placements after spring addition");
-
- yield startCustomizing();
- yield gCustomizeMode.reset();
- ok(CustomizableUI.inDefaultState, "Should be in default state after reset");
- placements = CustomizableUI.getWidgetIdsInArea(addonbarID);
- is(placements.join(','), addonbar.getAttribute("currentset"), "Addon-bar currentset should match default placements after reset");
- ok(!addonbar.getElementsByTagName("toolbarspring").length, "There should be no spring in the toolbar");
- yield endCustomizing();
-});
-
diff --git a/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js b/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js
deleted file mode 100644
index 73fc7c1ff..000000000
--- a/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-const kXULWidgetId = "a-test-button"; // we'll create a button with this ID.
-
-add_task(function setup() {
- // create a XUL button and add it to the palette.
- createDummyXULButton(kXULWidgetId, "test-button");
-});
-
-add_task(function* customizeToolbarAndKeepIt() {
- ok(gNavToolbox.toolbarset, "There should be a toolbarset");
- let toolbarID = "testAustralisCustomToolbar";
- gNavToolbox.appendCustomToolbar(toolbarID, "");
- let toolbarDOMID = getToolboxCustomToolbarId(toolbarID);
- let toolbarElement = document.getElementById(toolbarDOMID);
- ok(toolbarElement, "There should be a toolbar");
- if (!toolbarElement) {
- ok(false, "No toolbar created, bailing out of the test.");
- return;
- }
- is(toolbarElement.nextSibling, gNavToolbox.toolbarset,
- "Toolbar should have been inserted in toolbox, before toolbarset element");
- let cuiAreaType = CustomizableUI.getAreaType(toolbarDOMID);
- is(cuiAreaType, CustomizableUI.TYPE_TOOLBAR,
- "CustomizableUI should know the area and think it's a toolbar");
- if (cuiAreaType != CustomizableUI.TYPE_TOOLBAR) {
- ok(false, "Toolbar not registered successfully, bailing out of the test.");
- toolbarElement.remove();
- return;
- }
- ok(!CustomizableUI.getWidgetIdsInArea(toolbarDOMID).length, "There should be no widgets in the area yet.");
- CustomizableUI.addWidgetToArea("open-file-button", toolbarDOMID, 0);
- ok(toolbarElement.hasChildNodes(), "Toolbar should now have a button.");
- assertAreaPlacements(toolbarDOMID, ["open-file-button"]);
-
- gNavToolbox.toolbarset.setAttribute("toolbar1", toolbarID + ":open-file-button");
- document.persist(gNavToolbox.toolbarset.id, "toolbar1");
-
- yield startCustomizing();
- // First, exit customize mode without doing anything, and verify the toolbar doesn't get removed.
- yield endCustomizing();
- ok(!CustomizableUI.inDefaultState, "Shouldn't be in default state, the toolbar should still be there.");
- cuiAreaType = CustomizableUI.getAreaType(toolbarDOMID);
- is(cuiAreaType, CustomizableUI.TYPE_TOOLBAR,
- "CustomizableUI should still know the area and think it's a toolbar");
- ok(toolbarElement.parentNode, "Toolbar should still be in the DOM.");
- ok(toolbarElement.hasChildNodes(), "Toolbar should still have items in it.");
- assertAreaPlacements(toolbarDOMID, ["open-file-button"]);
-
- let newWindow = yield openAndLoadWindow({}, true);
- is(newWindow.gNavToolbox.toolbarset.getAttribute("toolbar1"),
- gNavToolbox.toolbarset.getAttribute("toolbar1"),
- "Attribute should be the same in new window");
- yield promiseWindowClosed(newWindow);
-
- // Then customize again, and this time empty out the toolbar and verify it *does* get removed.
- yield startCustomizing();
- let openFileButton = document.getElementById("open-file-button");
- let palette = document.getElementById("customization-palette");
- simulateItemDrag(openFileButton, palette);
- ok(!CustomizableUI.inDefaultState, "Shouldn't be in default state because there's still a non-collapsed toolbar.");
- ok(!toolbarElement.hasChildNodes(), "Toolbar should have no more child nodes.");
-
- toolbarElement.collapsed = true;
- ok(CustomizableUI.inDefaultState, "Should be in default state because there's now just a collapsed toolbar.");
- toolbarElement.collapsed = false;
- ok(!CustomizableUI.inDefaultState, "Shouldn't be in default state because there's a non-collapsed toolbar again.");
- yield endCustomizing();
- ok(CustomizableUI.inDefaultState, "Should be in default state because the toolbar should have been removed.");
-
- newWindow = yield openAndLoadWindow({}, true);
- ok(!newWindow.gNavToolbox.toolbarset.hasAttribute("toolbar1"),
- "Attribute should be gone in new window");
- yield promiseWindowClosed(newWindow);
-
- ok(!toolbarElement.parentNode, "Toolbar should no longer be in the DOM.");
- cuiAreaType = CustomizableUI.getAreaType(toolbarDOMID);
- is(cuiAreaType, null, "CustomizableUI should have forgotten all about the area");
-});
-
-add_task(function* resetShouldDealWithCustomToolbars() {
- ok(gNavToolbox.toolbarset, "There should be a toolbarset");
- let toolbarID = "testAustralisCustomToolbar";
- gNavToolbox.appendCustomToolbar(toolbarID, "");
- let toolbarDOMID = getToolboxCustomToolbarId(toolbarID);
- let toolbarElement = document.getElementById(toolbarDOMID);
- ok(toolbarElement, "There should be a toolbar");
- if (!toolbarElement) {
- ok(false, "No toolbar created, bailing out of the test.");
- return;
- }
- is(toolbarElement.nextSibling, gNavToolbox.toolbarset,
- "Toolbar should have been inserted in toolbox, before toolbarset element");
- let cuiAreaType = CustomizableUI.getAreaType(toolbarDOMID);
- is(cuiAreaType, CustomizableUI.TYPE_TOOLBAR,
- "CustomizableUI should know the area and think it's a toolbar");
- if (cuiAreaType != CustomizableUI.TYPE_TOOLBAR) {
- ok(false, "Toolbar not registered successfully, bailing out of the test.");
- toolbarElement.remove();
- return;
- }
- ok(!CustomizableUI.getWidgetIdsInArea(toolbarDOMID).length, "There should be no widgets in the area yet.");
- CustomizableUI.addWidgetToArea(kXULWidgetId, toolbarDOMID, 0);
- ok(toolbarElement.hasChildNodes(), "Toolbar should now have a button.");
- assertAreaPlacements(toolbarDOMID, [kXULWidgetId]);
-
- gNavToolbox.toolbarset.setAttribute("toolbar2", `${toolbarID}:${kXULWidgetId}`);
- document.persist(gNavToolbox.toolbarset.id, "toolbar2");
-
- let newWindow = yield openAndLoadWindow({}, true);
- is(newWindow.gNavToolbox.toolbarset.getAttribute("toolbar2"),
- gNavToolbox.toolbarset.getAttribute("toolbar2"),
- "Attribute should be the same in new window");
- yield promiseWindowClosed(newWindow);
-
- CustomizableUI.reset();
-
- newWindow = yield openAndLoadWindow({}, true);
- ok(!newWindow.gNavToolbox.toolbarset.hasAttribute("toolbar2"),
- "Attribute should be gone in new window");
- yield promiseWindowClosed(newWindow);
-
- ok(CustomizableUI.inDefaultState, "Should be in default state after reset.");
- let xulButton = document.getElementById(kXULWidgetId);
- ok(!xulButton, "XUL button shouldn't be in the document anymore.");
- ok(gNavToolbox.palette.querySelector(`#${kXULWidgetId}`), "XUL button should be in the palette");
- ok(!toolbarElement.hasChildNodes(), "Toolbar should have no more child nodes.");
- ok(!toolbarElement.parentNode, "Toolbar should no longer be in the DOM.");
- cuiAreaType = CustomizableUI.getAreaType(toolbarDOMID);
- is(cuiAreaType, null, "CustomizableUI should have forgotten all about the area");
-});
-
-
-add_task(function*() {
- let newWin = yield openAndLoadWindow({}, true);
- ok(!newWin.gNavToolbox.toolbarset.hasAttribute("toolbar1"), "New window shouldn't have attribute toolbar1");
- ok(!newWin.gNavToolbox.toolbarset.hasAttribute("toolbar2"), "New window shouldn't have attribute toolbar2");
- yield promiseWindowClosed(newWin);
-});
diff --git a/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js b/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js
deleted file mode 100644
index 3bfa8c25d..000000000
--- a/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbarName = "test-insertNodeInWindow-placements-toolbar";
-const kTestWidgetPrefix = "test-widget-for-insertNodeInWindow-placements-";
-
-
-/*
-Tries to replicate the situation of having a placement list like this:
-
-exists-1,trying-to-insert-this,doesn't-exist,exists-2
-*/
-add_task(function*() {
- let testWidgetExists = [true, false, false, true];
- let widgetIds = [];
- for (let i = 0; i < testWidgetExists.length; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- if (testWidgetExists[i]) {
- let spec = {id: id, type: "button", removable: true, label: "test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- }
- }
-
- let toolbarNode = createToolbarWithPlacements(kToolbarName, widgetIds);
- assertAreaPlacements(kToolbarName, widgetIds);
-
- let btnId = kTestWidgetPrefix + 1;
- let btn = createDummyXULButton(btnId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
-
- is(btn.parentNode.id, kToolbarName, "New XUL widget should be placed inside new toolbar");
-
- is(btn.previousSibling.id, toolbarNode.firstChild.id,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- btn.remove();
- removeCustomToolbars();
- yield resetCustomization();
-});
-
-
-/*
-Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
-situation similar to:
-
-exists-1,exists-2,overflow-1,trying-to-insert-this,overflow-2
-*/
-add_task(function*() {
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
- let widgetIds = [];
- for (let i = 0; i < 5; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- let spec = {id: id, type: "button", removable: true, label: "insertNodeInWindow test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- CustomizableUI.addWidgetToArea(id, "nav-bar");
- }
-
- for (let id of widgetIds) {
- document.getElementById(id).style.minWidth = "200px";
- }
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
-
- let testWidgetId = kTestWidgetPrefix + 3;
-
- CustomizableUI.destroyWidget(testWidgetId);
-
- let btn = createDummyXULButton(testWidgetId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
-
- is(btn.parentNode.id, navbar.overflowable._list.id, "New XUL widget should be placed inside overflow of toolbar");
- is(btn.previousSibling.id, kTestWidgetPrefix + 2,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
- is(btn.nextSibling.id, kTestWidgetPrefix + 4,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
-
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
- btn.remove();
- yield resetCustomization();
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
-});
-
-
-/*
-Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
-placements situation similar to:
-
-exists-1,exists-2,overflow-1,doesn't-exist,trying-to-insert-this,overflow-2
-*/
-add_task(function*() {
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
- let widgetIds = [];
- for (let i = 0; i < 5; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- let spec = {id: id, type: "button", removable: true, label: "insertNodeInWindow test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- CustomizableUI.addWidgetToArea(id, "nav-bar");
- }
-
- for (let id of widgetIds) {
- document.getElementById(id).style.minWidth = "200px";
- }
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
-
- let testWidgetId = kTestWidgetPrefix + 3;
-
- CustomizableUI.destroyWidget(kTestWidgetPrefix + 2);
- CustomizableUI.destroyWidget(testWidgetId);
-
- let btn = createDummyXULButton(testWidgetId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
-
- is(btn.parentNode.id, navbar.overflowable._list.id, "New XUL widget should be placed inside overflow of toolbar");
- is(btn.previousSibling.id, kTestWidgetPrefix + 1,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
- is(btn.nextSibling.id, kTestWidgetPrefix + 4,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
-
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
- btn.remove();
- yield resetCustomization();
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
-});
-
-
-/*
-Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
-placements situation similar to:
-
-exists-1,exists-2,overflow-1,doesn't-exist,trying-to-insert-this,doesn't-exist
-*/
-add_task(function*() {
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
- let widgetIds = [];
- for (let i = 0; i < 5; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- let spec = {id: id, type: "button", removable: true, label: "insertNodeInWindow test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- CustomizableUI.addWidgetToArea(id, "nav-bar");
- }
-
- for (let id of widgetIds) {
- document.getElementById(id).style.minWidth = "200px";
- }
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
-
- let testWidgetId = kTestWidgetPrefix + 3;
-
- CustomizableUI.destroyWidget(kTestWidgetPrefix + 2);
- CustomizableUI.destroyWidget(testWidgetId);
- CustomizableUI.destroyWidget(kTestWidgetPrefix + 4);
-
- let btn = createDummyXULButton(testWidgetId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
-
- is(btn.parentNode.id, navbar.overflowable._list.id, "New XUL widget should be placed inside overflow of toolbar");
- is(btn.previousSibling.id, kTestWidgetPrefix + 1,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
- is(btn.nextSibling, null,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
-
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
- btn.remove();
- yield resetCustomization();
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
-});
-
-
-/*
-Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
-placements situation similar to:
-
-exists-1,exists-2,overflow-1,can't-overflow,trying-to-insert-this,overflow-2
-*/
-add_task(function*() {
- let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-
- let widgetIds = [];
- for (let i = 5; i >= 0; i--) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- let spec = {id: id, type: "button", removable: true, label: "insertNodeInWindow test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- CustomizableUI.addWidgetToArea(id, "nav-bar", 0);
- }
-
- for (let i = 10; i < 15; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- let spec = {id: id, type: "button", removable: true, label: "insertNodeInWindow test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- CustomizableUI.addWidgetToArea(id, "nav-bar");
- }
-
- for (let id of widgetIds) {
- document.getElementById(id).style.minWidth = "200px";
- }
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => navbar.hasAttribute("overflowing"));
-
- // Find last widget that doesn't allow overflowing
- let nonOverflowing = navbar.customizationTarget.lastChild;
- is(nonOverflowing.getAttribute("overflows"), "false", "Last child is expected to not allow overflowing");
- isnot(nonOverflowing.getAttribute("skipintoolbarset"), "true", "Last child is expected to not be skipintoolbarset");
-
- let testWidgetId = kTestWidgetPrefix + 10;
- CustomizableUI.destroyWidget(testWidgetId);
-
- let btn = createDummyXULButton(testWidgetId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
-
- is(btn.parentNode.id, navbar.overflowable._list.id, "New XUL widget should be placed inside overflow of toolbar");
- is(btn.nextSibling.id, kTestWidgetPrefix + 11,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
-
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
- btn.remove();
- yield resetCustomization();
- yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
-});
-
-
-/*
-Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
-placements situation similar to:
-
-exists-1,exists-2,overflow-1,trying-to-insert-this,can't-overflow,overflow-2
-*/
-add_task(function*() {
- let widgetIds = [];
- let missingId = 2;
- let nonOverflowableId = 3;
- for (let i = 0; i < 5; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- if (i != missingId) {
- // Setting min-width to make the overflow state not depend on styling of the button and/or
- // screen width
- let spec = {id: id, type: "button", removable: true, label: "test", tooltiptext: "" + i,
- onCreated: function(node) {
- node.style.minWidth = "200px";
- if (id == (kTestWidgetPrefix + nonOverflowableId)) {
- node.setAttribute("overflows", false);
- }
- }};
- info("Creating: " + id);
- CustomizableUI.createWidget(spec);
- }
- }
-
- let toolbarNode = createOverflowableToolbarWithPlacements(kToolbarName, widgetIds);
- assertAreaPlacements(kToolbarName, widgetIds);
- ok(!toolbarNode.hasAttribute("overflowing"), "Toolbar shouldn't overflow to start with.");
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
- ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- let btnId = kTestWidgetPrefix + missingId;
- let btn = createDummyXULButton(btnId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
-
- is(btn.parentNode.id, kToolbarName + "-overflow-list", "New XUL widget should be placed inside new toolbar's overflow");
- is(btn.previousSibling.id, kTestWidgetPrefix + 1,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
- is(btn.nextSibling.id, kTestWidgetPrefix + 4,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !toolbarNode.hasAttribute("overflowing"));
-
- btn.remove();
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- removeCustomToolbars();
- yield resetCustomization();
-});
-
-
-/*
-Tests nodes do *not* get placed in the toolbar's overflow. Replicates a
-plcements situation similar to:
-
-exists-1,trying-to-insert-this,exists-2,overflowed-1
-*/
-add_task(function*() {
- let widgetIds = [];
- let missingId = 1;
- for (let i = 0; i < 5; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- if (i != missingId) {
- // Setting min-width to make the overflow state not depend on styling of the button and/or
- // screen width
- let spec = {id: id, type: "button", removable: true, label: "test", tooltiptext: "" + i,
- onCreated: function(node) { node.style.minWidth = "100px"; }};
- info("Creating: " + id);
- CustomizableUI.createWidget(spec);
- }
- }
-
- let toolbarNode = createOverflowableToolbarWithPlacements(kToolbarName, widgetIds);
- assertAreaPlacements(kToolbarName, widgetIds);
- ok(!toolbarNode.hasAttribute("overflowing"), "Toolbar shouldn't overflow to start with.");
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
- ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- let btnId = kTestWidgetPrefix + missingId;
- let btn = createDummyXULButton(btnId, "test");
- CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
-
- is(btn.parentNode.id, kToolbarName + "-target", "New XUL widget should be placed inside new toolbar");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !toolbarNode.hasAttribute("overflowing"));
-
- btn.remove();
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- removeCustomToolbars();
- yield resetCustomization();
-});
-
-
-/*
-Tests inserting a node onto the end of an overflowing toolbar *doesn't* put it in
-the overflow list when the widget disallows overflowing. ie:
-
-exists-1,exists-2,overflows-1,trying-to-insert-this
-
-Where trying-to-insert-this has overflows=false
-*/
-add_task(function*() {
- let widgetIds = [];
- let missingId = 3;
- for (let i = 0; i < 5; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- if (i != missingId) {
- // Setting min-width to make the overflow state not depend on styling of the button and/or
- // screen width
- let spec = {id: id, type: "button", removable: true, label: "test", tooltiptext: "" + i,
- onCreated: function(node) { node.style.minWidth = "200px"; }};
- info("Creating: " + id);
- CustomizableUI.createWidget(spec);
- }
- }
-
- let toolbarNode = createOverflowableToolbarWithPlacements(kToolbarName, widgetIds);
- assertAreaPlacements(kToolbarName, widgetIds);
- ok(!toolbarNode.hasAttribute("overflowing"), "Toolbar shouldn't overflow to start with.");
-
- let originalWindowWidth = window.outerWidth;
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
- ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-
- let btnId = kTestWidgetPrefix + missingId;
- let btn = createDummyXULButton(btnId, "test");
- btn.setAttribute("overflows", false);
- CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
-
- is(btn.parentNode.id, kToolbarName + "-target", "New XUL widget should be placed inside new toolbar");
- is(btn.nextSibling, null,
- "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
- yield waitForCondition(() => !toolbarNode.hasAttribute("overflowing"));
-
- btn.remove();
- widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
- removeCustomToolbars();
- yield resetCustomization();
-});
-
-
-add_task(function* asyncCleanUp() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_978084_dragEnd_after_move.js b/browser/components/customizableui/test/browser_978084_dragEnd_after_move.js
deleted file mode 100644
index a653c2d51..000000000
--- a/browser/components/customizableui/test/browser_978084_dragEnd_after_move.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var draggedItem;
-
-/**
- * Check that customizing-movingItem gets removed on a drop when the item is moved.
- */
-
-// Drop on the palette
-add_task(function*() {
- draggedItem = document.createElement("toolbarbutton");
- draggedItem.id = "test-dragEnd-after-move1";
- draggedItem.setAttribute("label", "Test");
- draggedItem.setAttribute("removable", "true");
- let navbar = document.getElementById("nav-bar");
- navbar.customizationTarget.appendChild(draggedItem);
- yield startCustomizing();
- simulateItemDrag(draggedItem, gCustomizeMode.visiblePalette);
- is(document.documentElement.hasAttribute("customizing-movingItem"), false,
- "Make sure customizing-movingItem is removed after dragging to the palette");
- yield endCustomizing();
-});
-
-// Drop on a customization target itself
-add_task(function*() {
- draggedItem = document.createElement("toolbarbutton");
- draggedItem.id = "test-dragEnd-after-move2";
- draggedItem.setAttribute("label", "Test");
- draggedItem.setAttribute("removable", "true");
- let dest = createToolbarWithPlacements("test-dragEnd");
- let navbar = document.getElementById("nav-bar");
- navbar.customizationTarget.appendChild(draggedItem);
- yield startCustomizing();
- simulateItemDrag(draggedItem, dest.customizationTarget);
- is(document.documentElement.hasAttribute("customizing-movingItem"), false,
- "Make sure customizing-movingItem is removed");
- yield endCustomizing();
-});
-
-add_task(function* asyncCleanup() {
- yield endCustomizing();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js b/browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js
deleted file mode 100644
index 15197ac86..000000000
--- a/browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kToolbarName = "test-new-overflowable-toolbar";
-const kTestWidgetPrefix = "test-widget-for-overflowable-toolbar-";
-
-add_task(function* addOverflowingToolbar() {
- let originalWindowWidth = window.outerWidth;
-
- let widgetIds = [];
- for (let i = 0; i < 10; i++) {
- let id = kTestWidgetPrefix + i;
- widgetIds.push(id);
- let spec = {id: id, type: "button", removable: true, label: "test", tooltiptext: "" + i};
- CustomizableUI.createWidget(spec);
- }
-
- let toolbarNode = createOverflowableToolbarWithPlacements(kToolbarName, widgetIds);
- assertAreaPlacements(kToolbarName, widgetIds);
-
- for (let id of widgetIds) {
- document.getElementById(id).style.minWidth = "200px";
- }
-
- isnot(toolbarNode.overflowable, null, "Toolbar should have overflowable controller");
- isnot(toolbarNode.customizationTarget, null, "Toolbar should have customization target");
- isnot(toolbarNode.customizationTarget, toolbarNode, "Customization target should not be toolbar node");
-
- let oldChildCount = toolbarNode.customizationTarget.childElementCount;
- let overflowableList = document.getElementById(kToolbarName + "-overflow-list");
- let oldOverflowCount = overflowableList.childElementCount;
-
- isnot(oldChildCount, 0, "Toolbar should have non-overflowing widgets");
-
- window.resizeTo(400, window.outerHeight);
- yield waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
- ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
- ok(toolbarNode.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
- ok(overflowableList.childElementCount > oldOverflowCount, "Should have more overflowed widgets.");
-
- window.resizeTo(originalWindowWidth, window.outerHeight);
-});
-
-
-add_task(function* asyncCleanup() {
- removeCustomToolbars();
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_981305_separator_insertion.js b/browser/components/customizableui/test/browser_981305_separator_insertion.js
deleted file mode 100644
index 8d4d86c2a..000000000
--- a/browser/components/customizableui/test/browser_981305_separator_insertion.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var tempElements = [];
-
-function insertTempItemsIntoMenu(parentMenu) {
- // Last element is null to insert at the end:
- let beforeEls = [parentMenu.firstChild, parentMenu.lastChild, null];
- for (let i = 0; i < beforeEls.length; i++) {
- let sep = document.createElement("menuseparator");
- tempElements.push(sep);
- parentMenu.insertBefore(sep, beforeEls[i]);
- let menu = document.createElement("menu");
- tempElements.push(menu);
- parentMenu.insertBefore(menu, beforeEls[i]);
- // And another separator for good measure:
- sep = document.createElement("menuseparator");
- tempElements.push(sep);
- parentMenu.insertBefore(sep, beforeEls[i]);
- }
-}
-
-function checkSeparatorInsertion(menuId, buttonId, subviewId) {
- return function*() {
- info("Checking for duplicate separators in " + buttonId + " widget");
- let menu = document.getElementById(menuId);
- insertTempItemsIntoMenu(menu);
-
- let placement = CustomizableUI.getPlacementOfWidget(buttonId);
- let changedPlacement = false;
- if (!placement || placement.area != CustomizableUI.AREA_PANEL) {
- CustomizableUI.addWidgetToArea(buttonId, CustomizableUI.AREA_PANEL);
- changedPlacement = true;
- }
- yield PanelUI.show();
-
- let button = document.getElementById(buttonId);
- button.click();
-
- yield waitForCondition(() => !PanelUI.multiView.hasAttribute("transitioning"));
- let subview = document.getElementById(subviewId);
- ok(subview.firstChild, "Subview should have a kid");
- is(subview.firstChild.localName, "toolbarbutton", "There should be no separators to start with");
-
- for (let kid of subview.children) {
- if (kid.localName == "menuseparator") {
- ok(kid.previousSibling && kid.previousSibling.localName != "menuseparator",
- "Separators should never have another separator next to them, and should never be the first node.");
- }
- }
-
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
-
- if (changedPlacement) {
- CustomizableUI.reset();
- }
- };
-}
-
-add_task(checkSeparatorInsertion("menuWebDeveloperPopup", "developer-button", "PanelUI-developerItems"));
-add_task(checkSeparatorInsertion("viewSidebarMenu", "sidebar-button", "PanelUI-sidebarItems"));
-
-registerCleanupFunction(function() {
- for (let el of tempElements) {
- el.remove();
- }
- tempElements = null;
-});
diff --git a/browser/components/customizableui/test/browser_981418-widget-onbeforecreated-handler.js b/browser/components/customizableui/test/browser_981418-widget-onbeforecreated-handler.js
deleted file mode 100644
index 9a7227a47..000000000
--- a/browser/components/customizableui/test/browser_981418-widget-onbeforecreated-handler.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-const kWidgetId = 'test-981418-widget-onbeforecreated';
-
-// Should be able to add broken view widget
-add_task(function* testAddOnBeforeCreatedWidget() {
- let viewShownDeferred = Promise.defer();
- let onBeforeCreatedCalled = false;
- let widgetSpec = {
- id: kWidgetId,
- type: 'view',
- viewId: kWidgetId + 'idontexistyet',
- onBeforeCreated: function(doc) {
- let view = doc.createElement("panelview");
- view.id = kWidgetId + 'idontexistyet';
- let label = doc.createElement("label");
- label.setAttribute("value", "Hello world");
- label.className = 'panel-subview-header';
- view.appendChild(label);
- document.getElementById("PanelUI-multiView").appendChild(view);
- onBeforeCreatedCalled = true;
- },
- onViewShowing: function() {
- viewShownDeferred.resolve();
- }
- };
-
- let noError = true;
- try {
- CustomizableUI.createWidget(widgetSpec);
- CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_NAVBAR);
- } catch (ex) {
- Cu.reportError(ex);
- noError = false;
- }
- ok(noError, "Should not throw an exception trying to add the widget.");
- ok(onBeforeCreatedCalled, "onBeforeCreated should have been called");
-
- let widgetNode = document.getElementById(kWidgetId);
- ok(widgetNode, "Widget should exist");
- if (widgetNode) {
- try {
- widgetNode.click();
-
- let tempPanel = document.getElementById("customizationui-widget-panel");
- let panelShownPromise = promisePanelElementShown(window, tempPanel);
-
- let shownTimeout = setTimeout(() => viewShownDeferred.reject("Panel not shown within 20s"), 20000);
- yield viewShownDeferred.promise;
- yield panelShownPromise;
- clearTimeout(shownTimeout);
- ok(true, "Found view shown");
-
- let panelHiddenPromise = promisePanelElementHidden(window, tempPanel);
- tempPanel.hidePopup();
- yield panelHiddenPromise;
-
- CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_PANEL);
- yield PanelUI.show();
-
- viewShownDeferred = Promise.defer();
- widgetNode.click();
-
- shownTimeout = setTimeout(() => viewShownDeferred.reject("Panel not shown within 20s"), 20000);
- yield viewShownDeferred.promise;
- clearTimeout(shownTimeout);
- ok(true, "Found view shown");
-
- let panelHidden = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidden;
- } catch (ex) {
- ok(false, "Unexpected exception (like a timeout for one of the yields) " +
- "when testing view widget.");
- }
- }
-
- noError = true;
- try {
- CustomizableUI.destroyWidget(kWidgetId);
- } catch (ex) {
- Cu.reportError(ex);
- noError = false;
- }
- ok(noError, "Should not throw an exception trying to remove the broken view widget.");
-});
-
-add_task(function* asyncCleanup() {
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_982656_restore_defaults_builtin_widgets.js b/browser/components/customizableui/test/browser_982656_restore_defaults_builtin_widgets.js
deleted file mode 100644
index e7f8d0cf4..000000000
--- a/browser/components/customizableui/test/browser_982656_restore_defaults_builtin_widgets.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Restoring default should not place addon widgets back in the toolbar
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Default state to begin");
-
- const kWidgetId = "bug982656-add-on-widget-should-not-restore-to-default-area";
- let widgetSpec = {
- id: kWidgetId,
- defaultArea: CustomizableUI.AREA_NAVBAR
- };
- CustomizableUI.createWidget(widgetSpec);
-
- ok(!CustomizableUI.inDefaultState, "Not in default state after widget added");
- is(CustomizableUI.getPlacementOfWidget(kWidgetId).area, CustomizableUI.AREA_NAVBAR, "Widget should be in navbar");
-
- yield resetCustomization();
-
- ok(CustomizableUI.inDefaultState, "Back in default state after reset");
- is(CustomizableUI.getPlacementOfWidget(kWidgetId), null, "Widget now in palette");
- CustomizableUI.destroyWidget(kWidgetId);
-});
-
-
-// resetCustomization shouldn't move 3rd party widgets out of custom toolbars
-add_task(function*() {
- const kToolbarId = "bug982656-toolbar-with-defaultset";
- const kWidgetId = "bug982656-add-on-widget-should-restore-to-default-area-when-area-is-not-builtin";
- ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
- let toolbar = createToolbarWithPlacements(kToolbarId);
- ok(CustomizableUI.areas.indexOf(kToolbarId) != -1,
- "Toolbar has been registered.");
- is(CustomizableUI.getAreaType(kToolbarId), CustomizableUI.TYPE_TOOLBAR,
- "Area should be registered as toolbar");
-
- let widgetSpec = {
- id: kWidgetId,
- defaultArea: kToolbarId
- };
- CustomizableUI.createWidget(widgetSpec);
-
- ok(!CustomizableUI.inDefaultState, "No longer in default state after toolbar is registered and visible.");
- is(CustomizableUI.getPlacementOfWidget(kWidgetId).area, kToolbarId, "Widget should be in custom toolbar");
-
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "Back in default state after reset");
- is(CustomizableUI.getPlacementOfWidget(kWidgetId).area, kToolbarId, "Widget still in custom toolbar");
- ok(toolbar.collapsed, "Custom toolbar should be collapsed after reset");
-
- toolbar.remove();
- CustomizableUI.destroyWidget(kWidgetId);
- CustomizableUI.unregisterArea(kToolbarId);
-});
diff --git a/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js b/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
deleted file mode 100644
index 42b346c10..000000000
--- a/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
+++ /dev/null
@@ -1,267 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-var gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget"));
-
-const kBookmarksButton = "bookmarks-menu-button";
-const kBookmarksItems = "personal-bookmarks";
-const kOriginalWindowWidth = window.outerWidth;
-const kSmallWidth = 400;
-
-/**
- * Helper function that opens the bookmarks menu, and returns a Promise that
- * resolves as soon as the menu is ready for interaction.
- */
-function bookmarksMenuPanelShown() {
- let deferred = Promise.defer();
- let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
- let onTransitionEnd = (e) => {
- if (e.target == bookmarksMenuPopup) {
- bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd);
- deferred.resolve();
- }
- }
- bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd);
- return deferred.promise;
-}
-
-/**
- * Checks that the placesContext menu is correctly attached to the
- * controller of some view. Returns a Promise that resolves as soon
- * as the context menu is closed.
- *
- * @param aItemWithContextMenu the item that we need to synthesize hte
- * right click on in order to open the context menu.
- */
-function checkPlacesContextMenu(aItemWithContextMenu) {
- return Task.spawn(function* () {
- let contextMenu = document.getElementById("placesContext");
- let newBookmarkItem = document.getElementById("placesContext_new:bookmark");
- info("Waiting for context menu on " + aItemWithContextMenu.id);
- let shownPromise = popupShown(contextMenu);
- EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu,
- {type: "contextmenu", button: 2});
- yield shownPromise;
-
- ok(!newBookmarkItem.hasAttribute("disabled"),
- "New bookmark item shouldn't be disabled");
-
- info("Closing context menu");
- yield closePopup(contextMenu);
- });
-}
-
-/**
- * Opens the bookmarks menu panel, and then opens each of the "special"
- * submenus in that list. Then it checks that those submenu's context menus
- * are properly hooked up to a controller.
- */
-function checkSpecialContextMenus() {
- return Task.spawn(function* () {
- let bookmarksMenuButton = document.getElementById(kBookmarksButton);
- let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
-
- const kSpecialItemIDs = {
- "BMB_bookmarksToolbar": "BMB_bookmarksToolbarPopup",
- "BMB_unsortedBookmarks": "BMB_unsortedBookmarksPopup",
- };
-
- // Open the bookmarks menu button context menus and ensure that
- // they have the proper views attached.
- let shownPromise = bookmarksMenuPanelShown();
- let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton,
- "anonid", "dropmarker");
- EventUtils.synthesizeMouseAtCenter(dropmarker, {});
- info("Waiting for bookmarks menu popup to show after clicking dropmarker.")
- yield shownPromise;
-
- for (let menuID in kSpecialItemIDs) {
- let menuItem = document.getElementById(menuID);
- let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
- info("Waiting to open menu for " + menuID);
- let shownPromise = popupShown(menuPopup);
- menuPopup.openPopup(menuItem, null, 0, 0, false, false, null);
- yield shownPromise;
-
- yield checkPlacesContextMenu(menuPopup);
- info("Closing menu for " + menuID);
- yield closePopup(menuPopup);
- }
-
- info("Closing bookmarks menu");
- yield closePopup(bookmarksMenuPopup);
- });
-}
-
-/**
- * Closes a focused popup by simulating pressing the Escape key,
- * and returns a Promise that resolves as soon as the popup is closed.
- *
- * @param aPopup the popup node to close.
- */
-function closePopup(aPopup) {
- let hiddenPromise = popupHidden(aPopup);
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- return hiddenPromise;
-}
-
-/**
- * Helper function that checks that the context menu of the
- * bookmark toolbar items chevron popup is correctly hooked up
- * to the controller of a view.
- */
-function checkBookmarksItemsChevronContextMenu() {
- return Task.spawn(function*() {
- let chevronPopup = document.getElementById("PlacesChevronPopup");
- let shownPromise = popupShown(chevronPopup);
- let chevron = document.getElementById("PlacesChevron");
- EventUtils.synthesizeMouseAtCenter(chevron, {});
- info("Waiting for bookmark toolbar item chevron popup to show");
- yield shownPromise;
- yield waitForCondition(() => {
- for (let child of chevronPopup.children) {
- if (child.style.visibility != "hidden")
- return true;
- }
- return false;
- });
- yield checkPlacesContextMenu(chevronPopup);
- info("Waiting for bookmark toolbar item chevron popup to close");
- yield closePopup(chevronPopup);
- });
-}
-
-/**
- * Forces the window to a width that causes the nav-bar to overflow
- * its contents. Returns a Promise that resolves as soon as the
- * overflowable nav-bar is showing its chevron.
- */
-function overflowEverything() {
- info("Waiting for overflow");
- window.resizeTo(kSmallWidth, window.outerHeight);
- return waitForCondition(() => gNavBar.hasAttribute("overflowing"));
-}
-
-/**
- * Returns the window to its original size from the start of the test,
- * and returns a Promise that resolves when the nav-bar is no longer
- * overflowing.
- */
-function stopOverflowing() {
- info("Waiting until we stop overflowing");
- window.resizeTo(kOriginalWindowWidth, window.outerHeight);
- return waitForCondition(() => !gNavBar.hasAttribute("overflowing"));
-}
-
-/**
- * Checks that an item with ID aID is overflowing in the nav-bar.
- *
- * @param aID the ID of the node to check for overflowingness.
- */
-function checkOverflowing(aID) {
- ok(!gNavBar.querySelector("#" + aID),
- "Item with ID " + aID + " should no longer be in the gNavBar");
- let item = gOverflowList.querySelector("#" + aID);
- ok(item, "Item with ID " + aID + " should be overflowing");
- is(item.getAttribute("overflowedItem"), "true",
- "Item with ID " + aID + " should have overflowedItem attribute");
-}
-
-/**
- * Checks that an item with ID aID is not overflowing in the nav-bar.
- *
- * @param aID the ID of hte node to check for non-overflowingness.
- */
-function checkNotOverflowing(aID) {
- ok(!gOverflowList.querySelector("#" + aID),
- "Item with ID " + aID + " should no longer be overflowing");
- let item = gNavBar.querySelector("#" + aID);
- ok(item, "Item with ID " + aID + " should be in the nav bar");
- ok(!item.hasAttribute("overflowedItem"),
- "Item with ID " + aID + " should not have overflowedItem attribute");
-}
-
-/**
- * Test that overflowing the bookmarks menu button doesn't break the
- * context menus for the Unsorted and Bookmarks Toolbar menu items.
- */
-add_task(function* testOverflowingBookmarksButtonContextMenu() {
- ok(!gNavBar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
-
- // Open the Unsorted and Bookmarks Toolbar context menus and ensure
- // that they have views attached.
- yield checkSpecialContextMenus();
-
- yield overflowEverything();
- checkOverflowing(kBookmarksButton);
-
- yield stopOverflowing();
- checkNotOverflowing(kBookmarksButton);
-
- yield checkSpecialContextMenus();
-});
-
-/**
- * Test that the bookmarks toolbar items context menu still works if moved
- * to the menu from the overflow panel, and then back to the toolbar.
- */
-add_task(function* testOverflowingBookmarksItemsContextMenu() {
- info("Ensuring panel is ready.");
- yield PanelUI.ensureReady();
-
- let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
- gCustomizeMode.addToToolbar(bookmarksToolbarItems);
- yield checkPlacesContextMenu(bookmarksToolbarItems);
-
- yield overflowEverything();
- checkOverflowing(kBookmarksItems)
-
- gCustomizeMode.addToPanel(bookmarksToolbarItems);
-
- yield stopOverflowing();
-
- gCustomizeMode.addToToolbar(bookmarksToolbarItems);
- yield checkPlacesContextMenu(bookmarksToolbarItems);
-});
-
-/**
- * Test that overflowing the bookmarks toolbar items doesn't cause the
- * context menu in the bookmarks toolbar items chevron to stop working.
- */
-add_task(function* testOverflowingBookmarksItemsChevronContextMenu() {
- // If it's not already there, let's move the bookmarks toolbar items to
- // the nav-bar.
- let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
- gCustomizeMode.addToToolbar(bookmarksToolbarItems);
-
- // We make the PlacesToolbarItems element be super tiny in order to force
- // the bookmarks toolbar items into overflowing and making the chevron
- // show itself.
- let placesToolbarItems = document.getElementById("PlacesToolbarItems");
- let placesChevron = document.getElementById("PlacesChevron");
- placesToolbarItems.style.maxWidth = "10px";
- info("Waiting for chevron to no longer be collapsed");
- yield waitForCondition(() => !placesChevron.collapsed);
-
- yield checkBookmarksItemsChevronContextMenu();
-
- yield overflowEverything();
- checkOverflowing(kBookmarksItems);
-
- yield stopOverflowing();
- checkNotOverflowing(kBookmarksItems);
-
- yield checkBookmarksItemsChevronContextMenu();
-
- placesToolbarItems.style.removeProperty("max-width");
-});
-
-add_task(function* asyncCleanup() {
- window.resizeTo(kOriginalWindowWidth, window.outerHeight);
- yield resetCustomization();
-});
diff --git a/browser/components/customizableui/test/browser_985815_propagate_setToolbarVisibility.js b/browser/components/customizableui/test/browser_985815_propagate_setToolbarVisibility.js
deleted file mode 100644
index c341c2158..000000000
--- a/browser/components/customizableui/test/browser_985815_propagate_setToolbarVisibility.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function*() {
- ok(CustomizableUI.inDefaultState, "Should start in default state.");
- this.otherWin = yield openAndLoadWindow({private: true}, true);
- yield startCustomizing(this.otherWin);
- let resetButton = this.otherWin.document.getElementById("customization-reset-button");
- ok(resetButton.disabled, "Reset button should be disabled");
-
- if (typeof CustomizableUI.setToolbarVisibility == "function") {
- CustomizableUI.setToolbarVisibility("PersonalToolbar", true);
- } else {
- setToolbarVisibility(document.getElementById("PersonalToolbar"), true);
- }
-
- let otherPersonalToolbar = this.otherWin.document.getElementById("PersonalToolbar");
- let personalToolbar = document.getElementById("PersonalToolbar");
- ok(!otherPersonalToolbar.collapsed, "Toolbar should be uncollapsed in private window");
- ok(!personalToolbar.collapsed, "Toolbar should be uncollapsed in normal window");
- ok(!resetButton.disabled, "Reset button should be enabled");
-
- yield this.otherWin.gCustomizeMode.reset();
-
- ok(otherPersonalToolbar.collapsed, "Toolbar should be collapsed in private window");
- ok(personalToolbar.collapsed, "Toolbar should be collapsed in normal window");
- ok(resetButton.disabled, "Reset button should be disabled");
-
- yield endCustomizing(this.otherWin);
-
- yield promiseWindowClosed(this.otherWin);
-});
-
-
-add_task(function* asyncCleanup() {
- if (this.otherWin && !this.otherWin.closed) {
- yield promiseWindowClosed(this.otherWin);
- }
- if (!CustomizableUI.inDefaultState) {
- CustomizableUI.reset();
- }
-});
diff --git a/browser/components/customizableui/test/browser_987177_destroyWidget_xul.js b/browser/components/customizableui/test/browser_987177_destroyWidget_xul.js
deleted file mode 100644
index 6a4d0aab4..000000000
--- a/browser/components/customizableui/test/browser_987177_destroyWidget_xul.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const BUTTONID = "test-XUL-wrapper-destroyWidget";
-
-
-add_task(function() {
- let btn = createDummyXULButton(BUTTONID, "XUL btn");
- gNavToolbox.palette.appendChild(btn);
- let firstWrapper = CustomizableUI.getWidget(BUTTONID).forWindow(window);
- ok(firstWrapper, "Should get a wrapper");
- ok(firstWrapper.node, "Node should be there on first wrapper.");
-
- btn.remove();
- CustomizableUI.destroyWidget(BUTTONID);
- let secondWrapper = CustomizableUI.getWidget(BUTTONID).forWindow(window);
- isnot(firstWrapper, secondWrapper, "Wrappers should be different after destroyWidget call.");
- ok(!firstWrapper.node, "No node should be there on old wrapper.");
- ok(!secondWrapper.node, "No node should be there on new wrapper.");
-
- btn = createDummyXULButton(BUTTONID, "XUL btn");
- gNavToolbox.palette.appendChild(btn);
- let thirdWrapper = CustomizableUI.getWidget(BUTTONID).forWindow(window);
- ok(thirdWrapper, "Should get a wrapper");
- is(secondWrapper, thirdWrapper, "Should get the second wrapper again.");
- ok(firstWrapper.node, "Node should be there on old wrapper.");
- ok(secondWrapper.node, "Node should be there on second wrapper.");
- ok(thirdWrapper.node, "Node should be there on third wrapper.");
-});
-
diff --git a/browser/components/customizableui/test/browser_987177_xul_wrapper_updating.js b/browser/components/customizableui/test/browser_987177_xul_wrapper_updating.js
deleted file mode 100644
index f838e204d..000000000
--- a/browser/components/customizableui/test/browser_987177_xul_wrapper_updating.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const BUTTONID = "test-XUL-wrapper-widget";
-add_task(function() {
- let btn = createDummyXULButton(BUTTONID, "XUL btn");
- gNavToolbox.palette.appendChild(btn);
- let groupWrapper = CustomizableUI.getWidget(BUTTONID);
- ok(groupWrapper, "Should get a group wrapper");
- let singleWrapper = groupWrapper.forWindow(window);
- ok(singleWrapper, "Should get a single wrapper");
- is(singleWrapper.node, btn, "Node should be in the wrapper");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, btn, "Button should be that instance.");
-
- CustomizableUI.addWidgetToArea(BUTTONID, CustomizableUI.AREA_NAVBAR);
-
- let otherSingleWrapper = groupWrapper.forWindow(window);
- is(singleWrapper, otherSingleWrapper, "Should get the same wrapper after adding the node to the navbar.");
- is(singleWrapper.node, btn, "Node should be in the wrapper");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, btn, "Button should be that instance.");
-
- CustomizableUI.removeWidgetFromArea(BUTTONID);
-
- otherSingleWrapper = groupWrapper.forWindow(window);
- isnot(singleWrapper, otherSingleWrapper, "Shouldn't get the same wrapper after removing it from the navbar.");
- singleWrapper = otherSingleWrapper;
- is(singleWrapper.node, btn, "Node should be in the wrapper");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, btn, "Button should be that instance.");
-
- btn.remove();
- otherSingleWrapper = groupWrapper.forWindow(window);
- is(singleWrapper, otherSingleWrapper, "Should get the same wrapper after physically removing the node.");
- is(singleWrapper.node, null, "Wrapper's node should be null now that it's left the DOM.");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, null, "That instance should be null.");
-
- btn = createDummyXULButton(BUTTONID, "XUL btn");
- gNavToolbox.palette.appendChild(btn);
- otherSingleWrapper = groupWrapper.forWindow(window);
- is(singleWrapper, otherSingleWrapper, "Should get the same wrapper after readding the node.");
- is(singleWrapper.node, btn, "Node should be in the wrapper");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, btn, "Button should be that instance.");
-
- CustomizableUI.addWidgetToArea(BUTTONID, CustomizableUI.AREA_NAVBAR);
-
- otherSingleWrapper = groupWrapper.forWindow(window);
- is(singleWrapper, otherSingleWrapper, "Should get the same wrapper after adding the node to the navbar.");
- is(singleWrapper.node, btn, "Node should be in the wrapper");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, btn, "Button should be that instance.");
-
- CustomizableUI.removeWidgetFromArea(BUTTONID);
-
- otherSingleWrapper = groupWrapper.forWindow(window);
- isnot(singleWrapper, otherSingleWrapper, "Shouldn't get the same wrapper after removing it from the navbar.");
- singleWrapper = otherSingleWrapper;
- is(singleWrapper.node, btn, "Node should be in the wrapper");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, btn, "Button should be that instance.");
-
- btn.remove();
- otherSingleWrapper = groupWrapper.forWindow(window);
- is(singleWrapper, otherSingleWrapper, "Should get the same wrapper after physically removing the node.");
- is(singleWrapper.node, null, "Wrapper's node should be null now that it's left the DOM.");
- is(groupWrapper.instances.length, 1, "There should be 1 instance on the group wrapper");
- is(groupWrapper.instances[0].node, null, "That instance should be null.");
-});
diff --git a/browser/components/customizableui/test/browser_987185_syncButton.js b/browser/components/customizableui/test/browser_987185_syncButton.js
deleted file mode 100755
index 988d738be..000000000
--- a/browser/components/customizableui/test/browser_987185_syncButton.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-"use strict";
-
-var syncService = {};
-Components.utils.import("resource://services-sync/service.js", syncService);
-
-var needsSetup;
-var originalSync;
-var service = syncService.Service;
-var syncWasCalled = false;
-
-add_task(function* testSyncButtonFunctionality() {
- info("Check Sync button functionality");
- storeInitialValues();
- mockFunctions();
-
- // add the Sync button to the panel
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
-
- // check the button's functionality
- yield PanelUI.show();
- info("The panel menu was opened");
-
- let syncButton = document.getElementById("sync-button");
- ok(syncButton, "The Sync button was added to the Panel Menu");
- // click the button - the panel should open.
- syncButton.click();
- let syncPanel = document.getElementById("PanelUI-remotetabs");
- ok(syncPanel.getAttribute("current"), "Sync Panel is in view");
-
- // Find and click the "setup" button.
- let syncNowButton = document.getElementById("PanelUI-remotetabs-syncnow");
- syncNowButton.click();
-
- info("The sync button was clicked");
-
- yield waitForCondition(() => syncWasCalled);
-});
-
-add_task(function* asyncCleanup() {
- // reset the panel UI to the default state
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "The panel UI is in default state again.");
-
- if (isPanelUIOpen()) {
- let panelHidePromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHidePromise;
- }
-
- restoreValues();
-});
-
-function mockFunctions() {
- // mock needsSetup
- gSyncUI._needsSetup = () => Promise.resolve(false);
-
- // mock service.errorHandler.syncAndReportErrors()
- service.errorHandler.syncAndReportErrors = mocked_syncAndReportErrors;
-}
-
-function mocked_syncAndReportErrors() {
- syncWasCalled = true;
-}
-
-function restoreValues() {
- gSyncUI._needsSetup = needsSetup;
- service.sync = originalSync;
-}
-
-function storeInitialValues() {
- needsSetup = gSyncUI._needsSetup;
- originalSync = service.sync;
-}
diff --git a/browser/components/customizableui/test/browser_987492_window_api.js b/browser/components/customizableui/test/browser_987492_window_api.js
deleted file mode 100644
index 1718303e1..000000000
--- a/browser/components/customizableui/test/browser_987492_window_api.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-
-add_task(function* testOneWindow() {
- let windows = [];
- for (let win of CustomizableUI.windows)
- windows.push(win);
- is(windows.length, 1, "Should have one customizable window");
-});
-
-
-add_task(function* testOpenCloseWindow() {
- let newWindow = null;
- let openListener = {
- onWindowOpened: function(window) {
- newWindow = window;
- }
- }
- CustomizableUI.addListener(openListener);
- let win = yield openAndLoadWindow(null, true);
- isnot(newWindow, null, "Should have gotten onWindowOpen event");
- is(newWindow, win, "onWindowOpen event should have received expected window");
- CustomizableUI.removeListener(openListener);
-
- let windows = [];
- for (let win of CustomizableUI.windows)
- windows.push(win);
- is(windows.length, 2, "Should have two customizable windows");
- isnot(windows.indexOf(window), -1, "Current window should be in window collection.");
- isnot(windows.indexOf(newWindow), -1, "New window should be in window collection.");
-
- let closedWindow = null;
- let closeListener = {
- onWindowClosed: function(window) {
- closedWindow = window;
- }
- }
- CustomizableUI.addListener(closeListener);
- yield promiseWindowClosed(newWindow);
- isnot(closedWindow, null, "Should have gotten onWindowClosed event")
- is(newWindow, closedWindow, "Closed window should match previously opened window");
- CustomizableUI.removeListener(closeListener);
-
- windows = [];
- for (let win of CustomizableUI.windows)
- windows.push(win);
- is(windows.length, 1, "Should have one customizable window");
- isnot(windows.indexOf(window), -1, "Current window should be in window collection.");
- is(windows.indexOf(closedWindow), -1, "Closed window should not be in window collection.");
-});
diff --git a/browser/components/customizableui/test/browser_987640_charEncoding.js b/browser/components/customizableui/test/browser_987640_charEncoding.js
deleted file mode 100644
index dfe02f940..000000000
--- a/browser/components/customizableui/test/browser_987640_charEncoding.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test_967000_charEncoding_page.html";
-
-add_task(function*() {
- info("Check Character Encoding panel functionality");
-
- // add the Character Encoding button to the panel
- CustomizableUI.addWidgetToArea("characterencoding-button",
- CustomizableUI.AREA_PANEL);
-
- let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE, true, true);
-
- yield PanelUI.show();
- let charEncodingButton = document.getElementById("characterencoding-button");
- let characterEncodingView = document.getElementById("PanelUI-characterEncodingView");
- let subviewShownPromise = subviewShown(characterEncodingView);
- charEncodingButton.click();
- yield subviewShownPromise;
-
- let checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
- let initialEncoding = checkedButtons[0];
- is(initialEncoding.getAttribute("label"), "Unicode", "The unicode encoding is initially selected");
-
- // change the encoding
- let encodings = characterEncodingView.querySelectorAll("toolbarbutton");
- let newEncoding = encodings[0].hasAttribute("checked") ? encodings[1] : encodings[0];
- let tabLoadPromise = promiseTabLoadEvent(gBrowser.selectedTab, TEST_PAGE);
- newEncoding.click();
- yield tabLoadPromise;
-
- // check that the new encodng is applied
- yield PanelUI.show();
- charEncodingButton.click();
- checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
- let selectedEncodingName = checkedButtons[0].getAttribute("label");
- ok(selectedEncodingName != "Unicode", "The encoding was changed to " + selectedEncodingName);
-
- // reset the initial encoding
- yield PanelUI.show();
- charEncodingButton.click();
- tabLoadPromise = promiseTabLoadEvent(gBrowser.selectedTab, TEST_PAGE);
- initialEncoding.click();
- yield tabLoadPromise;
- yield PanelUI.show();
- charEncodingButton.click();
- checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
- is(checkedButtons[0].getAttribute("label"), "Unicode", "The encoding was reset to Unicode");
- yield BrowserTestUtils.removeTab(newTab);
-});
-
-add_task(function* asyncCleanup() {
- // reset the panel to the default state
- yield resetCustomization();
- ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
-});
diff --git a/browser/components/customizableui/test/browser_988072_sidebar_events.js b/browser/components/customizableui/test/browser_988072_sidebar_events.js
deleted file mode 100644
index 6791be67a..000000000
--- a/browser/components/customizableui/test/browser_988072_sidebar_events.js
+++ /dev/null
@@ -1,392 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var gSidebarMenu = document.getElementById("viewSidebarMenu");
-var gTestSidebarItem = null;
-
-var EVENTS = {
- click: 0, command: 0,
- onclick: 0, oncommand: 0
-};
-
-window.sawEvent = function(event, isattr) {
- let type = (isattr ? "on" : "") + event.type
- EVENTS[type]++;
-};
-
-registerCleanupFunction(() => {
- delete window.sawEvent;
-
- // Ensure sidebar is hidden after each test:
- if (!document.getElementById("sidebar-box").hidden) {
- SidebarUI.hide();
- }
-});
-
-function checkExpectedEvents(expected) {
- for (let type of Object.keys(EVENTS)) {
- let count = (type in expected ? expected[type] : 0);
- is(EVENTS[type], count, "Should have seen the right number of " + type + " events");
- EVENTS[type] = 0;
- }
-}
-
-function createSidebarItem() {
- gTestSidebarItem = document.createElement("menuitem");
- gTestSidebarItem.id = "testsidebar";
- gTestSidebarItem.setAttribute("label", "Test Sidebar");
- gSidebarMenu.insertBefore(gTestSidebarItem, gSidebarMenu.firstChild);
-}
-
-function addWidget() {
- CustomizableUI.addWidgetToArea("sidebar-button", "nav-bar");
- PanelUI.disableSingleSubviewPanelAnimations();
-}
-
-function removeWidget() {
- CustomizableUI.removeWidgetFromArea("sidebar-button");
- PanelUI.enableSingleSubviewPanelAnimations();
-}
-
-// Filters out the trailing menuseparators from the sidebar list
-function getSidebarList() {
- let sidebars = [...gSidebarMenu.children].filter(sidebar => {
- if (sidebar.localName == "menuseparator")
- return false;
- if (sidebar.getAttribute("hidden") == "true")
- return false;
- return true;
- });
- return sidebars;
-}
-
-function compareElements(original, displayed) {
- let attrs = ["label", "key", "disabled", "hidden", "origin", "image", "checked"];
- for (let attr of attrs) {
- is(displayed.getAttribute(attr), original.getAttribute(attr), "Should have the same " + attr + " attribute");
- }
-}
-
-function compareList(original, displayed) {
- is(displayed.length, original.length, "Should have the same number of children");
-
- for (let i = 0; i < Math.min(original.length, displayed.length); i++) {
- compareElements(displayed[i], original[i]);
- }
-}
-
-var showSidebarPopup = Task.async(function*() {
- let button = document.getElementById("sidebar-button");
- let subview = document.getElementById("PanelUI-sidebar");
-
- let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
-
- let subviewShownPromise = subviewShown(subview);
- EventUtils.synthesizeMouseAtCenter(button, {});
- return Promise.all([subviewShownPromise, popupShownPromise]);
-});
-
-// Check the sidebar widget shows the default items
-add_task(function*() {
- addWidget();
-
- yield showSidebarPopup();
-
- let sidebars = getSidebarList();
- let displayed = [...document.getElementById("PanelUI-sidebarItems").children];
- compareList(sidebars, displayed);
-
- let subview = document.getElementById("PanelUI-sidebar");
- let subviewHiddenPromise = subviewHidden(subview);
- document.getElementById("customizationui-widget-panel").hidePopup();
- yield subviewHiddenPromise;
-
- removeWidget();
-});
-
-function add_sidebar_task(description, setup, teardown) {
- add_task(function*() {
- info(description);
- createSidebarItem();
- addWidget();
- yield setup();
-
- CustomizableUI.addWidgetToArea("sidebar-button", "nav-bar");
-
- yield showSidebarPopup();
-
- let sidebars = getSidebarList();
- let displayed = [...document.getElementById("PanelUI-sidebarItems").children];
- compareList(sidebars, displayed);
-
- is(displayed[0].label, "Test Sidebar", "Should have the right element at the top");
- let subview = document.getElementById("PanelUI-sidebar");
- let subviewHiddenPromise = subviewHidden(subview);
- EventUtils.synthesizeMouseAtCenter(displayed[0], {});
- yield subviewHiddenPromise;
-
- yield teardown();
- gTestSidebarItem.remove();
- removeWidget();
- });
-}
-
-add_sidebar_task(
- "Check that a sidebar that uses a command event listener works",
-function*() {
- gTestSidebarItem.addEventListener("command", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ command: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses a click event listener works",
-function*() {
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ click: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses both click and command event listeners works",
-function*() {
- gTestSidebarItem.addEventListener("command", window.sawEvent);
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ command: 1, click: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses an oncommand attribute works",
-function*() {
- gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
-}, function*() {
- checkExpectedEvents({ oncommand: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses an onclick attribute works",
-function*() {
- gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
-}, function*() {
- checkExpectedEvents({ onclick: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses both onclick and oncommand attributes works",
-function*() {
- gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
- gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
-}, function*() {
- checkExpectedEvents({ onclick: 1, oncommand: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses an onclick attribute and a command listener works",
-function*() {
- gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
- gTestSidebarItem.addEventListener("command", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ onclick: 1, command: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses an oncommand attribute and a click listener works",
-function*() {
- gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ click: 1, oncommand: 1 });
-});
-
-add_sidebar_task(
- "A sidebar with both onclick attribute and click listener sees only one event :(",
-function*() {
- gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ onclick: 1 });
-});
-
-add_sidebar_task(
- "A sidebar with both oncommand attribute and command listener sees only one event :(",
-function*() {
- gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
- gTestSidebarItem.addEventListener("command", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ oncommand: 1 });
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses a broadcaster with an oncommand attribute works",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-}, function*() {
- checkExpectedEvents({ oncommand: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses a broadcaster with an onclick attribute works",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-}, function*() {
- checkExpectedEvents({ onclick: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses a broadcaster with both onclick and oncommand attributes works",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
- broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-}, function*() {
- checkExpectedEvents({ onclick: 1, oncommand: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar with a click listener and a broadcaster with an oncommand attribute works",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ click: 1, oncommand: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar with a command listener and a broadcaster with an onclick attribute works",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
- gTestSidebarItem.addEventListener("command", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ onclick: 1, command: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar with a click listener and a broadcaster with an onclick " +
- "attribute only sees one event :(",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ onclick: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar with a command listener and a broadcaster with an oncommand " +
- "attribute only sees one event :(",
-function*() {
- let broadcaster = document.createElement("broadcaster");
- broadcaster.setAttribute("id", "testbroadcaster");
- broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
- broadcaster.setAttribute("label", "Test Sidebar");
- document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
-
- gTestSidebarItem.setAttribute("observes", "testbroadcaster");
- gTestSidebarItem.addEventListener("command", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ oncommand: 1 });
- document.getElementById("testbroadcaster").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses a command element with a command event listener works",
-function*() {
- let command = document.createElement("command");
- command.setAttribute("id", "testcommand");
- document.getElementById("mainCommandSet").appendChild(command);
- command.addEventListener("command", window.sawEvent);
-
- gTestSidebarItem.setAttribute("command", "testcommand");
-}, function*() {
- checkExpectedEvents({ command: 1 });
- document.getElementById("testcommand").remove();
-});
-
-add_sidebar_task(
- "Check that a sidebar that uses a command element with an oncommand attribute works",
-function*() {
- let command = document.createElement("command");
- command.setAttribute("id", "testcommand");
- command.setAttribute("oncommand", "window.sawEvent(event, true)");
- document.getElementById("mainCommandSet").appendChild(command);
-
- gTestSidebarItem.setAttribute("command", "testcommand");
-}, function*() {
- checkExpectedEvents({ oncommand: 1 });
- document.getElementById("testcommand").remove();
-});
-
-add_sidebar_task("Check that a sidebar that uses a command element with a " +
- "command event listener and oncommand attribute works",
-function*() {
- let command = document.createElement("command");
- command.setAttribute("id", "testcommand");
- command.setAttribute("oncommand", "window.sawEvent(event, true)");
- document.getElementById("mainCommandSet").appendChild(command);
- command.addEventListener("command", window.sawEvent);
-
- gTestSidebarItem.setAttribute("command", "testcommand");
-}, function*() {
- checkExpectedEvents({ command: 1, oncommand: 1 });
- document.getElementById("testcommand").remove();
-});
-
-add_sidebar_task(
- "A sidebar with a command element will still see click events",
-function*() {
- let command = document.createElement("command");
- command.setAttribute("id", "testcommand");
- command.setAttribute("oncommand", "window.sawEvent(event, true)");
- document.getElementById("mainCommandSet").appendChild(command);
- command.addEventListener("command", window.sawEvent);
-
- gTestSidebarItem.setAttribute("command", "testcommand");
- gTestSidebarItem.addEventListener("click", window.sawEvent);
-}, function*() {
- checkExpectedEvents({ click: 1, command: 1, oncommand: 1 });
- document.getElementById("testcommand").remove();
-});
diff --git a/browser/components/customizableui/test/browser_989338_saved_placements_not_resaved.js b/browser/components/customizableui/test/browser_989338_saved_placements_not_resaved.js
deleted file mode 100644
index 2a1b01bf7..000000000
--- a/browser/components/customizableui/test/browser_989338_saved_placements_not_resaved.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const BUTTONID = "test-widget-saved-earlier";
-const AREAID = "test-area-saved-earlier";
-
-var hadSavedState;
-function test() {
- // Hack our way into the module to fake a saved state that isn't there...
- let backstagePass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
- hadSavedState = backstagePass.gSavedState != null;
- if (!hadSavedState) {
- backstagePass.gSavedState = {placements: {}};
- }
- backstagePass.gSavedState.placements[AREAID] = [BUTTONID];
- // Put bogus stuff in the saved state for the nav-bar, so as to check the current placements
- // override this one...
- backstagePass.gSavedState.placements[CustomizableUI.AREA_NAVBAR] = ["bogus-navbar-item"];
-
- backstagePass.gDirty = true;
- backstagePass.CustomizableUIInternal.saveState();
-
- let newSavedState = JSON.parse(Services.prefs.getCharPref("browser.uiCustomization.state"));
- let savedArea = Array.isArray(newSavedState.placements[AREAID]);
- ok(savedArea, "Should have re-saved the state, even though the area isn't registered");
-
- if (savedArea) {
- placementArraysEqual(AREAID, newSavedState.placements[AREAID], [BUTTONID]);
- }
- ok(!backstagePass.gPlacements.has(AREAID), "Placements map shouldn't have been affected");
-
- let savedNavbar = Array.isArray(newSavedState.placements[CustomizableUI.AREA_NAVBAR]);
- ok(savedNavbar, "Should have saved nav-bar contents");
- if (savedNavbar) {
- placementArraysEqual(CustomizableUI.AREA_NAVBAR, newSavedState.placements[CustomizableUI.AREA_NAVBAR],
- CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_NAVBAR));
- }
-}
-
-registerCleanupFunction(function() {
- let backstagePass = Cu.import("resource:///modules/CustomizableUI.jsm", {});
- if (!hadSavedState) {
- backstagePass.gSavedState = null;
- } else {
- let savedPlacements = backstagePass.gSavedState.placements;
- delete savedPlacements[AREAID];
- let realNavBarPlacements = CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_NAVBAR);
- savedPlacements[CustomizableUI.AREA_NAVBAR] = realNavBarPlacements;
- }
- backstagePass.gDirty = true;
- backstagePass.CustomizableUIInternal.saveState();
-});
-
diff --git a/browser/components/customizableui/test/browser_989751_subviewbutton_class.js b/browser/components/customizableui/test/browser_989751_subviewbutton_class.js
deleted file mode 100644
index 0d11324ed..000000000
--- a/browser/components/customizableui/test/browser_989751_subviewbutton_class.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const kCustomClass = "acustomclassnoonewilluse";
-var tempElement = null;
-
-function insertClassNameToMenuChildren(parentMenu) {
- let el = parentMenu.querySelector("menuitem:first-of-type");
- el.classList.add(kCustomClass);
- tempElement = el;
-}
-
-function checkSubviewButtonClass(menuId, buttonId, subviewId) {
- return function*() {
- info("Checking for items without the subviewbutton class in " + buttonId + " widget");
- let menu = document.getElementById(menuId);
- insertClassNameToMenuChildren(menu);
-
- let placement = CustomizableUI.getPlacementOfWidget(buttonId);
- let changedPlacement = false;
- if (!placement || placement.area != CustomizableUI.AREA_PANEL) {
- CustomizableUI.addWidgetToArea(buttonId, CustomizableUI.AREA_PANEL);
- changedPlacement = true;
- }
- yield PanelUI.show();
-
- let button = document.getElementById(buttonId);
- button.click();
-
- yield waitForCondition(() => !PanelUI.multiView.hasAttribute("transitioning"));
- let subview = document.getElementById(subviewId);
- ok(subview.firstChild, "Subview should have a kid");
- let subviewchildren = subview.querySelectorAll("toolbarbutton");
- for (let i = 0; i < subviewchildren.length; i++) {
- let item = subviewchildren[i];
- let itemReadable = "Item '" + item.label + "' (classes: " + item.className + ")";
- ok(item.classList.contains("subviewbutton"), itemReadable + " should have the subviewbutton class.");
- if (i == 0) {
- ok(item.classList.contains(kCustomClass), itemReadable + " should still have its own class, too.");
- }
- }
-
- let panelHiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield panelHiddenPromise;
-
- if (changedPlacement) {
- CustomizableUI.reset();
- }
- };
-}
-
-add_task(checkSubviewButtonClass("menuWebDeveloperPopup", "developer-button", "PanelUI-developerItems"));
-add_task(checkSubviewButtonClass("viewSidebarMenu", "sidebar-button", "PanelUI-sidebarItems"));
-
-registerCleanupFunction(function() {
- tempElement.classList.remove(kCustomClass)
- tempElement = null;
-});
diff --git a/browser/components/customizableui/test/browser_992747_toggle_noncustomizable_toolbar.js b/browser/components/customizableui/test/browser_992747_toggle_noncustomizable_toolbar.js
deleted file mode 100644
index eb0a8c8ee..000000000
--- a/browser/components/customizableui/test/browser_992747_toggle_noncustomizable_toolbar.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TOOLBARID = "test-noncustomizable-toolbar-for-toggling";
-function test() {
- let tb = document.createElementNS(kNSXUL, "toolbar");
- tb.id = TOOLBARID;
- gNavToolbox.appendChild(tb);
- try {
- CustomizableUI.setToolbarVisibility(TOOLBARID, false);
- } catch (ex) {
- ok(false, "Should not throw exceptions trying to set toolbar visibility.");
- }
- is(tb.getAttribute("collapsed"), "true", "Toolbar should be collapsed");
- try {
- CustomizableUI.setToolbarVisibility(TOOLBARID, true);
- } catch (ex) {
- ok(false, "Should not throw exceptions trying to set toolbar visibility.");
- }
- is(tb.getAttribute("collapsed"), "false", "Toolbar should be uncollapsed");
- tb.remove();
-}
-
diff --git a/browser/components/customizableui/test/browser_993322_widget_notoolbar.js b/browser/components/customizableui/test/browser_993322_widget_notoolbar.js
deleted file mode 100644
index 9264eb78a..000000000
--- a/browser/components/customizableui/test/browser_993322_widget_notoolbar.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const BUTTONID = "test-API-created-widget-toolbar-gone";
-const TOOLBARID = "test-API-created-extra-toolbar";
-
-add_task(function*() {
- let toolbar = createToolbarWithPlacements(TOOLBARID, []);
- CustomizableUI.addWidgetToArea(BUTTONID, TOOLBARID);
- is(CustomizableUI.getPlacementOfWidget(BUTTONID).area, TOOLBARID, "Should be on toolbar");
- is(toolbar.children.length, 0, "Toolbar has no kid");
-
- CustomizableUI.unregisterArea(TOOLBARID);
- CustomizableUI.createWidget({id: BUTTONID, label: "Test widget toolbar gone"});
-
- let currentWidget = CustomizableUI.getWidget(BUTTONID);
-
- yield startCustomizing();
- let buttonNode = document.getElementById(BUTTONID);
- ok(buttonNode, "Should find button in window");
- if (buttonNode) {
- is(buttonNode.parentNode.localName, "toolbarpaletteitem", "Node should be wrapped");
- is(buttonNode.parentNode.getAttribute("place"), "palette", "Node should be in palette");
- is(buttonNode, gNavToolbox.palette.querySelector("#" + BUTTONID), "Node should really be in palette.");
- }
- is(currentWidget.forWindow(window).node, buttonNode, "Should have the same node for customize mode");
- yield endCustomizing();
-
- CustomizableUI.destroyWidget(BUTTONID);
- CustomizableUI.unregisterArea(TOOLBARID, true);
- toolbar.remove();
- gAddedToolbars.clear();
-});
diff --git a/browser/components/customizableui/test/browser_995164_registerArea_during_customize_mode.js b/browser/components/customizableui/test/browser_995164_registerArea_during_customize_mode.js
deleted file mode 100644
index 4d292a929..000000000
--- a/browser/components/customizableui/test/browser_995164_registerArea_during_customize_mode.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TOOLBARID = "test-toolbar-added-during-customize-mode";
-
-// The ID of a button that is not placed (ie, is in the palette) by default
-const kNonPlacedWidgetId = "open-file-button";
-
-add_task(function*() {
- yield startCustomizing();
- let toolbar = createToolbarWithPlacements(TOOLBARID, []);
- CustomizableUI.addWidgetToArea(kNonPlacedWidgetId, TOOLBARID);
- let button = document.getElementById(kNonPlacedWidgetId);
- ok(button, "Button should exist.");
- is(button.parentNode.localName, "toolbarpaletteitem", "Button's parent node should be a wrapper.");
-
- simulateItemDrag(button, gNavToolbox.palette);
- ok(!CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId), "Button moved to the palette");
- ok(gNavToolbox.palette.querySelector(`#${kNonPlacedWidgetId}`), "Button really is in palette.");
-
- button.scrollIntoView();
- simulateItemDrag(button, toolbar);
- ok(CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId), "Button moved out of palette");
- is(CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId).area, TOOLBARID, "Button's back on toolbar");
- ok(toolbar.querySelector(`#${kNonPlacedWidgetId}`), "Button really is on toolbar.");
-
- yield endCustomizing();
- isnot(button.parentNode.localName, "toolbarpaletteitem", "Button's parent node should not be a wrapper outside customize mode.");
- yield startCustomizing();
-
- is(button.parentNode.localName, "toolbarpaletteitem", "Button's parent node should be a wrapper back in customize mode.");
-
- simulateItemDrag(button, gNavToolbox.palette);
- ok(!CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId), "Button moved to the palette");
- ok(gNavToolbox.palette.querySelector(`#${kNonPlacedWidgetId}`), "Button really is in palette.");
-
- ok(!CustomizableUI.inDefaultState, "Not in default state while toolbar is not collapsed yet.");
- setToolbarVisibility(toolbar, false);
- ok(CustomizableUI.inDefaultState, "In default state while toolbar is collapsed.");
-
- setToolbarVisibility(toolbar, true);
-
- info("Check that removing the area registration from within customize mode works");
- CustomizableUI.unregisterArea(TOOLBARID);
- ok(CustomizableUI.inDefaultState, "Now that the toolbar is no longer registered, should be in default state.");
- ok(!gCustomizeMode.areas.has(toolbar), "Toolbar shouldn't be known to customize mode.");
-
- CustomizableUI.registerArea(TOOLBARID, {legacy: true, defaultPlacements: []});
- CustomizableUI.registerToolbarNode(toolbar, []);
- ok(!CustomizableUI.inDefaultState, "Now that the toolbar is registered again, should no longer be in default state.");
- ok(gCustomizeMode.areas.has(toolbar), "Toolbar should be known to customize mode again.");
-
- button.scrollIntoView();
- simulateItemDrag(button, toolbar);
- ok(CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId), "Button moved out of palette");
- is(CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId).area, TOOLBARID, "Button's back on toolbar");
- ok(toolbar.querySelector(`#${kNonPlacedWidgetId}`), "Button really is on toolbar.");
-
- let otherWin = yield openAndLoadWindow({}, true);
- let otherTB = otherWin.document.createElementNS(kNSXUL, "toolbar");
- otherTB.id = TOOLBARID;
- otherTB.setAttribute("customizable", "true");
- let wasInformedCorrectlyOfAreaAppearing = false;
- let listener = {
- onAreaNodeRegistered: function(aArea, aNode) {
- if (aNode == otherTB) {
- wasInformedCorrectlyOfAreaAppearing = true;
- }
- }
- };
- CustomizableUI.addListener(listener);
- otherWin.gNavToolbox.appendChild(otherTB);
- ok(wasInformedCorrectlyOfAreaAppearing, "Should have been told area was registered.");
- CustomizableUI.removeListener(listener);
-
- ok(otherTB.querySelector(`#${kNonPlacedWidgetId}`), "Button is on other toolbar, too.");
-
- simulateItemDrag(button, gNavToolbox.palette);
- ok(!CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId), "Button moved to the palette");
- ok(gNavToolbox.palette.querySelector(`#${kNonPlacedWidgetId}`), "Button really is in palette.");
- ok(!otherTB.querySelector(`#${kNonPlacedWidgetId}`), "Button is in palette in other window, too.");
-
- button.scrollIntoView();
- simulateItemDrag(button, toolbar);
- ok(CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId), "Button moved out of palette");
- is(CustomizableUI.getPlacementOfWidget(kNonPlacedWidgetId).area, TOOLBARID, "Button's back on toolbar");
- ok(toolbar.querySelector(`#${kNonPlacedWidgetId}`), "Button really is on toolbar.");
- ok(otherTB.querySelector(`#${kNonPlacedWidgetId}`), "Button is on other toolbar, too.");
-
- let wasInformedCorrectlyOfAreaDisappearing = false;
- // XXXgijs So we could be using promiseWindowClosed here. However, after
- // repeated random oranges, I'm instead relying on onWindowClosed below to
- // fire appropriately - it is linked to an unload event as well, and so
- // reusing it prevents a potential race between unload handlers where the
- // one from promiseWindowClosed could fire before the onWindowClosed
- // (and therefore onAreaNodeRegistered) one, causing the test to fail.
- let windowCloseDeferred = Promise.defer();
- listener = {
- onAreaNodeUnregistered: function(aArea, aNode, aReason) {
- if (aArea == TOOLBARID) {
- is(aNode, otherTB, "Should be informed about other toolbar");
- is(aReason, CustomizableUI.REASON_WINDOW_CLOSED, "Reason should be correct.");
- wasInformedCorrectlyOfAreaDisappearing = (aReason === CustomizableUI.REASON_WINDOW_CLOSED);
- }
- },
- onWindowClosed: function(aWindow) {
- if (aWindow == otherWin) {
- windowCloseDeferred.resolve(aWindow);
- } else {
- info("Other window was closed!");
- info("Other window title: " + (aWindow.document && aWindow.document.title));
- info("Our window title: " + (otherWin.document && otherWin.document.title));
- }
- },
- };
- CustomizableUI.addListener(listener);
- otherWin.close();
- let windowClosed = yield windowCloseDeferred.promise;
-
- is(windowClosed, otherWin, "Window should have sent onWindowClosed notification.");
- ok(wasInformedCorrectlyOfAreaDisappearing, "Should be told about window closing.");
- // Closing the other window should not be counted against this window's customize mode:
- is(button.parentNode.localName, "toolbarpaletteitem", "Button's parent node should still be a wrapper.");
- ok(gCustomizeMode.areas.has(toolbar), "Toolbar should still be a customizable area for this customize mode instance.");
-
- yield gCustomizeMode.reset();
-
- yield endCustomizing();
-
- CustomizableUI.removeListener(listener);
- wasInformedCorrectlyOfAreaDisappearing = false;
- listener = {
- onAreaNodeUnregistered: function(aArea, aNode, aReason) {
- if (aArea == TOOLBARID) {
- is(aNode, toolbar, "Should be informed about this window's toolbar");
- is(aReason, CustomizableUI.REASON_AREA_UNREGISTERED, "Reason for final removal should be correct.");
- wasInformedCorrectlyOfAreaDisappearing = (aReason === CustomizableUI.REASON_AREA_UNREGISTERED);
- }
- },
- }
- CustomizableUI.addListener(listener);
- removeCustomToolbars();
- ok(wasInformedCorrectlyOfAreaDisappearing, "Should be told about area being unregistered.");
- CustomizableUI.removeListener(listener);
- ok(CustomizableUI.inDefaultState, "Should be fine after exiting customize mode.");
-});
diff --git a/browser/components/customizableui/test/browser_996364_registerArea_different_properties.js b/browser/components/customizableui/test/browser_996364_registerArea_different_properties.js
deleted file mode 100644
index b9de5f687..000000000
--- a/browser/components/customizableui/test/browser_996364_registerArea_different_properties.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Calling CustomizableUI.registerArea twice with no
-// properties should not throw an exception.
-add_task(function() {
- try {
- CustomizableUI.registerArea("area-996364", {});
- CustomizableUI.registerArea("area-996364", {});
- } catch (ex) {
- ok(false, ex.message);
- }
-
- CustomizableUI.unregisterArea("area-996364", true);
-});
-
-add_task(function() {
- let exceptionThrown = false;
- try {
- CustomizableUI.registerArea("area-996364-2", {type: CustomizableUI.TYPE_TOOLBAR, defaultCollapsed: "false"});
- } catch (ex) {
- exceptionThrown = true;
- }
- ok(exceptionThrown, "defaultCollapsed is not allowed as an external property");
-
- // No need to unregister the area because registration fails.
-});
-
-add_task(function() {
- let exceptionThrown;
- try {
- CustomizableUI.registerArea("area-996364-3", {type: CustomizableUI.TYPE_TOOLBAR});
- CustomizableUI.registerArea("area-996364-3", {type: CustomizableUI.TYPE_MENU_PANEL});
- } catch (ex) {
- exceptionThrown = ex;
- }
- ok(exceptionThrown, "Exception expected, an area cannot change types: " + (exceptionThrown ? exceptionThrown : "[no exception]"));
-
- CustomizableUI.unregisterArea("area-996364-3", true);
-});
-
-add_task(function() {
- let exceptionThrown;
- try {
- CustomizableUI.registerArea("area-996364-4", {type: CustomizableUI.TYPE_MENU_PANEL});
- CustomizableUI.registerArea("area-996364-4", {type: CustomizableUI.TYPE_TOOLBAR});
- } catch (ex) {
- exceptionThrown = ex;
- }
- ok(exceptionThrown, "Exception expected, an area cannot change types: " + (exceptionThrown ? exceptionThrown : "[no exception]"));
-
- CustomizableUI.unregisterArea("area-996364-4", true);
-});
-
-add_task(function() {
- let exceptionThrown;
- try {
- CustomizableUI.registerArea("area-996899-1", { anchor: "PanelUI-menu-button",
- type: CustomizableUI.TYPE_MENU_PANEL,
- defaultPlacements: [] });
- CustomizableUI.registerArea("area-996899-1", { anchor: "home-button",
- type: CustomizableUI.TYPE_MENU_PANEL,
- defaultPlacements: [] });
- } catch (ex) {
- exceptionThrown = ex;
- }
- ok(!exceptionThrown, "Changing anchors shouldn't throw an exception: " + (exceptionThrown ? exceptionThrown : "[no exception]"));
- CustomizableUI.unregisterArea("area-996899-1", true);
-});
-
-add_task(function() {
- let exceptionThrown;
- try {
- CustomizableUI.registerArea("area-996899-2", { anchor: "PanelUI-menu-button",
- type: CustomizableUI.TYPE_MENU_PANEL,
- defaultPlacements: [] });
- CustomizableUI.registerArea("area-996899-2", { anchor: "PanelUI-menu-button",
- type: CustomizableUI.TYPE_MENU_PANEL,
- defaultPlacements: ["feed-button"] });
- } catch (ex) {
- exceptionThrown = ex;
- }
- ok(!exceptionThrown, "Changing defaultPlacements shouldn't throw an exception: " + (exceptionThrown ? exceptionThrown : "[no exception]"));
- CustomizableUI.unregisterArea("area-996899-2", true);
-});
-
-add_task(function() {
- let exceptionThrown;
- try {
- CustomizableUI.registerArea("area-996899-3", { legacy: true });
- CustomizableUI.registerArea("area-996899-3", { legacy: false });
- } catch (ex) {
- exceptionThrown = ex;
- }
- ok(exceptionThrown, "Changing 'legacy' should throw an exception: " + (exceptionThrown ? exceptionThrown : "[no exception]"));
- CustomizableUI.unregisterArea("area-996899-3", true);
-});
-
-add_task(function() {
- let exceptionThrown;
- try {
- CustomizableUI.registerArea("area-996899-4", { overflowable: true });
- CustomizableUI.registerArea("area-996899-4", { overflowable: false });
- } catch (ex) {
- exceptionThrown = ex;
- }
- ok(exceptionThrown, "Changing 'overflowable' should throw an exception: " + (exceptionThrown ? exceptionThrown : "[no exception]"));
- CustomizableUI.unregisterArea("area-996899-4", true);
-});
diff --git a/browser/components/customizableui/test/browser_996635_remove_non_widgets.js b/browser/components/customizableui/test/browser_996635_remove_non_widgets.js
deleted file mode 100644
index 14a446eec..000000000
--- a/browser/components/customizableui/test/browser_996635_remove_non_widgets.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// NB: This is testing what happens if something that /isn't/ a customizable
-// widget gets used in CustomizableUI APIs. Don't use this as an example of
-// what should happen in a "normal" case or how you should use the API.
-function test() {
- // First create a button that isn't customizable, and add it in the nav-bar,
- // but not in the customizable part of it (the customization target) but
- // next to the main (hamburger) menu button.
- const buttonID = "Test-non-widget-non-removable-button";
- let btn = document.createElement("toolbarbutton");
- btn.id = buttonID;
- btn.label = "Hi";
- btn.setAttribute("style", "width: 20px; height: 20px; background-color: red");
- document.getElementById("nav-bar").appendChild(btn);
- registerCleanupFunction(function() {
- btn.remove();
- });
-
- // Now try to add this non-customizable button to the tabstrip. This will
- // update the internal bookkeeping (ie placements) information, but shouldn't
- // move the node.
- CustomizableUI.addWidgetToArea(buttonID, CustomizableUI.AREA_TABSTRIP);
- let placement = CustomizableUI.getPlacementOfWidget(buttonID);
- // Check our bookkeeping
- ok(placement, "Button should be placed");
- is(placement && placement.area, CustomizableUI.AREA_TABSTRIP, "Should be placed on tabstrip.");
- // Check we didn't move the node.
- is(btn.parentNode && btn.parentNode.id, "nav-bar", "Actual button should still be on navbar.");
-
- // Now remove the node again. This should remove the bookkeeping, but again
- // not affect the actual node.
- CustomizableUI.removeWidgetFromArea(buttonID);
- placement = CustomizableUI.getPlacementOfWidget(buttonID);
- // Check our bookkeeping:
- ok(!placement, "Button should no longer have a placement.");
- // Check our node.
- is(btn.parentNode && btn.parentNode.id, "nav-bar", "Actual button should still be on navbar.");
-}
-
diff --git a/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js b/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js
deleted file mode 100644
index 2c5f0c79c..000000000
--- a/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-const kTestBarID = "testBar";
-const kWidgetID = "characterencoding-button";
-
-function createTestBar(aLegacy) {
- let testBar = document.createElement("toolbar");
- testBar.id = kTestBarID;
- testBar.setAttribute("customizable", "true");
- CustomizableUI.registerArea(kTestBarID, {
- type: CustomizableUI.TYPE_TOOLBAR,
- legacy: aLegacy,
- });
- gNavToolbox.appendChild(testBar);
- return testBar;
-}
-
-/**
- * Helper function that does the following:
- *
- * 1) Creates a custom toolbar and registers it
- * with CustomizableUI. Sets the legacy attribute
- * of the object passed to registerArea to aLegacy.
- * 2) Adds the widget with ID aWidgetID to that new
- * toolbar.
- * 3) Enters customize mode and makes sure that the
- * widget is still in the right toolbar.
- * 4) Exits customize mode, then removes and deregisters
- * the custom toolbar.
- * 5) Checks that the widget has no placement.
- * 6) Re-adds and re-registers a custom toolbar with the same
- * ID and options as the first one.
- * 7) Enters customize mode and checks that the widget is
- * properly back in the toolbar.
- * 8) Exits customize mode, removes and de-registers the
- * toolbar, and resets the toolbars to default.
- */
-function checkRestoredPresence(aWidgetID, aLegacy) {
- return Task.spawn(function* () {
- let testBar = createTestBar(aLegacy);
- CustomizableUI.addWidgetToArea(aWidgetID, kTestBarID);
- let placement = CustomizableUI.getPlacementOfWidget(aWidgetID);
- is(placement.area, kTestBarID,
- "Expected " + aWidgetID + " to be in the test toolbar");
-
- CustomizableUI.unregisterArea(testBar.id);
- testBar.remove();
-
- placement = CustomizableUI.getPlacementOfWidget(aWidgetID);
- is(placement, null, "Expected " + aWidgetID + " to be in the palette");
-
- testBar = createTestBar(aLegacy);
-
- yield startCustomizing();
- placement = CustomizableUI.getPlacementOfWidget(aWidgetID);
- is(placement.area, kTestBarID,
- "Expected " + aWidgetID + " to be in the test toolbar");
- yield endCustomizing();
-
- CustomizableUI.unregisterArea(testBar.id);
- testBar.remove();
-
- yield resetCustomization();
- });
-}
-
-add_task(function* () {
- yield checkRestoredPresence("downloads-button", false);
- yield checkRestoredPresence("downloads-button", true);
-});
-
-add_task(function* () {
- yield checkRestoredPresence("characterencoding-button", false);
- yield checkRestoredPresence("characterencoding-button", true);
-});
diff --git a/browser/components/customizableui/test/browser_check_tooltips_in_navbar.js b/browser/components/customizableui/test/browser_check_tooltips_in_navbar.js
deleted file mode 100644
index 31dd42ad8..000000000
--- a/browser/components/customizableui/test/browser_check_tooltips_in_navbar.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function* check_tooltips_in_navbar() {
- yield startCustomizing();
- let homeButtonWrapper = document.getElementById("wrapper-home-button");
- let homeButton = document.getElementById("home-button");
- is(homeButtonWrapper.getAttribute("tooltiptext"), homeButton.getAttribute("label"), "the wrapper's tooltip should match the button's label");
- ok(homeButtonWrapper.getAttribute("tooltiptext"), "the button should have tooltip text");
- yield endCustomizing();
-});
diff --git a/browser/components/customizableui/test/browser_customizemode_contextmenu_menubuttonstate.js b/browser/components/customizableui/test/browser_customizemode_contextmenu_menubuttonstate.js
deleted file mode 100644
index 8e1950291..000000000
--- a/browser/components/customizableui/test/browser_customizemode_contextmenu_menubuttonstate.js
+++ /dev/null
@@ -1,24 +0,0 @@
-"use strict";
-
-add_task(function*() {
- ok(!PanelUI.menuButton.hasAttribute("open"), "Menu button should not be 'pressed' outside customize mode");
- yield startCustomizing();
-
- is(PanelUI.menuButton.getAttribute("open"), "true", "Menu button should be 'pressed' when in customize mode");
-
- let contextMenu = document.getElementById("customizationPanelItemContextMenu");
- let shownPromise = popupShown(contextMenu);
- let newWindowButton = document.getElementById("wrapper-new-window-button");
- EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
- yield shownPromise;
- is(PanelUI.menuButton.getAttribute("open"), "true", "Menu button should be 'pressed' when in customize mode after opening a context menu");
-
- let hiddenContextPromise = popupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hiddenContextPromise;
- is(PanelUI.menuButton.getAttribute("open"), "true", "Menu button should be 'pressed' when in customize mode after hiding a context menu");
- yield endCustomizing();
-
- ok(!PanelUI.menuButton.hasAttribute("open"), "Menu button should not be 'pressed' after ending customize mode");
-});
-
diff --git a/browser/components/customizableui/test/browser_panel_toggle.js b/browser/components/customizableui/test/browser_panel_toggle.js
deleted file mode 100644
index 4c286fb85..000000000
--- a/browser/components/customizableui/test/browser_panel_toggle.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * Test opening and closing the menu panel UI.
- */
-
-// Show and hide the menu panel programmatically without an event (like UITour.jsm would)
-add_task(function*() {
- let shownPromise = promisePanelShown(window);
- PanelUI.show();
- yield shownPromise;
-
- is(PanelUI.panel.getAttribute("panelopen"), "true", "Check that panel has panelopen attribute");
- is(PanelUI.panel.state, "open", "Check that panel state is 'open'");
-
- let hiddenPromise = promisePanelHidden(window);
- PanelUI.hide();
- yield hiddenPromise;
-
- ok(!PanelUI.panel.hasAttribute("panelopen"), "Check that panel doesn't have the panelopen attribute");
- is(PanelUI.panel.state, "closed", "Check that panel state is 'closed'");
-});
-
-// Toggle the menu panel open and closed
-add_task(function*() {
- let shownPromise = promisePanelShown(window);
- PanelUI.toggle({type: "command"});
- yield shownPromise;
-
- is(PanelUI.panel.getAttribute("panelopen"), "true", "Check that panel has panelopen attribute");
- is(PanelUI.panel.state, "open", "Check that panel state is 'open'");
-
- let hiddenPromise = promisePanelHidden(window);
- PanelUI.toggle({type: "command"});
- yield hiddenPromise;
-
- ok(!PanelUI.panel.hasAttribute("panelopen"), "Check that panel doesn't have the panelopen attribute");
- is(PanelUI.panel.state, "closed", "Check that panel state is 'closed'");
-});
diff --git a/browser/components/customizableui/test/browser_switch_to_customize_mode.js b/browser/components/customizableui/test/browser_switch_to_customize_mode.js
deleted file mode 100644
index 459ea7a1c..000000000
--- a/browser/components/customizableui/test/browser_switch_to_customize_mode.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-add_task(function*() {
- yield startCustomizing();
- is(gBrowser.tabs.length, 2, "Should have 2 tabs");
-
- let paletteKidCount = document.getElementById("customization-palette").childElementCount;
- let nonCustomizingTab = gBrowser.tabContainer.querySelector("tab:not([customizemode=true])");
- let finishedCustomizing = BrowserTestUtils.waitForEvent(gNavToolbox, "aftercustomization");
- yield BrowserTestUtils.switchTab(gBrowser, nonCustomizingTab);
- yield finishedCustomizing;
-
- let startedCount = 0;
- let handler = e => startedCount++;
- gNavToolbox.addEventListener("customizationstarting", handler);
- yield startCustomizing();
- CustomizableUI.removeWidgetFromArea("home-button");
- yield gCustomizeMode.reset().catch(e => {
- ok(false, "Threw an exception trying to reset after making modifications in customize mode: " + e);
- });
-
- let newKidCount = document.getElementById("customization-palette").childElementCount;
- is(newKidCount, paletteKidCount, "Should have just as many items in the palette as before.");
- yield endCustomizing();
- is(startedCount, 1, "Should have only started once");
- gNavToolbox.removeEventListener("customizationstarting", handler);
- let customizableToolbars = document.querySelectorAll("toolbar[customizable=true]:not([autohide=true])");
- for (let toolbar of customizableToolbars) {
- ok(!toolbar.hasAttribute("customizing"), "Toolbar " + toolbar.id + " is no longer customizing");
- }
- let menuitem = document.getElementById("PanelUI-customize");
- isnot(menuitem.getAttribute("label"), menuitem.getAttribute("exitLabel"), "Should have exited successfully");
-});
-
diff --git a/browser/components/customizableui/test/head.js b/browser/components/customizableui/test/head.js
deleted file mode 100644
index 7b8d84e20..000000000
--- a/browser/components/customizableui/test/head.js
+++ /dev/null
@@ -1,499 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Avoid leaks by using tmp for imports...
-var tmp = {};
-Cu.import("resource://gre/modules/Promise.jsm", tmp);
-Cu.import("resource:///modules/CustomizableUI.jsm", tmp);
-Cu.import("resource://gre/modules/AppConstants.jsm", tmp);
-var {Promise, CustomizableUI, AppConstants} = tmp;
-
-var EventUtils = {};
-Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
-Services.prefs.setBoolPref("browser.uiCustomization.skipSourceNodeCheck", true);
-registerCleanupFunction(() => Services.prefs.clearUserPref("browser.uiCustomization.skipSourceNodeCheck"));
-
-// Remove temporary e10s related new window options in customize ui,
-// they break a lot of tests.
-CustomizableUI.destroyWidget("e10s-button");
-CustomizableUI.removeWidgetFromArea("e10s-button");
-
-var {synthesizeDragStart, synthesizeDrop} = EventUtils;
-
-const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-const kTabEventFailureTimeoutInMs = 20000;
-
-function createDummyXULButton(id, label, win = window) {
- let btn = document.createElementNS(kNSXUL, "toolbarbutton");
- btn.id = id;
- btn.setAttribute("label", label || id);
- btn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
- win.gNavToolbox.palette.appendChild(btn);
- return btn;
-}
-
-var gAddedToolbars = new Set();
-
-function createToolbarWithPlacements(id, placements = []) {
- gAddedToolbars.add(id);
- let tb = document.createElementNS(kNSXUL, "toolbar");
- tb.id = id;
- tb.setAttribute("customizable", "true");
- CustomizableUI.registerArea(id, {
- type: CustomizableUI.TYPE_TOOLBAR,
- defaultPlacements: placements
- });
- gNavToolbox.appendChild(tb);
- return tb;
-}
-
-function createOverflowableToolbarWithPlacements(id, placements) {
- gAddedToolbars.add(id);
-
- let tb = document.createElementNS(kNSXUL, "toolbar");
- tb.id = id;
- tb.setAttribute("customizationtarget", id + "-target");
-
- let customizationtarget = document.createElementNS(kNSXUL, "hbox");
- customizationtarget.id = id + "-target";
- customizationtarget.setAttribute("flex", "1");
- tb.appendChild(customizationtarget);
-
- let overflowPanel = document.createElementNS(kNSXUL, "panel");
- overflowPanel.id = id + "-overflow";
- document.getElementById("mainPopupSet").appendChild(overflowPanel);
-
- let overflowList = document.createElementNS(kNSXUL, "vbox");
- overflowList.id = id + "-overflow-list";
- overflowPanel.appendChild(overflowList);
-
- let chevron = document.createElementNS(kNSXUL, "toolbarbutton");
- chevron.id = id + "-chevron";
- tb.appendChild(chevron);
-
- CustomizableUI.registerArea(id, {
- type: CustomizableUI.TYPE_TOOLBAR,
- defaultPlacements: placements,
- overflowable: true,
- });
-
- tb.setAttribute("customizable", "true");
- tb.setAttribute("overflowable", "true");
- tb.setAttribute("overflowpanel", overflowPanel.id);
- tb.setAttribute("overflowtarget", overflowList.id);
- tb.setAttribute("overflowbutton", chevron.id);
-
- gNavToolbox.appendChild(tb);
- return tb;
-}
-
-function removeCustomToolbars() {
- CustomizableUI.reset();
- for (let toolbarId of gAddedToolbars) {
- CustomizableUI.unregisterArea(toolbarId, true);
- let tb = document.getElementById(toolbarId);
- if (tb.hasAttribute("overflowpanel")) {
- let panel = document.getElementById(tb.getAttribute("overflowpanel"));
- if (panel)
- panel.remove();
- }
- tb.remove();
- }
- gAddedToolbars.clear();
-}
-
-function getToolboxCustomToolbarId(toolbarName) {
- return "__customToolbar_" + toolbarName.replace(" ", "_");
-}
-
-function resetCustomization() {
- return CustomizableUI.reset();
-}
-
-function isInDevEdition() {
- return AppConstants.MOZ_DEV_EDITION;
-}
-
-function removeDeveloperButtonIfDevEdition(areaPanelPlacements) {
- if (isInDevEdition()) {
- areaPanelPlacements.splice(areaPanelPlacements.indexOf("developer-button"), 1);
- }
-}
-
-function assertAreaPlacements(areaId, expectedPlacements) {
- let actualPlacements = getAreaWidgetIds(areaId);
- placementArraysEqual(areaId, actualPlacements, expectedPlacements);
-}
-
-function placementArraysEqual(areaId, actualPlacements, expectedPlacements) {
- is(actualPlacements.length, expectedPlacements.length,
- "Area " + areaId + " should have " + expectedPlacements.length + " items.");
- let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
- for (let i = 0; i < minItems; i++) {
- if (typeof expectedPlacements[i] == "string") {
- is(actualPlacements[i], expectedPlacements[i],
- "Item " + i + " in " + areaId + " should match expectations.");
- } else if (expectedPlacements[i] instanceof RegExp) {
- ok(expectedPlacements[i].test(actualPlacements[i]),
- "Item " + i + " (" + actualPlacements[i] + ") in " +
- areaId + " should match " + expectedPlacements[i]);
- } else {
- ok(false, "Unknown type of expected placement passed to " +
- " assertAreaPlacements. Is your test broken?");
- }
- }
-}
-
-function todoAssertAreaPlacements(areaId, expectedPlacements) {
- let actualPlacements = getAreaWidgetIds(areaId);
- let isPassing = actualPlacements.length == expectedPlacements.length;
- let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
- for (let i = 0; i < minItems; i++) {
- if (typeof expectedPlacements[i] == "string") {
- isPassing = isPassing && actualPlacements[i] == expectedPlacements[i];
- } else if (expectedPlacements[i] instanceof RegExp) {
- isPassing = isPassing && expectedPlacements[i].test(actualPlacements[i]);
- } else {
- ok(false, "Unknown type of expected placement passed to " +
- " assertAreaPlacements. Is your test broken?");
- }
- }
- todo(isPassing, "The area placements for " + areaId +
- " should equal the expected placements.");
-}
-
-function getAreaWidgetIds(areaId) {
- return CustomizableUI.getWidgetIdsInArea(areaId);
-}
-
-function simulateItemDrag(aToDrag, aTarget) {
- synthesizeDrop(aToDrag.parentNode, aTarget);
-}
-
-function endCustomizing(aWindow=window) {
- if (aWindow.document.documentElement.getAttribute("customizing") != "true") {
- return true;
- }
- Services.prefs.setBoolPref("browser.uiCustomization.disableAnimation", true);
- let deferredEndCustomizing = Promise.defer();
- function onCustomizationEnds() {
- Services.prefs.setBoolPref("browser.uiCustomization.disableAnimation", false);
- aWindow.gNavToolbox.removeEventListener("aftercustomization", onCustomizationEnds);
- deferredEndCustomizing.resolve();
- }
- aWindow.gNavToolbox.addEventListener("aftercustomization", onCustomizationEnds);
- aWindow.gCustomizeMode.exit();
-
- return deferredEndCustomizing.promise;
-}
-
-function startCustomizing(aWindow=window) {
- if (aWindow.document.documentElement.getAttribute("customizing") == "true") {
- return null;
- }
- Services.prefs.setBoolPref("browser.uiCustomization.disableAnimation", true);
- let deferred = Promise.defer();
- function onCustomizing() {
- aWindow.gNavToolbox.removeEventListener("customizationready", onCustomizing);
- Services.prefs.setBoolPref("browser.uiCustomization.disableAnimation", false);
- deferred.resolve();
- }
- aWindow.gNavToolbox.addEventListener("customizationready", onCustomizing);
- aWindow.gCustomizeMode.enter();
- return deferred.promise;
-}
-
-function promiseObserverNotified(aTopic) {
- let deferred = Promise.defer();
- Services.obs.addObserver(function onNotification(aSubject, aTopic, aData) {
- Services.obs.removeObserver(onNotification, aTopic);
- deferred.resolve({subject: aSubject, data: aData});
- }, aTopic, false);
- return deferred.promise;
-}
-
-function openAndLoadWindow(aOptions, aWaitForDelayedStartup=false) {
- let deferred = Promise.defer();
- let win = OpenBrowserWindow(aOptions);
- if (aWaitForDelayedStartup) {
- Services.obs.addObserver(function onDS(aSubject, aTopic, aData) {
- 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);
- deferred.resolve(win);
- });
- }
- return deferred.promise;
-}
-
-function promiseWindowClosed(win) {
- let deferred = Promise.defer();
- win.addEventListener("unload", function onunload() {
- win.removeEventListener("unload", onunload);
- deferred.resolve();
- });
- win.close();
- return deferred.promise;
-}
-
-function promisePanelShown(win) {
- let panelEl = win.PanelUI.panel;
- return promisePanelElementShown(win, panelEl);
-}
-
-function promiseOverflowShown(win) {
- let panelEl = win.document.getElementById("widget-overflow");
- return promisePanelElementShown(win, panelEl);
-}
-
-function promisePanelElementShown(win, aPanel) {
- let deferred = Promise.defer();
- let timeoutId = win.setTimeout(() => {
- deferred.reject("Panel did not show within 20 seconds.");
- }, 20000);
- function onPanelOpen(e) {
- aPanel.removeEventListener("popupshown", onPanelOpen);
- win.clearTimeout(timeoutId);
- deferred.resolve();
- }
- aPanel.addEventListener("popupshown", onPanelOpen);
- return deferred.promise;
-}
-
-function promisePanelHidden(win) {
- let panelEl = win.PanelUI.panel;
- return promisePanelElementHidden(win, panelEl);
-}
-
-function promiseOverflowHidden(win) {
- let panelEl = document.getElementById("widget-overflow");
- return promisePanelElementHidden(win, panelEl);
-}
-
-function promisePanelElementHidden(win, aPanel) {
- let deferred = Promise.defer();
- let timeoutId = win.setTimeout(() => {
- deferred.reject("Panel did not hide within 20 seconds.");
- }, 20000);
- function onPanelClose(e) {
- aPanel.removeEventListener("popuphidden", onPanelClose);
- win.clearTimeout(timeoutId);
- deferred.resolve();
- }
- aPanel.addEventListener("popuphidden", onPanelClose);
- return deferred.promise;
-}
-
-function isPanelUIOpen() {
- return PanelUI.panel.state == "open" || PanelUI.panel.state == "showing";
-}
-
-function subviewShown(aSubview) {
- let deferred = Promise.defer();
- let win = aSubview.ownerGlobal;
- let timeoutId = win.setTimeout(() => {
- deferred.reject("Subview (" + aSubview.id + ") did not show within 20 seconds.");
- }, 20000);
- function onViewShowing(e) {
- aSubview.removeEventListener("ViewShowing", onViewShowing);
- win.clearTimeout(timeoutId);
- deferred.resolve();
- }
- aSubview.addEventListener("ViewShowing", onViewShowing);
- return deferred.promise;
-}
-
-function subviewHidden(aSubview) {
- let deferred = Promise.defer();
- let win = aSubview.ownerGlobal;
- let timeoutId = win.setTimeout(() => {
- deferred.reject("Subview (" + aSubview.id + ") did not hide within 20 seconds.");
- }, 20000);
- function onViewHiding(e) {
- aSubview.removeEventListener("ViewHiding", onViewHiding);
- win.clearTimeout(timeoutId);
- deferred.resolve();
- }
- aSubview.addEventListener("ViewHiding", onViewHiding);
- return deferred.promise;
-}
-
-function waitForCondition(aConditionFn, aMaxTries=50, aCheckInterval=100) {
- function tryNow() {
- tries++;
- if (aConditionFn()) {
- deferred.resolve();
- } else if (tries < aMaxTries) {
- tryAgain();
- } else {
- deferred.reject("Condition timed out: " + aConditionFn.toSource());
- }
- }
- function tryAgain() {
- setTimeout(tryNow, aCheckInterval);
- }
- let deferred = Promise.defer();
- let tries = 0;
- tryAgain();
- return deferred.promise;
-}
-
-function waitFor(aTimeout=100) {
- let deferred = Promise.defer();
- setTimeout(() => deferred.resolve(), aTimeout);
- return deferred.promise;
-}
-
-/**
- * Starts a load in an existing tab and waits for it to finish (via some event).
- *
- * @param aTab The tab to load into.
- * @param aUrl The url to load.
- * @param aEventType The load event type to wait for. Defaults to "load".
- * @return {Promise} resolved when the event is handled.
- */
-function promiseTabLoadEvent(aTab, aURL) {
- let browser = aTab.linkedBrowser;
-
- BrowserTestUtils.loadURI(browser, aURL);
- return BrowserTestUtils.browserLoaded(browser);
-}
-
-/**
- * Navigate back or forward in tab history and wait for it to finish.
- *
- * @param aDirection Number to indicate to move backward or forward in history.
- * @param aConditionFn Function that returns the result of an evaluated condition
- * that needs to be `true` to resolve the promise.
- * @return {Promise} resolved when navigation has finished.
- */
-function promiseTabHistoryNavigation(aDirection = -1, aConditionFn) {
- let deferred = Promise.defer();
-
- let timeoutId = setTimeout(() => {
- gBrowser.removeEventListener("pageshow", listener, true);
- deferred.reject("Pageshow did not happen within " + kTabEventFailureTimeoutInMs + "ms");
- }, kTabEventFailureTimeoutInMs);
-
- function listener(event) {
- gBrowser.removeEventListener("pageshow", listener, true);
- clearTimeout(timeoutId);
-
- if (aConditionFn) {
- waitForCondition(aConditionFn).then(() => deferred.resolve(),
- aReason => deferred.reject(aReason));
- } else {
- deferred.resolve();
- }
- }
- gBrowser.addEventListener("pageshow", listener, true);
-
- content.history.go(aDirection);
-
- return deferred.promise;
-}
-
-/**
- * Wait for an attribute on a node to change
- *
- * @param aNode Node on which the mutation is expected
- * @param aAttribute The attribute we're interested in
- * @param aFilterFn A function to check if the new value is what we want.
- * @return {Promise} resolved when the requisite mutation shows up.
- */
-function promiseAttributeMutation(aNode, aAttribute, aFilterFn) {
- return new Promise((resolve, reject) => {
- info("waiting for mutation of attribute '" + aAttribute + "'.");
- let obs = new MutationObserver((mutations) => {
- for (let mut of mutations) {
- let attr = mut.attributeName;
- let newValue = mut.target.getAttribute(attr);
- if (aFilterFn(newValue)) {
- ok(true, "mutation occurred: attribute '" + attr + "' changed to '" + newValue + "' from '" + mut.oldValue + "'.");
- obs.disconnect();
- resolve();
- } else {
- info("Ignoring mutation that produced value " + newValue + " because of filter.");
- }
- }
- });
- obs.observe(aNode, {attributeFilter: [aAttribute]});
- });
-}
-
-function popupShown(aPopup) {
- return promisePopupEvent(aPopup, "shown");
-}
-
-function popupHidden(aPopup) {
- return promisePopupEvent(aPopup, "hidden");
-}
-
-/**
- * Returns a Promise that resolves when aPopup fires an event of type
- * aEventType. Times out and rejects after 20 seconds.
- *
- * @param aPopup the popup to monitor for events.
- * @param aEventSuffix the _suffix_ for the popup event type to watch for.
- *
- * Example usage:
- * let popupShownPromise = promisePopupEvent(somePopup, "shown");
- * // ... something that opens a popup
- * yield popupShownPromise;
- *
- * let popupHiddenPromise = promisePopupEvent(somePopup, "hidden");
- * // ... something that hides a popup
- * yield popupHiddenPromise;
- */
-function promisePopupEvent(aPopup, aEventSuffix) {
- let deferred = Promise.defer();
- let eventType = "popup" + aEventSuffix;
-
- function onPopupEvent(e) {
- aPopup.removeEventListener(eventType, onPopupEvent);
- deferred.resolve();
- }
-
- aPopup.addEventListener(eventType, onPopupEvent);
- return deferred.promise;
-}
-
-// This is a simpler version of the context menu check that
-// exists in contextmenu_common.js.
-function checkContextMenu(aContextMenu, aExpectedEntries, aWindow=window) {
- let childNodes = [...aContextMenu.childNodes];
- // Ignore hidden nodes:
- childNodes = childNodes.filter((n) => !n.hidden);
-
- for (let i = 0; i < childNodes.length; i++) {
- let menuitem = childNodes[i];
- try {
- if (aExpectedEntries[i][0] == "---") {
- is(menuitem.localName, "menuseparator", "menuseparator expected");
- continue;
- }
-
- let selector = aExpectedEntries[i][0];
- ok(menuitem.matches(selector), "menuitem should match " + selector + " selector");
- let commandValue = menuitem.getAttribute("command");
- let relatedCommand = commandValue ? aWindow.document.getElementById(commandValue) : null;
- let menuItemDisabled = relatedCommand ?
- relatedCommand.getAttribute("disabled") == "true" :
- menuitem.getAttribute("disabled") == "true";
- is(menuItemDisabled, !aExpectedEntries[i][1], "disabled state for " + selector);
- } catch (e) {
- ok(false, "Exception when checking context menu: " + e);
- }
- }
-}
diff --git a/browser/components/customizableui/test/support/feeds_test_page.html b/browser/components/customizableui/test/support/feeds_test_page.html
deleted file mode 100644
index be78e4dff..000000000
--- a/browser/components/customizableui/test/support/feeds_test_page.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<head>
- <title>Feeds test page</title>
- <link rel="alternate" type="application/rss+xml" href="test-feed.xml" title="Test feed">
-</head>
-
-<body>
- This is a test page for feeds
-</body>
-</html>
diff --git a/browser/components/customizableui/test/support/test-feed.xml b/browser/components/customizableui/test/support/test-feed.xml
deleted file mode 100644
index 0e700b6d8..000000000
--- a/browser/components/customizableui/test/support/test-feed.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-
- <title>Example Feed</title>
- <link href="http://example.org/"/>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
- <id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
-
- <entry>
-
- <title>Item</title>
- <link href="http://example.org/first"/>
- <id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/customizableui/test/support/test_967000_charEncoding_page.html b/browser/components/customizableui/test/support/test_967000_charEncoding_page.html
deleted file mode 100644
index c8d35115c..000000000
--- a/browser/components/customizableui/test/support/test_967000_charEncoding_page.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>Test page</title>
- </head>
-
- <body>
- This is a test page
- </body>
-</html>
diff --git a/browser/components/dirprovider/tests/unit/.eslintrc.js b/browser/components/dirprovider/tests/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/dirprovider/tests/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/downloads/moz.build b/browser/components/downloads/moz.build
index 2b06a6465..241354619 100644
--- a/browser/components/downloads/moz.build
+++ b/browser/components/downloads/moz.build
@@ -4,12 +4,6 @@
# 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/.
-with Files('*'):
- BUG_COMPONENT = ('Firefox', 'Downloads Panel')
-
-XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
-BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
EXTRA_JS_MODULES += [
@@ -17,6 +11,3 @@ EXTRA_JS_MODULES += [
'DownloadsTaskbar.jsm',
'DownloadsViewUI.jsm',
]
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Downloads Panel')
diff --git a/browser/components/downloads/test/browser/.eslintrc.js b/browser/components/downloads/test/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/downloads/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/downloads/test/browser/browser.ini b/browser/components/downloads/test/browser/browser.ini
deleted file mode 100644
index 76f026c78..000000000
--- a/browser/components/downloads/test/browser/browser.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-[DEFAULT]
-support-files = head.js
-
-[browser_basic_functionality.js]
-[browser_first_download_panel.js]
-skip-if = os == "linux" # Bug 949434
-[browser_overflow_anchor.js]
-skip-if = os == "linux" # Bug 952422
-[browser_confirm_unblock_download.js]
-[browser_iframe_gone_mid_download.js]
-[browser_indicatorDrop.js]
-[browser_libraryDrop.js]
-[browser_downloads_panel_block.js]
-[browser_downloads_panel_footer.js]
-[browser_downloads_panel_height.js]
diff --git a/browser/components/downloads/test/browser/browser_basic_functionality.js b/browser/components/downloads/test/browser/browser_basic_functionality.js
deleted file mode 100644
index 564a344a7..000000000
--- a/browser/components/downloads/test/browser/browser_basic_functionality.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-registerCleanupFunction(function*() {
- yield task_resetState();
-});
-
-/**
- * Make sure the downloads panel can display items in the right order and
- * contains the expected data.
- */
-add_task(function* test_basic_functionality() {
- // Display one of each download state.
- const DownloadData = [
- { state: nsIDM.DOWNLOAD_NOTSTARTED },
- { state: nsIDM.DOWNLOAD_PAUSED },
- { state: nsIDM.DOWNLOAD_FINISHED },
- { state: nsIDM.DOWNLOAD_FAILED },
- { state: nsIDM.DOWNLOAD_CANCELED },
- ];
-
- // Wait for focus first
- yield promiseFocus();
-
- // Ensure that state is reset in case previous tests didn't finish.
- yield task_resetState();
-
- // For testing purposes, show all the download items at once.
- var originalCountLimit = DownloadsView.kItemCountLimit;
- DownloadsView.kItemCountLimit = DownloadData.length;
- registerCleanupFunction(function () {
- DownloadsView.kItemCountLimit = originalCountLimit;
- });
-
- // Populate the downloads database with the data required by this test.
- yield task_addDownloads(DownloadData);
-
- // Open the user interface and wait for data to be fully loaded.
- yield task_openPanel();
-
- // Test item data and count. This also tests the ordering of the display.
- let richlistbox = document.getElementById("downloadsListBox");
- /* disabled for failing intermittently (bug 767828)
- is(richlistbox.children.length, DownloadData.length,
- "There is the correct number of richlistitems");
- */
- let itemCount = richlistbox.children.length;
- for (let i = 0; i < itemCount; i++) {
- let element = richlistbox.children[itemCount - i - 1];
- let download = DownloadsView.itemForElement(element).download;
- is(DownloadsCommon.stateOfDownload(download), DownloadData[i].state,
- "Download states match up");
- }
-});
diff --git a/browser/components/downloads/test/browser/browser_confirm_unblock_download.js b/browser/components/downloads/test/browser/browser_confirm_unblock_download.js
deleted file mode 100644
index 8ba37ba64..000000000
--- a/browser/components/downloads/test/browser/browser_confirm_unblock_download.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Tests the dialog which allows the user to unblock a downloaded file.
-
-registerCleanupFunction(() => {});
-
-function* assertDialogResult({ args, buttonToClick, expectedResult }) {
- promiseAlertDialogOpen(buttonToClick);
- is(yield DownloadsCommon.confirmUnblockDownload(args), expectedResult);
-}
-
-/**
- * Tests the "unblock" dialog, for each of the possible verdicts.
- */
-add_task(function* test_unblock_dialog_unblock() {
- for (let verdict of [Downloads.Error.BLOCK_VERDICT_MALWARE,
- Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED,
- Downloads.Error.BLOCK_VERDICT_UNCOMMON]) {
- let args = { verdict, window, dialogType: "unblock" };
-
- // Test both buttons.
- yield assertDialogResult({
- args,
- buttonToClick: "accept",
- expectedResult: "unblock",
- });
- yield assertDialogResult({
- args,
- buttonToClick: "cancel",
- expectedResult: "cancel",
- });
- }
-});
-
-/**
- * Tests the "chooseUnblock" dialog for potentially unwanted downloads.
- */
-add_task(function* test_chooseUnblock_dialog() {
- let args = {
- verdict: Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED,
- window,
- dialogType: "chooseUnblock",
- };
-
- // Test each of the three buttons.
- yield assertDialogResult({
- args,
- buttonToClick: "accept",
- expectedResult: "unblock",
- });
- yield assertDialogResult({
- args,
- buttonToClick: "cancel",
- expectedResult: "cancel",
- });
- yield assertDialogResult({
- args,
- buttonToClick: "extra1",
- expectedResult: "confirmBlock",
- });
-});
-
-/**
- * Tests the "chooseOpen" dialog for uncommon downloads.
- */
-add_task(function* test_chooseOpen_dialog() {
- let args = {
- verdict: Downloads.Error.BLOCK_VERDICT_UNCOMMON,
- window,
- dialogType: "chooseOpen",
- };
-
- // Test each of the three buttons.
- yield assertDialogResult({
- args,
- buttonToClick: "accept",
- expectedResult: "open",
- });
- yield assertDialogResult({
- args,
- buttonToClick: "cancel",
- expectedResult: "cancel",
- });
- yield assertDialogResult({
- args,
- buttonToClick: "extra1",
- expectedResult: "confirmBlock",
- });
-});
diff --git a/browser/components/downloads/test/browser/browser_downloads_panel_block.js b/browser/components/downloads/test/browser/browser_downloads_panel_block.js
deleted file mode 100644
index 05056e842..000000000
--- a/browser/components/downloads/test/browser/browser_downloads_panel_block.js
+++ /dev/null
@@ -1,183 +0,0 @@
-"use strict";
-
-add_task(function* mainTest() {
- yield task_resetState();
-
- let verdicts = [
- Downloads.Error.BLOCK_VERDICT_UNCOMMON,
- Downloads.Error.BLOCK_VERDICT_MALWARE,
- Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED,
- ];
- yield task_addDownloads(verdicts.map(v => makeDownload(v)));
-
- // Check that the richlistitem for each download is correct.
- for (let i = 0; i < verdicts.length; i++) {
- yield openPanel();
-
- // The current item is always the first one in the listbox since each
- // iteration of this loop removes the item at the end.
- let item = DownloadsView.richListBox.firstChild;
-
- // Open the panel and click the item to show the subview.
- EventUtils.sendMouseEvent({ type: "click" }, item);
- yield promiseSubviewShown(true);
-
- // Items are listed in newest-to-oldest order, so e.g. the first item's
- // verdict is the last element in the verdicts array.
- Assert.ok(DownloadsBlockedSubview.subview.getAttribute("verdict"),
- verdicts[verdicts.count - i - 1]);
-
- // Click the sliver of the main view that's still showing on the left to go
- // back to it.
- EventUtils.synthesizeMouse(DownloadsPanel.panel, 10, 10, {}, window);
- yield promiseSubviewShown(false);
-
- // Show the subview again.
- EventUtils.sendMouseEvent({ type: "click" }, item);
- yield promiseSubviewShown(true);
-
- // Click the Open button. The download should be unblocked and then opened,
- // i.e., unblockAndOpenDownload() should be called on the item. The panel
- // should also be closed as a result, so wait for that too.
- let unblockOpenPromise = promiseUnblockAndOpenDownloadCalled(item);
- let hidePromise = promisePanelHidden();
- EventUtils.synthesizeMouse(DownloadsBlockedSubview.elements.openButton,
- 10, 10, {}, window);
- yield unblockOpenPromise;
- yield hidePromise;
-
- window.focus();
- yield SimpleTest.promiseFocus(window);
-
- // Reopen the panel and show the subview again.
- yield openPanel();
-
- EventUtils.sendMouseEvent({ type: "click" }, item);
- yield promiseSubviewShown(true);
-
- // Click the Remove button. The panel should close and the item should be
- // removed from it.
- EventUtils.synthesizeMouse(DownloadsBlockedSubview.elements.deleteButton,
- 10, 10, {}, window);
- yield promisePanelHidden();
- yield openPanel();
-
- Assert.ok(!item.parentNode);
- DownloadsPanel.hidePanel();
- yield promisePanelHidden();
- }
-
- yield task_resetState();
-});
-
-function* openPanel() {
- // This function is insane but something intermittently causes the panel to be
- // closed as soon as it's opening on Linux ASAN. Maybe it would also happen
- // on other build machines if the test ran often enough. Not only is the
- // panel closed, it's closed while it's opening, leaving DownloadsPanel._state
- // such that when you try to open the panel again, it thinks it's already
- // open, but it's not. The result is that the test times out.
- //
- // What this does is call DownloadsPanel.showPanel over and over again until
- // the panel is really open. There are a few wrinkles:
- //
- // (1) When panel.state is "open", check four more times (for a total of five)
- // before returning to make the panel stays open.
- // (2) If the panel is not open, check the _state. It should be either
- // kStateUninitialized or kStateHidden. If it's not, then the panel is in the
- // process of opening -- or maybe it's stuck in that process -- so reset the
- // _state to kStateHidden.
- // (3) If the _state is not kStateUninitialized or kStateHidden, then it may
- // actually be properly opening and not stuck at all. To avoid always closing
- // the panel while it's properly opening, use an exponential backoff mechanism
- // for retries.
- //
- // If all that fails, then the test will time out, but it would have timed out
- // anyway.
-
- yield promiseFocus();
- yield new Promise(resolve => {
- let verifyCount = 5;
- let backoff = 0;
- let iBackoff = 0;
- let interval = setInterval(() => {
- if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
- if (verifyCount > 0) {
- verifyCount--;
- } else {
- clearInterval(interval);
- resolve();
- }
- } else {
- if (iBackoff < backoff) {
- // Keep backing off before trying again.
- iBackoff++;
- } else {
- // Try (or retry) opening the panel.
- verifyCount = 5;
- backoff = Math.max(1, 2 * backoff);
- iBackoff = 0;
- if (DownloadsPanel._state != DownloadsPanel.kStateUninitialized) {
- DownloadsPanel._state = DownloadsPanel.kStateHidden;
- }
- DownloadsPanel.showPanel();
- }
- }
- }, 100);
- });
-}
-
-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);
- setTimeout(resolve, 0);
- });
- });
-}
-
-function makeDownload(verdict) {
- return {
- state: nsIDM.DOWNLOAD_DIRTY,
- hasBlockedData: true,
- errorObj: {
- result: Components.results.NS_ERROR_FAILURE,
- message: "Download blocked.",
- becauseBlocked: true,
- becauseBlockedByReputationCheck: true,
- reputationCheckVerdict: verdict,
- },
- };
-}
-
-function promiseSubviewShown(shown) {
- // More terribleness, but I'm tired of fighting intermittent timeouts on try.
- // Just poll for the subview and wait a second before resolving the promise.
- return new Promise(resolve => {
- let interval = setInterval(() => {
- if (shown == DownloadsBlockedSubview.view.showingSubView &&
- !DownloadsBlockedSubview.view._transitioning) {
- clearInterval(interval);
- setTimeout(resolve, 1000);
- return;
- }
- }, 0);
- });
-}
-
-function promiseUnblockAndOpenDownloadCalled(item) {
- return new Promise(resolve => {
- let realFn = item._shell.unblockAndOpenDownload;
- item._shell.unblockAndOpenDownload = () => {
- item._shell.unblockAndOpenDownload = realFn;
- resolve();
- // unblockAndOpenDownload returns a promise (that's resolved when the file
- // is opened).
- return Promise.resolve();
- };
- });
-}
diff --git a/browser/components/downloads/test/browser/browser_downloads_panel_footer.js b/browser/components/downloads/test/browser/browser_downloads_panel_footer.js
deleted file mode 100644
index 4083dde98..000000000
--- a/browser/components/downloads/test/browser/browser_downloads_panel_footer.js
+++ /dev/null
@@ -1,95 +0,0 @@
-"use strict";
-
-function *task_openDownloadsSubPanel() {
- let downloadSubPanel = document.getElementById("downloadSubPanel");
- let popupShownPromise = BrowserTestUtils.waitForEvent(downloadSubPanel, "popupshown");
-
- let downloadsDropmarker = document.getElementById("downloadsFooterDropmarker");
- EventUtils.synthesizeMouseAtCenter(downloadsDropmarker, {}, window);
-
- yield popupShownPromise;
-}
-
-add_task(function* test_openDownloadsFolder() {
- yield SpecialPowers.pushPrefEnv({"set": [["browser.download.showPanelDropmarker", true]]});
- yield task_openPanel();
-
- yield task_openDownloadsSubPanel();
-
- yield new Promise(resolve => {
- sinon.stub(DownloadsCommon, "showDirectory", file => {
- resolve(Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
- is(file.path, downloadsPath, "Check the download folder path.");
- }));
- });
-
- let itemOpenDownloadsFolder =
- document.getElementById("downloadsDropdownItemOpenDownloadsFolder");
- EventUtils.synthesizeMouseAtCenter(itemOpenDownloadsFolder, {}, window);
- });
-
- yield task_resetState();
-});
-
-add_task(function* test_clearList() {
- const kTestCases = [{
- downloads: [
- { state: nsIDM.DOWNLOAD_NOTSTARTED },
- { state: nsIDM.DOWNLOAD_FINISHED },
- { state: nsIDM.DOWNLOAD_FAILED },
- { state: nsIDM.DOWNLOAD_CANCELED },
- ],
- expectClearListShown: true,
- expectedItemNumber: 0,
- },{
- downloads: [
- { state: nsIDM.DOWNLOAD_NOTSTARTED },
- { state: nsIDM.DOWNLOAD_FINISHED },
- { state: nsIDM.DOWNLOAD_FAILED },
- { state: nsIDM.DOWNLOAD_PAUSED },
- { state: nsIDM.DOWNLOAD_CANCELED },
- ],
- expectClearListShown: true,
- expectedItemNumber: 1,
- },{
- downloads: [
- { state: nsIDM.DOWNLOAD_PAUSED },
- ],
- expectClearListShown: false,
- expectedItemNumber: 1,
- }];
-
- for (let testCase of kTestCases) {
- yield verify_clearList(testCase);
- }
-});
-
-function *verify_clearList(testCase) {
- let downloads = testCase.downloads;
- yield task_addDownloads(downloads);
-
- yield task_openPanel();
- is(DownloadsView._downloads.length, downloads.length,
- "Expect the number of download items");
-
- yield task_openDownloadsSubPanel();
-
- let itemClearList = document.getElementById("downloadsDropdownItemClearList");
- let itemNumberPromise = BrowserTestUtils.waitForCondition(() => {
- return DownloadsView._downloads.length === testCase.expectedItemNumber;
- });
- if (testCase.expectClearListShown) {
- isnot("true", itemClearList.getAttribute("hidden"),
- "Should show Clear Preview Panel button");
- EventUtils.synthesizeMouseAtCenter(itemClearList, {}, window);
- } else {
- is("true", itemClearList.getAttribute("hidden"),
- "Should not show Clear Preview Panel button");
- }
-
- yield itemNumberPromise;
- is(DownloadsView._downloads.length, testCase.expectedItemNumber,
- "Download items remained.");
-
- yield task_resetState();
-}
diff --git a/browser/components/downloads/test/browser/browser_downloads_panel_height.js b/browser/components/downloads/test/browser/browser_downloads_panel_height.js
deleted file mode 100644
index 1638e4f0e..000000000
--- a/browser/components/downloads/test/browser/browser_downloads_panel_height.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * This test exists because we use a <panelmultiview> element and it handles
- * some of the height changes for us. We need to verify that the height is
- * updated correctly if downloads are removed while the panel is hidden.
- */
-add_task(function* test_height_reduced_after_removal() {
- yield task_addDownloads([
- { state: nsIDM.DOWNLOAD_FINISHED },
- ]);
-
- yield task_openPanel();
- let panel = document.getElementById("downloadsPanel");
- let heightBeforeRemoval = panel.getBoundingClientRect().height;
-
- // We want to close the panel before we remove the download from the list.
- DownloadsPanel.hidePanel();
- yield task_resetState();
-
- yield task_openPanel();
- let heightAfterRemoval = panel.getBoundingClientRect().height;
- Assert.greater(heightBeforeRemoval, heightAfterRemoval);
-
- yield task_resetState();
-});
diff --git a/browser/components/downloads/test/browser/browser_first_download_panel.js b/browser/components/downloads/test/browser/browser_first_download_panel.js
deleted file mode 100644
index 2cd871360..000000000
--- a/browser/components/downloads/test/browser/browser_first_download_panel.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Make sure the downloads panel only opens automatically on the first
- * download it notices. All subsequent downloads, even across sessions, should
- * not open the panel automatically.
- */
-add_task(function* test_first_download_panel() {
- // Clear the download panel has shown preference first as this test is used to
- // verify this preference's behaviour.
- let oldPrefValue = Services.prefs.getBoolPref("browser.download.panel.shown");
- Services.prefs.setBoolPref("browser.download.panel.shown", false);
-
- registerCleanupFunction(function*() {
- // Clean up when the test finishes.
- yield task_resetState();
-
- // Set the preference instead of clearing it afterwards to ensure the
- // right value is used no matter what the default was. This ensures the
- // panel doesn't appear and affect other tests.
- Services.prefs.setBoolPref("browser.download.panel.shown", oldPrefValue);
- });
-
- // Ensure that state is reset in case previous tests didn't finish.
- yield task_resetState();
-
- // With this set to false, we should automatically open the panel the first
- // time a download is started.
- DownloadsCommon.getData(window).panelHasShownBefore = false;
-
- let promise = promisePanelOpened();
- DownloadsCommon.getData(window)._notifyDownloadEvent("start");
- yield promise;
-
- // If we got here, that means the panel opened.
- DownloadsPanel.hidePanel();
-
- ok(DownloadsCommon.getData(window).panelHasShownBefore,
- "Should have recorded that the panel was opened on a download.")
-
- // Next, make sure that if we start another download, we don't open the
- // panel automatically.
- let originalOnPopupShown = DownloadsPanel.onPopupShown;
- DownloadsPanel.onPopupShown = function () {
- originalOnPopupShown.apply(this, arguments);
- ok(false, "Should not have opened the downloads panel.");
- };
-
- DownloadsCommon.getData(window)._notifyDownloadEvent("start");
-
- // Wait 2 seconds to ensure that the panel does not open.
- yield new Promise(resolve => setTimeout(resolve, 2000));
- DownloadsPanel.onPopupShown = originalOnPopupShown;
-});
diff --git a/browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js b/browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js
deleted file mode 100644
index ebdd4f9af..000000000
--- a/browser/components/downloads/test/browser/browser_iframe_gone_mid_download.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite";
-
-function test_deleted_iframe(perSitePref, windowOptions={}) {
- return function*() {
- Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, perSitePref);
- let {DownloadLastDir} = Cu.import("resource://gre/modules/DownloadLastDir.jsm", {});
-
- let win = yield promiseOpenAndLoadWindow(windowOptions);
- let tab = win.gBrowser.addTab();
- yield promiseTabLoadEvent(tab, "about:mozilla");
-
- let doc = tab.linkedBrowser.contentDocument;
- let iframe = doc.createElement("iframe");
- doc.body.appendChild(iframe);
-
- ok(iframe.contentWindow, "iframe should have a window");
- let gDownloadLastDir = new DownloadLastDir(iframe.contentWindow);
- let cw = iframe.contentWindow;
- let promiseIframeWindowGone = new Promise((resolve, reject) => {
- Services.obs.addObserver(function obs(subject, topic) {
- if (subject == cw) {
- Services.obs.removeObserver(obs, topic);
- resolve();
- }
- }, "dom-window-destroyed", false);
- });
- iframe.remove();
- yield promiseIframeWindowGone;
- cw = null;
- ok(!iframe.contentWindow, "Managed to destroy iframe");
-
- let someDir = "blah";
- try {
- someDir = yield new Promise((resolve, reject) => {
- gDownloadLastDir.getFileAsync("http://www.mozilla.org/", function(dir) {
- resolve(dir);
- });
- });
- } catch (ex) {
- ok(false, "Got an exception trying to get the directory where things should be saved.");
- Cu.reportError(ex);
- }
- // NB: someDir can legitimately be null here when set, hence the 'blah' workaround:
- isnot(someDir, "blah", "Should get a file even after the window was destroyed.");
-
- try {
- gDownloadLastDir.setFile("http://www.mozilla.org/", null);
- } catch (ex) {
- ok(false, "Got an exception trying to set the directory where things should be saved.");
- Cu.reportError(ex);
- }
-
- yield promiseWindowClosed(win);
- Services.prefs.clearUserPref(SAVE_PER_SITE_PREF);
- };
-}
-
-add_task(test_deleted_iframe(false));
-add_task(test_deleted_iframe(false));
-add_task(test_deleted_iframe(true, {private: true}));
-add_task(test_deleted_iframe(true, {private: true}));
-
diff --git a/browser/components/downloads/test/browser/browser_indicatorDrop.js b/browser/components/downloads/test/browser/browser_indicatorDrop.js
deleted file mode 100644
index 368d85ccf..000000000
--- a/browser/components/downloads/test/browser/browser_indicatorDrop.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
- "resource://testing-common/httpd.js");
-
-registerCleanupFunction(function*() {
- yield task_resetState();
- yield task_clearHistory();
-});
-
-add_task(function* test_indicatorDrop() {
- let downloadButton = document.getElementById("downloads-button");
- ok(downloadButton, "download button present");
-
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- function* task_drop(urls) {
- let dragData = [[{type: "text/plain", data: urls.join("\n")}]];
-
- let list = yield Downloads.getList(Downloads.ALL);
-
- let added = new Set();
- let succeeded = new Set();
- yield new Promise(function(resolve) {
- let view = {
- onDownloadAdded: function(download) {
- added.add(download.source.url);
- },
- onDownloadChanged: function(download) {
- if (!added.has(download.source.url))
- return;
- if (!download.succeeded)
- return;
- succeeded.add(download.source.url);
- if (succeeded.size == urls.length) {
- list.removeView(view).then(resolve);
- }
- }
- };
- list.addView(view).then(function() {
- EventUtils.synthesizeDrop(downloadButton, downloadButton, dragData, "link", window);
- });
- });
-
- for (let url of urls) {
- ok(added.has(url), url + " is added to download");
- }
- }
-
- // Ensure that state is reset in case previous tests didn't finish.
- yield task_resetState();
-
- yield setDownloadDir();
-
- startServer();
-
- yield* task_drop([httpUrl("file1.txt")]);
- yield* task_drop([httpUrl("file1.txt"),
- httpUrl("file2.txt"),
- httpUrl("file3.txt")]);
-});
diff --git a/browser/components/downloads/test/browser/browser_libraryDrop.js b/browser/components/downloads/test/browser/browser_libraryDrop.js
deleted file mode 100644
index fa7df8a87..000000000
--- a/browser/components/downloads/test/browser/browser_libraryDrop.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
- "resource://testing-common/httpd.js");
-
-registerCleanupFunction(function*() {
- yield task_resetState();
- yield task_clearHistory();
-});
-
-add_task(function* test_indicatorDrop() {
- let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- let EventUtils = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
- function task_drop(win, urls) {
- let dragData = [[{type: "text/plain", data: urls.join("\n")}]];
-
- let listBox = win.document.getElementById("downloadsRichListBox");
- ok(listBox, "download list box present");
-
- let list = yield Downloads.getList(Downloads.ALL);
-
- let added = new Set();
- let succeeded = new Set();
- yield new Promise(function(resolve) {
- let view = {
- onDownloadAdded: function(download) {
- added.add(download.source.url);
- },
- onDownloadChanged: function(download) {
- if (!added.has(download.source.url))
- return;
- if (!download.succeeded)
- return;
- succeeded.add(download.source.url);
- if (succeeded.size == urls.length) {
- list.removeView(view).then(resolve);
- }
- }
- };
- list.addView(view).then(function() {
- EventUtils.synthesizeDrop(listBox, listBox, dragData, "link", win);
- });
- });
-
- for (let url of urls) {
- ok(added.has(url), url + " is added to download");
- }
- }
-
- // Ensure that state is reset in case previous tests didn't finish.
- yield task_resetState();
-
- setDownloadDir();
-
- startServer();
-
- let win = yield openLibrary("Downloads");
- registerCleanupFunction(function() {
- win.close();
- });
-
- yield* task_drop(win, [httpUrl("file1.txt")]);
- yield* task_drop(win, [httpUrl("file1.txt"),
- httpUrl("file2.txt"),
- httpUrl("file3.txt")]);
-});
diff --git a/browser/components/downloads/test/browser/browser_overflow_anchor.js b/browser/components/downloads/test/browser/browser_overflow_anchor.js
deleted file mode 100644
index a293a81cf..000000000
--- a/browser/components/downloads/test/browser/browser_overflow_anchor.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-registerCleanupFunction(function*() {
- // Clean up when the test finishes.
- yield task_resetState();
-});
-
-/**
- * Make sure the downloads button and indicator overflows into the nav-bar
- * chevron properly, and then when those buttons are clicked in the overflow
- * panel that the downloads panel anchors to the chevron.
- */
-add_task(function* test_overflow_anchor() {
- // Ensure that state is reset in case previous tests didn't finish.
- yield task_resetState();
-
- // Record the original width of the window so we can put it back when
- // this test finishes.
- let oldWidth = window.outerWidth;
-
- // The downloads button should not be overflowed to begin with.
- let button = CustomizableUI.getWidget("downloads-button")
- .forWindow(window);
- ok(!button.overflowed, "Downloads button should not be overflowed.");
-
- // Hack - we lock the size of the default flex-y items in the nav-bar,
- // namely, the URL and search inputs. That way we can resize the
- // window without worrying about them flexing.
- const kFlexyItems = ["urlbar-container", "search-container"];
- registerCleanupFunction(() => unlockWidth(kFlexyItems));
- lockWidth(kFlexyItems);
-
- // Resize the window to half of its original size. That should
- // be enough to overflow the downloads button.
- window.resizeTo(oldWidth / 2, window.outerHeight);
- yield waitForOverflowed(button, true);
-
- let promise = promisePanelOpened();
- button.node.doCommand();
- yield promise;
-
- let panel = DownloadsPanel.panel;
- let chevron = document.getElementById("nav-bar-overflow-button");
- is(panel.anchorNode, chevron, "Panel should be anchored to the chevron.");
-
- DownloadsPanel.hidePanel();
-
- // Unlock the widths on the flex-y items.
- unlockWidth(kFlexyItems);
-
- // Put the window back to its original dimensions.
- window.resizeTo(oldWidth, window.outerHeight);
-
- // The downloads button should eventually be un-overflowed.
- yield waitForOverflowed(button, false);
-
- // Now try opening the panel again.
- promise = promisePanelOpened();
- button.node.doCommand();
- yield promise;
-
- is(panel.anchorNode.id, "downloads-indicator-anchor");
-
- DownloadsPanel.hidePanel();
-});
-
-/**
- * For some node IDs, finds the nodes and sets their min-width's to their
- * current width, preventing them from flex-shrinking.
- *
- * @param aItemIDs an array of item IDs to set min-width on.
- */
-function lockWidth(aItemIDs) {
- for (let itemID of aItemIDs) {
- let item = document.getElementById(itemID);
- let curWidth = item.getBoundingClientRect().width + "px";
- item.style.minWidth = curWidth;
- }
-}
-
-/**
- * Clears the min-width's set on a set of IDs by lockWidth.
- *
- * @param aItemIDs an array of ItemIDs to remove min-width on.
- */
-function unlockWidth(aItemIDs) {
- for (let itemID of aItemIDs) {
- let item = document.getElementById(itemID);
- item.style.minWidth = "";
- }
-}
-
-/**
- * Waits for a node to enter or exit the overflowed state.
- *
- * @param aItem the node to wait for.
- * @param aIsOverflowed if we're waiting for the item to be overflowed.
- */
-function waitForOverflowed(aItem, aIsOverflowed) {
- let deferOverflow = Promise.defer();
- if (aItem.overflowed == aIsOverflowed) {
- return deferOverflow.resolve();
- }
-
- let observer = new MutationObserver(function(aMutations) {
- if (aItem.overflowed == aIsOverflowed) {
- observer.disconnect();
- deferOverflow.resolve();
- }
- });
- observer.observe(aItem.node, {attributes: true});
-
- return deferOverflow.promise;
-}
diff --git a/browser/components/downloads/test/browser/head.js b/browser/components/downloads/test/browser/head.js
deleted file mode 100644
index bcf703eb6..000000000
--- a/browser/components/downloads/test/browser/head.js
+++ /dev/null
@@ -1,300 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Provides infrastructure for automated download components tests.
- */
-
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
- "resource://gre/modules/Downloads.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
- "resource:///modules/DownloadsCommon.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-const nsIDM = Ci.nsIDownloadManager;
-
-var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
-gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-
-// Load mocking/stubbing library, sinon
-// docs: http://sinonjs.org/docs/
-Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
-
-registerCleanupFunction(function () {
- gTestTargetFile.remove(false);
-
- delete window.sinon;
- delete window.setImmediate;
- delete window.clearImmediate;
-});
-
-////////////////////////////////////////////////////////////////////////////////
-//// Asynchronous support subroutines
-
-function promiseOpenAndLoadWindow(aOptions)
-{
- return new Promise((resolve, reject) => {
- let win = OpenBrowserWindow(aOptions);
- win.addEventListener("load", function onLoad() {
- win.removeEventListener("load", onLoad);
- resolve(win);
- });
- });
-}
-
-/**
- * Waits for a load (or custom) event to finish in a given tab. If provided
- * load an uri into the tab.
- *
- * @param tab
- * The tab to load into.
- * @param [optional] url
- * The url to load, or the current url.
- * @param [optional] event
- * The load event type to wait for. Defaults to "load".
- * @return {Promise} resolved when the event is handled.
- * @resolves to the received event
- * @rejects if a valid load event is not received within a meaningful interval
- */
-function promiseTabLoadEvent(tab, url, eventType="load")
-{
- let deferred = Promise.defer();
- info("Wait tab event: " + eventType);
-
- function handle(event) {
- if (event.originalTarget != tab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank" ||
- (url && event.target.location.href != url)) {
- info("Skipping spurious '" + eventType + "'' event" +
- " for " + event.target.location.href);
- return;
- }
- // Remove reference to tab from the cleanup function:
- realCleanup = () => {};
- tab.linkedBrowser.removeEventListener(eventType, handle, true);
- info("Tab event received: " + eventType);
- deferred.resolve(event);
- }
-
- // Juggle a bit to avoid leaks:
- let realCleanup = () => tab.linkedBrowser.removeEventListener(eventType, handle, true);
- registerCleanupFunction(() => realCleanup());
-
- tab.linkedBrowser.addEventListener(eventType, handle, true, true);
- if (url)
- tab.linkedBrowser.loadURI(url);
- return deferred.promise;
-}
-
-function promiseWindowClosed(win)
-{
- let promise = new Promise((resolve, reject) => {
- Services.obs.addObserver(function obs(subject, topic) {
- if (subject == win) {
- Services.obs.removeObserver(obs, topic);
- resolve();
- }
- }, "domwindowclosed", false);
- });
- win.close();
- return promise;
-}
-
-
-function promiseFocus()
-{
- let deferred = Promise.defer();
- waitForFocus(deferred.resolve);
- return deferred.promise;
-}
-
-function promisePanelOpened()
-{
- let deferred = Promise.defer();
-
- if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
- return deferred.resolve();
- }
-
- // Hook to wait until the panel is shown.
- let originalOnPopupShown = DownloadsPanel.onPopupShown;
- DownloadsPanel.onPopupShown = function () {
- DownloadsPanel.onPopupShown = originalOnPopupShown;
- originalOnPopupShown.apply(this, arguments);
-
- // Defer to the next tick of the event loop so that we don't continue
- // processing during the DOM event handler itself.
- setTimeout(deferred.resolve, 0);
- };
-
- return deferred.promise;
-}
-
-function* task_resetState()
-{
- // Remove all downloads.
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
- let downloads = yield publicList.getAll();
- for (let download of downloads) {
- publicList.remove(download);
- yield download.finalize(true);
- }
-
- DownloadsPanel.hidePanel();
-
- yield promiseFocus();
-}
-
-function* task_addDownloads(aItems)
-{
- let startTimeMs = Date.now();
-
- let publicList = yield Downloads.getList(Downloads.PUBLIC);
- for (let item of aItems) {
- let download = {
- source: {
- url: "http://www.example.com/test-download.txt",
- },
- target: {
- path: gTestTargetFile.path,
- },
- succeeded: item.state == nsIDM.DOWNLOAD_FINISHED,
- canceled: item.state == nsIDM.DOWNLOAD_CANCELED ||
- item.state == nsIDM.DOWNLOAD_PAUSED,
- error: item.state == nsIDM.DOWNLOAD_FAILED ? new Error("Failed.") : null,
- hasPartialData: item.state == nsIDM.DOWNLOAD_PAUSED,
- hasBlockedData: item.hasBlockedData || false,
- startTime: new Date(startTimeMs++),
- };
- // `"errorObj" in download` must be false when there's no error.
- if (item.errorObj) {
- download.errorObj = item.errorObj;
- }
- yield publicList.add(yield Downloads.createDownload(download));
- }
-}
-
-function* task_openPanel()
-{
- yield promiseFocus();
-
- let promise = promisePanelOpened();
- DownloadsPanel.showPanel();
- yield promise;
-}
-
-function* setDownloadDir() {
- let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
- tmpDir.append("testsavedir");
- if (!tmpDir.exists()) {
- tmpDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
- registerCleanupFunction(function () {
- try {
- tmpDir.remove(true);
- } catch (e) {
- // On Windows debug build this may fail.
- }
- });
- }
-
- yield new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": [
- ["browser.download.folderList", 2],
- ["browser.download.dir", tmpDir, Ci.nsIFile],
- ]}, resolve);
- });
-}
-
-
-let gHttpServer = null;
-function startServer() {
- gHttpServer = new HttpServer();
- gHttpServer.start(-1);
- registerCleanupFunction(function*() {
- yield new Promise(function(resolve) {
- gHttpServer.stop(resolve);
- });
- });
-
- gHttpServer.registerPathHandler("/file1.txt", (request, response) => {
- response.setStatusLine(null, 200, "OK");
- response.write("file1");
- response.processAsync();
- response.finish();
- });
- gHttpServer.registerPathHandler("/file2.txt", (request, response) => {
- response.setStatusLine(null, 200, "OK");
- response.write("file2");
- response.processAsync();
- response.finish();
- });
- gHttpServer.registerPathHandler("/file3.txt", (request, response) => {
- response.setStatusLine(null, 200, "OK");
- response.write("file3");
- response.processAsync();
- response.finish();
- });
-}
-
-function httpUrl(aFileName) {
- return "http://localhost:" + gHttpServer.identity.primaryPort + "/" +
- aFileName;
-}
-
-function task_clearHistory() {
- return new Promise(function(resolve) {
- Services.obs.addObserver(function observeCH(aSubject, aTopic, aData) {
- Services.obs.removeObserver(observeCH, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
- resolve();
- }, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
- PlacesUtils.history.clear();
- });
-}
-
-function openLibrary(aLeftPaneRoot) {
- let library = window.openDialog("chrome://browser/content/places/places.xul",
- "", "chrome,toolbar=yes,dialog=no,resizable",
- aLeftPaneRoot);
-
- return new Promise(resolve => {
- waitForFocus(resolve, library);
- });
-}
-
-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);
- 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();
- }
- });
- }
- });
- });
-}
diff --git a/browser/components/downloads/test/unit/.eslintrc.js b/browser/components/downloads/test/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/downloads/test/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/downloads/test/unit/head.js b/browser/components/downloads/test/unit/head.js
deleted file mode 100644
index d7ce4d48a..000000000
--- a/browser/components/downloads/test/unit/head.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Provides infrastructure for automated download components tests.
- */
-
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-var Cr = Components.results;
-
-Cu.import("resource:///modules/DownloadsCommon.jsm");
diff --git a/browser/components/downloads/test/unit/test_DownloadsCommon.js b/browser/components/downloads/test/unit/test_DownloadsCommon.js
deleted file mode 100644
index 46afbaef9..000000000
--- a/browser/components/downloads/test/unit/test_DownloadsCommon.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests for the functions located directly in the "DownloadsCommon" object.
- */
-
-function testFormatTimeLeft(aSeconds, aExpectedValue, aExpectedUnitString)
-{
- let expected = "";
- if (aExpectedValue) {
- // Format the expected result based on the current language.
- expected = DownloadsCommon.strings[aExpectedUnitString](aExpectedValue);
- }
- do_check_eq(DownloadsCommon.formatTimeLeft(aSeconds), expected);
-}
-
-function run_test()
-{
- testFormatTimeLeft( 0, "", "");
- testFormatTimeLeft( 1, "1", "shortTimeLeftSeconds");
- testFormatTimeLeft( 29, "29", "shortTimeLeftSeconds");
- testFormatTimeLeft( 30, "30", "shortTimeLeftSeconds");
- testFormatTimeLeft( 31, "1", "shortTimeLeftMinutes");
- testFormatTimeLeft( 60, "1", "shortTimeLeftMinutes");
- testFormatTimeLeft( 89, "1", "shortTimeLeftMinutes");
- testFormatTimeLeft( 90, "2", "shortTimeLeftMinutes");
- testFormatTimeLeft( 91, "2", "shortTimeLeftMinutes");
- testFormatTimeLeft( 3600, "1", "shortTimeLeftHours");
- testFormatTimeLeft( 86400, "24", "shortTimeLeftHours");
- testFormatTimeLeft( 169200, "47", "shortTimeLeftHours");
- testFormatTimeLeft( 172800, "2", "shortTimeLeftDays");
- testFormatTimeLeft(8553600, "99", "shortTimeLeftDays");
- testFormatTimeLeft(8640000, "99", "shortTimeLeftDays");
-}
diff --git a/browser/components/downloads/test/unit/xpcshell.ini b/browser/components/downloads/test/unit/xpcshell.ini
deleted file mode 100644
index f53a8cf89..000000000
--- a/browser/components/downloads/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-[test_DownloadsCommon.js]
diff --git a/browser/components/extensions/moz.build b/browser/components/extensions/moz.build
index 5b3654c3a..116e90415 100644
--- a/browser/components/extensions/moz.build
+++ b/browser/components/extensions/moz.build
@@ -12,6 +12,3 @@ EXTRA_COMPONENTS += [
DIRS += ['schemas']
-BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
-MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
-XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
diff --git a/browser/components/extensions/test/browser/.eslintrc.js b/browser/components/extensions/test/browser/.eslintrc.js
deleted file mode 100644
index 0e673ecb9..000000000
--- a/browser/components/extensions/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,36 +0,0 @@
-"use strict";
-
-module.exports = { // eslint-disable-line no-undef
- "extends": "../../../../../testing/mochitest/browser.eslintrc.js",
-
- "env": {
- "webextensions": true,
- },
-
- "globals": {
- "NetUtil": true,
- "XPCOMUtils": true,
- "Task": true,
-
- // Browser window globals.
- "PanelUI": false,
-
- // Test harness globals
- "ExtensionTestUtils": false,
- "TestUtils": false,
-
- "clickBrowserAction": true,
- "clickPageAction": true,
- "closeContextMenu": true,
- "closeExtensionContextMenu": true,
- "focusWindow": true,
- "makeWidgetId": true,
- "openContextMenu": true,
- "openExtensionContextMenu": true,
- "CustomizableUI": true,
- },
-
- "rules": {
- "no-shadow": 0,
- },
-};
diff --git a/browser/components/extensions/test/browser/browser.ini b/browser/components/extensions/test/browser/browser.ini
deleted file mode 100644
index 1e894dcb5..000000000
--- a/browser/components/extensions/test/browser/browser.ini
+++ /dev/null
@@ -1,115 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
- head_pageAction.js
- head_sessions.js
- context.html
- ctxmenu-image.png
- context_tabs_onUpdated_page.html
- context_tabs_onUpdated_iframe.html
- file_popup_api_injection_a.html
- file_popup_api_injection_b.html
- file_iframe_document.html
- file_iframe_document.sjs
- file_bypass_cache.sjs
- file_language_fr_en.html
- file_language_ja.html
- file_language_tlh.html
- file_dummy.html
- searchSuggestionEngine.xml
- searchSuggestionEngine.sjs
- ../../../../../toolkit/components/extensions/test/mochitest/head_webrequest.js
-tags = webextensions
-
-
-[browser_ext_browserAction_context.js]
-[browser_ext_browserAction_disabled.js]
-[browser_ext_browserAction_pageAction_icon.js]
-[browser_ext_browserAction_pageAction_icon_permissions.js]
-[browser_ext_browserAction_popup.js]
-[browser_ext_browserAction_popup_resize.js]
-[browser_ext_browserAction_simple.js]
-[browser_ext_commands_execute_browser_action.js]
-[browser_ext_commands_execute_page_action.js]
-[browser_ext_commands_getAll.js]
-[browser_ext_commands_onCommand.js]
-[browser_ext_contentscript_connect.js]
-[browser_ext_contextMenus.js]
-[browser_ext_contextMenus_checkboxes.js]
-[browser_ext_contextMenus_icons.js]
-[browser_ext_contextMenus_onclick.js]
-[browser_ext_contextMenus_radioGroups.js]
-[browser_ext_contextMenus_uninstall.js]
-[browser_ext_contextMenus_urlPatterns.js]
-[browser_ext_currentWindow.js]
-[browser_ext_getViews.js]
-[browser_ext_incognito_popup.js]
-[browser_ext_incognito_views.js]
-[browser_ext_lastError.js]
-[browser_ext_legacy_extension_context_contentscript.js]
-[browser_ext_omnibox.js]
-[browser_ext_optionsPage_privileges.js]
-[browser_ext_pageAction_context.js]
-[browser_ext_pageAction_popup.js]
-[browser_ext_pageAction_popup_resize.js]
-[browser_ext_pageAction_simple.js]
-[browser_ext_pageAction_title.js]
-[browser_ext_popup_api_injection.js]
-[browser_ext_popup_background.js]
-[browser_ext_popup_corners.js]
-[browser_ext_popup_sendMessage.js]
-[browser_ext_popup_shutdown.js]
-[browser_ext_runtime_openOptionsPage.js]
-[browser_ext_runtime_openOptionsPage_uninstall.js]
-[browser_ext_runtime_setUninstallURL.js]
-[browser_ext_sessions_getRecentlyClosed.js]
-[browser_ext_sessions_getRecentlyClosed_private.js]
-[browser_ext_sessions_getRecentlyClosed_tabs.js]
-[browser_ext_sessions_restore.js]
-[browser_ext_simple.js]
-[browser_ext_tab_runtimeConnect.js]
-[browser_ext_tabs_audio.js]
-[browser_ext_tabs_captureVisibleTab.js]
-[browser_ext_tabs_create.js]
-[browser_ext_tabs_create_invalid_url.js]
-[browser_ext_tabs_detectLanguage.js]
-[browser_ext_tabs_duplicate.js]
-[browser_ext_tabs_events.js]
-[browser_ext_tabs_executeScript.js]
-[browser_ext_tabs_executeScript_good.js]
-[browser_ext_tabs_executeScript_bad.js]
-[browser_ext_tabs_executeScript_runAt.js]
-[browser_ext_tabs_getCurrent.js]
-[browser_ext_tabs_insertCSS.js]
-[browser_ext_tabs_removeCSS.js]
-[browser_ext_tabs_move.js]
-[browser_ext_tabs_move_window.js]
-[browser_ext_tabs_move_window_multiple.js]
-[browser_ext_tabs_move_window_pinned.js]
-[browser_ext_tabs_onHighlighted.js]
-[browser_ext_tabs_onUpdated.js]
-[browser_ext_tabs_query.js]
-[browser_ext_tabs_reload.js]
-[browser_ext_tabs_reload_bypass_cache.js]
-[browser_ext_tabs_sendMessage.js]
-[browser_ext_tabs_cookieStoreId.js]
-[browser_ext_tabs_update.js]
-[browser_ext_tabs_zoom.js]
-[browser_ext_tabs_update_url.js]
-[browser_ext_topwindowid.js]
-[browser_ext_webNavigation_frameId0.js]
-[browser_ext_webNavigation_getFrames.js]
-[browser_ext_webNavigation_urlbar_transitions.js]
-[browser_ext_webRequest.js]
-[browser_ext_windows.js]
-[browser_ext_windows_allowScriptsToClose.js]
-[browser_ext_windows_create.js]
-tags = fullscreen
-[browser_ext_windows_create_params.js]
-[browser_ext_windows_create_tabId.js]
-[browser_ext_windows_create_url.js]
-[browser_ext_windows_events.js]
-[browser_ext_windows_size.js]
-skip-if = os == 'mac' # Fails when windows are randomly opened in fullscreen mode
-[browser_ext_windows_update.js]
-tags = fullscreen
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_context.js b/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
deleted file mode 100644
index 8a26dbb3c..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
+++ /dev/null
@@ -1,398 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* runTests(options) {
- async function background(getTests) {
- async function checkDetails(expecting, tabId) {
- let title = await browser.browserAction.getTitle({tabId});
- browser.test.assertEq(expecting.title, title,
- "expected value from getTitle");
-
- let popup = await browser.browserAction.getPopup({tabId});
- browser.test.assertEq(expecting.popup, popup,
- "expected value from getPopup");
-
- let badge = await browser.browserAction.getBadgeText({tabId});
- browser.test.assertEq(expecting.badge, badge,
- "expected value from getBadge");
-
- let badgeBackgroundColor = await browser.browserAction.getBadgeBackgroundColor({tabId});
- browser.test.assertEq(String(expecting.badgeBackgroundColor),
- String(badgeBackgroundColor),
- "expected value from getBadgeBackgroundColor");
- }
-
- let expectDefaults = expecting => {
- return checkDetails(expecting);
- };
-
- let tabs = [];
- let tests = getTests(tabs, expectDefaults);
-
- {
- let tabId = 0xdeadbeef;
- let calls = [
- () => browser.browserAction.enable(tabId),
- () => browser.browserAction.disable(tabId),
- () => browser.browserAction.setTitle({tabId, title: "foo"}),
- () => browser.browserAction.setIcon({tabId, path: "foo.png"}),
- () => browser.browserAction.setPopup({tabId, popup: "foo.html"}),
- () => browser.browserAction.setBadgeText({tabId, text: "foo"}),
- () => browser.browserAction.setBadgeBackgroundColor({tabId, color: [0xff, 0, 0, 0xff]}),
- ];
-
- for (let call of calls) {
- await browser.test.assertRejects(
- new Promise(resolve => resolve(call())),
- RegExp(`Invalid tab ID: ${tabId}`),
- "Expected invalid tab ID error");
- }
- }
-
- // Runs the next test in the `tests` array, checks the results,
- // and passes control back to the outer test scope.
- function nextTest() {
- let test = tests.shift();
-
- test(async expecting => {
- // Check that the API returns the expected values, and then
- // run the next test.
- let tabs = await browser.tabs.query({active: true, currentWindow: true});
- await checkDetails(expecting, tabs[0].id);
-
- // Check that the actual icon has the expected values, then
- // run the next test.
- browser.test.sendMessage("nextTest", expecting, tests.length);
- });
- }
-
- browser.test.onMessage.addListener((msg) => {
- if (msg != "runNextTest") {
- browser.test.fail("Expecting 'runNextTest' message");
- }
-
- nextTest();
- });
-
- browser.tabs.query({active: true, currentWindow: true}, resultTabs => {
- tabs[0] = resultTabs[0].id;
-
- nextTest();
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: options.manifest,
-
- files: options.files || {},
-
- background: `(${background})(${options.getTests})`,
- });
-
- let browserActionId;
- function checkDetails(details) {
- if (!browserActionId) {
- browserActionId = `${makeWidgetId(extension.id)}-browser-action`;
- }
-
- let button = document.getElementById(browserActionId);
-
- ok(button, "button exists");
-
- let title = details.title || options.manifest.name;
-
- is(getListStyleImage(button), details.icon, "icon URL is correct");
- is(button.getAttribute("tooltiptext"), title, "image title is correct");
- is(button.getAttribute("label"), title, "image label is correct");
- is(button.getAttribute("badge"), details.badge, "badge text is correct");
- is(button.getAttribute("disabled") == "true", Boolean(details.disabled), "disabled state is correct");
-
- if (details.badge && details.badgeBackgroundColor) {
- let badge = button.ownerDocument.getAnonymousElementByAttribute(
- button, "class", "toolbarbutton-badge");
-
- let badgeColor = window.getComputedStyle(badge).backgroundColor;
- let color = details.badgeBackgroundColor;
- let expectedColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
-
- is(badgeColor, expectedColor, "badge color is correct");
- }
-
-
- // TODO: Popup URL.
- }
-
- let awaitFinish = new Promise(resolve => {
- extension.onMessage("nextTest", (expecting, testsRemaining) => {
- checkDetails(expecting);
-
- if (testsRemaining) {
- extension.sendMessage("runNextTest");
- } else {
- resolve();
- }
- });
- });
-
- yield extension.startup();
-
- yield awaitFinish;
-
- yield extension.unload();
-}
-
-add_task(function* testTabSwitchContext() {
- yield runTests({
- manifest: {
- "browser_action": {
- "default_icon": "default.png",
- "default_popup": "__MSG_popup__",
- "default_title": "Default __MSG_title__",
- },
-
- "default_locale": "en",
-
- "permissions": ["tabs"],
- },
-
- "files": {
- "_locales/en/messages.json": {
- "popup": {
- "message": "default.html",
- "description": "Popup",
- },
-
- "title": {
- "message": "Title",
- "description": "Title",
- },
- },
-
- "default.png": imageBuffer,
- "default-2.png": imageBuffer,
- "1.png": imageBuffer,
- "2.png": imageBuffer,
- },
-
- getTests(tabs, expectDefaults) {
- const DEFAULT_BADGE_COLOR = [0xd9, 0, 0, 255];
-
- let details = [
- {"icon": browser.runtime.getURL("default.png"),
- "popup": browser.runtime.getURL("default.html"),
- "title": "Default Title",
- "badge": "",
- "badgeBackgroundColor": DEFAULT_BADGE_COLOR},
- {"icon": browser.runtime.getURL("1.png"),
- "popup": browser.runtime.getURL("default.html"),
- "title": "Default Title",
- "badge": "",
- "badgeBackgroundColor": DEFAULT_BADGE_COLOR},
- {"icon": browser.runtime.getURL("2.png"),
- "popup": browser.runtime.getURL("2.html"),
- "title": "Title 2",
- "badge": "2",
- "badgeBackgroundColor": [0xff, 0, 0, 0xff],
- "disabled": true},
- {"icon": browser.runtime.getURL("1.png"),
- "popup": browser.runtime.getURL("default-2.html"),
- "title": "Default Title 2",
- "badge": "d2",
- "badgeBackgroundColor": [0, 0xff, 0, 0xff],
- "disabled": true},
- {"icon": browser.runtime.getURL("1.png"),
- "popup": browser.runtime.getURL("default-2.html"),
- "title": "Default Title 2",
- "badge": "d2",
- "badgeBackgroundColor": [0, 0xff, 0, 0xff],
- "disabled": false},
- {"icon": browser.runtime.getURL("default-2.png"),
- "popup": browser.runtime.getURL("default-2.html"),
- "title": "Default Title 2",
- "badge": "d2",
- "badgeBackgroundColor": [0, 0xff, 0, 0xff]},
- ];
-
- return [
- async expect => {
- browser.test.log("Initial state, expect default properties.");
-
- await expectDefaults(details[0]);
- expect(details[0]);
- },
- async expect => {
- browser.test.log("Change the icon in the current tab. Expect default properties excluding the icon.");
- browser.browserAction.setIcon({tabId: tabs[0], path: "1.png"});
-
- await expectDefaults(details[0]);
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Create a new tab. Expect default properties.");
- let tab = await browser.tabs.create({active: true, url: "about:blank?0"});
- tabs.push(tab.id);
-
- await expectDefaults(details[0]);
- expect(details[0]);
- },
- async expect => {
- browser.test.log("Change properties. Expect new properties.");
- let tabId = tabs[1];
- browser.browserAction.setIcon({tabId, path: "2.png"});
- browser.browserAction.setPopup({tabId, popup: "2.html"});
- browser.browserAction.setTitle({tabId, title: "Title 2"});
- browser.browserAction.setBadgeText({tabId, text: "2"});
- browser.browserAction.setBadgeBackgroundColor({tabId, color: "#ff0000"});
- browser.browserAction.disable(tabId);
-
- await expectDefaults(details[0]);
- expect(details[2]);
- },
- expect => {
- browser.test.log("Navigate to a new page. Expect no changes.");
-
- // TODO: This listener should not be necessary, but the |tabs.update|
- // callback currently fires too early in e10s windows.
- browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
- if (tabId == tabs[1] && changed.url) {
- browser.tabs.onUpdated.removeListener(listener);
- expect(details[2]);
- }
- });
-
- browser.tabs.update(tabs[1], {url: "about:blank?1"});
- },
- async expect => {
- browser.test.log("Switch back to the first tab. Expect previously set properties.");
- await browser.tabs.update(tabs[0], {active: true});
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Change default values, expect those changes reflected.");
- browser.browserAction.setIcon({path: "default-2.png"});
- browser.browserAction.setPopup({popup: "default-2.html"});
- browser.browserAction.setTitle({title: "Default Title 2"});
- browser.browserAction.setBadgeText({text: "d2"});
- browser.browserAction.setBadgeBackgroundColor({color: [0, 0xff, 0, 0xff]});
- browser.browserAction.disable();
-
- await expectDefaults(details[3]);
- expect(details[3]);
- },
- async expect => {
- browser.test.log("Re-enable by default. Expect enabled.");
- browser.browserAction.enable();
-
- await expectDefaults(details[4]);
- expect(details[4]);
- },
- async expect => {
- browser.test.log("Switch back to tab 2. Expect former value, unaffected by changes to defaults in previous step.");
- await browser.tabs.update(tabs[1], {active: true});
-
- await expectDefaults(details[3]);
- expect(details[2]);
- },
- async expect => {
- browser.test.log("Delete tab, switch back to tab 1. Expect previous results again.");
- await browser.tabs.remove(tabs[1]);
- expect(details[4]);
- },
- async expect => {
- browser.test.log("Create a new tab. Expect new default properties.");
- let tab = await browser.tabs.create({active: true, url: "about:blank?2"});
- tabs.push(tab.id);
- expect(details[5]);
- },
- async expect => {
- browser.test.log("Delete tab.");
- await browser.tabs.remove(tabs[2]);
- expect(details[4]);
- },
- ];
- },
- });
-});
-
-add_task(function* testDefaultTitle() {
- yield runTests({
- manifest: {
- "name": "Foo Extension",
-
- "browser_action": {
- "default_icon": "icon.png",
- },
-
- "permissions": ["tabs"],
- },
-
- files: {
- "icon.png": imageBuffer,
- },
-
- getTests(tabs, expectDefaults) {
- const DEFAULT_BADGE_COLOR = [0xd9, 0, 0, 255];
-
- let details = [
- {"title": "Foo Extension",
- "popup": "",
- "badge": "",
- "badgeBackgroundColor": DEFAULT_BADGE_COLOR,
- "icon": browser.runtime.getURL("icon.png")},
- {"title": "Foo Title",
- "popup": "",
- "badge": "",
- "badgeBackgroundColor": DEFAULT_BADGE_COLOR,
- "icon": browser.runtime.getURL("icon.png")},
- {"title": "Bar Title",
- "popup": "",
- "badge": "",
- "badgeBackgroundColor": DEFAULT_BADGE_COLOR,
- "icon": browser.runtime.getURL("icon.png")},
- {"title": "",
- "popup": "",
- "badge": "",
- "badgeBackgroundColor": DEFAULT_BADGE_COLOR,
- "icon": browser.runtime.getURL("icon.png")},
- ];
-
- return [
- async expect => {
- browser.test.log("Initial state. Expect extension title as default title.");
-
- await expectDefaults(details[0]);
- expect(details[0]);
- },
- async expect => {
- browser.test.log("Change the title. Expect new title.");
- browser.browserAction.setTitle({tabId: tabs[0], title: "Foo Title"});
-
- await expectDefaults(details[0]);
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Change the default. Expect same properties.");
- browser.browserAction.setTitle({title: "Bar Title"});
-
- await expectDefaults(details[2]);
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Clear the title. Expect new default title.");
- browser.browserAction.setTitle({tabId: tabs[0], title: ""});
-
- await expectDefaults(details[2]);
- expect(details[2]);
- },
- async expect => {
- browser.test.log("Set default title to null string. Expect null string from API, extension title in UI.");
- browser.browserAction.setTitle({title: ""});
-
- await expectDefaults(details[3]);
- expect(details[3]);
- },
- ];
- },
- });
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_disabled.js b/browser/components/extensions/test/browser/browser_ext_browserAction_disabled.js
deleted file mode 100644
index c0b9c1a1d..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_disabled.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testDisabled() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {},
- },
-
- background: function() {
- let clicked = false;
-
- browser.browserAction.onClicked.addListener(() => {
- browser.test.log("Got click event");
- clicked = true;
- });
-
- browser.test.onMessage.addListener((msg, expectClick) => {
- if (msg == "enable") {
- browser.test.log("enable browserAction");
- browser.browserAction.enable();
- } else if (msg == "disable") {
- browser.test.log("disable browserAction");
- browser.browserAction.disable();
- } else if (msg == "check-clicked") {
- browser.test.assertEq(expectClick, clicked, "got click event?");
- clicked = false;
- } else {
- browser.test.fail("Unexpected message");
- }
-
- browser.test.sendMessage("next-test");
- });
-
- browser.test.sendMessage("ready");
- },
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- yield clickBrowserAction(extension);
- yield new Promise(resolve => setTimeout(resolve, 0));
-
- extension.sendMessage("check-clicked", true);
- yield extension.awaitMessage("next-test");
-
- extension.sendMessage("disable");
- yield extension.awaitMessage("next-test");
-
- yield clickBrowserAction(extension);
- yield new Promise(resolve => setTimeout(resolve, 0));
-
- extension.sendMessage("check-clicked", false);
- yield extension.awaitMessage("next-test");
-
- extension.sendMessage("enable");
- yield extension.awaitMessage("next-test");
-
- yield clickBrowserAction(extension);
- yield new Promise(resolve => setTimeout(resolve, 0));
-
- extension.sendMessage("check-clicked", true);
- yield extension.awaitMessage("next-test");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon.js b/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon.js
deleted file mode 100644
index 9665d6832..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon.js
+++ /dev/null
@@ -1,321 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-// Test that various combinations of icon details specs, for both paths
-// and ImageData objects, result in the correct image being displayed in
-// all display resolutions.
-add_task(function* testDetailsObjects() {
- function background() {
- function getImageData(color) {
- let canvas = document.createElement("canvas");
- canvas.width = 2;
- canvas.height = 2;
- let canvasContext = canvas.getContext("2d");
-
- canvasContext.clearRect(0, 0, canvas.width, canvas.height);
- canvasContext.fillStyle = color;
- canvasContext.fillRect(0, 0, 1, 1);
-
- return {
- url: canvas.toDataURL("image/png"),
- imageData: canvasContext.getImageData(0, 0, canvas.width, canvas.height),
- };
- }
-
- let imageData = {
- red: getImageData("red"),
- green: getImageData("green"),
- };
-
- /* eslint-disable comma-dangle, indent */
- let iconDetails = [
- // Only paths.
- {details: {"path": "a.png"},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": browser.runtime.getURL("data/a.png")}},
- {details: {"path": "/a.png"},
- resolutions: {
- "1": browser.runtime.getURL("a.png"),
- "2": browser.runtime.getURL("a.png")}},
- {details: {"path": {"19": "a.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": browser.runtime.getURL("data/a.png")}},
- {details: {"path": {"38": "a.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": browser.runtime.getURL("data/a.png")}},
- {details: {"path": {"19": "a.png", "38": "a-x2.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": browser.runtime.getURL("data/a-x2.png")}},
-
- // Test that CSS strings are escaped properly.
- {details: {"path": 'a.png#" \\'},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png#%22%20%5C"),
- "2": browser.runtime.getURL("data/a.png#%22%20%5C")}},
-
- // Only ImageData objects.
- {details: {"imageData": imageData.red.imageData},
- resolutions: {
- "1": imageData.red.url,
- "2": imageData.red.url}},
- {details: {"imageData": {"19": imageData.red.imageData}},
- resolutions: {
- "1": imageData.red.url,
- "2": imageData.red.url}},
- {details: {"imageData": {"38": imageData.red.imageData}},
- resolutions: {
- "1": imageData.red.url,
- "2": imageData.red.url}},
- {details: {"imageData": {
- "19": imageData.red.imageData,
- "38": imageData.green.imageData}},
- resolutions: {
- "1": imageData.red.url,
- "2": imageData.green.url}},
-
- // Mixed path and imageData objects.
- //
- // The behavior is currently undefined if both |path| and
- // |imageData| specify icons of the same size.
- {details: {
- "path": {"19": "a.png"},
- "imageData": {"38": imageData.red.imageData}},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": imageData.red.url}},
- {details: {
- "path": {"38": "a.png"},
- "imageData": {"19": imageData.red.imageData}},
- resolutions: {
- "1": imageData.red.url,
- "2": browser.runtime.getURL("data/a.png")}},
-
- // A path or ImageData object by itself is treated as a 19px icon.
- {details: {
- "path": "a.png",
- "imageData": {"38": imageData.red.imageData}},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": imageData.red.url}},
- {details: {
- "path": {"38": "a.png"},
- "imageData": imageData.red.imageData},
- resolutions: {
- "1": imageData.red.url,
- "2": browser.runtime.getURL("data/a.png")}},
-
- // Various resolutions
- {details: {"path": {"18": "a.png", "36": "a-x2.png"}},
- legacy: true,
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": browser.runtime.getURL("data/a-x2.png")}},
- {details: {"path": {"16": "a.png", "30": "a-x2.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/a.png"),
- "2": browser.runtime.getURL("data/a-x2.png")}},
- {details: {"path": {"16": "16.png", "100": "100.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/16.png"),
- "2": browser.runtime.getURL("data/100.png")}},
- {details: {"path": {"2": "2.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/2.png"),
- "2": browser.runtime.getURL("data/2.png")}},
- {details: {"path": {
- "16": "16.svg",
- "18": "18.svg"}},
- resolutions: {
- "1": browser.runtime.getURL("data/16.svg"),
- "2": browser.runtime.getURL("data/18.svg")}},
- {details: {"path": {
- "6": "6.png",
- "18": "18.png",
- "36": "36.png",
- "48": "48.png",
- "128": "128.png"}},
- legacy: true,
- resolutions: {
- "1": browser.runtime.getURL("data/18.png"),
- "2": browser.runtime.getURL("data/36.png")},
- menuResolutions: {
- "1": browser.runtime.getURL("data/36.png"),
- "2": browser.runtime.getURL("data/128.png")}},
- {details: {"path": {
- "16": "16.png",
- "18": "18.png",
- "32": "32.png",
- "48": "48.png",
- "64": "64.png",
- "128": "128.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/16.png"),
- "2": browser.runtime.getURL("data/32.png")},
- menuResolutions: {
- "1": browser.runtime.getURL("data/32.png"),
- "2": browser.runtime.getURL("data/64.png")}},
- {details: {"path": {
- "18": "18.png",
- "32": "32.png",
- "48": "48.png",
- "128": "128.png"}},
- resolutions: {
- "1": browser.runtime.getURL("data/32.png"),
- "2": browser.runtime.getURL("data/32.png")}},
- ];
-
- // Allow serializing ImageData objects for logging.
- ImageData.prototype.toJSON = () => "<ImageData>";
-
- let tabId;
-
- browser.test.onMessage.addListener((msg, test) => {
- if (msg != "setIcon") {
- browser.test.fail("expecting 'setIcon' message");
- }
-
- let details = iconDetails[test.index];
-
- let detailString = JSON.stringify(details);
- browser.test.log(`Setting browerAction/pageAction to ${detailString} expecting URLs ${JSON.stringify(details.resolutions)}`);
-
- Promise.all([
- browser.browserAction.setIcon(Object.assign({tabId}, details.details)),
- browser.pageAction.setIcon(Object.assign({tabId}, details.details)),
- ]).then(() => {
- browser.test.sendMessage("iconSet");
- });
- });
-
- // Generate a list of tests and resolutions to send back to the test
- // context.
- //
- // This process is a bit convoluted, because the outer test context needs
- // to handle checking the button nodes and changing the screen resolution,
- // but it can't pass us icon definitions with ImageData objects. This
- // shouldn't be a problem, since structured clones should handle ImageData
- // objects without issue. Unfortunately, |cloneInto| implements a slightly
- // different algorithm than we use in web APIs, and does not handle them
- // correctly.
- let tests = [];
- for (let [idx, icon] of iconDetails.entries()) {
- tests.push({
- index: idx,
- legacy: !!icon.legacy,
- menuResolutions: icon.menuResolutions,
- resolutions: icon.resolutions,
- });
- }
-
- // Sort by resolution, so we don't needlessly switch back and forth
- // between each test.
- tests.sort(test => test.resolution);
-
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- tabId = tabs[0].id;
- browser.pageAction.show(tabId).then(() => {
- browser.test.sendMessage("ready", tests);
- });
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {},
- "page_action": {},
- "background": {
- "page": "data/background.html",
- }
- },
-
- files: {
- "data/background.html": `<script src="background.js"></script>`,
- "data/background.js": background,
-
- "data/16.svg": imageBuffer,
- "data/18.svg": imageBuffer,
-
- "data/16.png": imageBuffer,
- "data/18.png": imageBuffer,
- "data/32.png": imageBuffer,
- "data/36.png": imageBuffer,
- "data/48.png": imageBuffer,
- "data/64.png": imageBuffer,
- "data/128.png": imageBuffer,
-
- "a.png": imageBuffer,
- "data/2.png": imageBuffer,
- "data/100.png": imageBuffer,
- "data/a.png": imageBuffer,
- "data/a-x2.png": imageBuffer,
- },
- });
-
- const RESOLUTION_PREF = "layout.css.devPixelsPerPx";
-
- yield extension.startup();
-
- let pageActionId = `${makeWidgetId(extension.id)}-page-action`;
- let browserActionWidget = getBrowserActionWidget(extension);
-
- let tests = yield extension.awaitMessage("ready");
- for (let test of tests) {
- extension.sendMessage("setIcon", test);
- yield extension.awaitMessage("iconSet");
-
- let browserActionButton = browserActionWidget.forWindow(window).node;
- let pageActionImage = document.getElementById(pageActionId);
-
-
- // Test icon sizes in the toolbar/urlbar.
- for (let resolution of Object.keys(test.resolutions)) {
- yield SpecialPowers.pushPrefEnv({set: [[RESOLUTION_PREF, resolution]]});
-
- is(window.devicePixelRatio, +resolution, "window has the required resolution");
-
- let imageURL = test.resolutions[resolution];
- is(getListStyleImage(browserActionButton), imageURL, `browser action has the correct image at ${resolution}x resolution`);
- is(getListStyleImage(pageActionImage), imageURL, `page action has the correct image at ${resolution}x resolution`);
-
- let isLegacy = browserActionButton.classList.contains("toolbarbutton-legacy-addon");
- is(isLegacy, test.legacy, "Legacy class should be present?");
-
- yield SpecialPowers.popPrefEnv();
- }
-
- if (!test.menuResolutions) {
- continue;
- }
-
-
- // Test icon sizes in the menu panel.
- CustomizableUI.addWidgetToArea(browserActionWidget.id,
- CustomizableUI.AREA_PANEL);
-
- yield showBrowserAction(extension);
- browserActionButton = browserActionWidget.forWindow(window).node;
-
- for (let resolution of Object.keys(test.menuResolutions)) {
- yield SpecialPowers.pushPrefEnv({set: [[RESOLUTION_PREF, resolution]]});
-
- is(window.devicePixelRatio, +resolution, "window has the required resolution");
-
- let imageURL = test.menuResolutions[resolution];
- is(getListStyleImage(browserActionButton), imageURL, `browser action has the correct menu image at ${resolution}x resolution`);
-
- yield SpecialPowers.popPrefEnv();
- }
-
- yield closeBrowserAction(extension);
-
- CustomizableUI.addWidgetToArea(browserActionWidget.id,
- CustomizableUI.AREA_NAVBAR);
- }
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon_permissions.js b/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon_permissions.js
deleted file mode 100644
index 110746cae..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_pageAction_icon_permissions.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-// Test that an error is thrown when providing invalid icon sizes
-add_task(function* testInvalidIconSizes() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {},
- "page_action": {},
- },
-
- background: function() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- let tabId = tabs[0].id;
-
- let promises = [];
- for (let api of ["pageAction", "browserAction"]) {
- // helper function to run setIcon and check if it fails
- let assertSetIconThrows = function(detail, error, message) {
- detail.tabId = tabId;
- promises.push(
- browser.test.assertRejects(
- browser[api].setIcon(detail),
- /must be an integer/,
- "setIcon with invalid icon size"));
- };
-
- let imageData = new ImageData(1, 1);
-
- // test invalid icon size inputs
- for (let type of ["path", "imageData"]) {
- let img = type == "imageData" ? imageData : "test.png";
-
- assertSetIconThrows({[type]: {"abcdef": img}});
- assertSetIconThrows({[type]: {"48px": img}});
- assertSetIconThrows({[type]: {"20.5": img}});
- assertSetIconThrows({[type]: {"5.0": img}});
- assertSetIconThrows({[type]: {"-300": img}});
- assertSetIconThrows({[type]: {"abc": img, "5": img}});
- }
-
- assertSetIconThrows({imageData: {"abcdef": imageData}, path: {"5": "test.png"}});
- assertSetIconThrows({path: {"abcdef": "test.png"}, imageData: {"5": imageData}});
- }
-
- Promise.all(promises).then(() => {
- browser.test.notifyPass("setIcon with invalid icon size");
- });
- });
- },
- });
-
- yield Promise.all([extension.startup(), extension.awaitFinish("setIcon with invalid icon size")]);
-
- yield extension.unload();
-});
-
-
-// Test that default icon details in the manifest.json file are handled
-// correctly.
-add_task(function* testDefaultDetails() {
- // TODO: Test localized variants.
- let icons = [
- "foo/bar.png",
- "/foo/bar.png",
- {"19": "foo/bar.png"},
- {"38": "foo/bar.png"},
- ];
-
- if (window.devicePixelRatio > 1) {
- icons.push({"19": "baz/quux.png", "38": "foo/bar.png"});
- } else {
- icons.push({"19": "foo/bar.png", "38": "baz/quux@2x.png"});
- }
-
- let expectedURL = new RegExp(String.raw`^moz-extension://[^/]+/foo/bar\.png$`);
-
- for (let icon of icons) {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {"default_icon": icon},
- "page_action": {"default_icon": icon},
- },
-
- background: function() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- let tabId = tabs[0].id;
-
- browser.pageAction.show(tabId).then(() => {
- browser.test.sendMessage("ready");
- });
- });
- },
-
- files: {
- "foo/bar.png": imageBuffer,
- "baz/quux.png": imageBuffer,
- "baz/quux@2x.png": imageBuffer,
- },
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("ready")]);
-
- let browserActionId = makeWidgetId(extension.id) + "-browser-action";
- let pageActionId = makeWidgetId(extension.id) + "-page-action";
-
- let browserActionButton = document.getElementById(browserActionId);
- let image = getListStyleImage(browserActionButton);
-
- ok(expectedURL.test(image), `browser action image ${image} matches ${expectedURL}`);
-
- let pageActionImage = document.getElementById(pageActionId);
- image = getListStyleImage(pageActionImage);
-
- ok(expectedURL.test(image), `page action image ${image} matches ${expectedURL}`);
-
- yield extension.unload();
-
- let node = document.getElementById(pageActionId);
- is(node, null, "pageAction image removed from document");
- }
-});
-
-
-// Check that attempts to load a privileged URL as an icon image fail.
-add_task(function* testSecureURLsDenied() {
- // Test URLs passed to setIcon.
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {},
- "page_action": {},
- },
-
- background: function() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- let tabId = tabs[0].id;
-
- let urls = ["chrome://browser/content/browser.xul",
- "javascript:true"];
-
- let promises = [];
- for (let url of urls) {
- for (let api of ["pageAction", "browserAction"]) {
- promises.push(
- browser.test.assertRejects(
- browser[api].setIcon({tabId, path: url}),
- /Illegal URL/,
- `Load of '${url}' should fail.`));
- }
- }
-
- Promise.all(promises).then(() => {
- browser.test.notifyPass("setIcon security tests");
- });
- });
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("setIcon security tests");
- yield extension.unload();
-});
-
-
-add_task(function* testSecureManifestURLsDenied() {
- // Test URLs included in the manifest.
-
- let urls = ["chrome://browser/content/browser.xul",
- "javascript:true"];
-
- let apis = ["browser_action", "page_action"];
-
- for (let url of urls) {
- for (let api of apis) {
- info(`TEST ${api} icon url: ${url}`);
-
- let matchURLForbidden = url => ({
- message: new RegExp(`match the format "strictRelativeUrl"`),
- });
-
- let messages = [matchURLForbidden(url)];
-
- let waitForConsole = new Promise(resolve => {
- // Not necessary in browser-chrome tests, but monitorConsole gripes
- // if we don't call it.
- SimpleTest.waitForExplicitFinish();
-
- SimpleTest.monitorConsole(resolve, messages);
- });
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- [api]: {
- "default_icon": url,
- },
- },
- });
-
- yield Assert.rejects(extension.startup(),
- null,
- "Manifest rejected");
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
- }
- }
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_popup.js b/browser/components/extensions/test/browser/browser_ext_browserAction_popup.js
deleted file mode 100644
index 9f04b3c11..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_popup.js
+++ /dev/null
@@ -1,413 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function getBrowserAction(extension) {
- const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let ext = GlobalManager.extensionMap.get(extension.id);
- return browserActionFor(ext);
-}
-
-let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head><body>${url}</body></html>`;
-
-function* testInArea(area) {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "background": {
- "page": "data/background.html",
- },
- "browser_action": {
- "default_popup": "popup-a.html",
- "browser_style": true,
- },
- },
-
- files: {
- "popup-a.html": scriptPage("popup-a.js"),
- "popup-a.js": function() {
- window.onload = () => {
- let color = window.getComputedStyle(document.body).color;
- browser.test.assertEq("rgb(34, 36, 38)", color);
- browser.runtime.sendMessage("from-popup-a");
- };
- browser.runtime.onMessage.addListener(msg => {
- if (msg == "close-popup-using-window.close") {
- window.close();
- }
- });
- },
-
- "data/popup-b.html": scriptPage("popup-b.js"),
- "data/popup-b.js": function() {
- window.onload = () => {
- browser.runtime.sendMessage("from-popup-b");
- };
- },
-
- "data/popup-c.html": scriptPage("popup-c.js"),
- "data/popup-c.js": function() {
- // Close the popup before the document is fully-loaded to make sure that
- // we handle this case sanely.
- browser.runtime.sendMessage("from-popup-c");
- window.close();
- },
-
- "data/background.html": scriptPage("background.js"),
-
- "data/background.js": function() {
- let sendClick;
- let tests = [
- () => {
- browser.test.log(`Click browser action, expect popup "a".`);
- sendClick({expectEvent: false, expectPopup: "a"});
- },
- () => {
- browser.test.log(`Click browser action again, expect popup "a".`);
- sendClick({expectEvent: false, expectPopup: "a"});
- },
- () => {
- browser.test.log(`Call triggerAction, expect popup "a" again. Leave popup open.`);
- sendClick({expectEvent: false, expectPopup: "a", closePopup: false}, "trigger-action");
- },
- () => {
- browser.test.log(`Call triggerAction again. Expect remaining popup closed.`);
- sendClick({expectEvent: false, expectPopup: null}, "trigger-action");
- browser.test.sendMessage("next-test", {waitUntilClosed: true});
- },
- () => {
- browser.test.log(`Call triggerAction again. Expect popup "a" again.`);
- sendClick({expectEvent: false, expectPopup: "a"}, "trigger-action");
- },
- () => {
- browser.test.log(`Set popup to "c" and click browser action. Expect popup "c".`);
- browser.browserAction.setPopup({popup: "popup-c.html"});
- sendClick({expectEvent: false, expectPopup: "c", closePopup: false});
- },
- () => {
- browser.test.log(`Set popup to "b" and click browser action. Expect popup "b".`);
- browser.browserAction.setPopup({popup: "popup-b.html"});
- sendClick({expectEvent: false, expectPopup: "b"});
- },
- () => {
- browser.test.log(`Click browser action again, expect popup "b".`);
- sendClick({expectEvent: false, expectPopup: "b"});
- },
- () => {
- browser.test.log(`Clear popup URL. Click browser action. Expect click event.`);
- browser.browserAction.setPopup({popup: ""});
- sendClick({expectEvent: true, expectPopup: null});
- },
- () => {
- browser.test.log(`Click browser action again. Expect another click event.`);
- sendClick({expectEvent: true, expectPopup: null});
- },
- () => {
- browser.test.log(`Call triggerAction. Expect click event.`);
- sendClick({expectEvent: true, expectPopup: null}, "trigger-action");
- },
- () => {
- browser.test.log(`Set popup to "a" and click browser action. Expect popup "a", and leave open.`);
- browser.browserAction.setPopup({popup: "/popup-a.html"});
- sendClick({expectEvent: false, expectPopup: "a", closePopup: false});
- },
- () => {
- browser.test.log(`Tell popup "a" to call window.close(). Expect popup closed.`);
- browser.test.sendMessage("next-test", {closePopupUsingWindow: true});
- },
- ];
-
- let expect = {};
- sendClick = ({expectEvent, expectPopup, runNextTest, waitUntilClosed, closePopup}, message = "send-click") => {
- if (closePopup == undefined) {
- closePopup = true;
- }
-
- expect = {event: expectEvent, popup: expectPopup, runNextTest, waitUntilClosed, closePopup};
- browser.test.sendMessage(message);
- };
-
- browser.runtime.onMessage.addListener(msg => {
- if (msg == "close-popup-using-window.close") {
- return;
- } else if (expect.popup) {
- browser.test.assertEq(msg, `from-popup-${expect.popup}`,
- "expected popup opened");
- } else {
- browser.test.fail(`unexpected popup: ${msg}`);
- }
-
- expect.popup = null;
- browser.test.sendMessage("next-test", expect);
- });
-
- browser.browserAction.onClicked.addListener(() => {
- if (expect.event) {
- browser.test.succeed("expected click event received");
- } else {
- browser.test.fail("unexpected click event");
- }
-
- expect.event = false;
- browser.test.sendMessage("next-test", expect);
- });
-
- browser.test.onMessage.addListener((msg) => {
- if (msg == "close-popup-using-window.close") {
- browser.runtime.sendMessage("close-popup-using-window.close");
- return;
- }
-
- if (msg != "next-test") {
- browser.test.fail("Expecting 'next-test' message");
- }
-
- if (tests.length) {
- let test = tests.shift();
- test();
- } else {
- browser.test.notifyPass("browseraction-tests-done");
- }
- });
-
- browser.test.sendMessage("next-test");
- },
- },
- });
-
- extension.onMessage("send-click", () => {
- clickBrowserAction(extension);
- });
-
- extension.onMessage("trigger-action", () => {
- getBrowserAction(extension).triggerAction(window);
- });
-
- let widget;
- extension.onMessage("next-test", Task.async(function* (expecting = {}) {
- if (!widget) {
- widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, area);
- }
- if (expecting.waitUntilClosed) {
- let panel = getBrowserActionPopup(extension);
- if (panel && panel.state != "closed") {
- yield promisePopupHidden(panel);
- }
- } else if (expecting.closePopupUsingWindow) {
- let panel = getBrowserActionPopup(extension);
- ok(panel, "Expect panel to exist");
- yield promisePopupShown(panel);
-
- extension.sendMessage("close-popup-using-window.close");
-
- yield promisePopupHidden(panel);
- ok(true, "Panel is closed");
- } else if (expecting.closePopup) {
- yield closeBrowserAction(extension);
- }
-
- extension.sendMessage("next-test");
- }));
-
- yield Promise.all([extension.startup(), extension.awaitFinish("browseraction-tests-done")]);
-
- yield extension.unload();
-
- let view = document.getElementById(widget.viewId);
- is(view, null, "browserAction view removed from document");
-}
-
-add_task(function* testBrowserActionInToolbar() {
- yield testInArea(CustomizableUI.AREA_NAVBAR);
-});
-
-add_task(function* testBrowserActionInPanel() {
- yield testInArea(CustomizableUI.AREA_PANEL);
-});
-
-add_task(function* testBrowserActionClickCanceled() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- "permissions": ["activeTab"],
- },
-
- files: {
- "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head></html>`,
- },
- });
-
- yield extension.startup();
-
- const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let ext = GlobalManager.extensionMap.get(extension.id);
- let browserAction = browserActionFor(ext);
-
- let widget = getBrowserActionWidget(extension).forWindow(window);
- let tab = window.gBrowser.selectedTab;
-
- // Test canceled click.
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
-
- isnot(browserAction.pendingPopup, null, "Have pending popup");
- is(browserAction.pendingPopup.window, window, "Have pending popup for the correct window");
-
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
- is(browserAction.tabToRevokeDuringClearPopup, tab, "Tab to revoke was saved");
- is(browserAction.tabManager.hasActiveTabPermission(tab), true, "Active tab was granted permission");
-
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mouseup", button: 0}, window);
-
- is(browserAction.pendingPopup, null, "Pending popup was cleared");
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
- is(browserAction.tabToRevokeDuringClearPopup, null, "Tab to revoke was removed");
- is(browserAction.tabManager.hasActiveTabPermission(tab), false, "Permission was revoked from tab");
-
- // Test completed click.
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
-
- isnot(browserAction.pendingPopup, null, "Have pending popup");
- is(browserAction.pendingPopup.window, window, "Have pending popup for the correct window");
-
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
- // We need to do these tests during the mouseup event cycle, since the click
- // and command events will be dispatched immediately after mouseup, and void
- // the results.
- let mouseUpPromise = BrowserTestUtils.waitForEvent(widget.node, "mouseup", false, event => {
- isnot(browserAction.pendingPopup, null, "Pending popup was not cleared");
- isnot(browserAction.pendingPopupTimeout, null, "Have a pending popup timeout");
- return true;
- });
-
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mouseup", button: 0}, window);
-
- yield mouseUpPromise;
-
- is(browserAction.pendingPopup, null, "Pending popup was cleared");
- is(browserAction.pendingPopupTimeout, null, "Pending popup timeout was cleared");
-
- yield promisePopupShown(getBrowserActionPopup(extension));
- yield closeBrowserAction(extension);
-
- yield extension.unload();
-});
-
-add_task(function* testBrowserActionDisabled() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- },
-
- background() {
- browser.browserAction.disable();
- },
-
- files: {
- "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"><script src="popup.js"></script></head></html>`,
- "popup.js"() {
- browser.test.fail("Should not get here");
- },
- },
- });
-
- yield extension.startup();
-
- const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let ext = GlobalManager.extensionMap.get(extension.id);
- let browserAction = browserActionFor(ext);
-
- let widget = getBrowserActionWidget(extension).forWindow(window);
-
- // Test canceled click.
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
-
- is(browserAction.pendingPopup, null, "Have no pending popup");
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
- EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mouseup", button: 0}, window);
-
- is(browserAction.pendingPopup, null, "Have no pending popup");
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
-
- // Test completed click.
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
-
- is(browserAction.pendingPopup, null, "Have no pending popup");
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
- // We need to do these tests during the mouseup event cycle, since the click
- // and command events will be dispatched immediately after mouseup, and void
- // the results.
- let mouseUpPromise = BrowserTestUtils.waitForEvent(widget.node, "mouseup", false, event => {
- is(browserAction.pendingPopup, null, "Have no pending popup");
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
- return true;
- });
-
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mouseup", button: 0}, window);
-
- yield mouseUpPromise;
-
- is(browserAction.pendingPopup, null, "Have no pending popup");
- is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
-
- // Give the popup a chance to load and trigger a failure, if it was
- // erroneously opened.
- yield new Promise(resolve => setTimeout(resolve, 250));
-
- yield extension.unload();
-});
-
-add_task(function* testBrowserActionTabPopulation() {
- // Note: This test relates to https://bugzilla.mozilla.org/show_bug.cgi?id=1310019
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- "permissions": ["activeTab"],
- },
-
- files: {
- "popup.html": scriptPage("popup.js"),
- "popup.js": function() {
- browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
- browser.test.assertEq("mochitest index /",
- tabs[0].title,
- "Tab has the expected title on first click");
- browser.test.sendMessage("tabTitle");
- });
- },
- },
- });
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, "http://example.com/");
- yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
-
- yield extension.startup();
-
- let widget = getBrowserActionWidget(extension).forWindow(win);
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, win);
-
- yield extension.awaitMessage("tabTitle");
-
- EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mouseup", button: 0}, win);
-
- yield extension.unload();
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js b/browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js
deleted file mode 100644
index 6c19b17f1..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js
+++ /dev/null
@@ -1,304 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* openPanel(extension, win = window, awaitLoad = false) {
- clickBrowserAction(extension, win);
-
- return yield awaitExtensionPanel(extension, win, awaitLoad);
-}
-
-add_task(function* testBrowserActionPopupResize() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- },
-
- files: {
- "popup.html": '<!DOCTYPE html><html><head><meta charset="utf-8"></head></html>',
- },
- });
-
- yield extension.startup();
-
- let browser = yield openPanel(extension);
-
- function* checkSize(expected) {
- let dims = yield promiseContentDimensions(browser);
-
- is(dims.window.innerHeight, expected, `Panel window should be ${expected}px tall`);
- is(dims.body.clientHeight, dims.body.scrollHeight,
- "Panel body should be tall enough to fit its contents");
-
- // Tolerate if it is 1px too wide, as that may happen with the current resizing method.
- ok(Math.abs(dims.window.innerWidth - expected) <= 1, `Panel window should be ${expected}px wide`);
- is(dims.body.clientWidth, dims.body.scrollWidth,
- "Panel body should be wide enough to fit its contents");
- }
-
- /* eslint-disable mozilla/no-cpows-in-tests */
- function setSize(size) {
- content.document.body.style.height = `${size}px`;
- content.document.body.style.width = `${size}px`;
- }
- /* eslint-enable mozilla/no-cpows-in-tests */
-
- let sizes = [
- 200,
- 400,
- 300,
- ];
-
- for (let size of sizes) {
- yield alterContent(browser, setSize, size);
- yield checkSize(size);
- }
-
- yield closeBrowserAction(extension);
- yield extension.unload();
-});
-
-function* testPopupSize(standardsMode, browserWin = window, arrowSide = "top") {
- let docType = standardsMode ? "<!DOCTYPE html>" : "";
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
- },
-
- files: {
- "popup.html": `${docType}
- <html>
- <head>
- <meta charset="utf-8">
- <style type="text/css">
- body > span {
- display: inline-block;
- width: 10px;
- height: 150px;
- border: 2px solid black;
- }
- .big > span {
- width: 300px;
- height: 100px;
- }
- .bigger > span {
- width: 150px;
- height: 150px;
- }
- .huge > span {
- height: ${2 * screen.height}px;
- }
- </style>
- </head>
- <body>
- <span></span>
- <span></span>
- <span></span>
- <span></span>
- </body>
- </html>`,
- },
- });
-
- yield extension.startup();
-
- /* eslint-disable mozilla/no-cpows-in-tests */
-
- if (arrowSide == "top") {
- // Test the standalone panel for a toolbar button.
- let browser = yield openPanel(extension, browserWin, true);
-
- let dims = yield promiseContentDimensions(browser);
-
- is(dims.isStandards, standardsMode, "Document has the expected compat mode");
-
- let {innerWidth, innerHeight} = dims.window;
-
- dims = yield alterContent(browser, () => {
- content.document.body.classList.add("bigger");
- });
-
- let win = dims.window;
- is(win.innerHeight, innerHeight, "Window height should not change");
- ok(win.innerWidth > innerWidth, `Window width should increase (${win.innerWidth} > ${innerWidth})`);
-
-
- dims = yield alterContent(browser, () => {
- content.document.body.classList.remove("bigger");
- });
-
- win = dims.window;
- is(win.innerHeight, innerHeight, "Window height should not change");
-
- // The getContentSize calculation is not always reliable to single-pixel
- // precision.
- ok(Math.abs(win.innerWidth - innerWidth) <= 1,
- `Window width should return to approximately its original value (${win.innerWidth} ~= ${innerWidth})`);
-
- yield closeBrowserAction(extension, browserWin);
- }
-
-
- // Test the PanelUI panel for a menu panel button.
- let widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, CustomizableUI.AREA_PANEL);
-
- let browser = yield openPanel(extension, browserWin);
-
- let {panel} = browserWin.PanelUI;
- let origPanelRect = panel.getBoundingClientRect();
-
- // Check that the panel is still positioned as expected.
- let checkPanelPosition = () => {
- is(panel.getAttribute("side"), arrowSide, "Panel arrow is positioned as expected");
-
- let panelRect = panel.getBoundingClientRect();
- if (arrowSide == "top") {
- ok(panelRect.top, origPanelRect.top, "Panel has not moved downwards");
- ok(panelRect.bottom >= origPanelRect.bottom, `Panel has not shrunk from original size (${panelRect.bottom} >= ${origPanelRect.bottom})`);
-
- let screenBottom = browserWin.screen.availTop + browserWin.screen.availHeight;
- let panelBottom = browserWin.mozInnerScreenY + panelRect.bottom;
- ok(panelBottom <= screenBottom, `Bottom of popup should be on-screen. (${panelBottom} <= ${screenBottom})`);
- } else {
- ok(panelRect.bottom, origPanelRect.bottom, "Panel has not moved upwards");
- ok(panelRect.top <= origPanelRect.top, `Panel has not shrunk from original size (${panelRect.top} <= ${origPanelRect.top})`);
-
- let panelTop = browserWin.mozInnerScreenY + panelRect.top;
- ok(panelTop >= browserWin.screen.availTop, `Top of popup should be on-screen. (${panelTop} >= ${browserWin.screen.availTop})`);
- }
- };
-
- yield awaitBrowserLoaded(browser);
-
- // Wait long enough to make sure the initial resize debouncing timer has
- // expired.
- yield new Promise(resolve => setTimeout(resolve, 100));
-
- let dims = yield promiseContentDimensions(browser);
-
- is(dims.isStandards, standardsMode, "Document has the expected compat mode");
-
- // If the browser's preferred height is smaller than the initial height of the
- // panel, then it will still take up the full available vertical space. Even
- // so, we need to check that we've gotten the preferred height calculation
- // correct, so check that explicitly.
- let getHeight = () => parseFloat(browser.style.height);
-
- let {innerWidth, innerHeight} = dims.window;
- let height = getHeight();
-
-
- let setClass = className => {
- content.document.body.className = className;
- };
-
- info("Increase body children's width. " +
- "Expect them to wrap, and the frame to grow vertically rather than widen.");
-
- dims = yield alterContent(browser, setClass, "big");
- let win = dims.window;
-
- ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
-
- is(win.innerWidth, innerWidth, "Window width should not change");
- ok(win.innerHeight >= innerHeight, `Window height should increase (${win.innerHeight} >= ${innerHeight})`);
- is(win.scrollMaxY, 0, "Document should not be vertically scrollable");
-
- checkPanelPosition();
-
-
- info("Increase body children's width and height. " +
- "Expect them to wrap, and the frame to grow vertically rather than widen.");
-
- dims = yield alterContent(browser, setClass, "bigger");
- win = dims.window;
-
- ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
-
- is(win.innerWidth, innerWidth, "Window width should not change");
- ok(win.innerHeight >= innerHeight, `Window height should increase (${win.innerHeight} >= ${innerHeight})`);
- is(win.scrollMaxY, 0, "Document should not be vertically scrollable");
-
- checkPanelPosition();
-
-
- info("Increase body height beyond the height of the screen. " +
- "Expect the panel to grow to accommodate, but not larger than the height of the screen.");
-
- dims = yield alterContent(browser, setClass, "huge");
- win = dims.window;
-
- ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
-
- is(win.innerWidth, innerWidth, "Window width should not change");
- ok(win.innerHeight > innerHeight, `Window height should increase (${win.innerHeight} > ${innerHeight})`);
- ok(win.innerHeight < screen.height, `Window height be less than the screen height (${win.innerHeight} < ${screen.height})`);
- ok(win.scrollMaxY > 0, `Document should be vertically scrollable (${win.scrollMaxY} > 0)`);
-
- checkPanelPosition();
-
-
- info("Restore original styling. Expect original dimensions.");
- dims = yield alterContent(browser, setClass, "");
- win = dims.window;
-
- is(getHeight(), height, "Browser height should return to its original value");
-
- is(win.innerWidth, innerWidth, "Window width should not change");
- is(win.innerHeight, innerHeight, "Window height should return to its original value");
- is(win.scrollMaxY, 0, "Document should not be vertically scrollable");
-
- checkPanelPosition();
-
- yield closeBrowserAction(extension, browserWin);
-
- yield extension.unload();
-}
-
-add_task(function* testBrowserActionMenuResizeStandards() {
- yield testPopupSize(true);
-});
-
-add_task(function* testBrowserActionMenuResizeQuirks() {
- yield testPopupSize(false);
-});
-
-// Test that we still make reasonable maximum size calculations when the window
-// is close enough to the bottom of the screen that the menu panel opens above,
-// rather than below, its button.
-add_task(function* testBrowserActionMenuResizeBottomArrow() {
- const WIDTH = 800;
- const HEIGHT = 300;
-
- let left = screen.availLeft + screen.availWidth - WIDTH;
- let top = screen.availTop + screen.availHeight - HEIGHT;
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
-
- win.resizeTo(WIDTH, HEIGHT);
-
- // Sometimes we run into problems on Linux with resizing being asynchronous
- // and window managers not allowing us to move the window so that any part of
- // it is off-screen, so we need to try more than once.
- for (let i = 0; i < 20; i++) {
- win.moveTo(left, top);
-
- if (win.screenX == left && win.screenY == top) {
- break;
- }
-
- yield new Promise(resolve => setTimeout(resolve, 100));
- }
-
- yield testPopupSize(true, win, "bottom");
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_simple.js b/browser/components/extensions/test/browser/browser_ext_browserAction_simple.js
deleted file mode 100644
index e83010958..000000000
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_simple.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "unrecognized_property": "with-a-random-value",
- },
- },
-
- files: {
- "popup.html": `
- <!DOCTYPE html>
- <html><body>
- <script src="popup.js"></script>
- </body></html>
- `,
-
- "popup.js": function() {
- window.onload = () => {
- browser.runtime.sendMessage("from-popup");
- };
- },
- },
-
- background: function() {
- browser.runtime.onMessage.addListener(msg => {
- browser.test.assertEq(msg, "from-popup", "correct message received");
- browser.test.sendMessage("popup");
- });
- },
- });
-
- SimpleTest.waitForExplicitFinish();
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{
- message: /Reading manifest: Error processing browser_action.unrecognized_property: An unexpected property was found/,
- }]);
- });
-
- yield extension.startup();
-
- // Do this a few times to make sure the pop-up is reloaded each time.
- for (let i = 0; i < 3; i++) {
- clickBrowserAction(extension);
-
- yield extension.awaitMessage("popup");
-
- closeBrowserAction(extension);
- }
-
- yield extension.unload();
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_commands_execute_browser_action.js b/browser/components/extensions/test/browser/browser_ext_commands_execute_browser_action.js
deleted file mode 100644
index f97a735d4..000000000
--- a/browser/components/extensions/test/browser/browser_ext_commands_execute_browser_action.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* testExecuteBrowserActionWithOptions(options = {}) {
- let extensionOptions = {};
-
- extensionOptions.manifest = {
- "commands": {
- "_execute_browser_action": {
- "suggested_key": {
- "default": "Alt+Shift+J",
- },
- },
- },
- "browser_action": {
- "browser_style": true,
- },
- };
-
- if (options.withPopup) {
- extensionOptions.manifest.browser_action.default_popup = "popup.html";
-
- extensionOptions.files = {
- "popup.html": `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <script src="popup.js"></script>
- </head>
- </html>
- `,
-
- "popup.js": function() {
- browser.runtime.sendMessage("from-browser-action-popup");
- },
- };
- }
-
- extensionOptions.background = () => {
- browser.test.onMessage.addListener((message, withPopup) => {
- browser.commands.onCommand.addListener((commandName) => {
- if (commandName == "_execute_browser_action") {
- browser.test.fail("The onCommand listener should never fire for _execute_browser_action.");
- }
- });
-
- browser.browserAction.onClicked.addListener(() => {
- if (withPopup) {
- browser.test.fail("The onClick listener should never fire if the browserAction has a popup.");
- browser.test.notifyFail("execute-browser-action-on-clicked-fired");
- } else {
- browser.test.notifyPass("execute-browser-action-on-clicked-fired");
- }
- });
-
- browser.runtime.onMessage.addListener(msg => {
- if (msg == "from-browser-action-popup") {
- browser.test.notifyPass("execute-browser-action-popup-opened");
- }
- });
-
- browser.test.sendMessage("send-keys");
- });
- };
-
- let extension = ExtensionTestUtils.loadExtension(extensionOptions);
-
- extension.onMessage("send-keys", () => {
- EventUtils.synthesizeKey("j", {altKey: true, shiftKey: true});
- });
-
- yield extension.startup();
-
- if (options.inArea) {
- let widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, options.inArea);
- }
-
- extension.sendMessage("withPopup", options.withPopup);
-
- if (options.withPopup) {
- yield extension.awaitFinish("execute-browser-action-popup-opened");
- yield closeBrowserAction(extension);
- } else {
- yield extension.awaitFinish("execute-browser-action-on-clicked-fired");
- }
- yield extension.unload();
-}
-
-add_task(function* test_execute_browser_action_with_popup() {
- yield testExecuteBrowserActionWithOptions({
- withPopup: true,
- });
-});
-
-add_task(function* test_execute_browser_action_without_popup() {
- yield testExecuteBrowserActionWithOptions();
-});
-
-add_task(function* test_execute_browser_action_in_hamburger_menu_with_popup() {
- yield testExecuteBrowserActionWithOptions({
- withPopup: true,
- inArea: CustomizableUI.AREA_PANEL,
- });
-});
-
-add_task(function* test_execute_browser_action_in_hamburger_menu_without_popup() {
- yield testExecuteBrowserActionWithOptions({
- inArea: CustomizableUI.AREA_PANEL,
- });
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_commands_execute_page_action.js b/browser/components/extensions/test/browser/browser_ext_commands_execute_page_action.js
deleted file mode 100644
index 83684493e..000000000
--- a/browser/components/extensions/test/browser/browser_ext_commands_execute_page_action.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* test_execute_page_action_without_popup() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "commands": {
- "_execute_page_action": {
- "suggested_key": {
- "default": "Alt+Shift+J",
- },
- },
- "send-keys-command": {
- "suggested_key": {
- "default": "Alt+Shift+3",
- },
- },
- },
- "page_action": {},
- },
-
- background: function() {
- let isShown = false;
-
- browser.commands.onCommand.addListener((commandName) => {
- if (commandName == "_execute_page_action") {
- browser.test.fail(`The onCommand listener should never fire for ${commandName}.`);
- } else if (commandName == "send-keys-command") {
- if (!isShown) {
- isShown = true;
- browser.tabs.query({currentWindow: true, active: true}, tabs => {
- tabs.forEach(tab => {
- browser.pageAction.show(tab.id);
- });
- browser.test.sendMessage("send-keys");
- });
- }
- }
- });
-
- browser.pageAction.onClicked.addListener(() => {
- browser.test.assertTrue(isShown, "The onClicked event should fire if the page action is shown.");
- browser.test.notifyPass("page-action-without-popup");
- });
-
- browser.test.sendMessage("send-keys");
- },
- });
-
- extension.onMessage("send-keys", () => {
- EventUtils.synthesizeKey("j", {altKey: true, shiftKey: true});
- EventUtils.synthesizeKey("3", {altKey: true, shiftKey: true});
- });
-
- yield extension.startup();
- yield extension.awaitFinish("page-action-without-popup");
- yield extension.unload();
-});
-
-add_task(function* test_execute_page_action_with_popup() {
- let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head><body>Test Popup</body></html>`;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "commands": {
- "_execute_page_action": {
- "suggested_key": {
- "default": "Alt+Shift+J",
- },
- },
- "send-keys-command": {
- "suggested_key": {
- "default": "Alt+Shift+3",
- },
- },
- },
- "page_action": {
- "default_popup": "popup.html",
- },
- },
-
- files: {
- "popup.html": scriptPage("popup.js"),
- "popup.js": function() {
- browser.runtime.sendMessage("popup-opened");
- },
- },
-
- background: function() {
- let isShown = false;
-
- browser.commands.onCommand.addListener((message) => {
- if (message == "_execute_page_action") {
- browser.test.fail(`The onCommand listener should never fire for ${message}.`);
- }
-
- if (message == "send-keys-command") {
- if (!isShown) {
- isShown = true;
- browser.tabs.query({currentWindow: true, active: true}, tabs => {
- tabs.forEach(tab => {
- browser.pageAction.show(tab.id);
- });
- browser.test.sendMessage("send-keys");
- });
- }
- }
- });
-
- browser.pageAction.onClicked.addListener(() => {
- browser.test.fail(`The onClicked listener should never fire when the pageAction has a popup.`);
- });
-
- browser.runtime.onMessage.addListener(msg => {
- browser.test.assertEq(msg, "popup-opened", "expected popup opened");
- browser.test.assertTrue(isShown, "The onClicked event should fire if the page action is shown.");
- browser.test.notifyPass("page-action-with-popup");
- });
-
- browser.test.sendMessage("send-keys");
- },
- });
-
- extension.onMessage("send-keys", () => {
- EventUtils.synthesizeKey("j", {altKey: true, shiftKey: true});
- EventUtils.synthesizeKey("3", {altKey: true, shiftKey: true});
- });
-
- yield extension.startup();
- yield extension.awaitFinish("page-action-with-popup");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_commands_getAll.js b/browser/components/extensions/test/browser/browser_ext_commands_getAll.js
deleted file mode 100644
index 5885e8aee..000000000
--- a/browser/components/extensions/test/browser/browser_ext_commands_getAll.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-var {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm");
-
-add_task(function* () {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "name": "Commands Extension",
- "commands": {
- "with-desciption": {
- "suggested_key": {
- "default": "Ctrl+Shift+Y",
- },
- "description": "should have a description",
- },
- "without-description": {
- "suggested_key": {
- "default": "Ctrl+Shift+D",
- },
- },
- "with-platform-info": {
- "suggested_key": {
- "mac": "Ctrl+Shift+M",
- "linux": "Ctrl+Shift+L",
- "windows": "Ctrl+Shift+W",
- "android": "Ctrl+Shift+A",
- },
- },
- },
- },
-
- background: function() {
- browser.test.onMessage.addListener((message, additionalScope) => {
- browser.commands.getAll((commands) => {
- let errorMessage = "getAll should return an array of commands";
- browser.test.assertEq(commands.length, 3, errorMessage);
-
- let command = commands.find(c => c.name == "with-desciption");
-
- errorMessage = "The description should match what is provided in the manifest";
- browser.test.assertEq("should have a description", command.description, errorMessage);
-
- errorMessage = "The shortcut should match the default shortcut provided in the manifest";
- browser.test.assertEq("Ctrl+Shift+Y", command.shortcut, errorMessage);
-
- command = commands.find(c => c.name == "without-description");
-
- errorMessage = "The description should be empty when it is not provided";
- browser.test.assertEq(null, command.description, errorMessage);
-
- errorMessage = "The shortcut should match the default shortcut provided in the manifest";
- browser.test.assertEq("Ctrl+Shift+D", command.shortcut, errorMessage);
-
- let platformKeys = {
- macosx: "M",
- linux: "L",
- win: "W",
- android: "A",
- };
-
- command = commands.find(c => c.name == "with-platform-info");
- let platformKey = platformKeys[additionalScope.platform];
- let shortcut = `Ctrl+Shift+${platformKey}`;
- errorMessage = `The shortcut should match the one provided in the manifest for OS='${additionalScope.platform}'`;
- browser.test.assertEq(shortcut, command.shortcut, errorMessage);
-
- browser.test.notifyPass("commands");
- });
- });
- browser.test.sendMessage("ready");
- },
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
- extension.sendMessage("additional-scope", {platform: AppConstants.platform});
- yield extension.awaitFinish("commands");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_commands_onCommand.js b/browser/components/extensions/test/browser/browser_ext_commands_onCommand.js
deleted file mode 100644
index dd959dcec..000000000
--- a/browser/components/extensions/test/browser/browser_ext_commands_onCommand.js
+++ /dev/null
@@ -1,229 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-add_task(function* test_user_defined_commands() {
- const testCommands = [
- // Ctrl Shortcuts
- {
- name: "toggle-ctrl-a",
- shortcut: "Ctrl+A",
- key: "A",
- modifiers: {
- accelKey: true,
- },
- },
- {
- name: "toggle-ctrl-up",
- shortcut: "Ctrl+Up",
- key: "VK_UP",
- modifiers: {
- accelKey: true,
- },
- },
- // Alt Shortcuts
- {
- name: "toggle-alt-a",
- shortcut: "Alt+A",
- key: "A",
- modifiers: {
- altKey: true,
- },
- },
- {
- name: "toggle-alt-down",
- shortcut: "Alt+Down",
- key: "VK_DOWN",
- modifiers: {
- altKey: true,
- },
- },
- // Mac Shortcuts
- {
- name: "toggle-command-shift-page-up",
- shortcutMac: "Command+Shift+PageUp",
- key: "VK_PAGE_UP",
- modifiers: {
- accelKey: true,
- shiftKey: true,
- },
- },
- {
- name: "toggle-mac-control-shift+period",
- shortcut: "Ctrl+Shift+Period",
- shortcutMac: "MacCtrl+Shift+Period",
- key: "VK_PERIOD",
- modifiers: {
- ctrlKey: true,
- shiftKey: true,
- },
- },
- // Ctrl+Shift Shortcuts
- {
- name: "toggle-ctrl-shift-left",
- shortcut: "Ctrl+Shift+Left",
- key: "VK_LEFT",
- modifiers: {
- accelKey: true,
- shiftKey: true,
- },
- },
- // Alt+Shift Shortcuts
- {
- name: "toggle-alt-shift-1",
- shortcut: "Alt+Shift+1",
- key: "1",
- modifiers: {
- altKey: true,
- shiftKey: true,
- },
- },
- {
- name: "toggle-alt-shift-a",
- shortcut: "Alt+Shift+A",
- key: "A",
- modifiers: {
- altKey: true,
- shiftKey: true,
- },
- },
- {
- name: "toggle-alt-shift-right",
- shortcut: "Alt+Shift+Right",
- key: "VK_RIGHT",
- modifiers: {
- altKey: true,
- shiftKey: true,
- },
- },
- // Misc Shortcuts
- {
- name: "valid-command-with-unrecognized-property-name",
- shortcut: "Alt+Shift+3",
- key: "3",
- modifiers: {
- altKey: true,
- shiftKey: true,
- },
- unrecognized_property: "with-a-random-value",
- },
- {
- name: "spaces-in-shortcut-name",
- shortcut: " Alt + Shift + 2 ",
- key: "2",
- modifiers: {
- altKey: true,
- shiftKey: true,
- },
- },
- ];
-
- // Create a window before the extension is loaded.
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.loadURI(win1.gBrowser.selectedBrowser, "about:robots");
- yield BrowserTestUtils.browserLoaded(win1.gBrowser.selectedBrowser);
-
- let commands = {};
- let isMac = AppConstants.platform == "macosx";
- let totalMacOnlyCommands = 0;
-
- for (let testCommand of testCommands) {
- let command = {
- suggested_key: {},
- };
-
- if (testCommand.shortcut) {
- command.suggested_key.default = testCommand.shortcut;
- }
-
- if (testCommand.shortcutMac) {
- command.suggested_key.mac = testCommand.shortcutMac;
- }
-
- if (testCommand.shortcutMac && !testCommand.shortcut) {
- totalMacOnlyCommands++;
- }
-
- if (testCommand.unrecognized_property) {
- command.unrecognized_property = testCommand.unrecognized_property;
- }
-
- commands[testCommand.name] = command;
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "commands": commands,
- },
-
- background: function() {
- browser.commands.onCommand.addListener(commandName => {
- browser.test.sendMessage("oncommand", commandName);
- });
- browser.test.sendMessage("ready");
- },
- });
-
- SimpleTest.waitForExplicitFinish();
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{
- message: /Reading manifest: Error processing commands.*.unrecognized_property: An unexpected property was found/,
- }]);
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- function* runTest(window) {
- for (let testCommand of testCommands) {
- if (testCommand.shortcutMac && !testCommand.shortcut && !isMac) {
- continue;
- }
- EventUtils.synthesizeKey(testCommand.key, testCommand.modifiers, window);
- let message = yield extension.awaitMessage("oncommand");
- is(message, testCommand.name, `Expected onCommand listener to fire with the correct name: ${testCommand.name}`);
- }
- }
-
- // Create another window after the extension is loaded.
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.loadURI(win2.gBrowser.selectedBrowser, "about:robots");
- yield BrowserTestUtils.browserLoaded(win2.gBrowser.selectedBrowser);
-
- let totalTestCommands = Object.keys(testCommands).length;
- let expectedCommandsRegistered = isMac ? totalTestCommands : totalTestCommands - totalMacOnlyCommands;
-
- // Confirm the keysets have been added to both windows.
- let keysetID = `ext-keyset-id-${makeWidgetId(extension.id)}`;
- let keyset = win1.document.getElementById(keysetID);
- ok(keyset != null, "Expected keyset to exist");
- is(keyset.childNodes.length, expectedCommandsRegistered, "Expected keyset to have the correct number of children");
-
- keyset = win2.document.getElementById(keysetID);
- ok(keyset != null, "Expected keyset to exist");
- is(keyset.childNodes.length, expectedCommandsRegistered, "Expected keyset to have the correct number of children");
-
- // Confirm that the commands are registered to both windows.
- yield focusWindow(win1);
- yield runTest(win1);
-
- yield focusWindow(win2);
- yield runTest(win2);
-
- yield extension.unload();
-
- // Confirm that the keysets have been removed from both windows after the extension is unloaded.
- keyset = win1.document.getElementById(keysetID);
- is(keyset, null, "Expected keyset to be removed from the window");
-
- keyset = win2.document.getElementById(keysetID);
- is(keyset, null, "Expected keyset to be removed from the window");
-
- yield BrowserTestUtils.closeWindow(win1);
- yield BrowserTestUtils.closeWindow(win2);
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contentscript_connect.js b/browser/components/extensions/test/browser/browser_ext_contentscript_connect.js
deleted file mode 100644
index 8b2d9badf..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contentscript_connect.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["http://mochi.test/"],
- },
-
- background: function() {
- let ports_received = 0;
- let port_messages_received = 0;
-
- browser.runtime.onConnect.addListener((port) => {
- browser.test.assertTrue(!!port, "port1 received");
-
- ports_received++;
- browser.test.assertEq(1, ports_received, "1 port received");
-
- port.onMessage.addListener((msg, msgPort) => {
- browser.test.assertEq("port message", msg, "listener1 port message received");
- browser.test.assertEq(port, msgPort, "onMessage should receive port as second argument");
-
- port_messages_received++;
- browser.test.assertEq(1, port_messages_received, "1 port message received");
- });
- });
- browser.runtime.onConnect.addListener((port) => {
- browser.test.assertTrue(!!port, "port2 received");
-
- ports_received++;
- browser.test.assertEq(2, ports_received, "2 ports received");
-
- port.onMessage.addListener((msg, msgPort) => {
- browser.test.assertEq("port message", msg, "listener2 port message received");
- browser.test.assertEq(port, msgPort, "onMessage should receive port as second argument");
-
- port_messages_received++;
- browser.test.assertEq(2, port_messages_received, "2 port messages received");
-
- browser.test.notifyPass("contentscript_connect.pass");
- });
- });
-
- browser.tabs.executeScript({file: "script.js"}).catch(e => {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFail("contentscript_connect.pass");
- });
- },
-
- files: {
- "script.js": function() {
- let port = browser.runtime.connect();
- port.postMessage("port message");
- },
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("contentscript_connect.pass");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus.js b/browser/components/extensions/test/browser/browser_ext_contextMenus.js
deleted file mode 100644
index fa1483b20..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus.js
+++ /dev/null
@@ -1,342 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-const PAGE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
-
- background: function() {
- browser.contextMenus.create({
- id: "clickme-image",
- title: "Click me!",
- contexts: ["image"],
- });
- browser.contextMenus.create({
- id: "clickme-page",
- title: "Click me!",
- contexts: ["page"],
- });
- browser.test.notifyPass();
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish();
-
- let contentAreaContextMenu = yield openContextMenu("#img1");
- let item = contentAreaContextMenu.getElementsByAttribute("label", "Click me!");
- is(item.length, 1, "contextMenu item for image was found");
- yield closeContextMenu();
-
- contentAreaContextMenu = yield openContextMenu("body");
- item = contentAreaContextMenu.getElementsByAttribute("label", "Click me!");
- is(item.length, 1, "contextMenu item for page was found");
- yield closeContextMenu();
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
-});
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
-
- background: async function() {
- // A generic onclick callback function.
- function genericOnClick(info, tab) {
- browser.test.sendMessage("onclick", {info, tab});
- }
-
- browser.contextMenus.onClicked.addListener((info, tab) => {
- browser.test.sendMessage("browser.contextMenus.onClicked", {info, tab});
- });
-
- browser.contextMenus.create({
- contexts: ["all"],
- type: "separator",
- });
-
- let contexts = ["page", "selection", "image", "editable"];
- for (let i = 0; i < contexts.length; i++) {
- let context = contexts[i];
- let title = context;
- browser.contextMenus.create({
- title: title,
- contexts: [context],
- id: "ext-" + context,
- onclick: genericOnClick,
- });
- if (context == "selection") {
- browser.contextMenus.update("ext-selection", {
- title: "selection is: '%s'",
- onclick: (info, tab) => {
- browser.contextMenus.removeAll();
- genericOnClick(info, tab);
- },
- });
- }
- }
-
- let parent = browser.contextMenus.create({
- title: "parent",
- });
- browser.contextMenus.create({
- title: "child1",
- parentId: parent,
- onclick: genericOnClick,
- });
- let child2 = browser.contextMenus.create({
- title: "child2",
- parentId: parent,
- onclick: genericOnClick,
- });
-
- let parentToDel = browser.contextMenus.create({
- title: "parentToDel",
- });
- browser.contextMenus.create({
- title: "child1",
- parentId: parentToDel,
- onclick: genericOnClick,
- });
- browser.contextMenus.create({
- title: "child2",
- parentId: parentToDel,
- onclick: genericOnClick,
- });
- browser.contextMenus.remove(parentToDel);
-
- browser.contextMenus.create({
- title: "Without onclick property",
- id: "ext-without-onclick",
- });
-
- await browser.test.assertRejects(
- browser.contextMenus.update(parent, {parentId: child2}),
- /cannot be an ancestor/,
- "Should not be able to reparent an item as descendent of itself");
-
- browser.test.notifyPass("contextmenus");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus");
-
- let expectedClickInfo = {
- menuItemId: "ext-image",
- mediaType: "image",
- srcUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/ctxmenu-image.png",
- pageUrl: PAGE,
- editable: false,
- };
-
- function checkClickInfo(result) {
- for (let i of Object.keys(expectedClickInfo)) {
- is(result.info[i], expectedClickInfo[i],
- "click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + result.info[i]);
- }
- is(expectedClickInfo.pageSrc, result.tab.url, "click info page source is the right tab");
- }
-
- let extensionMenuRoot = yield openExtensionContextMenu();
-
- // Check some menu items
- let items = extensionMenuRoot.getElementsByAttribute("label", "image");
- is(items.length, 1, "contextMenu item for image was found (context=image)");
- let image = items[0];
-
- items = extensionMenuRoot.getElementsByAttribute("label", "selection-edited");
- is(items.length, 0, "contextMenu item for selection was not found (context=image)");
-
- items = extensionMenuRoot.getElementsByAttribute("label", "parentToDel");
- is(items.length, 0, "contextMenu item for removed parent was not found (context=image)");
-
- items = extensionMenuRoot.getElementsByAttribute("label", "parent");
- is(items.length, 1, "contextMenu item for parent was found (context=image)");
-
- is(items[0].childNodes[0].childNodes.length, 2, "child items for parent were found (context=image)");
-
- // Click on ext-image item and check the click results
- yield closeExtensionContextMenu(image);
-
- let result = yield extension.awaitMessage("onclick");
- checkClickInfo(result);
- result = yield extension.awaitMessage("browser.contextMenus.onClicked");
- checkClickInfo(result);
-
-
- // Test "editable" context and OnClick data property.
- extensionMenuRoot = yield openExtensionContextMenu("#edit-me");
-
- // Check some menu items.
- items = extensionMenuRoot.getElementsByAttribute("label", "editable");
- is(items.length, 1, "contextMenu item for text input element was found (context=editable)");
- let editable = items[0];
-
- // Click on ext-editable item and check the click results.
- yield closeExtensionContextMenu(editable);
-
- expectedClickInfo = {
- menuItemId: "ext-editable",
- pageUrl: PAGE,
- editable: true,
- };
-
- result = yield extension.awaitMessage("onclick");
- checkClickInfo(result);
- result = yield extension.awaitMessage("browser.contextMenus.onClicked");
- checkClickInfo(result);
-
-
- // Select some text
- yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
- let doc = content.document;
- let range = doc.createRange();
- let selection = content.getSelection();
- selection.removeAllRanges();
- let textNode = doc.getElementById("img1").previousSibling;
- range.setStart(textNode, 0);
- range.setEnd(textNode, 100);
- selection.addRange(range);
- });
-
- // Bring up context menu again
- extensionMenuRoot = yield openExtensionContextMenu();
-
- // Check some menu items
- items = extensionMenuRoot.getElementsByAttribute("label", "Without onclick property");
- is(items.length, 1, "contextMenu item was found (context=page)");
-
- yield closeExtensionContextMenu(items[0]);
-
- expectedClickInfo = {
- menuItemId: "ext-without-onclick",
- pageUrl: PAGE,
- };
-
- result = yield extension.awaitMessage("browser.contextMenus.onClicked");
- checkClickInfo(result);
-
- // Bring up context menu again
- extensionMenuRoot = yield openExtensionContextMenu();
-
- // Check some menu items
- items = extensionMenuRoot.getElementsByAttribute("label", "selection is: 'just some text 123456789012345678901234567890...'");
- is(items.length, 1, "contextMenu item for selection was found (context=selection)");
- let selectionItem = items[0];
-
- items = extensionMenuRoot.getElementsByAttribute("label", "selection");
- is(items.length, 0, "contextMenu item label update worked (context=selection)");
-
- yield closeExtensionContextMenu(selectionItem);
-
- expectedClickInfo = {
- menuItemId: "ext-selection",
- pageUrl: PAGE,
- selectionText: "just some text 1234567890123456789012345678901234567890123456789012345678901234567890123456789012",
- };
-
- result = yield extension.awaitMessage("onclick");
- checkClickInfo(result);
- result = yield extension.awaitMessage("browser.contextMenus.onClicked");
- checkClickInfo(result);
-
- let contentAreaContextMenu = yield openContextMenu("#img1");
- items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
- is(items.length, 0, "top level item was not found (after removeAll()");
- yield closeContextMenu();
-
- yield extension.unload();
- yield BrowserTestUtils.removeTab(tab1);
-});
-
-add_task(function* testRemoveAllWithTwoExtensions() {
- const tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
- const manifest = {permissions: ["contextMenus"]};
-
- const first = ExtensionTestUtils.loadExtension({manifest, background() {
- browser.contextMenus.create({title: "alpha", contexts: ["all"]});
-
- browser.contextMenus.onClicked.addListener(() => {
- browser.contextMenus.removeAll();
- });
- browser.test.onMessage.addListener(msg => {
- if (msg == "ping") {
- browser.test.sendMessage("pong-alpha");
- return;
- }
- browser.contextMenus.create({title: "gamma", contexts: ["all"]});
- });
- }});
-
- const second = ExtensionTestUtils.loadExtension({manifest, background() {
- browser.contextMenus.create({title: "beta", contexts: ["all"]});
-
- browser.contextMenus.onClicked.addListener(() => {
- browser.contextMenus.removeAll();
- });
-
- browser.test.onMessage.addListener(() => {
- browser.test.sendMessage("pong-beta");
- });
- }});
-
- yield first.startup();
- yield second.startup();
-
- function* confirmMenuItems(...items) {
- // Round-trip to extension to make sure that the context menu state has been
- // updated by the async contextMenus.create / contextMenus.removeAll calls.
- first.sendMessage("ping");
- second.sendMessage("ping");
- yield first.awaitMessage("pong-alpha");
- yield second.awaitMessage("pong-beta");
-
- const menu = yield openContextMenu();
- for (const id of ["alpha", "beta", "gamma"]) {
- const expected = items.includes(id);
- const found = menu.getElementsByAttribute("label", id);
- is(found.length, expected, `menu item ${id} ${expected ? "" : "not "}found`);
- }
- // Return the first menu item, we need to click it.
- return menu.getElementsByAttribute("label", items[0])[0];
- }
-
- // Confirm alpha, beta exist; click alpha to remove it.
- const alpha = yield confirmMenuItems("alpha", "beta");
- yield closeExtensionContextMenu(alpha);
-
- // Confirm only beta exists.
- yield confirmMenuItems("beta");
- yield closeContextMenu();
-
- // Create gamma, confirm, click.
- first.sendMessage("create");
- const beta = yield confirmMenuItems("beta", "gamma");
- yield closeExtensionContextMenu(beta);
-
- // Confirm only gamma is left.
- yield confirmMenuItems("gamma");
- yield closeContextMenu();
-
- yield first.unload();
- yield second.unload();
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js
deleted file mode 100644
index a3fa9d32c..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
-
- background: function() {
- // Report onClickData info back.
- browser.contextMenus.onClicked.addListener(info => {
- browser.test.sendMessage("contextmenus-click", info);
- });
-
- browser.contextMenus.create({
- title: "Checkbox",
- type: "checkbox",
- });
-
- browser.contextMenus.create({
- type: "separator",
- });
-
- browser.contextMenus.create({
- title: "Checkbox",
- type: "checkbox",
- checked: true,
- });
-
- browser.contextMenus.create({
- title: "Checkbox",
- type: "checkbox",
- });
-
- browser.test.notifyPass("contextmenus-checkboxes");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus-checkboxes");
-
- function confirmCheckboxStates(extensionMenuRoot, expectedStates) {
- let checkboxItems = extensionMenuRoot.getElementsByAttribute("type", "checkbox");
-
- is(checkboxItems.length, 3, "there should be 3 checkbox items in the context menu");
-
- is(checkboxItems[0].hasAttribute("checked"), expectedStates[0], `checkbox item 1 has state (checked=${expectedStates[0]})`);
- is(checkboxItems[1].hasAttribute("checked"), expectedStates[1], `checkbox item 2 has state (checked=${expectedStates[1]})`);
- is(checkboxItems[2].hasAttribute("checked"), expectedStates[2], `checkbox item 3 has state (checked=${expectedStates[2]})`);
-
- return extensionMenuRoot.getElementsByAttribute("type", "checkbox");
- }
-
- function confirmOnClickData(onClickData, id, was, checked) {
- is(onClickData.wasChecked, was, `checkbox item ${id} was ${was ? "" : "not "}checked before the click`);
- is(onClickData.checked, checked, `checkbox item ${id} is ${checked ? "" : "not "}checked after the click`);
- }
-
- let extensionMenuRoot = yield openExtensionContextMenu();
- let items = confirmCheckboxStates(extensionMenuRoot, [false, true, false]);
- yield closeExtensionContextMenu(items[0]);
-
- let result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 1, false, true);
-
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmCheckboxStates(extensionMenuRoot, [true, true, false]);
- yield closeExtensionContextMenu(items[2]);
-
- result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 3, false, true);
-
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmCheckboxStates(extensionMenuRoot, [true, true, true]);
- yield closeExtensionContextMenu(items[0]);
-
- result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 1, true, false);
-
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmCheckboxStates(extensionMenuRoot, [false, true, true]);
- yield closeExtensionContextMenu(items[2]);
-
- result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 3, true, false);
-
- yield extension.unload();
- yield BrowserTestUtils.removeTab(tab1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_icons.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_icons.js
deleted file mode 100644
index a3d31bd19..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_icons.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
-
- let encodedImageData = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAC4klEQVRYhdWXLWzbQBSADQtDAwsHC1tUhUxqfL67lk2tdn+OJg0ODU0rLByqgqINBY6tmlbn7LMTJ5FaFVVBk1G0oUGjG2jT2Y7jxmmcbU/6iJ+f36fz+e5sGP9riCGm9hB37RG+scd4Yo/wsDXCZyIE2xuXsce4bY+wXkAsQtzYmExrfFgvkJkRbkzo1ehoxx5iXcgI/9iYUGt8WH9MqDXEcmNChmEYrRCf2SHWeYgQx3x0tLNRIeKQLTtEFyJEep4NTuhk8BC+yMrwEE3+iozo42d8gK7FAOkMsRiiN8QhW2ttSK5QTfRRV4QoymVeJMvPvDp7gCZigD613MN6yRFA3SWarow9QB9LCfG+NeF9qCtjAKOSQjCqVKhfVsiHEQ+grgx/lRGqUihAc1uL8EFD+KCRO+GrF4J61phcoRoPoEzkYhZYpykh5sMb7kOdIeY+jHKur4QI4Feh4AFX1nVeLxrAvQchGsBz5ls6wa2QdwcvIcE2863bTH79KOvsz/uUYJsp+J0pSzNlDckVqqVGUAF+n6uS7txcOl6wot4JVy70ufDLy4pWLUQVPE81pRI0mGe9oxLMHSeohHvMs/STUNaUK6vDPCvOyxMFDx4achehRDJmHnydnkPww5OFfLxrGIZBFDyYl4LpMzlTQFIP6AQx86w2UeYBccFpJrcKv5L9eGDtUAU6RIELqsB74uynjy/UBRF1gS5BTFxwQT1wTiXoUg9MH7m/3NZRRoi5IJytUbMgzv4Wc832+oQkiKgEehmyMkkpKsFkQV11QsRJL5rJYBLItQgRaUZEmnoZXsomz3vGiWw+I9KMF9SVFOqZEemZekli1jN3U/UOqhHHvC6oWWGElhfSpGdOk6+O9prdwvtLj5BjRsQxdRnot+Zeifpy/2/0stktKTRNLmbk0mwXyl8253fyojj+8rxOHNAhjjm5n0/5OOCGOKBzkrMO0Z75lvSAzKlrF32Z/3z8BqLAn+yMV7VhAAAAAElFTkSuQmCC";
- let decodedImageData = atob(encodedImageData);
- const IMAGE_ARRAYBUFFER = Uint8Array.from(decodedImageData, byte => byte.charCodeAt(0)).buffer;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- "icons": {
- "18": "extension.png",
- },
- },
-
- files: {
- "extension.png": IMAGE_ARRAYBUFFER,
- },
-
- background: function() {
- let menuitemId = browser.contextMenus.create({
- title: "child-to-delete",
- onclick: () => {
- browser.contextMenus.remove(menuitemId);
- },
- });
-
- browser.contextMenus.create({
- title: "child",
- });
-
- browser.test.onMessage.addListener(() => {
- browser.test.sendMessage("pong");
- });
- browser.test.notifyPass("contextmenus-icons");
- },
- });
-
- let confirmContextMenuIcon = (rootElement) => {
- let expectedURL = new RegExp(String.raw`^moz-extension://[^/]+/extension\.png$`);
- let imageUrl = rootElement.getAttribute("image");
- ok(expectedURL.test(imageUrl), "The context menu should display the extension icon next to the root element");
- };
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus-icons");
-
- let extensionMenu = yield openExtensionContextMenu();
-
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let topLevelMenuItem = contextMenu.getElementsByAttribute("ext-type", "top-level-menu")[0];
- confirmContextMenuIcon(topLevelMenuItem);
-
- let childToDelete = extensionMenu.getElementsByAttribute("label", "child-to-delete")[0];
- yield closeExtensionContextMenu(childToDelete);
- // Now perform a roundtrip to the extension process to make sure that the
- // click event has had a chance to fire.
- extension.sendMessage("ping");
- yield extension.awaitMessage("pong");
-
- yield openExtensionContextMenu();
-
- contextMenu = document.getElementById("contentAreaContextMenu");
- topLevelMenuItem = contextMenu.getElementsByAttribute("label", "child")[0];
-
- confirmContextMenuIcon(topLevelMenuItem);
- yield closeContextMenu();
-
- yield extension.unload();
- yield BrowserTestUtils.removeTab(tab1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_onclick.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_onclick.js
deleted file mode 100644
index 96453863d..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_onclick.js
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-// Loaded both as a background script and a tab page.
-function testScript() {
- let page = location.pathname.includes("tab.html") ? "tab" : "background";
- let clickCounts = {
- old: 0,
- new: 0,
- };
- browser.contextMenus.onClicked.addListener(() => {
- // Async to give other onclick handlers a chance to fire.
- setTimeout(() => {
- browser.test.sendMessage("onClicked-fired", page);
- });
- });
- browser.test.onMessage.addListener((toPage, msg) => {
- if (toPage !== page) {
- return;
- }
- browser.test.log(`Received ${msg} for ${toPage}`);
- if (msg == "get-click-counts") {
- browser.test.sendMessage("click-counts", clickCounts);
- } else if (msg == "clear-click-counts") {
- clickCounts.old = clickCounts.new = 0;
- browser.test.sendMessage("next");
- } else if (msg == "create-with-onclick") {
- browser.contextMenus.create({
- id: "iden",
- title: "tifier",
- onclick() {
- ++clickCounts.old;
- browser.test.log(`onclick fired for original onclick property in ${page}`);
- },
- }, () => browser.test.sendMessage("next"));
- } else if (msg == "create-without-onclick") {
- browser.contextMenus.create({
- id: "iden",
- title: "tifier",
- }, () => browser.test.sendMessage("next"));
- } else if (msg == "update-without-onclick") {
- browser.contextMenus.update("iden", {
- enabled: true, // Already enabled, so this does nothing.
- }, () => browser.test.sendMessage("next"));
- } else if (msg == "update-with-onclick") {
- browser.contextMenus.update("iden", {
- onclick() {
- ++clickCounts.new;
- browser.test.log(`onclick fired for updated onclick property in ${page}`);
- },
- }, () => browser.test.sendMessage("next"));
- } else if (msg == "remove") {
- browser.contextMenus.remove("iden", () => browser.test.sendMessage("next"));
- } else if (msg == "removeAll") {
- browser.contextMenus.removeAll(() => browser.test.sendMessage("next"));
- }
- });
-
- if (page == "background") {
- browser.test.log("Opening tab.html");
- browser.tabs.create({
- url: "tab.html",
- active: false, // To not interfere with the context menu tests.
- });
- } else {
- // Sanity check - the pages must be in the same process.
- let pages = browser.extension.getViews();
- browser.test.assertTrue(pages.includes(window),
- "Expected this tab to be an extension view");
- pages = pages.filter(w => w !== window);
- browser.test.assertEq(pages[0], browser.extension.getBackgroundPage(),
- "Expected the other page to be a background page");
- browser.test.sendMessage("tab.html ready");
- }
-}
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
- background: testScript,
- files: {
- "tab.html": `<!DOCTYPE html><meta charset="utf-8"><script src="tab.js"></script>`,
- "tab.js": testScript,
- },
- });
- yield extension.startup();
- yield extension.awaitMessage("tab.html ready");
-
- function* clickContextMenu() {
- // Using openContextMenu instead of openExtensionContextMenu because the
- // test extension has only one context menu item.
- let extensionMenuRoot = yield openContextMenu();
- let items = extensionMenuRoot.getElementsByAttribute("label", "tifier");
- is(items.length, 1, "Expected one context menu item");
- yield closeExtensionContextMenu(items[0]);
- // One of them is "tab", the other is "background".
- info(`onClicked from: ${yield extension.awaitMessage("onClicked-fired")}`);
- info(`onClicked from: ${yield extension.awaitMessage("onClicked-fired")}`);
- }
-
- function* getCounts(page) {
- extension.sendMessage(page, "get-click-counts");
- return yield extension.awaitMessage("click-counts");
- }
- function* resetCounts() {
- extension.sendMessage("tab", "clear-click-counts");
- extension.sendMessage("background", "clear-click-counts");
- yield extension.awaitMessage("next");
- yield extension.awaitMessage("next");
- }
-
- // During this test, at most one "onclick" attribute is expected at any time.
- for (let pageOne of ["background", "tab"]) {
- for (let pageTwo of ["background", "tab"]) {
- info(`Testing with menu created by ${pageOne} and updated by ${pageTwo}`);
- extension.sendMessage(pageOne, "create-with-onclick");
- yield extension.awaitMessage("next");
-
- // Test that update without onclick attribute does not clear the existing
- // onclick handler.
- extension.sendMessage(pageTwo, "update-without-onclick");
- yield extension.awaitMessage("next");
- yield clickContextMenu();
- let clickCounts = yield getCounts(pageOne);
- is(clickCounts.old, 1, `Original onclick should still be present in ${pageOne}`);
- is(clickCounts.new, 0, `Not expecting any new handlers in ${pageOne}`);
- if (pageOne !== pageTwo) {
- clickCounts = yield getCounts(pageTwo);
- is(clickCounts.old, 0, `Not expecting any handlers in ${pageTwo}`);
- is(clickCounts.new, 0, `Not expecting any new handlers in ${pageTwo}`);
- }
- yield resetCounts();
-
- // Test that update with onclick handler in a different page clears the
- // existing handler and activates the new onclick handler.
- extension.sendMessage(pageTwo, "update-with-onclick");
- yield extension.awaitMessage("next");
- yield clickContextMenu();
- clickCounts = yield getCounts(pageOne);
- is(clickCounts.old, 0, `Original onclick should be gone from ${pageOne}`);
- if (pageOne !== pageTwo) {
- is(clickCounts.new, 0, `Still not expecting new handlers in ${pageOne}`);
- }
- clickCounts = yield getCounts(pageTwo);
- if (pageOne !== pageTwo) {
- is(clickCounts.old, 0, `Not expecting an old onclick in ${pageTwo}`);
- }
- is(clickCounts.new, 1, `New onclick should be triggered in ${pageTwo}`);
- yield resetCounts();
-
- // Test that updating the handler (different again from the last `update`
- // call, but the same as the `create` call) clears the existing handler
- // and activates the new onclick handler.
- extension.sendMessage(pageOne, "update-with-onclick");
- yield extension.awaitMessage("next");
- yield clickContextMenu();
- clickCounts = yield getCounts(pageOne);
- is(clickCounts.new, 1, `onclick should be triggered in ${pageOne}`);
- if (pageOne !== pageTwo) {
- clickCounts = yield getCounts(pageTwo);
- is(clickCounts.new, 0, `onclick should be gone from ${pageTwo}`);
- }
- yield resetCounts();
-
- // Test that removing the context menu and recreating it with the same ID
- // (in a different context) does not leave behind any onclick handlers.
- extension.sendMessage(pageTwo, "remove");
- yield extension.awaitMessage("next");
- extension.sendMessage(pageTwo, "create-without-onclick");
- yield extension.awaitMessage("next");
- yield clickContextMenu();
- clickCounts = yield getCounts(pageOne);
- is(clickCounts.new, 0, `Did not expect any click handlers in ${pageOne}`);
- if (pageOne !== pageTwo) {
- clickCounts = yield getCounts(pageTwo);
- is(clickCounts.new, 0, `Did not expect any click handlers in ${pageTwo}`);
- }
- yield resetCounts();
-
- // Remove context menu for the next iteration of the test. And just to get
- // more coverage, let's use removeAll instead of remove.
- extension.sendMessage(pageOne, "removeAll");
- yield extension.awaitMessage("next");
- }
- }
- yield extension.unload();
- yield BrowserTestUtils.removeTab(tab1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js
deleted file mode 100644
index 3c5fa584b..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
-
- background: function() {
- // Report onClickData info back.
- browser.contextMenus.onClicked.addListener(info => {
- browser.test.sendMessage("contextmenus-click", info);
- });
-
- browser.contextMenus.create({
- title: "radio-group-1",
- type: "radio",
- checked: true,
- });
-
- browser.contextMenus.create({
- type: "separator",
- });
-
- browser.contextMenus.create({
- title: "radio-group-2",
- type: "radio",
- });
-
- browser.contextMenus.create({
- title: "radio-group-2",
- type: "radio",
- });
-
- browser.test.notifyPass("contextmenus-radio-groups");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus-radio-groups");
-
- function confirmRadioGroupStates(extensionMenuRoot, expectedStates) {
- let radioItems = extensionMenuRoot.getElementsByAttribute("type", "radio");
- let radioGroup1 = extensionMenuRoot.getElementsByAttribute("label", "radio-group-1");
- let radioGroup2 = extensionMenuRoot.getElementsByAttribute("label", "radio-group-2");
-
- is(radioItems.length, 3, "there should be 3 radio items in the context menu");
- is(radioGroup1.length, 1, "the first radio group should only have 1 radio item");
- is(radioGroup2.length, 2, "the second radio group should only have 2 radio items");
-
- is(radioGroup1[0].hasAttribute("checked"), expectedStates[0], `radio item 1 has state (checked=${expectedStates[0]})`);
- is(radioGroup2[0].hasAttribute("checked"), expectedStates[1], `radio item 2 has state (checked=${expectedStates[1]})`);
- is(radioGroup2[1].hasAttribute("checked"), expectedStates[2], `radio item 3 has state (checked=${expectedStates[2]})`);
-
- return extensionMenuRoot.getElementsByAttribute("type", "radio");
- }
-
- function confirmOnClickData(onClickData, id, was, checked) {
- is(onClickData.wasChecked, was, `radio item ${id} was ${was ? "" : "not "}checked before the click`);
- is(onClickData.checked, checked, `radio item ${id} is ${checked ? "" : "not "}checked after the click`);
- }
-
- let extensionMenuRoot = yield openExtensionContextMenu();
- let items = confirmRadioGroupStates(extensionMenuRoot, [true, false, false]);
- yield closeExtensionContextMenu(items[1]);
-
- let result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 2, false, true);
-
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmRadioGroupStates(extensionMenuRoot, [true, true, false]);
- yield closeExtensionContextMenu(items[2]);
-
- result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 3, false, true);
-
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
- yield closeExtensionContextMenu(items[0]);
-
- result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 1, true, true);
-
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
- yield closeExtensionContextMenu(items[0]);
-
- result = yield extension.awaitMessage("contextmenus-click");
- confirmOnClickData(result, 1, true, true);
-
- yield extension.unload();
- yield BrowserTestUtils.removeTab(tab1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_uninstall.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_uninstall.js
deleted file mode 100644
index fdf06d656..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_uninstall.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
-
- // Install an extension.
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
-
- background: function() {
- browser.contextMenus.create({title: "a"});
- browser.contextMenus.create({title: "b"});
- browser.test.notifyPass("contextmenus-icons");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus-icons");
-
- // Open the context menu.
- let contextMenu = yield openContextMenu("#img1");
-
- // Confirm that the extension menu item exists.
- let topLevelExtensionMenuItems = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
- is(topLevelExtensionMenuItems.length, 1, "the top level extension menu item exists");
-
- yield closeContextMenu();
-
- // Uninstall the extension.
- yield extension.unload();
-
- // Open the context menu.
- contextMenu = yield openContextMenu("#img1");
-
- // Confirm that the extension menu item has been removed.
- topLevelExtensionMenuItems = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
- is(topLevelExtensionMenuItems.length, 0, "no top level extension menu items should exist");
-
- yield closeContextMenu();
-
- // Install a new extension.
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
- background: function() {
- browser.contextMenus.create({title: "c"});
- browser.contextMenus.create({title: "d"});
- browser.test.notifyPass("contextmenus-uninstall-second-extension");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus-uninstall-second-extension");
-
- // Open the context menu.
- contextMenu = yield openContextMenu("#img1");
-
- // Confirm that only the new extension menu item is in the context menu.
- topLevelExtensionMenuItems = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
- is(topLevelExtensionMenuItems.length, 1, "only one top level extension menu item should exist");
-
- // Close the context menu.
- yield closeContextMenu();
-
- // Uninstall the extension.
- yield extension.unload();
-
- // Open the context menu.
- contextMenu = yield openContextMenu("#img1");
-
- // Confirm that no extension menu items exist.
- topLevelExtensionMenuItems = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
- is(topLevelExtensionMenuItems.length, 0, "no top level extension menu items should exist");
-
- yield closeContextMenu();
-
- yield BrowserTestUtils.removeTab(tab1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_urlPatterns.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_urlPatterns.js
deleted file mode 100644
index 7849b8778..000000000
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_urlPatterns.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["contextMenus"],
- },
-
- background: function() {
- // Test menu items using targetUrlPatterns.
- browser.contextMenus.create({
- title: "targetUrlPatterns-patternMatches-contextAll",
- targetUrlPatterns: ["*://*/*ctxmenu-image.png", "*://*/*some-link"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "targetUrlPatterns-patternMatches-contextImage",
- targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "targetUrlPatterns-patternMatches-contextLink",
- targetUrlPatterns: ["*://*/*some-link"],
- contexts: ["link"],
- });
-
- browser.contextMenus.create({
- title: "targetUrlPatterns-patternDoesNotMatch-contextAll",
- targetUrlPatterns: ["*://*/does-not-match"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "targetUrlPatterns-patternDoesNotMatch-contextImage",
- targetUrlPatterns: ["*://*/does-not-match"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "targetUrlPatterns-patternDoesNotMatch-contextLink",
- targetUrlPatterns: ["*://*/does-not-match"],
- contexts: ["link"],
- });
-
- // Test menu items using documentUrlPatterns.
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-contextAll",
- documentUrlPatterns: ["*://*/*context.html"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-contextImage",
- documentUrlPatterns: ["*://*/*context.html", "http://*/url-that-does-not-match"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-contextLink",
- documentUrlPatterns: ["*://*/*context.html", "*://*/does-not-match"],
- contexts: ["link"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-contextAll",
- documentUrlPatterns: ["*://*/does-not-match"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-contextImage",
- documentUrlPatterns: ["*://*/does-not-match"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-contextLink",
- documentUrlPatterns: ["*://*/does-not-match"],
- contexts: ["link"],
- });
-
- // Test menu items using both targetUrlPatterns and documentUrlPatterns.
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextAll",
- documentUrlPatterns: ["*://*/*context.html"],
- targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextAll",
- documentUrlPatterns: ["*://does-not-match"],
- targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextAll",
- documentUrlPatterns: ["*://*/*context.html"],
- targetUrlPatterns: ["*://does-not-match"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextAll",
- documentUrlPatterns: ["*://does-not-match"],
- targetUrlPatterns: ["*://does-not-match"],
- contexts: ["all"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextImage",
- documentUrlPatterns: ["*://*/*context.html"],
- targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextImage",
- documentUrlPatterns: ["*://does-not-match"],
- targetUrlPatterns: ["*://*/*ctxmenu-image.png"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextImage",
- documentUrlPatterns: ["*://*/*context.html"],
- targetUrlPatterns: ["*://does-not-match"],
- contexts: ["image"],
- });
-
- browser.contextMenus.create({
- title: "documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextImage",
- documentUrlPatterns: ["*://does-not-match"],
- targetUrlPatterns: ["*://does-not-match"],
- contexts: ["image"],
- });
-
- browser.test.notifyPass("contextmenus-urlPatterns");
- },
- });
-
- function* confirmContextMenuItems(menu, expected) {
- for (let [label, shouldShow] of expected) {
- let items = menu.getElementsByAttribute("label", label);
- if (shouldShow) {
- is(items.length, 1, `The menu item for label ${label} was correctly shown`);
- } else {
- is(items.length, 0, `The menu item for label ${label} was correctly not shown`);
- }
- }
- }
-
- yield extension.startup();
- yield extension.awaitFinish("contextmenus-urlPatterns");
-
- let extensionContextMenu = yield openExtensionContextMenu("#img1");
- let expected = [
- ["targetUrlPatterns-patternMatches-contextAll", true],
- ["targetUrlPatterns-patternMatches-contextImage", true],
- ["targetUrlPatterns-patternMatches-contextLink", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextLink", false],
- ["documentUrlPatterns-patternMatches-contextAll", true],
- ["documentUrlPatterns-patternMatches-contextImage", true],
- ["documentUrlPatterns-patternMatches-contextLink", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextLink", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextAll", true],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextAll", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextImage", true],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextImage", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ];
- yield confirmContextMenuItems(extensionContextMenu, expected);
- yield closeContextMenu();
-
- let contextMenu = yield openContextMenu("body");
- expected = [
- ["targetUrlPatterns-patternMatches-contextAll", false],
- ["targetUrlPatterns-patternMatches-contextImage", false],
- ["targetUrlPatterns-patternMatches-contextLink", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextLink", false],
- ["documentUrlPatterns-patternMatches-contextAll", true],
- ["documentUrlPatterns-patternMatches-contextImage", false],
- ["documentUrlPatterns-patternMatches-contextLink", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextLink", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextAll", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternMatches-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternMatches-contextImage", false],
- ["documentUrlPatterns-patternMatches-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ];
- yield confirmContextMenuItems(contextMenu, expected);
- yield closeContextMenu();
-
- contextMenu = yield openContextMenu("#link1");
- expected = [
- ["targetUrlPatterns-patternMatches-contextAll", true],
- ["targetUrlPatterns-patternMatches-contextImage", false],
- ["targetUrlPatterns-patternMatches-contextLink", true],
- ["targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextLink", false],
- ["documentUrlPatterns-patternMatches-contextAll", true],
- ["documentUrlPatterns-patternMatches-contextImage", false],
- ["documentUrlPatterns-patternMatches-contextLink", true],
- ["documentUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextLink", false],
- ];
- yield confirmContextMenuItems(contextMenu, expected);
- yield closeContextMenu();
-
- contextMenu = yield openContextMenu("#img-wrapped-in-link");
- expected = [
- ["targetUrlPatterns-patternMatches-contextAll", true],
- ["targetUrlPatterns-patternMatches-contextImage", true],
- ["targetUrlPatterns-patternMatches-contextLink", true],
- ["targetUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["targetUrlPatterns-patternDoesNotMatch-contextLink", false],
- ["documentUrlPatterns-patternMatches-contextAll", true],
- ["documentUrlPatterns-patternMatches-contextImage", true],
- ["documentUrlPatterns-patternMatches-contextLink", true],
- ["documentUrlPatterns-patternDoesNotMatch-contextAll", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextImage", false],
- ["documentUrlPatterns-patternDoesNotMatch-contextLink", false],
- ];
- yield confirmContextMenuItems(contextMenu, expected);
- yield closeContextMenu();
-
- yield extension.unload();
- yield BrowserTestUtils.removeTab(tab1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_currentWindow.js b/browser/components/extensions/test/browser/browser_ext_currentWindow.js
deleted file mode 100644
index 11660bf4d..000000000
--- a/browser/components/extensions/test/browser/browser_ext_currentWindow.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function genericChecker() {
- let kind = "background";
- let path = window.location.pathname;
- if (path.includes("/popup.html")) {
- kind = "popup";
- } else if (path.includes("/page.html")) {
- kind = "page";
- }
-
- browser.test.onMessage.addListener((msg, ...args) => {
- if (msg == kind + "-check-current1") {
- browser.tabs.query({
- currentWindow: true,
- }, function(tabs) {
- browser.test.sendMessage("result", tabs[0].windowId);
- });
- } else if (msg == kind + "-check-current2") {
- browser.tabs.query({
- windowId: browser.windows.WINDOW_ID_CURRENT,
- }, function(tabs) {
- browser.test.sendMessage("result", tabs[0].windowId);
- });
- } else if (msg == kind + "-check-current3") {
- browser.windows.getCurrent(function(window) {
- browser.test.sendMessage("result", window.id);
- });
- } else if (msg == kind + "-open-page") {
- browser.tabs.create({windowId: args[0], url: browser.runtime.getURL("page.html")});
- } else if (msg == kind + "-close-page") {
- browser.tabs.query({
- windowId: args[0],
- }, tabs => {
- let tab = tabs.find(tab => tab.url.includes("/page.html"));
- browser.tabs.remove(tab.id, () => {
- browser.test.sendMessage("closed");
- });
- });
- }
- });
- browser.test.sendMessage(kind + "-ready");
-}
-
-add_task(function* () {
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- yield focusWindow(win2);
-
- yield BrowserTestUtils.loadURI(win1.gBrowser.selectedBrowser, "about:robots");
- yield BrowserTestUtils.browserLoaded(win1.gBrowser.selectedBrowser);
-
- yield BrowserTestUtils.loadURI(win2.gBrowser.selectedBrowser, "about:config");
- yield BrowserTestUtils.browserLoaded(win2.gBrowser.selectedBrowser);
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
-
- "browser_action": {
- "default_popup": "popup.html",
- },
- },
-
- files: {
- "page.html": `
- <!DOCTYPE html>
- <html><body>
- <script src="page.js"></script>
- </body></html>
- `,
-
- "page.js": genericChecker,
-
- "popup.html": `
- <!DOCTYPE html>
- <html><body>
- <script src="popup.js"></script>
- </body></html>
- `,
-
- "popup.js": genericChecker,
- },
-
- background: genericChecker,
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("background-ready")]);
-
- let {Management: {global: {WindowManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let winId1 = WindowManager.getId(win1);
- let winId2 = WindowManager.getId(win2);
-
- function* checkWindow(kind, winId, name) {
- extension.sendMessage(kind + "-check-current1");
- is((yield extension.awaitMessage("result")), winId, `${name} is on top (check 1) [${kind}]`);
- extension.sendMessage(kind + "-check-current2");
- is((yield extension.awaitMessage("result")), winId, `${name} is on top (check 2) [${kind}]`);
- extension.sendMessage(kind + "-check-current3");
- is((yield extension.awaitMessage("result")), winId, `${name} is on top (check 3) [${kind}]`);
- }
-
- yield focusWindow(win1);
- yield checkWindow("background", winId1, "win1");
- yield focusWindow(win2);
- yield checkWindow("background", winId2, "win2");
-
- function* triggerPopup(win, callback) {
- yield clickBrowserAction(extension, win);
- yield awaitExtensionPanel(extension, win);
-
- yield extension.awaitMessage("popup-ready");
-
- yield callback();
-
- closeBrowserAction(extension, win);
- }
-
- // Set focus to some other window.
- yield focusWindow(window);
-
- yield triggerPopup(win1, function* () {
- yield checkWindow("popup", winId1, "win1");
- });
-
- yield triggerPopup(win2, function* () {
- yield checkWindow("popup", winId2, "win2");
- });
-
- function* triggerPage(winId, name) {
- extension.sendMessage("background-open-page", winId);
- yield extension.awaitMessage("page-ready");
- yield checkWindow("page", winId, name);
- extension.sendMessage("background-close-page", winId);
- yield extension.awaitMessage("closed");
- }
-
- yield triggerPage(winId1, "win1");
- yield triggerPage(winId2, "win2");
-
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(win1);
- yield BrowserTestUtils.closeWindow(win2);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_getViews.js b/browser/components/extensions/test/browser/browser_ext_getViews.js
deleted file mode 100644
index 684e19ac5..000000000
--- a/browser/components/extensions/test/browser/browser_ext_getViews.js
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function genericChecker() {
- let kind = "background";
- let path = window.location.pathname;
- if (path.indexOf("popup") != -1) {
- kind = "popup";
- } else if (path.indexOf("tab") != -1) {
- kind = "tab";
- }
- window.kind = kind;
-
- browser.test.onMessage.addListener((msg, ...args) => {
- if (msg == kind + "-check-views") {
- let windowId = args[0];
- let counts = {
- "background": 0,
- "tab": 0,
- "popup": 0,
- "kind": 0,
- "window": 0,
- };
- if (Number.isInteger(windowId)) {
- counts.window = browser.extension.getViews({windowId: windowId}).length;
- }
- if (kind !== "background") {
- counts.kind = browser.extension.getViews({type: kind}).length;
- }
- let views = browser.extension.getViews();
- let background;
- for (let i = 0; i < views.length; i++) {
- let view = views[i];
- browser.test.assertTrue(view.kind in counts, "view type is valid");
- counts[view.kind]++;
- if (view.kind == "background") {
- browser.test.assertTrue(view === browser.extension.getBackgroundPage(),
- "background page is correct");
- background = view;
- }
- }
- if (background) {
- browser.runtime.getBackgroundPage().then(view => {
- browser.test.assertEq(background, view, "runtime.getBackgroundPage() is correct");
- browser.test.sendMessage("counts", counts);
- });
- } else {
- browser.test.sendMessage("counts", counts);
- }
- } else if (msg == kind + "-open-tab") {
- browser.tabs.create({windowId: args[0], url: browser.runtime.getURL("tab.html")});
- } else if (msg == kind + "-close-tab") {
- browser.tabs.query({
- windowId: args[0],
- }, tabs => {
- let tab = tabs.find(tab => tab.url.indexOf("tab.html") != -1);
- browser.tabs.remove(tab.id, () => {
- browser.test.sendMessage("closed");
- });
- });
- }
- });
- browser.test.sendMessage(kind + "-ready");
-}
-
-add_task(function* () {
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
-
- "browser_action": {
- "default_popup": "popup.html",
- },
- },
-
- files: {
- "tab.html": `
- <!DOCTYPE html>
- <html><body>
- <script src="tab.js"></script>
- </body></html>
- `,
-
- "tab.js": genericChecker,
-
- "popup.html": `
- <!DOCTYPE html>
- <html><body>
- <script src="popup.js"></script>
- </body></html>
- `,
-
- "popup.js": genericChecker,
- },
-
- background: genericChecker,
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("background-ready")]);
-
- info("started");
-
- let {Management: {global: {WindowManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let winId1 = WindowManager.getId(win1);
- let winId2 = WindowManager.getId(win2);
-
- function* openTab(winId) {
- extension.sendMessage("background-open-tab", winId);
- yield extension.awaitMessage("tab-ready");
- }
-
- function* checkViews(kind, tabCount, popupCount, kindCount, windowId = undefined, windowCount = 0) {
- extension.sendMessage(kind + "-check-views", windowId);
- let counts = yield extension.awaitMessage("counts");
- is(counts.background, 1, "background count correct");
- is(counts.tab, tabCount, "tab count correct");
- is(counts.popup, popupCount, "popup count correct");
- is(counts.kind, kindCount, "count for type correct");
- is(counts.window, windowCount, "count for window correct");
- }
-
- yield checkViews("background", 0, 0, 0);
-
- yield openTab(winId1);
-
- yield checkViews("background", 1, 0, 0, winId1, 1);
- yield checkViews("tab", 1, 0, 1);
-
- yield openTab(winId2);
-
- yield checkViews("background", 2, 0, 0, winId2, 1);
-
- function* triggerPopup(win, callback) {
- yield clickBrowserAction(extension, win);
- yield awaitExtensionPanel(extension, win);
-
- yield extension.awaitMessage("popup-ready");
-
- yield callback();
-
- closeBrowserAction(extension, win);
- }
-
- // The popup occasionally closes prematurely if we open it immediately here.
- // I'm not sure what causes it to close (it's something internal, and seems to
- // be focus-related, but it's not caused by JS calling hidePopup), but even a
- // short timeout seems to consistently fix it.
- yield new Promise(resolve => win1.setTimeout(resolve, 10));
-
- yield triggerPopup(win1, function* () {
- yield checkViews("background", 2, 1, 0, winId1, 2);
- yield checkViews("popup", 2, 1, 1);
- });
-
- yield triggerPopup(win2, function* () {
- yield checkViews("background", 2, 1, 0, winId2, 2);
- yield checkViews("popup", 2, 1, 1);
- });
-
- info("checking counts after popups");
-
- yield checkViews("background", 2, 0, 0, winId1, 1);
-
- info("closing one tab");
-
- extension.sendMessage("background-close-tab", winId1);
- yield extension.awaitMessage("closed");
-
- info("one tab closed, one remains");
-
- yield checkViews("background", 1, 0, 0);
-
- info("opening win1 popup");
-
- yield triggerPopup(win1, function* () {
- yield checkViews("background", 1, 1, 0);
- yield checkViews("tab", 1, 1, 1);
- yield checkViews("popup", 1, 1, 1);
- });
-
- info("opening win2 popup");
-
- yield triggerPopup(win2, function* () {
- yield checkViews("background", 1, 1, 0);
- yield checkViews("tab", 1, 1, 1);
- yield checkViews("popup", 1, 1, 1);
- });
-
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(win1);
- yield BrowserTestUtils.closeWindow(win2);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_incognito_popup.js b/browser/components/extensions/test/browser/browser_ext_incognito_popup.js
deleted file mode 100644
index 174b2179d..000000000
--- a/browser/components/extensions/test/browser/browser_ext_incognito_popup.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testIncognitoPopup() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- "browser_action": {
- "default_popup": "popup.html",
- },
- "page_action": {
- "default_popup": "popup.html",
- },
- },
-
- background: async function() {
- let resolveMessage;
- browser.runtime.onMessage.addListener(msg => {
- if (resolveMessage && msg.message == "popup-details") {
- resolveMessage(msg);
- }
- });
-
- let awaitPopup = windowId => {
- return new Promise(resolve => {
- resolveMessage = resolve;
- }).then(msg => {
- browser.test.assertEq(windowId, msg.windowId, "Got popup message from correct window");
- return msg;
- });
- };
-
- let testWindow = async window => {
- let [tab] = await browser.tabs.query({active: true, windowId: window.id});
-
- await browser.pageAction.show(tab.id);
- browser.test.sendMessage("click-pageAction");
-
- let msg = await awaitPopup(window.id);
- browser.test.assertEq(window.incognito, msg.incognito, "Correct incognito status in pageAction popup");
-
- browser.test.sendMessage("click-browserAction");
-
- msg = await awaitPopup(window.id);
- browser.test.assertEq(window.incognito, msg.incognito, "Correct incognito status in browserAction popup");
- };
-
- const URL = "http://example.com/incognito";
- let windowReady = new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId, changed, tab) {
- if (changed.status == "complete" && tab.url == URL) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
-
- try {
- {
- let window = await browser.windows.getCurrent();
-
- await testWindow(window);
- }
-
- {
- let window = await browser.windows.create({incognito: true, url: URL});
- await windowReady;
-
- await testWindow(window);
-
- await browser.windows.remove(window.id);
- }
-
- browser.test.notifyPass("incognito");
- } catch (error) {
- browser.test.fail(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("incognito");
- }
- },
-
- files: {
- "popup.html": '<html><head><meta charset="utf-8"><script src="popup.js"></script></head></html>',
-
- "popup.js": async function() {
- let win = await browser.windows.getCurrent();
- browser.runtime.sendMessage({
- message: "popup-details",
- windowId: win.id,
- incognito: browser.extension.inIncognitoContext,
- });
- window.close();
- },
- },
- });
-
- extension.onMessage("click-browserAction", () => {
- clickBrowserAction(extension, Services.wm.getMostRecentWindow("navigator:browser"));
- });
-
- extension.onMessage("click-pageAction", () => {
- clickPageAction(extension, Services.wm.getMostRecentWindow("navigator:browser"));
- });
-
- yield extension.startup();
- yield extension.awaitFinish("incognito");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_incognito_views.js b/browser/components/extensions/test/browser/browser_ext_incognito_views.js
deleted file mode 100644
index 4865b2d4f..000000000
--- a/browser/components/extensions/test/browser/browser_ext_incognito_views.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testIncognitoViews() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- "browser_action": {
- "default_popup": "popup.html",
- },
- },
-
- background: async function() {
- window.isBackgroundPage = true;
-
- let resolveMessage;
- browser.runtime.onMessage.addListener(msg => {
- if (resolveMessage && msg.message == "popup-details") {
- resolveMessage(msg);
- }
- });
-
- let awaitPopup = windowId => {
- return new Promise(resolve => {
- resolveMessage = resolve;
- }).then(msg => {
- browser.test.assertEq(windowId, msg.windowId, "Got popup message from correct window");
- return msg;
- });
- };
-
- let testWindow = async window => {
- browser.test.sendMessage("click-browserAction");
-
- let msg = await awaitPopup(window.id);
- browser.test.assertEq(window.incognito, msg.incognito, "Correct incognito status in browserAction popup");
- };
-
- const URL = "http://example.com/incognito";
- let windowReady = new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId, changed, tab) {
- if (changed.status == "complete" && tab.url == URL) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
-
- try {
- {
- let window = await browser.windows.getCurrent();
-
- await testWindow(window);
- }
-
- {
- let window = await browser.windows.create({incognito: true, url: URL});
- await windowReady;
-
- await testWindow(window);
-
- await browser.windows.remove(window.id);
- }
-
- browser.test.notifyPass("incognito-views");
- } catch (error) {
- browser.test.fail(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("incognito-views");
- }
- },
-
- files: {
- "popup.html": '<html><head><meta charset="utf-8"><script src="popup.js"></script></head></html>',
-
- "popup.js": async function() {
- let views = browser.extension.getViews();
-
- if (browser.extension.inIncognitoContext) {
- let bgPage = browser.extension.getBackgroundPage();
- browser.test.assertEq(null, bgPage, "Should not be able to access background page in incognito context");
-
- bgPage = await browser.runtime.getBackgroundPage();
- browser.test.assertEq(null, bgPage, "Should not be able to access background page in incognito context");
-
- browser.test.assertEq(1, views.length, "Should only see one view in incognito popup");
- browser.test.assertEq(window, views[0], "This window should be the only view");
- } else {
- let bgPage = browser.extension.getBackgroundPage();
- browser.test.assertEq(true, bgPage.isBackgroundPage,
- "Should be able to access background page in non-incognito context");
-
- bgPage = await browser.runtime.getBackgroundPage();
- browser.test.assertEq(true, bgPage.isBackgroundPage,
- "Should be able to access background page in non-incognito context");
-
- browser.test.assertEq(2, views.length, "Should only two views in non-incognito popup");
- browser.test.assertEq(bgPage, views[0], "The background page should be the first view");
- browser.test.assertEq(window, views[1], "This window should be the second view");
- }
-
- let win = await browser.windows.getCurrent();
- browser.runtime.sendMessage({
- message: "popup-details",
- windowId: win.id,
- incognito: browser.extension.inIncognitoContext,
- });
-
- window.close();
- },
- },
- });
-
- extension.onMessage("click-browserAction", () => {
- clickBrowserAction(extension, Services.wm.getMostRecentWindow("navigator:browser"));
- });
-
- yield extension.startup();
- yield extension.awaitFinish("incognito-views");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_lastError.js b/browser/components/extensions/test/browser/browser_ext_lastError.js
deleted file mode 100644
index 499e709aa..000000000
--- a/browser/components/extensions/test/browser/browser_ext_lastError.js
+++ /dev/null
@@ -1,55 +0,0 @@
-"use strict";
-
-function* sendMessage(options) {
- function background(options) {
- browser.runtime.sendMessage(result => {
- browser.test.assertEq(undefined, result, "Argument value");
- if (options.checkLastError) {
- let lastError = browser[options.checkLastError].lastError;
- browser.test.assertEq("runtime.sendMessage's message argument is missing",
- lastError && lastError.message,
- "lastError value");
- }
- browser.test.sendMessage("done");
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background: `(${background})(${JSON.stringify(options)})`,
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("done");
-
- yield extension.unload();
-}
-
-add_task(function* testLastError() {
- // Not necessary in browser-chrome tests, but monitorConsole gripes
- // if we don't call it.
- SimpleTest.waitForExplicitFinish();
-
- // Check that we have no unexpected console messages when lastError is
- // checked.
- for (let api of ["extension", "runtime"]) {
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{message: /message argument is missing/, forbid: true}]);
- });
-
- yield sendMessage({checkLastError: api});
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
- }
-
- // Check that we do have a console message when lastError is not checked.
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{message: /Unchecked lastError value: Error: runtime.sendMessage's message argument is missing/}]);
- });
-
- yield sendMessage({});
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_legacy_extension_context_contentscript.js b/browser/components/extensions/test/browser/browser_ext_legacy_extension_context_contentscript.js
deleted file mode 100644
index 01557a745..000000000
--- a/browser/components/extensions/test/browser/browser_ext_legacy_extension_context_contentscript.js
+++ /dev/null
@@ -1,173 +0,0 @@
-"use strict";
-
-const {
- LegacyExtensionContext,
-} = Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
-
-function promiseAddonStartup(extension) {
- const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- return new Promise((resolve) => {
- let listener = (evt, extensionInstance) => {
- Management.off("startup", listener);
- resolve(extensionInstance);
- };
- Management.on("startup", listener);
- });
-}
-
-/**
- * This test case ensures that the LegacyExtensionContext can receive a connection
- * from a content script and that the received port contains the expected sender
- * tab info.
- */
-add_task(function* test_legacy_extension_context_contentscript_connection() {
- function backgroundScript() {
- // Extract the assigned uuid from the background page url and send it
- // in a test message.
- let uuid = window.location.hostname;
-
- browser.test.onMessage.addListener(async msg => {
- if (msg == "open-test-tab") {
- let tab = await browser.tabs.create({url: "http://example.com/"});
- browser.test.sendMessage("get-expected-sender-info",
- {uuid, tab});
- } else if (msg == "close-current-tab") {
- try {
- let [tab] = await browser.tabs.query({active: true});
- await browser.tabs.remove(tab.id);
- browser.test.sendMessage("current-tab-closed", true);
- } catch (e) {
- browser.test.sendMessage("current-tab-closed", false);
- }
- }
- });
-
- browser.test.sendMessage("ready");
- }
-
- function contentScript() {
- browser.runtime.sendMessage("webextension -> legacy_extension message", (reply) => {
- browser.test.assertEq("legacy_extension -> webextension reply", reply,
- "Got the expected reply from the LegacyExtensionContext");
- browser.test.sendMessage("got-reply-message");
- });
-
- let port = browser.runtime.connect();
-
- port.onMessage.addListener(msg => {
- browser.test.assertEq("legacy_extension -> webextension port message", msg,
- "Got the expected message from the LegacyExtensionContext");
- port.postMessage("webextension -> legacy_extension port message");
- });
- }
-
- let extensionData = {
- background: `new ${backgroundScript}`,
- manifest: {
- content_scripts: [
- {
- matches: ["http://example.com/*"],
- js: ["content-script.js"],
- },
- ],
- },
- files: {
- "content-script.js": `new ${contentScript}`,
- },
- };
-
- let extension = ExtensionTestUtils.loadExtension(extensionData);
-
- let waitForExtensionReady = extension.awaitMessage("ready");
-
- let waitForExtensionInstance = promiseAddonStartup(extension);
-
- extension.startup();
-
- let extensionInstance = yield waitForExtensionInstance;
-
- // Connect to the target extension.id as an external context
- // using the given custom sender info.
- let legacyContext = new LegacyExtensionContext(extensionInstance);
-
- let waitConnectPort = new Promise(resolve => {
- let {browser} = legacyContext.api;
- browser.runtime.onConnect.addListener(port => {
- resolve(port);
- });
- });
-
- let waitMessage = new Promise(resolve => {
- let {browser} = legacyContext.api;
- browser.runtime.onMessage.addListener((singleMsg, msgSender, sendReply) => {
- sendReply("legacy_extension -> webextension reply");
- resolve({singleMsg, msgSender});
- });
- });
-
- is(legacyContext.envType, "legacy_extension",
- "LegacyExtensionContext instance has the expected type");
-
- ok(legacyContext.api, "Got the API object");
-
- yield waitForExtensionReady;
-
- extension.sendMessage("open-test-tab");
-
- let {uuid, tab} = yield extension.awaitMessage("get-expected-sender-info");
-
- let {singleMsg, msgSender} = yield waitMessage;
- is(singleMsg, "webextension -> legacy_extension message",
- "Got the expected message");
- ok(msgSender, "Got a message sender object");
-
- is(msgSender.id, uuid, "The sender has the expected id property");
- is(msgSender.url, "http://example.com/", "The sender has the expected url property");
- ok(msgSender.tab, "The sender has a tab property");
- is(msgSender.tab.id, tab.id, "The port sender has the expected tab.id");
-
- // Wait confirmation that the reply has been received.
- yield extension.awaitMessage("got-reply-message");
-
- let port = yield waitConnectPort;
-
- ok(port, "Got the Port API object");
- ok(port.sender, "The port has a sender property");
-
- is(port.sender.id, uuid, "The port sender has an id property");
- is(port.sender.url, "http://example.com/", "The port sender has the expected url property");
- ok(port.sender.tab, "The port sender has a tab property");
- is(port.sender.tab.id, tab.id, "The port sender has the expected tab.id");
-
- let waitPortMessage = new Promise(resolve => {
- port.onMessage.addListener((msg) => {
- resolve(msg);
- });
- });
-
- port.postMessage("legacy_extension -> webextension port message");
-
- let msg = yield waitPortMessage;
-
- is(msg, "webextension -> legacy_extension port message",
- "LegacyExtensionContext received the expected message from the webextension");
-
- let waitForDisconnect = new Promise(resolve => {
- port.onDisconnect.addListener(resolve);
- });
-
- let waitForTestDone = extension.awaitMessage("current-tab-closed");
-
- extension.sendMessage("close-current-tab");
-
- yield waitForDisconnect;
-
- info("Got the disconnect event on tab closed");
-
- let success = yield waitForTestDone;
-
- ok(success, "Test completed successfully");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_omnibox.js b/browser/components/extensions/test/browser/browser_ext_omnibox.js
deleted file mode 100644
index 98d3573c5..000000000
--- a/browser/components/extensions/test/browser/browser_ext_omnibox.js
+++ /dev/null
@@ -1,286 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* setup() {
- const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, false);
-
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
- });
-}
-
-add_task(function* () {
- let keyword = "test";
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "omnibox": {
- "keyword": keyword,
- },
- },
-
- background: function() {
- browser.omnibox.onInputStarted.addListener(() => {
- browser.test.sendMessage("on-input-started-fired");
- });
-
- let synchronous = true;
- let suggestions = null;
- let suggestCallback = null;
-
- browser.omnibox.onInputChanged.addListener((text, suggest) => {
- if (synchronous && suggestions) {
- suggest(suggestions);
- } else {
- suggestCallback = suggest;
- }
- browser.test.sendMessage("on-input-changed-fired", {text});
- });
-
- browser.omnibox.onInputCancelled.addListener(() => {
- browser.test.sendMessage("on-input-cancelled-fired");
- });
-
- browser.omnibox.onInputEntered.addListener((text, disposition) => {
- browser.test.sendMessage("on-input-entered-fired", {text, disposition});
- });
-
- browser.test.onMessage.addListener((msg, data) => {
- switch (msg) {
- case "set-suggestions":
- suggestions = data.suggestions;
- browser.test.sendMessage("suggestions-set");
- break;
- case "set-default-suggestion":
- browser.omnibox.setDefaultSuggestion(data.suggestion);
- browser.test.sendMessage("default-suggestion-set");
- break;
- case "set-synchronous":
- synchronous = data.synchronous;
- break;
- case "test-multiple-suggest-calls":
- suggestions.forEach(suggestion => suggestCallback([suggestion]));
- browser.test.sendMessage("test-ready");
- break;
- case "test-suggestions-after-delay":
- Promise.resolve().then(() => {
- suggestCallback(suggestions);
- browser.test.sendMessage("test-ready");
- });
- break;
- }
- });
- },
- });
-
- function* expectEvent(event, expected = {}) {
- let actual = yield extension.awaitMessage(event);
- if (expected.text) {
- is(actual.text, expected.text,
- `Expected "${event}" to have fired with text: "${expected.text}".`);
- }
- if (expected.disposition) {
- is(actual.disposition, expected.disposition,
- `Expected "${event}" to have fired with disposition: "${expected.disposition}".`);
- }
- }
-
- function* startInputSession() {
- gURLBar.focus();
- gURLBar.value = keyword;
- EventUtils.synthesizeKey(" ", {});
- yield expectEvent("on-input-started-fired");
- EventUtils.synthesizeKey("t", {});
- yield expectEvent("on-input-changed-fired", {text: "t"});
- return "t";
- }
-
- function* testInputEvents() {
- gURLBar.focus();
-
- // Start an input session by typing in <keyword><space>.
- for (let letter of keyword) {
- EventUtils.synthesizeKey(letter, {});
- }
- EventUtils.synthesizeKey(" ", {});
- yield expectEvent("on-input-started-fired");
-
- // We should expect input changed events now that the keyword is active.
- EventUtils.synthesizeKey("b", {});
- yield expectEvent("on-input-changed-fired", {text: "b"});
-
- EventUtils.synthesizeKey("c", {});
- yield expectEvent("on-input-changed-fired", {text: "bc"});
-
- EventUtils.synthesizeKey("VK_BACK_SPACE", {});
- yield expectEvent("on-input-changed-fired", {text: "b"});
-
- // Even though the input is <keyword><space> We should not expect an
- // input started event to fire since the keyword is active.
- EventUtils.synthesizeKey("VK_BACK_SPACE", {});
- yield expectEvent("on-input-changed-fired", {text: ""});
-
- // Make the keyword inactive by hitting backspace.
- EventUtils.synthesizeKey("VK_BACK_SPACE", {});
- yield expectEvent("on-input-cancelled-fired");
-
- // Activate the keyword by typing a space.
- // Expect onInputStarted to fire.
- EventUtils.synthesizeKey(" ", {});
- yield expectEvent("on-input-started-fired");
-
- // onInputChanged should fire even if a space is entered.
- EventUtils.synthesizeKey(" ", {});
- yield expectEvent("on-input-changed-fired", {text: " "});
-
- // The active session should cancel if the input blurs.
- gURLBar.blur();
- yield expectEvent("on-input-cancelled-fired");
- }
-
- function* testHeuristicResult(expectedText, setDefaultSuggestion) {
- if (setDefaultSuggestion) {
- extension.sendMessage("set-default-suggestion", {
- suggestion: {
- description: expectedText,
- },
- });
- yield extension.awaitMessage("default-suggestion-set");
- }
-
- let text = yield startInputSession();
-
- let item = gURLBar.popup.richlistbox.children[0];
-
- is(item.getAttribute("title"), expectedText,
- `Expected heuristic result to have title: "${expectedText}".`);
-
- is(item.getAttribute("displayurl"), `${keyword} ${text}`,
- `Expected heuristic result to have displayurl: "${keyword} ${text}".`);
-
- EventUtils.synthesizeMouseAtCenter(item, {});
-
- yield expectEvent("on-input-entered-fired", {
- text,
- disposition: "currentTab",
- });
- }
-
- function* testDisposition(suggestionIndex, expectedDisposition, expectedText) {
- yield startInputSession();
-
- // Select the suggestion.
- for (let i = 0; i < suggestionIndex; i++) {
- EventUtils.synthesizeKey("VK_DOWN", {});
- }
-
- let item = gURLBar.popup.richlistbox.children[suggestionIndex];
- if (expectedDisposition == "currentTab") {
- EventUtils.synthesizeMouseAtCenter(item, {});
- } else if (expectedDisposition == "newForegroundTab") {
- EventUtils.synthesizeMouseAtCenter(item, {accelKey: true});
- } else if (expectedDisposition == "newBackgroundTab") {
- EventUtils.synthesizeMouseAtCenter(item, {shiftKey: true, accelKey: true});
- }
-
- yield expectEvent("on-input-entered-fired", {
- text: expectedText,
- disposition: expectedDisposition,
- });
- }
-
- function* testSuggestions(info) {
- extension.sendMessage("set-synchronous", {synchronous: false});
-
- function expectSuggestion({content, description}, index) {
- let item = gURLBar.popup.richlistbox.children[index + 1]; // Skip the heuristic result.
-
- ok(!!item, "Expected item to exist");
- is(item.getAttribute("title"), description,
- `Expected suggestion to have title: "${description}".`);
-
- is(item.getAttribute("displayurl"), `${keyword} ${content}`,
- `Expected suggestion to have displayurl: "${keyword} ${content}".`);
- }
-
- let text = yield startInputSession();
-
- extension.sendMessage(info.test);
- yield extension.awaitMessage("test-ready");
-
- info.suggestions.forEach(expectSuggestion);
-
- EventUtils.synthesizeMouseAtCenter(gURLBar.popup.richlistbox.children[0], {});
- yield expectEvent("on-input-entered-fired", {
- text,
- disposition: "currentTab",
- });
- }
-
- yield setup();
- yield extension.startup();
-
- yield testInputEvents();
-
- // Test the heuristic result with default suggestions.
- yield testHeuristicResult("Generated extension", false /* setDefaultSuggestion */);
- yield testHeuristicResult("hello world", true /* setDefaultSuggestion */);
- yield testHeuristicResult("foo bar", true /* setDefaultSuggestion */);
-
- let suggestions = [
- {content: "a", description: "select a"},
- {content: "b", description: "select b"},
- {content: "c", description: "select c"},
- ];
-
- extension.sendMessage("set-suggestions", {suggestions});
- yield extension.awaitMessage("suggestions-set");
-
- // Test each suggestion and search disposition.
- yield testDisposition(1, "currentTab", suggestions[0].content);
- yield testDisposition(2, "newForegroundTab", suggestions[1].content);
- yield testDisposition(3, "newBackgroundTab", suggestions[2].content);
-
- extension.sendMessage("set-suggestions", {suggestions});
- yield extension.awaitMessage("suggestions-set");
-
- // Test adding suggestions asynchronously.
- yield testSuggestions({
- test: "test-multiple-suggest-calls",
- skipHeuristic: true,
- suggestions,
- });
- yield testSuggestions({
- test: "test-suggestions-after-delay",
- skipHeuristic: true,
- suggestions,
- });
-
- // Start monitoring the console.
- SimpleTest.waitForExplicitFinish();
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{
- message: new RegExp(`The keyword provided is already registered: "${keyword}"`),
- }]);
- });
-
- // Try registering another extension with the same keyword
- let extension2 = ExtensionTestUtils.loadExtension({
- manifest: {
- "omnibox": {
- "keyword": keyword,
- },
- },
- });
-
- yield extension2.startup();
-
- // Stop monitoring the console and confirm the correct errors are logged.
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
-
- yield extension2.unload();
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_optionsPage_privileges.js b/browser/components/extensions/test/browser/browser_ext_optionsPage_privileges.js
deleted file mode 100644
index 3e7342dd1..000000000
--- a/browser/components/extensions/test/browser/browser_ext_optionsPage_privileges.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* test_tab_options_privileges() {
- function backgroundScript() {
- browser.runtime.onMessage.addListener(({msgName, tabId}) => {
- if (msgName == "removeTabId") {
- browser.tabs.remove(tabId).then(() => {
- browser.test.notifyPass("options-ui-privileges");
- }).catch(error => {
- browser.test.log(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("options-ui-privileges");
- });
- }
- });
- browser.runtime.openOptionsPage();
- }
-
- async function optionsScript() {
- try {
- let [tab] = await browser.tabs.query({url: "http://example.com/"});
- browser.test.assertEq("http://example.com/", tab.url, "Got the expect tab");
-
- tab = await browser.tabs.getCurrent();
- browser.runtime.sendMessage({msgName: "removeTabId", tabId: tab.id});
- } catch (error) {
- browser.test.log(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("options-ui-privileges");
- }
- }
-
- const ID = "options_privileges@tests.mozilla.org";
- let extension = ExtensionTestUtils.loadExtension({
- useAddonManager: "temporary",
-
- manifest: {
- applications: {gecko: {id: ID}},
- "permissions": ["tabs"],
- "options_ui": {
- "page": "options.html",
- },
- },
- files: {
- "options.html": `<!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <script src="options.js" type="text/javascript"></script>
- </head>
- </html>`,
- "options.js": optionsScript,
- },
- background: backgroundScript,
- });
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
-
- yield extension.startup();
-
- yield extension.awaitFinish("options-ui-privileges");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_pageAction_context.js b/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
deleted file mode 100644
index 2c2a4cd2f..000000000
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* global runTests */
-
-Services.scriptloader.loadSubScript(new URL("head_pageAction.js", gTestPath).href,
- this);
-
-add_task(function* testTabSwitchContext() {
- yield runTests({
- manifest: {
- "name": "Foo Extension",
-
- "page_action": {
- "default_icon": "default.png",
- "default_popup": "__MSG_popup__",
- "default_title": "Default __MSG_title__ \u263a",
- },
-
- "default_locale": "en",
-
- "permissions": ["tabs"],
- },
-
- "files": {
- "_locales/en/messages.json": {
- "popup": {
- "message": "default.html",
- "description": "Popup",
- },
-
- "title": {
- "message": "Title",
- "description": "Title",
- },
- },
-
- "_locales/es_ES/messages.json": {
- "popup": {
- "message": "default.html",
- "description": "Popup",
- },
-
- "title": {
- "message": "T\u00edtulo",
- "description": "Title",
- },
- },
-
- "default.png": imageBuffer,
- "1.png": imageBuffer,
- "2.png": imageBuffer,
- },
-
- getTests(tabs) {
- let details = [
- {"icon": browser.runtime.getURL("default.png"),
- "popup": browser.runtime.getURL("default.html"),
- "title": "Default T\u00edtulo \u263a"},
- {"icon": browser.runtime.getURL("1.png"),
- "popup": browser.runtime.getURL("default.html"),
- "title": "Default T\u00edtulo \u263a"},
- {"icon": browser.runtime.getURL("2.png"),
- "popup": browser.runtime.getURL("2.html"),
- "title": "Title 2"},
- {"icon": browser.runtime.getURL("2.png"),
- "popup": browser.runtime.getURL("2.html"),
- "title": "Default T\u00edtulo \u263a"},
- ];
-
- let promiseTabLoad = details => {
- return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
- if (tabId == details.id && changed.url == details.url) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
- };
-
- return [
- expect => {
- browser.test.log("Initial state. No icon visible.");
- expect(null);
- },
- async expect => {
- browser.test.log("Show the icon on the first tab, expect default properties.");
- await browser.pageAction.show(tabs[0]);
- expect(details[0]);
- },
- expect => {
- browser.test.log("Change the icon. Expect default properties excluding the icon.");
- browser.pageAction.setIcon({tabId: tabs[0], path: "1.png"});
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Create a new tab. No icon visible.");
- let tab = await browser.tabs.create({active: true, url: "about:blank?0"});
- tabs.push(tab.id);
- expect(null);
- },
- expect => {
- browser.test.log("Await tab load. No icon visible.");
- expect(null);
- },
- async expect => {
- browser.test.log("Change properties. Expect new properties.");
- let tabId = tabs[1];
- await browser.pageAction.show(tabId);
-
- browser.pageAction.setIcon({tabId, path: "2.png"});
- browser.pageAction.setPopup({tabId, popup: "2.html"});
- browser.pageAction.setTitle({tabId, title: "Title 2"});
-
- expect(details[2]);
- },
- async expect => {
- browser.test.log("Change the hash. Expect same properties.");
-
- let promise = promiseTabLoad({id: tabs[1], url: "about:blank?0#ref"});
- browser.tabs.update(tabs[1], {url: "about:blank?0#ref"});
- await promise;
-
- expect(details[2]);
- },
- expect => {
- browser.test.log("Clear the title. Expect default title.");
- browser.pageAction.setTitle({tabId: tabs[1], title: ""});
-
- expect(details[3]);
- },
- async expect => {
- browser.test.log("Navigate to a new page. Expect icon hidden.");
-
- // TODO: This listener should not be necessary, but the |tabs.update|
- // callback currently fires too early in e10s windows.
- let promise = promiseTabLoad({id: tabs[1], url: "about:blank?1"});
-
- browser.tabs.update(tabs[1], {url: "about:blank?1"});
-
- await promise;
- expect(null);
- },
- async expect => {
- browser.test.log("Show the icon. Expect default properties again.");
-
- await browser.pageAction.show(tabs[1]);
- expect(details[0]);
- },
- async expect => {
- browser.test.log("Switch back to the first tab. Expect previously set properties.");
- await browser.tabs.update(tabs[0], {active: true});
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Hide the icon on tab 2. Switch back, expect hidden.");
- await browser.pageAction.hide(tabs[1]);
-
- await browser.tabs.update(tabs[1], {active: true});
- expect(null);
- },
- async expect => {
- browser.test.log("Switch back to tab 1. Expect previous results again.");
- await browser.tabs.remove(tabs[1]);
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Hide the icon. Expect hidden.");
-
- await browser.pageAction.hide(tabs[0]);
- expect(null);
- },
- ];
- },
- });
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_pageAction_popup.js b/browser/components/extensions/test/browser/browser_ext_pageAction_popup.js
deleted file mode 100644
index 83defdd68..000000000
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_popup.js
+++ /dev/null
@@ -1,238 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testPageActionPopup() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
-
- let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head></html>`;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "background": {
- "page": "data/background.html",
- },
- "page_action": {
- "default_popup": "popup-a.html",
- },
- },
-
- files: {
- "popup-a.html": scriptPage("popup-a.js"),
- "popup-a.js": function() {
- window.onload = () => {
- let background = window.getComputedStyle(document.body).backgroundColor;
- browser.test.assertEq("transparent", background);
- browser.runtime.sendMessage("from-popup-a");
- };
- browser.runtime.onMessage.addListener(msg => {
- if (msg == "close-popup") {
- window.close();
- }
- });
- },
-
- "data/popup-b.html": scriptPage("popup-b.js"),
- "data/popup-b.js": function() {
- browser.runtime.sendMessage("from-popup-b");
- },
-
- "data/background.html": scriptPage("background.js"),
-
- "data/background.js": async function() {
- let tabId;
-
- let sendClick;
- let tests = [
- () => {
- sendClick({expectEvent: false, expectPopup: "a"});
- },
- () => {
- sendClick({expectEvent: false, expectPopup: "a"});
- },
- () => {
- browser.pageAction.setPopup({tabId, popup: "popup-b.html"});
- sendClick({expectEvent: false, expectPopup: "b"});
- },
- () => {
- sendClick({expectEvent: false, expectPopup: "b"});
- },
- () => {
- browser.pageAction.setPopup({tabId, popup: ""});
- sendClick({expectEvent: true, expectPopup: null});
- },
- () => {
- sendClick({expectEvent: true, expectPopup: null});
- },
- () => {
- browser.pageAction.setPopup({tabId, popup: "/popup-a.html"});
- sendClick({expectEvent: false, expectPopup: "a", runNextTest: true});
- },
- () => {
- browser.test.sendMessage("next-test", {expectClosed: true});
- },
- () => {
- sendClick({expectEvent: false, expectPopup: "a", runNextTest: true});
- },
- () => {
- browser.test.sendMessage("next-test", {closeOnTabSwitch: true});
- },
- ];
-
- let expect = {};
- sendClick = ({expectEvent, expectPopup, runNextTest}) => {
- expect = {event: expectEvent, popup: expectPopup, runNextTest};
- browser.test.sendMessage("send-click");
- };
-
- browser.runtime.onMessage.addListener(msg => {
- if (msg == "close-popup") {
- return;
- } else if (expect.popup) {
- browser.test.assertEq(msg, `from-popup-${expect.popup}`,
- "expected popup opened");
- } else {
- browser.test.fail(`unexpected popup: ${msg}`);
- }
-
- expect.popup = null;
- if (expect.runNextTest) {
- expect.runNextTest = false;
- tests.shift()();
- } else {
- browser.test.sendMessage("next-test");
- }
- });
-
- browser.pageAction.onClicked.addListener(() => {
- if (expect.event) {
- browser.test.succeed("expected click event received");
- } else {
- browser.test.fail("unexpected click event");
- }
-
- expect.event = false;
- browser.test.sendMessage("next-test");
- });
-
- browser.test.onMessage.addListener(msg => {
- if (msg == "close-popup") {
- browser.runtime.sendMessage("close-popup");
- return;
- }
-
- if (msg != "next-test") {
- browser.test.fail("Expecting 'next-test' message");
- }
-
- if (tests.length) {
- let test = tests.shift();
- test();
- } else {
- browser.test.notifyPass("pageaction-tests-done");
- }
- });
-
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- tabId = tab.id;
-
- await browser.pageAction.show(tabId);
- browser.test.sendMessage("next-test");
- },
- },
- });
-
- extension.onMessage("send-click", () => {
- clickPageAction(extension);
- });
-
- let pageActionId, panelId;
- extension.onMessage("next-test", Task.async(function* (expecting = {}) {
- pageActionId = `${makeWidgetId(extension.id)}-page-action`;
- panelId = `${makeWidgetId(extension.id)}-panel`;
- let panel = document.getElementById(panelId);
- if (expecting.expectClosed) {
- ok(panel, "Expect panel to exist");
- yield promisePopupShown(panel);
-
- extension.sendMessage("close-popup");
-
- yield promisePopupHidden(panel);
- ok(true, `Panel is closed`);
- } else if (expecting.closeOnTabSwitch) {
- ok(panel, "Expect panel to exist");
- yield promisePopupShown(panel);
-
- let oldTab = gBrowser.selectedTab;
- ok(oldTab != gBrowser.tabs[0], "Should have an inactive tab to switch to");
-
- let hiddenPromise = promisePopupHidden(panel);
-
- gBrowser.selectedTab = gBrowser.tabs[0];
- yield hiddenPromise;
- info("Panel closed");
-
- gBrowser.selectedTab = oldTab;
- } else if (panel) {
- yield promisePopupShown(panel);
- panel.hidePopup();
- }
-
- if (panel) {
- panel = document.getElementById(panelId);
- is(panel, null, "panel successfully removed from document after hiding");
- }
-
- extension.sendMessage("next-test");
- }));
-
-
- yield extension.startup();
- yield extension.awaitFinish("pageaction-tests-done");
-
- yield extension.unload();
-
- let node = document.getElementById(pageActionId);
- is(node, null, "pageAction image removed from document");
-
- let panel = document.getElementById(panelId);
- is(panel, null, "pageAction panel removed from document");
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-
-add_task(function* testPageActionSecurity() {
- const URL = "chrome://browser/content/browser.xul";
-
- let apis = ["browser_action", "page_action"];
-
- for (let api of apis) {
- info(`TEST ${api} icon url: ${URL}`);
-
- let messages = [/Access to restricted URI denied/];
-
- let waitForConsole = new Promise(resolve => {
- // Not necessary in browser-chrome tests, but monitorConsole gripes
- // if we don't call it.
- SimpleTest.waitForExplicitFinish();
-
- SimpleTest.monitorConsole(resolve, messages);
- });
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- [api]: {"default_popup": URL},
- },
- });
-
- yield Assert.rejects(extension.startup(),
- null,
- "Manifest rejected");
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
- }
-});
-
-add_task(forceGC);
diff --git a/browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js b/browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js
deleted file mode 100644
index 98c4c3488..000000000
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_popup_resize.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-let delay = ms => new Promise(resolve => {
- setTimeout(resolve, ms);
-});
-
-add_task(function* testPageActionPopupResize() {
- let browser;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- },
- background: function() {
- /* global browser */
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- const tabId = tabs[0].id;
-
- browser.pageAction.show(tabId).then(() => {
- browser.test.sendMessage("action-shown");
- });
- });
- },
-
- files: {
- "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><div></div></body></html>`,
- },
- });
-
- yield extension.startup();
- yield extension.awaitMessage("action-shown");
-
- clickPageAction(extension, window);
-
- browser = yield awaitExtensionPanel(extension);
-
- function* checkSize(expected) {
- let dims = yield promiseContentDimensions(browser);
- let {body, root} = dims;
-
- is(dims.window.innerHeight, expected, `Panel window should be ${expected}px tall`);
- is(body.clientHeight, body.scrollHeight,
- "Panel body should be tall enough to fit its contents");
- is(root.clientHeight, root.scrollHeight,
- "Panel root should be tall enough to fit its contents");
-
- // Tolerate if it is 1px too wide, as that may happen with the current resizing method.
- ok(Math.abs(dims.window.innerWidth - expected) <= 1, `Panel window should be ${expected}px wide`);
- is(body.clientWidth, body.scrollWidth,
- "Panel body should be wide enough to fit its contents");
- }
-
- /* eslint-disable mozilla/no-cpows-in-tests */
- function setSize(size) {
- let elem = content.document.body.firstChild;
- elem.style.height = `${size}px`;
- elem.style.width = `${size}px`;
- }
- /* eslint-enable mozilla/no-cpows-in-tests */
-
- let sizes = [
- 200,
- 400,
- 300,
- ];
-
- for (let size of sizes) {
- yield alterContent(browser, setSize, size);
- yield checkSize(size);
- }
-
- yield alterContent(browser, setSize, 1400);
-
- let dims = yield promiseContentDimensions(browser);
- let {body, root} = dims;
-
- if (AppConstants.platform == "win") {
- while (dims.window.innerWidth < 800) {
- yield delay(50);
- dims = yield promiseContentDimensions(browser);
- }
- }
-
- is(dims.window.innerWidth, 800, "Panel window width");
- ok(body.clientWidth <= 800, `Panel body width ${body.clientWidth} is less than 800`);
- is(body.scrollWidth, 1400, "Panel body scroll width");
-
- is(dims.window.innerHeight, 600, "Panel window height");
- ok(root.clientHeight <= 600, `Panel root height (${root.clientHeight}px) is less than 600px`);
- is(root.scrollHeight, 1400, "Panel root scroll height");
-
- yield extension.unload();
-});
-
-add_task(function* testPageActionPopupReflow() {
- let browser;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- },
- background: function() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- const tabId = tabs[0].id;
-
- browser.pageAction.show(tabId).then(() => {
- browser.test.sendMessage("action-shown");
- });
- });
- },
-
- files: {
- "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"></head>
- <body>
- The quick mauve fox jumps over the opalescent toad, with its glowing
- eyes, and its vantablack mouth, and its bottomless chasm where you
- would hope to find a heart, that looks straight into the deepest
- pits of hell. The fox shivers, and cowers, and tries to run, but
- the toad is utterly without pity. It turns, ever so slightly...
- </body>
- </html>`,
- },
- });
-
- yield extension.startup();
- yield extension.awaitMessage("action-shown");
-
- clickPageAction(extension, window);
-
- browser = yield awaitExtensionPanel(extension);
-
- /* eslint-disable mozilla/no-cpows-in-tests */
- function setSize(size) {
- content.document.body.style.fontSize = `${size}px`;
- }
- /* eslint-enable mozilla/no-cpows-in-tests */
-
- let dims = yield alterContent(browser, setSize, 18);
-
- if (AppConstants.platform == "win") {
- while (dims.window.innerWidth < 800) {
- yield delay(50);
- dims = yield promiseContentDimensions(browser);
- }
- }
-
- is(dims.window.innerWidth, 800, "Panel window should be 800px wide");
- is(dims.body.clientWidth, 800, "Panel body should be 800px wide");
- is(dims.body.clientWidth, dims.body.scrollWidth,
- "Panel body should be wide enough to fit its contents");
-
- ok(dims.window.innerHeight > 36,
- `Panel window height (${dims.window.innerHeight}px) should be taller than two lines of text.`);
-
- is(dims.body.clientHeight, dims.body.scrollHeight,
- "Panel body should be tall enough to fit its contents");
- is(dims.root.clientHeight, dims.root.scrollHeight,
- "Panel root should be tall enough to fit its contents");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_pageAction_simple.js b/browser/components/extensions/test/browser/browser_ext_pageAction_simple.js
deleted file mode 100644
index d1d173801..000000000
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_simple.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "page_action": {
- "default_popup": "popup.html",
- "unrecognized_property": "with-a-random-value",
- },
- },
-
- files: {
- "popup.html": `
- <!DOCTYPE html>
- <html><body>
- <script src="popup.js"></script>
- </body></html>
- `,
-
- "popup.js": function() {
- browser.runtime.sendMessage("from-popup");
- },
- },
-
- background: function() {
- browser.runtime.onMessage.addListener(msg => {
- browser.test.assertEq(msg, "from-popup", "correct message received");
- browser.test.sendMessage("popup");
- });
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- let tabId = tabs[0].id;
-
- browser.pageAction.show(tabId).then(() => {
- browser.test.sendMessage("page-action-shown");
- });
- });
- },
- });
-
- SimpleTest.waitForExplicitFinish();
- let waitForConsole = new Promise(resolve => {
- SimpleTest.monitorConsole(resolve, [{
- message: /Reading manifest: Error processing page_action.unrecognized_property: An unexpected property was found/,
- }]);
- });
-
- yield extension.startup();
- yield extension.awaitMessage("page-action-shown");
-
- clickPageAction(extension);
-
- yield extension.awaitMessage("popup");
-
- yield extension.unload();
-
- SimpleTest.endMonitorConsole();
- yield waitForConsole;
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_pageAction_title.js b/browser/components/extensions/test/browser/browser_ext_pageAction_title.js
deleted file mode 100644
index 793cd4499..000000000
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_title.js
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* global runTests */
-
-Services.scriptloader.loadSubScript(new URL("head_pageAction.js", gTestPath).href,
- this);
-
-add_task(function* testTabSwitchContext() {
- yield runTests({
- manifest: {
- "name": "Foo Extension",
-
- "page_action": {
- "default_icon": "default.png",
- "default_popup": "__MSG_popup__",
- "default_title": "Default __MSG_title__ \u263a",
- },
-
- "default_locale": "en",
-
- "permissions": ["tabs"],
- },
-
- "files": {
- "_locales/en/messages.json": {
- "popup": {
- "message": "default.html",
- "description": "Popup",
- },
-
- "title": {
- "message": "Title",
- "description": "Title",
- },
- },
-
- "_locales/es_ES/messages.json": {
- "popup": {
- "message": "default.html",
- "description": "Popup",
- },
-
- "title": {
- "message": "T\u00edtulo",
- "description": "Title",
- },
- },
-
- "default.png": imageBuffer,
- "1.png": imageBuffer,
- "2.png": imageBuffer,
- },
-
- getTests(tabs) {
- let details = [
- {"icon": browser.runtime.getURL("default.png"),
- "popup": browser.runtime.getURL("default.html"),
- "title": "Default T\u00edtulo \u263a"},
- {"icon": browser.runtime.getURL("1.png"),
- "popup": browser.runtime.getURL("default.html"),
- "title": "Default T\u00edtulo \u263a"},
- {"icon": browser.runtime.getURL("2.png"),
- "popup": browser.runtime.getURL("2.html"),
- "title": "Title 2"},
- {"icon": browser.runtime.getURL("2.png"),
- "popup": browser.runtime.getURL("2.html"),
- "title": "Default T\u00edtulo \u263a"},
- ];
-
- let promiseTabLoad = details => {
- return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
- if (tabId == details.id && changed.url == details.url) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
- };
- return [
- expect => {
- browser.test.log("Initial state. No icon visible.");
- expect(null);
- },
- async expect => {
- browser.test.log("Show the icon on the first tab, expect default properties.");
- await browser.pageAction.show(tabs[0]);
- expect(details[0]);
- },
- expect => {
- browser.test.log("Change the icon. Expect default properties excluding the icon.");
- browser.pageAction.setIcon({tabId: tabs[0], path: "1.png"});
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Create a new tab. No icon visible.");
- let tab = await browser.tabs.create({active: true, url: "about:blank?0"});
- tabs.push(tab.id);
- expect(null);
- },
- expect => {
- browser.test.log("Await tab load. No icon visible.");
- expect(null);
- },
- async expect => {
- browser.test.log("Change properties. Expect new properties.");
- let tabId = tabs[1];
-
- await browser.pageAction.show(tabId);
- browser.pageAction.setIcon({tabId, path: "2.png"});
- browser.pageAction.setPopup({tabId, popup: "2.html"});
- browser.pageAction.setTitle({tabId, title: "Title 2"});
-
- expect(details[2]);
- },
- async expect => {
- browser.test.log("Change the hash. Expect same properties.");
-
- let promise = promiseTabLoad({id: tabs[1], url: "about:blank?0#ref"});
-
- browser.tabs.update(tabs[1], {url: "about:blank?0#ref"});
-
- await promise;
- expect(details[2]);
- },
- expect => {
- browser.test.log("Clear the title. Expect default title.");
- browser.pageAction.setTitle({tabId: tabs[1], title: ""});
-
- expect(details[3]);
- },
- async expect => {
- browser.test.log("Navigate to a new page. Expect icon hidden.");
-
- // TODO: This listener should not be necessary, but the |tabs.update|
- // callback currently fires too early in e10s windows.
- let promise = promiseTabLoad({id: tabs[1], url: "about:blank?1"});
-
- browser.tabs.update(tabs[1], {url: "about:blank?1"});
-
- await promise;
- expect(null);
- },
- async expect => {
- browser.test.log("Show the icon. Expect default properties again.");
- await browser.pageAction.show(tabs[1]);
- expect(details[0]);
- },
- async expect => {
- browser.test.log("Switch back to the first tab. Expect previously set properties.");
- await browser.tabs.update(tabs[0], {active: true});
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Hide the icon on tab 2. Switch back, expect hidden.");
- await browser.pageAction.hide(tabs[1]);
- await browser.tabs.update(tabs[1], {active: true});
- expect(null);
- },
- async expect => {
- browser.test.log("Switch back to tab 1. Expect previous results again.");
- await browser.tabs.remove(tabs[1]);
- expect(details[1]);
- },
- async expect => {
- browser.test.log("Hide the icon. Expect hidden.");
- await browser.pageAction.hide(tabs[0]);
- expect(null);
- },
- ];
- },
- });
-});
-
-add_task(function* testDefaultTitle() {
- yield runTests({
- manifest: {
- "name": "Foo Extension",
-
- "page_action": {
- "default_icon": "icon.png",
- },
-
- "permissions": ["tabs"],
- },
-
- files: {
- "icon.png": imageBuffer,
- },
-
- getTests(tabs) {
- let details = [
- {"title": "Foo Extension",
- "popup": "",
- "icon": browser.runtime.getURL("icon.png")},
- {"title": "Foo Title",
- "popup": "",
- "icon": browser.runtime.getURL("icon.png")},
- ];
-
- return [
- expect => {
- browser.test.log("Initial state. No icon visible.");
- expect(null);
- },
- async expect => {
- browser.test.log("Show the icon on the first tab, expect extension title as default title.");
- await browser.pageAction.show(tabs[0]);
- expect(details[0]);
- },
- expect => {
- browser.test.log("Change the title. Expect new title.");
- browser.pageAction.setTitle({tabId: tabs[0], title: "Foo Title"});
- expect(details[1]);
- },
- expect => {
- browser.test.log("Clear the title. Expect extension title.");
- browser.pageAction.setTitle({tabId: tabs[0], title: ""});
- expect(details[0]);
- },
- ];
- },
- });
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_popup_api_injection.js b/browser/components/extensions/test/browser/browser_ext_popup_api_injection.js
deleted file mode 100644
index 6f8a541a9..000000000
--- a/browser/components/extensions/test/browser/browser_ext_popup_api_injection.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testPageActionPopup() {
- const BASE = "http://example.com/browser/browser/components/extensions/test/browser";
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": `${BASE}/file_popup_api_injection_a.html`,
- },
- "page_action": {
- "default_popup": `${BASE}/file_popup_api_injection_b.html`,
- },
- },
-
- files: {
- "popup-a.html": `<html><head><meta charset="utf-8">
- <script type="application/javascript" src="popup-a.js"></script></head></html>`,
- "popup-a.js": 'browser.test.sendMessage("from-popup-a");',
-
- "popup-b.html": `<html><head><meta charset="utf-8">
- <script type="application/javascript" src="popup-b.js"></script></head></html>`,
- "popup-b.js": 'browser.test.sendMessage("from-popup-b");',
- },
-
- background: function() {
- let tabId;
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- tabId = tabs[0].id;
- browser.pageAction.show(tabId).then(() => {
- browser.test.sendMessage("ready");
- });
- });
-
- browser.test.onMessage.addListener(() => {
- browser.browserAction.setPopup({popup: "/popup-a.html"});
- browser.pageAction.setPopup({tabId, popup: "popup-b.html"});
-
- browser.test.sendMessage("ok");
- });
- },
- });
-
- let promiseConsoleMessage = pattern => new Promise(resolve => {
- Services.console.registerListener(function listener(msg) {
- if (pattern.test(msg.message)) {
- resolve(msg.message);
- Services.console.unregisterListener(listener);
- }
- });
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
-
- // Check that unprivileged documents don't get the API.
- // BrowserAction:
- let awaitMessage = promiseConsoleMessage(/WebExt Privilege Escalation: BrowserAction/);
- SimpleTest.expectUncaughtException();
- yield clickBrowserAction(extension);
- yield promisePopupShown(getBrowserActionPopup(extension));
-
- let message = yield awaitMessage;
- ok(message.includes("WebExt Privilege Escalation: BrowserAction: typeof(browser) = undefined"),
- `No BrowserAction API injection`);
-
- yield closeBrowserAction(extension);
-
- // PageAction
- awaitMessage = promiseConsoleMessage(/WebExt Privilege Escalation: PageAction/);
- SimpleTest.expectUncaughtException();
- yield clickPageAction(extension);
-
- message = yield awaitMessage;
- ok(message.includes("WebExt Privilege Escalation: PageAction: typeof(browser) = undefined"),
- `No PageAction API injection: ${message}`);
-
- yield closePageAction(extension);
-
- SimpleTest.expectUncaughtException(false);
-
-
- // Check that privileged documents *do* get the API.
- extension.sendMessage("next");
- yield extension.awaitMessage("ok");
-
-
- yield clickBrowserAction(extension);
- yield extension.awaitMessage("from-popup-a");
- yield promisePopupShown(getBrowserActionPopup(extension));
- yield closeBrowserAction(extension);
-
- yield clickPageAction(extension);
- yield extension.awaitMessage("from-popup-b");
- yield closePageAction(extension);
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_popup_background.js b/browser/components/extensions/test/browser/browser_ext_popup_background.js
deleted file mode 100644
index 8b310c674..000000000
--- a/browser/components/extensions/test/browser/browser_ext_popup_background.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testPopupBackground() {
- let extension = ExtensionTestUtils.loadExtension({
- background() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- browser.pageAction.show(tabs[0].id);
- });
- },
-
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
-
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
- },
-
- files: {
- "popup.html": `<!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body style="width: 100px; height: 100px; background-color: green;">
- </body>
- </html>`,
- },
- });
-
- yield extension.startup();
-
- function* testPanel(browser, standAlone) {
- let panel = getPanelForNode(browser);
- let arrowContent = document.getAnonymousElementByAttribute(panel, "class", "panel-arrowcontent");
- let arrow = document.getAnonymousElementByAttribute(panel, "anonid", "arrow");
-
- let borderColor = getComputedStyle(arrowContent).borderTopColor;
-
- let checkArrow = (background = null) => {
- let image = getComputedStyle(arrow).listStyleImage;
-
- if (background == null || !standAlone) {
- ok(image.startsWith('url("chrome://'), `We should have the built-in background image (got: ${image})`);
- return;
- }
-
- if (AppConstants.platform == "mac") {
- // Panels have a drop shadow rather than a border on OS-X, so we extend
- // the background color through the border area instead.
- borderColor = background;
- }
-
- image = decodeURIComponent(image);
- let borderIndex = image.indexOf(`fill="${borderColor}"`);
- let backgroundIndex = image.lastIndexOf(`fill="${background}"`);
-
- ok(borderIndex >= 0, `Have border fill (index=${borderIndex})`);
- ok(backgroundIndex >= 0, `Have background fill (index=${backgroundIndex})`);
- is(getComputedStyle(arrowContent).backgroundColor, background, "Arrow content should have correct background");
- isnot(borderIndex, backgroundIndex, "Border and background fills are separate elements");
- };
-
- function getBackground(browser) {
- return ContentTask.spawn(browser, null, function* () {
- return content.getComputedStyle(content.document.body)
- .backgroundColor;
- });
- }
-
- /* eslint-disable mozilla/no-cpows-in-tests */
- let setBackground = color => {
- content.document.body.style.backgroundColor = color;
- };
- /* eslint-enable mozilla/no-cpows-in-tests */
-
- yield new Promise(resolve => setTimeout(resolve, 100));
-
- info("Test that initial background color is applied");
-
- checkArrow(yield getBackground(browser));
-
- info("Test that dynamically-changed background color is applied");
-
- yield alterContent(browser, setBackground, "black");
-
- checkArrow(yield getBackground(browser));
-
- info("Test that non-opaque background color results in default styling");
-
- yield alterContent(browser, setBackground, "rgba(1, 2, 3, .9)");
-
- checkArrow(null);
- }
-
- {
- info("Test stand-alone browserAction popup");
-
- clickBrowserAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- yield testPanel(browser, true);
- yield closeBrowserAction(extension);
- }
-
- {
- info("Test menu panel browserAction popup");
-
- let widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, CustomizableUI.AREA_PANEL);
-
- clickBrowserAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- yield testPanel(browser, false);
- yield closeBrowserAction(extension);
- }
-
- {
- info("Test pageAction popup");
-
- clickPageAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- yield testPanel(browser, true);
- yield closePageAction(extension);
- }
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_popup_corners.js b/browser/components/extensions/test/browser/browser_ext_popup_corners.js
deleted file mode 100644
index 52985ee46..000000000
--- a/browser/components/extensions/test/browser/browser_ext_popup_corners.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testPopupBorderRadius() {
- let extension = ExtensionTestUtils.loadExtension({
- background() {
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- browser.pageAction.show(tabs[0].id);
- });
- },
-
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
-
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
- },
-
- files: {
- "popup.html": `<!DOCTYPE html>
- <html>
- <head><meta charset="utf-8"></head>
- <body style="width: 100px; height: 100px;"></body>
- </html>`,
- },
- });
-
- yield extension.startup();
-
- function* testPanel(browser, standAlone = true) {
- let panel = getPanelForNode(browser);
- let arrowContent = document.getAnonymousElementByAttribute(panel, "class", "panel-arrowcontent");
-
- let panelStyle = getComputedStyle(arrowContent);
-
- let viewNode = browser.parentNode === panel ? browser : browser.parentNode;
- let viewStyle = getComputedStyle(viewNode);
-
- let props = ["borderTopLeftRadius", "borderTopRightRadius",
- "borderBottomRightRadius", "borderBottomLeftRadius"];
-
- /* eslint-disable mozilla/no-cpows-in-tests */
- let bodyStyle = yield ContentTask.spawn(browser, props, function* (props) {
- let bodyStyle = content.getComputedStyle(content.document.body);
-
- return new Map(props.map(prop => [prop, bodyStyle[prop]]));
- });
- /* eslint-enable mozilla/no-cpows-in-tests */
-
- for (let prop of props) {
- if (standAlone) {
- is(viewStyle[prop], panelStyle[prop], `Panel and view ${prop} should be the same`);
- is(bodyStyle.get(prop), panelStyle[prop], `Panel and body ${prop} should be the same`);
- } else {
- is(viewStyle[prop], "0px", `View node ${prop} should be 0px`);
- is(bodyStyle.get(prop), "0px", `Body node ${prop} should be 0px`);
- }
- }
- }
-
- {
- info("Test stand-alone browserAction popup");
-
- clickBrowserAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- yield testPanel(browser);
- yield closeBrowserAction(extension);
- }
-
- {
- info("Test menu panel browserAction popup");
-
- let widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, CustomizableUI.AREA_PANEL);
-
- clickBrowserAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- yield testPanel(browser, false);
- yield closeBrowserAction(extension);
- }
-
- {
- info("Test pageAction popup");
-
- clickPageAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- yield testPanel(browser);
- yield closePageAction(extension);
- }
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_popup_sendMessage.js b/browser/components/extensions/test/browser/browser_ext_popup_sendMessage.js
deleted file mode 100644
index 472ee7bbd..000000000
--- a/browser/components/extensions/test/browser/browser_ext_popup_sendMessage.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* test_popup_sendMessage_reply() {
- let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head><body>${url}</body></html>`;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
-
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": true,
- },
- },
-
- files: {
- "popup.html": scriptPage("popup.js"),
- "popup.js": async function() {
- browser.runtime.onMessage.addListener(async msg => {
- if (msg == "popup-ping") {
- return Promise.resolve("popup-pong");
- }
- });
-
- let response = await browser.runtime.sendMessage("background-ping");
- browser.test.sendMessage("background-ping-response", response);
- },
- },
-
- async background() {
- browser.runtime.onMessage.addListener(async msg => {
- if (msg == "background-ping") {
- let response = await browser.runtime.sendMessage("popup-ping");
-
- browser.test.sendMessage("popup-ping-response", response);
-
- await new Promise(resolve => {
- // Wait long enough that we're relatively sure the docShells have
- // been swapped. Note that this value is fairly arbitrary. The load
- // event that triggers the swap should happen almost immediately
- // after the message is sent. The extra quarter of a second gives us
- // enough leeway that we can expect to respond after the swap in the
- // vast majority of cases.
- setTimeout(resolve, 250);
- });
-
- return "background-pong";
- }
- });
-
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
-
- await browser.pageAction.show(tab.id);
-
- browser.test.sendMessage("page-action-ready");
- },
- });
-
- yield extension.startup();
-
- {
- clickBrowserAction(extension);
-
- let pong = yield extension.awaitMessage("background-ping-response");
- is(pong, "background-pong", "Got pong");
-
- pong = yield extension.awaitMessage("popup-ping-response");
- is(pong, "popup-pong", "Got pong");
-
- yield closeBrowserAction(extension);
- }
-
- yield extension.awaitMessage("page-action-ready");
-
- {
- clickPageAction(extension);
-
- let pong = yield extension.awaitMessage("background-ping-response");
- is(pong, "background-pong", "Got pong");
-
- pong = yield extension.awaitMessage("popup-ping-response");
- is(pong, "popup-pong", "Got pong");
-
- yield closePageAction(extension);
- }
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_popup_shutdown.js b/browser/components/extensions/test/browser/browser_ext_popup_shutdown.js
deleted file mode 100644
index 66d37e857..000000000
--- a/browser/components/extensions/test/browser/browser_ext_popup_shutdown.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-let getExtension = () => {
- return ExtensionTestUtils.loadExtension({
- background: async function() {
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- await browser.pageAction.show(tab.id);
- browser.test.sendMessage("pageAction ready");
- },
-
- manifest: {
- "browser_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
-
- "page_action": {
- "default_popup": "popup.html",
- "browser_style": false,
- },
- },
-
- files: {
- "popup.html": `<!DOCTYPE html>
- <html><head><meta charset="utf-8"></head></html>`,
- },
- });
-};
-
-add_task(function* testStandaloneBrowserAction() {
- info("Test stand-alone browserAction popup");
-
- let extension = getExtension();
- yield extension.startup();
- yield extension.awaitMessage("pageAction ready");
-
- clickBrowserAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- let panel = getPanelForNode(browser);
-
- yield extension.unload();
-
- is(panel.parentNode, null, "Panel should be removed from the document");
-});
-
-add_task(function* testMenuPanelBrowserAction() {
- let extension = getExtension();
- yield extension.startup();
- yield extension.awaitMessage("pageAction ready");
-
- let widget = getBrowserActionWidget(extension);
- CustomizableUI.addWidgetToArea(widget.id, CustomizableUI.AREA_PANEL);
-
- clickBrowserAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- let panel = getPanelForNode(browser);
-
- yield extension.unload();
-
- is(panel.state, "closed", "Panel should be closed");
-});
-
-add_task(function* testPageAction() {
- let extension = getExtension();
- yield extension.startup();
- yield extension.awaitMessage("pageAction ready");
-
- clickPageAction(extension);
- let browser = yield awaitExtensionPanel(extension);
- let panel = getPanelForNode(browser);
-
- yield extension.unload();
-
- is(panel.parentNode, null, "Panel should be removed from the document");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage.js b/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage.js
deleted file mode 100644
index 1631ececa..000000000
--- a/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage.js
+++ /dev/null
@@ -1,276 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-requestLongerTimeout(2);
-
-function add_tasks(task) {
- add_task(task.bind(null, {embedded: false}));
-
- add_task(task.bind(null, {embedded: true}));
-}
-
-function* loadExtension(options) {
- let extension = ExtensionTestUtils.loadExtension({
- useAddonManager: "temporary",
-
- embedded: options.embedded,
-
- manifest: Object.assign({
- "permissions": ["tabs"],
- }, options.manifest),
-
- files: {
- "options.html": `<!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <script src="options.js" type="text/javascript"></script>
- </head>
- </html>`,
-
- "options.js": function() {
- window.iAmOption = true;
- browser.runtime.sendMessage("options.html");
- browser.runtime.onMessage.addListener((msg, sender, respond) => {
- if (msg == "ping") {
- respond("pong");
- }
- });
- },
- },
-
- background: options.background,
- });
-
- yield extension.startup();
-
- return extension;
-}
-
-add_tasks(function* test_inline_options(extraOptions) {
- info(`Test options opened inline (${JSON.stringify(extraOptions)})`);
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
-
- let extension = yield loadExtension(Object.assign({}, extraOptions, {
- manifest: {
- applications: {gecko: {id: "inline_options@tests.mozilla.org"}},
- "options_ui": {
- "page": "options.html",
- },
- },
-
- background: async function() {
- let _optionsPromise;
- let awaitOptions = () => {
- browser.test.assertFalse(_optionsPromise, "Should not be awaiting options already");
-
- return new Promise(resolve => {
- _optionsPromise = {resolve};
- });
- };
-
- browser.runtime.onMessage.addListener((msg, sender) => {
- if (msg == "options.html") {
- if (_optionsPromise) {
- _optionsPromise.resolve(sender.tab);
- _optionsPromise = null;
- } else {
- browser.test.fail("Saw unexpected options page load");
- }
- }
- });
-
- try {
- let [firstTab] = await browser.tabs.query({currentWindow: true, active: true});
-
- browser.test.log("Open options page. Expect fresh load.");
-
- let [, optionsTab] = await Promise.all([
- browser.runtime.openOptionsPage(),
- awaitOptions(),
- ]);
-
- browser.test.assertEq("about:addons", optionsTab.url, "Tab contains AddonManager");
- browser.test.assertTrue(optionsTab.active, "Tab is active");
- browser.test.assertTrue(optionsTab.id != firstTab.id, "Tab is a new tab");
-
- browser.test.assertEq(0, browser.extension.getViews({type: "popup"}).length, "viewType is not popup");
- browser.test.assertEq(1, browser.extension.getViews({type: "tab"}).length, "viewType is tab");
- browser.test.assertEq(1, browser.extension.getViews({windowId: optionsTab.windowId}).length, "windowId matches");
-
- let views = browser.extension.getViews();
- browser.test.assertEq(2, views.length, "Expected the options page and the background page");
- browser.test.assertTrue(views.includes(window), "One of the views is the background page");
- browser.test.assertTrue(views.some(w => w.iAmOption), "One of the views is the options page");
-
- browser.test.log("Switch tabs.");
- await browser.tabs.update(firstTab.id, {active: true});
-
- browser.test.log("Open options page again. Expect tab re-selected, no new load.");
-
- await browser.runtime.openOptionsPage();
- let [tab] = await browser.tabs.query({currentWindow: true, active: true});
-
- browser.test.assertEq(optionsTab.id, tab.id, "Tab is the same as the previous options tab");
- browser.test.assertEq("about:addons", tab.url, "Tab contains AddonManager");
-
- browser.test.log("Ping options page.");
- let pong = await browser.runtime.sendMessage("ping");
- browser.test.assertEq("pong", pong, "Got pong.");
-
- browser.test.log("Remove options tab.");
- await browser.tabs.remove(optionsTab.id);
-
- browser.test.log("Open options page again. Expect fresh load.");
- [, tab] = await Promise.all([
- browser.runtime.openOptionsPage(),
- awaitOptions(),
- ]);
- browser.test.assertEq("about:addons", tab.url, "Tab contains AddonManager");
- browser.test.assertTrue(tab.active, "Tab is active");
- browser.test.assertTrue(tab.id != optionsTab.id, "Tab is a new tab");
-
- await browser.tabs.remove(tab.id);
-
- browser.test.notifyPass("options-ui");
- } catch (error) {
- browser.test.fail(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("options-ui");
- }
- },
- }));
-
- yield extension.awaitFinish("options-ui");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_tasks(function* test_tab_options(extraOptions) {
- info(`Test options opened in a tab (${JSON.stringify(extraOptions)})`);
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
-
- let extension = yield loadExtension(Object.assign({}, extraOptions, {
- manifest: {
- applications: {gecko: {id: "tab_options@tests.mozilla.org"}},
- "options_ui": {
- "page": "options.html",
- "open_in_tab": true,
- },
- },
-
- background: async function() {
- let _optionsPromise;
- let awaitOptions = () => {
- browser.test.assertFalse(_optionsPromise, "Should not be awaiting options already");
-
- return new Promise(resolve => {
- _optionsPromise = {resolve};
- });
- };
-
- browser.runtime.onMessage.addListener((msg, sender) => {
- if (msg == "options.html") {
- if (_optionsPromise) {
- _optionsPromise.resolve(sender.tab);
- _optionsPromise = null;
- } else {
- browser.test.fail("Saw unexpected options page load");
- }
- }
- });
-
- let optionsURL = browser.extension.getURL("options.html");
-
- try {
- let [firstTab] = await browser.tabs.query({currentWindow: true, active: true});
-
- browser.test.log("Open options page. Expect fresh load.");
- let [, optionsTab] = await Promise.all([
- browser.runtime.openOptionsPage(),
- awaitOptions(),
- ]);
- browser.test.assertEq(optionsURL, optionsTab.url, "Tab contains options.html");
- browser.test.assertTrue(optionsTab.active, "Tab is active");
- browser.test.assertTrue(optionsTab.id != firstTab.id, "Tab is a new tab");
-
- browser.test.assertEq(0, browser.extension.getViews({type: "popup"}).length, "viewType is not popup");
- browser.test.assertEq(1, browser.extension.getViews({type: "tab"}).length, "viewType is tab");
- browser.test.assertEq(1, browser.extension.getViews({windowId: optionsTab.windowId}).length, "windowId matches");
-
- let views = browser.extension.getViews();
- browser.test.assertEq(2, views.length, "Expected the options page and the background page");
- browser.test.assertTrue(views.includes(window), "One of the views is the background page");
- browser.test.assertTrue(views.some(w => w.iAmOption), "One of the views is the options page");
-
- browser.test.log("Switch tabs.");
- await browser.tabs.update(firstTab.id, {active: true});
-
- browser.test.log("Open options page again. Expect tab re-selected, no new load.");
-
- await browser.runtime.openOptionsPage();
- let [tab] = await browser.tabs.query({currentWindow: true, active: true});
-
- browser.test.assertEq(optionsTab.id, tab.id, "Tab is the same as the previous options tab");
- browser.test.assertEq(optionsURL, tab.url, "Tab contains options.html");
-
- // Unfortunately, we can't currently do this, since onMessage doesn't
- // currently support responses when there are multiple listeners.
- //
- // browser.test.log("Ping options page.");
- // return new Promise(resolve => browser.runtime.sendMessage("ping", resolve));
-
- browser.test.log("Remove options tab.");
- await browser.tabs.remove(optionsTab.id);
-
- browser.test.log("Open options page again. Expect fresh load.");
- [, tab] = await Promise.all([
- browser.runtime.openOptionsPage(),
- awaitOptions(),
- ]);
- browser.test.assertEq(optionsURL, tab.url, "Tab contains options.html");
- browser.test.assertTrue(tab.active, "Tab is active");
- browser.test.assertTrue(tab.id != optionsTab.id, "Tab is a new tab");
-
- await browser.tabs.remove(tab.id);
-
- browser.test.notifyPass("options-ui-tab");
- } catch (error) {
- browser.test.fail(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("options-ui-tab");
- }
- },
- }));
-
- yield extension.awaitFinish("options-ui-tab");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_tasks(function* test_options_no_manifest(extraOptions) {
- info(`Test with no manifest key (${JSON.stringify(extraOptions)})`);
-
- let extension = yield loadExtension(Object.assign({}, extraOptions, {
- manifest: {
- applications: {gecko: {id: "no_options@tests.mozilla.org"}},
- },
-
- async background() {
- browser.test.log("Try to open options page when not specified in the manifest.");
-
- await browser.test.assertRejects(
- browser.runtime.openOptionsPage(),
- /No `options_ui` declared/,
- "Expected error from openOptionsPage()");
-
- browser.test.notifyPass("options-no-manifest");
- },
- }));
-
- yield extension.awaitFinish("options-no-manifest");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage_uninstall.js b/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage_uninstall.js
deleted file mode 100644
index 0c123b70e..000000000
--- a/browser/components/extensions/test/browser/browser_ext_runtime_openOptionsPage_uninstall.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* loadExtension(options) {
- let extension = ExtensionTestUtils.loadExtension({
- useAddonManager: "temporary",
-
- manifest: Object.assign({
- "permissions": ["tabs"],
- }, options.manifest),
-
- files: {
- "options.html": `<!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <script src="options.js" type="text/javascript"></script>
- </head>
- </html>`,
-
- "options.js": function() {
- browser.runtime.sendMessage("options.html");
- browser.runtime.onMessage.addListener((msg, sender, respond) => {
- if (msg == "ping") {
- respond("pong");
- }
- });
- },
- },
-
- background: options.background,
- });
-
- yield extension.startup();
-
- return extension;
-}
-
-add_task(function* test_inline_options_uninstall() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
-
- let extension = yield loadExtension({
- manifest: {
- applications: {gecko: {id: "inline_options_uninstall@tests.mozilla.org"}},
- "options_ui": {
- "page": "options.html",
- },
- },
-
- background: async function() {
- let _optionsPromise;
- let awaitOptions = () => {
- browser.test.assertFalse(_optionsPromise, "Should not be awaiting options already");
-
- return new Promise(resolve => {
- _optionsPromise = {resolve};
- });
- };
-
- browser.runtime.onMessage.addListener((msg, sender) => {
- if (msg == "options.html") {
- if (_optionsPromise) {
- _optionsPromise.resolve(sender.tab);
- _optionsPromise = null;
- } else {
- browser.test.fail("Saw unexpected options page load");
- }
- }
- });
-
- try {
- let [firstTab] = await browser.tabs.query({currentWindow: true, active: true});
-
- browser.test.log("Open options page. Expect fresh load.");
- let [, tab] = await Promise.all([
- browser.runtime.openOptionsPage(),
- awaitOptions(),
- ]);
-
- browser.test.assertEq("about:addons", tab.url, "Tab contains AddonManager");
- browser.test.assertTrue(tab.active, "Tab is active");
- browser.test.assertTrue(tab.id != firstTab.id, "Tab is a new tab");
-
- browser.test.sendMessage("options-ui-open");
- } catch (error) {
- browser.test.fail(`Error: ${error} :: ${error.stack}`);
- }
- },
- });
-
- yield extension.awaitMessage("options-ui-open");
- yield extension.unload();
-
- is(gBrowser.selectedBrowser.currentURI.spec, "about:addons",
- "Add-on manager tab should still be open");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_runtime_setUninstallURL.js b/browser/components/extensions/test/browser/browser_ext_runtime_setUninstallURL.js
deleted file mode 100644
index 1c7ef4969..000000000
--- a/browser/components/extensions/test/browser/browser_ext_runtime_setUninstallURL.js
+++ /dev/null
@@ -1,94 +0,0 @@
-"use strict";
-
-let {AddonManager} = Components.utils.import("resource://gre/modules/AddonManager.jsm", {});
-let {Extension} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function* makeAndInstallXPI(id, backgroundScript, loadedURL) {
- let xpi = Extension.generateXPI({
- manifest: {applications: {gecko: {id}}},
- background: backgroundScript,
- });
- SimpleTest.registerCleanupFunction(function cleanupXPI() {
- Services.obs.notifyObservers(xpi, "flush-cache-entry", null);
- xpi.remove(false);
- });
-
- let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, loadedURL);
-
-
- info(`installing ${xpi.path}`);
- let addon = yield AddonManager.installTemporaryAddon(xpi);
- info("installed");
-
- // A WebExtension is started asynchronously, we have our test extension
- // open a new tab to signal that the background script has executed.
- let loadTab = yield loadPromise;
- yield BrowserTestUtils.removeTab(loadTab);
-
- return addon;
-}
-
-
-add_task(function* test_setuninstallurl_badargs() {
- async function background() {
- await browser.test.assertRejects(
- browser.runtime.setUninstallURL("this is not a url"),
- /Invalid URL/,
- "setUninstallURL with an invalid URL should fail");
-
- await browser.test.assertRejects(
- browser.runtime.setUninstallURL("file:///etc/passwd"),
- /must have the scheme http or https/,
- "setUninstallURL with an illegal URL should fail");
-
- browser.test.notifyPass("setUninstallURL bad params");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background,
- });
- yield extension.startup();
- yield extension.awaitFinish();
- yield extension.unload();
-});
-
-// Test the documented behavior of setUninstallURL() that passing an
-// empty string is equivalent to not setting an uninstall URL
-// (i.e., no new tab is opened upon uninstall)
-add_task(function* test_setuninstall_empty_url() {
- async function backgroundScript() {
- await browser.runtime.setUninstallURL("");
- browser.tabs.create({url: "http://example.com/addon_loaded"});
- }
-
- let addon = yield makeAndInstallXPI("test_uinstallurl2@tests.mozilla.org",
- backgroundScript,
- "http://example.com/addon_loaded");
-
- addon.uninstall(true);
- info("uninstalled");
-
- // no need to explicitly check for the absence of a new tab,
- // BrowserTestUtils will eventually complain if one is opened.
-});
-
-add_task(function* test_setuninstallurl() {
- async function backgroundScript() {
- await browser.runtime.setUninstallURL("http://example.com/addon_uninstalled");
- browser.tabs.create({url: "http://example.com/addon_loaded"});
- }
-
- let addon = yield makeAndInstallXPI("test_uinstallurl@tests.mozilla.org",
- backgroundScript,
- "http://example.com/addon_loaded");
-
- // look for a new tab with the uninstall url.
- let uninstallPromise = BrowserTestUtils.waitForNewTab(gBrowser, "http://example.com/addon_uninstalled");
-
- addon.uninstall(true);
- info("uninstalled");
-
- let uninstalledTab = yield uninstallPromise;
- isnot(uninstalledTab, null, "opened tab with uninstall url");
- yield BrowserTestUtils.removeTab(uninstalledTab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js
deleted file mode 100644
index 413f7bde6..000000000
--- a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* globals recordInitialTimestamps, onlyNewItemsFilter, checkRecentlyClosed */
-
-requestLongerTimeout(2);
-
-Services.scriptloader.loadSubScript(new URL("head_sessions.js", gTestPath).href,
- this);
-
-add_task(function* test_sessions_get_recently_closed() {
- function* openAndCloseWindow(url = "http://example.com", tabUrls) {
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url);
- yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
- if (tabUrls) {
- for (let url of tabUrls) {
- yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, url);
- }
- }
- yield BrowserTestUtils.closeWindow(win);
- }
-
- function background() {
- Promise.all([
- browser.sessions.getRecentlyClosed(),
- browser.tabs.query({active: true, currentWindow: true}),
- ]).then(([recentlyClosed, tabs]) => {
- browser.test.sendMessage("initialData", {recentlyClosed, currentWindowId: tabs[0].windowId});
- });
-
- browser.test.onMessage.addListener((msg, filter) => {
- if (msg == "check-sessions") {
- browser.sessions.getRecentlyClosed(filter).then(recentlyClosed => {
- browser.test.sendMessage("recentlyClosed", recentlyClosed);
- });
- }
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["sessions", "tabs"],
- },
- background,
- });
-
- // Open and close a window that will be ignored, to prove that we are removing previous entries
- yield openAndCloseWindow();
-
- yield extension.startup();
-
- let {recentlyClosed, currentWindowId} = yield extension.awaitMessage("initialData");
- recordInitialTimestamps(recentlyClosed.map(item => item.lastModified));
-
- yield openAndCloseWindow();
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- checkRecentlyClosed(recentlyClosed.filter(onlyNewItemsFilter), 1, currentWindowId);
-
- yield openAndCloseWindow("about:config", ["about:robots", "about:mozilla"]);
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- // Check for multiple tabs in most recently closed window
- is(recentlyClosed[0].window.tabs.length, 3, "most recently closed window has the expected number of tabs");
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
- yield BrowserTestUtils.removeTab(tab);
-
- tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
- yield BrowserTestUtils.removeTab(tab);
-
- yield openAndCloseWindow();
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- let finalResult = recentlyClosed.filter(onlyNewItemsFilter);
- checkRecentlyClosed(finalResult, 5, currentWindowId);
-
- isnot(finalResult[0].window, undefined, "first item is a window");
- is(finalResult[0].tab, undefined, "first item is not a tab");
- isnot(finalResult[1].tab, undefined, "second item is a tab");
- is(finalResult[1].window, undefined, "second item is not a window");
- isnot(finalResult[2].tab, undefined, "third item is a tab");
- is(finalResult[2].window, undefined, "third item is not a window");
- isnot(finalResult[3].window, undefined, "fourth item is a window");
- is(finalResult[3].tab, undefined, "fourth item is not a tab");
- isnot(finalResult[4].window, undefined, "fifth item is a window");
- is(finalResult[4].tab, undefined, "fifth item is not a tab");
-
- // test with filter
- extension.sendMessage("check-sessions", {maxResults: 2});
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- checkRecentlyClosed(recentlyClosed.filter(onlyNewItemsFilter), 2, currentWindowId);
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_private.js b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_private.js
deleted file mode 100644
index 217c8e130..000000000
--- a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_private.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* globals recordInitialTimestamps, onlyNewItemsFilter, checkRecentlyClosed */
-
-SimpleTest.requestCompleteLog();
-
-Services.scriptloader.loadSubScript(new URL("head_sessions.js", gTestPath).href,
- this);
-
-add_task(function* test_sessions_get_recently_closed_private() {
- function background() {
- browser.test.onMessage.addListener((msg, filter) => {
- if (msg == "check-sessions") {
- browser.sessions.getRecentlyClosed(filter).then(recentlyClosed => {
- browser.test.sendMessage("recentlyClosed", recentlyClosed);
- });
- }
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["sessions", "tabs"],
- },
- background,
- });
-
- // Open a private browsing window.
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
-
- yield extension.startup();
-
- let {Management: {global: {WindowManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
- let privateWinId = WindowManager.getId(privateWin);
-
- extension.sendMessage("check-sessions");
- let recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- recordInitialTimestamps(recentlyClosed.map(item => item.lastModified));
-
- // Open and close two tabs in the private window
- let tab = yield BrowserTestUtils.openNewForegroundTab(privateWin.gBrowser, "http://example.com");
- yield BrowserTestUtils.removeTab(tab);
-
- tab = yield BrowserTestUtils.openNewForegroundTab(privateWin.gBrowser, "http://example.com");
- yield BrowserTestUtils.removeTab(tab);
-
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- checkRecentlyClosed(recentlyClosed.filter(onlyNewItemsFilter), 2, privateWinId, true);
-
- // Close the private window.
- yield BrowserTestUtils.closeWindow(privateWin);
-
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- is(recentlyClosed.filter(onlyNewItemsFilter).length, 0, "the closed private window info was not found in recently closed data");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js
deleted file mode 100644
index ae0daff9a..000000000
--- a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function expectedTabInfo(tab, window) {
- let browser = tab.linkedBrowser;
- return {
- url: browser.currentURI.spec,
- title: browser.contentTitle,
- favIconUrl: window.gBrowser.getIcon(tab),
- };
-}
-
-function checkTabInfo(expected, actual) {
- for (let prop in expected) {
- is(actual[prop], expected[prop], `Expected value found for ${prop} of tab object.`);
- }
-}
-
-add_task(async function test_sessions_get_recently_closed_tabs() {
- async function background() {
- browser.test.onMessage.addListener(async msg => {
- if (msg == "check-sessions") {
- let recentlyClosed = await browser.sessions.getRecentlyClosed();
- browser.test.sendMessage("recentlyClosed", recentlyClosed);
- }
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["sessions", "tabs"],
- },
- background,
- });
-
- let win = await BrowserTestUtils.openNewBrowserWindow();
- await BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, "about:addons");
- await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
- let expectedTabs = [];
- let tab = win.gBrowser.selectedTab;
- expectedTabs.push(expectedTabInfo(tab, win));
-
- for (let url of ["about:robots", "about:mozilla"]) {
- tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, url);
- expectedTabs.push(expectedTabInfo(tab, win));
- }
-
- await extension.startup();
-
- // Test with a closed tab.
- await BrowserTestUtils.removeTab(tab);
-
- extension.sendMessage("check-sessions");
- let recentlyClosed = await extension.awaitMessage("recentlyClosed");
- let tabInfo = recentlyClosed[0].tab;
- let expectedTab = expectedTabs.pop();
- checkTabInfo(expectedTab, tabInfo);
-
- // Test with a closed window containing tabs.
- await BrowserTestUtils.closeWindow(win);
-
- extension.sendMessage("check-sessions");
- recentlyClosed = await extension.awaitMessage("recentlyClosed");
- let tabInfos = recentlyClosed[0].window.tabs;
- is(tabInfos.length, 2, "Expected number of tabs in closed window.");
- for (let x = 0; x < tabInfos.length; x++) {
- checkTabInfo(expectedTabs[x], tabInfos[x]);
- }
-
- await extension.unload();
-
- // Test without tabs permission.
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["sessions"],
- },
- background,
- });
-
- await extension.startup();
-
- extension.sendMessage("check-sessions");
- recentlyClosed = await extension.awaitMessage("recentlyClosed");
- tabInfos = recentlyClosed[0].window.tabs;
- is(tabInfos.length, 2, "Expected number of tabs in closed window.");
- for (let tabInfo of tabInfos) {
- for (let prop in expectedTabs[0]) {
- is(undefined,
- tabInfo[prop],
- `${prop} of tab object is undefined without tabs permission.`);
- }
- }
-
- await extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_restore.js b/browser/components/extensions/test/browser/browser_ext_sessions_restore.js
deleted file mode 100644
index 6f1c6cf9a..000000000
--- a/browser/components/extensions/test/browser/browser_ext_sessions_restore.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-SimpleTest.requestCompleteLog();
-
-XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
- "resource:///modules/sessionstore/SessionStore.jsm");
-
-add_task(function* test_sessions_restore() {
- function background() {
- browser.test.onMessage.addListener((msg, data) => {
- if (msg == "check-sessions") {
- browser.sessions.getRecentlyClosed().then(recentlyClosed => {
- browser.test.sendMessage("recentlyClosed", recentlyClosed);
- });
- } else if (msg == "restore") {
- browser.sessions.restore(data).then(sessions => {
- browser.test.sendMessage("restored", sessions);
- });
- } else if (msg == "restore-reject") {
- browser.sessions.restore("not-a-valid-session-id").then(
- sessions => {
- browser.test.fail("restore rejected with an invalid sessionId");
- },
- error => {
- browser.test.assertTrue(
- error.message.includes("Could not restore object using sessionId not-a-valid-session-id."));
- browser.test.sendMessage("restore-rejected");
- }
- );
- }
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["sessions", "tabs"],
- },
- background,
- });
-
- yield extension.startup();
-
- let {Management: {global: {WindowManager, TabManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- function checkLocalTab(tab, expectedUrl) {
- let realTab = TabManager.getTab(tab.id);
- let tabState = JSON.parse(SessionStore.getTabState(realTab));
- is(tabState.entries[0].url, expectedUrl, "restored tab has the expected url");
- }
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, "about:config");
- yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
- for (let url of ["about:robots", "about:mozilla"]) {
- yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, url);
- }
- yield BrowserTestUtils.closeWindow(win);
-
- extension.sendMessage("check-sessions");
- let recentlyClosed = yield extension.awaitMessage("recentlyClosed");
-
- // Check that our expected window is the most recently closed.
- is(recentlyClosed[0].window.tabs.length, 3, "most recently closed window has the expected number of tabs");
-
- // Restore the window.
- extension.sendMessage("restore");
- let restored = yield extension.awaitMessage("restored");
-
- is(restored.length, 1, "restore returned the expected number of sessions");
- is(restored[0].window.tabs.length, 3, "restore returned a window with the expected number of tabs");
- checkLocalTab(restored[0].window.tabs[0], "about:config");
- checkLocalTab(restored[0].window.tabs[1], "about:robots");
- checkLocalTab(restored[0].window.tabs[2], "about:mozilla");
-
- // Close the window again.
- let window = WindowManager.getWindow(restored[0].window.id);
- yield BrowserTestUtils.closeWindow(window);
-
- // Restore the window using the sessionId.
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- extension.sendMessage("restore", recentlyClosed[0].window.sessionId);
- restored = yield extension.awaitMessage("restored");
-
- is(restored.length, 1, "restore returned the expected number of sessions");
- is(restored[0].window.tabs.length, 3, "restore returned a window with the expected number of tabs");
- checkLocalTab(restored[0].window.tabs[0], "about:config");
- checkLocalTab(restored[0].window.tabs[1], "about:robots");
- checkLocalTab(restored[0].window.tabs[2], "about:mozilla");
-
- // Close the window again.
- window = WindowManager.getWindow(restored[0].window.id);
- yield BrowserTestUtils.closeWindow(window);
-
- // Open and close a tab.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
- yield BrowserTestUtils.removeTab(tab);
-
- // Restore the most recently closed item.
- extension.sendMessage("restore");
- restored = yield extension.awaitMessage("restored");
-
- is(restored.length, 1, "restore returned the expected number of sessions");
- tab = restored[0].tab;
- ok(tab, "restore returned a tab");
- checkLocalTab(tab, "about:robots");
-
- // Close the tab again.
- let realTab = TabManager.getTab(tab.id);
- yield BrowserTestUtils.removeTab(realTab);
-
- // Restore the tab using the sessionId.
- extension.sendMessage("check-sessions");
- recentlyClosed = yield extension.awaitMessage("recentlyClosed");
- extension.sendMessage("restore", recentlyClosed[0].tab.sessionId);
- restored = yield extension.awaitMessage("restored");
-
- is(restored.length, 1, "restore returned the expected number of sessions");
- tab = restored[0].tab;
- ok(tab, "restore returned a tab");
- checkLocalTab(tab, "about:robots");
-
- // Close the tab again.
- realTab = TabManager.getTab(tab.id);
- yield BrowserTestUtils.removeTab(realTab);
-
- // Try to restore something with an invalid sessionId.
- extension.sendMessage("restore-reject");
- restored = yield extension.awaitMessage("restore-rejected");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_simple.js b/browser/components/extensions/test/browser/browser_ext_simple.js
deleted file mode 100644
index ffa00c9db..000000000
--- a/browser/components/extensions/test/browser/browser_ext_simple.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* test_simple() {
- let extensionData = {
- manifest: {
- "name": "Simple extension test",
- "version": "1.0",
- "manifest_version": 2,
- "description": "",
- },
- };
-
- let extension = ExtensionTestUtils.loadExtension(extensionData);
- info("load complete");
- yield extension.startup();
- info("startup complete");
- yield extension.unload();
- info("extension unloaded successfully");
-});
-
-add_task(function* test_background() {
- function backgroundScript() {
- browser.test.log("running background script");
-
- browser.test.onMessage.addListener((x, y) => {
- browser.test.assertEq(x, 10, "x is 10");
- browser.test.assertEq(y, 20, "y is 20");
-
- browser.test.notifyPass("background test passed");
- });
-
- browser.test.sendMessage("running", 1);
- }
-
- let extensionData = {
- background: "(" + backgroundScript.toString() + ")()",
- manifest: {
- "name": "Simple extension test",
- "version": "1.0",
- "manifest_version": 2,
- "description": "",
- },
- };
-
- let extension = ExtensionTestUtils.loadExtension(extensionData);
- info("load complete");
- let [, x] = yield Promise.all([extension.startup(), extension.awaitMessage("running")]);
- is(x, 1, "got correct value from extension");
- info("startup complete");
- extension.sendMessage(10, 20);
- yield extension.awaitFinish();
- info("test complete");
- yield extension.unload();
- info("extension unloaded successfully");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tab_runtimeConnect.js b/browser/components/extensions/test/browser/browser_ext_tab_runtimeConnect.js
deleted file mode 100644
index a5541a002..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tab_runtimeConnect.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- let messages_received = [];
-
- let tabId;
-
- browser.runtime.onConnect.addListener((port) => {
- browser.test.assertTrue(!!port, "tab to background port received");
- browser.test.assertEq("tab-connection-name", port.name, "port name should be defined and equal to connectInfo.name");
- browser.test.assertTrue(!!port.sender.tab, "port.sender.tab should be defined");
- browser.test.assertEq(tabId, port.sender.tab.id, "port.sender.tab.id should be equal to the expected tabId");
-
- port.onMessage.addListener((msg) => {
- messages_received.push(msg);
-
- if (messages_received.length == 1) {
- browser.test.assertEq("tab to background port message", msg, "'tab to background' port message received");
- port.postMessage("background to tab port message");
- }
-
- if (messages_received.length == 2) {
- browser.test.assertTrue(!!msg.tabReceived, "'background to tab' reply port message received");
- browser.test.assertEq("background to tab port message", msg.tabReceived, "reply port content contains the message received");
-
- browser.test.notifyPass("tabRuntimeConnect.pass");
- }
- });
- });
-
- browser.tabs.create({url: "tab.html"},
- (tab) => { tabId = tab.id; });
- },
-
- files: {
- "tab.js": function() {
- let port = browser.runtime.connect({name: "tab-connection-name"});
- port.postMessage("tab to background port message");
- port.onMessage.addListener((msg) => {
- port.postMessage({tabReceived: msg});
- });
- },
- "tab.html": `
- <!DOCTYPE html>
- <html>
- <head>
- <title>test tab extension page</title>
- <meta charset="utf-8">
- <script src="tab.js" async></script>
- </head>
- <body>
- <h1>test tab extension page</h1>
- </body>
- </html>
- `,
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabRuntimeConnect.pass");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_audio.js b/browser/components/extensions/test/browser/browser_ext_tabs_audio.js
deleted file mode 100644
index f9f6956d4..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_audio.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank?1");
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank?2");
-
- gBrowser.selectedTab = tab1;
-
- async function background() {
- function promiseUpdated(tabId, attr) {
- return new Promise(resolve => {
- let onUpdated = (tabId_, changeInfo, tab) => {
- if (tabId == tabId_ && attr in changeInfo) {
- browser.tabs.onUpdated.removeListener(onUpdated);
-
- resolve({changeInfo, tab});
- }
- };
- browser.tabs.onUpdated.addListener(onUpdated);
- });
- }
-
- let deferred = {};
- browser.test.onMessage.addListener((message, tabId, result) => {
- if (message == "change-tab-done" && deferred[tabId]) {
- deferred[tabId].resolve(result);
- }
- });
-
- function changeTab(tabId, attr, on) {
- return new Promise((resolve, reject) => {
- deferred[tabId] = {resolve, reject};
- browser.test.sendMessage("change-tab", tabId, attr, on);
- });
- }
-
-
- try {
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
- browser.test.assertEq(tabs.length, 3, "We have three tabs");
-
- for (let tab of tabs) {
- // Note: We want to check that these are actual boolean values, not
- // just that they evaluate as false.
- browser.test.assertEq(false, tab.mutedInfo.muted, "Tab is not muted");
- browser.test.assertEq(undefined, tab.mutedInfo.reason, "Tab has no muted info reason");
- browser.test.assertEq(false, tab.audible, "Tab is not audible");
- }
-
- let windowId = tabs[0].windowId;
- let tabIds = [tabs[1].id, tabs[2].id];
-
- browser.test.log("Test initial queries for muted and audible return no tabs");
- let silent = await browser.tabs.query({windowId, audible: false});
- let audible = await browser.tabs.query({windowId, audible: true});
- let muted = await browser.tabs.query({windowId, muted: true});
- let nonMuted = await browser.tabs.query({windowId, muted: false});
-
- browser.test.assertEq(3, silent.length, "Three silent tabs");
- browser.test.assertEq(0, audible.length, "No audible tabs");
-
- browser.test.assertEq(0, muted.length, "No muted tabs");
- browser.test.assertEq(3, nonMuted.length, "Three non-muted tabs");
-
- browser.test.log("Toggle muted and audible externally on one tab each, and check results");
- [muted, audible] = await Promise.all([
- promiseUpdated(tabIds[0], "mutedInfo"),
- promiseUpdated(tabIds[1], "audible"),
- changeTab(tabIds[0], "muted", true),
- changeTab(tabIds[1], "audible", true),
- ]);
-
- for (let obj of [muted.changeInfo, muted.tab]) {
- browser.test.assertEq(true, obj.mutedInfo.muted, "Tab is muted");
- browser.test.assertEq("user", obj.mutedInfo.reason, "Tab was muted by the user");
- }
-
- browser.test.assertEq(true, audible.changeInfo.audible, "Tab audible state changed");
- browser.test.assertEq(true, audible.tab.audible, "Tab is audible");
-
- browser.test.log("Re-check queries. Expect one audible and one muted tab");
- silent = await browser.tabs.query({windowId, audible: false});
- audible = await browser.tabs.query({windowId, audible: true});
- muted = await browser.tabs.query({windowId, muted: true});
- nonMuted = await browser.tabs.query({windowId, muted: false});
-
- browser.test.assertEq(2, silent.length, "Two silent tabs");
- browser.test.assertEq(1, audible.length, "One audible tab");
-
- browser.test.assertEq(1, muted.length, "One muted tab");
- browser.test.assertEq(2, nonMuted.length, "Two non-muted tabs");
-
- browser.test.assertEq(true, muted[0].mutedInfo.muted, "Tab is muted");
- browser.test.assertEq("user", muted[0].mutedInfo.reason, "Tab was muted by the user");
-
- browser.test.assertEq(true, audible[0].audible, "Tab is audible");
-
- browser.test.log("Toggle muted internally on two tabs, and check results");
- [nonMuted, muted] = await Promise.all([
- promiseUpdated(tabIds[0], "mutedInfo"),
- promiseUpdated(tabIds[1], "mutedInfo"),
- browser.tabs.update(tabIds[0], {muted: false}),
- browser.tabs.update(tabIds[1], {muted: true}),
- ]);
-
- for (let obj of [nonMuted.changeInfo, nonMuted.tab]) {
- browser.test.assertEq(false, obj.mutedInfo.muted, "Tab is not muted");
- }
- for (let obj of [muted.changeInfo, muted.tab]) {
- browser.test.assertEq(true, obj.mutedInfo.muted, "Tab is muted");
- }
-
- for (let obj of [nonMuted.changeInfo, nonMuted.tab, muted.changeInfo, muted.tab]) {
- browser.test.assertEq("extension", obj.mutedInfo.reason, "Mute state changed by extension");
-
- // FIXME: browser.runtime.id is currently broken.
- browser.test.assertEq(browser.i18n.getMessage("@@extension_id"),
- obj.mutedInfo.extensionId,
- "Mute state changed by extension");
- }
-
- browser.test.log("Test that mutedInfo is preserved by sessionstore");
- let tab = await changeTab(tabIds[1], "duplicate").then(browser.tabs.get);
-
- browser.test.assertEq(true, tab.mutedInfo.muted, "Tab is muted");
-
- browser.test.assertEq("extension", tab.mutedInfo.reason, "Mute state changed by extension");
-
- // FIXME: browser.runtime.id is currently broken.
- browser.test.assertEq(browser.i18n.getMessage("@@extension_id"),
- tab.mutedInfo.extensionId,
- "Mute state changed by extension");
-
- browser.test.log("Unmute externally, and check results");
- [nonMuted] = await Promise.all([
- promiseUpdated(tabIds[1], "mutedInfo"),
- changeTab(tabIds[1], "muted", false),
- browser.tabs.remove(tab.id),
- ]);
-
- for (let obj of [nonMuted.changeInfo, nonMuted.tab]) {
- browser.test.assertEq(false, obj.mutedInfo.muted, "Tab is not muted");
- browser.test.assertEq("user", obj.mutedInfo.reason, "Mute state changed by user");
- }
-
- browser.test.notifyPass("tab-audio");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("tab-audio");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- extension.onMessage("change-tab", (tabId, attr, on) => {
- let {Management: {global: {TabManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let tab = TabManager.getTab(tabId);
-
- if (attr == "muted") {
- // Ideally we'd simulate a click on the tab audio icon for this, but the
- // handler relies on CSS :hover states, which are complicated and fragile
- // to simulate.
- if (tab.muted != on) {
- tab.toggleMuteAudio();
- }
- } else if (attr == "audible") {
- let browser = tab.linkedBrowser;
- if (on) {
- browser.audioPlaybackStarted();
- } else {
- browser.audioPlaybackStopped();
- }
- } else if (attr == "duplicate") {
- // This is a bit of a hack. It won't be necessary once we have
- // `tabs.duplicate`.
- let newTab = gBrowser.duplicateTab(tab);
- BrowserTestUtils.waitForEvent(newTab, "SSTabRestored", () => true).then(() => {
- extension.sendMessage("change-tab-done", tabId, TabManager.getId(newTab));
- });
- return;
- }
-
- extension.sendMessage("change-tab-done", tabId);
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("tab-audio");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_captureVisibleTab.js b/browser/components/extensions/test/browser/browser_ext_tabs_captureVisibleTab.js
deleted file mode 100644
index 1491a19ab..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_captureVisibleTab.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* runTest(options) {
- options.neutral = [0xaa, 0xaa, 0xaa];
-
- let html = `
- <!DOCTYPE html>
- <html lang="en">
- <head><meta charset="UTF-8"></head>
- <body style="background-color: rgb(${options.color})">
- <!-- Fill most of the image with a neutral color to test edge-to-edge scaling. -->
- <div style="position: absolute;
- left: 2px;
- right: 2px;
- top: 2px;
- bottom: 2px;
- background: rgb(${options.neutral});"></div>
- </body>
- </html>
- `;
-
- let url = `data:text/html,${encodeURIComponent(html)}`;
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url, true);
-
- tab.linkedBrowser.fullZoom = options.fullZoom;
-
- async function background(options) {
- browser.test.log(`Test color ${options.color} at fullZoom=${options.fullZoom}`);
-
- try {
- let [tab] = await browser.tabs.query({currentWindow: true, active: true});
-
- let [jpeg, png, ...pngs] = await Promise.all([
- browser.tabs.captureVisibleTab(tab.windowId, {format: "jpeg", quality: 95}),
- browser.tabs.captureVisibleTab(tab.windowId, {format: "png", quality: 95}),
- browser.tabs.captureVisibleTab(tab.windowId, {quality: 95}),
- browser.tabs.captureVisibleTab(tab.windowId),
- ]);
-
- browser.test.assertTrue(pngs.every(url => url == png), "All PNGs are identical");
-
- browser.test.assertTrue(jpeg.startsWith("data:image/jpeg;base64,"), "jpeg is JPEG");
- browser.test.assertTrue(png.startsWith("data:image/png;base64,"), "png is PNG");
-
- let promises = [jpeg, png].map(url => new Promise(resolve => {
- let img = new Image();
- img.src = url;
- img.onload = () => resolve(img);
- }));
-
- [jpeg, png] = await Promise.all(promises);
- let tabDims = `${tab.width}\u00d7${tab.height}`;
-
- let images = {jpeg, png};
- for (let format of Object.keys(images)) {
- let img = images[format];
-
- let dims = `${img.width}\u00d7${img.height}`;
- browser.test.assertEq(tabDims, dims, `${format} dimensions are correct`);
-
- let canvas = document.createElement("canvas");
- canvas.width = img.width;
- canvas.height = img.height;
- canvas.mozOpaque = true;
-
- let ctx = canvas.getContext("2d");
- ctx.drawImage(img, 0, 0);
-
- // Check the colors of the first and last pixels of the image, to make
- // sure we capture the entire frame, and scale it correctly.
- let coords = [
- {x: 0, y: 0,
- color: options.color},
- {x: img.width - 1,
- y: img.height - 1,
- color: options.color},
- {x: img.width / 2 | 0,
- y: img.height / 2 | 0,
- color: options.neutral},
- ];
-
- for (let {x, y, color} of coords) {
- let imageData = ctx.getImageData(x, y, 1, 1).data;
-
- if (format == "png") {
- browser.test.assertEq(`rgba(${color},255)`, `rgba(${[...imageData]})`, `${format} image color is correct at (${x}, ${y})`);
- } else {
- // Allow for some deviation in JPEG version due to lossy compression.
- const SLOP = 3;
-
- browser.test.log(`Testing ${format} image color at (${x}, ${y}), have rgba(${[...imageData]}), expecting approx. rgba(${color},255)`);
-
- browser.test.assertTrue(Math.abs(color[0] - imageData[0]) <= SLOP, `${format} image color.red is correct at (${x}, ${y})`);
- browser.test.assertTrue(Math.abs(color[1] - imageData[1]) <= SLOP, `${format} image color.green is correct at (${x}, ${y})`);
- browser.test.assertTrue(Math.abs(color[2] - imageData[2]) <= SLOP, `${format} image color.blue is correct at (${x}, ${y})`);
- browser.test.assertEq(255, imageData[3], `${format} image color.alpha is correct at (${x}, ${y})`);
- }
- }
- }
-
- browser.test.notifyPass("captureVisibleTab");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFail("captureVisibleTab");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["<all_urls>"],
- },
-
- background: `(${background})(${JSON.stringify(options)})`,
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("captureVisibleTab");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-}
-
-add_task(function* testCaptureVisibleTab() {
- yield runTest({color: [0, 0, 0], fullZoom: 1});
-
- yield runTest({color: [0, 0, 0], fullZoom: 2});
-
- yield runTest({color: [0, 0, 0], fullZoom: 0.5});
-
- yield runTest({color: [255, 255, 255], fullZoom: 1});
-});
-
-add_task(function* testCaptureVisibleTabPermissions() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background() {
- browser.test.assertFalse("captureVisibleTab" in browser.tabs,
- 'Extension without "<all_tabs>" permission should not have access to captureVisibleTab');
- browser.test.notifyPass("captureVisibleTabPermissions");
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("captureVisibleTabPermissions");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js b/browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js
deleted file mode 100644
index dc0647e3c..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* setup() {
- // make sure userContext is enabled.
- return SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true],
- ]});
-});
-
-add_task(function* () {
- info("Start testing tabs.create with cookieStoreId");
-
- let testCases = [
- // No private window
- {privateTab: false, cookieStoreId: null, success: true, expectedCookieStoreId: "firefox-default"},
- {privateTab: false, cookieStoreId: "firefox-default", success: true, expectedCookieStoreId: "firefox-default"},
- {privateTab: false, cookieStoreId: "firefox-container-1", success: true, expectedCookieStoreId: "firefox-container-1"},
- {privateTab: false, cookieStoreId: "firefox-container-2", success: true, expectedCookieStoreId: "firefox-container-2"},
- {privateTab: false, cookieStoreId: "firefox-container-42", failure: "exist"},
- {privateTab: false, cookieStoreId: "firefox-private", failure: "defaultToPrivate"},
- {privateTab: false, cookieStoreId: "wow", failure: "illegal"},
-
- // Private window
- {privateTab: true, cookieStoreId: null, success: true, expectedCookieStoreId: "firefox-private"},
- {privateTab: true, cookieStoreId: "firefox-private", success: true, expectedCookieStoreId: "firefox-private"},
- {privateTab: true, cookieStoreId: "firefox-default", failure: "privateToDefault"},
- {privateTab: true, cookieStoreId: "firefox-container-1", failure: "privateToDefault"},
- {privateTab: true, cookieStoreId: "wow", failure: "illegal"},
- ];
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs", "cookies"],
- },
-
- background: function() {
- function testTab(data, tab) {
- browser.test.assertTrue(data.success, "we want a success");
- browser.test.assertTrue(!!tab, "we have a tab");
- browser.test.assertEq(data.expectedCookieStoreId, tab.cookieStoreId, "tab should have the correct cookieStoreId");
- }
-
- async function runTest(data) {
- try {
- // Tab Creation
- let tab;
- try {
- tab = await browser.tabs.create({
- windowId: data.privateTab ? this.privateWindowId : this.defaultWindowId,
- cookieStoreId: data.cookieStoreId,
- });
-
- browser.test.assertTrue(!data.failure, "we want a success");
- } catch (error) {
- browser.test.assertTrue(!!data.failure, "we want a failure");
-
- if (data.failure == "illegal") {
- browser.test.assertTrue(/Illegal cookieStoreId/.test(error.message),
- "runtime.lastError should report the expected error message");
- } else if (data.failure == "defaultToPrivate") {
- browser.test.assertTrue("Illegal to set private cookieStorageId in a non private window",
- error.message,
- "runtime.lastError should report the expected error message");
- } else if (data.failure == "privateToDefault") {
- browser.test.assertTrue("Illegal to set non private cookieStorageId in a private window",
- error.message,
- "runtime.lastError should report the expected error message");
- } else if (data.failure == "exist") {
- browser.test.assertTrue(/No cookie store exists/.test(error.message),
- "runtime.lastError should report the expected error message");
- } else {
- browser.test.fail("The test is broken");
- }
-
- browser.test.sendMessage("test-done");
- return;
- }
-
- // Tests for tab creation
- testTab(data, tab);
-
- {
- // Tests for tab querying
- let [tab] = await browser.tabs.query({
- windowId: data.privateTab ? this.privateWindowId : this.defaultWindowId,
- cookieStoreId: data.cookieStoreId,
- });
-
- browser.test.assertTrue(tab != undefined, "Tab found!");
- testTab(data, tab);
- }
-
- let stores = await browser.cookies.getAllCookieStores();
-
- let store = stores.find(store => store.id === tab.cookieStoreId);
- browser.test.assertTrue(!!store, "We have a store for this tab.");
-
- await browser.tabs.remove(tab.id);
-
- browser.test.sendMessage("test-done");
- } catch (e) {
- browser.test.fail("An exception has been thrown");
- }
- }
-
- async function initialize() {
- let win = await browser.windows.create({incognito: true});
- this.privateWindowId = win.id;
-
- win = await browser.windows.create({incognito: false});
- this.defaultWindowId = win.id;
-
- browser.test.sendMessage("ready");
- }
-
- async function shutdown() {
- await browser.windows.remove(this.privateWindowId);
- await browser.windows.remove(this.defaultWindowId);
- browser.test.sendMessage("gone");
- }
-
- // Waiting for messages
- browser.test.onMessage.addListener((msg, data) => {
- if (msg == "be-ready") {
- initialize();
- } else if (msg == "test") {
- runTest(data);
- } else {
- browser.test.assertTrue("finish", msg, "Shutting down");
- shutdown();
- }
- });
- },
- });
-
- yield extension.startup();
-
- info("Tests must be ready...");
- extension.sendMessage("be-ready");
- yield extension.awaitMessage("ready");
- info("Tests are ready to run!");
-
- for (let test of testCases) {
- info(`test tab.create with cookieStoreId: "${test.cookieStoreId}"`);
- extension.sendMessage("test", test);
- yield extension.awaitMessage("test-done");
- }
-
- info("Waiting for shutting down...");
- extension.sendMessage("finish");
- yield extension.awaitMessage("gone");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_create.js b/browser/components/extensions/test/browser/browser_ext_tabs_create.js
deleted file mode 100644
index 8bc5a68a2..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_create.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
- gBrowser.selectedTab = tab;
-
- // TODO: Multiple windows.
-
- // Using pre-loaded new tab pages interferes with onUpdated events.
- // It probably shouldn't.
- SpecialPowers.setBoolPref("browser.newtab.preload", false);
- registerCleanupFunction(() => {
- SpecialPowers.clearUserPref("browser.newtab.preload");
- });
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
-
- "background": {"page": "bg/background.html"},
- },
-
- files: {
- "bg/blank.html": `<html><head><meta charset="utf-8"></head></html>`,
-
- "bg/background.html": `<html><head>
- <meta charset="utf-8">
- <script src="background.js"></script>
- </head></html>`,
-
- "bg/background.js": function() {
- let activeTab;
- let activeWindow;
-
- function runTests() {
- const DEFAULTS = {
- index: 2,
- windowId: activeWindow,
- active: true,
- pinned: false,
- url: "about:newtab",
- };
-
- let tests = [
- {
- create: {url: "http://example.com/"},
- result: {url: "http://example.com/"},
- },
- {
- create: {url: "blank.html"},
- result: {url: browser.runtime.getURL("bg/blank.html")},
- },
- {
- create: {},
- result: {url: "about:newtab"},
- },
- {
- create: {active: false},
- result: {active: false},
- },
- {
- create: {active: true},
- result: {active: true},
- },
- {
- create: {pinned: true},
- result: {pinned: true, index: 0},
- },
- {
- create: {pinned: true, active: true},
- result: {pinned: true, active: true, index: 0},
- },
- {
- create: {pinned: true, active: false},
- result: {pinned: true, active: false, index: 0},
- },
- {
- create: {index: 1},
- result: {index: 1},
- },
- {
- create: {index: 1, active: false},
- result: {index: 1, active: false},
- },
- {
- create: {windowId: activeWindow},
- result: {windowId: activeWindow},
- },
- ];
-
- async function nextTest() {
- if (!tests.length) {
- browser.test.notifyPass("tabs.create");
- return;
- }
-
- let test = tests.shift();
- let expected = Object.assign({}, DEFAULTS, test.result);
-
- browser.test.log(`Testing tabs.create(${JSON.stringify(test.create)}), expecting ${JSON.stringify(test.result)}`);
-
- let updatedPromise = new Promise(resolve => {
- let onUpdated = (changedTabId, changed) => {
- if (changed.url) {
- browser.tabs.onUpdated.removeListener(onUpdated);
- resolve({tabId: changedTabId, url: changed.url});
- }
- };
- browser.tabs.onUpdated.addListener(onUpdated);
- });
-
- let createdPromise = new Promise(resolve => {
- let onCreated = tab => {
- browser.test.assertTrue("id" in tab, `Expected tabs.onCreated callback to receive tab object`);
- resolve();
- };
- browser.tabs.onCreated.addListener(onCreated);
- });
-
- let [tab] = await Promise.all([
- browser.tabs.create(test.create),
- createdPromise,
- ]);
- let tabId = tab.id;
-
- for (let key of Object.keys(expected)) {
- if (key === "url") {
- // FIXME: This doesn't get updated until later in the load cycle.
- continue;
- }
-
- browser.test.assertEq(expected[key], tab[key], `Expected value for tab.${key}`);
- }
-
- let updated = await updatedPromise;
- browser.test.assertEq(tabId, updated.tabId, `Expected value for tab.id`);
- browser.test.assertEq(expected.url, updated.url, `Expected value for tab.url`);
-
- await browser.tabs.remove(tabId);
- await browser.tabs.update(activeTab, {active: true});
-
- nextTest();
- }
-
- nextTest();
- }
-
- browser.tabs.query({active: true, currentWindow: true}, tabs => {
- activeTab = tabs[0].id;
- activeWindow = tabs[0].windowId;
-
- runTests();
- });
- },
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.create");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_create_invalid_url.js b/browser/components/extensions/test/browser/browser_ext_tabs_create_invalid_url.js
deleted file mode 100644
index 49938bf22..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_create_invalid_url.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* testTabsCreateInvalidURL(tabsCreateURL) {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.test.sendMessage("ready");
- browser.test.onMessage.addListener((msg, tabsCreateURL) => {
- browser.tabs.create({url: tabsCreateURL}, (tab) => {
- browser.test.assertEq(undefined, tab, "on error tab should be undefined");
- browser.test.assertTrue(/Illegal URL/.test(browser.runtime.lastError.message),
- "runtime.lastError should report the expected error message");
-
- // Remove the opened tab is any.
- if (tab) {
- browser.tabs.remove(tab.id);
- }
- browser.test.sendMessage("done");
- });
- });
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("ready");
-
- info(`test tab.create on invalid URL "${tabsCreateURL}"`);
-
- extension.sendMessage("start", tabsCreateURL);
- yield extension.awaitMessage("done");
-
- yield extension.unload();
-}
-
-add_task(function* () {
- info("Start testing tabs.create on invalid URLs");
-
- let dataURLPage = `data:text/html,
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <h1>data url page</h1>
- </body>
- </html>`;
-
- let testCases = [
- {tabsCreateURL: "about:addons"},
- {tabsCreateURL: "javascript:console.log('tabs.update execute javascript')"},
- {tabsCreateURL: dataURLPage},
- ];
-
- for (let {tabsCreateURL} of testCases) {
- yield* testTabsCreateInvalidURL(tabsCreateURL);
- }
-
- info("done");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_detectLanguage.js b/browser/components/extensions/test/browser/browser_ext_tabs_detectLanguage.js
deleted file mode 100644
index f28606001..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_detectLanguage.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testDetectLanguage() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: async function() {
- const BASE_PATH = "browser/browser/components/extensions/test/browser";
-
- function loadTab(url) {
- return browser.tabs.create({url});
- }
-
- try {
- let tab = await loadTab(`http://example.co.jp/${BASE_PATH}/file_language_ja.html`);
- let lang = await browser.tabs.detectLanguage(tab.id);
- browser.test.assertEq("ja", lang, "Japanese document should be detected as Japanese");
- await browser.tabs.remove(tab.id);
-
- tab = await loadTab(`http://example.co.jp/${BASE_PATH}/file_language_fr_en.html`);
- lang = await browser.tabs.detectLanguage(tab.id);
- browser.test.assertEq("fr", lang, "French/English document should be detected as primarily French");
- await browser.tabs.remove(tab.id);
-
- tab = await loadTab(`http://example.co.jp/${BASE_PATH}/file_language_tlh.html`);
- lang = await browser.tabs.detectLanguage(tab.id);
- browser.test.assertEq("und", lang, "Klingon document should not be detected, should return 'und'");
- await browser.tabs.remove(tab.id);
-
- browser.test.notifyPass("detectLanguage");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFail("detectLanguage");
- }
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("detectLanguage");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_duplicate.js b/browser/components/extensions/test/browser/browser_ext_tabs_duplicate.js
deleted file mode 100644
index c4b0ffd2d..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_duplicate.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testDuplicateTab() {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- lastFocusedWindow: true,
- }, function(tabs) {
- let source = tabs[1];
- // By moving it 0, we check that the new tab is created next
- // to the existing one.
- browser.tabs.move(source.id, {index: 0}, () => {
- browser.tabs.duplicate(source.id, (tab) => {
- browser.test.assertEq("http://example.net/", tab.url);
- // Should be the second tab, next to the one duplicated.
- browser.test.assertEq(1, tab.index);
- // Should be selected by default.
- browser.test.assertTrue(tab.selected);
- browser.test.notifyPass("tabs.duplicate");
- });
- });
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.duplicate");
- yield extension.unload();
-
- while (gBrowser.tabs[0].linkedBrowser.currentURI.spec === "http://example.net/") {
- yield BrowserTestUtils.removeTab(gBrowser.tabs[0]);
- }
-});
-
-add_task(function* testDuplicateTabLazily() {
- async function background() {
- let tabLoadComplete = new Promise(resolve => {
- browser.test.onMessage.addListener((message, tabId, result) => {
- if (message == "duplicate-tab-done") {
- resolve(tabId);
- }
- });
- });
-
- function awaitLoad(tabId) {
- return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
- if (tabId == tabId_ && changed.status == "complete") {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
- }
-
- try {
- let url = "http://example.com/browser/browser/components/extensions/test/browser/file_dummy.html";
- let tab = await browser.tabs.create({url});
- let startTabId = tab.id;
-
- await awaitLoad(startTabId);
- browser.test.sendMessage("duplicate-tab", startTabId);
-
- let unloadedTabId = await tabLoadComplete;
- let loadedtab = await browser.tabs.get(startTabId);
- browser.test.assertEq("Dummy test page", loadedtab.title, "Title should be returned for loaded pages");
- browser.test.assertEq("complete", loadedtab.status, "Tab status should be complete for loaded pages");
-
- let unloadedtab = await browser.tabs.get(unloadedTabId);
- browser.test.assertEq("Dummy test page", unloadedtab.title, "Title should be returned after page has been unloaded");
-
- await browser.tabs.remove([tab.id, unloadedTabId]);
- browser.test.notifyPass("tabs.hasCorrectTabTitle");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("tabs.hasCorrectTabTitle");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- extension.onMessage("duplicate-tab", tabId => {
- let {Management: {global: {TabManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let tab = TabManager.getTab(tabId);
- // This is a bit of a hack to load a tab in the background.
- let newTab = gBrowser.duplicateTab(tab, false);
-
- BrowserTestUtils.waitForEvent(newTab, "SSTabRestored", () => true).then(() => {
- extension.sendMessage("duplicate-tab-done", TabManager.getId(newTab));
- });
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.hasCorrectTabTitle");
- yield extension.unload();
-});
-
-add_task(function* testDuplicatePinnedTab() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
- gBrowser.pinTab(tab);
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- lastFocusedWindow: true,
- }, function(tabs) {
- // Duplicate the pinned tab, example.net.
- browser.tabs.duplicate(tabs[0].id, (tab) => {
- browser.test.assertEq("http://example.net/", tab.url);
- // Should be the second tab, next to the one duplicated.
- browser.test.assertEq(1, tab.index);
- // Should be pinned.
- browser.test.assertTrue(tab.pinned);
- browser.test.notifyPass("tabs.duplicate.pinned");
- });
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.duplicate.pinned");
- yield extension.unload();
-
- while (gBrowser.tabs[0].linkedBrowser.currentURI.spec === "http://example.net/") {
- yield BrowserTestUtils.removeTab(gBrowser.tabs[0]);
- }
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_events.js b/browser/components/extensions/test/browser/browser_ext_tabs_events.js
deleted file mode 100644
index 75dea40fd..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_events.js
+++ /dev/null
@@ -1,280 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testTabEvents() {
- async function background() {
- let events = [];
- browser.tabs.onCreated.addListener(tab => {
- events.push({type: "onCreated", tab});
- });
-
- browser.tabs.onAttached.addListener((tabId, info) => {
- events.push(Object.assign({type: "onAttached", tabId}, info));
- });
-
- browser.tabs.onDetached.addListener((tabId, info) => {
- events.push(Object.assign({type: "onDetached", tabId}, info));
- });
-
- browser.tabs.onRemoved.addListener((tabId, info) => {
- events.push(Object.assign({type: "onRemoved", tabId}, info));
- });
-
- browser.tabs.onMoved.addListener((tabId, info) => {
- events.push(Object.assign({type: "onMoved", tabId}, info));
- });
-
- async function expectEvents(names) {
- browser.test.log(`Expecting events: ${names.join(", ")}`);
-
- await new Promise(resolve => setTimeout(resolve, 0));
-
- browser.test.assertEq(names.length, events.length, "Got expected number of events");
- for (let [i, name] of names.entries()) {
- browser.test.assertEq(name, i in events && events[i].type,
- `Got expected ${name} event`);
- }
- return events.splice(0);
- }
-
- try {
- browser.test.log("Create second browser window");
-
- let windows = await Promise.all([
- browser.windows.getCurrent(),
- browser.windows.create({url: "about:blank"}),
- ]);
-
- let windowId = windows[0].id;
- let otherWindowId = windows[1].id;
-
- let [created] = await expectEvents(["onCreated"]);
- let initialTab = created.tab;
-
-
- browser.test.log("Create tab in window 1");
- let tab = await browser.tabs.create({windowId, index: 0, url: "about:blank"});
- let oldIndex = tab.index;
- browser.test.assertEq(0, oldIndex, "Tab has the expected index");
-
- [created] = await expectEvents(["onCreated"]);
- browser.test.assertEq(tab.id, created.tab.id, "Got expected tab ID");
- browser.test.assertEq(oldIndex, created.tab.index, "Got expected tab index");
-
-
- browser.test.log("Move tab to window 2");
- await browser.tabs.move([tab.id], {windowId: otherWindowId, index: 0});
-
- let [detached, attached] = await expectEvents(["onDetached", "onAttached"]);
- browser.test.assertEq(oldIndex, detached.oldPosition, "Expected old index");
- browser.test.assertEq(windowId, detached.oldWindowId, "Expected old window ID");
-
- browser.test.assertEq(0, attached.newPosition, "Expected new index");
- browser.test.assertEq(otherWindowId, attached.newWindowId, "Expected new window ID");
-
-
- browser.test.log("Move tab within the same window");
- let [moved] = await browser.tabs.move([tab.id], {index: 1});
- browser.test.assertEq(1, moved.index, "Expected new index");
-
- [moved] = await expectEvents(["onMoved"]);
- browser.test.assertEq(tab.id, moved.tabId, "Expected tab ID");
- browser.test.assertEq(0, moved.fromIndex, "Expected old index");
- browser.test.assertEq(1, moved.toIndex, "Expected new index");
- browser.test.assertEq(otherWindowId, moved.windowId, "Expected window ID");
-
-
- browser.test.log("Remove tab");
- await browser.tabs.remove(tab.id);
- let [removed] = await expectEvents(["onRemoved"]);
-
- browser.test.assertEq(tab.id, removed.tabId, "Expected removed tab ID");
- browser.test.assertEq(otherWindowId, removed.windowId, "Expected removed tab window ID");
- // Note: We want to test for the actual boolean value false here.
- browser.test.assertEq(false, removed.isWindowClosing, "Expected isWindowClosing value");
-
-
- browser.test.log("Close second window");
- await browser.windows.remove(otherWindowId);
- [removed] = await expectEvents(["onRemoved"]);
- browser.test.assertEq(initialTab.id, removed.tabId, "Expected removed tab ID");
- browser.test.assertEq(otherWindowId, removed.windowId, "Expected removed tab window ID");
- browser.test.assertEq(true, removed.isWindowClosing, "Expected isWindowClosing value");
-
-
- browser.test.log("Create additional tab in window 1");
- tab = await browser.tabs.create({windowId, url: "about:blank"});
- await expectEvents(["onCreated"]);
-
-
- browser.test.log("Create a new window, adopting the new tab");
- // We have to explicitly wait for the event here, since its timing is
- // not predictable.
- let promiseAttached = new Promise(resolve => {
- browser.tabs.onAttached.addListener(function listener(tabId) {
- browser.tabs.onAttached.removeListener(listener);
- resolve();
- });
- });
-
- let [window] = await Promise.all([
- browser.windows.create({tabId: tab.id}),
- promiseAttached,
- ]);
-
- [detached, attached] = await expectEvents(["onDetached", "onAttached"]);
-
- browser.test.assertEq(tab.id, detached.tabId, "Expected onDetached tab ID");
-
- browser.test.assertEq(tab.id, attached.tabId, "Expected onAttached tab ID");
- browser.test.assertEq(0, attached.newPosition, "Expected onAttached new index");
- browser.test.assertEq(window.id, attached.newWindowId,
- "Expected onAttached new window id");
-
- browser.test.log("Close the new window");
- await browser.windows.remove(window.id);
-
- browser.test.notifyPass("tabs-events");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("tabs-events");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs-events");
- yield extension.unload();
-});
-
-add_task(function* testTabEventsSize() {
- function background() {
- function sendSizeMessages(tab, type) {
- browser.test.sendMessage(`${type}-dims`, {width: tab.width, height: tab.height});
- }
-
- browser.tabs.onCreated.addListener(tab => {
- sendSizeMessages(tab, "on-created");
- });
-
- browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
- if (changeInfo.status == "complete") {
- sendSizeMessages(tab, "on-updated");
- }
- });
-
- browser.test.onMessage.addListener(async (msg, arg) => {
- if (msg === "create-tab") {
- let tab = await browser.tabs.create({url: "http://example.com/"});
- sendSizeMessages(tab, "create");
- browser.test.sendMessage("created-tab-id", tab.id);
- } else if (msg === "update-tab") {
- let tab = await browser.tabs.update(arg, {url: "http://example.org/"});
- sendSizeMessages(tab, "update");
- } else if (msg === "remove-tab") {
- browser.tabs.remove(arg);
- browser.test.sendMessage("tab-removed");
- }
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
- background,
- });
-
- const RESOLUTION_PREF = "layout.css.devPixelsPerPx";
- registerCleanupFunction(() => {
- SpecialPowers.clearUserPref(RESOLUTION_PREF);
- });
-
- function checkDimensions(dims, type) {
- is(dims.width, gBrowser.selectedBrowser.clientWidth, `tab from ${type} reports expected width`);
- is(dims.height, gBrowser.selectedBrowser.clientHeight, `tab from ${type} reports expected height`);
- }
-
- yield Promise.all([extension.startup(), extension.awaitMessage("ready")]);
-
- for (let resolution of [2, 1]) {
- SpecialPowers.setCharPref(RESOLUTION_PREF, String(resolution));
- is(window.devicePixelRatio, resolution, "window has the required resolution");
-
- extension.sendMessage("create-tab");
- let tabId = yield extension.awaitMessage("created-tab-id");
-
- checkDimensions(yield extension.awaitMessage("create-dims"), "create");
- checkDimensions(yield extension.awaitMessage("on-created-dims"), "onCreated");
- checkDimensions(yield extension.awaitMessage("on-updated-dims"), "onUpdated");
-
- extension.sendMessage("update-tab", tabId);
-
- checkDimensions(yield extension.awaitMessage("update-dims"), "update");
- checkDimensions(yield extension.awaitMessage("on-updated-dims"), "onUpdated");
-
- extension.sendMessage("remove-tab", tabId);
- yield extension.awaitMessage("tab-removed");
- }
-
- yield extension.unload();
- SpecialPowers.clearUserPref(RESOLUTION_PREF);
-});
-
-add_task(function* testTabRemovalEvent() {
- async function background() {
- function awaitLoad(tabId) {
- return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
- if (tabId == tabId_ && changed.status == "complete") {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
- }
-
- chrome.tabs.onRemoved.addListener((tabId, info) => {
- browser.test.log("Make sure the removed tab is not available in the tabs.query callback.");
- chrome.tabs.query({}, tabs => {
- for (let tab of tabs) {
- browser.test.assertTrue(tab.id != tabId, "Tab query should not include removed tabId");
- }
- browser.test.notifyPass("tabs-events");
- });
- });
-
- try {
- let url = "http://example.com/browser/browser/components/extensions/test/browser/context.html";
- let tab = await browser.tabs.create({url: url});
- await awaitLoad(tab.id);
-
- await browser.tabs.remove(tab.id);
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("tabs-events");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs-events");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript.js b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript.js
deleted file mode 100644
index 5a15f2e39..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testExecuteScript() {
- let {MessageChannel} = Cu.import("resource://gre/modules/MessageChannel.jsm", {});
-
- function countMM(messageManagerMap) {
- let count = 0;
- // List of permanent message managers in the main process. We should not
- // count them in the test because MessageChannel unsubscribes when the
- // message manager closes, which never happens to these, of course.
- let globalMMs = [
- Services.mm,
- Services.ppmm,
- Services.ppmm.getChildAt(0),
- ];
- for (let mm of messageManagerMap.keys()) {
- // Sanity check: mm is a message manager.
- try {
- mm.QueryInterface(Ci.nsIMessageSender);
- } catch (e) {
- mm.QueryInterface(Ci.nsIMessageBroadcaster);
- }
- if (!globalMMs.includes(mm)) {
- ++count;
- }
- }
- return count;
- }
-
- let messageManagersSize = countMM(MessageChannel.messageManagers);
- let responseManagersSize = countMM(MessageChannel.responseManagers);
-
- const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
- const URL = BASE + "file_iframe_document.html";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URL, true);
-
- async function background() {
- try {
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- let frames = await browser.webNavigation.getAllFrames({tabId: tab.id});
-
- browser.test.log(`FRAMES: ${frames[1].frameId} ${JSON.stringify(frames)}\n`);
- await Promise.all([
- browser.tabs.executeScript({
- code: "42",
- }).then(result => {
- browser.test.assertEq(1, result.length, "Expected one callback result");
- browser.test.assertEq(42, result[0], "Expected callback result");
- }),
-
- browser.tabs.executeScript({
- file: "script.js",
- code: "42",
- }).then(result => {
- browser.test.fail("Expected not to be able to execute a script with both file and code");
- }, error => {
- browser.test.assertTrue(/a 'code' or a 'file' property, but not both/.test(error.message),
- "Got expected error");
- }),
-
- browser.tabs.executeScript({
- file: "script.js",
- }).then(result => {
- browser.test.assertEq(1, result.length, "Expected one callback result");
- browser.test.assertEq(undefined, result[0], "Expected callback result");
- }),
-
- browser.tabs.executeScript({
- file: "script2.js",
- }).then(result => {
- browser.test.assertEq(1, result.length, "Expected one callback result");
- browser.test.assertEq(27, result[0], "Expected callback result");
- }),
-
- browser.tabs.executeScript({
- code: "location.href;",
- allFrames: true,
- }).then(result => {
- browser.test.assertTrue(Array.isArray(result), "Result is an array");
-
- browser.test.assertEq(2, result.length, "Result has correct length");
-
- browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
- browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
- }),
-
- browser.tabs.executeScript({
- code: "location.href;",
- runAt: "document_end",
- }).then(result => {
- browser.test.assertEq(1, result.length, "Expected callback result");
- browser.test.assertEq("string", typeof result[0], "Result is a string");
-
- browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "Result is correct");
- }),
-
- browser.tabs.executeScript({
- code: "window",
- }).then(result => {
- browser.test.fail("Expected error when returning non-structured-clonable object");
- }, error => {
- browser.test.assertEq("Script returned non-structured-clonable data",
- error.message, "Got expected error");
- }),
-
- browser.tabs.executeScript({
- code: "Promise.resolve(window)",
- }).then(result => {
- browser.test.fail("Expected error when returning non-structured-clonable object");
- }, error => {
- browser.test.assertEq("Script returned non-structured-clonable data",
- error.message, "Got expected error");
- }),
-
- browser.tabs.executeScript({
- frameId: Number.MAX_SAFE_INTEGER,
- code: "42",
- }).then(result => {
- browser.test.fail("Expected error when specifying invalid frame ID");
- }, error => {
- let details = {
- frame_id: Number.MAX_SAFE_INTEGER,
- matchesHost: ["http://mochi.test/", "http://example.com/"],
- };
- browser.test.assertEq(`No window matching ${JSON.stringify(details)}`,
- error.message, "Got expected error");
- }),
-
- browser.tabs.create({url: "http://example.net/", active: false}).then(async tab => {
- await browser.tabs.executeScript(tab.id, {
- code: "42",
- }).then(result => {
- browser.test.fail("Expected error when trying to execute on invalid domain");
- }, error => {
- let details = {
- matchesHost: ["http://mochi.test/", "http://example.com/"],
- };
- browser.test.assertEq(`No window matching ${JSON.stringify(details)}`,
- error.message, "Got expected error");
- });
-
- await browser.tabs.remove(tab.id);
- }),
-
- browser.tabs.executeScript({
- code: "Promise.resolve(42)",
- }).then(result => {
- browser.test.assertEq(42, result[0], "Got expected promise resolution value as result");
- }),
-
- browser.tabs.executeScript({
- code: "location.href;",
- runAt: "document_end",
- allFrames: true,
- }).then(result => {
- browser.test.assertTrue(Array.isArray(result), "Result is an array");
-
- browser.test.assertEq(2, result.length, "Result has correct length");
-
- browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
- browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
- }),
-
- browser.tabs.executeScript({
- code: "location.href;",
- frameId: frames[0].frameId,
- }).then(result => {
- browser.test.assertEq(1, result.length, "Expected one result");
- browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), `Result for frameId[0] is correct: ${result[0]}`);
- }),
-
- browser.tabs.executeScript({
- code: "location.href;",
- frameId: frames[1].frameId,
- }).then(result => {
- browser.test.assertEq(1, result.length, "Expected one result");
- browser.test.assertEq("http://mochi.test:8888/", result[0], "Result for frameId[1] is correct");
- }),
-
- browser.tabs.create({url: "http://example.com/"}).then(async tab => {
- let result = await browser.tabs.executeScript(tab.id, {code: "location.href"});
-
- browser.test.assertEq("http://example.com/", result[0], "Script executed correctly in new tab");
-
- await browser.tabs.remove(tab.id);
- }),
-
- new Promise(resolve => {
- browser.runtime.onMessage.addListener(message => {
- browser.test.assertEq("script ran", message, "Expected runtime message");
- resolve();
- });
- }),
- ]);
-
- browser.test.notifyPass("executeScript");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFail("executeScript");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["http://mochi.test/", "http://example.com/", "webNavigation"],
- },
-
- background,
-
- files: {
- "script.js": function() {
- browser.runtime.sendMessage("script ran");
- },
-
- "script2.js": "27",
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("executeScript");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-
- // Make sure that we're not holding on to references to closed message
- // managers.
- is(countMM(MessageChannel.messageManagers), messageManagersSize, "Message manager count");
- is(countMM(MessageChannel.responseManagers), responseManagersSize, "Response manager count");
- is(MessageChannel.pendingResponses.size, 0, "Pending response count");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_bad.js b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_bad.js
deleted file mode 100644
index d11354ead..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_bad.js
+++ /dev/null
@@ -1,217 +0,0 @@
-"use strict";
-
-// This is a pretty terrible hack, but it's the best we can do until we
-// support |executeScript| callbacks and |lastError|.
-function* testHasNoPermission(params) {
- let contentSetup = params.contentSetup || (() => Promise.resolve());
-
- async function background(contentSetup) {
- browser.runtime.onMessage.addListener((msg, sender) => {
- browser.test.assertEq(msg, "second script ran", "second script ran");
- browser.test.notifyPass("executeScript");
- });
-
- browser.test.onMessage.addListener(msg => {
- browser.test.assertEq(msg, "execute-script");
-
- browser.tabs.query({currentWindow: true}, tabs => {
- browser.tabs.executeScript({
- file: "script.js",
- });
-
- // Execute a script we know we have permissions for in the
- // second tab, in the hopes that it will execute after the
- // first one. This has intermittent failure written all over
- // it, but it's just about the best we can do until we
- // support callbacks for executeScript.
- browser.tabs.executeScript(tabs[1].id, {
- file: "second-script.js",
- });
- });
- });
-
- await contentSetup();
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: params.manifest,
-
- background: `(${background})(${contentSetup})`,
-
- files: {
- "script.js": function() {
- browser.runtime.sendMessage("first script ran");
- },
-
- "second-script.js": function() {
- browser.runtime.sendMessage("second script ran");
- },
- },
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- if (params.setup) {
- yield params.setup(extension);
- }
-
- extension.sendMessage("execute-script");
-
- yield extension.awaitFinish("executeScript");
- yield extension.unload();
-}
-
-add_task(function* testBadPermissions() {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
-
- info("Test no special permissions");
- yield testHasNoPermission({
- manifest: {"permissions": ["http://example.com/"]},
- });
-
- info("Test tabs permissions");
- yield testHasNoPermission({
- manifest: {"permissions": ["http://example.com/", "tabs"]},
- });
-
- info("Test no special permissions, commands, key press");
- yield testHasNoPermission({
- manifest: {
- "permissions": ["http://example.com/"],
- "commands": {
- "test-tabs-executeScript": {
- "suggested_key": {
- "default": "Alt+Shift+K",
- },
- },
- },
- },
- contentSetup() {
- browser.commands.onCommand.addListener(function(command) {
- if (command == "test-tabs-executeScript") {
- browser.test.sendMessage("tabs-command-key-pressed");
- }
- });
- return Promise.resolve();
- },
- setup: function* (extension) {
- yield EventUtils.synthesizeKey("k", {altKey: true, shiftKey: true});
- yield extension.awaitMessage("tabs-command-key-pressed");
- },
- });
-
- info("Test active tab, commands, no key press");
- yield testHasNoPermission({
- manifest: {
- "permissions": ["http://example.com/", "activeTab"],
- "commands": {
- "test-tabs-executeScript": {
- "suggested_key": {
- "default": "Alt+Shift+K",
- },
- },
- },
- },
- });
-
- info("Test active tab, browser action, no click");
- yield testHasNoPermission({
- manifest: {
- "permissions": ["http://example.com/", "activeTab"],
- "browser_action": {},
- },
- });
-
- info("Test active tab, page action, no click");
- yield testHasNoPermission({
- manifest: {
- "permissions": ["http://example.com/", "activeTab"],
- "page_action": {},
- },
- async contentSetup() {
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- await browser.pageAction.show(tab.id);
- },
- });
-
- yield BrowserTestUtils.removeTab(tab2);
- yield BrowserTestUtils.removeTab(tab1);
-});
-
-add_task(function* testBadURL() {
- async function background() {
- let promises = [
- new Promise(resolve => {
- browser.tabs.executeScript({
- file: "http://example.com/script.js",
- }, result => {
- browser.test.assertEq(undefined, result, "Result value");
-
- browser.test.assertTrue(browser.extension.lastError instanceof Error,
- "runtime.lastError is Error");
-
- browser.test.assertTrue(browser.runtime.lastError instanceof Error,
- "runtime.lastError is Error");
-
- browser.test.assertEq(
- "Files to be injected must be within the extension",
- browser.extension.lastError && browser.extension.lastError.message,
- "extension.lastError value");
-
- browser.test.assertEq(
- "Files to be injected must be within the extension",
- browser.runtime.lastError && browser.runtime.lastError.message,
- "runtime.lastError value");
-
- resolve();
- });
- }),
-
- browser.tabs.executeScript({
- file: "http://example.com/script.js",
- }).catch(error => {
- browser.test.assertTrue(error instanceof Error, "Error is Error");
-
- browser.test.assertEq(null, browser.extension.lastError,
- "extension.lastError value");
-
- browser.test.assertEq(null, browser.runtime.lastError,
- "runtime.lastError value");
-
- browser.test.assertEq(
- "Files to be injected must be within the extension",
- error && error.message,
- "error value");
- }),
- ];
-
- await Promise.all(promises);
-
- browser.test.notifyPass("executeScript-lastError");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["<all_urls>"],
- },
-
- background,
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("executeScript-lastError");
-
- yield extension.unload();
-});
-
-// TODO: Test that |executeScript| fails if the tab has navigated to a
-// new page, and no longer matches our expected state. This involves
-// intentionally trying to trigger a race condition, and is probably not
-// even worth attempting until we have proper |executeScript| callbacks.
-
-add_task(forceGC);
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js
deleted file mode 100644
index cf4721310..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-requestLongerTimeout(2);
-
-function* testHasPermission(params) {
- let contentSetup = params.contentSetup || (() => Promise.resolve());
-
- async function background(contentSetup) {
- browser.runtime.onMessage.addListener((msg, sender) => {
- browser.test.assertEq(msg, "script ran", "script ran");
- browser.test.notifyPass("executeScript");
- });
-
- browser.test.onMessage.addListener(msg => {
- browser.test.assertEq(msg, "execute-script");
-
- browser.tabs.executeScript({
- file: "script.js",
- });
- });
-
- await contentSetup();
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: params.manifest,
-
- background: `(${background})(${contentSetup})`,
-
- files: {
- "script.js": function() {
- browser.runtime.sendMessage("script ran");
- },
- },
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- if (params.setup) {
- yield params.setup(extension);
- }
-
- extension.sendMessage("execute-script");
-
- yield extension.awaitFinish("executeScript");
-
- if (params.tearDown) {
- yield params.tearDown(extension);
- }
-
- yield extension.unload();
-}
-
-add_task(function* testGoodPermissions() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/", true);
-
- info("Test explicit host permission");
- yield testHasPermission({
- manifest: {"permissions": ["http://mochi.test/"]},
- });
-
- info("Test explicit host subdomain permission");
- yield testHasPermission({
- manifest: {"permissions": ["http://*.mochi.test/"]},
- });
-
- info("Test explicit <all_urls> permission");
- yield testHasPermission({
- manifest: {"permissions": ["<all_urls>"]},
- });
-
- info("Test activeTab permission with a command key press");
- yield testHasPermission({
- manifest: {
- "permissions": ["activeTab"],
- "commands": {
- "test-tabs-executeScript": {
- "suggested_key": {
- "default": "Alt+Shift+K",
- },
- },
- },
- },
- contentSetup() {
- browser.commands.onCommand.addListener(function(command) {
- if (command == "test-tabs-executeScript") {
- browser.test.sendMessage("tabs-command-key-pressed");
- }
- });
- return Promise.resolve();
- },
- setup: function* (extension) {
- yield EventUtils.synthesizeKey("k", {altKey: true, shiftKey: true});
- yield extension.awaitMessage("tabs-command-key-pressed");
- },
- });
-
- info("Test activeTab permission with a browser action click");
- yield testHasPermission({
- manifest: {
- "permissions": ["activeTab"],
- "browser_action": {},
- },
- contentSetup() {
- browser.browserAction.onClicked.addListener(() => {
- browser.test.log("Clicked.");
- });
- return Promise.resolve();
- },
- setup: clickBrowserAction,
- tearDown: closeBrowserAction,
- });
-
- info("Test activeTab permission with a page action click");
- yield testHasPermission({
- manifest: {
- "permissions": ["activeTab"],
- "page_action": {},
- },
- contentSetup: async () => {
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- await browser.pageAction.show(tab.id);
- },
- setup: clickPageAction,
- tearDown: closePageAction,
- });
-
- info("Test activeTab permission with a browser action w/popup click");
- yield testHasPermission({
- manifest: {
- "permissions": ["activeTab"],
- "browser_action": {"default_popup": "_blank.html"},
- },
- setup: async extension => {
- await clickBrowserAction(extension);
- return awaitExtensionPanel(extension, window, "_blank.html");
- },
- tearDown: closeBrowserAction,
- });
-
- info("Test activeTab permission with a page action w/popup click");
- yield testHasPermission({
- manifest: {
- "permissions": ["activeTab"],
- "page_action": {"default_popup": "_blank.html"},
- },
- contentSetup: async () => {
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- await browser.pageAction.show(tab.id);
- },
- setup: clickPageAction,
- tearDown: closePageAction,
- });
-
- info("Test activeTab permission with a context menu click");
- yield testHasPermission({
- manifest: {
- "permissions": ["activeTab", "contextMenus"],
- },
- contentSetup() {
- browser.contextMenus.create({title: "activeTab", contexts: ["all"]});
- return Promise.resolve();
- },
- setup: function* (extension) {
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- let awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("a[href]", {type: "contextmenu", button: 2},
- gBrowser.selectedBrowser);
- yield awaitPopupShown;
-
- let item = contextMenu.querySelector("[label=activeTab]");
-
- yield EventUtils.synthesizeMouseAtCenter(item, {}, window);
-
- yield awaitPopupHidden;
- },
- });
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(forceGC);
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_no_create.js b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_no_create.js
deleted file mode 100644
index 7b2ffe175..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_no_create.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testExecuteScriptAtOnUpdated() {
- const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
- const URL = BASE + "file_iframe_document.html";
- // This is a regression test for bug 1325830.
- // The bug (executeScript not completing any more) occurred when executeScript
- // was called early at the onUpdated event, unless the tabs.create method is
- // called. So this test does not use tabs.create to open new tabs.
- // Note that if this test is run together with other tests that do call
- // tabs.create, then this test case does not properly test the conditions of
- // the regression any more. To verify that the regression has been resolved,
- // this test must be run in isolation.
-
- function background() {
- // Using variables to prevent listeners from running more than once, instead
- // of removing the listener. This is to minimize any IPC, since the bug that
- // is being tested is sensitive to timing.
- let ignore = false;
- let url;
- browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
- if (changeInfo.status === "loading" && tab.url === url && !ignore) {
- ignore = true;
- browser.tabs.executeScript(tabId, {
- code: "document.URL",
- }).then(results => {
- browser.test.assertEq(url, results[0], "Content script should run");
- browser.test.notifyPass("executeScript-at-onUpdated");
- }, error => {
- browser.test.fail(`Unexpected error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("executeScript-at-onUpdated");
- });
- // (running this log call after executeScript to minimize IPC between
- // onUpdated and executeScript.)
- browser.test.log(`Found expected navigation to ${url}`);
- } else {
- // The bug occurs when executeScript is called before a tab is
- // initialized.
- browser.tabs.executeScript(tabId, {code: ""});
- }
- });
- browser.test.onMessage.addListener(testUrl => {
- url = testUrl;
- browser.test.sendMessage("open-test-tab");
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["http://mochi.test/", "tabs"],
- },
- background,
- });
-
- yield extension.startup();
- extension.sendMessage(URL);
- yield extension.awaitMessage("open-test-tab");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URL, true);
-
- yield extension.awaitFinish("executeScript-at-onUpdated");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_runAt.js b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_runAt.js
deleted file mode 100644
index a4c0ed6f1..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_runAt.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/**
- * These tests ensure that the runAt argument to tabs.executeScript delays
- * script execution until the document has reached the correct state.
- *
- * Since tests of this nature are especially race-prone, it relies on a
- * server-JS script to delay the completion of our test page's load cycle long
- * enough for us to attempt to load our scripts in the earlies phase we support.
- *
- * And since we can't actually rely on that timing, it retries any attempts that
- * fail to load as early as expected, but don't load at any illegal time.
- */
-
-add_task(function* testExecuteScript() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true);
-
- async function background() {
- let tab;
-
- const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
- const URL = BASE + "file_iframe_document.sjs";
-
- const MAX_TRIES = 10;
-
- try {
- [tab] = await browser.tabs.query({active: true, currentWindow: true});
-
- let success = false;
- for (let tries = 0; !success && tries < MAX_TRIES; tries++) {
- let url = `${URL}?r=${Math.random()}`;
-
- let loadingPromise = new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId, changed, tab_) {
- if (tabId == tab.id && changed.status == "loading" && tab_.url == url) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
-
- // TODO: Test allFrames and frameId.
-
- await browser.tabs.update({url});
- await loadingPromise;
-
- let states = await Promise.all([
- // Send the executeScript requests in the reverse order that we expect
- // them to execute in, to avoid them passing only because of timing
- // races.
- browser.tabs.executeScript({
- code: "document.readyState",
- runAt: "document_idle",
- }),
- browser.tabs.executeScript({
- code: "document.readyState",
- runAt: "document_end",
- }),
- browser.tabs.executeScript({
- code: "document.readyState",
- runAt: "document_start",
- }),
- ].reverse());
-
- browser.test.log(`Got states: ${states}`);
-
- // Make sure that none of our scripts executed earlier than expected,
- // regardless of retries.
- browser.test.assertTrue(states[1] == "interactive" || states[1] == "complete",
- `document_end state is valid: ${states[1]}`);
- browser.test.assertTrue(states[2] == "complete",
- `document_idle state is valid: ${states[2]}`);
-
- // If we have the earliest valid states for each script, we're done.
- // Otherwise, try again.
- success = (states[0] == "loading" &&
- states[1] == "interactive" &&
- states[2] == "complete");
- }
-
- browser.test.assertTrue(success, "Got the earliest expected states at least once");
-
- browser.test.notifyPass("executeScript-runAt");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFail("executeScript-runAt");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["http://mochi.test/", "tabs"],
- },
-
- background,
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("executeScript-runAt");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_getCurrent.js b/browser/components/extensions/test/browser/browser_ext_tabs_getCurrent.js
deleted file mode 100644
index b67d935cb..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_getCurrent.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
-
- "browser_action": {"default_popup": "popup.html"},
- },
-
- files: {
- "tab.js": function() {
- let url = document.location.href;
-
- browser.tabs.getCurrent(currentTab => {
- browser.test.assertEq(currentTab.url, url, "getCurrent in non-active background tab");
-
- // Activate the tab.
- browser.tabs.onActivated.addListener(function listener({tabId}) {
- if (tabId == currentTab.id) {
- browser.tabs.onActivated.removeListener(listener);
-
- browser.tabs.getCurrent(currentTab => {
- browser.test.assertEq(currentTab.id, tabId, "in active background tab");
- browser.test.assertEq(currentTab.url, url, "getCurrent in non-active background tab");
-
- browser.test.sendMessage("tab-finished");
- });
- }
- });
- browser.tabs.update(currentTab.id, {active: true});
- });
- },
-
- "popup.js": function() {
- browser.tabs.getCurrent(tab => {
- browser.test.assertEq(tab, undefined, "getCurrent in popup script");
- browser.test.sendMessage("popup-finished");
- });
- },
-
- "tab.html": `<head><meta charset="utf-8"><script src="tab.js"></script></head>`,
- "popup.html": `<head><meta charset="utf-8"><script src="popup.js"></script></head>`,
- },
-
- background: function() {
- browser.tabs.getCurrent(tab => {
- browser.test.assertEq(tab, undefined, "getCurrent in background script");
- browser.test.sendMessage("background-finished");
- });
-
- browser.tabs.create({url: "tab.html", active: false});
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("background-finished");
- yield extension.awaitMessage("tab-finished");
-
- clickBrowserAction(extension);
- yield awaitExtensionPanel(extension);
- yield extension.awaitMessage("popup-finished");
- yield closeBrowserAction(extension);
-
- // The extension tab is automatically closed when the extension unloads.
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js b/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js
deleted file mode 100644
index a8e172d94..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_insertCSS.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testExecuteScript() {
- let {MessageChannel} = Cu.import("resource://gre/modules/MessageChannel.jsm", {});
-
- let messageManagersSize = MessageChannel.messageManagers.size;
- let responseManagersSize = MessageChannel.responseManagers.size;
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/", true);
-
- async function background() {
- let tasks = [
- {
- background: "transparent",
- foreground: "rgb(0, 113, 4)",
- promise: () => {
- return browser.tabs.insertCSS({
- file: "file2.css",
- });
- },
- },
- {
- background: "rgb(42, 42, 42)",
- foreground: "rgb(0, 113, 4)",
- promise: () => {
- return browser.tabs.insertCSS({
- code: "* { background: rgb(42, 42, 42) }",
- });
- },
- },
- ];
-
- function checkCSS() {
- let computedStyle = window.getComputedStyle(document.body);
- return [computedStyle.backgroundColor, computedStyle.color];
- }
-
- try {
- for (let {promise, background, foreground} of tasks) {
- let result = await promise();
-
- browser.test.assertEq(undefined, result, "Expected callback result");
-
- [result] = await browser.tabs.executeScript({
- code: `(${checkCSS})()`,
- });
-
- browser.test.assertEq(background, result[0], "Expected background color");
- browser.test.assertEq(foreground, result[1], "Expected foreground color");
- }
-
- browser.test.notifyPass("insertCSS");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFailure("insertCSS");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["http://mochi.test/"],
- },
-
- background,
-
- files: {
- "file2.css": "* { color: rgb(0, 113, 4) }",
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("insertCSS");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-
- // Make sure that we're not holding on to references to closed message
- // managers.
- is(MessageChannel.messageManagers.size, messageManagersSize, "Message manager count");
- is(MessageChannel.responseManagers.size, responseManagersSize, "Response manager count");
- is(MessageChannel.pendingResponses.size, 0, "Pending response count");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_move.js b/browser/components/extensions/test/browser/browser_ext_tabs_move.js
deleted file mode 100644
index 917cdc146..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_move.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config");
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: async function() {
- let [tab] = await browser.tabs.query({lastFocusedWindow: true});
-
- browser.tabs.move(tab.id, {index: 0});
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
-
- browser.test.assertEq(tabs[0].url, tab.url, "should be first tab");
- browser.test.notifyPass("tabs.move.single");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.single");
- yield extension.unload();
-
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: async function() {
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
-
- tabs.sort(function(a, b) { return a.url > b.url; });
-
- browser.tabs.move(tabs.map(tab => tab.id), {index: 0});
-
- tabs = await browser.tabs.query({lastFocusedWindow: true});
-
- browser.test.assertEq(tabs[0].url, "about:blank", "should be first tab");
- browser.test.assertEq(tabs[1].url, "about:config", "should be second tab");
- browser.test.assertEq(tabs[2].url, "about:robots", "should be third tab");
-
- browser.test.notifyPass("tabs.move.multiple");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.multiple");
- yield extension.unload();
-
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- async background() {
- let [, tab] = await browser.tabs.query({lastFocusedWindow: true});
-
- // Assuming that tab.id of 12345 does not exist.
- await browser.test.assertRejects(
- browser.tabs.move([tab.id, 12345], {index: 0}),
- /Invalid tab/,
- "Should receive invalid tab error");
-
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
- browser.test.assertEq(tabs[1].url, tab.url, "should be second tab");
- browser.test.notifyPass("tabs.move.invalid");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.invalid");
- yield extension.unload();
-
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: async function() {
- let [tab] = await browser.tabs.query({lastFocusedWindow: true});
- browser.tabs.move(tab.id, {index: -1});
-
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
-
- browser.test.assertEq(tabs[2].url, tab.url, "should be last tab");
- browser.test.notifyPass("tabs.move.last");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.last");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_move_window.js b/browser/components/extensions/test/browser/browser_ext_tabs_move_window.js
deleted file mode 100644
index f3bce364a..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_move_window.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
- let window1 = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- async background() {
- let tabs = await browser.tabs.query({url: "<all_urls>"});
- let destination = tabs[0];
- let source = tabs[1]; // skip over about:blank in window1
-
- // Assuming that this windowId does not exist.
- await browser.test.assertRejects(
- browser.tabs.move(source.id, {windowId: 123144576, index: 0}),
- /Invalid window/,
- "Should receive invalid window error");
-
- browser.tabs.move(source.id, {windowId: destination.windowId, index: 0});
-
- tabs = await browser.tabs.query({url: "<all_urls>"});
- browser.test.assertEq(tabs[0].url, "http://example.com/");
- browser.test.assertEq(tabs[0].windowId, destination.windowId);
- browser.test.notifyPass("tabs.move.window");
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.window");
- yield extension.unload();
-
- for (let tab of window.gBrowser.tabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- yield BrowserTestUtils.closeWindow(window1);
-});
-
-add_task(function* test_currentWindowAfterTabMoved() {
- const files = {
- "current.html": "<meta charset=utf-8><script src=current.js></script>",
- "current.js": function() {
- browser.test.onMessage.addListener(msg => {
- if (msg === "current") {
- browser.windows.getCurrent(win => {
- browser.test.sendMessage("id", win.id);
- });
- }
- });
- browser.test.sendMessage("ready");
- },
- };
-
- async function background() {
- let tabId;
-
- const url = browser.extension.getURL("current.html");
-
- browser.test.onMessage.addListener(async msg => {
- if (msg === "move") {
- await browser.windows.create({tabId});
- browser.test.sendMessage("moved");
- } else if (msg === "close") {
- await browser.tabs.remove(tabId);
- browser.test.sendMessage("done");
- }
- });
-
- let tab = await browser.tabs.create({url});
- tabId = tab.id;
- }
-
- const extension = ExtensionTestUtils.loadExtension({files, background});
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- extension.sendMessage("current");
- const first = yield extension.awaitMessage("id");
-
- extension.sendMessage("move");
- yield extension.awaitMessage("moved");
-
- extension.sendMessage("current");
- const second = yield extension.awaitMessage("id");
-
- isnot(first, second, "current window id is different after moving the tab");
-
- extension.sendMessage("close");
- yield extension.awaitMessage("done");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_move_window_multiple.js b/browser/components/extensions/test/browser/browser_ext_tabs_move_window_multiple.js
deleted file mode 100644
index dacd547f2..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_move_window_multiple.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let window1 = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, "http://example.net/");
- yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, "http://example.com/");
- yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.net/");
- yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query(
- {url: "<all_urls>"},
- tabs => {
- let move1 = tabs[1];
- let move3 = tabs[3];
- browser.tabs.move([move1.id, move3.id], {index: 0});
- browser.tabs.query(
- {url: "<all_urls>"},
- tabs => {
- browser.test.assertEq(tabs[0].url, move1.url);
- browser.test.assertEq(tabs[2].url, move3.url);
- browser.test.notifyPass("tabs.move.multiple");
- });
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.multiple");
- yield extension.unload();
-
- for (let tab of window.gBrowser.tabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- yield BrowserTestUtils.closeWindow(window1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_move_window_pinned.js b/browser/components/extensions/test/browser/browser_ext_tabs_move_window_pinned.js
deleted file mode 100644
index c592dc56d..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_move_window_pinned.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
- let window1 = yield BrowserTestUtils.openNewBrowserWindow();
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(window1.gBrowser, "http://example.com/");
- window1.gBrowser.pinTab(tab1);
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query(
- {url: "<all_urls>"},
- tabs => {
- let destination = tabs[0];
- let source = tabs[1]; // remember, pinning moves it to the left.
- browser.tabs.move(source.id, {windowId: destination.windowId, index: 0});
-
- browser.tabs.query(
- {url: "<all_urls>"},
- tabs => {
- browser.test.assertEq(true, tabs[0].pinned);
- browser.test.notifyPass("tabs.move.pin");
- });
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.move.pin");
- yield extension.unload();
-
- for (let tab of window.gBrowser.tabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- yield BrowserTestUtils.closeWindow(window1);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js b/browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js
deleted file mode 100644
index 9cc2554d6..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_onHighlighted.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testTabEvents() {
- async function background() {
- /** The list of active tab ID's */
- let tabIds = [];
-
- /**
- * Stores the events that fire for each tab.
- *
- * events {
- * tabId1: [event1, event2, ...],
- * tabId2: [event1, event2, ...],
- * }
- */
- let events = {};
-
- browser.tabs.onActivated.addListener((info) => {
- if (info.tabId in events) {
- events[info.tabId].push("onActivated");
- } else {
- events[info.tabId] = ["onActivated"];
- }
- });
-
- browser.tabs.onHighlighted.addListener((info) => {
- if (info.tabIds[0] in events) {
- events[info.tabIds[0]].push("onHighlighted");
- } else {
- events[info.tabIds[0]] = ["onHighlighted"];
- }
- });
-
- /**
- * Asserts that the expected events are fired for the tab with id = tabId.
- * The events associated to the specified tab are removed after this check is made.
- *
- * @param {number} tabId
- * @param {Array<string>} expectedEvents
- */
- async function expectEvents(tabId, expectedEvents) {
- browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
-
- await new Promise(resolve => setTimeout(resolve, 0));
-
- browser.test.assertEq(expectedEvents.length, events[tabId].length,
- `Got expected number of events for ${tabId}`);
-
- for (let [i, name] of expectedEvents.entries()) {
- browser.test.assertEq(name, i in events[tabId] && events[tabId][i],
- `Got expected ${name} event`);
- }
- delete events[tabId];
- }
-
- /**
- * Opens a new tab and asserts that the correct events are fired.
- *
- * @param {number} windowId
- */
- async function openTab(windowId) {
- let tab = await browser.tabs.create({windowId});
-
- tabIds.push(tab.id);
- browser.test.log(`Opened tab ${tab.id}`);
-
- await expectEvents(tab.id, [
- "onActivated",
- "onHighlighted",
- ]);
- }
-
- /**
- * Highlights an existing tab and asserts that the correct events are fired.
- *
- * @param {number} tabId
- */
- async function highlightTab(tabId) {
- browser.test.log(`Highlighting tab ${tabId}`);
- let tab = await browser.tabs.update(tabId, {active: true});
-
- browser.test.assertEq(tab.id, tabId, `Tab ${tab.id} highlighted`);
-
- await expectEvents(tab.id, [
- "onActivated",
- "onHighlighted",
- ]);
- }
-
- /**
- * The main entry point to the tests.
- */
- let tabs = await browser.tabs.query({active: true, currentWindow: true});
-
- let activeWindow = tabs[0].windowId;
- await Promise.all([
- openTab(activeWindow),
- openTab(activeWindow),
- openTab(activeWindow),
- ]);
-
- await Promise.all([
- highlightTab(tabIds[0]),
- highlightTab(tabIds[1]),
- highlightTab(tabIds[2]),
- ]);
-
- await Promise.all(tabIds.map(id => browser.tabs.remove(id)));
-
- browser.test.notifyPass("tabs.highlight");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.highlight");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
deleted file mode 100644
index 2c26bbd16..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-requestLongerTimeout(2);
-
-add_task(function* () {
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
-
- yield focusWindow(win1);
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- "content_scripts": [{
- "matches": ["http://mochi.test/*/context_tabs_onUpdated_page.html"],
- "js": ["content-script.js"],
- "run_at": "document_start",
- }],
- },
-
- background: function() {
- let pageURL = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html";
-
- let expectedSequence = [
- {status: "loading"},
- {status: "loading", url: pageURL},
- {status: "complete"},
- ];
- let collectedSequence = [];
-
- browser.tabs.onUpdated.addListener(function(tabId, updatedInfo) {
- // onUpdated also fires with updatedInfo.faviconUrl, so explicitly
- // check for updatedInfo.status before recording the event.
- if ("status" in updatedInfo) {
- collectedSequence.push(updatedInfo);
- }
- });
-
- browser.runtime.onMessage.addListener(function() {
- if (collectedSequence.length !== expectedSequence.length) {
- browser.test.assertEq(
- JSON.stringify(expectedSequence),
- JSON.stringify(collectedSequence),
- "got unexpected number of updateInfo data"
- );
- } else {
- for (let i = 0; i < expectedSequence.length; i++) {
- browser.test.assertEq(
- expectedSequence[i].status,
- collectedSequence[i].status,
- "check updatedInfo status"
- );
- if (expectedSequence[i].url || collectedSequence[i].url) {
- browser.test.assertEq(
- expectedSequence[i].url,
- collectedSequence[i].url,
- "check updatedInfo url"
- );
- }
- }
- }
-
- browser.test.notifyPass("tabs.onUpdated");
- });
-
- browser.tabs.create({url: pageURL});
- },
- files: {
- "content-script.js": `
- window.addEventListener("message", function(evt) {
- if (evt.data == "frame-updated") {
- browser.runtime.sendMessage("load-completed");
- }
- }, true);
- `,
- },
- });
-
- yield Promise.all([
- extension.startup(),
- extension.awaitFinish("tabs.onUpdated"),
- ]);
-
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(win1);
-});
-
-function* do_test_update(background, withPermissions = true) {
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
-
- yield focusWindow(win1);
-
- let manifest = {};
- if (withPermissions) {
- manifest.permissions = ["tabs"];
- }
- let extension = ExtensionTestUtils.loadExtension({manifest, background});
-
- yield Promise.all([
- yield extension.startup(),
- yield extension.awaitFinish("finish"),
- ]);
-
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(win1);
-}
-
-add_task(function* test_pinned() {
- yield do_test_update(function background() {
- // Create a new tab for testing update.
- browser.tabs.create({}, function(tab) {
- browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
- // Check callback
- browser.test.assertEq(tabId, tab.id, "Check tab id");
- browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
- if ("pinned" in changeInfo) {
- browser.test.assertTrue(changeInfo.pinned, "Check changeInfo.pinned");
- browser.tabs.onUpdated.removeListener(onUpdated);
- // Remove created tab.
- browser.tabs.remove(tabId);
- browser.test.notifyPass("finish");
- return;
- }
- });
- browser.tabs.update(tab.id, {pinned: true});
- });
- });
-});
-
-add_task(function* test_unpinned() {
- yield do_test_update(function background() {
- // Create a new tab for testing update.
- browser.tabs.create({pinned: true}, function(tab) {
- browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
- // Check callback
- browser.test.assertEq(tabId, tab.id, "Check tab id");
- browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
- if ("pinned" in changeInfo) {
- browser.test.assertFalse(changeInfo.pinned, "Check changeInfo.pinned");
- browser.tabs.onUpdated.removeListener(onUpdated);
- // Remove created tab.
- browser.tabs.remove(tabId);
- browser.test.notifyPass("finish");
- return;
- }
- });
- browser.tabs.update(tab.id, {pinned: false});
- });
- });
-});
-
-add_task(function* test_url() {
- yield do_test_update(function background() {
- // Create a new tab for testing update.
- browser.tabs.create({}, function(tab) {
- browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
- // Check callback
- browser.test.assertEq(tabId, tab.id, "Check tab id");
- browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
- if ("url" in changeInfo) {
- browser.test.assertEq("about:blank", changeInfo.url,
- "Check changeInfo.url");
- browser.tabs.onUpdated.removeListener(onUpdated);
- // Remove created tab.
- browser.tabs.remove(tabId);
- browser.test.notifyPass("finish");
- return;
- }
- });
- browser.tabs.update(tab.id, {url: "about:blank"});
- });
- });
-});
-
-add_task(function* test_without_tabs_permission() {
- yield do_test_update(function background() {
- browser.tabs.create({url: "about:blank"}, function(tab) {
- browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
- if (tabId == tab.id) {
- browser.test.assertFalse("url" in changeInfo, "url should not be included without tabs permission");
- browser.test.assertFalse("favIconUrl" in changeInfo, "favIconUrl should not be included without tabs permission");
-
- if (changeInfo.status == "complete") {
- browser.tabs.onUpdated.removeListener(onUpdated);
- browser.tabs.remove(tabId);
- browser.test.notifyPass("finish");
- }
- }
- });
- browser.tabs.reload(tab.id);
- });
- }, false /* withPermissions */);
-});
-
-add_task(forceGC);
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_query.js b/browser/components/extensions/test/browser/browser_ext_tabs_query.js
deleted file mode 100644
index 7804d1454..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_query.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-requestLongerTimeout(2);
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config");
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- lastFocusedWindow: true,
- }, function(tabs) {
- browser.test.assertEq(tabs.length, 3, "should have three tabs");
-
- tabs.sort((tab1, tab2) => tab1.index - tab2.index);
-
- browser.test.assertEq(tabs[0].url, "about:blank", "first tab blank");
- tabs.shift();
-
- browser.test.assertTrue(tabs[0].active, "tab 0 active");
- browser.test.assertFalse(tabs[1].active, "tab 1 inactive");
-
- browser.test.assertFalse(tabs[0].pinned, "tab 0 unpinned");
- browser.test.assertFalse(tabs[1].pinned, "tab 1 unpinned");
-
- browser.test.assertEq(tabs[0].url, "about:robots", "tab 0 url correct");
- browser.test.assertEq(tabs[1].url, "about:config", "tab 1 url correct");
-
- browser.test.assertEq(tabs[0].status, "complete", "tab 0 status correct");
- browser.test.assertEq(tabs[1].status, "complete", "tab 1 status correct");
-
- browser.test.assertEq(tabs[0].title, "Gort! Klaatu barada nikto!", "tab 0 title correct");
-
- browser.test.notifyPass("tabs.query");
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.query");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-
- tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
- tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
- let tab3 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://test1.example.org/MochiKit/");
-
- // test simple queries
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- url: "<all_urls>",
- }, function(tabs) {
- browser.test.assertEq(tabs.length, 3, "should have three tabs");
-
- tabs.sort((tab1, tab2) => tab1.index - tab2.index);
-
- browser.test.assertEq(tabs[0].url, "http://example.com/", "tab 0 url correct");
- browser.test.assertEq(tabs[1].url, "http://example.net/", "tab 1 url correct");
- browser.test.assertEq(tabs[2].url, "http://test1.example.org/MochiKit/", "tab 2 url correct");
-
- browser.test.notifyPass("tabs.query");
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.query");
- yield extension.unload();
-
- // match pattern
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- url: "http://*/MochiKit*",
- }, function(tabs) {
- browser.test.assertEq(tabs.length, 1, "should have one tab");
-
- browser.test.assertEq(tabs[0].url, "http://test1.example.org/MochiKit/", "tab 0 url correct");
-
- browser.test.notifyPass("tabs.query");
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.query");
- yield extension.unload();
-
- // match array of patterns
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- url: ["http://*/MochiKit*", "http://*.com/*"],
- }, function(tabs) {
- browser.test.assertEq(tabs.length, 2, "should have two tabs");
-
- tabs.sort((tab1, tab2) => tab1.index - tab2.index);
-
- browser.test.assertEq(tabs[0].url, "http://example.com/", "tab 0 url correct");
- browser.test.assertEq(tabs[1].url, "http://test1.example.org/MochiKit/", "tab 1 url correct");
-
- browser.test.notifyPass("tabs.query");
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.query");
- yield extension.unload();
-
- // test width and height
- extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.test.onMessage.addListener(async msg => {
- let tabs = await browser.tabs.query({active: true});
-
- browser.test.assertEq(tabs.length, 1, "should have one tab");
- browser.test.sendMessage("dims", {width: tabs[0].width, height: tabs[0].height});
- });
- browser.test.sendMessage("ready");
- },
- });
-
- const RESOLUTION_PREF = "layout.css.devPixelsPerPx";
- registerCleanupFunction(() => {
- SpecialPowers.clearUserPref(RESOLUTION_PREF);
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("ready")]);
-
- for (let resolution of [2, 1]) {
- SpecialPowers.setCharPref(RESOLUTION_PREF, String(resolution));
- is(window.devicePixelRatio, resolution, "window has the required resolution");
-
- let {clientHeight, clientWidth} = gBrowser.selectedBrowser;
-
- extension.sendMessage("check-size");
- let dims = yield extension.awaitMessage("dims");
- is(dims.width, clientWidth, "tab reports expected width");
- is(dims.height, clientHeight, "tab reports expected height");
- }
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
- yield BrowserTestUtils.removeTab(tab3);
- SpecialPowers.clearUserPref(RESOLUTION_PREF);
-});
-
-add_task(function* testQueryPermissions() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": [],
- },
-
- async background() {
- try {
- let tabs = await browser.tabs.query({currentWindow: true, active: true});
- browser.test.assertEq(tabs.length, 1, "Expect query to return tabs");
- browser.test.notifyPass("queryPermissions");
- } catch (e) {
- browser.test.notifyFail("queryPermissions");
- }
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("queryPermissions");
-
- yield extension.unload();
-});
-
-add_task(function* testQueryWithURLPermissions() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": [],
- },
-
- async background() {
- await browser.test.assertRejects(
- browser.tabs.query({"url": "http://www.bbc.com/"}),
- 'The "tabs" permission is required to use the query API with the "url" parameter',
- "Expected tabs.query with 'url' to fail with permissions error message");
-
- browser.test.notifyPass("queryWithURLPermissions");
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("queryWithURLPermissions");
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_reload.js b/browser/components/extensions/test/browser/browser_ext_tabs_reload.js
deleted file mode 100644
index 99b2d426b..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_reload.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- files: {
- "tab.js": function() {
- browser.runtime.sendMessage("tab-loaded");
- },
- "tab.html":
- `<head>
- <meta charset="utf-8">
- <script src="tab.js"></script>
- </head>`,
- },
-
- async background() {
- let tabLoadedCount = 0;
-
- let tab = await browser.tabs.create({url: "tab.html", active: true});
-
- browser.runtime.onMessage.addListener(msg => {
- if (msg == "tab-loaded") {
- tabLoadedCount++;
-
- if (tabLoadedCount == 1) {
- // Reload the tab once passing no arguments.
- return browser.tabs.reload();
- }
-
- if (tabLoadedCount == 2) {
- // Reload the tab again with explicit arguments.
- return browser.tabs.reload(tab.id, {
- bypassCache: false,
- });
- }
-
- if (tabLoadedCount == 3) {
- browser.test.notifyPass("tabs.reload");
- }
- }
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.reload");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_reload_bypass_cache.js b/browser/components/extensions/test/browser/browser_ext_tabs_reload_bypass_cache.js
deleted file mode 100644
index 648361724..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_reload_bypass_cache.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs", "<all_urls>"],
- },
-
- async background() {
- const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
- const URL = BASE + "file_bypass_cache.sjs";
-
- function awaitLoad(tabId) {
- return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
- if (tabId == tabId_ && changed.status == "complete" && tab.url == URL) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
- }
-
- try {
- let tab = await browser.tabs.create({url: URL});
- await awaitLoad(tab.id);
-
- await browser.tabs.reload(tab.id, {bypassCache: false});
- await awaitLoad(tab.id);
-
- let [textContent] = await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"});
- browser.test.assertEq("", textContent, "`textContent` should be empty when bypassCache=false");
-
- await browser.tabs.reload(tab.id, {bypassCache: true});
- await awaitLoad(tab.id);
-
- [textContent] = await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"});
-
- let [pragma, cacheControl] = textContent.split(":");
- browser.test.assertEq("no-cache", pragma, "`pragma` should be set to `no-cache` when bypassCache is true");
- browser.test.assertEq("no-cache", cacheControl, "`cacheControl` should be set to `no-cache` when bypassCache is true");
-
- await browser.tabs.remove(tab.id);
-
- browser.test.notifyPass("tabs.reload_bypass_cache");
- } catch (error) {
- browser.test.fail(`${error} :: ${error.stack}`);
- browser.test.notifyFail("tabs.reload_bypass_cache");
- }
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("tabs.reload_bypass_cache");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js b/browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js
deleted file mode 100644
index e0eadab64..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_removeCSS.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testExecuteScript() {
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/", true);
-
- async function background() {
- let tasks = [
- // Insert CSS file.
- {
- background: "transparent",
- foreground: "rgb(0, 113, 4)",
- promise: () => {
- return browser.tabs.insertCSS({
- file: "file2.css",
- });
- },
- },
- // Insert CSS code.
- {
- background: "rgb(42, 42, 42)",
- foreground: "rgb(0, 113, 4)",
- promise: () => {
- return browser.tabs.insertCSS({
- code: "* { background: rgb(42, 42, 42) }",
- });
- },
- },
- // Remove CSS code again.
- {
- background: "transparent",
- foreground: "rgb(0, 113, 4)",
- promise: () => {
- return browser.tabs.removeCSS({
- code: "* { background: rgb(42, 42, 42) }",
- });
- },
- },
- // Remove CSS file again.
- {
- background: "transparent",
- foreground: "rgb(0, 0, 0)",
- promise: () => {
- return browser.tabs.removeCSS({
- file: "file2.css",
- });
- },
- },
- ];
-
- function checkCSS() {
- let computedStyle = window.getComputedStyle(document.body);
- return [computedStyle.backgroundColor, computedStyle.color];
- }
-
- try {
- for (let {promise, background, foreground} of tasks) {
- let result = await promise();
- browser.test.assertEq(undefined, result, "Expected callback result");
-
- [result] = await browser.tabs.executeScript({
- code: `(${checkCSS})()`,
- });
- browser.test.assertEq(background, result[0], "Expected background color");
- browser.test.assertEq(foreground, result[1], "Expected foreground color");
- }
-
- browser.test.notifyPass("removeCSS");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFailure("removeCSS");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["http://mochi.test/"],
- },
-
- background,
-
- files: {
- "file2.css": "* { color: rgb(0, 113, 4) }",
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("removeCSS");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_sendMessage.js b/browser/components/extensions/test/browser/browser_ext_tabs_sendMessage.js
deleted file mode 100644
index 64e97afb1..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_sendMessage.js
+++ /dev/null
@@ -1,227 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* tabsSendMessageReply() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
-
- "content_scripts": [{
- "matches": ["http://example.com/"],
- "js": ["content-script.js"],
- "run_at": "document_start",
- }],
- },
-
- background: async function() {
- let firstTab;
- let promiseResponse = new Promise(resolve => {
- browser.runtime.onMessage.addListener((msg, sender, respond) => {
- if (msg == "content-script-ready") {
- let tabId = sender.tab.id;
-
- Promise.all([
- promiseResponse,
-
- browser.tabs.sendMessage(tabId, "respond-now"),
- browser.tabs.sendMessage(tabId, "respond-now-2"),
- new Promise(resolve => browser.tabs.sendMessage(tabId, "respond-soon", resolve)),
- browser.tabs.sendMessage(tabId, "respond-promise"),
- browser.tabs.sendMessage(tabId, "respond-never"),
- new Promise(resolve => {
- browser.runtime.sendMessage("respond-never", response => { resolve(response); });
- }),
-
- browser.tabs.sendMessage(tabId, "respond-error").catch(error => Promise.resolve({error})),
- browser.tabs.sendMessage(tabId, "throw-error").catch(error => Promise.resolve({error})),
-
- browser.tabs.sendMessage(firstTab, "no-listener").catch(error => Promise.resolve({error})),
- ]).then(([response, respondNow, respondNow2, respondSoon, respondPromise, respondNever, respondNever2, respondError, throwError, noListener]) => {
- browser.test.assertEq("expected-response", response, "Content script got the expected response");
-
- browser.test.assertEq("respond-now", respondNow, "Got the expected immediate response");
- browser.test.assertEq("respond-now-2", respondNow2, "Got the expected immediate response from the second listener");
- browser.test.assertEq("respond-soon", respondSoon, "Got the expected delayed response");
- browser.test.assertEq("respond-promise", respondPromise, "Got the expected promise response");
- browser.test.assertEq(undefined, respondNever, "Got the expected no-response resolution");
- browser.test.assertEq(undefined, respondNever2, "Got the expected no-response resolution");
-
- browser.test.assertEq("respond-error", respondError.error.message, "Got the expected error response");
- browser.test.assertEq("throw-error", throwError.error.message, "Got the expected thrown error response");
-
- browser.test.assertEq("Could not establish connection. Receiving end does not exist.",
- noListener.error.message,
- "Got the expected no listener response");
-
- return browser.tabs.remove(tabId);
- }).then(() => {
- browser.test.notifyPass("sendMessage");
- });
-
- return Promise.resolve("expected-response");
- } else if (msg[0] == "got-response") {
- resolve(msg[1]);
- }
- });
- });
-
- let tabs = await browser.tabs.query({currentWindow: true, active: true});
- firstTab = tabs[0].id;
- browser.tabs.create({url: "http://example.com/"});
- },
-
- files: {
- "content-script.js": async function() {
- browser.runtime.onMessage.addListener((msg, sender, respond) => {
- if (msg == "respond-now") {
- respond(msg);
- } else if (msg == "respond-soon") {
- setTimeout(() => { respond(msg); }, 0);
- return true;
- } else if (msg == "respond-promise") {
- return Promise.resolve(msg);
- } else if (msg == "respond-never") {
- return;
- } else if (msg == "respond-error") {
- return Promise.reject(new Error(msg));
- } else if (msg == "throw-error") {
- throw new Error(msg);
- }
- });
-
- browser.runtime.onMessage.addListener((msg, sender, respond) => {
- if (msg == "respond-now") {
- respond("hello");
- } else if (msg == "respond-now-2") {
- respond(msg);
- }
- });
-
- let response = await browser.runtime.sendMessage("content-script-ready");
- browser.runtime.sendMessage(["got-response", response]);
- },
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("sendMessage");
-
- yield extension.unload();
-});
-
-
-add_task(function* tabsSendHidden() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
-
- "content_scripts": [{
- "matches": ["http://example.com/content*"],
- "js": ["content-script.js"],
- "run_at": "document_start",
- }],
- },
-
- background: async function() {
- let resolveContent;
- browser.runtime.onMessage.addListener((msg, sender) => {
- if (msg[0] == "content-ready") {
- resolveContent(msg[1]);
- }
- });
-
- let awaitContent = url => {
- return new Promise(resolve => {
- resolveContent = resolve;
- }).then(result => {
- browser.test.assertEq(url, result, "Expected content script URL");
- });
- };
-
- try {
- const URL1 = "http://example.com/content1.html";
- const URL2 = "http://example.com/content2.html";
-
- let tab = await browser.tabs.create({url: URL1});
- await awaitContent(URL1);
-
- let url = await browser.tabs.sendMessage(tab.id, URL1);
- browser.test.assertEq(URL1, url, "Should get response from expected content window");
-
- await browser.tabs.update(tab.id, {url: URL2});
- await awaitContent(URL2);
-
- url = await browser.tabs.sendMessage(tab.id, URL2);
- browser.test.assertEq(URL2, url, "Should get response from expected content window");
-
- // Repeat once just to be sure the first message was processed by all
- // listeners before we exit the test.
- url = await browser.tabs.sendMessage(tab.id, URL2);
- browser.test.assertEq(URL2, url, "Should get response from expected content window");
-
- await browser.tabs.remove(tab.id);
-
- browser.test.notifyPass("contentscript-bfcache-window");
- } catch (error) {
- browser.test.fail(`Error: ${error} :: ${error.stack}`);
- browser.test.notifyFail("contentscript-bfcache-window");
- }
- },
-
- files: {
- "content-script.js": function() {
- // Store this in a local variable to make sure we don't touch any
- // properties of the possibly-hidden content window.
- let href = window.location.href;
-
- browser.runtime.onMessage.addListener((msg, sender) => {
- browser.test.assertEq(href, msg, "Should be in the expected content window");
-
- return Promise.resolve(href);
- });
-
- browser.runtime.sendMessage(["content-ready", href]);
- },
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("contentscript-bfcache-window");
-
- yield extension.unload();
-});
-
-
-add_task(function* tabsSendMessageNoExceptionOnNonExistentTab() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- async background() {
- let url = "http://example.com/mochitest/browser/browser/components/extensions/test/browser/file_dummy.html";
- let tab = await browser.tabs.create({url});
-
- try {
- browser.tabs.sendMessage(tab.id, "message");
- browser.tabs.sendMessage(tab.id + 100, "message");
- } catch (e) {
- browser.test.fail("no exception should be raised on tabs.sendMessage to nonexistent tabs");
- }
-
- await browser.tabs.remove(tab.id);
-
- browser.test.notifyPass("tabs.sendMessage");
- },
- });
-
- yield Promise.all([
- extension.startup(),
- extension.awaitFinish("tabs.sendMessage"),
- ]);
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_update.js b/browser/components/extensions/test/browser/browser_ext_tabs_update.js
deleted file mode 100644
index 8e56a746c..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_update.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots");
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config");
-
- gBrowser.selectedTab = tab1;
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background: function() {
- browser.tabs.query({
- lastFocusedWindow: true,
- }, function(tabs) {
- browser.test.assertEq(tabs.length, 3, "should have three tabs");
-
- tabs.sort((tab1, tab2) => tab1.index - tab2.index);
-
- browser.test.assertEq(tabs[0].url, "about:blank", "first tab blank");
- tabs.shift();
-
- browser.test.assertTrue(tabs[0].active, "tab 0 active");
- browser.test.assertFalse(tabs[1].active, "tab 1 inactive");
-
- browser.tabs.update(tabs[1].id, {active: true}, function() {
- browser.test.sendMessage("check");
- });
- });
- },
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("check")]);
-
- ok(gBrowser.selectedTab == tab2, "correct tab selected");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_update_url.js b/browser/components/extensions/test/browser/browser_ext_tabs_update_url.js
deleted file mode 100644
index b43855fb1..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_update_url.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected) {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- files: {
- "tab.html": `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <h1>tab page</h1>
- </body>
- </html>
- `.trim(),
- },
- background: function() {
- browser.test.sendMessage("ready", browser.runtime.getURL("tab.html"));
-
- browser.test.onMessage.addListener(async (msg, tabsUpdateURL, isErrorExpected) => {
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
-
- try {
- let tab = await browser.tabs.update(tabs[1].id, {url: tabsUpdateURL});
-
- browser.test.assertFalse(isErrorExpected, `tabs.update with URL ${tabsUpdateURL} should be rejected`);
- browser.test.assertTrue(tab, "on success the tab should be defined");
- } catch (error) {
- browser.test.assertTrue(isErrorExpected, `tabs.update with URL ${tabsUpdateURL} should not be rejected`);
- browser.test.assertTrue(/^Illegal URL/.test(error.message),
- "tabs.update should be rejected with the expected error message");
- }
-
- browser.test.sendMessage("done");
- });
- },
- });
-
- yield extension.startup();
-
- let mozExtTabURL = yield extension.awaitMessage("ready");
-
- if (tabsUpdateURL == "self") {
- tabsUpdateURL = mozExtTabURL;
- }
-
- info(`tab.update URL "${tabsUpdateURL}" on tab with URL "${existentTabURL}"`);
-
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, existentTabURL);
-
- extension.sendMessage("start", tabsUpdateURL, isErrorExpected);
- yield extension.awaitMessage("done");
-
- yield BrowserTestUtils.removeTab(tab1);
- yield extension.unload();
-}
-
-add_task(function* () {
- info("Start testing tabs.update on javascript URLs");
-
- let dataURLPage = `data:text/html,
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <h1>data url page</h1>
- </body>
- </html>`;
-
- let checkList = [
- {
- tabsUpdateURL: "http://example.net",
- isErrorExpected: false,
- },
- {
- tabsUpdateURL: "self",
- isErrorExpected: false,
- },
- {
- tabsUpdateURL: "about:addons",
- isErrorExpected: true,
- },
- {
- tabsUpdateURL: "javascript:console.log('tabs.update execute javascript')",
- isErrorExpected: true,
- },
- {
- tabsUpdateURL: dataURLPage,
- isErrorExpected: true,
- },
- ];
-
- let testCases = checkList
- .map((check) => Object.assign({}, check, {existentTabURL: "about:blank"}));
-
- for (let {existentTabURL, tabsUpdateURL, isErrorExpected} of testCases) {
- yield* testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected);
- }
-
- info("done");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js b/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js
deleted file mode 100644
index c2e54d3ea..000000000
--- a/browser/components/extensions/test/browser/browser_ext_tabs_zoom.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-const SITE_SPECIFIC_PREF = "browser.zoom.siteSpecific";
-
-add_task(function* () {
- let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
- let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.net/");
-
- gBrowser.selectedTab = tab1;
-
- async function background() {
- function promiseUpdated(tabId, attr) {
- return new Promise(resolve => {
- let onUpdated = (tabId_, changeInfo, tab) => {
- if (tabId == tabId_ && attr in changeInfo) {
- browser.tabs.onUpdated.removeListener(onUpdated);
-
- resolve({changeInfo, tab});
- }
- };
- browser.tabs.onUpdated.addListener(onUpdated);
- });
- }
-
- let deferred = {};
- browser.test.onMessage.addListener((message, msg, result) => {
- if (message == "msg-done" && deferred[msg]) {
- deferred[msg].resolve(result);
- }
- });
-
- let _id = 0;
- function msg(...args) {
- return new Promise((resolve, reject) => {
- let id = ++_id;
- deferred[id] = {resolve, reject};
- browser.test.sendMessage("msg", id, ...args);
- });
- }
-
-
- let zoomEvents = [];
- let eventPromises = [];
- browser.tabs.onZoomChange.addListener(info => {
- zoomEvents.push(info);
- if (eventPromises.length) {
- eventPromises.shift().resolve();
- }
- });
-
- let awaitZoom = async (tabId, newValue) => {
- let listener;
-
- await new Promise(async resolve => {
- listener = info => {
- if (info.tabId == tabId && info.newZoomFactor == newValue) {
- resolve();
- }
- };
- browser.tabs.onZoomChange.addListener(listener);
-
- let zoomFactor = await browser.tabs.getZoom(tabId);
- if (zoomFactor == newValue) {
- resolve();
- }
- });
-
- browser.tabs.onZoomChange.removeListener(listener);
- };
-
- let checkZoom = async (tabId, newValue, oldValue = null) => {
- let awaitEvent;
- if (oldValue != null && !zoomEvents.length) {
- awaitEvent = new Promise(resolve => {
- eventPromises.push({resolve});
- });
- }
-
- let [apiZoom, realZoom] = await Promise.all([
- browser.tabs.getZoom(tabId),
- msg("get-zoom", tabId),
- awaitEvent,
- ]);
-
- browser.test.assertEq(newValue, apiZoom, `Got expected zoom value from API`);
- browser.test.assertEq(newValue, realZoom, `Got expected zoom value from parent`);
-
- if (oldValue != null) {
- let event = zoomEvents.shift();
- browser.test.assertEq(tabId, event.tabId, `Got expected zoom event tab ID`);
- browser.test.assertEq(newValue, event.newZoomFactor, `Got expected zoom event zoom factor`);
- browser.test.assertEq(oldValue, event.oldZoomFactor, `Got expected zoom event old zoom factor`);
-
- browser.test.assertEq(3, Object.keys(event.zoomSettings).length, `Zoom settings should have 3 keys`);
- browser.test.assertEq("automatic", event.zoomSettings.mode, `Mode should be "automatic"`);
- browser.test.assertEq("per-origin", event.zoomSettings.scope, `Scope should be "per-origin"`);
- browser.test.assertEq(1, event.zoomSettings.defaultZoomFactor, `Default zoom should be 1`);
- }
- };
-
- try {
- let tabs = await browser.tabs.query({lastFocusedWindow: true});
- browser.test.assertEq(tabs.length, 3, "We have three tabs");
-
- let tabIds = [tabs[1].id, tabs[2].id];
- await checkZoom(tabIds[0], 1);
-
- await browser.tabs.setZoom(tabIds[0], 2);
- await checkZoom(tabIds[0], 2, 1);
-
- let zoomSettings = await browser.tabs.getZoomSettings(tabIds[0]);
- browser.test.assertEq(3, Object.keys(zoomSettings).length, `Zoom settings should have 3 keys`);
- browser.test.assertEq("automatic", zoomSettings.mode, `Mode should be "automatic"`);
- browser.test.assertEq("per-origin", zoomSettings.scope, `Scope should be "per-origin"`);
- browser.test.assertEq(1, zoomSettings.defaultZoomFactor, `Default zoom should be 1`);
-
-
- browser.test.log(`Switch to tab 2`);
- await browser.tabs.update(tabIds[1], {active: true});
- await checkZoom(tabIds[1], 1);
-
-
- browser.test.log(`Navigate tab 2 to origin of tab 1`);
- browser.tabs.update(tabIds[1], {url: "http://example.com"});
- await promiseUpdated(tabIds[1], "url");
- await checkZoom(tabIds[1], 2, 1);
-
-
- browser.test.log(`Update zoom in tab 2, expect changes in both tabs`);
- await browser.tabs.setZoom(tabIds[1], 1.5);
- await checkZoom(tabIds[1], 1.5, 2);
-
-
- browser.test.log(`Switch to tab 1, expect asynchronous zoom change just after the switch`);
- await Promise.all([
- awaitZoom(tabIds[0], 1.5),
- browser.tabs.update(tabIds[0], {active: true}),
- ]);
- await checkZoom(tabIds[0], 1.5, 2);
-
-
- browser.test.log("Set zoom to 0, expect it set to 1");
- await browser.tabs.setZoom(tabIds[0], 0);
- await checkZoom(tabIds[0], 1, 1.5);
-
-
- browser.test.log("Change zoom externally, expect changes reflected");
- await msg("enlarge");
- await checkZoom(tabIds[0], 1.1, 1);
-
- await Promise.all([
- browser.tabs.setZoom(tabIds[0], 0),
- browser.tabs.setZoom(tabIds[1], 0),
- ]);
- await Promise.all([
- checkZoom(tabIds[0], 1, 1.1),
- checkZoom(tabIds[1], 1, 1.5),
- ]);
-
-
- browser.test.log("Check that invalid zoom values throw an error");
- await browser.test.assertRejects(
- browser.tabs.setZoom(tabIds[0], 42),
- /Zoom value 42 out of range/,
- "Expected an out of range error");
-
- browser.test.log("Disable site-specific zoom, expect correct scope");
- await msg("site-specific", false);
- zoomSettings = await browser.tabs.getZoomSettings(tabIds[0]);
-
- browser.test.assertEq("per-tab", zoomSettings.scope, `Scope should be "per-tab"`);
- await msg("site-specific", null);
-
- browser.test.notifyPass("tab-zoom");
- } catch (e) {
- browser.test.fail(`Error: ${e} :: ${e.stack}`);
- browser.test.notifyFail("tab-zoom");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- extension.onMessage("msg", (id, msg, ...args) => {
- let {Management: {global: {TabManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let resp;
- if (msg == "get-zoom") {
- let tab = TabManager.getTab(args[0]);
- resp = ZoomManager.getZoomForBrowser(tab.linkedBrowser);
- } else if (msg == "set-zoom") {
- let tab = TabManager.getTab(args[0]);
- ZoomManager.setZoomForBrowser(tab.linkedBrowser);
- } else if (msg == "enlarge") {
- FullZoom.enlarge();
- } else if (msg == "site-specific") {
- if (args[0] == null) {
- SpecialPowers.clearUserPref(SITE_SPECIFIC_PREF);
- } else {
- SpecialPowers.setBoolPref(SITE_SPECIFIC_PREF, args[0]);
- }
- }
-
- extension.sendMessage("msg-done", id, resp);
- });
-
- yield extension.startup();
-
- yield extension.awaitFinish("tab-zoom");
-
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_topwindowid.js b/browser/components/extensions/test/browser/browser_ext_topwindowid.js
deleted file mode 100644
index 9176ac946..000000000
--- a/browser/components/extensions/test/browser/browser_ext_topwindowid.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* test_topwindowid_cleanup() {
- let {Frames} = Cu.import("resource://gre/modules/ExtensionManagement.jsm", {});
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
-
- let {outerWindowID, messageManager} = tab.linkedBrowser;
-
- ok(Frames.topWindowIds.has(outerWindowID), "Outer window ID is registered");
-
- let awaitDisconnect = TestUtils.topicObserved("message-manager-disconnect",
- subject => subject === messageManager);
-
- yield BrowserTestUtils.removeTab(tab);
-
- yield awaitDisconnect;
-
- ok(!Frames.topWindowIds.has(outerWindowID), "Outer window ID is no longer registered");
-});
-
diff --git a/browser/components/extensions/test/browser/browser_ext_webNavigation_frameId0.js b/browser/components/extensions/test/browser/browser_ext_webNavigation_frameId0.js
deleted file mode 100644
index 0058ca065..000000000
--- a/browser/components/extensions/test/browser/browser_ext_webNavigation_frameId0.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* webNavigation_getFrameId_of_existing_main_frame() {
- // Whether the frame ID in the extension API is 0 is determined by a map that
- // is maintained by |Frames| in ExtensionManagement.jsm. This map is filled
- // using data from content processes. But if ExtensionManagement.jsm is not
- // imported, then the "Extension:TopWindowID" message gets lost.
- // As a result, if the state is not synchronized again, the webNavigation API
- // will mistakenly report a non-zero frame ID for top-level frames.
- //
- // If you want to be absolutely sure that the frame ID is correct, don't open
- // tabs before starting an extension, or explicitly load the module in the
- // main process:
- // Cu.import("resource://gre/modules/ExtensionManagement.jsm", {});
- //
- // Or simply run the test again.
- const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
- const DUMMY_URL = BASE + "file_dummy.html";
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, DUMMY_URL, true);
-
- async function background(DUMMY_URL) {
- let tabs = await browser.tabs.query({active: true, currentWindow: true});
- let frames = await browser.webNavigation.getAllFrames({tabId: tabs[0].id});
- browser.test.assertEq(1, frames.length, "The dummy page has one frame");
- browser.test.assertEq(0, frames[0].frameId, "Main frame's ID must be 0");
- browser.test.assertEq(DUMMY_URL, frames[0].url, "Main frame URL must match");
- browser.test.notifyPass("frameId checked");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["webNavigation"],
- },
-
- background: `(${background})(${JSON.stringify(DUMMY_URL)});`,
- });
-
- yield extension.startup();
- yield extension.awaitFinish("frameId checked");
- yield extension.unload();
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js b/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
deleted file mode 100644
index 6b4a597ad..000000000
--- a/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testWebNavigationGetNonExistentTab() {
- let extension = ExtensionTestUtils.loadExtension({
- background: async function() {
- // There is no "tabId = 0" because the id assigned by TabManager (defined in ext-utils.js)
- // starts from 1.
- await browser.test.assertRejects(
- browser.webNavigation.getAllFrames({tabId: 0}),
- "Invalid tab ID: 0",
- "getAllFrames rejected Promise should pass the expected error");
-
- // There is no "tabId = 0" because the id assigned by TabManager (defined in ext-utils.js)
- // starts from 1, processId is currently marked as optional and it is ignored.
- await browser.test.assertRejects(
- browser.webNavigation.getFrame({tabId: 0, frameId: 15, processId: 20}),
- "Invalid tab ID: 0",
- "getFrame rejected Promise should pass the expected error");
-
- browser.test.sendMessage("getNonExistentTab.done");
- },
- manifest: {
- permissions: ["webNavigation"],
- },
- });
- info("load complete");
-
- yield extension.startup();
- info("startup complete");
-
- yield extension.awaitMessage("getNonExistentTab.done");
-
- yield extension.unload();
- info("extension unloaded");
-});
-
-add_task(function* testWebNavigationFrames() {
- let extension = ExtensionTestUtils.loadExtension({
- background: async function() {
- let tabId;
- let collectedDetails = [];
-
- browser.webNavigation.onCompleted.addListener(async details => {
- collectedDetails.push(details);
-
- if (details.frameId !== 0) {
- // wait for the top level iframe to be complete
- return;
- }
-
- let getAllFramesDetails = await browser.webNavigation.getAllFrames({tabId});
-
- let getFramePromises = getAllFramesDetails.map(({frameId}) => {
- // processId is currently marked as optional and it is ignored.
- return browser.webNavigation.getFrame({tabId, frameId, processId: 0});
- });
-
- let getFrameResults = await Promise.all(getFramePromises);
- browser.test.sendMessage("webNavigationFrames.done", {
- collectedDetails, getAllFramesDetails, getFrameResults,
- });
-
- // Pick a random frameId.
- let nonExistentFrameId = Math.floor(Math.random() * 10000);
-
- // Increment the picked random nonExistentFrameId until it doesn't exists.
- while (getAllFramesDetails.filter((details) => details.frameId == nonExistentFrameId).length > 0) {
- nonExistentFrameId += 1;
- }
-
- // Check that getFrame Promise is rejected with the expected error message on nonexistent frameId.
- await browser.test.assertRejects(
- browser.webNavigation.getFrame({tabId, frameId: nonExistentFrameId, processId: 20}),
- `No frame found with frameId: ${nonExistentFrameId}`,
- "getFrame promise should be rejected with the expected error message on unexistent frameId");
-
- await browser.tabs.remove(tabId);
- browser.test.sendMessage("webNavigationFrames.done");
- });
-
- let tab = await browser.tabs.create({url: "tab.html"});
- tabId = tab.id;
- },
- manifest: {
- permissions: ["webNavigation", "tabs"],
- },
- files: {
- "tab.html": `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <iframe src="subframe.html"></iframe>
- <iframe src="subframe.html"></iframe>
- </body>
- </html>
- `,
- "subframe.html": `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- </html>
- `,
- },
- });
- info("load complete");
-
- yield extension.startup();
- info("startup complete");
-
- let {
- collectedDetails,
- getAllFramesDetails,
- getFrameResults,
- } = yield extension.awaitMessage("webNavigationFrames.done");
-
- is(getAllFramesDetails.length, 3, "expected number of frames found");
- is(getAllFramesDetails.length, collectedDetails.length,
- "number of frames found should equal the number onCompleted events collected");
-
- is(getAllFramesDetails[0].frameId, 0, "the root frame has the expected frameId");
- is(getAllFramesDetails[0].parentFrameId, -1, "the root frame has the expected parentFrameId");
-
- // ordered by frameId
- let sortByFrameId = (el1, el2) => {
- let val1 = el1 ? el1.frameId : -1;
- let val2 = el2 ? el2.frameId : -1;
- return val1 - val2;
- };
-
- collectedDetails = collectedDetails.sort(sortByFrameId);
- getAllFramesDetails = getAllFramesDetails.sort(sortByFrameId);
- getFrameResults = getFrameResults.sort(sortByFrameId);
-
- info("check frame details content");
-
- is(getFrameResults.length, getAllFramesDetails.length,
- "getFrame and getAllFrames should return the same number of results");
-
- Assert.deepEqual(getFrameResults, getAllFramesDetails,
- "getFrame and getAllFrames should return the same results");
-
- info(`check frame details collected and retrieved with getAllFrames`);
-
- for (let [i, collected] of collectedDetails.entries()) {
- let getAllFramesDetail = getAllFramesDetails[i];
-
- is(getAllFramesDetail.frameId, collected.frameId, "frameId");
- is(getAllFramesDetail.parentFrameId, collected.parentFrameId, "parentFrameId");
- is(getAllFramesDetail.tabId, collected.tabId, "tabId");
-
- // This can be uncommented once Bug 1246125 has been fixed
- // is(getAllFramesDetail.url, collected.url, "url");
- }
-
- info("frame details content checked");
-
- yield extension.awaitMessage("webNavigationFrames.done");
-
- yield extension.unload();
- info("extension unloaded");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_webNavigation_urlbar_transitions.js b/browser/components/extensions/test/browser/browser_ext_webNavigation_urlbar_transitions.js
deleted file mode 100644
index f2ea0d901..000000000
--- a/browser/components/extensions/test/browser/browser_ext_webNavigation_urlbar_transitions.js
+++ /dev/null
@@ -1,251 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
-const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
-
-function* promiseAutocompleteResultPopup(inputText) {
- gURLBar.focus();
- gURLBar.value = inputText;
- gURLBar.controller.startSearch(inputText);
- yield promisePopupShown(gURLBar.popup);
- yield BrowserTestUtils.waitForCondition(() => {
- return gURLBar.controller.searchStatus >=
- Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH;
- });
-}
-
-function* addBookmark(bookmark) {
- if (bookmark.keyword) {
- yield PlacesUtils.keywords.insert({
- keyword: bookmark.keyword,
- url: bookmark.url,
- });
- }
-
- yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: bookmark.url,
- title: bookmark.title,
- });
-
- registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.eraseEverything();
- });
-}
-
-function addSearchEngine(basename) {
- return new Promise((resolve, reject) => {
- info("Waiting for engine to be added: " + basename);
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: (engine) => {
- info(`Search engine added: ${basename}`);
- registerCleanupFunction(() => Services.search.removeEngine(engine));
- resolve(engine);
- },
- onError: (errCode) => {
- ok(false, `addEngine failed with error code ${errCode}`);
- reject();
- },
- });
- });
-}
-
-function* prepareSearchEngine() {
- let oldCurrentEngine = Services.search.currentEngine;
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
- let engine = yield addSearchEngine(TEST_ENGINE_BASENAME);
- Services.search.currentEngine = engine;
-
- registerCleanupFunction(function* () {
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
- Services.search.currentEngine = oldCurrentEngine;
-
- // Make sure the popup is closed for the next test.
- gURLBar.blur();
- gURLBar.popup.selectedIndex = -1;
- gURLBar.popup.hidePopup();
- ok(!gURLBar.popup.popupOpen, "popup should be closed");
-
- // Clicking suggestions causes visits to search results pages, so clear that
- // history now.
- yield PlacesTestUtils.clearHistory();
- });
-}
-
-add_task(function* test_webnavigation_urlbar_typed_transitions() {
- function backgroundScript() {
- browser.webNavigation.onCommitted.addListener((msg) => {
- browser.test.assertEq("http://example.com/?q=typed", msg.url,
- "Got the expected url");
- // assert from_address_bar transition qualifier
- browser.test.assertTrue(msg.transitionQualifiers &&
- msg.transitionQualifiers.includes("from_address_bar"),
- "Got the expected from_address_bar transitionQualifier");
- browser.test.assertEq("typed", msg.transitionType,
- "Got the expected transitionType");
- browser.test.notifyPass("webNavigation.from_address_bar.typed");
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background: backgroundScript,
- manifest: {
- permissions: ["webNavigation"],
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("ready");
-
- gURLBar.focus();
- gURLBar.textValue = "http://example.com/?q=typed";
-
- EventUtils.synthesizeKey("VK_RETURN", {altKey: true});
-
- yield extension.awaitFinish("webNavigation.from_address_bar.typed");
-
- yield extension.unload();
- info("extension unloaded");
-});
-
-add_task(function* test_webnavigation_urlbar_bookmark_transitions() {
- function backgroundScript() {
- browser.webNavigation.onCommitted.addListener((msg) => {
- browser.test.assertEq("http://example.com/?q=bookmark", msg.url,
- "Got the expected url");
-
- // assert from_address_bar transition qualifier
- browser.test.assertTrue(msg.transitionQualifiers &&
- msg.transitionQualifiers.includes("from_address_bar"),
- "Got the expected from_address_bar transitionQualifier");
- browser.test.assertEq("auto_bookmark", msg.transitionType,
- "Got the expected transitionType");
- browser.test.notifyPass("webNavigation.from_address_bar.auto_bookmark");
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background: backgroundScript,
- manifest: {
- permissions: ["webNavigation"],
- },
- });
-
- yield addBookmark({
- title: "Bookmark To Click",
- url: "http://example.com/?q=bookmark",
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("ready");
-
- yield promiseAutocompleteResultPopup("Bookmark To Click");
-
- let item = gURLBar.popup.richlistbox.getItemAtIndex(1);
- item.click();
- yield extension.awaitFinish("webNavigation.from_address_bar.auto_bookmark");
-
- yield extension.unload();
- info("extension unloaded");
-});
-
-add_task(function* test_webnavigation_urlbar_keyword_transition() {
- function backgroundScript() {
- browser.webNavigation.onCommitted.addListener((msg) => {
- browser.test.assertEq(`http://example.com/?q=search`, msg.url,
- "Got the expected url");
-
- // assert from_address_bar transition qualifier
- browser.test.assertTrue(msg.transitionQualifiers &&
- msg.transitionQualifiers.includes("from_address_bar"),
- "Got the expected from_address_bar transitionQualifier");
- browser.test.assertEq("keyword", msg.transitionType,
- "Got the expected transitionType");
- browser.test.notifyPass("webNavigation.from_address_bar.keyword");
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background: backgroundScript,
- manifest: {
- permissions: ["webNavigation"],
- },
- });
-
- yield addBookmark({
- title: "Test Keyword",
- url: "http://example.com/?q=%s",
- keyword: "testkw",
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("ready");
-
- yield promiseAutocompleteResultPopup("testkw search");
-
- let item = gURLBar.popup.richlistbox.getItemAtIndex(0);
- item.click();
-
- yield extension.awaitFinish("webNavigation.from_address_bar.keyword");
-
- yield extension.unload();
- info("extension unloaded");
-});
-
-add_task(function* test_webnavigation_urlbar_search_transitions() {
- function backgroundScript() {
- browser.webNavigation.onCommitted.addListener((msg) => {
- browser.test.assertEq("http://mochi.test:8888/", msg.url,
- "Got the expected url");
-
- // assert from_address_bar transition qualifier
- browser.test.assertTrue(msg.transitionQualifiers &&
- msg.transitionQualifiers.includes("from_address_bar"),
- "Got the expected from_address_bar transitionQualifier");
- browser.test.assertEq("generated", msg.transitionType,
- "Got the expected 'generated' transitionType");
- browser.test.notifyPass("webNavigation.from_address_bar.generated");
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background: backgroundScript,
- manifest: {
- permissions: ["webNavigation"],
- },
- });
-
- yield extension.startup();
-
- yield extension.awaitMessage("ready");
-
- yield prepareSearchEngine();
- yield promiseAutocompleteResultPopup("foo");
-
- let item = gURLBar.popup.richlistbox.getItemAtIndex(0);
- item.click();
-
- yield extension.awaitFinish("webNavigation.from_address_bar.generated");
-
- yield extension.unload();
- info("extension unloaded");
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_webRequest.js b/browser/components/extensions/test/browser/browser_ext_webRequest.js
deleted file mode 100644
index ab9f58480..000000000
--- a/browser/components/extensions/test/browser/browser_ext_webRequest.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-/* globals makeExtension */
-"use strict";
-
-Services.scriptloader.loadSubScript(new URL("head_webrequest.js", gTestPath).href,
- this);
-
-Cu.import("resource:///modules/HiddenFrame.jsm", this);
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-function createHiddenBrowser(url) {
- let frame = new HiddenFrame();
- return new Promise(resolve =>
- frame.get().then(subframe => {
- let doc = subframe.document;
- let browser = doc.createElementNS(XUL_NS, "browser");
- browser.setAttribute("type", "content");
- browser.setAttribute("disableglobalhistory", "true");
- browser.setAttribute("src", url);
-
- doc.documentElement.appendChild(browser);
- resolve({frame: frame, browser: browser});
- }));
-}
-
-let extension;
-let dummy = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/file_dummy.html";
-
-add_task(function* setup() {
- // SelfSupport has a tendency to fire when running this test alone, without
- // a good way to turn it off we just set the url to ""
- yield SpecialPowers.pushPrefEnv({
- set: [["browser.selfsupport.url", ""]],
- });
- extension = makeExtension();
- yield extension.startup();
-});
-
-add_task(function* test_newWindow() {
- let expect = {
- "file_dummy.html": {
- type: "main_frame",
- },
- };
- // NOTE: When running solo, favicon will be loaded at some point during
- // the tests in this file, so all tests ignore it. When running with
- // other tests in this directory, favicon gets loaded at some point before
- // we run, and we never see the request, thus it cannot be handled as part
- // of expect above.
- extension.sendMessage("set-expected", {expect, ignore: ["favicon.ico"]});
- yield extension.awaitMessage("continue");
-
- let openedWindow = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.openNewForegroundTab(openedWindow.gBrowser, dummy + "?newWindow");
-
- yield extension.awaitMessage("done");
- yield BrowserTestUtils.closeWindow(openedWindow);
-});
-
-add_task(function* test_newTab() {
- // again, in this window
- let expect = {
- "file_dummy.html": {
- type: "main_frame",
- },
- };
- extension.sendMessage("set-expected", {expect, ignore: ["favicon.ico"]});
- yield extension.awaitMessage("continue");
- let tab = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser, dummy + "?newTab");
-
- yield extension.awaitMessage("done");
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_subframe() {
- let expect = {
- "file_dummy.html": {
- type: "main_frame",
- },
- };
- // test a content subframe attached to hidden window
- extension.sendMessage("set-expected", {expect, ignore: ["favicon.ico"]});
- yield extension.awaitMessage("continue");
- let frameInfo = yield createHiddenBrowser(dummy + "?subframe");
- yield extension.awaitMessage("done");
- // cleanup
- frameInfo.browser.remove();
- frameInfo.frame.destroy();
-});
-
-add_task(function* teardown() {
- yield extension.unload();
-});
-
diff --git a/browser/components/extensions/test/browser/browser_ext_windows.js b/browser/components/extensions/test/browser/browser_ext_windows.js
deleted file mode 100644
index d3dd6ecdb..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- let raisedWin = Services.ww.openWindow(
- null, Services.prefs.getCharPref("browser.chromeURL"), "_blank",
- "chrome,dialog=no,all,alwaysRaised", null);
-
- yield TestUtils.topicObserved("browser-delayed-startup-finished",
- subject => subject == raisedWin);
-
- let extension = ExtensionTestUtils.loadExtension({
- background: function() {
- browser.windows.getAll((wins) => {
- browser.test.assertEq(wins.length, 2, "Expect two windows");
-
- browser.test.assertEq(false, wins[0].alwaysOnTop,
- "Expect first window not to be always on top");
- browser.test.assertEq(true, wins[1].alwaysOnTop,
- "Expect first window to be always on top");
-
- browser.test.notifyPass("alwaysOnTop");
- });
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("alwaysOnTop");
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(raisedWin);
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_allowScriptsToClose.js b/browser/components/extensions/test/browser/browser_ext_windows_allowScriptsToClose.js
deleted file mode 100644
index 13f8b2eee..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_allowScriptsToClose.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-// Tests allowScriptsToClose option
-add_task(function* test_allowScriptsToClose() {
- const files = {
- "dummy.html": "<meta charset=utf-8><script src=close.js></script>",
- "close.js": function() {
- window.close();
- if (!window.closed) {
- browser.test.sendMessage("close-failed");
- }
- },
- };
-
- function background() {
- browser.test.onMessage.addListener((msg, options) => {
- function listener(_, {status}, {url}) {
- if (status == "complete" && url == options.url) {
- browser.tabs.onUpdated.removeListener(listener);
- browser.tabs.executeScript({file: "close.js"});
- }
- }
- options.url = browser.runtime.getURL(options.url);
- browser.windows.create(options);
- if (msg === "create+execute") {
- browser.tabs.onUpdated.addListener(listener);
- }
- });
- browser.test.notifyPass();
- }
-
- const example = "http://example.com/";
- const manifest = {permissions: ["tabs", example]};
-
- const extension = ExtensionTestUtils.loadExtension({files, background, manifest});
- yield SpecialPowers.pushPrefEnv({set: [["dom.allow_scripts_to_close_windows", false]]});
-
- yield extension.startup();
- yield extension.awaitFinish();
-
- extension.sendMessage("create", {url: "dummy.html"});
- let win = yield BrowserTestUtils.waitForNewWindow();
- yield BrowserTestUtils.windowClosed(win);
- info("script allowed to close the window");
-
- extension.sendMessage("create+execute", {url: example});
- win = yield BrowserTestUtils.waitForNewWindow();
- yield extension.awaitMessage("close-failed");
- info("script prevented from closing the window");
- win.close();
-
- extension.sendMessage("create+execute", {url: example, allowScriptsToClose: true});
- win = yield BrowserTestUtils.waitForNewWindow();
- yield BrowserTestUtils.windowClosed(win);
- info("script allowed to close the window");
-
- yield SpecialPowers.popPrefEnv();
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_create.js b/browser/components/extensions/test/browser/browser_ext_windows_create.js
deleted file mode 100644
index f209c9836..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_create.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-requestLongerTimeout(2);
-
-add_task(function* testWindowCreate() {
- let extension = ExtensionTestUtils.loadExtension({
- async background() {
- let _checkWindowPromise;
- browser.test.onMessage.addListener(msg => {
- if (msg == "checked-window") {
- _checkWindowPromise.resolve();
- _checkWindowPromise = null;
- }
- });
-
- let os;
-
- function checkWindow(expected) {
- return new Promise(resolve => {
- _checkWindowPromise = {resolve};
- browser.test.sendMessage("check-window", expected);
- });
- }
-
- async function createWindow(params, expected, keep = false) {
- let window = await browser.windows.create(...params);
- // params is null when testing create without createData
- params = params[0] || {};
-
- for (let key of Object.keys(params)) {
- if (key == "state" && os == "mac" && params.state == "normal") {
- // OS-X doesn't have a hard distinction between "normal" and
- // "maximized" states.
- browser.test.assertTrue(window.state == "normal" || window.state == "maximized",
- `Expected window.state (currently ${window.state}) to be "normal" but will accept "maximized"`);
- } else {
- browser.test.assertEq(params[key], window[key], `Got expected value for window.${key}`);
- }
- }
-
- browser.test.assertEq(1, window.tabs.length, "tabs property got populated");
-
- await checkWindow(expected);
- if (keep) {
- return window;
- }
-
- if (params.state == "fullscreen" && os == "win") {
- // FIXME: Closing a fullscreen window causes a window leak in
- // Windows tests.
- await browser.windows.update(window.id, {state: "normal"});
- }
- await browser.windows.remove(window.id);
- }
-
- try {
- ({os} = await browser.runtime.getPlatformInfo());
-
- // Set the current window to state: "normal" because the test is failing on Windows
- // where the current window is maximized.
- let currentWindow = await browser.windows.getCurrent();
- await browser.windows.update(currentWindow.id, {state: "normal"});
-
- await createWindow([], {state: "STATE_NORMAL"});
- await createWindow([{state: "maximized"}], {state: "STATE_MAXIMIZED"});
- await createWindow([{state: "minimized"}], {state: "STATE_MINIMIZED"});
- await createWindow([{state: "normal"}], {state: "STATE_NORMAL", hiddenChrome: []});
- await createWindow([{state: "fullscreen"}], {state: "STATE_FULLSCREEN"});
-
- let window = await createWindow(
- [{type: "popup"}],
- {hiddenChrome: ["menubar", "toolbar", "location", "directories", "status", "extrachrome"],
- chromeFlags: ["CHROME_OPENAS_DIALOG"]},
- true);
-
- let tabs = await browser.tabs.query({windowType: "popup", active: true});
-
- browser.test.assertEq(1, tabs.length, "Expected only one popup");
- browser.test.assertEq(window.id, tabs[0].windowId, "Expected new window to be returned in query");
-
- await browser.windows.remove(window.id);
-
- browser.test.notifyPass("window-create");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-create");
- }
- },
- });
-
- let latestWindow;
- let windowListener = (window, topic) => {
- if (topic == "domwindowopened") {
- latestWindow = window;
- }
- };
- Services.ww.registerNotification(windowListener);
-
- extension.onMessage("check-window", expected => {
- if (expected.state != null) {
- let {windowState} = latestWindow;
- if (latestWindow.fullScreen) {
- windowState = latestWindow.STATE_FULLSCREEN;
- }
-
- if (expected.state == "STATE_NORMAL" && AppConstants.platform == "macosx") {
- ok(windowState == window.STATE_NORMAL || windowState == window.STATE_MAXIMIZED,
- `Expected windowState (currently ${windowState}) to be STATE_NORMAL but will accept STATE_MAXIMIZED`);
- } else {
- is(windowState, window[expected.state],
- `Expected window state to be ${expected.state}`);
- }
- }
- if (expected.hiddenChrome) {
- let chromeHidden = latestWindow.document.documentElement.getAttribute("chromehidden");
- is(chromeHidden.trim().split(/\s+/).sort().join(" "),
- expected.hiddenChrome.sort().join(" "),
- "Got expected hidden chrome");
- }
- if (expected.chromeFlags) {
- let {chromeFlags} = latestWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDocShell)
- .treeOwner.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIXULWindow);
- for (let flag of expected.chromeFlags) {
- ok(chromeFlags & Ci.nsIWebBrowserChrome[flag],
- `Expected window to have the ${flag} flag`);
- }
- }
-
- extension.sendMessage("checked-window");
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-create");
- yield extension.unload();
-
- Services.ww.unregisterNotification(windowListener);
- latestWindow = null;
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_create_params.js b/browser/components/extensions/test/browser/browser_ext_windows_create_params.js
deleted file mode 100644
index c54d94e05..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_create_params.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-
-// Tests that incompatible parameters can't be used together.
-add_task(function* testWindowCreateParams() {
- let extension = ExtensionTestUtils.loadExtension({
- async background() {
- try {
- for (let state of ["minimized", "maximized", "fullscreen"]) {
- for (let param of ["left", "top", "width", "height"]) {
- let expected = `"state": "${state}" may not be combined with "left", "top", "width", or "height"`;
-
- await browser.test.assertRejects(
- browser.windows.create({state, [param]: 100}),
- RegExp(expected),
- `Got expected error from create(${param}=100)`);
- }
- }
-
- browser.test.notifyPass("window-create-params");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-create-params");
- }
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-create-params");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js b/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
deleted file mode 100644
index 52ffaea8b..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testWindowCreate() {
- async function background() {
- let promiseTabAttached = () => {
- return new Promise(resolve => {
- browser.tabs.onAttached.addListener(function listener() {
- browser.tabs.onAttached.removeListener(listener);
- resolve();
- });
- });
- };
-
- let promiseTabUpdated = (expected) => {
- return new Promise(resolve => {
- browser.tabs.onUpdated.addListener(function listener(tabId, changeInfo, tab) {
- if (changeInfo.url === expected) {
- browser.tabs.onUpdated.removeListener(listener);
- resolve();
- }
- });
- });
- };
-
- try {
- let window = await browser.windows.getCurrent();
- let windowId = window.id;
-
- browser.test.log("Create additional tab in window 1");
- let tab = await browser.tabs.create({windowId, url: "about:blank"});
- let tabId = tab.id;
-
- browser.test.log("Create a new window, adopting the new tab");
-
- // Note that we want to check against actual boolean values for
- // all of the `incognito` property tests.
- browser.test.assertEq(false, tab.incognito, "Tab is not private");
-
- {
- let [, window] = await Promise.all([
- promiseTabAttached(),
- browser.windows.create({tabId: tabId}),
- ]);
- browser.test.assertEq(false, window.incognito, "New window is not private");
- browser.test.assertEq(tabId, window.tabs[0].id, "tabs property populated correctly");
-
- browser.test.log("Close the new window");
- await browser.windows.remove(window.id);
- }
-
- {
- browser.test.log("Create a new private window");
- let privateWindow = await browser.windows.create({incognito: true});
- browser.test.assertEq(true, privateWindow.incognito, "Private window is private");
-
- browser.test.log("Create additional tab in private window");
- let privateTab = await browser.tabs.create({windowId: privateWindow.id});
- browser.test.assertEq(true, privateTab.incognito, "Private tab is private");
-
- browser.test.log("Create a new window, adopting the new private tab");
- let [, newWindow] = await Promise.all([
- promiseTabAttached(),
- browser.windows.create({tabId: privateTab.id}),
- ]);
- browser.test.assertEq(true, newWindow.incognito, "New private window is private");
-
- browser.test.log("Close the new private window");
- await browser.windows.remove(newWindow.id);
-
- browser.test.log("Close the private window");
- await browser.windows.remove(privateWindow.id);
- }
-
-
- browser.test.log("Try to create a window with both a tab and a URL");
- [tab] = await browser.tabs.query({windowId, active: true});
- await browser.test.assertRejects(
- browser.windows.create({tabId: tab.id, url: "http://example.com/"}),
- /`tabId` may not be used in conjunction with `url`/,
- "Create call failed as expected");
-
- browser.test.log("Try to create a window with both a tab and an invalid incognito setting");
- await browser.test.assertRejects(
- browser.windows.create({tabId: tab.id, incognito: true}),
- /`incognito` property must match the incognito state of tab/,
- "Create call failed as expected");
-
-
- browser.test.log("Try to create a window with an invalid tabId");
- await browser.test.assertRejects(
- browser.windows.create({tabId: 0}),
- /Invalid tab ID: 0/,
- "Create call failed as expected");
-
-
- browser.test.log("Try to create a window with two URLs");
- let readyPromise = Promise.all([
- // tabs.onUpdated can be invoked between the call of windows.create and
- // the invocation of its callback/promise, so set up the listeners
- // before creating the window.
- promiseTabUpdated("http://example.com/"),
- promiseTabUpdated("http://example.org/"),
- ]);
-
- window = await browser.windows.create({url: ["http://example.com/", "http://example.org/"]});
- await readyPromise;
-
- browser.test.assertEq(2, window.tabs.length, "2 tabs were opened in new window");
- browser.test.assertEq("about:blank", window.tabs[0].url, "about:blank, page not loaded yet");
- browser.test.assertEq("about:blank", window.tabs[1].url, "about:blank, page not loaded yet");
-
- window = await browser.windows.get(window.id, {populate: true});
-
- browser.test.assertEq(2, window.tabs.length, "2 tabs were opened in new window");
- browser.test.assertEq("http://example.com/", window.tabs[0].url, "Correct URL was loaded in tab 1");
- browser.test.assertEq("http://example.org/", window.tabs[1].url, "Correct URL was loaded in tab 2");
-
- await browser.windows.remove(window.id);
-
- browser.test.notifyPass("window-create");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-create");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- "permissions": ["tabs"],
- },
-
- background,
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-create");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_create_url.js b/browser/components/extensions/test/browser/browser_ext_windows_create_url.js
deleted file mode 100644
index c5c7aaf20..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_create_url.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testWindowCreate() {
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["tabs"],
- },
-
- background: async function() {
- const EXTENSION_URL = browser.runtime.getURL("test.html");
- const REMOTE_URL = browser.runtime.getURL("test.html");
-
- let windows = new class extends Map { // eslint-disable-line new-parens
- get(id) {
- if (!this.has(id)) {
- let window = {
- tabs: new Map(),
- };
- window.promise = new Promise(resolve => {
- window.resolvePromise = resolve;
- });
-
- this.set(id, window);
- }
-
- return super.get(id);
- }
- };
-
- browser.tabs.onUpdated.addListener((tabId, changed, tab) => {
- if (changed.status == "complete" && tab.url !== "about:blank") {
- let window = windows.get(tab.windowId);
- window.tabs.set(tab.index, tab);
-
- if (window.tabs.size === window.expectedTabs) {
- window.resolvePromise(window);
- }
- }
- });
-
- async function create(options) {
- let window = await browser.windows.create(options);
- let win = windows.get(window.id);
-
- win.expectedTabs = Array.isArray(options.url) ? options.url.length : 1;
-
- return win.promise;
- }
-
- try {
- let windows = await Promise.all([
- create({url: REMOTE_URL}),
- create({url: "test.html"}),
- create({url: EXTENSION_URL}),
- create({url: [REMOTE_URL, "test.html", EXTENSION_URL]}),
- ]);
- browser.test.assertEq(REMOTE_URL, windows[0].tabs.get(0).url, "Single, absolute, remote URL");
-
- browser.test.assertEq(REMOTE_URL, windows[1].tabs.get(0).url, "Single, relative URL");
-
- browser.test.assertEq(REMOTE_URL, windows[2].tabs.get(0).url, "Single, absolute, extension URL");
-
- browser.test.assertEq(REMOTE_URL, windows[3].tabs.get(0).url, "url[0]: Absolute, remote URL");
- browser.test.assertEq(EXTENSION_URL, windows[3].tabs.get(1).url, "url[1]: Relative URL");
- browser.test.assertEq(EXTENSION_URL, windows[3].tabs.get(2).url, "url[2]: Absolute, extension URL");
-
- browser.test.notifyPass("window-create-url");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-create-url");
- }
- },
-
- files: {
- "test.html": `<DOCTYPE html><html><head><meta charset="utf-8"></head></html>`,
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-create-url");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_events.js b/browser/components/extensions/test/browser/browser_ext_windows_events.js
deleted file mode 100644
index dc3485b98..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_events.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-SimpleTest.requestCompleteLog();
-
-add_task(function* testWindowsEvents() {
- function background() {
- browser.windows.onCreated.addListener(window => {
- browser.test.log(`onCreated: windowId=${window.id}`);
-
- browser.test.assertTrue(Number.isInteger(window.id),
- "Window object's id is an integer");
- browser.test.assertEq("normal", window.type,
- "Window object returned with the correct type");
- browser.test.sendMessage("window-created", window.id);
- });
-
- let lastWindowId, os;
- browser.windows.onFocusChanged.addListener(async windowId => {
- browser.test.log(`onFocusChange: windowId=${windowId} lastWindowId=${lastWindowId}`);
-
- if (windowId === browser.windows.WINDOW_ID_NONE && os === "linux") {
- browser.test.log("Ignoring a superfluous WINDOW_ID_NONE (blur) event on Linux");
- return;
- }
-
- browser.test.assertTrue(lastWindowId !== windowId,
- "onFocusChanged fired once for the given window");
- lastWindowId = windowId;
-
- browser.test.assertTrue(Number.isInteger(windowId),
- "windowId is an integer");
-
- let window = await browser.windows.getLastFocused();
-
- browser.test.assertEq(windowId, window.id,
- "Last focused window has the correct id");
- browser.test.sendMessage(`window-focus-changed`, window.id);
- });
-
- browser.windows.onRemoved.addListener(windowId => {
- browser.test.log(`onRemoved: windowId=${windowId}`);
-
- browser.test.assertTrue(Number.isInteger(windowId),
- "windowId is an integer");
- browser.test.sendMessage(`window-removed`, windowId);
- browser.test.notifyPass("windows.events");
- });
-
- browser.runtime.getPlatformInfo(info => {
- os = info.os;
- browser.test.sendMessage("ready");
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- background: `(${background})()`,
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- let {Management: {global: {WindowManager}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
- let currentWindow = window;
- let currentWindowId = WindowManager.getId(currentWindow);
- info(`Current window ID: ${currentWindowId}`);
-
- info(`Create browser window 1`);
- let win1 = yield BrowserTestUtils.openNewBrowserWindow();
- let win1Id = yield extension.awaitMessage("window-created");
- info(`Window 1 ID: ${win1Id}`);
-
- // This shouldn't be necessary, but tests intermittently fail, so let's give
- // it a try.
- win1.focus();
-
- let winId = yield extension.awaitMessage(`window-focus-changed`);
- is(winId, win1Id, "Got focus change event for the correct window ID.");
-
- info(`Create browser window 2`);
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
- let win2Id = yield extension.awaitMessage("window-created");
- info(`Window 2 ID: ${win2Id}`);
-
- win2.focus();
-
- winId = yield extension.awaitMessage(`window-focus-changed`);
- is(winId, win2Id, "Got focus change event for the correct window ID.");
-
- info(`Focus browser window 1`);
- yield focusWindow(win1);
-
- winId = yield extension.awaitMessage(`window-focus-changed`);
- is(winId, win1Id, "Got focus change event for the correct window ID.");
-
- info(`Close browser window 2`);
- yield BrowserTestUtils.closeWindow(win2);
-
- winId = yield extension.awaitMessage(`window-removed`);
- is(winId, win2Id, "Got removed event for the correct window ID.");
-
- info(`Close browser window 1`);
- yield BrowserTestUtils.closeWindow(win1);
-
- winId = yield extension.awaitMessage(`window-removed`);
- is(winId, win1Id, "Got removed event for the correct window ID.");
-
- winId = yield extension.awaitMessage(`window-focus-changed`);
- is(winId, currentWindowId, "Got focus change event for the correct window ID.");
-
- yield extension.awaitFinish("windows.events");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_size.js b/browser/components/extensions/test/browser/browser_ext_windows_size.js
deleted file mode 100644
index be822fea1..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_size.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* testWindowCreate() {
- let extension = ExtensionTestUtils.loadExtension({
- async background() {
- let _checkWindowPromise;
- browser.test.onMessage.addListener((msg, arg) => {
- if (msg == "checked-window") {
- _checkWindowPromise.resolve(arg);
- _checkWindowPromise = null;
- }
- });
-
- let getWindowSize = () => {
- return new Promise(resolve => {
- _checkWindowPromise = {resolve};
- browser.test.sendMessage("check-window");
- });
- };
-
- const KEYS = ["left", "top", "width", "height"];
- function checkGeom(expected, actual) {
- for (let key of KEYS) {
- browser.test.assertEq(expected[key], actual[key], `Expected '${key}' value`);
- }
- }
-
- let windowId;
- async function checkWindow(expected, retries = 5) {
- let geom = await getWindowSize();
-
- if (retries && KEYS.some(key => expected[key] != geom[key])) {
- browser.test.log(`Got mismatched size (${JSON.stringify(expected)} != ${JSON.stringify(geom)}). ` +
- `Retrying after a short delay.`);
-
- await new Promise(resolve => setTimeout(resolve, 200));
-
- return checkWindow(expected, retries - 1);
- }
-
- browser.test.log(`Check actual window size`);
- checkGeom(expected, geom);
-
- browser.test.log("Check API-reported window size");
-
- geom = await browser.windows.get(windowId);
-
- checkGeom(expected, geom);
- }
-
- try {
- let geom = {left: 100, top: 100, width: 500, height: 300};
-
- let window = await browser.windows.create(geom);
- windowId = window.id;
-
- await checkWindow(geom);
-
- let update = {left: 150, width: 600};
- Object.assign(geom, update);
- await browser.windows.update(windowId, update);
- await checkWindow(geom);
-
- update = {top: 150, height: 400};
- Object.assign(geom, update);
- await browser.windows.update(windowId, update);
- await checkWindow(geom);
-
- geom = {left: 200, top: 200, width: 800, height: 600};
- await browser.windows.update(windowId, geom);
- await checkWindow(geom);
-
- let platformInfo = await browser.runtime.getPlatformInfo();
- if (platformInfo.os != "linux") {
- geom = {left: -50, top: -50, width: 800, height: 600};
- await browser.windows.update(windowId, geom);
- await checkWindow(geom);
- }
-
- await browser.windows.remove(windowId);
- browser.test.notifyPass("window-size");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-size");
- }
- },
- });
-
- let latestWindow;
- let windowListener = (window, topic) => {
- if (topic == "domwindowopened") {
- latestWindow = window;
- }
- };
- Services.ww.registerNotification(windowListener);
-
- extension.onMessage("check-window", () => {
- extension.sendMessage("checked-window", {
- top: latestWindow.screenY,
- left: latestWindow.screenX,
- width: latestWindow.outerWidth,
- height: latestWindow.outerHeight,
- });
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-size");
- yield extension.unload();
-
- Services.ww.unregisterNotification(windowListener);
- latestWindow = null;
-});
diff --git a/browser/components/extensions/test/browser/browser_ext_windows_update.js b/browser/components/extensions/test/browser/browser_ext_windows_update.js
deleted file mode 100644
index b9475547a..000000000
--- a/browser/components/extensions/test/browser/browser_ext_windows_update.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-add_task(function* () {
- function promiseWaitForFocus(window) {
- return new Promise(resolve => {
- waitForFocus(function() {
- ok(Services.focus.activeWindow === window, "correct window focused");
- resolve();
- }, window);
- });
- }
-
- let window1 = window;
- let window2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- Services.focus.activeWindow = window2;
- yield promiseWaitForFocus(window2);
-
- let extension = ExtensionTestUtils.loadExtension({
- background: function() {
- browser.windows.getAll(undefined, function(wins) {
- browser.test.assertEq(wins.length, 2, "should have two windows");
-
- // Sort the unfocused window to the lower index.
- wins.sort(function(win1, win2) {
- if (win1.focused === win2.focused) {
- return 0;
- }
-
- return win1.focused ? 1 : -1;
- });
-
- browser.windows.update(wins[0].id, {focused: true}, function() {
- browser.test.sendMessage("check");
- });
- });
- },
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("check")]);
-
- yield promiseWaitForFocus(window1);
-
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(window2);
-});
-
-
-add_task(function* testWindowUpdate() {
- let extension = ExtensionTestUtils.loadExtension({
- async background() {
- let _checkWindowPromise;
- browser.test.onMessage.addListener(msg => {
- if (msg == "checked-window") {
- _checkWindowPromise.resolve();
- _checkWindowPromise = null;
- }
- });
-
- let os;
- function checkWindow(expected) {
- return new Promise(resolve => {
- _checkWindowPromise = {resolve};
- browser.test.sendMessage("check-window", expected);
- });
- }
-
- let currentWindowId;
- async function updateWindow(windowId, params, expected) {
- let window = await browser.windows.update(windowId, params);
-
- browser.test.assertEq(currentWindowId, window.id, "Expected WINDOW_ID_CURRENT to refer to the same window");
- for (let key of Object.keys(params)) {
- if (key == "state" && os == "mac" && params.state == "normal") {
- // OS-X doesn't have a hard distinction between "normal" and
- // "maximized" states.
- browser.test.assertTrue(window.state == "normal" || window.state == "maximized",
- `Expected window.state (currently ${window.state}) to be "normal" but will accept "maximized"`);
- } else {
- browser.test.assertEq(params[key], window[key], `Got expected value for window.${key}`);
- }
- }
-
- return checkWindow(expected);
- }
-
- try {
- let windowId = browser.windows.WINDOW_ID_CURRENT;
-
- ({os} = await browser.runtime.getPlatformInfo());
-
- let window = await browser.windows.getCurrent();
- currentWindowId = window.id;
-
- await updateWindow(windowId, {state: "maximized"}, {state: "STATE_MAXIMIZED"});
- await updateWindow(windowId, {state: "minimized"}, {state: "STATE_MINIMIZED"});
- await updateWindow(windowId, {state: "normal"}, {state: "STATE_NORMAL"});
- await updateWindow(windowId, {state: "fullscreen"}, {state: "STATE_FULLSCREEN"});
- await updateWindow(windowId, {state: "normal"}, {state: "STATE_NORMAL"});
-
- browser.test.notifyPass("window-update");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-update");
- }
- },
- });
-
- extension.onMessage("check-window", expected => {
- if (expected.state != null) {
- let {windowState} = window;
- if (window.fullScreen) {
- windowState = window.STATE_FULLSCREEN;
- }
-
- // Temporarily accepting STATE_MAXIMIZED on Linux because of bug 1307759.
- if (expected.state == "STATE_NORMAL" && (AppConstants.platform == "macosx" || AppConstants.platform == "linux")) {
- ok(windowState == window.STATE_NORMAL || windowState == window.STATE_MAXIMIZED,
- `Expected windowState (currently ${windowState}) to be STATE_NORMAL but will accept STATE_MAXIMIZED`);
- } else {
- is(windowState, window[expected.state],
- `Expected window state to be ${expected.state}`);
- }
- }
-
- extension.sendMessage("checked-window");
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-update");
- yield extension.unload();
-});
-
-add_task(function* () {
- let window2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- let extension = ExtensionTestUtils.loadExtension({
- background: function() {
- browser.windows.getAll(undefined, function(wins) {
- browser.test.assertEq(wins.length, 2, "should have two windows");
-
- let unfocused = wins.find(win => !win.focused);
- browser.windows.update(unfocused.id, {drawAttention: true}, function() {
- browser.test.sendMessage("check");
- });
- });
- },
- });
-
- yield Promise.all([extension.startup(), extension.awaitMessage("check")]);
-
- yield extension.unload();
-
- yield BrowserTestUtils.closeWindow(window2);
-});
-
-
-// Tests that incompatible parameters can't be used together.
-add_task(function* testWindowUpdateParams() {
- let extension = ExtensionTestUtils.loadExtension({
- async background() {
- try {
- for (let state of ["minimized", "maximized", "fullscreen"]) {
- for (let param of ["left", "top", "width", "height"]) {
- let expected = `"state": "${state}" may not be combined with "left", "top", "width", or "height"`;
-
- let windowId = browser.windows.WINDOW_ID_CURRENT;
- await browser.test.assertRejects(
- browser.windows.update(windowId, {state, [param]: 100}),
- RegExp(expected),
- `Got expected error for create(${param}=100`);
- }
- }
-
- browser.test.notifyPass("window-update-params");
- } catch (e) {
- browser.test.fail(`${e} :: ${e.stack}`);
- browser.test.notifyFail("window-update-params");
- }
- },
- });
-
- yield extension.startup();
- yield extension.awaitFinish("window-update-params");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/browser/context.html b/browser/components/extensions/test/browser/context.html
deleted file mode 100644
index 954feea52..000000000
--- a/browser/components/extensions/test/browser/context.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- just some text 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
- <img src="ctxmenu-image.png" id="img1">
-
- <p>
- <a href="some-link" id="link1">Some link</a>
- </p>
-
- <p>
- <a href="image-around-some-link">
- <img src="ctxmenu-image.png" id="img-wrapped-in-link">
- </a>
- </p>
-
- <p>
- <input type="text" id="edit-me">
- </p>
- </body>
-</html>
diff --git a/browser/components/extensions/test/browser/context_tabs_onUpdated_iframe.html b/browser/components/extensions/test/browser/context_tabs_onUpdated_iframe.html
deleted file mode 100644
index 0e9b54b52..000000000
--- a/browser/components/extensions/test/browser/context_tabs_onUpdated_iframe.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<html>
- <body>
- <h3>test iframe</h3>
- <script>
- "use strict";
-
- window.onload = function() {
- window.onhashchange = function() {
- window.parent.postMessage("updated-iframe-url", "*");
- };
- // NOTE: without the this setTimeout the location change is not fired
- // even without the "fire only for top level windows" fix
- setTimeout(function() {
- window.location.hash = "updated-iframe-url";
- }, 0);
- };
- </script>
- </body>
-</html>
diff --git a/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html b/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html
deleted file mode 100644
index 0f2ce1e8f..000000000
--- a/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<html>
- <body>
- <h3>test page</h3>
- <iframe src="about:blank"></iframe>
- <script>
- "use strict";
-
- window.onmessage = function(evt) {
- if (evt.data === "updated-iframe-url") {
- window.postMessage("frame-updated", "*");
- }
- };
- window.onload = function() {
- document.querySelector("iframe").setAttribute("src", "context_tabs_onUpdated_iframe.html");
- };
- </script>
- </body>
-</html>
diff --git a/browser/components/extensions/test/browser/ctxmenu-image.png b/browser/components/extensions/test/browser/ctxmenu-image.png
deleted file mode 100644
index 4c3be5084..000000000
--- a/browser/components/extensions/test/browser/ctxmenu-image.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/extensions/test/browser/file_bypass_cache.sjs b/browser/components/extensions/test/browser/file_bypass_cache.sjs
deleted file mode 100644
index c91c76b88..000000000
--- a/browser/components/extensions/test/browser/file_bypass_cache.sjs
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */
-"use strict";
-
-function handleRequest(request, response) {
- response.setHeader("Content-Type", "text/plain; charset=UTF-8", false);
-
- if (request.hasHeader("pragma") && request.hasHeader("cache-control")) {
- response.write(`${request.getHeader("pragma")}:${request.getHeader("cache-control")}`);
- }
-} \ No newline at end of file
diff --git a/browser/components/extensions/test/browser/file_dummy.html b/browser/components/extensions/test/browser/file_dummy.html
deleted file mode 100644
index 1a87e2840..000000000
--- a/browser/components/extensions/test/browser/file_dummy.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>Dummy test page</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<p>Dummy test page</p>
-</body>
-</html>
diff --git a/browser/components/extensions/test/browser/file_iframe_document.html b/browser/components/extensions/test/browser/file_iframe_document.html
deleted file mode 100644
index fcadccf02..000000000
--- a/browser/components/extensions/test/browser/file_iframe_document.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title></title>
-</head>
-<body>
- <iframe src="/"></iframe>
-</body>
-</html>
diff --git a/browser/components/extensions/test/browser/file_iframe_document.sjs b/browser/components/extensions/test/browser/file_iframe_document.sjs
deleted file mode 100644
index 661a768af..000000000
--- a/browser/components/extensions/test/browser/file_iframe_document.sjs
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */
-"use strict";
-
-// This script slows the load of an HTML document so that we can reliably test
-// all phases of the load cycle supported by the extension API.
-
-/* eslint-disable no-unused-vars */
-
-const DELAY = 1 * 1000; // Delay one second before completing the request.
-
-const Ci = Components.interfaces;
-
-let nsTimer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
-
-let timer;
-
-function handleRequest(request, response) {
- response.processAsync();
-
- response.setHeader("Content-Type", "text/html", false);
- response.setHeader("Cache-Control", "no-cache", false);
- response.write(`<!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- `);
-
- // Note: We need to store a reference to the timer to prevent it from being
- // canceled when it's GCed.
- timer = new nsTimer(() => {
- response.write(`
- <iframe src="/"></iframe>
- </body>
- </html>`);
- response.finish();
- }, DELAY, Ci.nsITimer.TYPE_ONE_SHOT);
-}
diff --git a/browser/components/extensions/test/browser/file_language_fr_en.html b/browser/components/extensions/test/browser/file_language_fr_en.html
deleted file mode 100644
index 5e3c7b3b0..000000000
--- a/browser/components/extensions/test/browser/file_language_fr_en.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html lang="fr">
-<head>
- <meta charset="UTF-8">
- <title></title>
-</head>
-<body>
- France is the largest country in Western Europe and the third-largest in Europe as a whole.
- A accès aux chiens et aux frontaux qui lui ont été il peut consulter et modifier ses collections et exporter
- Cet article concerne le pays européen aujourd’hui appelé République française. Pour d’autres usages du nom France,
- Pour une aide rapide et effective, veuiller trouver votre aide dans le menu ci-dessus.
- Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumps over the lazy dog.
-</body>
-</html>
diff --git a/browser/components/extensions/test/browser/file_language_ja.html b/browser/components/extensions/test/browser/file_language_ja.html
deleted file mode 100644
index ed07ba70e..000000000
--- a/browser/components/extensions/test/browser/file_language_ja.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html lang="ja">
-<head>
- <meta charset="UTF-8">
- <title></title>
-</head>
-<body>
- ã“ã®ãƒš ジã§ã¯ アカウントã«æŒ‡å®šã•ã‚ŒãŸäºˆç®—ã®å±¥æ­´ã‚’一覧ã«ã—ã¦ã„ã¾ã™ ãã‚Œãžã‚Œã®é …ç›®ã«ã¯ 予算é¡ã¨ç‰¹å®šæœŸé–“ã®ã‚¹ãƒ† タスãŒè¡¨ç¤ºã•ã‚Œã¾ã™ ç¾åœ¨ã¾ãŸã¯ä»Šå¾Œã®äºˆç®—を設定ã™ã‚‹ã«ã¯
-</body>
-</html>
diff --git a/browser/components/extensions/test/browser/file_language_tlh.html b/browser/components/extensions/test/browser/file_language_tlh.html
deleted file mode 100644
index dd7da7bdb..000000000
--- a/browser/components/extensions/test/browser/file_language_tlh.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html lang="tlh">
-<head>
- <meta charset="UTF-8">
- <title></title>
-</head>
-<body>
- tlhIngan maH!
- Hab SoSlI' Quch!
- Heghlu'meH QaQ jajvam
-</body>
-</html>
diff --git a/browser/components/extensions/test/browser/file_popup_api_injection_a.html b/browser/components/extensions/test/browser/file_popup_api_injection_a.html
deleted file mode 100644
index 750ff1db3..000000000
--- a/browser/components/extensions/test/browser/file_popup_api_injection_a.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <script type="application/javascript">
- "use strict";
- throw new Error(`WebExt Privilege Escalation: BrowserAction: typeof(browser) = ${typeof(browser)}`);
- </script>
-</head>
-</html>
diff --git a/browser/components/extensions/test/browser/file_popup_api_injection_b.html b/browser/components/extensions/test/browser/file_popup_api_injection_b.html
deleted file mode 100644
index b8c287e55..000000000
--- a/browser/components/extensions/test/browser/file_popup_api_injection_b.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <script type="application/javascript">
- "use strict";
- throw new Error(`WebExt Privilege Escalation: PageAction: typeof(browser) = ${typeof(browser)}`);
- </script>
-</head>
-</html>
diff --git a/browser/components/extensions/test/browser/head.js b/browser/components/extensions/test/browser/head.js
deleted file mode 100644
index f8d59c944..000000000
--- a/browser/components/extensions/test/browser/head.js
+++ /dev/null
@@ -1,263 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* exported CustomizableUI makeWidgetId focusWindow forceGC
- * getBrowserActionWidget
- * clickBrowserAction clickPageAction
- * getBrowserActionPopup getPageActionPopup
- * closeBrowserAction closePageAction
- * promisePopupShown promisePopupHidden
- * openContextMenu closeContextMenu
- * openExtensionContextMenu closeExtensionContextMenu
- * imageBuffer getListStyleImage getPanelForNode
- * awaitExtensionPanel awaitPopupResize
- * promiseContentDimensions alterContent
- */
-
-var {AppConstants} = Cu.import("resource://gre/modules/AppConstants.jsm");
-var {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
-
-// Bug 1239884: Our tests occasionally hit a long GC pause at unpredictable
-// times in debug builds, which results in intermittent timeouts. Until we have
-// a better solution, we force a GC after certain strategic tests, which tend to
-// accumulate a high number of unreaped windows.
-function forceGC() {
- if (AppConstants.DEBUG) {
- Cu.forceGC();
- }
-}
-
-function makeWidgetId(id) {
- id = id.toLowerCase();
- return id.replace(/[^a-z0-9_-]/g, "_");
-}
-
-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);
- resolve();
- }, true);
- });
-
- win.focus();
- yield promise;
-});
-
-let img = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==";
-var imageBuffer = Uint8Array.from(atob(img), byte => byte.charCodeAt(0)).buffer;
-
-function getListStyleImage(button) {
- let style = button.ownerDocument.defaultView.getComputedStyle(button);
-
- let match = /^url\("(.*)"\)$/.exec(style.listStyleImage);
-
- return match && match[1];
-}
-
-function promisePopupShown(popup) {
- return new Promise(resolve => {
- if (popup.state == "open") {
- resolve();
- } else {
- let onPopupShown = event => {
- popup.removeEventListener("popupshown", onPopupShown);
- resolve();
- };
- popup.addEventListener("popupshown", onPopupShown);
- }
- });
-}
-
-function promisePopupHidden(popup) {
- return new Promise(resolve => {
- let onPopupHidden = event => {
- popup.removeEventListener("popuphidden", onPopupHidden);
- resolve();
- };
- popup.addEventListener("popuphidden", onPopupHidden);
- });
-}
-
-function promiseContentDimensions(browser) {
- return ContentTask.spawn(browser, null, function* () {
- function copyProps(obj, props) {
- let res = {};
- for (let prop of props) {
- res[prop] = obj[prop];
- }
- return res;
- }
-
- return {
- window: copyProps(content,
- ["innerWidth", "innerHeight", "outerWidth", "outerHeight",
- "scrollX", "scrollY", "scrollMaxX", "scrollMaxY"]),
- body: copyProps(content.document.body,
- ["clientWidth", "clientHeight", "scrollWidth", "scrollHeight"]),
- root: copyProps(content.document.documentElement,
- ["clientWidth", "clientHeight", "scrollWidth", "scrollHeight"]),
-
- isStandards: content.document.compatMode !== "BackCompat",
- };
- });
-}
-
-function* awaitPopupResize(browser) {
- return BrowserTestUtils.waitForEvent(browser, "WebExtPopupResized",
- event => event.detail === "delayed");
-}
-
-function alterContent(browser, task, arg = null) {
- return Promise.all([
- ContentTask.spawn(browser, arg, task),
- awaitPopupResize(browser),
- ]).then(() => {
- return promiseContentDimensions(browser);
- });
-}
-
-function getPanelForNode(node) {
- while (node.localName != "panel") {
- node = node.parentNode;
- }
- return node;
-}
-
-var awaitBrowserLoaded = browser => ContentTask.spawn(browser, null, () => {
- if (content.document.readyState !== "complete") {
- return ContentTaskUtils.waitForEvent(content, "load").then(() => {});
- }
-});
-
-var awaitExtensionPanel = Task.async(function* (extension, win = window, awaitLoad = true) {
- let {originalTarget: browser} = yield BrowserTestUtils.waitForEvent(
- win.document, "WebExtPopupLoaded", true,
- event => event.detail.extension.id === extension.id);
-
- yield Promise.all([
- promisePopupShown(getPanelForNode(browser)),
-
- awaitLoad && awaitBrowserLoaded(browser),
- ]);
-
- return browser;
-});
-
-function getBrowserActionWidget(extension) {
- return CustomizableUI.getWidget(makeWidgetId(extension.id) + "-browser-action");
-}
-
-function getBrowserActionPopup(extension, win = window) {
- let group = getBrowserActionWidget(extension);
-
- if (group.areaType == CustomizableUI.TYPE_TOOLBAR) {
- return win.document.getElementById("customizationui-widget-panel");
- }
- return win.PanelUI.panel;
-}
-
-var showBrowserAction = Task.async(function* (extension, win = window) {
- let group = getBrowserActionWidget(extension);
- let widget = group.forWindow(win);
-
- if (group.areaType == CustomizableUI.TYPE_TOOLBAR) {
- ok(!widget.overflowed, "Expect widget not to be overflowed");
- } else if (group.areaType == CustomizableUI.TYPE_MENU_PANEL) {
- yield win.PanelUI.show();
- }
-});
-
-var clickBrowserAction = Task.async(function* (extension, win = window) {
- yield showBrowserAction(extension, win);
-
- let widget = getBrowserActionWidget(extension).forWindow(win);
-
- EventUtils.synthesizeMouseAtCenter(widget.node, {}, win);
-});
-
-function closeBrowserAction(extension, win = window) {
- let group = getBrowserActionWidget(extension);
-
- let node = win.document.getElementById(group.viewId);
- CustomizableUI.hidePanelForNode(node);
-
- return Promise.resolve();
-}
-
-function* openContextMenu(selector = "#img1") {
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
- yield BrowserTestUtils.synthesizeMouseAtCenter(selector, {type: "contextmenu"}, gBrowser.selectedBrowser);
- yield popupShownPromise;
- return contentAreaContextMenu;
-}
-
-function* closeContextMenu() {
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- contentAreaContextMenu.hidePopup();
- yield popupHiddenPromise;
-}
-
-function* openExtensionContextMenu(selector = "#img1") {
- let contextMenu = yield openContextMenu(selector);
- let topLevelMenu = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
-
- // Return null if the extension only has one item and therefore no extension menu.
- if (topLevelMenu.length == 0) {
- return null;
- }
-
- let extensionMenu = topLevelMenu[0].childNodes[0];
- let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- EventUtils.synthesizeMouseAtCenter(extensionMenu, {});
- yield popupShownPromise;
- return extensionMenu;
-}
-
-function* closeExtensionContextMenu(itemToSelect) {
- let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
- EventUtils.synthesizeMouseAtCenter(itemToSelect, {});
- yield popupHiddenPromise;
-}
-
-function getPageActionPopup(extension, win = window) {
- let panelId = makeWidgetId(extension.id) + "-panel";
- return win.document.getElementById(panelId);
-}
-
-function clickPageAction(extension, win = window) {
- // This would normally be set automatically on navigation, and cleared
- // when the user types a value into the URL bar, to show and hide page
- // identity info and icons such as page action buttons.
- //
- // Unfortunately, that doesn't happen automatically in browser chrome
- // tests.
- /* globals SetPageProxyState */
- SetPageProxyState("valid");
-
- let pageActionId = makeWidgetId(extension.id) + "-page-action";
- let elem = win.document.getElementById(pageActionId);
-
- EventUtils.synthesizeMouseAtCenter(elem, {}, win);
- return new Promise(SimpleTest.executeSoon);
-}
-
-function closePageAction(extension, win = window) {
- let node = getPageActionPopup(extension, win);
- if (node) {
- return promisePopupShown(node).then(() => {
- node.hidePopup();
- });
- }
-
- return Promise.resolve();
-}
diff --git a/browser/components/extensions/test/browser/head_pageAction.js b/browser/components/extensions/test/browser/head_pageAction.js
deleted file mode 100644
index f2d81e512..000000000
--- a/browser/components/extensions/test/browser/head_pageAction.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* exported runTests */
-/* globals getListStyleImage */
-
-function* runTests(options) {
- function background(getTests) {
- let tabs;
- let tests;
-
- // Gets the current details of the page action, and returns a
- // promise that resolves to an object containing them.
- async function getDetails() {
- let [tab] = await browser.tabs.query({active: true, currentWindow: true});
- let tabId = tab.id;
-
- browser.test.log(`Get details: tab={id: ${tabId}, url: ${JSON.stringify(tab.url)}}`);
-
- return {
- title: await browser.pageAction.getTitle({tabId}),
- popup: await browser.pageAction.getPopup({tabId}),
- };
- }
-
-
- // Runs the next test in the `tests` array, checks the results,
- // and passes control back to the outer test scope.
- function nextTest() {
- let test = tests.shift();
-
- test(async expecting => {
- function finish() {
- // Check that the actual icon has the expected values, then
- // run the next test.
- browser.test.sendMessage("nextTest", expecting, tests.length);
- }
-
- if (expecting) {
- // Check that the API returns the expected values, and then
- // run the next test.
- let details = await getDetails();
-
- browser.test.assertEq(expecting.title, details.title,
- "expected value from getTitle");
-
- browser.test.assertEq(expecting.popup, details.popup,
- "expected value from getPopup");
- }
-
- finish();
- });
- }
-
- async function runTests() {
- tabs = [];
- tests = getTests(tabs);
-
- let resultTabs = await browser.tabs.query({active: true, currentWindow: true});
-
- tabs[0] = resultTabs[0].id;
-
- nextTest();
- }
-
- browser.test.onMessage.addListener((msg) => {
- if (msg == "runTests") {
- runTests();
- } else if (msg == "runNextTest") {
- nextTest();
- } else {
- browser.test.fail(`Unexpected message: ${msg}`);
- }
- });
-
- runTests();
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: options.manifest,
-
- files: options.files || {},
-
- background: `(${background})(${options.getTests})`,
- });
-
- let pageActionId;
- let currentWindow = window;
- let windows = [];
-
- function checkDetails(details) {
- let image = currentWindow.document.getElementById(pageActionId);
- if (details == null) {
- ok(image == null || image.hidden, "image is hidden");
- } else {
- ok(image, "image exists");
-
- is(getListStyleImage(image), details.icon, "icon URL is correct");
-
- let title = details.title || options.manifest.name;
- is(image.getAttribute("tooltiptext"), title, "image title is correct");
- is(image.getAttribute("aria-label"), title, "image aria-label is correct");
- // TODO: Popup URL.
- }
- }
-
- let testNewWindows = 1;
-
- let awaitFinish = new Promise(resolve => {
- extension.onMessage("nextTest", (expecting, testsRemaining) => {
- if (!pageActionId) {
- pageActionId = `${makeWidgetId(extension.id)}-page-action`;
- }
-
- checkDetails(expecting);
-
- if (testsRemaining) {
- extension.sendMessage("runNextTest");
- } else if (testNewWindows) {
- testNewWindows--;
-
- BrowserTestUtils.openNewBrowserWindow().then(window => {
- windows.push(window);
- currentWindow = window;
- return focusWindow(window);
- }).then(() => {
- extension.sendMessage("runTests");
- });
- } else {
- resolve();
- }
- });
- });
-
- yield SpecialPowers.pushPrefEnv({set: [["general.useragent.locale", "es-ES"]]});
-
- yield extension.startup();
-
- yield awaitFinish;
-
- yield extension.unload();
-
- yield SpecialPowers.popPrefEnv();
-
- let node = document.getElementById(pageActionId);
- is(node, null, "pageAction image removed from document");
-
- currentWindow = null;
- for (let win of windows.splice(0)) {
- node = win.document.getElementById(pageActionId);
- is(node, null, "pageAction image removed from second document");
-
- yield BrowserTestUtils.closeWindow(win);
- }
-}
-
diff --git a/browser/components/extensions/test/browser/head_sessions.js b/browser/components/extensions/test/browser/head_sessions.js
deleted file mode 100644
index ca3a86c24..000000000
--- a/browser/components/extensions/test/browser/head_sessions.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* exported recordInitialTimestamps onlyNewItemsFilter checkRecentlyClosed */
-
-let initialTimestamps = [];
-
-function recordInitialTimestamps(timestamps) {
- initialTimestamps = timestamps;
-}
-
-function onlyNewItemsFilter(item) {
- return !initialTimestamps.includes(item.lastModified);
-}
-
-function checkWindow(window) {
- for (let prop of ["focused", "incognito", "alwaysOnTop"]) {
- is(window[prop], false, `closed window has the expected value for ${prop}`);
- }
- for (let prop of ["state", "type"]) {
- is(window[prop], "normal", `closed window has the expected value for ${prop}`);
- }
-}
-
-function checkTab(tab, windowId, incognito) {
- for (let prop of ["selected", "highlighted", "active", "pinned"]) {
- is(tab[prop], false, `closed tab has the expected value for ${prop}`);
- }
- is(tab.windowId, windowId, "closed tab has the expected value for windowId");
- is(tab.incognito, incognito, "closed tab has the expected value for incognito");
-}
-
-function checkRecentlyClosed(recentlyClosed, expectedCount, windowId, incognito = false) {
- let sessionIds = new Set();
- is(recentlyClosed.length, expectedCount, "the expected number of closed tabs/windows was found");
- for (let item of recentlyClosed) {
- if (item.window) {
- sessionIds.add(item.window.sessionId);
- checkWindow(item.window);
- } else if (item.tab) {
- sessionIds.add(item.tab.sessionId);
- checkTab(item.tab, windowId, incognito);
- }
- }
- is(sessionIds.size, expectedCount, "each item has a unique sessionId");
-}
diff --git a/browser/components/extensions/test/browser/searchSuggestionEngine.sjs b/browser/components/extensions/test/browser/searchSuggestionEngine.sjs
deleted file mode 100644
index 1978b4f66..000000000
--- a/browser/components/extensions/test/browser/searchSuggestionEngine.sjs
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function handleRequest(req, resp) {
- let suffixes = ["foo", "bar"];
- let data = [req.queryString, suffixes.map(s => req.queryString + s)];
- resp.setHeader("Content-Type", "application/json", false);
- resp.write(JSON.stringify(data));
-}
diff --git a/browser/components/extensions/test/browser/searchSuggestionEngine.xml b/browser/components/extensions/test/browser/searchSuggestionEngine.xml
deleted file mode 100644
index 703d45925..000000000
--- a/browser/components/extensions/test/browser/searchSuggestionEngine.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_searchSuggestionEngine searchSuggestionEngine.xml</ShortName>
-<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/components/extensions/test/browser/searchSuggestionEngine.sjs?{searchTerms}"/>
-<Url type="text/html" method="GET" template="http://mochi.test:8888/" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/components/extensions/test/mochitest/mochitest.ini b/browser/components/extensions/test/mochitest/mochitest.ini
deleted file mode 100644
index 39290db61..000000000
--- a/browser/components/extensions/test/mochitest/mochitest.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[DEFAULT]
-support-files =
- ../../../../../toolkit/components/extensions/test/mochitest/test_ext_all_apis.js
-tags = webextensions
-
-[test_ext_all_apis.html]
diff --git a/browser/components/extensions/test/mochitest/test_ext_all_apis.html b/browser/components/extensions/test/mochitest/test_ext_all_apis.html
deleted file mode 100644
index 176d380c2..000000000
--- a/browser/components/extensions/test/mochitest/test_ext_all_apis.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>WebExtension test</title>
- <meta charset="utf-8">
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
- <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-</head>
-<body>
-<script>
-"use strict";
-/* exported expectedContentApisTargetSpecific, expectedBackgroundApisTargetSpecific */
-let expectedContentApisTargetSpecific = [
-];
-
-let expectedBackgroundApisTargetSpecific = [
- "tabs.MutedInfoReason",
- "tabs.TAB_ID_NONE",
- "tabs.TabStatus",
- "tabs.WindowType",
- "tabs.ZoomSettingsMode",
- "tabs.ZoomSettingsScope",
- "tabs.connect",
- "tabs.create",
- "tabs.detectLanguage",
- "tabs.duplicate",
- "tabs.executeScript",
- "tabs.get",
- "tabs.getCurrent",
- "tabs.getZoom",
- "tabs.getZoomSettings",
- "tabs.highlight",
- "tabs.insertCSS",
- "tabs.move",
- "tabs.onActivated",
- "tabs.onAttached",
- "tabs.onCreated",
- "tabs.onDetached",
- "tabs.onHighlighted",
- "tabs.onMoved",
- "tabs.onRemoved",
- "tabs.onReplaced",
- "tabs.onUpdated",
- "tabs.onZoomChange",
- "tabs.query",
- "tabs.reload",
- "tabs.remove",
- "tabs.removeCSS",
- "tabs.sendMessage",
- "tabs.setZoom",
- "tabs.setZoomSettings",
- "tabs.update",
- "windows.CreateType",
- "windows.WINDOW_ID_CURRENT",
- "windows.WINDOW_ID_NONE",
- "windows.WindowState",
- "windows.WindowType",
- "windows.create",
- "windows.get",
- "windows.getAll",
- "windows.getCurrent",
- "windows.getLastFocused",
- "windows.onCreated",
- "windows.onFocusChanged",
- "windows.onRemoved",
- "windows.remove",
- "windows.update",
-];
-</script>
-<script src="test_ext_all_apis.js"></script>
-
-</body>
-</html>
diff --git a/browser/components/extensions/test/xpcshell/.eslintrc.js b/browser/components/extensions/test/xpcshell/.eslintrc.js
deleted file mode 100644
index 2bfe540ea..000000000
--- a/browser/components/extensions/test/xpcshell/.eslintrc.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-module.exports = { // eslint-disable-line no-undef
- "extends": "../../../../../testing/xpcshell/xpcshell.eslintrc.js",
-
- "globals": {
- "browser": false,
- },
-};
diff --git a/browser/components/extensions/test/xpcshell/head.js b/browser/components/extensions/test/xpcshell/head.js
deleted file mode 100644
index de4a4a3f6..000000000
--- a/browser/components/extensions/test/xpcshell/head.js
+++ /dev/null
@@ -1,55 +0,0 @@
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-/* exported createHttpServer */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
- "resource://gre/modules/AppConstants.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Extension",
- "resource://gre/modules/Extension.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ExtensionData",
- "resource://gre/modules/Extension.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ExtensionManagement",
- "resource://gre/modules/ExtensionManagement.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ExtensionTestUtils",
- "resource://testing-common/ExtensionXPCShellUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
- "resource://testing-common/httpd.js");
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
- "resource://gre/modules/NetUtil.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
- "resource://gre/modules/Schemas.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Services",
- "resource://gre/modules/Services.jsm");
-
-ExtensionTestUtils.init(this);
-
-
-/**
- * Creates a new HttpServer for testing, and begins listening on the
- * specified port. Automatically shuts down the server when the test
- * unit ends.
- *
- * @param {integer} [port]
- * The port to listen on. If omitted, listen on a random
- * port. The latter is the preferred behavior.
- *
- * @returns {HttpServer}
- */
-function createHttpServer(port = -1) {
- let server = new HttpServer();
- server.start(port);
-
- do_register_cleanup(() => {
- return new Promise(resolve => {
- server.stop(resolve);
- });
- });
-
- return server;
-}
diff --git a/browser/components/extensions/test/xpcshell/test_ext_bookmarks.js b/browser/components/extensions/test/xpcshell/test_ext_bookmarks.js
deleted file mode 100644
index 142c0a37c..000000000
--- a/browser/components/extensions/test/xpcshell/test_ext_bookmarks.js
+++ /dev/null
@@ -1,601 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function backgroundScript() {
- let unsortedId, ourId;
- let initialBookmarkCount = 0;
- let createdBookmarks = new Set();
- let createdFolderId;
- let collectedEvents = [];
- const nonExistentId = "000000000000";
- const bookmarkGuids = {
- menuGuid: "menu________",
- toolbarGuid: "toolbar_____",
- unfiledGuid: "unfiled_____",
- };
-
- function checkOurBookmark(bookmark) {
- browser.test.assertEq(ourId, bookmark.id, "Bookmark has the expected Id");
- browser.test.assertTrue("parentId" in bookmark, "Bookmark has a parentId");
- browser.test.assertEq(0, bookmark.index, "Bookmark has the expected index"); // We assume there are no other bookmarks.
- browser.test.assertEq("http://example.org/", bookmark.url, "Bookmark has the expected url");
- browser.test.assertEq("test bookmark", bookmark.title, "Bookmark has the expected title");
- browser.test.assertTrue("dateAdded" in bookmark, "Bookmark has a dateAdded");
- browser.test.assertFalse("dateGroupModified" in bookmark, "Bookmark does not have a dateGroupModified");
- browser.test.assertFalse("unmodifiable" in bookmark, "Bookmark is not unmodifiable");
- }
-
- function checkBookmark(expected, bookmark) {
- browser.test.assertEq(expected.url, bookmark.url, "Bookmark has the expected url");
- browser.test.assertEq(expected.title, bookmark.title, "Bookmark has the expected title");
- browser.test.assertEq(expected.index, bookmark.index, "Bookmark has expected index");
- if ("parentId" in expected) {
- browser.test.assertEq(expected.parentId, bookmark.parentId, "Bookmark has the expected parentId");
- }
- }
-
- function expectedError() {
- browser.test.fail("Did not get expected error");
- }
-
- function checkOnCreated(id, parentId, index, title, url, dateAdded) {
- let createdData = collectedEvents.pop();
- browser.test.assertEq("onCreated", createdData.event, "onCreated was the last event received");
- browser.test.assertEq(id, createdData.id, "onCreated event received the expected id");
- let bookmark = createdData.bookmark;
- browser.test.assertEq(id, bookmark.id, "onCreated event received the expected bookmark id");
- browser.test.assertEq(parentId, bookmark.parentId, "onCreated event received the expected bookmark parentId");
- browser.test.assertEq(index, bookmark.index, "onCreated event received the expected bookmark index");
- browser.test.assertEq(title, bookmark.title, "onCreated event received the expected bookmark title");
- browser.test.assertEq(url, bookmark.url, "onCreated event received the expected bookmark url");
- browser.test.assertEq(dateAdded, bookmark.dateAdded, "onCreated event received the expected bookmark dateAdded");
- }
-
- function checkOnChanged(id, url, title) {
- // If both url and title are changed, then url is fired last.
- let changedData = collectedEvents.pop();
- browser.test.assertEq("onChanged", changedData.event, "onChanged was the last event received");
- browser.test.assertEq(id, changedData.id, "onChanged event received the expected id");
- browser.test.assertEq(url, changedData.info.url, "onChanged event received the expected url");
- // title is fired first.
- changedData = collectedEvents.pop();
- browser.test.assertEq("onChanged", changedData.event, "onChanged was the last event received");
- browser.test.assertEq(id, changedData.id, "onChanged event received the expected id");
- browser.test.assertEq(title, changedData.info.title, "onChanged event received the expected title");
- }
-
- function checkOnMoved(id, parentId, oldParentId, index, oldIndex) {
- let movedData = collectedEvents.pop();
- browser.test.assertEq("onMoved", movedData.event, "onMoved was the last event received");
- browser.test.assertEq(id, movedData.id, "onMoved event received the expected id");
- let info = movedData.info;
- browser.test.assertEq(parentId, info.parentId, "onMoved event received the expected parentId");
- browser.test.assertEq(oldParentId, info.oldParentId, "onMoved event received the expected oldParentId");
- browser.test.assertEq(index, info.index, "onMoved event received the expected index");
- browser.test.assertEq(oldIndex, info.oldIndex, "onMoved event received the expected oldIndex");
- }
-
- function checkOnRemoved(id, parentId, index, url) {
- let removedData = collectedEvents.pop();
- browser.test.assertEq("onRemoved", removedData.event, "onRemoved was the last event received");
- browser.test.assertEq(id, removedData.id, "onRemoved event received the expected id");
- let info = removedData.info;
- browser.test.assertEq(parentId, removedData.info.parentId, "onRemoved event received the expected parentId");
- browser.test.assertEq(index, removedData.info.index, "onRemoved event received the expected index");
- let node = info.node;
- browser.test.assertEq(id, node.id, "onRemoved event received the expected node id");
- browser.test.assertEq(parentId, node.parentId, "onRemoved event received the expected node parentId");
- browser.test.assertEq(index, node.index, "onRemoved event received the expected node index");
- browser.test.assertEq(url, node.url, "onRemoved event received the expected node url");
- }
-
- browser.bookmarks.onChanged.addListener((id, info) => {
- collectedEvents.push({event: "onChanged", id, info});
- });
-
- browser.bookmarks.onCreated.addListener((id, bookmark) => {
- collectedEvents.push({event: "onCreated", id, bookmark});
- });
-
- browser.bookmarks.onMoved.addListener((id, info) => {
- collectedEvents.push({event: "onMoved", id, info});
- });
-
- browser.bookmarks.onRemoved.addListener((id, info) => {
- collectedEvents.push({event: "onRemoved", id, info});
- });
-
- browser.bookmarks.get(["not-a-bookmark-guid"]).then(expectedError, invalidGuidError => {
- browser.test.assertTrue(
- invalidGuidError.message.includes("Invalid value for property 'guid': not-a-bookmark-guid"),
- "Expected error thrown when trying to get a bookmark using an invalid guid"
- );
-
- return browser.bookmarks.get([nonExistentId]).then(expectedError, nonExistentIdError => {
- browser.test.assertTrue(
- nonExistentIdError.message.includes("Bookmark not found"),
- "Expected error thrown when trying to get a bookmark using a non-existent Id"
- );
- });
- }).then(() => {
- return browser.bookmarks.search({});
- }).then(results => {
- initialBookmarkCount = results.length;
- return browser.bookmarks.create({title: "test bookmark", url: "http://example.org"});
- }).then(result => {
- ourId = result.id;
- checkOurBookmark(result);
- browser.test.assertEq(1, collectedEvents.length, "1 expected event received");
- checkOnCreated(ourId, bookmarkGuids.unfiledGuid, 0, "test bookmark", "http://example.org/", result.dateAdded);
-
- return browser.bookmarks.get(ourId);
- }).then(results => {
- browser.test.assertEq(results.length, 1);
- checkOurBookmark(results[0]);
-
- unsortedId = results[0].parentId;
- return browser.bookmarks.get(unsortedId);
- }).then(results => {
- let folder = results[0];
- browser.test.assertEq(1, results.length, "1 bookmark was returned");
-
- browser.test.assertEq(unsortedId, folder.id, "Folder has the expected id");
- browser.test.assertTrue("parentId" in folder, "Folder has a parentId");
- browser.test.assertTrue("index" in folder, "Folder has an index");
- browser.test.assertFalse("url" in folder, "Folder does not have a url");
- browser.test.assertEq("Other Bookmarks", folder.title, "Folder has the expected title");
- browser.test.assertTrue("dateAdded" in folder, "Folder has a dateAdded");
- browser.test.assertTrue("dateGroupModified" in folder, "Folder has a dateGroupModified");
- browser.test.assertFalse("unmodifiable" in folder, "Folder is not unmodifiable"); // TODO: Do we want to enable this?
-
- return browser.bookmarks.getChildren(unsortedId);
- }).then(results => {
- browser.test.assertEq(1, results.length, "The folder has one child");
- checkOurBookmark(results[0]);
-
- return browser.bookmarks.update(nonExistentId, {title: "new test title"}).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("No bookmarks found for the provided GUID"),
- "Expected error thrown when trying to update a non-existent bookmark"
- );
-
- return browser.bookmarks.update(ourId, {title: "new test title", url: "http://example.com/"});
- });
- }).then(result => {
- browser.test.assertEq("new test title", result.title, "Updated bookmark has the expected title");
- browser.test.assertEq("http://example.com/", result.url, "Updated bookmark has the expected URL");
- browser.test.assertEq(ourId, result.id, "Updated bookmark has the expected id");
-
- browser.test.assertEq(2, collectedEvents.length, "2 expected events received");
- checkOnChanged(ourId, "http://example.com/", "new test title");
-
- return Promise.resolve().then(() => {
- return browser.bookmarks.update(ourId, {url: "this is not a valid url"});
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Invalid bookmark:"),
- "Expected error thrown when trying update with an invalid url"
- );
- return browser.bookmarks.getTree();
- });
- }).then(results => {
- browser.test.assertEq(1, results.length, "getTree returns one result");
- let bookmark = results[0].children.find(bookmarkItem => bookmarkItem.id == unsortedId);
- browser.test.assertEq(
- "Other Bookmarks",
- bookmark.title,
- "Folder returned from getTree has the expected title"
- );
-
- return browser.bookmarks.create({parentId: "invalid"}).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Invalid bookmark"),
- "Expected error thrown when trying to create a bookmark with an invalid parentId"
- );
- browser.test.assertTrue(
- error.message.includes(`"parentGuid":"invalid"`),
- "Expected error thrown when trying to create a bookmark with an invalid parentId"
- );
- });
- }).then(() => {
- return browser.bookmarks.remove(ourId);
- }).then(result => {
- browser.test.assertEq(undefined, result, "Removing a bookmark returns undefined");
-
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnRemoved(ourId, bookmarkGuids.unfiledGuid, 0, "http://example.com/");
-
- return browser.bookmarks.get(ourId).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Bookmark not found"),
- "Expected error thrown when trying to get a removed bookmark"
- );
- });
- }).then(() => {
- return browser.bookmarks.remove(nonExistentId).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("No bookmarks found for the provided GUID"),
- "Expected error thrown when trying removed a non-existent bookmark"
- );
- });
- }).then(() => {
- // test bookmarks.search
- return Promise.all([
- browser.bookmarks.create({title: "MØzillä", url: "http://møzîllä.örg/"}),
- browser.bookmarks.create({title: "Example", url: "http://example.org/"}),
- browser.bookmarks.create({title: "Mozilla Folder"}),
- browser.bookmarks.create({title: "EFF", url: "http://eff.org/"}),
- browser.bookmarks.create({title: "Menu Item", url: "http://menu.org/", parentId: bookmarkGuids.menuGuid}),
- browser.bookmarks.create({title: "Toolbar Item", url: "http://toolbar.org/", parentId: bookmarkGuids.toolbarGuid}),
- ]);
- }).then(results => {
- browser.test.assertEq(6, collectedEvents.length, "6 expected events received");
- checkOnCreated(results[5].id, bookmarkGuids.toolbarGuid, 0, "Toolbar Item", "http://toolbar.org/", results[5].dateAdded);
- checkOnCreated(results[4].id, bookmarkGuids.menuGuid, 0, "Menu Item", "http://menu.org/", results[4].dateAdded);
- checkOnCreated(results[3].id, bookmarkGuids.unfiledGuid, 0, "EFF", "http://eff.org/", results[3].dateAdded);
- checkOnCreated(results[2].id, bookmarkGuids.unfiledGuid, 0, "Mozilla Folder", undefined, results[2].dateAdded);
- checkOnCreated(results[1].id, bookmarkGuids.unfiledGuid, 0, "Example", "http://example.org/", results[1].dateAdded);
- checkOnCreated(results[0].id, bookmarkGuids.unfiledGuid, 0, "MØzillä", "http://møzîllä.örg/", results[0].dateAdded);
-
- for (let result of results) {
- if (result.title !== "Mozilla Folder") {
- createdBookmarks.add(result.id);
- }
- }
- let folderResult = results[2];
- createdFolderId = folderResult.id;
- return Promise.all([
- browser.bookmarks.create({title: "Mozilla", url: "http://allizom.org/", parentId: createdFolderId}),
- browser.bookmarks.create({title: "Mozilla Corporation", url: "http://allizom.com/", parentId: createdFolderId}),
- browser.bookmarks.create({title: "Firefox", url: "http://allizom.org/firefox/", parentId: createdFolderId}),
- ]).then(newBookmarks => {
- browser.test.assertEq(3, collectedEvents.length, "3 expected events received");
- checkOnCreated(newBookmarks[2].id, createdFolderId, 0, "Firefox", "http://allizom.org/firefox/", newBookmarks[2].dateAdded);
- checkOnCreated(newBookmarks[1].id, createdFolderId, 0, "Mozilla Corporation", "http://allizom.com/", newBookmarks[1].dateAdded);
- checkOnCreated(newBookmarks[0].id, createdFolderId, 0, "Mozilla", "http://allizom.org/", newBookmarks[0].dateAdded);
-
- return browser.bookmarks.create({
- title: "About Mozilla",
- url: "http://allizom.org/about/",
- parentId: createdFolderId,
- index: 1,
- });
- }).then(result => {
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnCreated(result.id, createdFolderId, 1, "About Mozilla", "http://allizom.org/about/", result.dateAdded);
-
- // returns all items on empty object
- return browser.bookmarks.search({});
- }).then(bookmarksSearchResults => {
- browser.test.assertTrue(bookmarksSearchResults.length >= 9, "At least as many bookmarks as added were returned by search({})");
-
- return Promise.resolve().then(() => {
- return browser.bookmarks.remove(createdFolderId);
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Cannot remove a non-empty folder"),
- "Expected error thrown when trying to remove a non-empty folder"
- );
- return browser.bookmarks.getSubTree(createdFolderId);
- });
- });
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of nodes returned by getSubTree");
- browser.test.assertEq("Mozilla Folder", results[0].title, "Folder has the expected title");
- let children = results[0].children;
- browser.test.assertEq(4, children.length, "Expected number of bookmarks returned by getSubTree");
- browser.test.assertEq("Firefox", children[0].title, "Bookmark has the expected title");
- browser.test.assertEq("About Mozilla", children[1].title, "Bookmark has the expected title");
- browser.test.assertEq(1, children[1].index, "Bookmark has the expected index");
- browser.test.assertEq("Mozilla Corporation", children[2].title, "Bookmark has the expected title");
- browser.test.assertEq("Mozilla", children[3].title, "Bookmark has the expected title");
-
- // throws an error for invalid query objects
- Promise.resolve().then(() => {
- return browser.bookmarks.search();
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Incorrect argument types for bookmarks.search"),
- "Expected error thrown when trying to search with no arguments"
- );
- });
-
- Promise.resolve().then(() => {
- return browser.bookmarks.search(null);
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Incorrect argument types for bookmarks.search"),
- "Expected error thrown when trying to search with null as an argument"
- );
- });
-
- Promise.resolve().then(() => {
- return browser.bookmarks.search(function() {});
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Incorrect argument types for bookmarks.search"),
- "Expected error thrown when trying to search with a function as an argument"
- );
- });
-
- Promise.resolve().then(() => {
- return browser.bookmarks.search({banana: "banana"});
- }).then(expectedError, error => {
- let substr = `an unexpected "banana" property`;
- browser.test.assertTrue(
- error.message.includes(substr),
- `Expected error ${JSON.stringify(error.message)} to contain ${JSON.stringify(substr)}`);
- });
-
- Promise.resolve().then(() => {
- return browser.bookmarks.search({url: "spider-man vs. batman"});
- }).then(expectedError, error => {
- let substr = 'must match the format "url"';
- browser.test.assertTrue(
- error.message.includes(substr),
- `Expected error ${JSON.stringify(error.message)} to contain ${JSON.stringify(substr)}`);
- });
-
- // queries the full url
- return browser.bookmarks.search("http://example.org/");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for url search");
- checkBookmark({title: "Example", url: "http://example.org/", index: 2}, results[0]);
-
- // queries a partial url
- return browser.bookmarks.search("example.org");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for url search");
- checkBookmark({title: "Example", url: "http://example.org/", index: 2}, results[0]);
-
- // queries the title
- return browser.bookmarks.search("EFF");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for title search");
- checkBookmark({title: "EFF", url: "http://eff.org/", index: 0, parentId: bookmarkGuids.unfiledGuid}, results[0]);
-
- // finds menu items
- return browser.bookmarks.search("Menu Item");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for menu item search");
- checkBookmark({title: "Menu Item", url: "http://menu.org/", index: 0, parentId: bookmarkGuids.menuGuid}, results[0]);
-
- // finds toolbar items
- return browser.bookmarks.search("Toolbar Item");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for toolbar item search");
- checkBookmark({title: "Toolbar Item", url: "http://toolbar.org/", index: 0, parentId: bookmarkGuids.toolbarGuid}, results[0]);
-
- // finds folders
- return browser.bookmarks.search("Mozilla Folder");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of folders returned");
- browser.test.assertEq("Mozilla Folder", results[0].title, "Folder has the expected title");
-
- // is case-insensitive
- return browser.bookmarks.search("corporation");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returnedfor case-insensitive search");
- browser.test.assertEq("Mozilla Corporation", results[0].title, "Bookmark has the expected title");
-
- // is case-insensitive for non-ascii
- return browser.bookmarks.search("MøZILLÄ");
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for non-ascii search");
- browser.test.assertEq("MØzillä", results[0].title, "Bookmark has the expected title");
-
- // returns multiple results
- return browser.bookmarks.search("allizom");
- }).then(results => {
- browser.test.assertEq(4, results.length, "Expected number of multiple results returned");
- browser.test.assertEq("Mozilla", results[0].title, "Bookmark has the expected title");
- browser.test.assertEq("Mozilla Corporation", results[1].title, "Bookmark has the expected title");
- browser.test.assertEq("Firefox", results[2].title, "Bookmark has the expected title");
- browser.test.assertEq("About Mozilla", results[3].title, "Bookmark has the expected title");
-
- // accepts a url field
- return browser.bookmarks.search({url: "http://allizom.com/"});
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for url field");
- checkBookmark({title: "Mozilla Corporation", url: "http://allizom.com/", index: 2}, results[0]);
-
- // normalizes urls
- return browser.bookmarks.search({url: "http://allizom.com"});
- }).then(results => {
- browser.test.assertEq(results.length, 1, "Expected number of results returned for normalized url field");
- checkBookmark({title: "Mozilla Corporation", url: "http://allizom.com/", index: 2}, results[0]);
-
- // normalizes urls even more
- return browser.bookmarks.search({url: "http:allizom.com"});
- }).then(results => {
- browser.test.assertEq(results.length, 1, "Expected number of results returned for normalized url field");
- checkBookmark({title: "Mozilla Corporation", url: "http://allizom.com/", index: 2}, results[0]);
-
- // accepts a title field
- return browser.bookmarks.search({title: "Mozilla"});
- }).then(results => {
- browser.test.assertEq(results.length, 1, "Expected number of results returned for title field");
- checkBookmark({title: "Mozilla", url: "http://allizom.org/", index: 3}, results[0]);
-
- // can combine title and query
- return browser.bookmarks.search({title: "Mozilla", query: "allizom"});
- }).then(results => {
- browser.test.assertEq(1, results.length, "Expected number of results returned for title and query fields");
- checkBookmark({title: "Mozilla", url: "http://allizom.org/", index: 3}, results[0]);
-
- // uses AND conditions
- return browser.bookmarks.search({title: "EFF", query: "allizom"});
- }).then(results => {
- browser.test.assertEq(
- 0,
- results.length,
- "Expected number of results returned for non-matching title and query fields"
- );
-
- // returns an empty array on item not found
- return browser.bookmarks.search("microsoft");
- }).then(results => {
- browser.test.assertEq(0, results.length, "Expected number of results returned for non-matching search");
-
- return Promise.resolve().then(() => {
- return browser.bookmarks.getRecent("");
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Incorrect argument types for bookmarks.getRecent"),
- "Expected error thrown when calling getRecent with an empty string"
- );
- });
- }).then(() => {
- return Promise.resolve().then(() => {
- return browser.bookmarks.getRecent(1.234);
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Incorrect argument types for bookmarks.getRecent"),
- "Expected error thrown when calling getRecent with a decimal number"
- );
- });
- }).then(() => {
- return Promise.all([
- browser.bookmarks.search("corporation"),
- browser.bookmarks.getChildren(bookmarkGuids.menuGuid),
- ]);
- }).then(results => {
- let corporationBookmark = results[0][0];
- let childCount = results[1].length;
-
- browser.test.assertEq(2, corporationBookmark.index, "Bookmark has the expected index");
-
- return browser.bookmarks.move(corporationBookmark.id, {index: 0}).then(result => {
- browser.test.assertEq(0, result.index, "Bookmark has the expected index");
-
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnMoved(corporationBookmark.id, createdFolderId, createdFolderId, 0, 2);
-
- return browser.bookmarks.move(corporationBookmark.id, {parentId: bookmarkGuids.menuGuid});
- }).then(result => {
- browser.test.assertEq(bookmarkGuids.menuGuid, result.parentId, "Bookmark has the expected parent");
- browser.test.assertEq(childCount, result.index, "Bookmark has the expected index");
-
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnMoved(corporationBookmark.id, bookmarkGuids.menuGuid, createdFolderId, 1, 0);
-
- return browser.bookmarks.move(corporationBookmark.id, {index: 0});
- }).then(result => {
- browser.test.assertEq(bookmarkGuids.menuGuid, result.parentId, "Bookmark has the expected parent");
- browser.test.assertEq(0, result.index, "Bookmark has the expected index");
-
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnMoved(corporationBookmark.id, bookmarkGuids.menuGuid, bookmarkGuids.menuGuid, 0, 1);
-
- return browser.bookmarks.move(corporationBookmark.id, {parentId: bookmarkGuids.toolbarGuid, index: 1});
- }).then(result => {
- browser.test.assertEq(bookmarkGuids.toolbarGuid, result.parentId, "Bookmark has the expected parent");
- browser.test.assertEq(1, result.index, "Bookmark has the expected index");
-
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnMoved(corporationBookmark.id, bookmarkGuids.toolbarGuid, bookmarkGuids.menuGuid, 1, 0);
-
- createdBookmarks.add(corporationBookmark.id);
- });
- }).then(() => {
- return browser.bookmarks.getRecent(4);
- }).then(results => {
- browser.test.assertEq(4, results.length, "Expected number of results returned by getRecent");
- let prevDate = results[0].dateAdded;
- for (let bookmark of results) {
- browser.test.assertTrue(bookmark.dateAdded <= prevDate, "The recent bookmarks are sorted by dateAdded");
- prevDate = bookmark.dateAdded;
- }
- let bookmarksByTitle = results.sort((a, b) => {
- return a.title.localeCompare(b.title);
- });
- browser.test.assertEq("About Mozilla", bookmarksByTitle[0].title, "Bookmark has the expected title");
- browser.test.assertEq("Firefox", bookmarksByTitle[1].title, "Bookmark has the expected title");
- browser.test.assertEq("Mozilla", bookmarksByTitle[2].title, "Bookmark has the expected title");
- browser.test.assertEq("Mozilla Corporation", bookmarksByTitle[3].title, "Bookmark has the expected title");
-
- return browser.bookmarks.search({});
- }).then(results => {
- let startBookmarkCount = results.length;
-
- return browser.bookmarks.search({title: "Mozilla Folder"}).then(result => {
- return browser.bookmarks.removeTree(result[0].id);
- }).then(() => {
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnRemoved(createdFolderId, bookmarkGuids.unfiledGuid, 1);
-
- return browser.bookmarks.search({}).then(searchResults => {
- browser.test.assertEq(
- startBookmarkCount - 4,
- searchResults.length,
- "Expected number of results returned after removeTree");
- });
- });
- }).then(() => {
- return browser.bookmarks.create({title: "Empty Folder"});
- }).then(result => {
- let emptyFolderId = result.id;
-
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnCreated(emptyFolderId, bookmarkGuids.unfiledGuid, 3, "Empty Folder", undefined, result.dateAdded);
-
- browser.test.assertEq("Empty Folder", result.title, "Folder has the expected title");
- return browser.bookmarks.remove(emptyFolderId).then(() => {
- browser.test.assertEq(1, collectedEvents.length, "1 expected events received");
- checkOnRemoved(emptyFolderId, bookmarkGuids.unfiledGuid, 3);
-
- return browser.bookmarks.get(emptyFolderId).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("Bookmark not found"),
- "Expected error thrown when trying to get a removed folder"
- );
- });
- });
- }).then(() => {
- return browser.bookmarks.getChildren(nonExistentId).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("root is null"),
- "Expected error thrown when trying to getChildren for a non-existent folder"
- );
- });
- }).then(() => {
- return Promise.resolve().then(() => {
- return browser.bookmarks.move(nonExistentId, {});
- }).then(expectedError, error => {
- browser.test.assertTrue(
- error.message.includes("No bookmarks found for the provided GUID"),
- "Expected error thrown when calling move with a non-existent bookmark"
- );
- });
- }).then(() => {
- // remove all created bookmarks
- let promises = Array.from(createdBookmarks, guid => browser.bookmarks.remove(guid));
- return Promise.all(promises);
- }).then(() => {
- browser.test.assertEq(createdBookmarks.size, collectedEvents.length, "expected number of events received");
-
- return browser.bookmarks.search({});
- }).then(results => {
- browser.test.assertEq(initialBookmarkCount, results.length, "All created bookmarks have been removed");
-
- return browser.test.notifyPass("bookmarks");
- }).catch(error => {
- browser.test.fail(`Error: ${String(error)} :: ${error.stack}`);
- browser.test.notifyFail("bookmarks");
- });
-}
-
-let extensionData = {
- background: `(${backgroundScript})()`,
- manifest: {
- permissions: ["bookmarks"],
- },
-};
-
-add_task(function* test_contentscript() {
- let extension = ExtensionTestUtils.loadExtension(extensionData);
- yield extension.startup();
- yield extension.awaitFinish("bookmarks");
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/xpcshell/test_ext_history.js b/browser/components/extensions/test/xpcshell/test_ext_history.js
deleted file mode 100644
index 78df33151..000000000
--- a/browser/components/extensions/test/xpcshell/test_ext_history.js
+++ /dev/null
@@ -1,487 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ExtensionUtils",
- "resource://gre/modules/ExtensionUtils.jsm");
-
-add_task(function* test_delete() {
- function background() {
- let historyClearedCount = 0;
- let removedUrls = [];
-
- browser.history.onVisitRemoved.addListener(data => {
- if (data.allHistory) {
- historyClearedCount++;
- browser.test.assertEq(0, data.urls.length, "onVisitRemoved received an empty urls array");
- } else {
- browser.test.assertEq(1, data.urls.length, "onVisitRemoved received one URL");
- removedUrls.push(data.urls[0]);
- }
- });
-
- browser.test.onMessage.addListener((msg, arg) => {
- if (msg === "delete-url") {
- browser.history.deleteUrl({url: arg}).then(result => {
- browser.test.assertEq(undefined, result, "browser.history.deleteUrl returns nothing");
- browser.test.sendMessage("url-deleted");
- });
- } else if (msg === "delete-range") {
- browser.history.deleteRange(arg).then(result => {
- browser.test.assertEq(undefined, result, "browser.history.deleteRange returns nothing");
- browser.test.sendMessage("range-deleted", removedUrls);
- });
- } else if (msg === "delete-all") {
- browser.history.deleteAll().then(result => {
- browser.test.assertEq(undefined, result, "browser.history.deleteAll returns nothing");
- browser.test.sendMessage("history-cleared", [historyClearedCount, removedUrls]);
- });
- }
- });
-
- browser.test.sendMessage("ready");
- }
-
- const BASE_URL = "http://mozilla.com/test_history/";
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["history"],
- },
- background: `(${background})()`,
- });
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
- yield PlacesTestUtils.clearHistory();
-
- let historyClearedCount;
- let visits = [];
- let visitDate = new Date(1999, 9, 9, 9, 9).getTime();
-
- function pushVisit(subvisits) {
- visitDate += 1000;
- subvisits.push({date: new Date(visitDate)});
- }
-
- // Add 5 visits for one uri and 3 visits for 3 others
- for (let i = 0; i < 4; ++i) {
- let visit = {
- url: `${BASE_URL}${i}`,
- title: "visit " + i,
- visits: [],
- };
- if (i === 0) {
- for (let j = 0; j < 5; ++j) {
- pushVisit(visit.visits);
- }
- } else {
- pushVisit(visit.visits);
- }
- visits.push(visit);
- }
-
- yield PlacesUtils.history.insertMany(visits);
- equal((yield PlacesTestUtils.visitsInDB(visits[0].url)), 5, "5 visits for uri found in history database");
-
- let testUrl = visits[2].url;
- ok((yield PlacesTestUtils.isPageInDB(testUrl)), "expected url found in history database");
-
- extension.sendMessage("delete-url", testUrl);
- yield extension.awaitMessage("url-deleted");
- equal((yield PlacesTestUtils.isPageInDB(testUrl)), false, "expected url not found in history database");
-
- // delete 3 of the 5 visits for url 1
- let filter = {
- startTime: visits[0].visits[0].date,
- endTime: visits[0].visits[2].date,
- };
-
- extension.sendMessage("delete-range", filter);
- let removedUrls = yield extension.awaitMessage("range-deleted");
- ok(!removedUrls.includes(visits[0].url), `${visits[0].url} not received by onVisitRemoved`);
- ok((yield PlacesTestUtils.isPageInDB(visits[0].url)), "expected uri found in history database");
- equal((yield PlacesTestUtils.visitsInDB(visits[0].url)), 2, "2 visits for uri found in history database");
- ok((yield PlacesTestUtils.isPageInDB(visits[1].url)), "expected uri found in history database");
- equal((yield PlacesTestUtils.visitsInDB(visits[1].url)), 1, "1 visit for uri found in history database");
-
- // delete the rest of the visits for url 1, and the visit for url 2
- filter.startTime = visits[0].visits[0].date;
- filter.endTime = visits[1].visits[0].date;
-
- extension.sendMessage("delete-range", filter);
- yield extension.awaitMessage("range-deleted");
-
- equal((yield PlacesTestUtils.isPageInDB(visits[0].url)), false, "expected uri not found in history database");
- equal((yield PlacesTestUtils.visitsInDB(visits[0].url)), 0, "0 visits for uri found in history database");
- equal((yield PlacesTestUtils.isPageInDB(visits[1].url)), false, "expected uri not found in history database");
- equal((yield PlacesTestUtils.visitsInDB(visits[1].url)), 0, "0 visits for uri found in history database");
-
- ok((yield PlacesTestUtils.isPageInDB(visits[3].url)), "expected uri found in history database");
-
- extension.sendMessage("delete-all");
- [historyClearedCount, removedUrls] = yield extension.awaitMessage("history-cleared");
- equal(PlacesUtils.history.hasHistoryEntries, false, "history is empty");
- equal(historyClearedCount, 2, "onVisitRemoved called for each clearing of history");
- equal(removedUrls.length, 3, "onVisitRemoved called the expected number of times");
- for (let i = 1; i < 3; ++i) {
- let url = visits[i].url;
- ok(removedUrls.includes(url), `${url} received by onVisitRemoved`);
- }
- yield extension.unload();
-});
-
-add_task(function* test_search() {
- const SINGLE_VISIT_URL = "http://example.com/";
- const DOUBLE_VISIT_URL = "http://example.com/2/";
- const MOZILLA_VISIT_URL = "http://mozilla.com/";
- const REFERENCE_DATE = new Date();
- // pages/visits to add via History.insert
- const PAGE_INFOS = [
- {
- url: SINGLE_VISIT_URL,
- title: `test visit for ${SINGLE_VISIT_URL}`,
- visits: [
- {date: new Date(Number(REFERENCE_DATE) - 1000)},
- ],
- },
- {
- url: DOUBLE_VISIT_URL,
- title: `test visit for ${DOUBLE_VISIT_URL}`,
- visits: [
- {date: REFERENCE_DATE},
- {date: new Date(Number(REFERENCE_DATE) - 2000)},
- ],
- },
- {
- url: MOZILLA_VISIT_URL,
- title: `test visit for ${MOZILLA_VISIT_URL}`,
- visits: [
- {date: new Date(Number(REFERENCE_DATE) - 3000)},
- ],
- },
- ];
-
- function background(BGSCRIPT_REFERENCE_DATE) {
- const futureTime = Date.now() + 24 * 60 * 60 * 1000;
-
- browser.test.onMessage.addListener(msg => {
- browser.history.search({text: ""}).then(results => {
- browser.test.sendMessage("empty-search", results);
- return browser.history.search({text: "mozilla.com"});
- }).then(results => {
- browser.test.sendMessage("text-search", results);
- return browser.history.search({text: "example.com", maxResults: 1});
- }).then(results => {
- browser.test.sendMessage("max-results-search", results);
- return browser.history.search({text: "", startTime: BGSCRIPT_REFERENCE_DATE - 2000, endTime: BGSCRIPT_REFERENCE_DATE - 1000});
- }).then(results => {
- browser.test.sendMessage("date-range-search", results);
- return browser.history.search({text: "", startTime: futureTime});
- }).then(results => {
- browser.test.assertEq(0, results.length, "no results returned for late start time");
- return browser.history.search({text: "", endTime: 0});
- }).then(results => {
- browser.test.assertEq(0, results.length, "no results returned for early end time");
- return browser.history.search({text: "", startTime: Date.now(), endTime: 0});
- }).then(results => {
- browser.test.fail("history.search rejects with startTime that is after the endTime");
- }, error => {
- browser.test.assertEq(
- "The startTime cannot be after the endTime",
- error.message,
- "history.search rejects with startTime that is after the endTime");
- }).then(() => {
- browser.test.notifyPass("search");
- });
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["history"],
- },
- background: `(${background})(${Number(REFERENCE_DATE)})`,
- });
-
- function findResult(url, results) {
- return results.find(r => r.url === url);
- }
-
- function checkResult(results, url, expectedCount) {
- let result = findResult(url, results);
- notEqual(result, null, `history.search result was found for ${url}`);
- equal(result.visitCount, expectedCount, `history.search reports ${expectedCount} visit(s)`);
- equal(result.title, `test visit for ${url}`, "title for search result is correct");
- }
-
- yield extension.startup();
- yield extension.awaitMessage("ready");
- yield PlacesTestUtils.clearHistory();
-
- yield PlacesUtils.history.insertMany(PAGE_INFOS);
-
- extension.sendMessage("check-history");
-
- let results = yield extension.awaitMessage("empty-search");
- equal(results.length, 3, "history.search with empty text returned 3 results");
- checkResult(results, SINGLE_VISIT_URL, 1);
- checkResult(results, DOUBLE_VISIT_URL, 2);
- checkResult(results, MOZILLA_VISIT_URL, 1);
-
- results = yield extension.awaitMessage("text-search");
- equal(results.length, 1, "history.search with specific text returned 1 result");
- checkResult(results, MOZILLA_VISIT_URL, 1);
-
- results = yield extension.awaitMessage("max-results-search");
- equal(results.length, 1, "history.search with maxResults returned 1 result");
- checkResult(results, DOUBLE_VISIT_URL, 2);
-
- results = yield extension.awaitMessage("date-range-search");
- equal(results.length, 2, "history.search with a date range returned 2 result");
- checkResult(results, DOUBLE_VISIT_URL, 2);
- checkResult(results, SINGLE_VISIT_URL, 1);
-
- yield extension.awaitFinish("search");
- yield extension.unload();
- yield PlacesTestUtils.clearHistory();
-});
-
-add_task(function* test_add_url() {
- function background() {
- const TEST_DOMAIN = "http://example.com/";
-
- browser.test.onMessage.addListener((msg, testData) => {
- let [details, type] = testData;
- details.url = details.url || `${TEST_DOMAIN}${type}`;
- if (msg === "add-url") {
- details.title = `Title for ${type}`;
- browser.history.addUrl(details).then(() => {
- return browser.history.search({text: details.url});
- }).then(results => {
- browser.test.assertEq(1, results.length, "1 result found when searching for added URL");
- browser.test.sendMessage("url-added", {details, result: results[0]});
- });
- } else if (msg === "expect-failure") {
- let expectedMsg = testData[2];
- browser.history.addUrl(details).then(() => {
- browser.test.fail(`Expected error thrown for ${type}`);
- }, error => {
- browser.test.assertTrue(
- error.message.includes(expectedMsg),
- `"Expected error thrown when trying to add a URL with ${type}`
- );
- browser.test.sendMessage("add-failed");
- });
- }
- });
-
- browser.test.sendMessage("ready");
- }
-
- let addTestData = [
- [{}, "default"],
- [{visitTime: new Date()}, "with_date"],
- [{visitTime: Date.now()}, "with_ms_number"],
- [{visitTime: new Date().toISOString()}, "with_iso_string"],
- [{transition: "typed"}, "valid_transition"],
- ];
-
- let failTestData = [
- [{transition: "generated"}, "an invalid transition", "|generated| is not a supported transition for history"],
- [{visitTime: Date.now() + 1000000}, "a future date", "cannot be a future date"],
- [{url: "about.config"}, "an invalid url", "about.config is not a valid URL"],
- ];
-
- function* checkUrl(results) {
- ok((yield PlacesTestUtils.isPageInDB(results.details.url)), `${results.details.url} found in history database`);
- ok(PlacesUtils.isValidGuid(results.result.id), "URL was added with a valid id");
- equal(results.result.title, results.details.title, "URL was added with the correct title");
- if (results.details.visitTime) {
- equal(results.result.lastVisitTime,
- Number(ExtensionUtils.normalizeTime(results.details.visitTime)),
- "URL was added with the correct date");
- }
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["history"],
- },
- background: `(${background})()`,
- });
-
- yield PlacesTestUtils.clearHistory();
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- for (let data of addTestData) {
- extension.sendMessage("add-url", data);
- let results = yield extension.awaitMessage("url-added");
- yield checkUrl(results);
- }
-
- for (let data of failTestData) {
- extension.sendMessage("expect-failure", data);
- yield extension.awaitMessage("add-failed");
- }
-
- yield extension.unload();
-});
-
-add_task(function* test_get_visits() {
- function background() {
- const TEST_DOMAIN = "http://example.com/";
- const FIRST_DATE = Date.now();
- const INITIAL_DETAILS = {
- url: TEST_DOMAIN,
- visitTime: FIRST_DATE,
- transition: "link",
- };
-
- let visitIds = new Set();
-
- function checkVisit(visit, expected) {
- visitIds.add(visit.visitId);
- browser.test.assertEq(expected.visitTime, visit.visitTime, "visit has the correct visitTime");
- browser.test.assertEq(expected.transition, visit.transition, "visit has the correct transition");
- browser.history.search({text: expected.url}).then(results => {
- // all results will have the same id, so we only need to use the first one
- browser.test.assertEq(results[0].id, visit.id, "visit has the correct id");
- });
- }
-
- let details = Object.assign({}, INITIAL_DETAILS);
-
- browser.history.addUrl(details).then(() => {
- return browser.history.getVisits({url: details.url});
- }).then(results => {
- browser.test.assertEq(1, results.length, "the expected number of visits were returned");
- checkVisit(results[0], details);
- details.url = `${TEST_DOMAIN}/1/`;
- return browser.history.addUrl(details);
- }).then(() => {
- return browser.history.getVisits({url: details.url});
- }).then(results => {
- browser.test.assertEq(1, results.length, "the expected number of visits were returned");
- checkVisit(results[0], details);
- details.visitTime = FIRST_DATE - 1000;
- details.transition = "typed";
- return browser.history.addUrl(details);
- }).then(() => {
- return browser.history.getVisits({url: details.url});
- }).then(results => {
- browser.test.assertEq(2, results.length, "the expected number of visits were returned");
- checkVisit(results[0], INITIAL_DETAILS);
- checkVisit(results[1], details);
- }).then(() => {
- browser.test.assertEq(3, visitIds.size, "each visit has a unique visitId");
- browser.test.notifyPass("get-visits");
- });
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["history"],
- },
- background: `(${background})()`,
- });
-
- yield PlacesTestUtils.clearHistory();
- yield extension.startup();
-
- yield extension.awaitFinish("get-visits");
- yield extension.unload();
-});
-
-add_task(function* test_on_visited() {
- const SINGLE_VISIT_URL = "http://example.com/1/";
- const DOUBLE_VISIT_URL = "http://example.com/2/";
- let visitDate = new Date(1999, 9, 9, 9, 9).getTime();
-
- // pages/visits to add via History.insertMany
- const PAGE_INFOS = [
- {
- url: SINGLE_VISIT_URL,
- title: `visit to ${SINGLE_VISIT_URL}`,
- visits: [
- {date: new Date(visitDate)},
- ],
- },
- {
- url: DOUBLE_VISIT_URL,
- title: `visit to ${DOUBLE_VISIT_URL}`,
- visits: [
- {date: new Date(visitDate += 1000)},
- {date: new Date(visitDate += 1000)},
- ],
- },
- ];
-
- function background() {
- let onVisitedData = [];
-
- browser.history.onVisited.addListener(data => {
- if (data.url.includes("moz-extension")) {
- return;
- }
- onVisitedData.push(data);
- if (onVisitedData.length == 3) {
- browser.test.sendMessage("on-visited-data", onVisitedData);
- }
- });
-
- browser.test.sendMessage("ready");
- }
-
- let extension = ExtensionTestUtils.loadExtension({
- manifest: {
- permissions: ["history"],
- },
- background: `(${background})()`,
- });
-
- yield PlacesTestUtils.clearHistory();
- yield extension.startup();
- yield extension.awaitMessage("ready");
-
- yield PlacesUtils.history.insertMany(PAGE_INFOS);
-
- let onVisitedData = yield extension.awaitMessage("on-visited-data");
-
- function checkOnVisitedData(index, expected) {
- let onVisited = onVisitedData[index];
- ok(PlacesUtils.isValidGuid(onVisited.id), "onVisited received a valid id");
- equal(onVisited.url, expected.url, "onVisited received the expected url");
- // Title will be blank until bug 1287928 lands
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1287928
- equal(onVisited.title, "", "onVisited received a blank title");
- equal(onVisited.lastVisitTime, expected.time, "onVisited received the expected time");
- equal(onVisited.visitCount, expected.visitCount, "onVisited received the expected visitCount");
- }
-
- let expected = {
- url: PAGE_INFOS[0].url,
- title: PAGE_INFOS[0].title,
- time: PAGE_INFOS[0].visits[0].date.getTime(),
- visitCount: 1,
- };
- checkOnVisitedData(0, expected);
-
- expected.url = PAGE_INFOS[1].url;
- expected.title = PAGE_INFOS[1].title;
- expected.time = PAGE_INFOS[1].visits[0].date.getTime();
- checkOnVisitedData(1, expected);
-
- expected.time = PAGE_INFOS[1].visits[1].date.getTime();
- expected.visitCount = 2;
- checkOnVisitedData(2, expected);
-
- yield extension.unload();
-});
diff --git a/browser/components/extensions/test/xpcshell/test_ext_manifest_commands.js b/browser/components/extensions/test/xpcshell/test_ext_manifest_commands.js
deleted file mode 100644
index 4de7afe01..000000000
--- a/browser/components/extensions/test/xpcshell/test_ext_manifest_commands.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-
-add_task(function* test_manifest_commands() {
- let normalized = yield ExtensionTestUtils.normalizeManifest({
- "commands": {
- "toggle-feature": {
- "suggested_key": {"default": "Shifty+Y"},
- "description": "Send a 'toggle-feature' event to the extension",
- },
- },
- });
-
- let expectedError = (
- String.raw`commands.toggle-feature.suggested_key.default: Value must either: ` +
- String.raw`match the pattern /^\s*(Alt|Ctrl|Command|MacCtrl)\s*\+\s*(Shift\s*\+\s*)?([A-Z0-9]|Comma|Period|Home|End|PageUp|PageDown|Space|Insert|Delete|Up|Down|Left|Right)\s*$/, or ` +
- String.raw`match the pattern /^(MediaNextTrack|MediaPlayPause|MediaPrevTrack|MediaStop)$/`
- );
-
- ok(normalized.error.includes(expectedError),
- `The manifest error ${JSON.stringify(normalized.error)} must contain ${JSON.stringify(expectedError)}`);
-});
diff --git a/browser/components/extensions/test/xpcshell/test_ext_manifest_omnibox.js b/browser/components/extensions/test/xpcshell/test_ext_manifest_omnibox.js
deleted file mode 100644
index 2cb141235..000000000
--- a/browser/components/extensions/test/xpcshell/test_ext_manifest_omnibox.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-function* testKeyword(params) {
- let normalized = yield ExtensionTestUtils.normalizeManifest({
- "omnibox": {
- "keyword": params.keyword,
- },
- });
-
- if (params.expectError) {
- let expectedError = (
- String.raw`omnibox.keyword: String "${params.keyword}" ` +
- String.raw`must match /^[^?\s:]([^\s:]*[^/\s:])?$/`
- );
- ok(normalized.error.includes(expectedError),
- `The manifest error ${JSON.stringify(normalized.error)} ` +
- `must contain ${JSON.stringify(expectedError)}`);
- } else {
- equal(normalized.error, undefined, "Should not have an error");
- equal(normalized.errors.length, 0, "Should not have warnings");
- }
-}
-
-add_task(function* test_manifest_commands() {
- // accepted single character keywords
- yield testKeyword({keyword: "a", expectError: false});
- yield testKeyword({keyword: "-", expectError: false});
- yield testKeyword({keyword: "å—¨", expectError: false});
- yield testKeyword({keyword: "*", expectError: false});
- yield testKeyword({keyword: "/", expectError: false});
-
- // rejected single character keywords
- yield testKeyword({keyword: "?", expectError: true});
- yield testKeyword({keyword: " ", expectError: true});
- yield testKeyword({keyword: ":", expectError: true});
-
- // accepted multi-character keywords
- yield testKeyword({keyword: "aa", expectError: false});
- yield testKeyword({keyword: "http", expectError: false});
- yield testKeyword({keyword: "f?a", expectError: false});
- yield testKeyword({keyword: "fa?", expectError: false});
- yield testKeyword({keyword: "f/x", expectError: false});
- yield testKeyword({keyword: "/fx", expectError: false});
-
- // rejected multi-character keywords
- yield testKeyword({keyword: " a", expectError: true});
- yield testKeyword({keyword: "a ", expectError: true});
- yield testKeyword({keyword: " ", expectError: true});
- yield testKeyword({keyword: " a ", expectError: true});
- yield testKeyword({keyword: "?fx", expectError: true});
- yield testKeyword({keyword: "fx/", expectError: true});
- yield testKeyword({keyword: "f:x", expectError: true});
- yield testKeyword({keyword: "fx:", expectError: true});
- yield testKeyword({keyword: "f x", expectError: true});
-
- // miscellaneous tests
- yield testKeyword({keyword: "ã“ã‚“ã«ã¡ã¯", expectError: false});
- yield testKeyword({keyword: "http://", expectError: true});
-});
diff --git a/browser/components/extensions/test/xpcshell/test_ext_manifest_permissions.js b/browser/components/extensions/test/xpcshell/test_ext_manifest_permissions.js
deleted file mode 100644
index 2c436535d..000000000
--- a/browser/components/extensions/test/xpcshell/test_ext_manifest_permissions.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set sts=2 sw=2 et tw=80: */
-"use strict";
-
-/* globals chrome */
-
-function* testPermission(options) {
- function background(bgOptions) {
- browser.test.sendMessage("typeof-namespace", {
- browser: typeof browser[bgOptions.namespace],
- chrome: typeof chrome[bgOptions.namespace],
- });
- }
-
- let extensionDetails = {
- background: `(${background})(${JSON.stringify(options)})`,
- };
-
- let extension = ExtensionTestUtils.loadExtension(extensionDetails);
-
- yield extension.startup();
-
- let types = yield extension.awaitMessage("typeof-namespace");
- equal(types.browser, "undefined", `Type of browser.${options.namespace} without manifest entry`);
- equal(types.chrome, "undefined", `Type of chrome.${options.namespace} without manifest entry`);
-
- yield extension.unload();
-
- extensionDetails.manifest = options.manifest;
- extension = ExtensionTestUtils.loadExtension(extensionDetails);
-
- yield extension.startup();
-
- types = yield extension.awaitMessage("typeof-namespace");
- equal(types.browser, "object", `Type of browser.${options.namespace} with manifest entry`);
- equal(types.chrome, "object", `Type of chrome.${options.namespace} with manifest entry`);
-
- yield extension.unload();
-}
-
-add_task(function* test_browserAction() {
- yield testPermission({
- namespace: "browserAction",
- manifest: {
- browser_action: {},
- },
- });
-});
-
-add_task(function* test_pageAction() {
- yield testPermission({
- namespace: "pageAction",
- manifest: {
- page_action: {},
- },
- });
-});
diff --git a/browser/components/extensions/test/xpcshell/xpcshell.ini b/browser/components/extensions/test/xpcshell/xpcshell.ini
deleted file mode 100644
index b9148a697..000000000
--- a/browser/components/extensions/test/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-firefox-appdir = browser
-tags = webextensions
-
-[test_ext_bookmarks.js]
-[test_ext_history.js]
-[test_ext_manifest_commands.js]
-[test_ext_manifest_omnibox.js]
-[test_ext_manifest_permissions.js]
diff --git a/browser/components/feeds/moz.build b/browser/components/feeds/moz.build
index c22129165..b8755fcc9 100644
--- a/browser/components/feeds/moz.build
+++ b/browser/components/feeds/moz.build
@@ -4,10 +4,6 @@
# 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/.
-XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
-MOCHITEST_CHROME_MANIFESTS += ['test/chrome/chrome.ini']
-MOCHITEST_MANIFESTS += ['test/mochitest.ini']
-
JAR_MANIFESTS += ['jar.mn']
XPIDL_SOURCES += [
@@ -36,6 +32,3 @@ for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
LOCAL_INCLUDES += [
'../build',
]
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'RSS Discovery and Preview')
diff --git a/browser/components/feeds/test/.eslintrc.js b/browser/components/feeds/test/.eslintrc.js
deleted file mode 100644
index 3c788d6d6..000000000
--- a/browser/components/feeds/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/mochitest.eslintrc.js"
- ]
-};
diff --git a/browser/components/feeds/test/bug368464-data.xml b/browser/components/feeds/test/bug368464-data.xml
deleted file mode 100644
index 2745b061d..000000000
--- a/browser/components/feeds/test/bug368464-data.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
- <rdf:RDF
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://my.netscape.com/rdf/simple/0.9/">
- <channel>
- <title>Tinderbox - Firefox</title>
- <description>Build bustages for Firefox</description>
- <link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link>
- </channel>
- <image>
- <title>Bad</title>
- <url>http://tinderbox.mozilla.org/channelflames.gif</url>
- <link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link>
- </image>
- <item><title>The tree is currently closed</title><link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link></item>
-
-<item><title>MacOSX Darwin 8.8.4 qm-xserve01 dep unit test is in flames</title><link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link></item>
-</rdf:RDF>
diff --git a/browser/components/feeds/test/bug408328-data.xml b/browser/components/feeds/test/bug408328-data.xml
deleted file mode 100644
index e9385e5ab..000000000
--- a/browser/components/feeds/test/bug408328-data.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-
- <title>Example Feed</title>
- <link href="http://example.org/"/>
- <updated>2003-12-13T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
- <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-
- <entry>
-
- <title>Good item</title>
- <link href="http://example.org/first"/>
- <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
- <updated>2003-12-13T18:30:02Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
- <entry>
-
- <title>data: link</title>
- <link href="data:text/plain,Hi"/>
- <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6b</id>
- <updated>2003-12-13T18:30:03Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
- <entry>
-
- <title>javascript: link</title>
- <link href="javascript:alert('Hi')"/>
- <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6c</id>
- <updated>2003-12-13T18:30:04Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
- <entry>
-
- <title>file: link</title>
- <link href="file:///var/"/>
- <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6d</id>
- <updated>2003-12-13T18:30:05Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
- <entry>
-
- <title>chrome: link</title>
- <link href="chrome://browser/content/browser.js"/>
- <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6e</id>
- <updated>2003-12-13T18:30:06Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/feeds/test/bug436801-data.xml b/browser/components/feeds/test/bug436801-data.xml
deleted file mode 100644
index 0e45c7ed8..000000000
--- a/browser/components/feeds/test/bug436801-data.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://www.example.com/">
-
- <title type="xhtml" xml:base="/foo/bar/">
- <div xmlns="http://www.w3.org/1999/xhtml">Example of a <em>special</em> feed (<img height="20px" src="baz.png" alt="base test sprite"/>)</div>
- </title>
-
- <subtitle type="html" xml:base="/foo/bar/">
- <![CDATA[
- With a <em>special</em> subtitle (<img height="20px" src="baz.png" alt="base test sprite"/>)
- ]]>
- </subtitle>
-
- <link href="http://example.org/"/>
-
- <updated>2010-09-02T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
-
- <id>urn:uuid:22906062-ecbd-46e2-b6a7-3039506a398f</id>
-
- <entry>
- <title type="xhtml" xml:base="/foo/bar/">
- <div xmlns="http://www.w3.org/1999/xhtml">Some <abbr title="Extensible Hyper-text Mark-up Language">XHTML</abbr> examples (<img height="20px" src="baz.png" alt="base test sprite"/>)</div>
- </title>
- <id>urn:uuid:b48083a7-71a7-4c9c-8515-b7c0d22955e7</id>
- <updated>2010-09-02T18:30:02Z</updated>
- <summary>Some text.</summary>
- </entry>
-
- <entry>
- <title type="html" xml:base="/foo/bar/">
- <![CDATA[
- Some <abbr title="Hyper-text Mark-up Language">HTML</abbr> examples (<img height="20px" src="baz.png" alt="base test sprite"/>)
- ]]>
- </title>
- <id>urn:uuid:1424967a-280a-414d-b0ab-8b11c4ac1bb7</id>
- <updated>2010-09-02T18:30:02Z</updated>
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/feeds/test/bug494328-data.xml b/browser/components/feeds/test/bug494328-data.xml
deleted file mode 100644
index 58342bafc..000000000
--- a/browser/components/feeds/test/bug494328-data.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0">
- <channel>
- <title>Channel title</title>
- <description>Channel description</description>
- <link>Channel link</link>
- <item>
- <title>Episode 1</title>
- <enclosure url="http://www.example.com/podcasts/Episode%201" length="0" type="audio/x-m4a" />
- </item>
- <item>
- <title>Episode 2</title>
- <enclosure url="http://www.example.com/podcasts/Episode%20%232" length="0" type="audio/x-m4a" />
- </item>
- <item>
- <title>Episode 3</title>
- <enclosure url="http://www.example.com/podcasts/Episode%20%233/" length="0" type="audio/x-m4a" />
- </item>
- <item>
- <title>Episode 4</title>
- <enclosure url="http://www.example.com/podcasts/Is%20This%20Episode%20%234%3F" length="0" type="audio/x-m4a" />
- </item>
- </channel>
-</rss>
diff --git a/browser/components/feeds/test/bug589543-data.xml b/browser/components/feeds/test/bug589543-data.xml
deleted file mode 100644
index 0e700b6d8..000000000
--- a/browser/components/feeds/test/bug589543-data.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-
- <title>Example Feed</title>
- <link href="http://example.org/"/>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
- <id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
-
- <entry>
-
- <title>Item</title>
- <link href="http://example.org/first"/>
- <id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/feeds/test/chrome/.eslintrc.js b/browser/components/feeds/test/chrome/.eslintrc.js
deleted file mode 100644
index 8c0f4f574..000000000
--- a/browser/components/feeds/test/chrome/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/chrome.eslintrc.js"
- ]
-};
diff --git a/browser/components/feeds/test/chrome/chrome.ini b/browser/components/feeds/test/chrome/chrome.ini
deleted file mode 100644
index 7bad142ab..000000000
--- a/browser/components/feeds/test/chrome/chrome.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[DEFAULT]
-support-files = sample_feed.atom
- !/browser/components/feeds/test/bug408328-data.xml
- !/browser/components/feeds/test/valid-feed.xml
- !/browser/components/feeds/test/valid-unsniffable-feed.xml
-
-[test_423060.xul]
-[test_bug368464.html]
-[test_bug408328.html]
-[test_maxSniffing.html]
diff --git a/browser/components/feeds/test/chrome/sample_feed.atom b/browser/components/feeds/test/chrome/sample_feed.atom
deleted file mode 100644
index add75efb4..000000000
--- a/browser/components/feeds/test/chrome/sample_feed.atom
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-
- <title>Example Feed</title>
- <link href="http://example.org/"/>
- <updated>2003-12-13T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
- <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-
- <entry>
-
- <title>Atom-Powered Robots Run Amok</title>
- <link href="http://example.org/2003/12/13/atom03"/>
- <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
- <updated>2003-12-13T18:30:02Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/feeds/test/chrome/test_423060.xul b/browser/components/feeds/test/chrome/test_423060.xul
deleted file mode 100644
index 465cf2dd2..000000000
--- a/browser/components/feeds/test/chrome/test_423060.xul
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
- href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Make sure feed preview works when a default reader is selected"
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <script type="application/javascript">
- SimpleTest.waitForExplicitFinish();
-
- const Cc = Components.classes;
- const Ci = Components.interfaces;
-
- var wccrID = "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
- /* abort the test if web feed handlers are not available */
- if (!Cc[wccrID])
- SimpleTest.finish()
-
- /* Turn off the first run UI */
- var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
- prefBranch.setBoolPref("browser.feeds.showFirstRunUI", false);
-
- /* register a handler for the feed type */
- const MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
- var handlerPage = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/demohandler.html?feedurl=%s";
- var wccr = Cc[wccrID].getService(Ci.nsIWebContentConverterService);
- wccr.registerContentHandler(MAYBE_FEED, handlerPage, "Demo handler", null);
- var demoHandler = wccr.getWebContentHandlerByURI(MAYBE_FEED, handlerPage);
- wccr.setAutoHandler(MAYBE_FEED, demoHandler);
-
- /* Don't show the preview page */
- prefBranch.setCharPref("browser.feeds.handler", "reader");
-
- function finishUp() {
- var theframe = document.getElementById('theframe');
- var previewURL = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/demohandler.html?feedurl=http%3A%2F%2Fmochi.test%3A8888%2Ftests%2Ftoolkit%2Fcomponents%2Fplaces%2Ftests%2Fchrome%2Fsample_feed.atom";
- is(theframe.contentDocument.URL, previewURL);
-
- /* remove our demoHandler */
- wccr.setAutoHandler(MAYBE_FEED, null);
- wccr.removeContentHandler(MAYBE_FEED, handlerPage);
- prefBranch.setCharPref("browser.feeds.handler", "ask");
- prefBranch.setBoolPref("browser.feeds.showFirstRunUI", true);
-
- SimpleTest.finish();
- }
- </script>
- <html:iframe src="http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/sample_feed.atom" height="400px"
- id="theframe" onload="finishUp();">
- </html:iframe>
-</window>
diff --git a/browser/components/feeds/test/chrome/test_bug368464.html b/browser/components/feeds/test/chrome/test_bug368464.html
deleted file mode 100644
index dd7486f66..000000000
--- a/browser/components/feeds/test/chrome/test_bug368464.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=368464
--->
-<head>
- <title>Test that RSS 0.90 isn't sniffed</title>
- <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=368464">Mozilla Bug 368464</a>
-<p id="display"><iframe id="testFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/bug368464-data.xml"></iframe></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 368464 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- ok($("testFrame").contentDocument.documentElement.id != "feedHandler",
- "RSS 0.90 shouldn't be sniffed as a feed");
-});
-addLoadEvent(SimpleTest.finish);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/browser/components/feeds/test/chrome/test_bug408328.html b/browser/components/feeds/test/chrome/test_bug408328.html
deleted file mode 100644
index e4901320a..000000000
--- a/browser/components/feeds/test/chrome/test_bug408328.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=408328
--->
-<head>
- <title>Test feed preview safe-linkification</title>
- <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408328">Mozilla Bug 408328</a>
-<p id="display"><iframe id="testFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/bug408328-data.xml"></iframe></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 408328 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- var links = $("testFrame").contentDocument.getElementById("feedContent").getElementsByTagName("a");
- is(links.length, 5, "wrong number of linked items in feed preview");
- for (var i = 0; i < links.length; i++) {
- if (links[i].href)
- is(links[i].href, "http://example.org/first", "bad linkified item");
- }
-});
-addLoadEvent(SimpleTest.finish);
-
-</script>
-</pre>
-</body>
-</html>
-
diff --git a/browser/components/feeds/test/chrome/test_maxSniffing.html b/browser/components/feeds/test/chrome/test_maxSniffing.html
deleted file mode 100644
index 7a2044687..000000000
--- a/browser/components/feeds/test/chrome/test_maxSniffing.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=739040
--->
-<head>
- <title>Test that we only sniff 512 bytes</title>
- <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=739040">Mozilla Bug 739040</a>
-<p id="display">
- <iframe id="validTestFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/valid-feed.xml"></iframe>
- <iframe id="unsniffableTestFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/valid-unsniffable-feed.xml"></iframe>
-</p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 739040 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- is($("validTestFrame").contentDocument.documentElement.id, "feedHandler",
- "valid feed should be sniffed");
- isnot($("unsniffableTestFrame").contentDocument.documentElement.id, "feedHandler",
- "unsniffable feed should not be sniffed");
-});
-addLoadEvent(SimpleTest.finish);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/browser/components/feeds/test/mochitest.ini b/browser/components/feeds/test/mochitest.ini
deleted file mode 100644
index fc1e6a1a9..000000000
--- a/browser/components/feeds/test/mochitest.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-[DEFAULT]
-support-files =
- bug368464-data.xml
- bug408328-data.xml
- bug436801-data.xml
- bug494328-data.xml
- bug589543-data.xml
- valid-feed.xml
- valid-unsniffable-feed.xml
-
-[test_bug436801.html]
-[test_bug494328.html]
-[test_bug589543.html]
-[test_registerHandler.html]
diff --git a/browser/components/feeds/test/test_bug436801.html b/browser/components/feeds/test/test_bug436801.html
deleted file mode 100644
index 29fb5acf0..000000000
--- a/browser/components/feeds/test/test_bug436801.html
+++ /dev/null
@@ -1,118 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=436801
--->
-<head>
- <title>Test feed preview subscribe UI</title>
- <script type="text/javascript" src="/MochiKit/packed.js"></script>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=436801">Mozilla Bug 436801</a>
-<p id="display"><iframe id="testFrame" src="bug436801-data.xml"></iframe></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function () {
- var doc = SpecialPowers.wrap($("testFrame")).contentDocument;
-
- checkNode(doc.getElementById("feedTitleText"), [
- "ELEMENT", "h1", { "xml:base": "http://www.example.com/foo/bar/" }, [
- ["TEXT", "Example of a "],
- ["ELEMENT", "em", [
- ["TEXT", "special"],
- ]],
- ["TEXT", " feed ("],
- ["ELEMENT", "img", { "src": "baz.png" }],
- ["TEXT", ")"],
- ]
- ]);
-
- checkNode(doc.getElementById("feedSubtitleText"), [
- "ELEMENT", "h2", { "xml:base": "http://www.example.com/foo/bar/" }, [
- ["TEXT", "With a "],
- ["ELEMENT", "em", [
- ["TEXT", "special"],
- ]],
- ["TEXT", " subtitle ("],
- ["ELEMENT", "img", { "src": "baz.png" }],
- ["TEXT", ")"],
- ]
- ]);
-
- checkNode(doc.querySelector(".entry").firstChild.firstChild.firstChild, [
- "ELEMENT", "span", { "xml:base": "http://www.example.com/foo/bar/" }, [
- ["TEXT", "Some "],
- ["ELEMENT", "abbr", { title: "Extensible Hyper-text Mark-up Language" }, [
- ["TEXT", "XHTML"],
- ]],
- ["TEXT", " examples ("],
- ["ELEMENT", "img", { "src": "baz.png" }],
- ["TEXT", ")"],
- ]
- ]);
-
- checkNode(doc.querySelectorAll(".entry")[1].firstChild.firstChild.firstChild, [
- "ELEMENT", "span", { "xml:base": "http://www.example.com/foo/bar/" }, [
- ["TEXT", "Some "],
- ["ELEMENT", "abbr", { title: "Hyper-text Mark-up Language" }, [
- ["TEXT", "HTML"],
- ]],
- ["TEXT", " examples ("],
- ["ELEMENT", "img", { "src": "baz.png" }],
- ["TEXT", ")"],
- ]
- ]);
-});
-
-addLoadEvent(SimpleTest.finish);
-
-function checkNode(node, schema) {
- var typeName = schema.shift() + "_NODE";
- var type = Node[typeName];
- is(node.nodeType, type, "Node should be expected type " + typeName);
- if (type == Node.TEXT_NODE) {
- var text = schema.shift();
- is(node.data, text, "Text should match");
- return;
- }
- // type == Node.ELEMENT_NODE
- var tag = schema.shift();
- is(node.localName, tag, "Element should have expected tag");
- while (schema.length) {
- let val = schema.shift();
- if (Array.isArray(val))
- var childSchema = val;
- else
- var attrSchema = val;
- }
- if (attrSchema) {
- var nsTable = {
- xml: "http://www.w3.org/XML/1998/namespace",
- };
- for (var name in attrSchema) {
- var [ns, nsName] = name.split(":");
- let val = nsName ? node.getAttributeNS(nsTable[ns], nsName) :
- node.getAttribute(name);
- is(val, attrSchema[name], "Attribute " + name + " should match");
- }
- }
- if (childSchema) {
- var numChildren = node.childNodes.length;
- is(childSchema.length, numChildren,
- "Element should have expected number of children");
- for (var i = 0; i < numChildren; i++)
- checkNode(node.childNodes[i], childSchema[i]);
- }
-}
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/browser/components/feeds/test/test_bug494328.html b/browser/components/feeds/test/test_bug494328.html
deleted file mode 100644
index 054f62c1d..000000000
--- a/browser/components/feeds/test/test_bug494328.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=494328
--->
-<head>
- <title>Test for bug 494328</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=494328">Mozilla Bug 494328</a>
-<p id="display"><iframe id="testFrame" src="bug494328-data.xml"></iframe></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 494328 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- var links = SpecialPowers.wrap($("testFrame")).contentDocument.getElementById("feedContent").querySelectorAll("div.enclosure > a");
- is(links[0].textContent, "Episode 1", "filename decoded incorrectly");
- is(links[1].textContent, "Episode #2", "filename decoded incorrectly");
- is(links[2].textContent, "http://www.example.com/podcasts/Episode #3/", "filename decoded incorrectly");
- is(links[3].textContent, "Is This Episode #4?", "filename decoded incorrectly");
-});
-addLoadEvent(SimpleTest.finish);
-
-</script>
-</pre>
-</body>
-</html>
-
diff --git a/browser/components/feeds/test/test_bug589543.html b/browser/components/feeds/test/test_bug589543.html
deleted file mode 100644
index cee2a9661..000000000
--- a/browser/components/feeds/test/test_bug589543.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=589543
--->
-<head>
- <title>Test feed preview subscribe UI</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=589543">Mozilla Bug 589543</a>
-<p id="display"><iframe id="testFrame" src="bug589543-data.xml"></iframe></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 589543 **/
-SimpleTest.waitForExplicitFinish();
-
-addLoadEvent(function() {
- var doc = SpecialPowers.wrap($("testFrame")).contentDocument;
- var popup = doc.getElementById("handlersMenuList");
- isnot(popup, null, "Feed preview should have a handlers popup");
-});
-addLoadEvent(SimpleTest.finish);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/browser/components/feeds/test/test_registerHandler.html b/browser/components/feeds/test/test_registerHandler.html
deleted file mode 100644
index 34e61d034..000000000
--- a/browser/components/feeds/test/test_registerHandler.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=402788
--->
-<head>
- <title>Test for Bug 402788</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=402788">Mozilla Bug 402788</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Bug 402788 **/
-
- // return false if an exception has been catched, true otherwise
- function testRegisterHandler(aIsProtocol, aTxt, aUri, aTitle)
- {
- try {
- if (aIsProtocol)
- navigator.registerProtocolHandler(aTxt, aUri, aTitle);
- else
- navigator.registerContentHandler(aTxt, aUri, aTitle);
- }
- catch (e) {
- return false;
- }
-
- return true;
- }
-
- ok(navigator.registerProtocolHandler, "navigator.registerProtocolHandler should be defined");
- ok(navigator.registerContentHandler, "navigator.registerContentHandler should be defined");
-
- // testing a generic case
- is(testRegisterHandler(true, "foo", "http://mochi.test:8888/%s", "Foo handler"), true, "registering a foo protocol handler should work");
- is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering a foo content handler should work");
-
- // testing with wrong uris
- is(testRegisterHandler(true, "foo", "http://mochi.test:8888/", "Foo handler"), false, "a protocol handler uri should contain %s");
- is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/", "Foo handler"), false, "a content handler uri should contain %s");
-
- // the spec explicitly allows relative urls to be passed
- is(testRegisterHandler(true, "foo", "foo/%s", "Foo handler"), true, "a protocol handler uri should be valid");
- is(testRegisterHandler(false, "application/rss+xml", "foo/%s", "Foo handler"), true, "a content handler uri should be valid");
-
- // we should only accept to register when the handler has the same host as the current page (bug 402287)
- is(testRegisterHandler(true, "foo", "http://remotehost:8888/%s", "Foo handler"), false, "registering a foo protocol handler with a different host should not work");
- is(testRegisterHandler(false, "application/rss+xml", "http://remotehost:8888/%s", "Foo handler"), false, "registering a foo content handler with a different host should not work");
-
- // restriction to http(s) for the uri of the handler (bug 401343)
- // https should work (http already tested in the generic case)
- is(testRegisterHandler(true, "foo", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a foo protocol handler with https scheme should work");
- is(testRegisterHandler(false, "application/rss+xml", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a foo content handler with https scheme should work");
- // ftp should not work
- is(testRegisterHandler(true, "foo", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with ftp scheme should not work");
- is(testRegisterHandler(false, "application/rss+xml", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with ftp scheme should not work");
- // chrome should not work
- is(testRegisterHandler(true, "foo", "chrome://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with chrome scheme should not work");
- is(testRegisterHandler(false, "application/rss+xml", "chrome://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with chrome scheme should not work");
- // foo should not work
- is(testRegisterHandler(true, "foo", "foo://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with foo scheme should not work");
- is(testRegisterHandler(false, "application/rss+xml", "foo://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with foo scheme should not work");
-
- // for security reasons, protocol handlers should never be registered for some schemes (chrome, vbscript, ...) (bug 402788)
- is(testRegisterHandler(true, "chrome", "http://mochi.test:8888/%s", "chrome handler"), false, "registering a chrome protocol handler should not work");
- is(testRegisterHandler(true, "vbscript", "http://mochi.test:8888/%s", "vbscript handler"), false, "registering a vbscript protocol handler should not work");
- is(testRegisterHandler(true, "javascript", "http://mochi.test:8888/%s", "javascript handler"), false, "registering a javascript protocol handler should not work");
- is(testRegisterHandler(true, "moz-icon", "http://mochi.test:8888/%s", "moz-icon handler"), false, "registering a moz-icon protocol handler should not work");
-
- // for security reasons, content handlers should never be registered for some types (html, ...)
- is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering rss content handlers should work");
- is(testRegisterHandler(false, "application/atom+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering atom content handlers should work");
- todo_is(testRegisterHandler(false, "text/html", "http://mochi.test:8888/%s", "Foo handler"), false, "registering html content handlers should not work"); // bug 403798
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/browser/components/feeds/test/unit/.eslintrc.js b/browser/components/feeds/test/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/feeds/test/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/feeds/test/unit/head_feeds.js b/browser/components/feeds/test/unit/head_feeds.js
deleted file mode 100644
index 3b1135ef7..000000000
--- a/browser/components/feeds/test/unit/head_feeds.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cr = Components.results;
-
-var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
diff --git a/browser/components/feeds/test/unit/test_355473.js b/browser/components/feeds/test/unit/test_355473.js
deleted file mode 100644
index 8a20d1389..000000000
--- a/browser/components/feeds/test/unit/test_355473.js
+++ /dev/null
@@ -1,43 +0,0 @@
-var Cu = Components.utils;
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-function run_test() {
- var feedFeedURI = ios.newURI("feed://example.com/feed.xml", null, null);
- var httpFeedURI = ios.newURI("feed:http://example.com/feed.xml", null, null);
- var httpURI = ios.newURI("http://example.com/feed.xml", null, null);
-
- var httpsFeedURI =
- ios.newURI("feed:https://example.com/feed.xml", null, null);
- var httpsURI = ios.newURI("https://example.com/feed.xml", null, null);
-
- var feedChannel = NetUtil.newChannel({
- uri: feedFeedURI,
- loadUsingSystemPrincipal: true
- });
-
- var httpChannel = NetUtil.newChannel({
- uri: httpFeedURI,
- loadUsingSystemPrincipal: true
- });
-
- var httpsChannel = NetUtil.newChannel({
- uri: httpsFeedURI,
- loadUsingSystemPrincipal: true
- });
-
- // not setting .originalURI to the original URI is naughty
- do_check_true(feedFeedURI.equals(feedChannel.originalURI));
- do_check_true(httpFeedURI.equals(httpChannel.originalURI));
- do_check_true(httpsFeedURI.equals(httpsChannel.originalURI));
-
- // actually using the horrible mess that's a feed: URI is suicidal
- do_check_true(httpURI.equals(feedChannel.URI));
- do_check_true(httpURI.equals(httpChannel.URI));
- do_check_true(httpsURI.equals(httpsChannel.URI));
-
- // check that we throw creating feed: URIs from file and ftp
- Assert.throws(function() { ios.newURI("feed:ftp://example.com/feed.xml", null, null); },
- "Should throw an exception when trying to create a feed: URI with an ftp: inner");
- Assert.throws(function() { ios.newURI("feed:file:///var/feed.xml", null, null); },
- "Should throw an exception when trying to create a feed: URI with a file: inner");
-}
diff --git a/browser/components/feeds/test/unit/test_758990.js b/browser/components/feeds/test/unit/test_758990.js
deleted file mode 100644
index e6f88baf2..000000000
--- a/browser/components/feeds/test/unit/test_758990.js
+++ /dev/null
@@ -1,42 +0,0 @@
-function run_test() {
- var success = false;
- try {
- ios.newURI("feed:javascript:alert('hi');", null, null);
- }
- catch (e) {
- success = e.result == Cr.NS_ERROR_MALFORMED_URI;
- }
- if (!success)
- do_throw("We didn't throw NS_ERROR_MALFORMED_URI creating a feed:javascript: URI");
-
- success = false;
- try {
- ios.newURI("feed:data:text/html,hi", null, null);
- }
- catch (e) {
- success = e.result == Cr.NS_ERROR_MALFORMED_URI;
- }
- if (!success)
- do_throw("We didn't throw NS_ERROR_MALFORMED_URI creating a feed:data: URI");
-
- success = false;
- try {
- ios.newURI("pcast:javascript:alert('hi');", null, null);
- }
- catch (e) {
- success = e.result == Cr.NS_ERROR_MALFORMED_URI;
- }
- if (!success)
- do_throw("We didn't throw NS_ERROR_MALFORMED_URI creating a pcast:javascript: URI");
-
- success = false;
- try {
- ios.newURI("pcast:data:text/html,hi", null, null);
- }
- catch (e) {
- success = e.result == Cr.NS_ERROR_MALFORMED_URI;
- }
- if (!success)
- do_throw("We didn't throw NS_ERROR_MALFORMED_URI creating a pcast:data: URI");
-
-}
diff --git a/browser/components/feeds/test/unit/xpcshell.ini b/browser/components/feeds/test/unit/xpcshell.ini
deleted file mode 100644
index 9faf57396..000000000
--- a/browser/components/feeds/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[DEFAULT]
-head = head_feeds.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-[test_355473.js]
-[test_758990.js]
diff --git a/browser/components/feeds/test/valid-feed.xml b/browser/components/feeds/test/valid-feed.xml
deleted file mode 100644
index 0e700b6d8..000000000
--- a/browser/components/feeds/test/valid-feed.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-
- <title>Example Feed</title>
- <link href="http://example.org/"/>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
- <id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
-
- <entry>
-
- <title>Item</title>
- <link href="http://example.org/first"/>
- <id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/feeds/test/valid-unsniffable-feed.xml b/browser/components/feeds/test/valid-unsniffable-feed.xml
deleted file mode 100644
index e75315739..000000000
--- a/browser/components/feeds/test/valid-unsniffable-feed.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 512 bytes!
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- -->
-<feed xmlns="http://www.w3.org/2005/Atom">
-
- <title>Example Feed</title>
- <link href="http://example.org/"/>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <author>
- <name>John Doe</name>
- </author>
- <id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
-
- <entry>
-
- <title>Item</title>
- <link href="http://example.org/first"/>
- <id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
- <updated>2010-08-22T18:30:02Z</updated>
-
- <summary>Some text.</summary>
- </entry>
-
-</feed>
diff --git a/browser/components/migration/moz.build b/browser/components/migration/moz.build
index 751ea0cd9..465e3eade 100644
--- a/browser/components/migration/moz.build
+++ b/browser/components/migration/moz.build
@@ -4,12 +4,6 @@
# 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/.
-XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
-
-MARIONETTE_UNIT_MANIFESTS += ['tests/marionette/manifest.ini']
-
-BROWSER_CHROME_MANIFESTS += [ 'tests/browser/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
XPIDL_SOURCES += [
@@ -57,6 +51,3 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DEFINES['HAS_SAFARI_MIGRATOR'] = True
FINAL_LIBRARY = 'browsercomps'
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Migration')
diff --git a/browser/components/migration/tests/browser/.eslintrc.js b/browser/components/migration/tests/browser/.eslintrc.js
deleted file mode 100644
index 3ea6eeb8c..000000000
--- a/browser/components/migration/tests/browser/.eslintrc.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js",
- "../../../../../testing/mochitest/mochitest.eslintrc.js",
- ]
-};
-
diff --git a/browser/components/migration/tests/browser/browser.ini b/browser/components/migration/tests/browser/browser.ini
deleted file mode 100644
index 94edfe7aa..000000000
--- a/browser/components/migration/tests/browser/browser.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[browser_undo_notification.js]
-[browser_undo_notification_wording.js]
-[browser_undo_notification_multiple_dismissal.js]
diff --git a/browser/components/migration/tests/browser/browser_undo_notification.js b/browser/components/migration/tests/browser/browser_undo_notification.js
deleted file mode 100644
index 6c97922e0..000000000
--- a/browser/components/migration/tests/browser/browser_undo_notification.js
+++ /dev/null
@@ -1,67 +0,0 @@
-"use strict";
-
-let scope = {};
-Cu.import("resource:///modules/AutoMigrate.jsm", scope);
-let oldCanUndo = scope.AutoMigrate.canUndo;
-let oldUndo = scope.AutoMigrate.undo;
-registerCleanupFunction(function() {
- scope.AutoMigrate.canUndo = oldCanUndo;
- scope.AutoMigrate.undo = oldUndo;
-});
-
-const kExpectedNotificationId = "automigration-undo";
-
-add_task(function* autoMigrationUndoNotificationShows() {
- let getNotification = browser =>
- gBrowser.getNotificationBox(browser).getNotificationWithValue(kExpectedNotificationId);
-
- scope.AutoMigrate.canUndo = () => true;
- let undoCalled;
- scope.AutoMigrate.undo = () => { undoCalled = true };
- for (let url of ["about:newtab", "about:home"]) {
- undoCalled = false;
- // Can't use pushPrefEnv because of bug 1323779
- Services.prefs.setCharPref("browser.migrate.automigrate.browser", "someunknownbrowser");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url, false);
- let browser = tab.linkedBrowser;
- if (!getNotification(browser)) {
- info(`Notification for ${url} not immediately present, waiting for it.`);
- yield BrowserTestUtils.waitForNotificationBar(gBrowser, browser, kExpectedNotificationId);
- }
-
- ok(true, `Got notification for ${url}`);
- let notification = getNotification(browser);
- let notificationBox = notification.parentNode;
- notification.querySelector("button.notification-button-default").click();
- ok(!undoCalled, "Undo should not be called when clicking the default button");
- is(notification, notificationBox._closedNotification, "Notification should be closing");
- yield BrowserTestUtils.removeTab(tab);
-
- undoCalled = false;
- Services.prefs.setCharPref("browser.migrate.automigrate.browser", "chrome");
- tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url, false);
- browser = tab.linkedBrowser;
- if (!getNotification(browser)) {
- info(`Notification for ${url} not immediately present, waiting for it.`);
- yield BrowserTestUtils.waitForNotificationBar(gBrowser, browser, kExpectedNotificationId);
- }
-
- ok(true, `Got notification for ${url}`);
- notification = getNotification(browser);
- notificationBox = notification.parentNode;
- // Set up the survey:
- yield SpecialPowers.pushPrefEnv({set: [
- ["browser.migrate.automigrate.undo-survey", "https://example.com/?browser=%IMPORTEDBROWSER%"],
- ["browser.migrate.automigrate.undo-survey-locales", "en-US"],
- ]});
- let tabOpenedPromise = BrowserTestUtils.waitForNewTab(gBrowser, "https://example.com/?browser=Google%20Chrome");
- notification.querySelector("button:not(.notification-button-default)").click();
- ok(undoCalled, "Undo should be called when clicking the non-default (Don't Keep) button");
- is(notification, notificationBox._closedNotification, "Notification should be closing");
- let surveyTab = yield tabOpenedPromise;
- ok(surveyTab, "Should have opened a tab with a survey");
- yield BrowserTestUtils.removeTab(surveyTab);
- yield BrowserTestUtils.removeTab(tab);
- }
-});
-
diff --git a/browser/components/migration/tests/browser/browser_undo_notification_multiple_dismissal.js b/browser/components/migration/tests/browser/browser_undo_notification_multiple_dismissal.js
deleted file mode 100644
index 90b5d0d08..000000000
--- a/browser/components/migration/tests/browser/browser_undo_notification_multiple_dismissal.js
+++ /dev/null
@@ -1,122 +0,0 @@
-"use strict";
-
-
-const kExpectedNotificationId = "automigration-undo";
-
-/**
- * Pretend we can undo something, trigger a notification, pick the undo option,
- * and verify that the notifications are all dismissed immediately.
- */
-add_task(function* checkNotificationsDismissed() {
- yield SpecialPowers.pushPrefEnv({set: [
- ["browser.migrate.automigrate.enabled", true],
- ["browser.migrate.automigrate.ui.enabled", true],
- ]});
- let getNotification = browser =>
- gBrowser.getNotificationBox(browser).getNotificationWithValue(kExpectedNotificationId);
-
- Services.prefs.setCharPref("browser.migrate.automigrate.browser", "someunknownbrowser");
-
- let {guid, lastModified} = yield PlacesUtils.bookmarks.insert(
- {title: "Some imported bookmark", parentGuid: PlacesUtils.bookmarks.toolbarGuid, url: "http://www.example.com"}
- );
-
- let testUndoData = {
- visits: [],
- bookmarks: [{guid, lastModified: lastModified.getTime()}],
- logins: [],
- };
- let path = OS.Path.join(OS.Constants.Path.profileDir, "initialMigrationMetadata.jsonlz4");
- registerCleanupFunction(() => {
- return OS.File.remove(path, {ignoreAbsent: true});
- });
- yield OS.File.writeAtomic(path, JSON.stringify(testUndoData), {
- encoding: "utf-8",
- compression: "lz4",
- tmpPath: path + ".tmp",
- });
-
- let firstTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", false);
- if (!getNotification(firstTab.linkedBrowser)) {
- info(`Notification not immediately present on first tab, waiting for it.`);
- yield BrowserTestUtils.waitForNotificationBar(gBrowser, firstTab.linkedBrowser, kExpectedNotificationId);
- }
- let secondTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", false);
- if (!getNotification(secondTab.linkedBrowser)) {
- info(`Notification not immediately present on second tab, waiting for it.`);
- yield BrowserTestUtils.waitForNotificationBar(gBrowser, secondTab.linkedBrowser, kExpectedNotificationId);
- }
-
- // Create a listener for the removal in the first tab, and a listener for bookmarks removal,
- // then click 'Don't keep' in the second tab, and verify that the notification is removed
- // before we start removing bookmarks.
- let haveRemovedBookmark = false;
- let bmObserver;
- let bookmarkRemovedPromise = new Promise(resolve => {
- bmObserver = {
- onItemRemoved(itemId, parentId, index, itemType, uri, removedGuid) {
- if (guid == removedGuid) {
- haveRemovedBookmark = true;
- resolve();
- }
- },
- };
- PlacesUtils.bookmarks.addObserver(bmObserver, false);
- registerCleanupFunction(() => PlacesUtils.bookmarks.removeObserver(bmObserver));
- });
-
- let firstTabNotificationRemovedPromise = new Promise(resolve => {
- let notification = getNotification(firstTab.linkedBrowser);
- // Save this reference because notification.parentNode will be null once it's removed.
- let notificationBox = notification.parentNode;
- let mut = new MutationObserver(mutations => {
- // Yucky, but we have to detect either the removal via animation (with marginTop)
- // or when the element is removed. We can't just detect the element being removed
- // because this happens asynchronously (after the animation) and so it'd race
- // with the rest of the undo happening.
- for (let mutation of mutations) {
- if (mutation.target == notification && mutation.attributeName == "style" &&
- parseInt(notification.style.marginTop, 10) < 0) {
- ok(!haveRemovedBookmark, "Should not have removed bookmark yet");
- mut.disconnect();
- resolve();
- return;
- }
- if (mutation.target == notificationBox && mutation.removedNodes.length &&
- mutation.removedNodes[0] == notification) {
- ok(!haveRemovedBookmark, "Should not have removed bookmark yet");
- mut.disconnect();
- resolve();
- return;
- }
- }
- });
- mut.observe(notification.parentNode, {childList: true});
- mut.observe(notification, {attributes: true});
- });
-
- let prefResetPromise = new Promise(resolve => {
- const kObservedPref = "browser.migrate.automigrate.browser";
- let obs = () => {
- Services.prefs.removeObserver(kObservedPref, obs);
- ok(!Services.prefs.prefHasUserValue(kObservedPref),
- "Pref should have been reset");
- resolve();
- };
- Services.prefs.addObserver(kObservedPref, obs, false);
- });
-
- // Click "Don't keep" button:
- let notificationToActivate = getNotification(secondTab.linkedBrowser);
- notificationToActivate.querySelector("button:not(.notification-button-default)").click();
- info("Waiting for notification to be removed in first (background) tab");
- yield firstTabNotificationRemovedPromise;
- info("Waiting for bookmark to be removed");
- yield bookmarkRemovedPromise;
- info("Waiting for prefs to be reset");
- yield prefResetPromise;
-
- info("Removing spare tabs");
- yield BrowserTestUtils.removeTab(firstTab);
- yield BrowserTestUtils.removeTab(secondTab);
-});
diff --git a/browser/components/migration/tests/browser/browser_undo_notification_wording.js b/browser/components/migration/tests/browser/browser_undo_notification_wording.js
deleted file mode 100644
index f0a9ceec9..000000000
--- a/browser/components/migration/tests/browser/browser_undo_notification_wording.js
+++ /dev/null
@@ -1,67 +0,0 @@
-"use strict";
-
-let scope = {};
-Cu.import("resource:///modules/AutoMigrate.jsm", scope);
-let oldCanUndo = scope.AutoMigrate.canUndo;
-registerCleanupFunction(function() {
- scope.AutoMigrate.canUndo = oldCanUndo;
-});
-
-const kExpectedNotificationId = "automigration-undo";
-
-add_task(function* autoMigrationUndoNotificationShows() {
- let getNotification = browser =>
- gBrowser.getNotificationBox(browser).getNotificationWithValue(kExpectedNotificationId);
- let localizedVersionOf = str => {
- if (str == "logins") {
- return "passwords";
- }
- if (str == "visits") {
- return "history";
- }
- return str;
- };
-
- scope.AutoMigrate.canUndo = () => true;
- let url = "about:newtab";
- Services.prefs.setCharPref("browser.migrate.automigrate.browser", "someunknownbrowser");
- const kSubsets = [
- ["bookmarks", "logins", "visits"],
- ["bookmarks", "logins"],
- ["bookmarks", "visits"],
- ["logins", "visits"],
- ["bookmarks"],
- ["logins"],
- ["visits"],
- ];
- const kAllItems = ["bookmarks", "logins", "visits"];
- for (let subset of kSubsets) {
- let state = new Map(subset.map(item => [item, [{}]]));
- scope.AutoMigrate._setImportedItemPrefFromState(state);
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url, false);
- let browser = tab.linkedBrowser;
-
- if (!getNotification(browser)) {
- info(`Notification for ${url} not immediately present, waiting for it.`);
- yield BrowserTestUtils.waitForNotificationBar(gBrowser, browser, kExpectedNotificationId);
- }
-
- ok(true, `Got notification for ${url}`);
- let notification = getNotification(browser);
- let notificationText = document.getAnonymousElementByAttribute(notification, "class", "messageText");
- notificationText = notificationText.textContent;
- for (let potentiallyImported of kAllItems) {
- let localizedImportItem = localizedVersionOf(potentiallyImported);
- if (subset.includes(potentiallyImported)) {
- ok(notificationText.includes(localizedImportItem),
- "Expected notification to contain " + localizedImportItem);
- } else {
- ok(!notificationText.includes(localizedImportItem),
- "Expected notification not to contain " + localizedImportItem);
- }
- }
-
- yield BrowserTestUtils.removeTab(tab);
- }
-});
-
diff --git a/browser/components/migration/tests/marionette/manifest.ini b/browser/components/migration/tests/marionette/manifest.ini
deleted file mode 100644
index 3f404e724..000000000
--- a/browser/components/migration/tests/marionette/manifest.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-run-if = buildapp == 'browser'
-
-[test_refresh_firefox.py]
-
diff --git a/browser/components/migration/tests/marionette/test_refresh_firefox.py b/browser/components/migration/tests/marionette/test_refresh_firefox.py
deleted file mode 100644
index b348a3dcd..000000000
--- a/browser/components/migration/tests/marionette/test_refresh_firefox.py
+++ /dev/null
@@ -1,416 +0,0 @@
-import os
-import shutil
-
-from marionette_harness import MarionetteTestCase
-
-
-class TestFirefoxRefresh(MarionetteTestCase):
- _username = "marionette-test-login"
- _password = "marionette-test-password"
- _bookmarkURL = "about:mozilla"
- _bookmarkText = "Some bookmark from Marionette"
-
- _cookieHost = "firefox-refresh.marionette-test.mozilla.org"
- _cookiePath = "some/cookie/path"
- _cookieName = "somecookie"
- _cookieValue = "some cookie value"
-
- _historyURL = "http://firefox-refresh.marionette-test.mozilla.org/"
- _historyTitle = "Test visit for Firefox Reset"
-
- _formHistoryFieldName = "some-very-unique-marionette-only-firefox-reset-field"
- _formHistoryValue = "special-pumpkin-value"
-
- _expectedURLs = ["about:robots", "about:mozilla"]
-
- def savePassword(self):
- self.runCode("""
- let myLogin = new global.LoginInfo(
- "test.marionette.mozilla.com",
- "http://test.marionette.mozilla.com/some/form/",
- null,
- arguments[0],
- arguments[1],
- "username",
- "password"
- );
- Services.logins.addLogin(myLogin)
- """, script_args=[self._username, self._password])
-
- def createBookmark(self):
- self.marionette.execute_script("""
- let url = arguments[0];
- let title = arguments[1];
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.bookmarksMenuFolder,
- makeURI(url), 0, title);
- """, script_args=[self._bookmarkURL, self._bookmarkText])
-
- def createHistory(self):
- error = self.runAsyncCode("""
- // Copied from PlacesTestUtils, which isn't available in Marionette tests.
- let didReturn;
- PlacesUtils.asyncHistory.updatePlaces(
- [{title: arguments[1], uri: makeURI(arguments[0]), visits: [{
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- visitDate: (Date.now() - 5000) * 1000,
- referrerURI: makeURI("about:mozilla"),
- }]
- }],
- {
- handleError(resultCode, place) {
- didReturn = true;
- marionetteScriptFinished("Unexpected error in adding visit: " + resultCode);
- },
- handleResult() {},
- handleCompletion() {
- if (!didReturn) {
- marionetteScriptFinished(false);
- }
- },
- }
- );
- """, script_args=[self._historyURL, self._historyTitle])
- if error:
- print error
-
- def createFormHistory(self):
- error = self.runAsyncCode("""
- let updateDefinition = {
- op: "add",
- fieldname: arguments[0],
- value: arguments[1],
- firstUsed: (Date.now() - 5000) * 1000,
- };
- let finished = false;
- global.FormHistory.update(updateDefinition, {
- handleError(error) {
- finished = true;
- marionetteScriptFinished(error);
- },
- handleCompletion() {
- if (!finished) {
- marionetteScriptFinished(false);
- }
- }
- });
- """, script_args=[self._formHistoryFieldName, self._formHistoryValue])
- if error:
- print error
-
- def createCookie(self):
- self.runCode("""
- // Expire in 15 minutes:
- let expireTime = Math.floor(Date.now() / 1000) + 15 * 60;
- Services.cookies.add(arguments[0], arguments[1], arguments[2], arguments[3],
- true, false, false, expireTime);
- """, script_args=[self._cookieHost, self._cookiePath, self._cookieName, self._cookieValue])
-
- def createSession(self):
- self.runAsyncCode("""
- const COMPLETE_STATE = Ci.nsIWebProgressListener.STATE_STOP +
- Ci.nsIWebProgressListener.STATE_IS_NETWORK;
- let {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
- let expectedURLs = Array.from(arguments[0])
- gBrowser.addTabsProgressListener({
- onStateChange(browser, webprogress, request, flags, status) {
- try {
- request && request.QueryInterface(Ci.nsIChannel);
- } catch (ex) {}
- let uriLoaded = request.originalURI && request.originalURI.spec;
- if ((flags & COMPLETE_STATE == COMPLETE_STATE) && uriLoaded &&
- expectedURLs.includes(uriLoaded)) {
- TabStateFlusher.flush(browser).then(function() {
- expectedURLs.splice(expectedURLs.indexOf(uriLoaded), 1);
- if (!expectedURLs.length) {
- gBrowser.removeTabsProgressListener(this);
- marionetteScriptFinished();
- }
- });
- }
- }
- });
- for (let url of expectedURLs) {
- gBrowser.addTab(url);
- }
- """, script_args=[self._expectedURLs])
-
- def checkPassword(self):
- loginInfo = self.marionette.execute_script("""
- let ary = Services.logins.findLogins({},
- "test.marionette.mozilla.com",
- "http://test.marionette.mozilla.com/some/form/",
- null, {});
- return ary.length ? ary : {username: "null", password: "null"};
- """)
- self.assertEqual(len(loginInfo), 1)
- self.assertEqual(loginInfo[0]['username'], self._username)
- self.assertEqual(loginInfo[0]['password'], self._password)
-
- loginCount = self.marionette.execute_script("""
- return Services.logins.getAllLogins().length;
- """)
- self.assertEqual(loginCount, 1, "No other logins are present")
-
- def checkBookmark(self):
- titleInBookmarks = self.marionette.execute_script("""
- let url = arguments[0];
- let bookmarkIds = PlacesUtils.bookmarks.getBookmarkIdsForURI(makeURI(url), {}, {});
- return bookmarkIds.length == 1 ? PlacesUtils.bookmarks.getItemTitle(bookmarkIds[0]) : "";
- """, script_args=[self._bookmarkURL])
- self.assertEqual(titleInBookmarks, self._bookmarkText)
-
- def checkHistory(self):
- historyResults = self.runAsyncCode("""
- let placeInfos = [];
- PlacesUtils.asyncHistory.getPlacesInfo(makeURI(arguments[0]), {
- handleError(resultCode, place) {
- placeInfos = null;
- marionetteScriptFinished("Unexpected error in fetching visit: " + resultCode);
- },
- handleResult(placeInfo) {
- placeInfos.push(placeInfo);
- },
- handleCompletion() {
- if (placeInfos) {
- if (!placeInfos.length) {
- marionetteScriptFinished("No visits found");
- } else {
- marionetteScriptFinished(placeInfos);
- }
- }
- },
- });
- """, script_args=[self._historyURL])
- if type(historyResults) == str:
- self.fail(historyResults)
- return
-
- historyCount = len(historyResults)
- self.assertEqual(historyCount, 1, "Should have exactly 1 entry for URI, got %d" % historyCount)
- if historyCount == 1:
- self.assertEqual(historyResults[0]['title'], self._historyTitle)
-
- def checkFormHistory(self):
- formFieldResults = self.runAsyncCode("""
- let results = [];
- global.FormHistory.search(["value"], {fieldname: arguments[0]}, {
- handleError(error) {
- results = error;
- },
- handleResult(result) {
- results.push(result);
- },
- handleCompletion() {
- marionetteScriptFinished(results);
- },
- });
- """, script_args=[self._formHistoryFieldName])
- if type(formFieldResults) == str:
- self.fail(formFieldResults)
- return
-
- formFieldResultCount = len(formFieldResults)
- self.assertEqual(formFieldResultCount, 1, "Should have exactly 1 entry for this field, got %d" % formFieldResultCount)
- if formFieldResultCount == 1:
- self.assertEqual(formFieldResults[0]['value'], self._formHistoryValue)
-
- formHistoryCount = self.runAsyncCode("""
- let count;
- let callbacks = {
- handleResult: rv => count = rv,
- handleCompletion() {
- marionetteScriptFinished(count);
- },
- };
- global.FormHistory.count({}, callbacks);
- """)
- self.assertEqual(formHistoryCount, 1, "There should be only 1 entry in the form history")
-
- def checkCookie(self):
- cookieInfo = self.runCode("""
- try {
- let cookieEnum = Services.cookies.getCookiesFromHost(arguments[0]);
- let cookie = null;
- while (cookieEnum.hasMoreElements()) {
- let hostCookie = cookieEnum.getNext();
- hostCookie.QueryInterface(Ci.nsICookie2);
- // getCookiesFromHost returns any cookie from the BASE host.
- if (hostCookie.rawHost != arguments[0])
- continue;
- if (cookie != null) {
- return "more than 1 cookie! That shouldn't happen!";
- }
- cookie = hostCookie;
- }
- return {path: cookie.path, name: cookie.name, value: cookie.value};
- } catch (ex) {
- return "got exception trying to fetch cookie: " + ex;
- }
- """, script_args=[self._cookieHost])
- if not isinstance(cookieInfo, dict):
- self.fail(cookieInfo)
- return
- self.assertEqual(cookieInfo['path'], self._cookiePath)
- self.assertEqual(cookieInfo['value'], self._cookieValue)
- self.assertEqual(cookieInfo['name'], self._cookieName)
-
- def checkSession(self):
- tabURIs = self.runCode("""
- return [... gBrowser.browsers].map(b => b.currentURI && b.currentURI.spec)
- """)
- self.assertSequenceEqual(tabURIs, ["about:welcomeback"])
-
- tabURIs = self.runAsyncCode("""
- let mm = gBrowser.selectedBrowser.messageManager;
- let fs = function() {
- content.document.getElementById("errorTryAgain").click();
- };
- let {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
- window.addEventListener("SSWindowStateReady", function testSSPostReset() {
- window.removeEventListener("SSWindowStateReady", testSSPostReset, false);
- Promise.all(gBrowser.browsers.map(b => TabStateFlusher.flush(b))).then(function() {
- marionetteScriptFinished([... gBrowser.browsers].map(b => b.currentURI && b.currentURI.spec));
- });
- }, false);
- mm.loadFrameScript("data:application/javascript,(" + fs.toString() + ")()", true);
- """)
- self.assertSequenceEqual(tabURIs, ["about:blank"] + self._expectedURLs)
- pass
-
- def checkProfile(self, hasMigrated=False):
- self.checkPassword()
- self.checkBookmark()
- self.checkHistory()
- self.checkFormHistory()
- self.checkCookie()
- if hasMigrated:
- self.checkSession()
-
- def createProfileData(self):
- self.savePassword()
- self.createBookmark()
- self.createHistory()
- self.createFormHistory()
- self.createCookie()
- self.createSession()
-
- def setUpScriptData(self):
- self.marionette.set_context(self.marionette.CONTEXT_CHROME)
- self.marionette.execute_script("""
- global.LoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", "nsILoginInfo", "init");
- global.profSvc = Cc["@mozilla.org/toolkit/profile-service;1"].getService(Ci.nsIToolkitProfileService);
- global.Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
- global.FormHistory = Cu.import("resource://gre/modules/FormHistory.jsm", {}).FormHistory;
- """, new_sandbox=False, sandbox='system')
-
- def runCode(self, script, *args, **kwargs):
- return self.marionette.execute_script(script, new_sandbox=False, sandbox='system', *args, **kwargs)
-
- def runAsyncCode(self, script, *args, **kwargs):
- return self.marionette.execute_async_script(script, new_sandbox=False, sandbox='system', *args, **kwargs)
-
- def setUp(self):
- MarionetteTestCase.setUp(self)
- self.setUpScriptData()
-
- self.reset_profile_path = None
- self.desktop_backup_path = None
-
- self.createProfileData()
-
- def tearDown(self):
- # Force yet another restart with a clean profile to disconnect from the
- # profile and environment changes we've made, to leave a more or less
- # blank slate for the next person.
- self.marionette.restart(clean=True, in_app=False)
- self.setUpScriptData()
-
- # Super
- MarionetteTestCase.tearDown(self)
-
- # Some helpers to deal with removing a load of files
- import errno, stat
- def handleRemoveReadonly(func, path, exc):
- excvalue = exc[1]
- if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
- os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
- func(path)
- else:
- raise
-
- if self.desktop_backup_path:
- shutil.rmtree(self.desktop_backup_path, ignore_errors=False, onerror=handleRemoveReadonly)
-
- if self.reset_profile_path:
- # Remove ourselves from profiles.ini
- profileLeafName = os.path.basename(os.path.normpath(self.reset_profile_path))
- self.runCode("""
- let [salt, name] = arguments[0].split(".");
- let profile = global.profSvc.getProfileByName(name);
- profile.remove(false)
- global.profSvc.flush();
- """, script_args=[profileLeafName])
- # And delete all the files.
- shutil.rmtree(self.reset_profile_path, ignore_errors=False, onerror=handleRemoveReadonly)
-
- def doReset(self):
- self.runCode("""
- // Ensure the current (temporary) profile is in profiles.ini:
- let profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
- let profileName = "marionette-test-profile-" + Date.now();
- let myProfile = global.profSvc.createProfile(profD, profileName);
- global.profSvc.flush()
-
- // Now add the reset parameters:
- let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
- let allMarionettePrefs = Services.prefs.getChildList("marionette.");
- let prefObj = {};
- for (let pref of allMarionettePrefs) {
- let prefSuffix = pref.substr("marionette.".length);
- let prefVal = global.Preferences.get(pref);
- prefObj[prefSuffix] = prefVal;
- }
- let marionetteInfo = JSON.stringify(prefObj);
- env.set("MOZ_MARIONETTE_PREF_STATE_ACROSS_RESTARTS", marionetteInfo);
- env.set("MOZ_RESET_PROFILE_RESTART", "1");
- env.set("XRE_PROFILE_PATH", arguments[0]);
- env.set("XRE_PROFILE_NAME", profileName);
- """, script_args=[self.marionette.instance.profile.profile])
-
- profileLeafName = os.path.basename(os.path.normpath(self.marionette.instance.profile.profile))
-
- # Now restart the browser to get it reset:
- self.marionette.restart(clean=False, in_app=True)
- self.setUpScriptData()
-
- # Determine the new profile path (we'll need to remove it when we're done)
- self.reset_profile_path = self.runCode("""
- let profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
- return profD.path;
- """)
-
- # Determine the backup path
- self.desktop_backup_path = self.runCode("""
- let container;
- try {
- container = Services.dirsvc.get("Desk", Ci.nsIFile);
- } catch (ex) {
- container = Services.dirsvc.get("Home", Ci.nsIFile);
- }
- let bundle = Services.strings.createBundle("chrome://mozapps/locale/profile/profileSelection.properties");
- let dirName = bundle.formatStringFromName("resetBackupDirectory", [Services.appinfo.name], 1);
- container.append(dirName);
- container.append(arguments[0]);
- return container.path;
- """, script_args = [profileLeafName])
-
- self.assertTrue(os.path.isdir(self.reset_profile_path), "Reset profile path should be present")
- self.assertTrue(os.path.isdir(self.desktop_backup_path), "Backup profile path should be present")
-
- def testReset(self):
- self.checkProfile()
-
- self.doReset()
-
- # Now check that we're doing OK...
- self.checkProfile(hasMigrated=True)
diff --git a/browser/components/migration/tests/unit/.eslintrc.js b/browser/components/migration/tests/unit/.eslintrc.js
deleted file mode 100644
index ba65517f9..000000000
--- a/browser/components/migration/tests/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = { // eslint-disable-line no-undef
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/migration/tests/unit/AppData/Local/Google/Chrome/User Data/Default/Login Data b/browser/components/migration/tests/unit/AppData/Local/Google/Chrome/User Data/Default/Login Data
deleted file mode 100644
index 914149c71..000000000
--- a/browser/components/migration/tests/unit/AppData/Local/Google/Chrome/User Data/Default/Login Data
+++ /dev/null
Binary files differ
diff --git a/browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Default/Cookies b/browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Default/Cookies
deleted file mode 100644
index 83d855cb3..000000000
--- a/browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Default/Cookies
+++ /dev/null
Binary files differ
diff --git a/browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Local State b/browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Local State
deleted file mode 100644
index 01b99455e..000000000
--- a/browser/components/migration/tests/unit/Library/Application Support/Google/Chrome/Local State
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "profile" : {
- "info_cache" : {
- "Default" : {
- "active_time" : 1430950755.65137,
- "is_using_default_name" : true,
- "is_ephemeral" : false,
- "is_omitted_from_profile_list" : false,
- "user_name" : "",
- "background_apps" : false,
- "is_using_default_avatar" : true,
- "avatar_icon" : "chrome://theme/IDR_PROFILE_AVATAR_0",
- "name" : "Person 1"
- }
- },
- "profiles_created" : 1,
- "last_used" : "Default",
- "last_active_profiles" : [
- "Default"
- ]
- }
-}
diff --git a/browser/components/migration/tests/unit/Library/Safari/Bookmarks.plist b/browser/components/migration/tests/unit/Library/Safari/Bookmarks.plist
deleted file mode 100644
index 40783c7b1..000000000
--- a/browser/components/migration/tests/unit/Library/Safari/Bookmarks.plist
+++ /dev/null
Binary files differ
diff --git a/browser/components/migration/tests/unit/head_migration.js b/browser/components/migration/tests/unit/head_migration.js
deleted file mode 100644
index d3c258d54..000000000
--- a/browser/components/migration/tests/unit/head_migration.js
+++ /dev/null
@@ -1,69 +0,0 @@
-"use strict";
-
-/* exported gProfD, promiseMigration, registerFakePath */
-
-var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
-
-Cu.importGlobalProperties([ "URL" ]);
-
-Cu.import("resource:///modules/MigrationUtils.jsm");
-Cu.import("resource://gre/modules/LoginHelper.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/PlacesUtils.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/PromiseUtils.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://testing-common/TestUtils.jsm");
-Cu.import("resource://testing-common/PlacesTestUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm");
-
-// Initialize profile.
-var gProfD = do_get_profile();
-
-Cu.import("resource://testing-common/AppInfo.jsm"); /* globals updateAppInfo */
-updateAppInfo();
-
-/**
- * Migrates the requested resource and waits for the migration to be complete.
- */
-function promiseMigration(migrator, resourceType, aProfile = null) {
- // Ensure resource migration is available.
- let availableSources = migrator.getMigrateData(aProfile, false);
- Assert.ok((availableSources & resourceType) > 0, "Resource supported by migrator");
-
- return new Promise (resolve => {
- Services.obs.addObserver(function onMigrationEnded() {
- Services.obs.removeObserver(onMigrationEnded, "Migration:Ended");
- resolve();
- }, "Migration:Ended", false);
-
- migrator.migrate(resourceType, null, aProfile);
- });
-}
-
-/**
- * Replaces a directory service entry with a given nsIFile.
- */
-function registerFakePath(key, file) {
- // Register our own provider for the Library directory.
- let provider = {
- getFile(prop, persistent) {
- persistent.value = true;
- if (prop == key) {
- return file;
- }
- throw Cr.NS_ERROR_FAILURE;
- },
- QueryInterface: XPCOMUtils.generateQI([ Ci.nsIDirectoryServiceProvider ])
- };
- Services.dirsvc.QueryInterface(Ci.nsIDirectoryService)
- .registerProvider(provider);
- do_register_cleanup(() => {
- Services.dirsvc.QueryInterface(Ci.nsIDirectoryService)
- .unregisterProvider(provider);
- });
-}
diff --git a/browser/components/migration/tests/unit/test_Chrome_cookies.js b/browser/components/migration/tests/unit/test_Chrome_cookies.js
deleted file mode 100644
index 006693951..000000000
--- a/browser/components/migration/tests/unit/test_Chrome_cookies.js
+++ /dev/null
@@ -1,51 +0,0 @@
-"use strict";
-
-Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
-
-add_task(function* () {
- registerFakePath("ULibDir", do_get_file("Library/"));
- let migrator = MigrationUtils.getMigrator("chrome");
-
- Assert.ok(migrator.sourceExists, "Sanity check the source exists");
-
- const COOKIE = {
- expiry: 2145934800,
- host: "unencryptedcookie.invalid",
- isHttpOnly: false,
- isSession: false,
- name: "testcookie",
- path: "/",
- value: "testvalue",
- };
-
- // Sanity check.
- Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 0,
- "There are no cookies initially");
-
- const PROFILE = {
- id: "Default",
- name: "Person 1",
- };
-
- // Migrate unencrypted cookies.
- yield promiseMigration(migrator, MigrationUtils.resourceTypes.COOKIES, PROFILE);
-
- Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 1,
- "Migrated the expected number of unencrypted cookies");
- Assert.equal(Services.cookies.countCookiesFromHost("encryptedcookie.invalid"), 0,
- "Migrated the expected number of encrypted cookies");
-
- // Now check the cookie details.
- let enumerator = Services.cookies.getCookiesFromHost(COOKIE.host, {});
- Assert.ok(enumerator.hasMoreElements(), "Cookies available");
- let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
-
- for (let prop of Object.keys(COOKIE)) {
- Assert.equal(foundCookie[prop], COOKIE[prop], "Check cookie " + prop);
- }
-
- // Cleanup.
- ForgetAboutSite.removeDataFromDomain(COOKIE.host);
- Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 0,
- "There are no cookies after cleanup");
-});
diff --git a/browser/components/migration/tests/unit/test_Chrome_passwords.js b/browser/components/migration/tests/unit/test_Chrome_passwords.js
deleted file mode 100644
index 49147bd61..000000000
--- a/browser/components/migration/tests/unit/test_Chrome_passwords.js
+++ /dev/null
@@ -1,219 +0,0 @@
-"use strict";
-
-Cu.import("resource://gre/modules/OSCrypto.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-const PROFILE = {
- id: "Default",
- name: "Person 1",
-};
-
-const TEST_LOGINS = [
- {
- id: 1, // id of the row in the chrome login db
- username: "username",
- password: "password",
- hostname: "https://c9.io",
- formSubmitURL: "https://c9.io",
- httpRealm: null,
- usernameField: "inputEmail",
- passwordField: "inputPassword",
- timeCreated: 1437418416037,
- timePasswordChanged: 1437418416037,
- timesUsed: 1,
- },
- {
- id: 2,
- username: "username@gmail.com",
- password: "password2",
- hostname: "https://accounts.google.com",
- formSubmitURL: "https://accounts.google.com",
- httpRealm: null,
- usernameField: "Email",
- passwordField: "Passwd",
- timeCreated: 1437418446598,
- timePasswordChanged: 1437418446598,
- timesUsed: 6,
- },
- {
- id: 3,
- username: "username",
- password: "password3",
- hostname: "https://www.facebook.com",
- formSubmitURL: "https://www.facebook.com",
- httpRealm: null,
- usernameField: "email",
- passwordField: "pass",
- timeCreated: 1437418478851,
- timePasswordChanged: 1437418478851,
- timesUsed: 1,
- },
- {
- id: 4,
- username: "user",
- password: "password",
- hostname: "http://httpbin.org",
- formSubmitURL: null,
- httpRealm: "me@kennethreitz.com", // Digest auth.
- usernameField: "",
- passwordField: "",
- timeCreated: 1437787462368,
- timePasswordChanged: 1437787462368,
- timesUsed: 1,
- },
- {
- id: 5,
- username: "buser",
- password: "bpassword",
- hostname: "http://httpbin.org",
- formSubmitURL: null,
- httpRealm: "Fake Realm", // Basic auth.
- usernameField: "",
- passwordField: "",
- timeCreated: 1437787539233,
- timePasswordChanged: 1437787539233,
- timesUsed: 1,
- },
-];
-
-var crypto = new OSCrypto();
-var dbConn;
-
-function promiseSetPassword(login) {
- return new Promise((resolve, reject) => {
- let stmt = dbConn.createAsyncStatement(`
- UPDATE logins
- SET password_value = :password_value
- WHERE rowid = :rowid
- `);
- let passwordValue = crypto.stringToArray(crypto.encryptData(login.password));
- stmt.bindBlobByName("password_value", passwordValue, passwordValue.length);
- stmt.params.rowid = login.id;
-
- stmt.executeAsync({
- handleError(aError) {
- reject("Error with the query: " + aError.message);
- },
-
- handleCompletion(aReason) {
- if (aReason === Ci.mozIStorageStatementCallback.REASON_FINISHED) {
- resolve();
- } else {
- reject("Query has failed: " + aReason);
- }
- },
- });
- stmt.finalize();
- });
-}
-
-function checkLoginsAreEqual(passwordManagerLogin, chromeLogin, id) {
- passwordManagerLogin.QueryInterface(Ci.nsILoginMetaInfo);
-
- Assert.equal(passwordManagerLogin.username, chromeLogin.username,
- "The two logins ID " + id + " have the same username");
- Assert.equal(passwordManagerLogin.password, chromeLogin.password,
- "The two logins ID " + id + " have the same password");
- Assert.equal(passwordManagerLogin.hostname, chromeLogin.hostname,
- "The two logins ID " + id + " have the same hostname");
- Assert.equal(passwordManagerLogin.formSubmitURL, chromeLogin.formSubmitURL,
- "The two logins ID " + id + " have the same formSubmitURL");
- Assert.equal(passwordManagerLogin.httpRealm, chromeLogin.httpRealm,
- "The two logins ID " + id + " have the same httpRealm");
- Assert.equal(passwordManagerLogin.usernameField, chromeLogin.usernameField,
- "The two logins ID " + id + " have the same usernameElement");
- Assert.equal(passwordManagerLogin.passwordField, chromeLogin.passwordField,
- "The two logins ID " + id + " have the same passwordElement");
- Assert.equal(passwordManagerLogin.timeCreated, chromeLogin.timeCreated,
- "The two logins ID " + id + " have the same timeCreated");
- Assert.equal(passwordManagerLogin.timePasswordChanged, chromeLogin.timePasswordChanged,
- "The two logins ID " + id + " have the same timePasswordChanged");
- Assert.equal(passwordManagerLogin.timesUsed, chromeLogin.timesUsed,
- "The two logins ID " + id + " have the same timesUsed");
-}
-
-function generateDifferentLogin(login) {
- let newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
-
- newLogin.init(login.hostname, login.formSubmitURL, null,
- login.username, login.password + 1, login.usernameField + 1,
- login.passwordField + 1);
- newLogin.QueryInterface(Ci.nsILoginMetaInfo);
- newLogin.timeCreated = login.timeCreated + 1;
- newLogin.timePasswordChanged = login.timePasswordChanged + 1;
- newLogin.timesUsed = login.timesUsed + 1;
- return newLogin;
-}
-
-add_task(function* setup() {
- let loginDataFile = do_get_file("AppData/Local/Google/Chrome/User Data/Default/Login Data");
- dbConn = Services.storage.openUnsharedDatabase(loginDataFile);
- registerFakePath("LocalAppData", do_get_file("AppData/Local/"));
-
- do_register_cleanup(() => {
- Services.logins.removeAllLogins();
- dbConn.asyncClose();
- crypto.finalize();
- });
-});
-
-add_task(function* test_importIntoEmptyDB() {
- for (let login of TEST_LOGINS) {
- yield promiseSetPassword(login);
- }
-
- let migrator = MigrationUtils.getMigrator("chrome");
- Assert.ok(migrator.sourceExists, "Sanity check the source exists");
-
- let logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, 0, "There are no logins initially");
-
- // Migrate the logins.
- yield promiseMigration(migrator, MigrationUtils.resourceTypes.PASSWORDS, PROFILE);
-
- logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, TEST_LOGINS.length, "Check login count after importing the data");
- Assert.equal(logins.length, MigrationUtils._importQuantities.logins,
- "Check telemetry matches the actual import.");
-
- for (let i = 0; i < TEST_LOGINS.length; i++) {
- checkLoginsAreEqual(logins[i], TEST_LOGINS[i], i + 1);
- }
-});
-
-// Test that existing logins for the same primary key don't get overwritten
-add_task(function* test_importExistingLogins() {
- let migrator = MigrationUtils.getMigrator("chrome");
- Assert.ok(migrator.sourceExists, "Sanity check the source exists");
-
- Services.logins.removeAllLogins();
- let logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, 0, "There are no logins after removing all of them");
-
- let newLogins = [];
-
- // Create 3 new logins that are different but where the key properties are still the same.
- for (let i = 0; i < 3; i++) {
- newLogins.push(generateDifferentLogin(TEST_LOGINS[i]));
- Services.logins.addLogin(newLogins[i]);
- }
-
- logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, newLogins.length, "Check login count after the insertion");
-
- for (let i = 0; i < newLogins.length; i++) {
- checkLoginsAreEqual(logins[i], newLogins[i], i + 1);
- }
- // Migrate the logins.
- yield promiseMigration(migrator, MigrationUtils.resourceTypes.PASSWORDS, PROFILE);
-
- logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, TEST_LOGINS.length,
- "Check there are still the same number of logins after re-importing the data");
- Assert.equal(logins.length, MigrationUtils._importQuantities.logins,
- "Check telemetry matches the actual import.");
-
- for (let i = 0; i < newLogins.length; i++) {
- checkLoginsAreEqual(logins[i], newLogins[i], i + 1);
- }
-});
diff --git a/browser/components/migration/tests/unit/test_Edge_availability.js b/browser/components/migration/tests/unit/test_Edge_availability.js
deleted file mode 100644
index dba0e27bb..000000000
--- a/browser/components/migration/tests/unit/test_Edge_availability.js
+++ /dev/null
@@ -1,20 +0,0 @@
-"use strict";
-
-const EDGE_AVAILABLE_MIGRATIONS =
- MigrationUtils.resourceTypes.COOKIES |
- MigrationUtils.resourceTypes.BOOKMARKS |
- MigrationUtils.resourceTypes.HISTORY |
- MigrationUtils.resourceTypes.PASSWORDS;
-
-add_task(function* () {
- let migrator = MigrationUtils.getMigrator("edge");
- Cu.import("resource://gre/modules/AppConstants.jsm");
- Assert.equal(!!(migrator && migrator.sourceExists), AppConstants.isPlatformAndVersionAtLeast("win", "10"),
- "Edge should be available for migration if and only if we're on Win 10+");
- if (migrator) {
- let migratableData = migrator.getMigrateData(null, false);
- Assert.equal(migratableData, EDGE_AVAILABLE_MIGRATIONS,
- "All the data types we expect should be available");
- }
-});
-
diff --git a/browser/components/migration/tests/unit/test_Edge_db_migration.js b/browser/components/migration/tests/unit/test_Edge_db_migration.js
deleted file mode 100644
index 56ff612d5..000000000
--- a/browser/components/migration/tests/unit/test_Edge_db_migration.js
+++ /dev/null
@@ -1,471 +0,0 @@
-"use strict";
-
-Cu.import("resource://gre/modules/ctypes.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-let eseBackStage = Cu.import("resource:///modules/ESEDBReader.jsm");
-let ESE = eseBackStage.ESE;
-let KERNEL = eseBackStage.KERNEL;
-let gLibs = eseBackStage.gLibs;
-let COLUMN_TYPES = eseBackStage.COLUMN_TYPES;
-let declareESEFunction = eseBackStage.declareESEFunction;
-let loadLibraries = eseBackStage.loadLibraries;
-
-let gESEInstanceCounter = 1;
-
-ESE.JET_COLUMNCREATE_W = new ctypes.StructType("JET_COLUMNCREATE_W", [
- {"cbStruct": ctypes.unsigned_long},
- {"szColumnName": ESE.JET_PCWSTR},
- {"coltyp": ESE.JET_COLTYP },
- {"cbMax": ctypes.unsigned_long },
- {"grbit": ESE.JET_GRBIT },
- {"pvDefault": ctypes.voidptr_t},
- {"cbDefault": ctypes.unsigned_long },
- {"cp": ctypes.unsigned_long },
- {"columnid": ESE.JET_COLUMNID},
- {"err": ESE.JET_ERR},
-]);
-
-function createColumnCreationWrapper({name, type, cbMax}) {
- // We use a wrapper object because we need to be sure the JS engine won't GC
- // data that we're "only" pointing to.
- let wrapper = {};
- wrapper.column = new ESE.JET_COLUMNCREATE_W();
- wrapper.column.cbStruct = ESE.JET_COLUMNCREATE_W.size;
- let wchar_tArray = ctypes.ArrayType(ctypes.char16_t);
- wrapper.name = new wchar_tArray(name.length + 1);
- wrapper.name.value = String(name);
- wrapper.column.szColumnName = wrapper.name;
- wrapper.column.coltyp = type;
- let fallback = 0;
- switch (type) {
- case COLUMN_TYPES.JET_coltypText:
- fallback = 255;
- // Intentional fall-through
- case COLUMN_TYPES.JET_coltypLongText:
- wrapper.column.cbMax = cbMax || fallback || 64 * 1024;
- break;
- case COLUMN_TYPES.JET_coltypGUID:
- wrapper.column.cbMax = 16;
- break;
- case COLUMN_TYPES.JET_coltypBit:
- wrapper.column.cbMax = 1;
- break;
- case COLUMN_TYPES.JET_coltypLongLong:
- wrapper.column.cbMax = 8;
- break;
- default:
- throw new Error("Unknown column type!");
- }
-
- wrapper.column.columnid = new ESE.JET_COLUMNID();
- wrapper.column.grbit = 0;
- wrapper.column.pvDefault = null;
- wrapper.column.cbDefault = 0;
- wrapper.column.cp = 0;
-
- return wrapper;
-}
-
-// "forward declarations" of indexcreate and setinfo structs, which we don't use.
-ESE.JET_INDEXCREATE = new ctypes.StructType("JET_INDEXCREATE");
-ESE.JET_SETINFO = new ctypes.StructType("JET_SETINFO");
-
-ESE.JET_TABLECREATE_W = new ctypes.StructType("JET_TABLECREATE_W", [
- {"cbStruct": ctypes.unsigned_long},
- {"szTableName": ESE.JET_PCWSTR},
- {"szTemplateTableName": ESE.JET_PCWSTR},
- {"ulPages": ctypes.unsigned_long},
- {"ulDensity": ctypes.unsigned_long},
- {"rgcolumncreate": ESE.JET_COLUMNCREATE_W.ptr},
- {"cColumns": ctypes.unsigned_long},
- {"rgindexcreate": ESE.JET_INDEXCREATE.ptr},
- {"cIndexes": ctypes.unsigned_long},
- {"grbit": ESE.JET_GRBIT},
- {"tableid": ESE.JET_TABLEID},
- {"cCreated": ctypes.unsigned_long},
-]);
-
-function createTableCreationWrapper(tableName, columns) {
- let wrapper = {};
- let wchar_tArray = ctypes.ArrayType(ctypes.char16_t);
- wrapper.name = new wchar_tArray(tableName.length + 1);
- wrapper.name.value = String(tableName);
- wrapper.table = new ESE.JET_TABLECREATE_W();
- wrapper.table.cbStruct = ESE.JET_TABLECREATE_W.size;
- wrapper.table.szTableName = wrapper.name;
- wrapper.table.szTemplateTableName = null;
- wrapper.table.ulPages = 1;
- wrapper.table.ulDensity = 0;
- let columnArrayType = ESE.JET_COLUMNCREATE_W.array(columns.length);
- wrapper.columnAry = new columnArrayType();
- wrapper.table.rgcolumncreate = wrapper.columnAry.addressOfElement(0);
- wrapper.table.cColumns = columns.length;
- wrapper.columns = [];
- for (let i = 0; i < columns.length; i++) {
- let column = columns[i];
- let columnWrapper = createColumnCreationWrapper(column);
- wrapper.columnAry.addressOfElement(i).contents = columnWrapper.column;
- wrapper.columns.push(columnWrapper);
- }
- wrapper.table.rgindexcreate = null;
- wrapper.table.cIndexes = 0;
- return wrapper;
-}
-
-function convertValueForWriting(value, valueType) {
- let buffer;
- let valueOfValueType = ctypes.UInt64.lo(valueType);
- switch (valueOfValueType) {
- case COLUMN_TYPES.JET_coltypLongLong:
- if (value instanceof Date) {
- buffer = new KERNEL.FILETIME();
- let sysTime = new KERNEL.SYSTEMTIME();
- sysTime.wYear = value.getUTCFullYear();
- sysTime.wMonth = value.getUTCMonth() + 1;
- sysTime.wDay = value.getUTCDate();
- sysTime.wHour = value.getUTCHours();
- sysTime.wMinute = value.getUTCMinutes();
- sysTime.wSecond = value.getUTCSeconds();
- sysTime.wMilliseconds = value.getUTCMilliseconds();
- let rv = KERNEL.SystemTimeToFileTime(sysTime.address(), buffer.address());
- if (!rv) {
- throw new Error("Failed to get FileTime.");
- }
- return [buffer, KERNEL.FILETIME.size];
- }
- throw new Error("Unrecognized value for longlong column");
- case COLUMN_TYPES.JET_coltypLongText:
- let wchar_tArray = ctypes.ArrayType(ctypes.char16_t);
- buffer = new wchar_tArray(value.length + 1);
- buffer.value = String(value);
- return [buffer, buffer.length * 2];
- case COLUMN_TYPES.JET_coltypBit:
- buffer = new ctypes.uint8_t();
- // Bizarre boolean values, but whatever:
- buffer.value = value ? 255 : 0;
- return [buffer, 1];
- case COLUMN_TYPES.JET_coltypGUID:
- let byteArray = ctypes.ArrayType(ctypes.uint8_t);
- buffer = new byteArray(16);
- let j = 0;
- for (let i = 0; i < value.length; i++) {
- if (!(/[0-9a-f]/i).test(value[i])) {
- continue;
- }
- let byteAsHex = value.substr(i, 2);
- buffer[j++] = parseInt(byteAsHex, 16);
- i++;
- }
- return [buffer, 16];
- }
-
- throw new Error("Unknown type " + valueType);
-}
-
-let initializedESE = false;
-
-let eseDBWritingHelpers = {
- setupDB(dbFile, tableName, columns, rows) {
- if (!initializedESE) {
- initializedESE = true;
- loadLibraries();
-
- KERNEL.SystemTimeToFileTime = gLibs.kernel.declare("SystemTimeToFileTime",
- ctypes.default_abi, ctypes.bool, KERNEL.SYSTEMTIME.ptr, KERNEL.FILETIME.ptr);
-
- declareESEFunction("CreateDatabaseW", ESE.JET_SESID, ESE.JET_PCWSTR,
- ESE.JET_PCWSTR, ESE.JET_DBID.ptr, ESE.JET_GRBIT);
- declareESEFunction("CreateTableColumnIndexW", ESE.JET_SESID, ESE.JET_DBID,
- ESE.JET_TABLECREATE_W.ptr);
- declareESEFunction("BeginTransaction", ESE.JET_SESID);
- declareESEFunction("CommitTransaction", ESE.JET_SESID, ESE.JET_GRBIT);
- declareESEFunction("PrepareUpdate", ESE.JET_SESID, ESE.JET_TABLEID,
- ctypes.unsigned_long);
- declareESEFunction("Update", ESE.JET_SESID, ESE.JET_TABLEID,
- ctypes.voidptr_t, ctypes.unsigned_long,
- ctypes.unsigned_long.ptr);
- declareESEFunction("SetColumn", ESE.JET_SESID, ESE.JET_TABLEID,
- ESE.JET_COLUMNID, ctypes.voidptr_t,
- ctypes.unsigned_long, ESE.JET_GRBIT, ESE.JET_SETINFO.ptr);
- ESE.SetSystemParameterW(null, 0, 64 /* JET_paramDatabasePageSize*/,
- 8192, null);
- }
-
- let rootPath = dbFile.parent.path + "\\";
- let logPath = rootPath + "LogFiles\\";
-
- try {
- this._instanceId = new ESE.JET_INSTANCE();
- ESE.CreateInstanceW(this._instanceId.address(),
- "firefox-dbwriter-" + (gESEInstanceCounter++));
- this._instanceCreated = true;
-
- ESE.SetSystemParameterW(this._instanceId.address(), 0,
- 0 /* JET_paramSystemPath*/, 0, rootPath);
- ESE.SetSystemParameterW(this._instanceId.address(), 0,
- 1 /* JET_paramTempPath */, 0, rootPath);
- ESE.SetSystemParameterW(this._instanceId.address(), 0,
- 2 /* JET_paramLogFilePath*/, 0, logPath);
- // Shouldn't try to call JetTerm if the following call fails.
- this._instanceCreated = false;
- ESE.Init(this._instanceId.address());
- this._instanceCreated = true;
- this._sessionId = new ESE.JET_SESID();
- ESE.BeginSessionW(this._instanceId, this._sessionId.address(), null,
- null);
- this._sessionCreated = true;
-
- this._dbId = new ESE.JET_DBID();
- this._dbPath = rootPath + "spartan.edb";
- ESE.CreateDatabaseW(this._sessionId, this._dbPath, null,
- this._dbId.address(), 0);
- this._opened = this._attached = true;
-
- let tableCreationWrapper = createTableCreationWrapper(tableName, columns);
- ESE.CreateTableColumnIndexW(this._sessionId, this._dbId,
- tableCreationWrapper.table.address());
- this._tableId = tableCreationWrapper.table.tableid;
-
- let columnIdMap = new Map();
- if (rows.length) {
- // Iterate over the struct we passed into ESENT because they have the
- // created column ids.
- let columnCount = ctypes.UInt64.lo(tableCreationWrapper.table.cColumns);
- let columnsPassed = tableCreationWrapper.table.rgcolumncreate;
- for (let i = 0; i < columnCount; i++) {
- let column = columnsPassed.contents;
- columnIdMap.set(column.szColumnName.readString(), column);
- columnsPassed = columnsPassed.increment();
- }
- ESE.ManualMove(this._sessionId, this._tableId,
- -2147483648 /* JET_MoveFirst */, 0);
- ESE.BeginTransaction(this._sessionId);
- for (let row of rows) {
- ESE.PrepareUpdate(this._sessionId, this._tableId, 0 /* JET_prepInsert */);
- for (let columnName in row) {
- let col = columnIdMap.get(columnName);
- let colId = col.columnid;
- let [val, valSize] = convertValueForWriting(row[columnName], col.coltyp);
- /* JET_bitSetOverwriteLV */
- ESE.SetColumn(this._sessionId, this._tableId, colId, val.address(), valSize, 4, null);
- }
- let actualBookmarkSize = new ctypes.unsigned_long();
- ESE.Update(this._sessionId, this._tableId, null, 0, actualBookmarkSize.address());
- }
- ESE.CommitTransaction(this._sessionId, 0 /* JET_bitWaitLastLevel0Commit */);
- }
- } finally {
- try {
- this._close();
- } catch (ex) {
- Cu.reportError(ex);
- }
- }
- },
-
- _close() {
- if (this._tableId) {
- ESE.FailSafeCloseTable(this._sessionId, this._tableId);
- delete this._tableId;
- }
- if (this._opened) {
- ESE.FailSafeCloseDatabase(this._sessionId, this._dbId, 0);
- this._opened = false;
- }
- if (this._attached) {
- ESE.FailSafeDetachDatabaseW(this._sessionId, this._dbPath);
- this._attached = false;
- }
- if (this._sessionCreated) {
- ESE.FailSafeEndSession(this._sessionId, 0);
- this._sessionCreated = false;
- }
- if (this._instanceCreated) {
- ESE.FailSafeTerm(this._instanceId);
- this._instanceCreated = false;
- }
- },
-};
-
-add_task(function*() {
- let tempFile = Services.dirsvc.get("TmpD", Ci.nsIFile);
- tempFile.append("fx-xpcshell-edge-db");
- tempFile.createUnique(tempFile.DIRECTORY_TYPE, 0o600);
-
- let db = tempFile.clone();
- db.append("spartan.edb");
-
- let logs = tempFile.clone();
- logs.append("LogFiles");
- logs.create(tempFile.DIRECTORY_TYPE, 0o600);
-
- let creationDate = new Date(Date.now() - 5000);
- const kEdgeMenuParent = "62d07e2b-5f0d-4e41-8426-5f5ec9717beb";
- let itemsInDB = [
- {
- URL: "http://www.mozilla.org/",
- Title: "Mozilla",
- DateUpdated: new Date(creationDate.valueOf() + 100),
- ItemId: "1c00c10a-15f6-4618-92dd-22575102a4da",
- ParentId: kEdgeMenuParent,
- IsFolder: false,
- IsDeleted: false,
- },
- {
- Title: "Folder",
- DateUpdated: new Date(creationDate.valueOf() + 200),
- ItemId: "564b21f2-05d6-4f7d-8499-304d00ccc3aa",
- ParentId: kEdgeMenuParent,
- IsFolder: true,
- IsDeleted: false,
- },
- {
- Title: "Item in folder",
- URL: "http://www.iteminfolder.org/",
- DateUpdated: new Date(creationDate.valueOf() + 300),
- ItemId: "c295ddaf-04a1-424a-866c-0ebde011e7c8",
- ParentId: "564b21f2-05d6-4f7d-8499-304d00ccc3aa",
- IsFolder: false,
- IsDeleted: false,
- },
- {
- Title: "Deleted folder",
- DateUpdated: new Date(creationDate.valueOf() + 400),
- ItemId: "a547573c-4d4d-4406-a736-5b5462d93bca",
- ParentId: kEdgeMenuParent,
- IsFolder: true,
- IsDeleted: true,
- },
- {
- Title: "Deleted item",
- URL: "http://www.deleteditem.org/",
- DateUpdated: new Date(creationDate.valueOf() + 500),
- ItemId: "37a574bb-b44b-4bbc-a414-908615536435",
- ParentId: kEdgeMenuParent,
- IsFolder: false,
- IsDeleted: true,
- },
- {
- Title: "Item in deleted folder (should be in root)",
- URL: "http://www.itemindeletedfolder.org/",
- DateUpdated: new Date(creationDate.valueOf() + 600),
- ItemId: "74dd1cc3-4c5d-471f-bccc-7bc7c72fa621",
- ParentId: "a547573c-4d4d-4406-a736-5b5462d93bca",
- IsFolder: false,
- IsDeleted: false,
- },
- {
- Title: "_Favorites_Bar_",
- DateUpdated: new Date(creationDate.valueOf() + 700),
- ItemId: "921dc8a0-6c83-40ef-8df1-9bd1c5c56aaf",
- ParentId: kEdgeMenuParent,
- IsFolder: true,
- IsDeleted: false,
- },
- {
- Title: "Item in favorites bar",
- URL: "http://www.iteminfavoritesbar.org/",
- DateUpdated: new Date(creationDate.valueOf() + 800),
- ItemId: "9f2b1ff8-b651-46cf-8f41-16da8bcb6791",
- ParentId: "921dc8a0-6c83-40ef-8df1-9bd1c5c56aaf",
- IsFolder: false,
- IsDeleted: false,
- },
- ];
- eseDBWritingHelpers.setupDB(db, "Favorites", [
- {type: COLUMN_TYPES.JET_coltypLongText, name: "URL", cbMax: 4096},
- {type: COLUMN_TYPES.JET_coltypLongText, name: "Title", cbMax: 4096},
- {type: COLUMN_TYPES.JET_coltypLongLong, name: "DateUpdated"},
- {type: COLUMN_TYPES.JET_coltypGUID, name: "ItemId"},
- {type: COLUMN_TYPES.JET_coltypBit, name: "IsDeleted"},
- {type: COLUMN_TYPES.JET_coltypBit, name: "IsFolder"},
- {type: COLUMN_TYPES.JET_coltypGUID, name: "ParentId"},
- ], itemsInDB);
-
- let migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=edge"]
- .createInstance(Ci.nsIBrowserProfileMigrator);
- let bookmarksMigrator = migrator.wrappedJSObject.getESEMigratorForTesting(db);
- Assert.ok(bookmarksMigrator.exists, "Should recognize table we just created");
-
- let source = MigrationUtils.getLocalizedString("sourceNameEdge");
- let sourceLabel = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]);
-
- let seenBookmarks = [];
- let bookmarkObserver = {
- onItemAdded(itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid) {
- if (title.startsWith("Deleted")) {
- ok(false, "Should not see deleted items being bookmarked!");
- }
- seenBookmarks.push({itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid});
- },
- onBeginUpdateBatch() {},
- onEndUpdateBatch() {},
- onItemRemoved() {},
- onItemChanged() {},
- onItemVisited() {},
- onItemMoved() {},
- };
- PlacesUtils.bookmarks.addObserver(bookmarkObserver, false);
-
- let migrateResult = yield new Promise(resolve => bookmarksMigrator.migrate(resolve)).catch(ex => {
- Cu.reportError(ex);
- Assert.ok(false, "Got an exception trying to migrate data! " + ex);
- return false;
- });
- PlacesUtils.bookmarks.removeObserver(bookmarkObserver);
- Assert.ok(migrateResult, "Migration should succeed");
- Assert.equal(seenBookmarks.length, 7, "Should have seen 7 items being bookmarked.");
- Assert.equal(seenBookmarks.filter(bm => bm.title != sourceLabel).length,
- MigrationUtils._importQuantities.bookmarks,
- "Telemetry should have items except for 'From Microsoft Edge' folders");
-
- let menuParents = seenBookmarks.filter(item => item.parentGuid == PlacesUtils.bookmarks.menuGuid);
- Assert.equal(menuParents.length, 1, "Should have a single folder added to the menu");
- let toolbarParents = seenBookmarks.filter(item => item.parentGuid == PlacesUtils.bookmarks.toolbarGuid);
- Assert.equal(toolbarParents.length, 1, "Should have a single item added to the toolbar");
- let menuParentGuid = menuParents[0].itemGuid;
- let toolbarParentGuid = toolbarParents[0].itemGuid;
-
- let expectedTitlesInMenu = itemsInDB.filter(item => item.ParentId == kEdgeMenuParent).map(item => item.Title);
- // Hacky, but seems like much the simplest way:
- expectedTitlesInMenu.push("Item in deleted folder (should be in root)");
- let expectedTitlesInToolbar = itemsInDB.filter(item => item.ParentId == "921dc8a0-6c83-40ef-8df1-9bd1c5c56aaf").map(item => item.Title);
-
- let edgeNameStr = MigrationUtils.getLocalizedString("sourceNameEdge");
- let importParentFolderName = MigrationUtils.getLocalizedString("importedBookmarksFolder", [edgeNameStr]);
-
- for (let bookmark of seenBookmarks) {
- let shouldBeInMenu = expectedTitlesInMenu.includes(bookmark.title);
- let shouldBeInToolbar = expectedTitlesInToolbar.includes(bookmark.title);
- if (bookmark.title == "Folder" || bookmark.title == importParentFolderName) {
- Assert.equal(bookmark.itemType, PlacesUtils.bookmarks.TYPE_FOLDER,
- "Bookmark " + bookmark.title + " should be a folder");
- } else {
- Assert.notEqual(bookmark.itemType, PlacesUtils.bookmarks.TYPE_FOLDER,
- "Bookmark " + bookmark.title + " should not be a folder");
- }
-
- if (shouldBeInMenu) {
- Assert.equal(bookmark.parentGuid, menuParentGuid, "Item '" + bookmark.title + "' should be in menu");
- } else if (shouldBeInToolbar) {
- Assert.equal(bookmark.parentGuid, toolbarParentGuid, "Item '" + bookmark.title + "' should be in toolbar");
- } else if (bookmark.itemGuid == menuParentGuid || bookmark.itemGuid == toolbarParentGuid) {
- Assert.ok(true, "Expect toolbar and menu folders to not be in menu or toolbar");
- } else {
- // Bit hacky, but we do need to check this.
- Assert.equal(bookmark.title, "Item in folder", "Subfoldered item shouldn't be in menu or toolbar");
- let parent = seenBookmarks.find(maybeParent => maybeParent.itemGuid == bookmark.parentGuid);
- Assert.equal(parent && parent.title, "Folder", "Subfoldered item should be in subfolder labeled 'Folder'");
- }
-
- let dbItem = itemsInDB.find(someItem => bookmark.title == someItem.Title);
- if (!dbItem) {
- Assert.equal(bookmark.title, importParentFolderName, "Only the extra layer of folders isn't in the input we stuck in the DB.");
- Assert.ok([menuParentGuid, toolbarParentGuid].includes(bookmark.itemGuid), "This item should be one of the containers");
- } else {
- Assert.equal(dbItem.URL || null, bookmark.url && bookmark.url.spec, "URL is correct");
- Assert.equal(dbItem.DateUpdated.valueOf(), (new Date(bookmark.dateAdded / 1000)).valueOf(), "Date added is correct");
- }
- }
-});
-
diff --git a/browser/components/migration/tests/unit/test_IE7_passwords.js b/browser/components/migration/tests/unit/test_IE7_passwords.js
deleted file mode 100644
index 1ce016a7d..000000000
--- a/browser/components/migration/tests/unit/test_IE7_passwords.js
+++ /dev/null
@@ -1,397 +0,0 @@
-"use strict";
-
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry",
- "resource://gre/modules/WindowsRegistry.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto",
- "resource://gre/modules/OSCrypto.jsm");
-
-const IE7_FORM_PASSWORDS_MIGRATOR_NAME = "IE7FormPasswords";
-const LOGINS_KEY = "Software\\Microsoft\\Internet Explorer\\IntelliForms\\Storage2";
-const EXTENSION = "-backup";
-const TESTED_WEBSITES = {
- twitter: {
- uri: makeURI("https://twitter.com"),
- hash: "A89D42BC6406E27265B1AD0782B6F376375764A301",
- data: [12, 0, 0, 0, 56, 0, 0, 0, 38, 0, 0, 0, 87, 73, 67, 75, 24, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 36, 67, 124, 118, 212, 208, 1, 8, 0, 0, 0, 18, 0, 0, 0, 68, 36, 67, 124, 118, 212, 208, 1, 9, 0, 0, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 0, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 0, 0],
- logins: [
- {
- username: "abcdefgh",
- password: "123456789",
- hostname: "https://twitter.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439325854000,
- timeLastUsed: 1439325854000,
- timePasswordChanged: 1439325854000,
- timesUsed: 1,
- },
- ],
- },
- facebook: {
- uri: makeURI("https://www.facebook.com/"),
- hash: "EF44D3E034009CB0FD1B1D81A1FF3F3335213BD796",
- data: [12, 0, 0, 0, 152, 0, 0, 0, 160, 0, 0, 0, 87, 73, 67, 75, 24, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 182, 125, 18, 121, 212, 208, 1, 9, 0, 0, 0, 20, 0, 0, 0, 88, 182, 125, 18, 121, 212, 208, 1, 9, 0, 0, 0, 40, 0, 0, 0, 134, 65, 33, 37, 121, 212, 208, 1, 9, 0, 0, 0, 60, 0, 0, 0, 134, 65, 33, 37, 121, 212, 208, 1, 9, 0, 0, 0, 80, 0, 0, 0, 45, 242, 246, 62, 121, 212, 208, 1, 9, 0, 0, 0, 100, 0, 0, 0, 45, 242, 246, 62, 121, 212, 208, 1, 9, 0, 0, 0, 120, 0, 0, 0, 28, 10, 193, 80, 121, 212, 208, 1, 9, 0, 0, 0, 140, 0, 0, 0, 28, 10, 193, 80, 121, 212, 208, 1, 9, 0, 0, 0, 117, 0, 115, 0, 101, 0, 114, 0, 110, 0, 97, 0, 109, 0, 101, 0, 48, 0, 0, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 48, 0, 0, 0, 117, 0, 115, 0, 101, 0, 114, 0, 110, 0, 97, 0, 109, 0, 101, 0, 49, 0, 0, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 49, 0, 0, 0, 117, 0, 115, 0, 101, 0, 114, 0, 110, 0, 97, 0, 109, 0, 101, 0, 50, 0, 0, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 50, 0, 0, 0, 117, 0, 115, 0, 101, 0, 114, 0, 110, 0, 97, 0, 109, 0, 101, 0, 51, 0, 0, 0, 112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 51, 0, 0, 0],
- logins: [
- {
- username: "username0",
- password: "password0",
- hostname: "https://www.facebook.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439326966000,
- timeLastUsed: 1439326966000,
- timePasswordChanged: 1439326966000,
- timesUsed: 1,
- },
- {
- username: "username1",
- password: "password1",
- hostname: "https://www.facebook.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439326997000,
- timeLastUsed: 1439326997000,
- timePasswordChanged: 1439326997000,
- timesUsed: 1,
- },
- {
- username: "username2",
- password: "password2",
- hostname: "https://www.facebook.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439327040000,
- timeLastUsed: 1439327040000,
- timePasswordChanged: 1439327040000,
- timesUsed: 1,
- },
- {
- username: "username3",
- password: "password3",
- hostname: "https://www.facebook.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439327070000,
- timeLastUsed: 1439327070000,
- timePasswordChanged: 1439327070000,
- timesUsed: 1,
- },
- ],
- },
- live: {
- uri: makeURI("https://login.live.com/"),
- hash: "7B506F2D6B81D939A8E0456F036EE8970856FF705E",
- data: [12, 0, 0, 0, 56, 0, 0, 0, 44, 0, 0, 0, 87, 73, 67, 75, 24, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 17, 219, 140, 148, 212, 208, 1, 9, 0, 0, 0, 20, 0, 0, 0, 212, 17, 219, 140, 148, 212, 208, 1, 11, 0, 0, 0, 114, 0, 105, 0, 97, 0, 100, 0, 104, 0, 49, 6, 74, 6, 39, 6, 54, 6, 0, 0, 39, 6, 66, 6, 49, 6, 35, 6, 80, 0, 192, 0, 223, 0, 119, 0, 246, 0, 114, 0, 100, 0, 0, 0],
- logins: [
- {
- username: "riadhرياض",
- password: "اقرأPÀßwörd",
- hostname: "https://login.live.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439338767000,
- timeLastUsed: 1439338767000,
- timePasswordChanged: 1439338767000,
- timesUsed: 1,
- },
- ],
- },
- reddit: {
- uri: makeURI("http://www.reddit.com/"),
- hash: "B644028D1C109A91EC2C4B9D1F145E55A1FAE42065",
- data: [12, 0, 0, 0, 152, 0, 0, 0, 212, 0, 0, 0, 87, 73, 67, 75, 24, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 8, 234, 114, 153, 212, 208, 1, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 97, 93, 131, 116, 153, 212, 208, 1, 3, 0, 0, 0, 14, 0, 0, 0, 97, 93, 131, 116, 153, 212, 208, 1, 16, 0, 0, 0, 48, 0, 0, 0, 88, 150, 78, 174, 153, 212, 208, 1, 4, 0, 0, 0, 58, 0, 0, 0, 88, 150, 78, 174, 153, 212, 208, 1, 29, 0, 0, 0, 118, 0, 0, 0, 79, 102, 137, 34, 154, 212, 208, 1, 15, 0, 0, 0, 150, 0, 0, 0, 79, 102, 137, 34, 154, 212, 208, 1, 30, 0, 0, 0, 97, 0, 0, 0, 0, 0, 252, 140, 173, 138, 146, 48, 0, 0, 66, 0, 105, 0, 116, 0, 116, 0, 101, 0, 32, 0, 98, 0, 101, 0, 115, 0, 116, 0, 228, 0, 116, 0, 105, 0, 103, 0, 101, 0, 110, 0, 0, 0, 205, 145, 110, 127, 198, 91, 1, 120, 0, 0, 31, 4, 48, 4, 64, 4, 62, 4, 59, 4, 76, 4, 32, 0, 67, 4, 65, 4, 63, 4, 53, 4, 72, 4, 61, 4, 62, 4, 32, 0, 65, 4, 49, 4, 64, 4, 62, 4, 72, 4, 53, 4, 61, 4, 46, 0, 32, 0, 18, 4, 62, 4, 57, 4, 66, 4, 56, 4, 0, 0, 40, 6, 51, 6, 69, 6, 32, 0, 39, 6, 68, 6, 68, 6, 71, 6, 32, 0, 39, 6, 68, 6, 49, 6, 45, 6, 69, 6, 70, 6, 0, 0, 118, 0, 101, 0, 117, 0, 105, 0, 108, 0, 108, 0, 101, 0, 122, 0, 32, 0, 108, 0, 101, 0, 32, 0, 118, 0, 233, 0, 114, 0, 105, 0, 102, 0, 105, 0, 101, 0, 114, 0, 32, 0, 224, 0, 32, 0, 110, 0, 111, 0, 117, 0, 118, 0, 101, 0, 97, 0, 117, 0, 0, 0],
- logins: [
- {
- username: "購読を",
- password: "Bitte bestätigen",
- hostname: "http://www.reddit.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439340874000,
- timeLastUsed: 1439340874000,
- timePasswordChanged: 1439340874000,
- timesUsed: 1,
- },
- {
- username: "é‡ç½®å¯†ç ",
- password: "Пароль уÑпешно Ñброшен. Войти",
- hostname: "http://www.reddit.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439340971000,
- timeLastUsed: 1439340971000,
- timePasswordChanged: 1439340971000,
- timesUsed: 1,
- },
- {
- username: "بسم الله الرحمن",
- password: "veuillez le vérifier à nouveau",
- hostname: "http://www.reddit.com",
- formSubmitURL: "",
- httpRealm: null,
- usernameField: "",
- passwordField: "",
- timeCreated: 1439341166000,
- timeLastUsed: 1439341166000,
- timePasswordChanged: 1439341166000,
- timesUsed: 1,
- },
- ],
- },
-};
-
-const TESTED_URLS = [
- "http://a.foo.com",
- "http://b.foo.com",
- "http://c.foo.com",
- "http://www.test.net",
- "http://www.test.net/home",
- "http://www.test.net/index",
- "https://a.bar.com",
- "https://b.bar.com",
- "https://c.bar.com",
-];
-
-var nsIWindowsRegKey = Ci.nsIWindowsRegKey;
-var Storage2Key;
-
-/*
- * If the key value exists, it's going to be backed up and replaced, so the value could be restored.
- * Otherwise a new value is going to be created.
- */
-function backupAndStore(key, name, value) {
- if (key.hasValue(name)) {
- // backup the the current value
- let type = key.getValueType(name);
- // create a new value using use the current value name followed by EXTENSION as its new name
- switch (type) {
- case nsIWindowsRegKey.TYPE_STRING:
- key.writeStringValue(name + EXTENSION, key.readStringValue(name));
- break;
- case nsIWindowsRegKey.TYPE_BINARY:
- key.writeBinaryValue(name + EXTENSION, key.readBinaryValue(name));
- break;
- case nsIWindowsRegKey.TYPE_INT:
- key.writeIntValue(name + EXTENSION, key.readIntValue(name));
- break;
- case nsIWindowsRegKey.TYPE_INT64:
- key.writeInt64Value(name + EXTENSION, key.readInt64Value(name));
- break;
- }
- }
- key.writeBinaryValue(name, value);
-}
-
-// Remove all values where their names are members of the names array from the key of registry
-function removeAllValues(key, names) {
- for (let name of names) {
- key.removeValue(name);
- }
-}
-
-// Restore all the backed up values
-function restore(key) {
- let count = key.valueCount;
- let names = []; // the names of the key values
- for (let i = 0; i < count; ++i) {
- names.push(key.getValueName(i));
- }
-
- for (let name of names) {
- // backed up values have EXTENSION at the end of their names
- if (name.lastIndexOf(EXTENSION) == name.length - EXTENSION.length) {
- let valueName = name.substr(0, name.length - EXTENSION.length);
- let type = key.getValueType(name);
- // create a new value using the name before the backup and removed the backed up one
- switch (type) {
- case nsIWindowsRegKey.TYPE_STRING:
- key.writeStringValue(valueName, key.readStringValue(name));
- key.removeValue(name);
- break;
- case nsIWindowsRegKey.TYPE_BINARY:
- key.writeBinaryValue(valueName, key.readBinaryValue(name));
- key.removeValue(name);
- break;
- case nsIWindowsRegKey.TYPE_INT:
- key.writeIntValue(valueName, key.readIntValue(name));
- key.removeValue(name);
- break;
- case nsIWindowsRegKey.TYPE_INT64:
- key.writeInt64Value(valueName, key.readInt64Value(name));
- key.removeValue(name);
- break;
- }
- }
- }
-}
-
-function checkLoginsAreEqual(passwordManagerLogin, IELogin, id) {
- passwordManagerLogin.QueryInterface(Ci.nsILoginMetaInfo);
- for (let attribute in IELogin) {
- Assert.equal(passwordManagerLogin[attribute], IELogin[attribute],
- "The two logins ID " + id + " have the same " + attribute);
- }
-}
-
-function createRegistryPath(path) {
- let loginPath = path.split("\\");
- let parentKey = Cc["@mozilla.org/windows-registry-key;1"].
- createInstance(nsIWindowsRegKey);
- let currentPath = [];
- for (let currentKey of loginPath) {
- parentKey.open(nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, currentPath.join("\\"),
- nsIWindowsRegKey.ACCESS_ALL);
-
- if (!parentKey.hasChild(currentKey)) {
- parentKey.createChild(currentKey, 0);
- }
- currentPath.push(currentKey);
- parentKey.close();
- }
-}
-
-function getFirstResourceOfType(type) {
- let migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=ie"]
- .createInstance(Ci.nsISupports)
- .wrappedJSObject;
- let migrators = migrator.getResources();
- for (let m of migrators) {
- if (m.name == IE7_FORM_PASSWORDS_MIGRATOR_NAME && m.type == type) {
- return m;
- }
- }
- throw new Error("failed to find the " + type + " migrator");
-}
-
-function makeURI(aURL) {
- return Services.io.newURI(aURL, null, null);
-}
-
-add_task(function* setup() {
- if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2")) {
- Assert.throws(() => getFirstResourceOfType(MigrationUtils.resourceTypes.PASSWORDS),
- "The migrator doesn't exist for win8+");
- return;
- }
- // create the path to Storage2 in the registry if it doest exist.
- createRegistryPath(LOGINS_KEY);
- Storage2Key = Cc["@mozilla.org/windows-registry-key;1"].
- createInstance(nsIWindowsRegKey);
- Storage2Key.open(nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, LOGINS_KEY,
- nsIWindowsRegKey.ACCESS_ALL);
-
- // create a dummy value otherwise the migrator doesn't exist
- if (!Storage2Key.hasValue("dummy")) {
- Storage2Key.writeBinaryValue("dummy", "dummy");
- }
-});
-
-add_task(function* test_passwordsNotAvailable() {
- if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2")) {
- return;
- }
-
- let migrator = getFirstResourceOfType(MigrationUtils.resourceTypes.PASSWORDS);
- Assert.ok(migrator.exists, "The migrator has to exist");
- let logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, 0, "There are no logins at the beginning of the test");
-
- let uris = []; // the uris of the migrated logins
- for (let url of TESTED_URLS) {
- uris.push(makeURI(url));
- // in this test, there is no IE login data in the registry, so after the migration, the number
- // of logins in the store should be 0
- migrator._migrateURIs(uris);
- logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, 0,
- "There are no logins after doing the migration without adding values to the registry");
- }
-});
-
-add_task(function* test_passwordsAvailable() {
- if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2")) {
- return;
- }
-
- let crypto = new OSCrypto();
- let hashes = []; // the hashes of all migrator websites, this is going to be used for the clean up
-
- do_register_cleanup(() => {
- Services.logins.removeAllLogins();
- logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, 0, "There are no logins after the cleanup");
- // remove all the values created in this test from the registry
- removeAllValues(Storage2Key, hashes);
- // restore all backed up values
- restore(Storage2Key);
-
- // clean the dummy value
- if (Storage2Key.hasValue("dummy")) {
- Storage2Key.removeValue("dummy");
- }
- Storage2Key.close();
- crypto.finalize();
- });
-
- let migrator = getFirstResourceOfType(MigrationUtils.resourceTypes.PASSWORDS);
- Assert.ok(migrator.exists, "The migrator has to exist");
- let logins = Services.logins.getAllLogins({});
- Assert.equal(logins.length, 0, "There are no logins at the beginning of the test");
-
- let uris = []; // the uris of the migrated logins
-
- let loginCount = 0;
- for (let current in TESTED_WEBSITES) {
- let website = TESTED_WEBSITES[current];
- // backup the current the registry value if it exists and replace the existing value/create a
- // new value with the encrypted data
- backupAndStore(Storage2Key, website.hash,
- crypto.encryptData(crypto.arrayToString(website.data),
- website.uri.spec, true));
- Assert.ok(migrator.exists, "The migrator has to exist");
- uris.push(website.uri);
- hashes.push(website.hash);
-
- migrator._migrateURIs(uris);
- logins = Services.logins.getAllLogins({});
- // check that the number of logins in the password manager has increased as expected which means
- // that all the values for the current website were imported
- loginCount += website.logins.length;
- Assert.equal(logins.length, loginCount,
- "The number of logins has increased after the migration");
- // NB: because telemetry records any login data passed to the login manager, it
- // also gets told about logins that are duplicates or invalid (for one reason
- // or another) and so its counts might exceed those of the login manager itself.
- Assert.greaterOrEqual(MigrationUtils._importQuantities.logins, loginCount,
- "Telemetry quantities equal or exceed the actual import.");
- // Reset - this normally happens at the start of a new migration, but we're calling
- // the migrator directly so can't rely on that:
- MigrationUtils._importQuantities.logins = 0;
-
- let startIndex = loginCount - website.logins.length;
- // compares the imported password manager logins with their expected logins
- for (let i = 0; i < website.logins.length; i++) {
- checkLoginsAreEqual(logins[startIndex + i], website.logins[i],
- " " + current + " - " + i + " ");
- }
- }
-});
diff --git a/browser/components/migration/tests/unit/test_IE_bookmarks.js b/browser/components/migration/tests/unit/test_IE_bookmarks.js
deleted file mode 100644
index a166c0502..000000000
--- a/browser/components/migration/tests/unit/test_IE_bookmarks.js
+++ /dev/null
@@ -1,44 +0,0 @@
-"use strict";
-
-add_task(function* () {
- let migrator = MigrationUtils.getMigrator("ie");
- // Sanity check for the source.
- Assert.ok(migrator.sourceExists);
-
- // Wait for the imported bookmarks. Check that "From Internet Explorer"
- // folders are created in the menu and on the toolbar.
- let source = MigrationUtils.getLocalizedString("sourceNameIE");
- let label = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]);
-
- let expectedParents = [ PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.toolbarFolderId ];
-
- let itemCount = 0;
- let bmObserver = {
- onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle) {
- if (aTitle != label) {
- itemCount++;
- }
- if (expectedParents.length > 0 && aTitle == label) {
- let index = expectedParents.indexOf(aParentId);
- Assert.notEqual(index, -1);
- expectedParents.splice(index, 1);
- }
- },
- onBeginUpdateBatch() {},
- onEndUpdateBatch() {},
- onItemRemoved() {},
- onItemChanged() {},
- onItemVisited() {},
- onItemMoved() {},
- };
- PlacesUtils.bookmarks.addObserver(bmObserver, false);
-
- yield promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS);
- PlacesUtils.bookmarks.removeObserver(bmObserver);
- Assert.equal(MigrationUtils._importQuantities.bookmarks, itemCount,
- "Ensure telemetry matches actual number of imported items.");
-
- // Check the bookmarks have been imported to all the expected parents.
- Assert.equal(expectedParents.length, 0, "Got all the expected parents");
-});
diff --git a/browser/components/migration/tests/unit/test_IE_cookies.js b/browser/components/migration/tests/unit/test_IE_cookies.js
deleted file mode 100644
index 37a7462f2..000000000
--- a/browser/components/migration/tests/unit/test_IE_cookies.js
+++ /dev/null
@@ -1,111 +0,0 @@
-"use strict";
-
-XPCOMUtils.defineLazyModuleGetter(this, "ctypes",
- "resource://gre/modules/ctypes.jsm");
-
-add_task(function* () {
- let migrator = MigrationUtils.getMigrator("ie");
- // Sanity check for the source.
- Assert.ok(migrator.sourceExists);
-
- const BOOL = ctypes.bool;
- const LPCTSTR = ctypes.char16_t.ptr;
- const DWORD = ctypes.uint32_t;
- const LPDWORD = DWORD.ptr;
-
- let wininet = ctypes.open("Wininet");
-
- /*
- BOOL InternetSetCookieW(
- _In_ LPCTSTR lpszUrl,
- _In_ LPCTSTR lpszCookieName,
- _In_ LPCTSTR lpszCookieData
- );
- */
- let setIECookie = wininet.declare("InternetSetCookieW",
- ctypes.default_abi,
- BOOL,
- LPCTSTR,
- LPCTSTR,
- LPCTSTR);
-
- /*
- BOOL InternetGetCookieW(
- _In_ LPCTSTR lpszUrl,
- _In_ LPCTSTR lpszCookieName,
- _Out_ LPCTSTR lpszCookieData,
- _Inout_ LPDWORD lpdwSize
- );
- */
- let getIECookie = wininet.declare("InternetGetCookieW",
- ctypes.default_abi,
- BOOL,
- LPCTSTR,
- LPCTSTR,
- LPCTSTR,
- LPDWORD);
-
- // We need to randomize the cookie to avoid clashing with other cookies
- // that might have been set by previous tests and not properly cleared.
- let date = (new Date()).getDate();
- const COOKIE = {
- get host() {
- return new URL(this.href).host;
- },
- href: `http://mycookietest.${Math.random()}.com`,
- name: "testcookie",
- value: "testvalue",
- expiry: new Date(new Date().setDate(date + 2))
- };
- let data = ctypes.char16_t.array()(256);
- let sizeRef = DWORD(256).address();
-
- do_register_cleanup(() => {
- // Remove the cookie.
- try {
- let expired = new Date(new Date().setDate(date - 2));
- let rv = setIECookie(COOKIE.href, COOKIE.name,
- `; expires=${expired.toUTCString()}`);
- Assert.ok(rv, "Expired the IE cookie");
- Assert.ok(!getIECookie(COOKIE.href, COOKIE.name, data, sizeRef),
- "The cookie has been properly removed");
- } catch (ex) {}
-
- // Close the library.
- try {
- wininet.close();
- } catch (ex) {}
- });
-
- // Create the persistent cookie in IE.
- let value = `${COOKIE.value}; expires=${COOKIE.expiry.toUTCString()}`;
- let rv = setIECookie(COOKIE.href, COOKIE.name, value);
- Assert.ok(rv, "Added a persistent IE cookie: " + value);
-
- // Sanity check the cookie has been created.
- Assert.ok(getIECookie(COOKIE.href, COOKIE.name, data, sizeRef),
- "Found the added persistent IE cookie");
- do_print("Found cookie: " + data.readString());
- Assert.equal(data.readString(), `${COOKIE.name}=${COOKIE.value}`,
- "Found the expected cookie");
-
- // Sanity check that there are no cookies.
- Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 0,
- "There are no cookies initially");
-
- // Migrate cookies.
- yield promiseMigration(migrator, MigrationUtils.resourceTypes.COOKIES);
-
- Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 1,
- "Migrated the expected number of cookies");
-
- // Now check the cookie details.
- let enumerator = Services.cookies.getCookiesFromHost(COOKIE.host, {});
- Assert.ok(enumerator.hasMoreElements());
- let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
-
- Assert.equal(foundCookie.name, COOKIE.name);
- Assert.equal(foundCookie.value, COOKIE.value);
- Assert.equal(foundCookie.host, "." + COOKIE.host);
- Assert.equal(foundCookie.expiry, Math.floor(COOKIE.expiry / 1000));
-});
diff --git a/browser/components/migration/tests/unit/test_Safari_bookmarks.js b/browser/components/migration/tests/unit/test_Safari_bookmarks.js
deleted file mode 100644
index edc32dc72..000000000
--- a/browser/components/migration/tests/unit/test_Safari_bookmarks.js
+++ /dev/null
@@ -1,46 +0,0 @@
-"use strict";
-
-add_task(function* () {
- registerFakePath("ULibDir", do_get_file("Library/"));
-
- let migrator = MigrationUtils.getMigrator("safari");
- // Sanity check for the source.
- Assert.ok(migrator.sourceExists);
-
- // Wait for the imported bookmarks. Check that "From Safari"
- // folders are created on the toolbar.
- let source = MigrationUtils.getLocalizedString("sourceNameSafari");
- let label = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]);
-
- let expectedParents = [ PlacesUtils.toolbarFolderId ];
- let itemCount = 0;
-
- let bmObserver = {
- onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle) {
- if (aTitle != label) {
- itemCount++;
- }
- if (expectedParents.length > 0 && aTitle == label) {
- let index = expectedParents.indexOf(aParentId);
- Assert.ok(index != -1, "Found expected parent");
- expectedParents.splice(index, 1);
- }
- },
- onBeginUpdateBatch() {},
- onEndUpdateBatch() {},
- onItemRemoved() {},
- onItemChanged() {},
- onItemVisited() {},
- onItemMoved() {},
- };
- PlacesUtils.bookmarks.addObserver(bmObserver, false);
-
- yield promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS);
- PlacesUtils.bookmarks.removeObserver(bmObserver);
-
- // Check the bookmarks have been imported to all the expected parents.
- Assert.ok(!expectedParents.length, "No more expected parents");
- Assert.equal(itemCount, 13, "Should import all 13 items.");
- // Check that the telemetry matches:
- Assert.equal(MigrationUtils._importQuantities.bookmarks, itemCount, "Telemetry reporting correct.");
-});
diff --git a/browser/components/migration/tests/unit/test_automigration.js b/browser/components/migration/tests/unit/test_automigration.js
deleted file mode 100644
index bc9076a6c..000000000
--- a/browser/components/migration/tests/unit/test_automigration.js
+++ /dev/null
@@ -1,695 +0,0 @@
-"use strict";
-
-let AutoMigrateBackstage = Cu.import("resource:///modules/AutoMigrate.jsm"); /* globals AutoMigrate */
-
-let gShimmedMigratorKeyPicker = null;
-let gShimmedMigrator = null;
-
-const kUsecPerMin = 60 * 1000000;
-
-// This is really a proxy on MigrationUtils, but if we specify that directly,
-// we get in trouble because the object itself is frozen, and Proxies can't
-// return a different value to an object when directly proxying a frozen
-// object.
-AutoMigrateBackstage.MigrationUtils = new Proxy({}, {
- get(target, name) {
- if (name == "getMigratorKeyForDefaultBrowser" && gShimmedMigratorKeyPicker) {
- return gShimmedMigratorKeyPicker;
- }
- if (name == "getMigrator" && gShimmedMigrator) {
- return function() { return gShimmedMigrator };
- }
- return MigrationUtils[name];
- },
-});
-
-do_register_cleanup(function() {
- AutoMigrateBackstage.MigrationUtils = MigrationUtils;
-});
-
-// This should be replaced by using History.fetch with a fetchVisits option,
-// once that becomes available
-function* visitsForURL(url)
-{
- let visitCount = 0;
- let db = yield PlacesUtils.promiseDBConnection();
- visitCount = yield db.execute(
- `SELECT count(*) FROM moz_historyvisits v
- JOIN moz_places h ON h.id = v.place_id
- WHERE url_hash = hash(:url) AND url = :url`,
- {url});
- visitCount = visitCount[0].getInt64(0);
- return visitCount;
-}
-
-
-/**
- * Test automatically picking a browser to migrate from
- */
-add_task(function* checkMigratorPicking() {
- Assert.throws(() => AutoMigrate.pickMigrator("firefox"),
- /Can't automatically migrate from Firefox/,
- "Should throw when explicitly picking Firefox.");
-
- Assert.throws(() => AutoMigrate.pickMigrator("gobbledygook"),
- /migrator object is not available/,
- "Should throw when passing unknown migrator key");
- gShimmedMigratorKeyPicker = function() {
- return "firefox";
- };
- Assert.throws(() => AutoMigrate.pickMigrator(),
- /Can't automatically migrate from Firefox/,
- "Should throw when implicitly picking Firefox.");
- gShimmedMigratorKeyPicker = function() {
- return "gobbledygook";
- };
- Assert.throws(() => AutoMigrate.pickMigrator(),
- /migrator object is not available/,
- "Should throw when an unknown migrator is the default");
- gShimmedMigratorKeyPicker = function() {
- return "";
- };
- Assert.throws(() => AutoMigrate.pickMigrator(),
- /Could not determine default browser key/,
- "Should throw when an unknown migrator is the default");
-});
-
-
-/**
- * Test automatically picking a profile to migrate from
- */
-add_task(function* checkProfilePicking() {
- let fakeMigrator = {sourceProfiles: [{id: "a"}, {id: "b"}]};
- let profB = fakeMigrator.sourceProfiles[1];
- Assert.throws(() => AutoMigrate.pickProfile(fakeMigrator),
- /Don't know how to pick a profile when more/,
- "Should throw when there are multiple profiles.");
- Assert.throws(() => AutoMigrate.pickProfile(fakeMigrator, "c"),
- /Profile specified was not found/,
- "Should throw when the profile supplied doesn't exist.");
- let profileToMigrate = AutoMigrate.pickProfile(fakeMigrator, "b");
- Assert.equal(profileToMigrate, profB, "Should return profile supplied");
-
- fakeMigrator.sourceProfiles = null;
- Assert.throws(() => AutoMigrate.pickProfile(fakeMigrator, "c"),
- /Profile specified but only a default profile found./,
- "Should throw when the profile supplied doesn't exist.");
- profileToMigrate = AutoMigrate.pickProfile(fakeMigrator);
- Assert.equal(profileToMigrate, null, "Should return default profile when that's the only one.");
-
- fakeMigrator.sourceProfiles = [];
- Assert.throws(() => AutoMigrate.pickProfile(fakeMigrator),
- /No profile data found/,
- "Should throw when no profile data is present.");
-
- fakeMigrator.sourceProfiles = [{id: "a"}];
- let profA = fakeMigrator.sourceProfiles[0];
- profileToMigrate = AutoMigrate.pickProfile(fakeMigrator);
- Assert.equal(profileToMigrate, profA, "Should return the only profile if only one is present.");
-});
-
-/**
- * Test the complete automatic process including browser and profile selection,
- * and actual migration (which implies startup)
- */
-add_task(function* checkIntegration() {
- gShimmedMigrator = {
- get sourceProfiles() {
- do_print("Read sourceProfiles");
- return null;
- },
- getMigrateData(profileToMigrate) {
- this._getMigrateDataArgs = profileToMigrate;
- return Ci.nsIBrowserProfileMigrator.BOOKMARKS;
- },
- migrate(types, startup, profileToMigrate) {
- this._migrateArgs = [types, startup, profileToMigrate];
- },
- };
- gShimmedMigratorKeyPicker = function() {
- return "gobbledygook";
- };
- AutoMigrate.migrate("startup");
- Assert.strictEqual(gShimmedMigrator._getMigrateDataArgs, null,
- "getMigrateData called with 'null' as a profile");
-
- let {BOOKMARKS, HISTORY, PASSWORDS} = Ci.nsIBrowserProfileMigrator;
- let expectedTypes = BOOKMARKS | HISTORY | PASSWORDS;
- Assert.deepEqual(gShimmedMigrator._migrateArgs, [expectedTypes, "startup", null],
- "migrate called with 'null' as a profile");
-});
-
-/**
- * Test the undo preconditions and a no-op undo in the automigrator.
- */
-add_task(function* checkUndoPreconditions() {
- let shouldAddData = false;
- gShimmedMigrator = {
- get sourceProfiles() {
- do_print("Read sourceProfiles");
- return null;
- },
- getMigrateData(profileToMigrate) {
- this._getMigrateDataArgs = profileToMigrate;
- return Ci.nsIBrowserProfileMigrator.BOOKMARKS;
- },
- migrate(types, startup, profileToMigrate) {
- this._migrateArgs = [types, startup, profileToMigrate];
- if (shouldAddData) {
- // Insert a login and check that that worked.
- MigrationUtils.insertLoginWrapper({
- hostname: "www.mozilla.org",
- formSubmitURL: "http://www.mozilla.org",
- username: "user",
- password: "pass",
- });
- }
- TestUtils.executeSoon(function() {
- Services.obs.notifyObservers(null, "Migration:Ended", undefined);
- });
- },
- };
-
- gShimmedMigratorKeyPicker = function() {
- return "gobbledygook";
- };
- AutoMigrate.migrate("startup");
- let migrationFinishedPromise = TestUtils.topicObserved("Migration:Ended");
- Assert.strictEqual(gShimmedMigrator._getMigrateDataArgs, null,
- "getMigrateData called with 'null' as a profile");
-
- let {BOOKMARKS, HISTORY, PASSWORDS} = Ci.nsIBrowserProfileMigrator;
- let expectedTypes = BOOKMARKS | HISTORY | PASSWORDS;
- Assert.deepEqual(gShimmedMigrator._migrateArgs, [expectedTypes, "startup", null],
- "migrate called with 'null' as a profile");
-
- yield migrationFinishedPromise;
- Assert.ok(Preferences.has("browser.migrate.automigrate.browser"),
- "Should have set browser pref");
- Assert.ok(!(yield AutoMigrate.canUndo()), "Should not be able to undo migration, as there's no data");
- gShimmedMigrator._migrateArgs = null;
- gShimmedMigrator._getMigrateDataArgs = null;
- Preferences.reset("browser.migrate.automigrate.browser");
- shouldAddData = true;
-
- AutoMigrate.migrate("startup");
- migrationFinishedPromise = TestUtils.topicObserved("Migration:Ended");
- Assert.strictEqual(gShimmedMigrator._getMigrateDataArgs, null,
- "getMigrateData called with 'null' as a profile");
- Assert.deepEqual(gShimmedMigrator._migrateArgs, [expectedTypes, "startup", null],
- "migrate called with 'null' as a profile");
-
- yield migrationFinishedPromise;
- let storedLogins = Services.logins.findLogins({}, "www.mozilla.org",
- "http://www.mozilla.org", null);
- Assert.equal(storedLogins.length, 1, "Should have 1 login");
-
- Assert.ok(Preferences.has("browser.migrate.automigrate.browser"),
- "Should have set browser pref");
- Assert.ok((yield AutoMigrate.canUndo()), "Should be able to undo migration, as now there's data");
-
- yield AutoMigrate.undo();
- Assert.ok(true, "Should be able to finish an undo cycle.");
-
- // Check that the undo removed the passwords:
- storedLogins = Services.logins.findLogins({}, "www.mozilla.org",
- "http://www.mozilla.org", null);
- Assert.equal(storedLogins.length, 0, "Should have no logins");
-});
-
-/**
- * Fake a migration and then try to undo it to verify all data gets removed.
- */
-add_task(function* checkUndoRemoval() {
- MigrationUtils.initializeUndoData();
- Preferences.set("browser.migrate.automigrate.browser", "automationbrowser");
- // Insert a login and check that that worked.
- MigrationUtils.insertLoginWrapper({
- hostname: "www.mozilla.org",
- formSubmitURL: "http://www.mozilla.org",
- username: "user",
- password: "pass",
- });
- let storedLogins = Services.logins.findLogins({}, "www.mozilla.org",
- "http://www.mozilla.org", null);
- Assert.equal(storedLogins.length, 1, "Should have 1 login");
-
- // Insert a bookmark and check that we have exactly 1 bookmark for that URI.
- yield MigrationUtils.insertBookmarkWrapper({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- url: "http://www.example.org/",
- title: "Some example bookmark",
- });
-
- let bookmark = yield PlacesUtils.bookmarks.fetch({url: "http://www.example.org/"});
- Assert.ok(bookmark, "Should have a bookmark before undo");
- Assert.equal(bookmark.title, "Some example bookmark", "Should have correct bookmark before undo.");
-
- // Insert 2 history visits
- let now_uSec = Date.now() * 1000;
- let visitedURI = Services.io.newURI("http://www.example.com/", null, null);
- let frecencyUpdatePromise = new Promise(resolve => {
- let expectedChanges = 2;
- let observer = {
- onFrecencyChanged: function() {
- if (!--expectedChanges) {
- PlacesUtils.history.removeObserver(observer);
- resolve();
- }
- },
- };
- PlacesUtils.history.addObserver(observer, false);
- });
- yield MigrationUtils.insertVisitsWrapper([{
- uri: visitedURI,
- visits: [
- {
- transitionType: PlacesUtils.history.TRANSITION_LINK,
- visitDate: now_uSec,
- },
- {
- transitionType: PlacesUtils.history.TRANSITION_LINK,
- visitDate: now_uSec - 100 * kUsecPerMin,
- },
- ]
- }]);
- yield frecencyUpdatePromise;
-
- // Verify that both visits get reported.
- let opts = PlacesUtils.history.getNewQueryOptions();
- opts.resultType = opts.RESULTS_AS_VISIT;
- let query = PlacesUtils.history.getNewQuery();
- query.uri = visitedURI;
- let visits = PlacesUtils.history.executeQuery(query, opts);
- visits.root.containerOpen = true;
- Assert.equal(visits.root.childCount, 2, "Should have 2 visits");
- // Clean up:
- visits.root.containerOpen = false;
-
- yield AutoMigrate.saveUndoState();
-
- // Verify that we can undo, then undo:
- Assert.ok(AutoMigrate.canUndo(), "Should be possible to undo migration");
- yield AutoMigrate.undo();
-
- let histograms = [
- "FX_STARTUP_MIGRATION_UNDO_BOOKMARKS_ERRORCOUNT",
- "FX_STARTUP_MIGRATION_UNDO_LOGINS_ERRORCOUNT",
- "FX_STARTUP_MIGRATION_UNDO_VISITS_ERRORCOUNT",
- ];
- for (let histogramId of histograms) {
- let keyedHistogram = Services.telemetry.getKeyedHistogramById(histogramId);
- let histogramData = keyedHistogram.snapshot().automationbrowser;
- Assert.equal(histogramData.sum, 0, `Should have reported 0 errors to ${histogramId}.`);
- Assert.greaterOrEqual(histogramData.counts[0], 1, `Should have reported value of 0 one time to ${histogramId}.`);
- }
- histograms = [
- "FX_STARTUP_MIGRATION_UNDO_BOOKMARKS_MS",
- "FX_STARTUP_MIGRATION_UNDO_LOGINS_MS",
- "FX_STARTUP_MIGRATION_UNDO_VISITS_MS",
- "FX_STARTUP_MIGRATION_UNDO_TOTAL_MS",
- ];
- for (let histogramId of histograms) {
- Assert.greater(Services.telemetry.getKeyedHistogramById(histogramId).snapshot().automationbrowser.sum, 0,
- `Should have reported non-zero time spent using undo for ${histogramId}`);
- }
-
- // Check that the undo removed the history visits:
- visits = PlacesUtils.history.executeQuery(query, opts);
- visits.root.containerOpen = true;
- Assert.equal(visits.root.childCount, 0, "Should have no more visits");
- visits.root.containerOpen = false;
-
- // Check that the undo removed the bookmarks:
- bookmark = yield PlacesUtils.bookmarks.fetch({url: "http://www.example.org/"});
- Assert.ok(!bookmark, "Should have no bookmarks after undo");
-
- // Check that the undo removed the passwords:
- storedLogins = Services.logins.findLogins({}, "www.mozilla.org",
- "http://www.mozilla.org", null);
- Assert.equal(storedLogins.length, 0, "Should have no logins");
-});
-
-add_task(function* checkUndoBookmarksState() {
- MigrationUtils.initializeUndoData();
- const {TYPE_FOLDER, TYPE_BOOKMARK} = PlacesUtils.bookmarks;
- let title = "Some example bookmark";
- let url = "http://www.example.com";
- let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
- let {guid, lastModified} = yield MigrationUtils.insertBookmarkWrapper({
- title, url, parentGuid
- });
- Assert.deepEqual((yield MigrationUtils.stopAndRetrieveUndoData()).get("bookmarks"),
- [{lastModified, parentGuid, guid, type: TYPE_BOOKMARK}]);
-
- MigrationUtils.initializeUndoData();
- ({guid, lastModified} = yield MigrationUtils.insertBookmarkWrapper({
- title, parentGuid, type: TYPE_FOLDER
- }));
- let folder = {guid, lastModified, parentGuid, type: TYPE_FOLDER};
- let folderGuid = folder.guid;
- ({guid, lastModified} = yield MigrationUtils.insertBookmarkWrapper({
- title, url, parentGuid: folderGuid
- }));
- let kid1 = {guid, lastModified, parentGuid: folderGuid, type: TYPE_BOOKMARK};
- ({guid, lastModified} = yield MigrationUtils.insertBookmarkWrapper({
- title, url, parentGuid: folderGuid
- }));
- let kid2 = {guid, lastModified, parentGuid: folderGuid, type: TYPE_BOOKMARK};
-
- let bookmarksUndo = (yield MigrationUtils.stopAndRetrieveUndoData()).get("bookmarks");
- Assert.equal(bookmarksUndo.length, 3);
- // We expect that the last modified time from first kid #1 and then kid #2
- // has been propagated to the folder:
- folder.lastModified = kid2.lastModified;
- // Not just using deepEqual on the entire array (which should work) because
- // the failure messages get truncated by xpcshell which is unhelpful.
- Assert.deepEqual(bookmarksUndo[0], folder);
- Assert.deepEqual(bookmarksUndo[1], kid1);
- Assert.deepEqual(bookmarksUndo[2], kid2);
- yield PlacesUtils.bookmarks.eraseEverything();
-});
-
-add_task(function* testBookmarkRemovalByUndo() {
- const {TYPE_FOLDER} = PlacesUtils.bookmarks;
- MigrationUtils.initializeUndoData();
- let title = "Some example bookmark";
- let url = "http://www.mymagicaluniqueurl.com";
- let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
- let {guid} = yield MigrationUtils.insertBookmarkWrapper({
- title: "Some folder", parentGuid, type: TYPE_FOLDER
- });
- let folderGuid = guid;
- let itemsToRemove = [];
- ({guid} = yield MigrationUtils.insertBookmarkWrapper({
- title: "Inner folder", parentGuid: folderGuid, type: TYPE_FOLDER
- }));
- let innerFolderGuid = guid;
- itemsToRemove.push(innerFolderGuid);
-
- ({guid} = yield MigrationUtils.insertBookmarkWrapper({
- title: "Inner inner folder", parentGuid: innerFolderGuid, type: TYPE_FOLDER
- }));
- itemsToRemove.push(guid);
-
- ({guid} = yield MigrationUtils.insertBookmarkWrapper({
- title: "Inner nested item", url: "http://inner-nested-example.com", parentGuid: guid
- }));
- itemsToRemove.push(guid);
-
- ({guid} = yield MigrationUtils.insertBookmarkWrapper({
- title, url, parentGuid: folderGuid
- }));
- itemsToRemove.push(guid);
-
- for (let toBeRemovedGuid of itemsToRemove) {
- let dbResultForGuid = yield PlacesUtils.bookmarks.fetch(toBeRemovedGuid);
- Assert.ok(dbResultForGuid, "Should be able to find items that will be removed.");
- }
- let bookmarkUndoState = (yield MigrationUtils.stopAndRetrieveUndoData()).get("bookmarks");
- // Now insert a separate item into this folder, not related to the migration.
- let newItem = yield PlacesUtils.bookmarks.insert(
- {title: "Not imported", parentGuid: folderGuid, url: "http://www.example.com"}
- );
-
- yield AutoMigrate._removeUnchangedBookmarks(bookmarkUndoState);
- Assert.ok(true, "Successfully removed imported items.");
-
- let itemFromDB = yield PlacesUtils.bookmarks.fetch(newItem.guid);
- Assert.ok(itemFromDB, "Item we inserted outside of migration is still there.");
- itemFromDB = yield PlacesUtils.bookmarks.fetch(folderGuid);
- Assert.ok(itemFromDB, "Folder we inserted in migration is still there because of new kids.");
- for (let removedGuid of itemsToRemove) {
- let dbResultForGuid = yield PlacesUtils.bookmarks.fetch(removedGuid);
- let dbgStr = dbResultForGuid && dbResultForGuid.title;
- Assert.equal(null, dbResultForGuid, "Should not be able to find items that should have been removed, but found " + dbgStr);
- }
- yield PlacesUtils.bookmarks.eraseEverything();
-});
-
-add_task(function* checkUndoLoginsState() {
- MigrationUtils.initializeUndoData();
- MigrationUtils.insertLoginWrapper({
- username: "foo",
- password: "bar",
- hostname: "https://example.com",
- formSubmitURL: "https://example.com/",
- timeCreated: new Date(),
- });
- let storedLogins = Services.logins.findLogins({}, "https://example.com", "", "");
- let storedLogin = storedLogins[0];
- storedLogin.QueryInterface(Ci.nsILoginMetaInfo);
- let {guid, timePasswordChanged} = storedLogin;
- let undoLoginData = (yield MigrationUtils.stopAndRetrieveUndoData()).get("logins");
- Assert.deepEqual([{guid, timePasswordChanged}], undoLoginData);
- Services.logins.removeAllLogins();
-});
-
-add_task(function* testLoginsRemovalByUndo() {
- MigrationUtils.initializeUndoData();
- MigrationUtils.insertLoginWrapper({
- username: "foo",
- password: "bar",
- hostname: "https://example.com",
- formSubmitURL: "https://example.com/",
- timeCreated: new Date(),
- });
- MigrationUtils.insertLoginWrapper({
- username: "foo",
- password: "bar",
- hostname: "https://example.org",
- formSubmitURL: "https://example.org/",
- timeCreated: new Date(new Date().getTime() - 10000),
- });
- // This should update the existing login
- LoginHelper.maybeImportLogin({
- username: "foo",
- password: "bazzy",
- hostname: "https://example.org",
- formSubmitURL: "https://example.org/",
- timePasswordChanged: new Date(),
- });
- Assert.equal(1, LoginHelper.searchLoginsWithObject({hostname: "https://example.org", formSubmitURL: "https://example.org/"}).length,
- "Should be only 1 login for example.org (that was updated)");
- let undoLoginData = (yield MigrationUtils.stopAndRetrieveUndoData()).get("logins");
-
- yield AutoMigrate._removeUnchangedLogins(undoLoginData);
- Assert.equal(0, LoginHelper.searchLoginsWithObject({hostname: "https://example.com", formSubmitURL: "https://example.com/"}).length,
- "unchanged example.com entry should have been removed.");
- Assert.equal(1, LoginHelper.searchLoginsWithObject({hostname: "https://example.org", formSubmitURL: "https://example.org/"}).length,
- "changed example.org entry should have persisted.");
- Services.logins.removeAllLogins();
-});
-
-add_task(function* checkUndoVisitsState() {
- MigrationUtils.initializeUndoData();
- yield MigrationUtils.insertVisitsWrapper([{
- uri: NetUtil.newURI("http://www.example.com/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2015-07-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }, {
- visitDate: new Date("2015-09-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }, {
- visitDate: new Date("2015-08-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }, {
- uri: NetUtil.newURI("http://www.example.org/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2016-04-03").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }, {
- visitDate: new Date("2015-08-03").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }, {
- uri: NetUtil.newURI("http://www.example.com/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2015-10-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }]);
- let undoVisitData = (yield MigrationUtils.stopAndRetrieveUndoData()).get("visits");
- Assert.deepEqual(Array.from(undoVisitData.map(v => v.url)).sort(),
- ["http://www.example.com/", "http://www.example.org/"]);
- Assert.deepEqual(undoVisitData.find(v => v.url == "http://www.example.com/"), {
- url: "http://www.example.com/",
- visitCount: 4,
- first: new Date("2015-07-10").getTime() * 1000,
- last: new Date("2015-10-10").getTime() * 1000,
- });
- Assert.deepEqual(undoVisitData.find(v => v.url == "http://www.example.org/"), {
- url: "http://www.example.org/",
- visitCount: 2,
- first: new Date("2015-08-03").getTime() * 1000,
- last: new Date("2016-04-03").getTime() * 1000,
- });
-
- yield PlacesTestUtils.clearHistory();
-});
-
-add_task(function* checkUndoVisitsState() {
- MigrationUtils.initializeUndoData();
- yield MigrationUtils.insertVisitsWrapper([{
- uri: NetUtil.newURI("http://www.example.com/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2015-07-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }, {
- visitDate: new Date("2015-09-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }, {
- visitDate: new Date("2015-08-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }, {
- uri: NetUtil.newURI("http://www.example.org/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2016-04-03").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }, {
- visitDate: new Date("2015-08-03").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }, {
- uri: NetUtil.newURI("http://www.example.com/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2015-10-10").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }, {
- uri: NetUtil.newURI("http://www.mozilla.org/"),
- title: "Example",
- visits: [{
- visitDate: new Date("2015-01-01").getTime() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
- }],
- }]);
-
- // We have to wait until frecency updates have been handled in order
- // to accurately determine whether we're doing the right thing.
- let frecencyUpdatesHandled = new Promise(resolve => {
- PlacesUtils.history.addObserver({
- onFrecencyChanged(aURI) {
- if (aURI.spec == "http://www.unrelated.org/") {
- PlacesUtils.history.removeObserver(this);
- resolve();
- }
- }
- }, false);
- });
- yield PlacesUtils.history.insertMany([{
- url: "http://www.example.com/",
- title: "Example",
- visits: [{
- date: new Date("2015-08-16"),
- }],
- }, {
- url: "http://www.example.org/",
- title: "Example",
- visits: [{
- date: new Date("2016-01-03"),
- }, {
- date: new Date("2015-05-03"),
- }],
- }, {
- url: "http://www.unrelated.org/",
- title: "Unrelated",
- visits: [{
- date: new Date("2015-09-01"),
- }],
- }]);
- yield frecencyUpdatesHandled;
- let undoVisitData = (yield MigrationUtils.stopAndRetrieveUndoData()).get("visits");
-
- let frecencyChangesExpected = new Map([
- ["http://www.example.com/", PromiseUtils.defer()],
- ["http://www.example.org/", PromiseUtils.defer()]
- ]);
- let uriDeletedExpected = new Map([
- ["http://www.mozilla.org/", PromiseUtils.defer()],
- ]);
- let wrongMethodDeferred = PromiseUtils.defer();
- let observer = {
- onBeginUpdateBatch: function() {},
- onEndUpdateBatch: function() {},
- onVisit: function(uri) {
- wrongMethodDeferred.reject(new Error("Unexpected call to onVisit " + uri.spec));
- },
- onTitleChanged: function(uri) {
- wrongMethodDeferred.reject(new Error("Unexpected call to onTitleChanged " + uri.spec));
- },
- onClearHistory: function() {
- wrongMethodDeferred.reject("Unexpected call to onClearHistory");
- },
- onPageChanged: function(uri) {
- wrongMethodDeferred.reject(new Error("Unexpected call to onPageChanged " + uri.spec));
- },
- onFrecencyChanged: function(aURI) {
- do_print("frecency change");
- Assert.ok(frecencyChangesExpected.has(aURI.spec),
- "Should be expecting frecency change for " + aURI.spec);
- frecencyChangesExpected.get(aURI.spec).resolve();
- },
- onManyFrecenciesChanged: function() {
- do_print("Many frecencies changed");
- wrongMethodDeferred.reject(new Error("This test can't deal with onManyFrecenciesChanged to be called"));
- },
- onDeleteURI: function(aURI) {
- do_print("delete uri");
- Assert.ok(uriDeletedExpected.has(aURI.spec),
- "Should be expecting uri deletion for " + aURI.spec);
- uriDeletedExpected.get(aURI.spec).resolve();
- },
- };
- PlacesUtils.history.addObserver(observer, false);
-
- yield AutoMigrate._removeSomeVisits(undoVisitData);
- PlacesUtils.history.removeObserver(observer);
- yield Promise.all(uriDeletedExpected.values());
- yield Promise.all(frecencyChangesExpected.values());
-
- Assert.equal(yield visitsForURL("http://www.example.com/"), 1,
- "1 example.com visit (out of 5) should have persisted despite being within the range, due to limiting");
- Assert.equal(yield visitsForURL("http://www.mozilla.org/"), 0,
- "0 mozilla.org visits should have persisted (out of 1).");
- Assert.equal(yield visitsForURL("http://www.example.org/"), 2,
- "2 example.org visits should have persisted (out of 4).");
- Assert.equal(yield visitsForURL("http://www.unrelated.org/"), 1,
- "1 unrelated.org visits should have persisted as it's not involved in the import.");
- yield PlacesTestUtils.clearHistory();
-});
-
-add_task(function* checkHistoryRemovalCompletion() {
- AutoMigrate._errorMap = {bookmarks: 0, visits: 0, logins: 0};
- yield AutoMigrate._removeSomeVisits([{url: "http://www.example.com/", limit: -1}]);
- ok(true, "Removing visits should complete even if removing some visits failed.");
- Assert.equal(AutoMigrate._errorMap.visits, 1, "Should have logged the error for visits.");
-
- // Unfortunately there's not a reliable way to make removing bookmarks be
- // unhappy unless the DB is messed up (e.g. contains children but has
- // parents removed already).
- yield AutoMigrate._removeUnchangedBookmarks([
- {guid: PlacesUtils.bookmarks, lastModified: new Date(0), parentGuid: 0},
- {guid: "gobbledygook", lastModified: new Date(0), parentGuid: 0},
- ]);
- ok(true, "Removing bookmarks should complete even if some items are gone or bogus.");
- Assert.equal(AutoMigrate._errorMap.bookmarks, 0,
- "Should have ignored removing non-existing (or builtin) bookmark.");
-
-
- yield AutoMigrate._removeUnchangedLogins([
- {guid: "gobbledygook", timePasswordChanged: new Date(0)},
- ]);
- ok(true, "Removing logins should complete even if logins don't exist.");
- Assert.equal(AutoMigrate._errorMap.logins, 0,
- "Should have ignored removing non-existing logins.");
-});
diff --git a/browser/components/migration/tests/unit/test_fx_telemetry.js b/browser/components/migration/tests/unit/test_fx_telemetry.js
deleted file mode 100644
index a276f52f8..000000000
--- a/browser/components/migration/tests/unit/test_fx_telemetry.js
+++ /dev/null
@@ -1,288 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* globals do_get_tempdir */
-
-"use strict";
-
-function run_test() {
- run_next_test();
-}
-
-function readFile(file) {
- let stream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- stream.init(file, -1, -1, Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- let sis = Cc["@mozilla.org/scriptableinputstream;1"]
- .createInstance(Ci.nsIScriptableInputStream);
- sis.init(stream);
- let contents = sis.read(file.fileSize);
- sis.close();
- return contents;
-}
-
-function checkDirectoryContains(dir, files) {
- print("checking " + dir.path + " - should contain " + Object.keys(files));
- let seen = new Set();
- let enumerator = dir.directoryEntries;
- while (enumerator.hasMoreElements()) {
- let file = enumerator.getNext().QueryInterface(Ci.nsIFile);
- print("found file: " + file.path);
- Assert.ok(file.leafName in files, file.leafName + " exists, but shouldn't");
-
- let expectedContents = files[file.leafName];
- if (typeof expectedContents != "string") {
- // it's a subdir - recurse!
- Assert.ok(file.isDirectory(), "should be a subdir");
- let newDir = dir.clone();
- newDir.append(file.leafName);
- checkDirectoryContains(newDir, expectedContents);
- } else {
- Assert.ok(!file.isDirectory(), "should be a regular file");
- let contents = readFile(file);
- Assert.equal(contents, expectedContents);
- }
- seen.add(file.leafName);
- }
- let missing = [];
- for (let x in files) {
- if (!seen.has(x)) {
- missing.push(x);
- }
- }
- Assert.deepEqual(missing, [], "no missing files in " + dir.path);
-}
-
-function getTestDirs() {
- // we make a directory structure in a temp dir which mirrors what we are
- // testing.
- let tempDir = do_get_tempdir();
- let srcDir = tempDir.clone();
- srcDir.append("test_source_dir");
- srcDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-
- let targetDir = tempDir.clone();
- targetDir.append("test_target_dir");
- targetDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-
- // no need to cleanup these dirs - the xpcshell harness will do it for us.
- return [srcDir, targetDir];
-}
-
-function writeToFile(dir, leafName, contents) {
- let file = dir.clone();
- file.append(leafName);
-
- let outputStream = FileUtils.openFileOutputStream(file);
- outputStream.write(contents, contents.length);
- outputStream.close();
-}
-
-function createSubDir(dir, subDirName) {
- let subDir = dir.clone();
- subDir.append(subDirName);
- subDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
- return subDir;
-}
-
-function promiseMigrator(name, srcDir, targetDir) {
- let migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=firefox"]
- .createInstance(Ci.nsISupports)
- .wrappedJSObject;
- let migrators = migrator._getResourcesInternal(srcDir, targetDir);
- for (let m of migrators) {
- if (m.name == name) {
- return new Promise(resolve => m.migrate(resolve));
- }
- }
- throw new Error("failed to find the " + name + " migrator");
-}
-
-function promiseTelemetryMigrator(srcDir, targetDir) {
- return promiseMigrator("telemetry", srcDir, targetDir);
-}
-
-add_task(function* test_empty() {
- let [srcDir, targetDir] = getTestDirs();
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true with empty directories");
- // check both are empty
- checkDirectoryContains(srcDir, {});
- checkDirectoryContains(targetDir, {});
-});
-
-add_task(function* test_migrate_files() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Set up datareporting files, some to copy, some not.
- let stateContent = JSON.stringify({
- clientId: "68d5474e-19dc-45c1-8e9a-81fca592707c",
- });
- let sessionStateContent = "foobar 5432";
- let subDir = createSubDir(srcDir, "datareporting");
- writeToFile(subDir, "state.json", stateContent);
- writeToFile(subDir, "session-state.json", sessionStateContent);
- writeToFile(subDir, "other.file", "do not copy");
-
- let archived = createSubDir(subDir, "archived");
- writeToFile(archived, "other.file", "do not copy");
-
- // Set up FHR files, they should not be copied.
- writeToFile(srcDir, "healthreport.sqlite", "do not copy");
- writeToFile(srcDir, "healthreport.sqlite-wal", "do not copy");
- subDir = createSubDir(srcDir, "healthreport");
- writeToFile(subDir, "state.json", "do not copy");
- writeToFile(subDir, "other.file", "do not copy");
-
- // Perform migration.
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true with important telemetry files copied");
-
- checkDirectoryContains(targetDir, {
- "datareporting": {
- "state.json": stateContent,
- "session-state.json": sessionStateContent,
- },
- });
-});
-
-add_task(function* test_fallback_fhr_state() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Test that we fall back to migrating FHR state if the datareporting
- // state file does not exist.
- let stateContent = JSON.stringify({
- clientId: "68d5474e-19dc-45c1-8e9a-81fca592707c",
- });
- let subDir = createSubDir(srcDir, "healthreport");
- writeToFile(subDir, "state.json", stateContent);
-
- // Perform migration.
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
-
- checkDirectoryContains(targetDir, {
- "healthreport": {
- "state.json": stateContent,
- },
- });
-});
-
-
-add_task(function* test_datareporting_not_dir() {
- let [srcDir, targetDir] = getTestDirs();
-
- writeToFile(srcDir, "datareporting", "I'm a file but should be a directory");
-
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true even though the directory was a file");
-
- checkDirectoryContains(targetDir, {});
-});
-
-add_task(function* test_datareporting_empty() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Migrate with an empty 'datareporting' subdir.
- createSubDir(srcDir, "datareporting");
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
-
- // We should end up with no migrated files.
- checkDirectoryContains(targetDir, {
- "datareporting": {},
- });
-});
-
-add_task(function* test_healthreport_empty() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Migrate with no 'datareporting' and an empty 'healthreport' subdir.
- createSubDir(srcDir, "healthreport");
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
-
- // We should end up with no migrated files.
- checkDirectoryContains(targetDir, {});
-});
-
-add_task(function* test_datareporting_many() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Create some datareporting files.
- let subDir = createSubDir(srcDir, "datareporting");
- let shouldBeCopied = "should be copied";
- writeToFile(subDir, "state.json", shouldBeCopied);
- writeToFile(subDir, "session-state.json", shouldBeCopied);
- writeToFile(subDir, "something.else", "should not");
- createSubDir(subDir, "emptyDir");
-
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
-
- checkDirectoryContains(targetDir, {
- "datareporting" : {
- "state.json": shouldBeCopied,
- "session-state.json": shouldBeCopied,
- }
- });
-});
-
-add_task(function* test_no_session_state() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Check that migration still works properly if we only have state.json.
- let subDir = createSubDir(srcDir, "datareporting");
- let stateContent = "abcd984";
- writeToFile(subDir, "state.json", stateContent);
-
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
-
- checkDirectoryContains(targetDir, {
- "datareporting" : {
- "state.json": stateContent,
- }
- });
-});
-
-add_task(function* test_no_state() {
- let [srcDir, targetDir] = getTestDirs();
-
- // Check that migration still works properly if we only have session-state.json.
- let subDir = createSubDir(srcDir, "datareporting");
- let sessionStateContent = "abcd512";
- writeToFile(subDir, "session-state.json", sessionStateContent);
-
- let ok = yield promiseTelemetryMigrator(srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
-
- checkDirectoryContains(targetDir, {
- "datareporting" : {
- "session-state.json": sessionStateContent,
- }
- });
-});
-
-add_task(function* test_times_migration() {
- let [srcDir, targetDir] = getTestDirs();
-
- // create a times.json in the source directory.
- let contents = JSON.stringify({created: 1234});
- writeToFile(srcDir, "times.json", contents);
-
- let earliest = Date.now();
- let ok = yield promiseMigrator("times", srcDir, targetDir);
- Assert.ok(ok, "callback should have been true");
- let latest = Date.now();
-
- let timesFile = targetDir.clone();
- timesFile.append("times.json");
-
- let raw = readFile(timesFile);
- let times = JSON.parse(raw);
- Assert.ok(times.reset >= earliest && times.reset <= latest);
- // and it should have left the creation time alone.
- Assert.equal(times.created, 1234);
-});
diff --git a/browser/components/migration/tests/unit/xpcshell.ini b/browser/components/migration/tests/unit/xpcshell.ini
deleted file mode 100644
index 1b9f0a5f1..000000000
--- a/browser/components/migration/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,26 +0,0 @@
-[DEFAULT]
-head = head_migration.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-support-files =
- Library/**
- AppData/**
-
-[test_automigration.js]
-[test_Chrome_cookies.js]
-skip-if = os != "mac" # Relies on ULibDir
-[test_Chrome_passwords.js]
-skip-if = os != "win"
-[test_Edge_availability.js]
-[test_Edge_db_migration.js]
-skip-if = os != "win" || os_version == "5.1" || os_version == "5.2" # Relies on post-XP bits of ESEDB
-[test_fx_telemetry.js]
-[test_IE_bookmarks.js]
-skip-if = os != "win"
-[test_IE_cookies.js]
-skip-if = os != "win"
-[test_IE7_passwords.js]
-skip-if = os != "win"
-[test_Safari_bookmarks.js]
-skip-if = os != "mac"
diff --git a/browser/components/moz.build b/browser/components/moz.build
index 5ad29d088..3c0dea3fb 100644
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -14,7 +14,6 @@ DIRS += [
'feeds',
'migration',
'newtab',
- 'originattributes',
'places',
'preferences',
'privatebrowsing',
@@ -48,18 +47,3 @@ EXTRA_COMPONENTS += [
EXTRA_JS_MODULES += [
'distribution.js',
]
-
-BROWSER_CHROME_MANIFESTS += [
- 'safebrowsing/content/test/browser.ini',
- 'tests/browser/browser.ini'
-]
-
-XPCSHELL_TESTS_MANIFESTS += [
- 'tests/unit/xpcshell.ini'
-]
-
-with Files('safebrowsing/*'):
- BUG_COMPONENT = ('Toolkit', 'Phishing Protection')
-
-with Files('controlcenter/**'):
- BUG_COMPONENT = ('Firefox', 'General')
diff --git a/browser/components/newtab/moz.build b/browser/components/newtab/moz.build
index 37c9983f7..3d3be6454 100644
--- a/browser/components/newtab/moz.build
+++ b/browser/components/newtab/moz.build
@@ -4,12 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
-
-XPCSHELL_TESTS_MANIFESTS += [
- 'tests/xpcshell/xpcshell.ini',
-]
-
EXTRA_JS_MODULES += [
'NewTabMessages.jsm',
'NewTabPrefsProvider.jsm',
diff --git a/browser/components/newtab/tests/browser/.eslintrc.js b/browser/components/newtab/tests/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/newtab/tests/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/newtab/tests/browser/blue_page.html b/browser/components/newtab/tests/browser/blue_page.html
deleted file mode 100644
index a7f000bfd..000000000
--- a/browser/components/newtab/tests/browser/blue_page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
- <meta charset="utf-8">
-</head>
-<body style="background-color: blue">
-</body>
-</html>
diff --git a/browser/components/newtab/tests/browser/browser.ini b/browser/components/newtab/tests/browser/browser.ini
deleted file mode 100644
index fa740be9e..000000000
--- a/browser/components/newtab/tests/browser/browser.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[DEFAULT]
-support-files =
- blue_page.html
- dummy_page.html
- newtabwebchannel_basic.html
- newtabmessages_places.html
- newtabmessages_prefs.html
- newtabmessages_preview.html
- newtabmessages_search.html
-
-[browser_PreviewProvider.js]
-[browser_remotenewtab_pageloads.js]
-[browser_newtab_overrides.js]
-[browser_newtabmessages.js]
-skip-if = true # Bug 1271177, bug 1262719
-[browser_newtabwebchannel.js]
diff --git a/browser/components/newtab/tests/browser/browser_PreviewProvider.js b/browser/components/newtab/tests/browser/browser_PreviewProvider.js
deleted file mode 100644
index b1e3eda9f..000000000
--- a/browser/components/newtab/tests/browser/browser_PreviewProvider.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/* globals XPCOMUtils, Services, PreviewProvider, registerCleanupFunction */
-"use strict";
-
-let Cu = Components.utils;
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PreviewProvider",
- "resource:///modules/PreviewProvider.jsm");
-
-var oldEnabledPref = Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled");
-Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", false);
-
-registerCleanupFunction(function() {
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeTab(gBrowser.tabs[1]);
- }
- Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", oldEnabledPref);
-});
-
-const TEST_URL = "https://example.com/browser/browser/components/newtab/tests/browser/blue_page.html";
-
-function pixelsForDataURI(dataURI, options) {
- return new Promise(resolve => {
- if (!options) {
- options = {};
- }
- let {width, height} = options;
- if (!width) {
- width = 100;
- }
- 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);
- 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);
- });
- });
-}
-
-function* chunk_four(listData) {
- let index = 0;
- while (index < listData.length) {
- yield listData.slice(index, index + 5);
- index += 4;
- }
-}
-
-add_task(function* open_page() {
- let dataURI = yield PreviewProvider.getThumbnail(TEST_URL);
- let pixels = yield pixelsForDataURI(dataURI, {width: 10, height: 10});
- let rgbCount = {r: 0, g: 0, b: 0, a: 0};
- for (let [r, g, b, a] of chunk_four(pixels)) {
- if (r === 255) {
- rgbCount.r += 1;
- }
- if (g === 255) {
- rgbCount.g += 1;
- }
- if (b === 255) {
- rgbCount.b += 1;
- }
- if (a === 255) {
- rgbCount.a += 1;
- }
- }
- Assert.equal(`${rgbCount.r},${rgbCount.g},${rgbCount.b},${rgbCount.a}`,
- "0,0,100,100", "there should be 100 blue-only pixels at full opacity");
-});
-
-add_task(function* invalid_url() {
- try {
- yield PreviewProvider.getThumbnail("invalid:URL");
- } catch (err) {
- Assert.ok(true, "URL Failed");
- }
-});
diff --git a/browser/components/newtab/tests/browser/browser_newtab_overrides.js b/browser/components/newtab/tests/browser/browser_newtab_overrides.js
deleted file mode 100644
index eab9092a0..000000000
--- a/browser/components/newtab/tests/browser/browser_newtab_overrides.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/* globals
- XPCOMUtils,
- aboutNewTabService,
- Services,
- ContentTask,
- TestUtils,
- BrowserOpenTab,
- registerCleanupFunction,
- is,
- content
-*/
-
-"use strict";
-
-let Cu = Components.utils;
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
- "@mozilla.org/browser/aboutnewtab-service;1",
- "nsIAboutNewTabService");
-
-registerCleanupFunction(function() {
- Services.prefs.setBoolPref("browser.newtabpage.remote", false);
- aboutNewTabService.resetNewTabURL();
-});
-
-/*
- * Tests that the default newtab page is always returned when one types "about:newtab" in the URL bar,
- * even when overridden.
- */
-add_task(function* redirector_ignores_override() {
- let overrides = [
- "chrome://browser/content/downloads/contentAreaDownloadsView.xul",
- "about:home",
- ];
-
- for (let overrideURL of overrides) {
- let notificationPromise = nextChangeNotificationPromise(overrideURL, `newtab page now points to ${overrideURL}`);
- aboutNewTabService.newTabURL = overrideURL;
-
- yield notificationPromise;
- Assert.ok(aboutNewTabService.overridden, "url has been overridden");
-
- let tabOptions = {
- gBrowser,
- url: "about:newtab",
- };
-
- /*
- * Simulate typing "about:newtab" in the url bar.
- *
- * Bug 1240169 - We expect the redirector to lead the user to "about:newtab", the default URL,
- * due to invoking AboutRedirector. A user interacting with the chrome otherwise would lead
- * to the overriding URLs.
- */
- yield BrowserTestUtils.withNewTab(tabOptions, function*(browser) {
- yield ContentTask.spawn(browser, {}, function*() {
- Assert.equal(content.location.href, "about:newtab", "Got right URL");
- Assert.equal(content.document.location.href, "about:newtab", "Got right URL");
- Assert.equal(content.document.nodePrincipal,
- Services.scriptSecurityManager.getSystemPrincipal(),
- "nodePrincipal should match systemPrincipal");
- });
- }); // jshint ignore:line
- }
-});
-
-/*
- * Tests loading an overridden newtab page by simulating opening a newtab page from chrome
- */
-add_task(function* override_loads_in_browser() {
- let overrides = [
- "chrome://browser/content/downloads/contentAreaDownloadsView.xul",
- "about:home",
- " about:home",
- ];
-
- for (let overrideURL of overrides) {
- let notificationPromise = nextChangeNotificationPromise(overrideURL.trim(), `newtab page now points to ${overrideURL}`);
- aboutNewTabService.newTabURL = overrideURL;
-
- yield notificationPromise;
- Assert.ok(aboutNewTabService.overridden, "url has been overridden");
-
- // simulate a newtab open as a user would
- BrowserOpenTab(); // jshint ignore:line
-
- let browser = gBrowser.selectedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield ContentTask.spawn(browser, {url: overrideURL}, function*(args) {
- Assert.equal(content.location.href, args.url.trim(), "Got right URL");
- Assert.equal(content.document.location.href, args.url.trim(), "Got right URL");
- }); // jshint ignore:line
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- }
-});
-
-/*
- * Tests edge cases when someone overrides the newtabpage with whitespace
- */
-add_task(function* override_blank_loads_in_browser() {
- let overrides = [
- "",
- " ",
- "\n\t",
- " about:blank",
- ];
-
- for (let overrideURL of overrides) {
- let notificationPromise = nextChangeNotificationPromise("about:blank", "newtab page now points to about:blank");
- aboutNewTabService.newTabURL = overrideURL;
-
- yield notificationPromise;
- Assert.ok(aboutNewTabService.overridden, "url has been overridden");
-
- // simulate a newtab open as a user would
- BrowserOpenTab(); // jshint ignore:line
-
- let browser = gBrowser.selectedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield ContentTask.spawn(browser, {}, function*() {
- Assert.equal(content.location.href, "about:blank", "Got right URL");
- Assert.equal(content.document.location.href, "about:blank", "Got right URL");
- }); // jshint ignore:line
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- }
-});
-
-function nextChangeNotificationPromise(aNewURL, testMessage) {
- return TestUtils.topicObserved("newtab-url-changed", function observer(aSubject, aData) { // jshint unused:false
- Assert.equal(aData, aNewURL, testMessage);
- return true;
- }.bind(this));
-}
diff --git a/browser/components/newtab/tests/browser/browser_newtabmessages.js b/browser/components/newtab/tests/browser/browser_newtabmessages.js
deleted file mode 100644
index 319ca1c34..000000000
--- a/browser/components/newtab/tests/browser/browser_newtabmessages.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/* globals Cu, XPCOMUtils, Preferences, is, registerCleanupFunction, NewTabWebChannel,
-PlacesTestUtils, NewTabMessages, ok, Services, PlacesUtils, NetUtil, Task */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabWebChannel",
- "resource:///modules/NewTabWebChannel.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabMessages",
- "resource:///modules/NewTabMessages.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-let setup = Task.async(function*() {
- Preferences.set("browser.newtabpage.enhanced", true);
- Preferences.set("browser.newtabpage.remote.mode", "test");
- Preferences.set("browser.newtabpage.remote", true);
- NewTabMessages.init();
- yield PlacesTestUtils.clearHistory();
-});
-
-let cleanup = Task.async(function*() {
- NewTabMessages.uninit();
- Preferences.set("browser.newtabpage.remote", false);
- Preferences.set("browser.newtabpage.remote.mode", "production");
-});
-registerCleanupFunction(cleanup);
-
-/*
- * Sanity tests for pref messages
- */
-add_task(function* prefMessages_request() {
- yield setup();
-
- let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_prefs.html";
-
- let tabOptions = {
- gBrowser,
- url: testURL
- };
-
- let prefResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("responseAck", () => {
- ok(true, "a request response has been received");
- resolve();
- });
- });
-
- yield BrowserTestUtils.withNewTab(tabOptions, function*() {
- yield prefResponseAck;
- let prefChangeAck = new Promise(resolve => {
- NewTabWebChannel.once("responseAck", () => {
- ok(true, "a change response has been received");
- resolve();
- });
- });
- Preferences.set("browser.newtabpage.enhanced", false);
- yield prefChangeAck;
- });
- yield cleanup();
-});
-
-/*
- * Sanity tests for preview messages
- */
-add_task(function* previewMessages_request() {
- yield setup();
- var oldEnabledPref = Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled");
- Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", false);
-
- let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_preview.html";
-
- let tabOptions = {
- gBrowser,
- url: testURL
- };
-
- let previewResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("responseAck", () => {
- ok(true, "a request response has been received");
- resolve();
- });
- });
-
- yield BrowserTestUtils.withNewTab(tabOptions, function*() {
- yield previewResponseAck;
- });
- yield cleanup();
- Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", oldEnabledPref);
-});
-
-/*
- * Sanity tests for places messages
- */
-add_task(function* placesMessages_request() {
- yield setup();
- let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_places.html";
-
- // url prefix for test history population
- const TEST_URL = "https://mozilla.com/";
- // time when the test starts execution
- const TIME_NOW = (new Date()).getTime();
-
- // utility function to compute past timestamp
- function timeDaysAgo(numDays) {
- return TIME_NOW - (numDays * 24 * 60 * 60 * 1000);
- }
-
- // utility function to make a visit for insertion into places db
- function makeVisit(index, daysAgo, isTyped, domain=TEST_URL) {
- let {
- TRANSITION_TYPED,
- TRANSITION_LINK
- } = PlacesUtils.history;
-
- return {
- uri: NetUtil.newURI(`${domain}${index}`),
- visitDate: timeDaysAgo(daysAgo),
- transition: (isTyped) ? TRANSITION_TYPED : TRANSITION_LINK,
- };
- }
-
- yield PlacesTestUtils.clearHistory();
-
- // all four visits must come from different domains to avoid deduplication
- let visits = [
- makeVisit(0, 0, true, "http://bar.com/"), // frecency 200, today
- makeVisit(1, 0, true, "http://foo.com/"), // frecency 200, today
- makeVisit(2, 2, true, "http://buz.com/"), // frecency 200, 2 days ago
- makeVisit(3, 2, false, "http://aaa.com/"), // frecency 10, 2 days ago, transition
- ];
-
- yield PlacesTestUtils.addVisits(visits);
-
- /** Test Begins **/
-
- let tabOptions = {
- gBrowser,
- url: testURL
- };
-
- let placesResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("numItemsAck", (_, msg) => {
- ok(true, "a request response has been received");
- is(msg.data, visits.length + 1, "received an expected number of history items");
- resolve();
- });
- });
-
- yield BrowserTestUtils.withNewTab(tabOptions, function*() {
- yield placesResponseAck;
- ok(true, "a change response has been received");
- let placesChangeAck = new Promise(resolve => {
- NewTabWebChannel.once("clearHistoryAck", (_, msg) => {
- is(msg.data, "clearHistory", "a clear history message has been received");
- resolve();
- });
- });
- yield PlacesTestUtils.clearHistory();
- yield placesChangeAck;
- });
- yield cleanup();
-});
-
-/*
- * Sanity tests for search messages
- */
-add_task(function* searchMessages_request() {
- yield setup();
- let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_search.html";
-
- // create dummy test engines
- Services.search.addEngineWithDetails("Engine1", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- Services.search.addEngineWithDetails("Engine2", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- let tabOptions = {
- gBrowser,
- url: testURL
- };
-
- let UIStringsResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("UIStringsAck", (_, msg) => {
- ok(true, "a search request response for UI string has been received");
- ok(msg.data, "received the UI Strings");
- resolve();
- });
- });
- let suggestionsResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("suggestionsAck", (_, msg) => {
- ok(true, "a search request response for suggestions has been received");
- ok(msg.data, "received the suggestions");
- resolve();
- });
- });
- let stateResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("stateAck", (_, msg) => {
- ok(true, "a search request response for state has been received");
- ok(msg.data, "received a state object");
- resolve();
- });
- });
- let currentEngineResponseAck = new Promise(resolve => {
- NewTabWebChannel.once("currentEngineAck", (_, msg) => {
- ok(true, "a search request response for current engine has been received");
- ok(msg.data, "received a current engine");
- resolve();
- });
- });
-
- yield BrowserTestUtils.withNewTab(tabOptions, function*() {
- yield UIStringsResponseAck;
- yield suggestionsResponseAck;
- yield stateResponseAck;
- yield currentEngineResponseAck;
- });
-
- cleanup();
-});
diff --git a/browser/components/newtab/tests/browser/browser_newtabwebchannel.js b/browser/components/newtab/tests/browser/browser_newtabwebchannel.js
deleted file mode 100644
index f003b105b..000000000
--- a/browser/components/newtab/tests/browser/browser_newtabwebchannel.js
+++ /dev/null
@@ -1,251 +0,0 @@
-/* globals XPCOMUtils, Cu, Preferences, NewTabWebChannel, is, registerCleanupFunction */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Preferences.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabWebChannel",
- "resource:///modules/NewTabWebChannel.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabMessages",
- "resource:///modules/NewTabMessages.jsm");
-
-const TEST_URL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabwebchannel_basic.html";
-const TEST_URL_2 = "http://mochi.test:8888/browser/browser/components/newtab/tests/browser/newtabwebchannel_basic.html";
-
-function setup(mode = "test") {
- Preferences.set("browser.newtabpage.remote.mode", mode);
- Preferences.set("browser.newtabpage.remote", true);
- NewTabWebChannel.init();
- NewTabMessages.init();
-}
-
-function cleanup() {
- NewTabMessages.uninit();
- NewTabWebChannel.uninit();
- Preferences.set("browser.newtabpage.remote", false);
- Preferences.set("browser.newtabpage.remote.mode", "production");
-}
-registerCleanupFunction(cleanup);
-
-/*
- * Tests flow of messages from newtab to chrome and chrome to newtab
- */
-add_task(function* open_webchannel_basic() {
- setup();
-
- let tabOptions = {
- gBrowser,
- url: TEST_URL
- };
-
- let messagePromise = new Promise(resolve => {
- NewTabWebChannel.once("foo", function(name, msg) {
- is(name, "foo", "Correct message type sent: foo");
- is(msg.data, "bar", "Correct data sent: bar");
- resolve(msg.target);
- });
- });
-
- let replyPromise = new Promise(resolve => {
- NewTabWebChannel.once("reply", function(name, msg) {
- is(name, "reply", "Correct message type sent: reply");
- is(msg.data, "quuz", "Correct data sent: quuz");
- resolve(msg.target);
- });
- });
-
- let unloadPromise = new Promise(resolve => {
- NewTabWebChannel.once("targetUnload", function(name) {
- is(name, "targetUnload", "Correct message type sent: targetUnload");
- resolve();
- });
- });
-
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- yield BrowserTestUtils.withNewTab(tabOptions, function*(browser) {
- let target = yield messagePromise;
- is(NewTabWebChannel.numBrowsers, 1, "One target expected");
- is(target.browser, browser, "Same browser");
- NewTabWebChannel.send("respond", null, target);
- yield replyPromise;
- });
-
- Cu.forceGC();
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- yield unloadPromise;
- cleanup();
-});
-
-/*
- * Tests message broadcast reaches all open newtab pages
- */
-add_task(function* webchannel_broadcast() {
- setup();
-
- let countingMessagePromise = new Promise(resolve => {
- let count = 0;
- NewTabWebChannel.on("foo", function test_message(name, msg) {
- count += 1;
- if (count === 2) {
- NewTabWebChannel.off("foo", test_message);
- resolve(msg.target);
- }
- }.bind(this));
- });
-
- let countingReplyPromise = new Promise(resolve => {
- let count = 0;
- NewTabWebChannel.on("reply", function test_message(name, msg) {
- count += 1;
- if (count === 2) {
- NewTabWebChannel.off("reply", test_message);
- resolve(msg.target);
- }
- }.bind(this));
- });
-
- let countingUnloadPromise = new Promise(resolve => {
- let count = 0;
- NewTabWebChannel.on("targetUnload", function test_message() {
- count += 1;
- if (count === 2) {
- NewTabWebChannel.off("targetUnload", test_message);
- resolve();
- }
- });
- });
-
- let tabs = [];
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL));
- tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL));
-
- yield countingMessagePromise;
- is(NewTabWebChannel.numBrowsers, 2, "Two targets expected");
-
- NewTabWebChannel.broadcast("respond", null);
- yield countingReplyPromise;
-
- for (let tab of tabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- Cu.forceGC();
-
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- yield countingUnloadPromise;
- cleanup();
-});
-
-/*
- * Tests switching modes
- */
-add_task(function* webchannel_switch() {
- setup();
-
- function newMessagePromise() {
- return new Promise(resolve => {
- NewTabWebChannel.once("foo", function(name, msg) {
- resolve(msg.target);
- }.bind(this));
- });
- }
-
- let replyCount = 0;
- function newReplyPromise() {
- return new Promise(resolve => {
- NewTabWebChannel.on("reply", function() {
- replyCount += 1;
- resolve();
- });
- });
- }
-
- let unloadPromise = new Promise(resolve => {
- NewTabWebChannel.once("targetUnload", function() {
- resolve();
- });
- });
-
- let unloadAllPromise = new Promise(resolve => {
- NewTabWebChannel.once("targetUnloadAll", function() {
- resolve();
- });
- });
-
- let tabs = [];
- let messagePromise;
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
-
- messagePromise = newMessagePromise();
- tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL));
- yield messagePromise;
- is(NewTabWebChannel.numBrowsers, 1, "Correct number of targets");
-
- messagePromise = newMessagePromise();
- Preferences.set("browser.newtabpage.remote.mode", "test2");
- tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL_2));
- yield unloadAllPromise;
- yield messagePromise;
- is(NewTabWebChannel.numBrowsers, 1, "Correct number of targets");
-
- NewTabWebChannel.broadcast("respond", null);
- yield newReplyPromise();
- is(replyCount, 1, "only current channel is listened to for replies");
-
- const webchannelWhitelistPref = "webchannel.allowObject.urlWhitelist";
- let origWhitelist = Services.prefs.getCharPref(webchannelWhitelistPref);
- let newWhitelist = origWhitelist + " http://mochi.test:8888";
- Services.prefs.setCharPref(webchannelWhitelistPref, newWhitelist);
- try {
- NewTabWebChannel.broadcast("respond_object", null);
- yield newReplyPromise();
- } finally {
- Services.prefs.clearUserPref(webchannelWhitelistPref);
- }
-
- for (let tab of tabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
-
- Cu.forceGC();
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- yield unloadPromise;
- cleanup();
-});
-
-add_task(function* open_webchannel_reload() {
- setup();
-
- let tabOptions = {
- gBrowser,
- url: TEST_URL
- };
-
- let messagePromise = new Promise(resolve => {
- NewTabWebChannel.once("foo", function(name, msg) {
- is(name, "foo", "Correct message type sent: foo");
- is(msg.data, "bar", "Correct data sent: bar");
- resolve(msg.target);
- });
- });
- let unloadPromise = new Promise(resolve => {
- NewTabWebChannel.once("targetUnload", function() {
- resolve();
- });
- });
-
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- yield BrowserTestUtils.withNewTab(tabOptions, function*(browser) {
- let target = yield messagePromise;
- is(NewTabWebChannel.numBrowsers, 1, "One target expected");
- is(target.browser, browser, "Same browser");
-
- browser.reload();
- });
-
- Cu.forceGC();
- is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
- yield unloadPromise;
- cleanup();
-});
diff --git a/browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js b/browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js
deleted file mode 100644
index e99aeffc2..000000000
--- a/browser/components/newtab/tests/browser/browser_remotenewtab_pageloads.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* globals Cu, XPCOMUtils, TestUtils, aboutNewTabService, ContentTask, content, is */
-"use strict";
-
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
- "@mozilla.org/browser/aboutnewtab-service;1",
- "nsIAboutNewTabService");
-
-const TEST_URL = "https://example.com/browser/browser/components/newtab/tests/browser/dummy_page.html";
-
-/*
- * Tests opening a newtab page with a remote URL. Simulates a newtab open from chrome
- */
-add_task(function* open_newtab() {
- let notificationPromise = nextChangeNotificationPromise(TEST_URL, "newtab page now points to test url");
- aboutNewTabService.newTabURL = TEST_URL;
-
- yield notificationPromise;
- Assert.ok(aboutNewTabService.overridden, "url has been overridden");
-
- /*
- * Simulate a newtab open as a user would.
- *
- * Bug 1240169 - We cannot set the URL to about:newtab because that would invoke the redirector.
- * The redirector always yields the loading of a default newtab URL. We expect the user to use
- * the browser UI to access overriding URLs, for istance by click on the "+" button in the tab
- * bar, or by using the new tab shortcut key.
- */
- BrowserOpenTab(); // jshint ignore:line
-
- let browser = gBrowser.selectedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield ContentTask.spawn(browser, {url: TEST_URL}, function*(args) {
- Assert.equal(content.document.location.href, args.url,
- "document.location should match the external resource");
- Assert.equal(content.document.documentURI, args.url,
- "document.documentURI should match the external resource");
- Assert.equal(content.document.nodePrincipal.URI.spec, args.url,
- "nodePrincipal should match the external resource");
- });
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-function nextChangeNotificationPromise(aNewURL, testMessage) {
- return TestUtils.topicObserved("newtab-url-changed", function observer(aSubject, aData) { // jshint unused:false
- Assert.equal(aData, aNewURL, testMessage);
- return true;
- }.bind(this));
-}
diff --git a/browser/components/newtab/tests/browser/dummy_page.html b/browser/components/newtab/tests/browser/dummy_page.html
deleted file mode 100644
index 4b0689bde..000000000
--- a/browser/components/newtab/tests/browser/dummy_page.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
- <meta charset="utf-8">
-</head>
-<body>
-<p>Dummy Page</p>
-</body>
-</html>
diff --git a/browser/components/newtab/tests/browser/newtabmessages_places.html b/browser/components/newtab/tests/browser/newtabmessages_places.html
deleted file mode 100644
index e89bc4a22..000000000
--- a/browser/components/newtab/tests/browser/newtabmessages_places.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<html>
- <head>
- <meta charset="utf8">
- <title>Newtab WebChannel test</title>
- </head>
- <body>
- <script>
- window.addEventListener("WebChannelMessageToContent", function(e) {
- if (e.detail.message) {
- let reply;
- switch (e.detail.message.type) {
- case "RECEIVE_FRECENT":
- reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "numItemsAck", data: e.detail.message.data.length}),
- })
- });
- window.dispatchEvent(reply);
- break;
- case "RECEIVE_PLACES_CHANGE":
- if (e.detail.message.data.type === "clearHistory") {
- reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "clearHistoryAck", data: e.detail.message.data.type}),
- })
- });
- window.dispatchEvent(reply);
- }
- break;
- }
- }
- }, true);
-
- document.onreadystatechange = function () {
- if (document.readyState === "complete") {
- let msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_FRECENT"}),
- })
- });
- window.dispatchEvent(msg);
- }
- }
- </script>
- </body>
-</html>
diff --git a/browser/components/newtab/tests/browser/newtabmessages_prefs.html b/browser/components/newtab/tests/browser/newtabmessages_prefs.html
deleted file mode 100644
index 9b38af4b9..000000000
--- a/browser/components/newtab/tests/browser/newtabmessages_prefs.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<html>
- <head>
- <meta charset="utf8">
- <title>Newtab WebChannel test</title>
- </head>
- <body>
- <script>
- window.addEventListener("WebChannelMessageToContent", function(e) {
- if (e.detail.message && e.detail.message.type === "RECEIVE_PREFS") {
- let reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "responseAck"}),
- })
- });
- window.dispatchEvent(reply);
- }
- }, true);
-
- document.onreadystatechange = function () {
- let msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_PREFS"}),
- })
- });
- window.dispatchEvent(msg);
- };
-
- </script>
- </body>
-</html>
diff --git a/browser/components/newtab/tests/browser/newtabmessages_preview.html b/browser/components/newtab/tests/browser/newtabmessages_preview.html
deleted file mode 100644
index 4fe55132d..000000000
--- a/browser/components/newtab/tests/browser/newtabmessages_preview.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html>
- <head>
- <meta charset="utf8">
- <title>Newtab WebChannel test</title>
- </head>
- <body>
- <script>
- let thumbURL = "https://example.com/browser/browser/components/newtab/tests/browser/blue_page.html";
-
- window.addEventListener("WebChannelMessageToContent", function(e) {
- if (e.detail.message && e.detail.message.type === "RECEIVE_THUMB") {
- if (e.detail.message.data.imgData && e.detail.message.data.url === thumbURL) {
- let reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "responseAck"}),
- })
- });
- window.dispatchEvent(reply);
- }
- }
- }, true);
-
- document.onreadystatechange = function () {
- if (document.readyState === "complete") {
- let msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_THUMB", data: thumbURL}),
- })
- });
- window.dispatchEvent(msg);
- }
- };
- </script>
- </body>
-</html>
diff --git a/browser/components/newtab/tests/browser/newtabmessages_search.html b/browser/components/newtab/tests/browser/newtabmessages_search.html
deleted file mode 100644
index b8b21c42a..000000000
--- a/browser/components/newtab/tests/browser/newtabmessages_search.html
+++ /dev/null
@@ -1,113 +0,0 @@
-<html>
- <head>
- <meta charset="utf8">
- <title>Newtab WebChannel test</title>
- </head>
- <body>
- <script>
- let suggestionsData = {
- engineName: "Engine1",
- searchString: "test",
- };
- let removeFormHistoryData = "test";
- let performSearchData = {
- engineName: "Engine1",
- healthReportKey: "1",
- searchPurpose: "d",
- searchString: "test",
- };
- let cycleEngineData = "Engine2";
-
- window.addEventListener("WebChannelMessageToContent", function(e) {
- if (e.detail.message) {
- let reply;
- switch (e.detail.message.type) {
- case "RECEIVE_UISTRINGS":
- reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "UIStringsAck", data: e.detail.message.data}),
- }
- });
- window.dispatchEvent(reply);
- break;
- case "RECEIVE_SEARCH_SUGGESTIONS":
- reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "suggestionsAck", data: e.detail.message.data}),
- }
- });
- window.dispatchEvent(reply);
- break;
- case "RECEIVE_SEARCH_STATE":
- reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "stateAck", data: e.detail.message.data}),
- }
- });
- window.dispatchEvent(reply);
- break;
- case "RECEIVE_CURRENT_ENGINE":
- reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "currentEngineAck", data: e.detail.message.data}),
- }
- });
- window.dispatchEvent(reply);
- break;
- }
- }
- }, true);
-
- document.onreadystatechange = function () {
- if (document.readyState === "complete") {
- let msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_UISTRINGS"}),
- }
- });
- window.dispatchEvent(msg);
- msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_SEARCH_SUGGESTIONS", data: suggestionsData}),
- }
- });
- window.dispatchEvent(msg);
- msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_SEARCH_STATE"}),
- }
- });
- window.dispatchEvent(msg);
- msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_REMOVE_FORM_HISTORY", data: removeFormHistoryData}),
- }
- });
- window.dispatchEvent(msg);
- msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_PERFORM_SEARCH", data: performSearchData}),
- }
- });
- window.dispatchEvent(msg);
- msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: {
- id: "newtab",
- message: JSON.stringify({type: "REQUEST_CYCLE_ENGINE", data: cycleEngineData}),
- }
- });
- window.dispatchEvent(msg);
- }
- }
- </script>
- </body>
-</html>
diff --git a/browser/components/newtab/tests/browser/newtabwebchannel_basic.html b/browser/components/newtab/tests/browser/newtabwebchannel_basic.html
deleted file mode 100644
index 7f3c79920..000000000
--- a/browser/components/newtab/tests/browser/newtabwebchannel_basic.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<html>
- <head>
- <meta charset="utf8">
- <title>Newtab WebChannel test</title>
- </head>
- <body>
- <script>
- document.onreadystatechange = function () {
- let msg = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: JSON.stringify({
- id: "newtab",
- message: JSON.stringify({type: "foo", data: "bar"}),
- })
- });
- window.dispatchEvent(msg);
- };
-
- window.addEventListener("WebChannelMessageToContent", function(e) {
- if (e.detail.message && e.detail.message.type.startsWith("respond")) {
- var detail = {
- id: "newtab",
- message: JSON.stringify({type: "reply", data: "quuz"}),
- };
- if (e.detail.message.type !== "respond_object") {
- detail = JSON.stringify(detail);
- }
- let reply = new window.CustomEvent("WebChannelMessageToChrome", {
- detail: detail
- });
- window.dispatchEvent(reply);
- }
- }, true);
-
- </script>
- </body>
-</html>
diff --git a/browser/components/newtab/tests/xpcshell/.eslintrc.js b/browser/components/newtab/tests/xpcshell/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/newtab/tests/xpcshell/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js b/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
deleted file mode 100644
index 21f68ab70..000000000
--- a/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
+++ /dev/null
@@ -1,236 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/* globals Services, XPCOMUtils, NewTabPrefsProvider, Preferences, aboutNewTabService, do_register_cleanup */
-
-"use strict";
-
-const {utils: Cu} = Components;
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
- "resource:///modules/NewTabPrefsProvider.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
- "@mozilla.org/browser/aboutnewtab-service;1",
- "nsIAboutNewTabService");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Locale",
- "resource://gre/modules/Locale.jsm");
-
-const DEFAULT_HREF = aboutNewTabService.generateRemoteURL();
-const DEFAULT_CHROME_URL = "chrome://browser/content/newtab/newTab.xhtml";
-const DOWNLOADS_URL = "chrome://browser/content/downloads/contentAreaDownloadsView.xul";
-const DEFAULT_VERSION = aboutNewTabService.remoteVersion;
-
-function cleanup() {
- Services.prefs.setBoolPref("browser.newtabpage.remote", false);
- Services.prefs.setCharPref("browser.newtabpage.remote.version", DEFAULT_VERSION);
- aboutNewTabService.resetNewTabURL();
- NewTabPrefsProvider.prefs.uninit();
-}
-
-do_register_cleanup(cleanup);
-
-/**
- * Test the overriding of the default URL
- */
-add_task(function* test_override_remote_disabled() {
- NewTabPrefsProvider.prefs.init();
- let notificationPromise;
- Services.prefs.setBoolPref("browser.newtabpage.remote", false);
-
- // tests default is the local newtab resource
- Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
- `Default newtab URL should be ${DEFAULT_CHROME_URL}`);
-
- // override with some remote URL
- let url = "http://example.com/";
- notificationPromise = nextChangeNotificationPromise(url);
- aboutNewTabService.newTabURL = url;
- yield notificationPromise;
- Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
- Assert.ok(!aboutNewTabService.remoteEnabled, "Newtab remote should not be enabled");
- Assert.equal(aboutNewTabService.newTabURL, url, "Newtab URL should be the custom URL");
-
- // test reset with remote disabled
- notificationPromise = nextChangeNotificationPromise("about:newtab");
- aboutNewTabService.resetNewTabURL();
- yield notificationPromise;
- Assert.ok(!aboutNewTabService.overridden, "Newtab URL should not be overridden");
- Assert.equal(aboutNewTabService.newTabURL, "about:newtab", "Newtab URL should be the default");
-
- // test override to a chrome URL
- notificationPromise = nextChangeNotificationPromise(DOWNLOADS_URL);
- aboutNewTabService.newTabURL = DOWNLOADS_URL;
- yield notificationPromise;
- Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
- Assert.equal(aboutNewTabService.newTabURL, DOWNLOADS_URL, "Newtab URL should be the custom URL");
-
- cleanup();
-});
-
-add_task(function* test_override_remote_enabled() {
- NewTabPrefsProvider.prefs.init();
- let notificationPromise;
- // change newtab page to remote
- notificationPromise = nextChangeNotificationPromise("about:newtab");
- Services.prefs.setBoolPref("browser.newtabpage.remote", true);
- yield notificationPromise;
- let remoteHref = aboutNewTabService.generateRemoteURL();
- Assert.equal(aboutNewTabService.defaultURL, remoteHref, "Newtab URL should be the default remote URL");
- Assert.ok(!aboutNewTabService.overridden, "Newtab URL should not be overridden");
- Assert.ok(aboutNewTabService.remoteEnabled, "Newtab remote should be enabled");
-
- // change to local newtab page while remote is enabled
- notificationPromise = nextChangeNotificationPromise(DEFAULT_CHROME_URL);
- aboutNewTabService.newTabURL = DEFAULT_CHROME_URL;
- yield notificationPromise;
- Assert.equal(aboutNewTabService.newTabURL, DEFAULT_CHROME_URL,
- "Newtab URL set to chrome url");
- Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
- "Newtab URL defaultURL set to the default chrome URL");
- Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
- Assert.ok(!aboutNewTabService.remoteEnabled, "Newtab remote should not be enabled");
-
- cleanup();
-});
-
-/**
- * Tests reponse to updates to prefs
- */
-add_task(function* test_updates() {
- /*
- * Simulates a "cold-boot" situation, with some pref already set before testing a series
- * of changes.
- */
- Preferences.set("browser.newtabpage.remote", true);
- aboutNewTabService.resetNewTabURL(); // need to set manually because pref notifs are off
- let notificationPromise;
- let productionModeBaseUrl = "https://content.cdn.mozilla.net";
- let testModeBaseUrl = "https://example.com";
- let expectedPath = `/newtab` +
- `/v${aboutNewTabService.remoteVersion}` +
- `/${aboutNewTabService.remoteReleaseName}` +
- "/en-GB" +
- "/index.html";
- let expectedHref = productionModeBaseUrl + expectedPath;
- Preferences.set("intl.locale.matchOS", true);
- Preferences.set("general.useragent.locale", "en-GB");
- Preferences.set("browser.newtabpage.remote.mode", "production");
- NewTabPrefsProvider.prefs.init();
-
- // test update checks for prefs
- notificationPromise = nextChangeNotificationPromise(
- expectedHref, "Remote href should be updated");
- Preferences.set("intl.locale.matchOS", false);
- yield notificationPromise;
-
- notificationPromise = nextChangeNotificationPromise(
- DEFAULT_HREF, "Remote href changes back to default");
- Preferences.set("general.useragent.locale", "en-US");
- yield notificationPromise;
-
- // test update fires when mode is changed
- expectedPath = expectedPath.replace("/en-GB/", "/en-US/");
- notificationPromise = nextChangeNotificationPromise(
- testModeBaseUrl + expectedPath, "Remote href changes back to origin of test mode");
- Preferences.set("browser.newtabpage.remote.mode", "test");
- yield notificationPromise;
-
- // test invalid mode ends up pointing to production url
- notificationPromise = nextChangeNotificationPromise(
- DEFAULT_HREF, "Remote href changes back to production default");
- Preferences.set("browser.newtabpage.remote.mode", "invalid");
- yield notificationPromise;
-
- // test update fires on override and reset
- let testURL = "https://example.com/";
- notificationPromise = nextChangeNotificationPromise(
- testURL, "a notification occurs on override");
- aboutNewTabService.newTabURL = testURL;
- yield notificationPromise;
-
- // from overridden to default
- notificationPromise = nextChangeNotificationPromise(
- "about:newtab", "a notification occurs on reset");
- aboutNewTabService.resetNewTabURL();
- Assert.ok(aboutNewTabService.remoteEnabled, "Newtab remote should be enabled");
- Assert.equal(aboutNewTabService.defaultURL, DEFAULT_HREF, "Default URL should be the remote page");
- yield notificationPromise;
-
- // override to default URL from default URL
- notificationPromise = nextChangeNotificationPromise(
- testURL, "a notification only occurs for a change in overridden urls");
- aboutNewTabService.newTabURL = aboutNewTabService.generateRemoteURL();
- Assert.ok(aboutNewTabService.remoteEnabled, "Newtab remote should be enabled");
- aboutNewTabService.newTabURL = testURL;
- yield notificationPromise;
- Assert.ok(!aboutNewTabService.remoteEnabled, "Newtab remote should not be enabled");
-
- // reset twice, only one notification for default URL
- notificationPromise = nextChangeNotificationPromise(
- "about:newtab", "reset occurs");
- aboutNewTabService.resetNewTabURL();
- yield notificationPromise;
-
- cleanup();
-});
-
-/**
- * Verifies that releaseFromUpdateChannel
- * Returns the correct release names
- */
-add_task(function* test_release_names() {
- let valid_channels = ["esr", "release", "beta", "aurora", "nightly"];
- let invalid_channels = new Set(["default", "invalid"]);
-
- for (let channel of valid_channels) {
- Assert.equal(channel, aboutNewTabService.releaseFromUpdateChannel(channel),
- "release == channel name when valid");
- }
-
- for (let channel of invalid_channels) {
- Assert.equal("nightly", aboutNewTabService.releaseFromUpdateChannel(channel),
- "release == nightly when invalid");
- }
-});
-
-/**
- * Verifies that remote version updates changes the remote newtab url
- */
-add_task(function* test_version_update() {
- NewTabPrefsProvider.prefs.init();
-
- Services.prefs.setBoolPref("browser.newtabpage.remote", true);
- Assert.ok(aboutNewTabService.remoteEnabled, "remote mode enabled");
-
- let productionModeBaseUrl = "https://content.cdn.mozilla.net";
- let version_incr = String(parseInt(DEFAULT_VERSION) + 1);
- let expectedPath = `/newtab` +
- `/v${version_incr}` +
- `/${aboutNewTabService.remoteReleaseName}` +
- `/${Locale.getLocale()}` +
- `/index.html`;
- let expectedHref = productionModeBaseUrl + expectedPath;
-
- let notificationPromise;
- notificationPromise = nextChangeNotificationPromise(expectedHref);
- Preferences.set("browser.newtabpage.remote.version", version_incr);
- yield notificationPromise;
-
- cleanup();
-});
-
-function nextChangeNotificationPromise(aNewURL, testMessage) {
- return new Promise(resolve => {
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) { // jshint unused:false
- Services.obs.removeObserver(observer, aTopic);
- Assert.equal(aData, aNewURL, testMessage);
- resolve();
- }, "newtab-url-changed", false);
- });
-}
diff --git a/browser/components/newtab/tests/xpcshell/test_NewTabPrefsProvider.js b/browser/components/newtab/tests/xpcshell/test_NewTabPrefsProvider.js
deleted file mode 100644
index f364d0300..000000000
--- a/browser/components/newtab/tests/xpcshell/test_NewTabPrefsProvider.js
+++ /dev/null
@@ -1,50 +0,0 @@
-"use strict";
-
-/* global XPCOMUtils, equal, Preferences, NewTabPrefsProvider, run_next_test */
-/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
-
-const Cu = Components.utils;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
- "resource:///modules/NewTabPrefsProvider.jsm");
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* test_observe() {
- let prefsMap = NewTabPrefsProvider.prefs.prefsMap;
- for (let prefName of prefsMap.keys()) {
- let prefValueType = prefsMap.get(prefName);
-
- let beforeVal;
- let afterVal;
-
- switch (prefValueType) {
- case "bool":
- beforeVal = false;
- afterVal = true;
- Preferences.set(prefName, beforeVal);
- break;
- case "localized":
- case "str":
- beforeVal = "";
- afterVal = "someStr";
- Preferences.set(prefName, beforeVal);
- break;
- }
- NewTabPrefsProvider.prefs.init();
- let promise = new Promise(resolve => {
- NewTabPrefsProvider.prefs.once(prefName, (name, data) => { // jshint ignore:line
- resolve([name, data]);
- });
- });
- Preferences.set(prefName, afterVal);
- let [actualName, actualData] = yield promise;
- equal(prefName, actualName, `emitter sent the correct pref: ${prefName}`);
- equal(afterVal, actualData, `emitter collected correct pref data for ${prefName}`);
- NewTabPrefsProvider.prefs.uninit();
- }
-});
diff --git a/browser/components/newtab/tests/xpcshell/test_NewTabSearchProvider.js b/browser/components/newtab/tests/xpcshell/test_NewTabSearchProvider.js
deleted file mode 100644
index 3e60b282a..000000000
--- a/browser/components/newtab/tests/xpcshell/test_NewTabSearchProvider.js
+++ /dev/null
@@ -1,82 +0,0 @@
-"use strict";
-
-/* global XPCOMUtils, NewTabSearchProvider, run_next_test, ok, equal, do_check_true, do_get_profile, Services */
-/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
-
-const Cu = Components.utils;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabSearchProvider",
- "resource:///modules/NewTabSearchProvider.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch",
- "resource:///modules/ContentSearch.jsm");
-
-// ensure a profile exists
-do_get_profile();
-
-function run_test() {
- run_next_test();
-}
-
-function hasProp(obj) {
- return function(aProp) {
- ok(obj.hasOwnProperty(aProp), `expect to have property ${aProp}`);
- };
-}
-
-add_task(function* test_search() {
- ContentSearch.init();
- let observerPromise = new Promise(resolve => {
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
- if (aData === "init-complete" && aTopic === "browser-search-service") {
- Services.obs.removeObserver(observer, "browser-search-service");
- resolve();
- }
- }, "browser-search-service", false);
- });
- Services.search.init();
- yield observerPromise;
- do_check_true(Services.search.isInitialized);
-
- // get initial state of search and check it has correct properties
- let state = yield NewTabSearchProvider.search.asyncGetState();
- let stateProps = hasProp(state);
- ["engines", "currentEngine"].forEach(stateProps);
-
- // check that the current engine is correct and has correct properties
- let {currentEngine} = state;
- equal(currentEngine.name, Services.search.currentEngine.name, "Current engine has been correctly set");
- var engineProps = hasProp(currentEngine);
- ["name", "placeholder", "iconBuffer"].forEach(engineProps);
-
- // create dummy test engines to test observer
- Services.search.addEngineWithDetails("TestSearch1", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
- Services.search.addEngineWithDetails("TestSearch2", "", "", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- // set one of the dummy test engines to the default engine
- Services.search.defaultEngine = Services.search.getEngineByName("TestSearch1");
-
- // test that the event emitter is working by setting a new current engine "TestSearch2"
- let engineName = "TestSearch2";
- NewTabSearchProvider.search.init();
-
- // event emitter will fire when current engine is changed
- let promise = new Promise(resolve => {
- NewTabSearchProvider.search.once("browser-search-engine-modified", (name, data) => { // jshint ignore:line
- resolve([name, data.name]);
- });
- });
-
- // set a new current engine
- Services.search.currentEngine = Services.search.getEngineByName(engineName);
- let expectedEngineName = Services.search.currentEngine.name;
-
- // emitter should fire and return the new engine
- let [eventName, actualEngineName] = yield promise;
- equal(eventName, "browser-search-engine-modified", `emitter sent the correct event ${eventName}`);
- equal(expectedEngineName, actualEngineName, `emitter set the correct engine ${expectedEngineName}`);
- NewTabSearchProvider.search.uninit();
-});
diff --git a/browser/components/newtab/tests/xpcshell/test_NewTabURL.js b/browser/components/newtab/tests/xpcshell/test_NewTabURL.js
deleted file mode 100644
index 1505e638c..000000000
--- a/browser/components/newtab/tests/xpcshell/test_NewTabURL.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/* globals Services, NewTabURL, XPCOMUtils, aboutNewTabService, NewTabPrefsProvider */
-"use strict";
-
-const {utils: Cu} = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource:///modules/NewTabURL.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
- "resource:///modules/NewTabPrefsProvider.jsm");
-XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
- "@mozilla.org/browser/aboutnewtab-service;1",
- "nsIAboutNewTabService");
-
-add_task(function*() {
- let defaultURL = aboutNewTabService.newTabURL;
- Services.prefs.setBoolPref("browser.newtabpage.remote", false);
-
- Assert.equal(NewTabURL.get(), defaultURL, `Default newtab URL should be ${defaultURL}`);
- let url = "http://example.com/";
- let notificationPromise = promiseNewtabURLNotification(url);
- NewTabURL.override(url);
- yield notificationPromise;
- Assert.ok(NewTabURL.overridden, "Newtab URL should be overridden");
- Assert.equal(NewTabURL.get(), url, "Newtab URL should be the custom URL");
-
- notificationPromise = promiseNewtabURLNotification(defaultURL);
- NewTabURL.reset();
- yield notificationPromise;
- Assert.ok(!NewTabURL.overridden, "Newtab URL should not be overridden");
- Assert.equal(NewTabURL.get(), defaultURL, "Newtab URL should be the default");
-
- // change newtab page to remote
- NewTabPrefsProvider.prefs.init();
- Services.prefs.setBoolPref("browser.newtabpage.remote", true);
- Assert.equal(NewTabURL.get(), "about:newtab", `Newtab URL should be about:newtab`);
- Assert.ok(!NewTabURL.overridden, "Newtab URL should not be overridden");
- NewTabPrefsProvider.prefs.uninit();
-});
-
-function promiseNewtabURLNotification(aNewURL) {
- return new Promise(resolve => {
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) { // jshint ignore:line
- Services.obs.removeObserver(observer, aTopic);
- Assert.equal(aData, aNewURL, "Data for newtab-url-changed notification should be new URL.");
- resolve();
- }, "newtab-url-changed", false);
- });
-}
diff --git a/browser/components/newtab/tests/xpcshell/test_PlacesProvider.js b/browser/components/newtab/tests/xpcshell/test_PlacesProvider.js
deleted file mode 100644
index 22815741b..000000000
--- a/browser/components/newtab/tests/xpcshell/test_PlacesProvider.js
+++ /dev/null
@@ -1,358 +0,0 @@
-"use strict";
-
-/* global XPCOMUtils, PlacesUtils, PlacesTestUtils, PlacesProvider, NetUtil */
-/* global do_get_profile, run_next_test, add_task */
-/* global equal, ok */
-
-const {
- utils: Cu,
- interfaces: Ci,
-} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesProvider",
- "resource:///modules/PlacesProvider.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
- "resource://gre/modules/NetUtil.jsm");
-
-// ensure a profile exists
-do_get_profile();
-
-function run_test() {
- PlacesProvider.links.init();
- run_next_test();
-}
-
-// url prefix for test history population
-const TEST_URL = "https://mozilla.com/";
-// time when the test starts execution
-const TIME_NOW = (new Date()).getTime();
-
-// utility function to compute past timestap
-function timeDaysAgo(numDays) {
- return TIME_NOW - (numDays * 24 * 60 * 60 * 1000);
-}
-
-// utility function to make a visit for insetion into places db
-function makeVisit(index, daysAgo, isTyped, domain=TEST_URL) {
- let {
- TRANSITION_TYPED,
- TRANSITION_LINK
- } = PlacesUtils.history;
-
- return {
- uri: NetUtil.newURI(`${domain}${index}`),
- visitDate: timeDaysAgo(daysAgo),
- transition: (isTyped) ? TRANSITION_TYPED : TRANSITION_LINK,
- };
-}
-
-/** Test LinkChecker **/
-
-add_task(function test_LinkChecker_securityCheck() {
-
- let urls = [
- {url: "javascript:alert('hello')", expected: false}, // jshint ignore:line
- {url: "data:image/png;base64,XXX", expected: false},
- {url: "about:newtab", expected: true},
- {url: "https://example.com", expected: true},
- {url: "ftp://example.com", expected: true},
- {url: "file://home/file/image.png", expected: true},
- {url: "resource:///modules/PlacesProvider.jsm", expected: true},
- ];
- for (let {url, expected} of urls) {
- let observed = PlacesProvider.LinkChecker.checkLoadURI(url);
- equal(observed, expected, `can load "${url}"?`);
- }
-});
-
-/** Test Provider **/
-
-add_task(function* test_Links_getLinks() {
- yield PlacesTestUtils.clearHistory();
- let provider = PlacesProvider.links;
-
- let links = yield provider.getLinks();
- equal(links.length, 0, "empty history yields empty links");
-
- // add a visit
- let testURI = NetUtil.newURI("http://mozilla.com");
- yield PlacesTestUtils.addVisits(testURI);
-
- links = yield provider.getLinks();
- equal(links.length, 1, "adding a visit yields a link");
- equal(links[0].url, testURI.spec, "added visit corresponds to added url");
-});
-
-add_task(function* test_Links_getLinks_Order() {
- yield PlacesTestUtils.clearHistory();
- let provider = PlacesProvider.links;
-
- // all four visits must come from different domains to avoid deduplication
- let visits = [
- makeVisit(0, 0, true, "http://bar.com/"), // frecency 200, today
- makeVisit(1, 0, true, "http://foo.com/"), // frecency 200, today
- makeVisit(2, 2, true, "http://buz.com/"), // frecency 200, 2 days ago
- makeVisit(3, 2, false, "http://aaa.com/"), // frecency 10, 2 days ago, transition
- ];
-
- let links = yield provider.getLinks();
- equal(links.length, 0, "empty history yields empty links");
- yield PlacesTestUtils.addVisits(visits);
-
- links = yield provider.getLinks();
- equal(links.length, visits.length, "number of links added is the same as obtain by getLinks");
- for (let i = 0; i < links.length; i++) {
- equal(links[i].url, visits[i].uri.spec, "links are obtained in the expected order");
- }
-});
-
-add_task(function* test_Links_getLinks_Deduplication() {
- yield PlacesTestUtils.clearHistory();
- let provider = PlacesProvider.links;
-
- // all for visits must come from different domains to avoid deduplication
- let visits = [
- makeVisit(0, 2, true, "http://bar.com/"), // frecency 200, 2 days ago
- makeVisit(1, 0, true, "http://bar.com/"), // frecency 200, today
- makeVisit(2, 0, false, "http://foo.com/"), // frecency 10, today
- makeVisit(3, 0, true, "http://foo.com/"), // frecency 200, today
- ];
-
- let links = yield provider.getLinks();
- equal(links.length, 0, "empty history yields empty links");
- yield PlacesTestUtils.addVisits(visits);
-
- links = yield provider.getLinks();
- equal(links.length, 2, "only two links must be left after deduplication");
- equal(links[0].url, visits[1].uri.spec, "earliest link is present");
- equal(links[1].url, visits[3].uri.spec, "most fresent link is present");
-});
-
-add_task(function* test_Links_onLinkChanged() {
- let provider = PlacesProvider.links;
-
- let url = "https://example.com/onFrecencyChanged1";
- let linkChangedMsgCount = 0;
-
- let linkChangedPromise = new Promise(resolve => {
- let handler = (_, link) => { // jshint ignore:line
- /* There are 3 linkChanged events:
- * 1. visit insertion (-1 frecency by default)
- * 2. frecency score update (after transition type calculation etc)
- * 3. title change
- */
- if (link.url === url) {
- equal(link.url, url, `expected url on linkChanged event`);
- linkChangedMsgCount += 1;
- if (linkChangedMsgCount === 3) {
- ok(true, `all linkChanged events captured`);
- provider.off("linkChanged", this);
- resolve();
- }
- }
- };
- provider.on("linkChanged", handler);
- });
-
- // add a visit
- let testURI = NetUtil.newURI(url);
- yield PlacesTestUtils.addVisits(testURI);
- yield linkChangedPromise;
-
- yield PlacesTestUtils.clearHistory();
-});
-
-add_task(function* test_Links_onClearHistory() {
- let provider = PlacesProvider.links;
-
- let clearHistoryPromise = new Promise(resolve => {
- let handler = () => {
- ok(true, `clearHistory event captured`);
- provider.off("clearHistory", handler);
- resolve();
- };
- provider.on("clearHistory", handler);
- });
-
- // add visits
- for (let i = 0; i <= 10; i++) {
- let url = `https://example.com/onClearHistory${i}`;
- let testURI = NetUtil.newURI(url);
- yield PlacesTestUtils.addVisits(testURI);
- }
- yield PlacesTestUtils.clearHistory();
- yield clearHistoryPromise;
-});
-
-add_task(function* test_Links_onDeleteURI() {
- let provider = PlacesProvider.links;
-
- let testURL = "https://example.com/toDelete";
-
- let deleteURIPromise = new Promise(resolve => {
- let handler = (_, {url}) => { // jshint ignore:line
- equal(testURL, url, "deleted url and expected url are the same");
- provider.off("deleteURI", handler);
- resolve();
- };
-
- provider.on("deleteURI", handler);
- });
-
- let testURI = NetUtil.newURI(testURL);
- yield PlacesTestUtils.addVisits(testURI);
- yield PlacesUtils.history.remove(testURL);
- yield deleteURIPromise;
-});
-
-add_task(function* test_Links_onManyLinksChanged() {
- let provider = PlacesProvider.links;
-
- let promise = new Promise(resolve => {
- let handler = () => {
- ok(true);
- provider.off("manyLinksChanged", handler);
- resolve();
- };
-
- provider.on("manyLinksChanged", handler);
- });
-
- let testURL = "https://example.com/toDelete";
- let testURI = NetUtil.newURI(testURL);
- yield PlacesTestUtils.addVisits(testURI);
-
- // trigger DecayFrecency
- PlacesUtils.history.QueryInterface(Ci.nsIObserver).
- observe(null, "idle-daily", "");
-
- yield promise;
-});
-
-add_task(function* test_Links_execute_query() {
- yield PlacesTestUtils.clearHistory();
- let provider = PlacesProvider.links;
-
- let visits = [
- makeVisit(0, 0, true), // frecency 200, today
- makeVisit(1, 0, true), // frecency 200, today
- makeVisit(2, 2, true), // frecency 200, 2 days ago
- makeVisit(3, 2, false), // frecency 10, 2 days ago, transition
- ];
-
- yield PlacesTestUtils.addVisits(visits);
-
- function testItemValue(results, index, value) {
- equal(results[index][0], `${TEST_URL}${value}`, "raw url");
- equal(results[index][1], `test visit for ${TEST_URL}${value}`, "raw title");
- }
-
- function testItemObject(results, index, columnValues) {
- Object.keys(columnValues).forEach(name => {
- equal(results[index][name], columnValues[name], "object name " + name);
- });
- }
-
- // select all 4 records
- let results = yield provider.executePlacesQuery("select url, title from moz_places");
- equal(results.length, 4, "expect 4 items");
- // check for insert order sequence
- for (let i = 0; i < results.length; i++) {
- testItemValue(results, i, i);
- }
-
- // test parameter passing
- results = yield provider.executePlacesQuery(
- "select url, title from moz_places limit :limit",
- {params: {limit: 2}}
- );
- equal(results.length, 2, "expect 2 items");
- for (let i = 0; i < results.length; i++) {
- testItemValue(results, i, i);
- }
-
- // test extracting items by name
- results = yield provider.executePlacesQuery(
- "select url, title from moz_places limit :limit",
- {columns: ["url", "title"], params: {limit: 4}}
- );
- equal(results.length, 4, "expect 4 items");
- for (let i = 0; i < results.length; i++) {
- testItemObject(results, i, {
- "url": `${TEST_URL}${i}`,
- "title": `test visit for ${TEST_URL}${i}`,
- });
- }
-
- // test ordering
- results = yield provider.executePlacesQuery(
- "select url, title, last_visit_date, frecency from moz_places " +
- "order by frecency DESC, last_visit_date DESC, url DESC limit :limit",
- {columns: ["url", "title", "last_visit_date", "frecency"], params: {limit: 4}}
- );
- equal(results.length, 4, "expect 4 items");
- testItemObject(results, 0, {url: `${TEST_URL}1`});
- testItemObject(results, 1, {url: `${TEST_URL}0`});
- testItemObject(results, 2, {url: `${TEST_URL}2`});
- testItemObject(results, 3, {url: `${TEST_URL}3`});
-
- // test callback passing
- results = [];
- function handleRow(aRow) {
- results.push({
- url: aRow.getResultByName("url"),
- title: aRow.getResultByName("title"),
- last_visit_date: aRow.getResultByName("last_visit_date"),
- frecency: aRow.getResultByName("frecency")
- });
- }
- yield provider.executePlacesQuery(
- "select url, title, last_visit_date, frecency from moz_places " +
- "order by frecency DESC, last_visit_date DESC, url DESC",
- {callback: handleRow}
- );
- equal(results.length, 4, "expect 4 items");
- testItemObject(results, 0, {url: `${TEST_URL}1`});
- testItemObject(results, 1, {url: `${TEST_URL}0`});
- testItemObject(results, 2, {url: `${TEST_URL}2`});
- testItemObject(results, 3, {url: `${TEST_URL}3`});
-
- // negative test cases
- // bad sql
- try {
- yield provider.executePlacesQuery("select from moz");
- do_throw("bad sql should've thrown");
- }
- catch (e) {
- do_check_true("expected failure - bad sql");
- }
- // missing bindings
- try {
- yield provider.executePlacesQuery("select * from moz_places limit :limit");
- do_throw("bad sql should've thrown");
- }
- catch (e) {
- do_check_true("expected failure - missing bidning");
- }
- // non-existent column name
- try {
- yield provider.executePlacesQuery("select * from moz_places limit :limit",
- {columns: ["no-such-column"], params: {limit: 4}});
- do_throw("bad sql should've thrown");
- }
- catch (e) {
- do_check_true("expected failure - wrong column name");
- }
-
- // cleanup
- yield PlacesTestUtils.clearHistory();
-});
diff --git a/browser/components/newtab/tests/xpcshell/xpcshell.ini b/browser/components/newtab/tests/xpcshell/xpcshell.ini
deleted file mode 100644
index c249ee3e2..000000000
--- a/browser/components/newtab/tests/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-head =
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-[test_AboutNewTabService.js]
-[test_NewTabPrefsProvider.js]
-[test_NewTabSearchProvider.js]
-[test_NewTabURL.js]
-[test_PlacesProvider.js]
diff --git a/browser/components/originattributes/moz.build b/browser/components/originattributes/moz.build
deleted file mode 100644
index ea5943ea1..000000000
--- a/browser/components/originattributes/moz.build
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser/browser.ini',
-]
-
-MOCHITEST_MANIFESTS += [
- 'test/mochitest/mochitest.ini'
-]
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'OriginAttributes')
diff --git a/browser/components/originattributes/test/browser/.eslintrc.js b/browser/components/originattributes/test/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/originattributes/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/originattributes/test/browser/browser.ini b/browser/components/originattributes/test/browser/browser.ini
deleted file mode 100644
index 61f674377..000000000
--- a/browser/components/originattributes/test/browser/browser.ini
+++ /dev/null
@@ -1,64 +0,0 @@
-[DEFAULT]
-tags = usercontextid firstpartyisolation originattributes
-support-files =
- dummy.html
- file_broadcastChannel.html
- file_broadcastChanneliFrame.html
- file_cache.html
- file_favicon.html
- file_favicon.png
- file_favicon.png^headers^
- file_favicon_cache.html
- file_favicon_cache.png
- file_favicon_thirdParty.html
- file_firstPartyBasic.html
- file_sharedworker.html
- file_sharedworker.js
- file_thirdPartyChild.audio.ogg
- file_thirdPartyChild.embed.png
- file_thirdPartyChild.fetch.html
- file_thirdPartyChild.iframe.html
- file_thirdPartyChild.img.png
- file_thirdPartyChild.import.js
- file_thirdPartyChild.link.css
- file_thirdPartyChild.object.png
- file_thirdPartyChild.request.html
- file_thirdPartyChild.script.js
- file_thirdPartyChild.sharedworker.js
- file_thirdPartyChild.track.vtt
- file_thirdPartyChild.video.ogv
- file_thirdPartyChild.worker.fetch.html
- file_thirdPartyChild.worker.js
- file_thirdPartyChild.worker.request.html
- file_thirdPartyChild.worker.xhr.html
- file_thirdPartyChild.xhr.html
- head.js
- test.js
- test.js^headers^
- test.html
- test2.html
- test2.js
- test2.js^headers^
- test_firstParty.html
- test_firstParty_cookie.html
- test_firstParty_html_redirect.html
- test_firstParty_http_redirect.html
- test_firstParty_http_redirect.html^headers^
- test_firstParty_iframe_http_redirect.html
- test_firstParty_postMessage.html
- window.html
- worker_blobify.js
- worker_deblobify.js
-
-[browser_broadcastChannel.js]
-[browser_cache.js]
-[browser_cookieIsolation.js]
-[browser_favicon_firstParty.js]
-[browser_favicon_userContextId.js]
-[browser_firstPartyIsolation.js]
-[browser_localStorageIsolation.js]
-[browser_blobURLIsolation.js]
-[browser_imageCacheIsolation.js]
-[browser_sharedworker.js]
-[browser_httpauth.js]
-[browser_clientAuth.js]
diff --git a/browser/components/originattributes/test/browser/browser_blobURLIsolation.js b/browser/components/originattributes/test/browser/browser_blobURLIsolation.js
deleted file mode 100644
index 1d1b7c8e1..000000000
--- a/browser/components/originattributes/test/browser/browser_blobURLIsolation.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Bug 1264573 - A test case for blob url isolation.
- */
-
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/" +
- "originattributes/test/browser/file_firstPartyBasic.html";
-const SCRIPT_WORKER_BLOBIFY = "worker_blobify.js";
-const SCRIPT_WORKER_DEBLOBIFY = "worker_deblobify.js";
-
-function page_blobify(browser, input) {
- return ContentTask.spawn(browser, input, function(input) {
- return { blobURL: content.URL.createObjectURL(new content.Blob([input])) };
- });
-}
-
-function page_deblobify(browser, blobURL) {
- return ContentTask.spawn(browser, blobURL, function* (blobURL) {
- if ("error" in blobURL) {
- return blobURL;
- }
- blobURL = blobURL.blobURL;
-
- function blobURLtoBlob(blobURL) {
- return new content.Promise(function (resolve) {
- let xhr = new content.XMLHttpRequest();
- xhr.open("GET", blobURL, true);
- xhr.onload = function () {
- resolve(xhr.response);
- };
- xhr.onerror = function () {
- resolve("xhr error");
- };
- xhr.responseType = "blob";
- xhr.send();
- });
- }
-
- function blobToString(blob) {
- return new content.Promise(function (resolve) {
- let fileReader = new content.FileReader();
- fileReader.onload = function () {
- resolve(fileReader.result);
- };
- fileReader.readAsText(blob);
- });
- }
-
- let blob = yield blobURLtoBlob(blobURL);
- if (blob == "xhr error") {
- return "xhr error";
- }
-
- return yield blobToString(blob);
- });
-}
-
-function workerIO(browser, scriptFile, message) {
- return ContentTask.spawn(browser, {scriptFile, message}, function* (args) {
- let worker = new content.Worker(args.scriptFile);
- let promise = new content.Promise(function(resolve) {
- let listenFunction = function(event) {
- worker.removeEventListener("message", listenFunction, false);
- worker.terminate();
- resolve(event.data);
- };
- worker.addEventListener("message", listenFunction, false);
- });
- worker.postMessage(args.message);
- return yield promise;
- });
-}
-
-let worker_blobify = (browser, input) => workerIO(browser, SCRIPT_WORKER_BLOBIFY, input);
-let worker_deblobify = (browser, blobURL) => workerIO(browser, SCRIPT_WORKER_DEBLOBIFY, blobURL);
-
-function doTest(blobify, deblobify) {
- let blobURL = null;
- return function* (browser) {
- if (blobURL === null) {
- let input = Math.random().toString();
- blobURL = yield blobify(browser, input);
- return input;
- }
- let result = yield deblobify(browser, blobURL);
- blobURL = null;
- return result;
- }
-}
-
-let tests = [];
-for (let blobify of [page_blobify, worker_blobify]) {
- for (let deblobify of [page_deblobify, worker_deblobify]) {
- tests.push(doTest(blobify, deblobify));
- }
-}
-
-IsolationTestTools.runTests(TEST_PAGE, tests);
diff --git a/browser/components/originattributes/test/browser/browser_broadcastChannel.js b/browser/components/originattributes/test/browser/browser_broadcastChannel.js
deleted file mode 100644
index 3a2bd7405..000000000
--- a/browser/components/originattributes/test/browser/browser_broadcastChannel.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Bug 1264571 - A test case of broadcast channels for first party isolation.
- */
-
-const TEST_DOMAIN = "http://example.net/";
-const TEST_PATH = TEST_DOMAIN + "browser/browser/components/originattributes/test/browser/";
-const TEST_PAGE = TEST_PATH + "file_broadcastChannel.html";
-
-function* doTest(aBrowser) {
- let response = yield ContentTask.spawn(aBrowser, null, function* () {
-
- let displayItem = content.document.getElementById("display");
-
- // If there is nothing in the 'display', we will try to send a message to
- // the broadcast channel and wait until this message has been delivered.
- // The way that how we make sure the message is delivered is based on an
- // iframe which will reply everything it receives from the broadcast channel
- // to the current window through the postMessage. So, we can know that the
- // boradcast message is sent successfully when the window receives a message
- // from the iframe.
- if (displayItem.innerHTML === "") {
- let data = Math.random().toString();
-
- let receivedData = yield new Promise(resolve => {
- let listenFunc = event => {
- content.removeEventListener("message", listenFunc);
- resolve(event.data);
- };
-
- let bc = new content.BroadcastChannel("testBroadcastChannel");
-
- content.addEventListener("message", listenFunc, false);
- bc.postMessage(data);
- });
-
- is(receivedData, data, "The value should be the same.");
-
- return receivedData;
- }
-
- return displayItem.innerHTML;
- });
-
- return response;
-}
-
-IsolationTestTools.runTests(TEST_PAGE, doTest);
diff --git a/browser/components/originattributes/test/browser/browser_cache.js b/browser/components/originattributes/test/browser/browser_cache.js
deleted file mode 100644
index d5f3a8f58..000000000
--- a/browser/components/originattributes/test/browser/browser_cache.js
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Bug 1264577 - A test case for testing caches of various submodules.
- * This test case will load two pages that each page loads various resources
- * within the same third party domain for the same originAttributes or different
- * originAttributes. And then, it verifies the number of cache entries and
- * the originAttributes of loading channels. If these two pages belong to
- * the same originAttributes, the number of cache entries for a certain
- * resource would be one. Otherwise, it would be two.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
-let protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1"]
- .getService(Ci.nsIProtocolProxyService);
-
-const TEST_DOMAIN = "http://example.net";
-const TEST_PATH = "/browser/browser/components/originattributes/test/browser/";
-const TEST_PAGE = TEST_DOMAIN + TEST_PATH + "file_cache.html";
-
-let suffixes = ["iframe.html", "link.css", "script.js", "img.png", "object.png",
- "embed.png", "xhr.html", "worker.xhr.html", "audio.ogg",
- "video.ogv", "track.vtt",
- "fetch.html", "worker.fetch.html",
- "request.html", "worker.request.html",
- "import.js", "worker.js", "sharedworker.js"];
-
-// A random value for isolating video/audio elements across different tests.
-let randomSuffix;
-
-function clearAllImageCaches() {
- let tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
- .getService(SpecialPowers.Ci.imgITools);
- let imageCache = tools.getImgCacheForDocument(window.document);
- imageCache.clearCache(true); // true=chrome
- imageCache.clearCache(false); // false=content
-}
-
-function cacheDataForContext(loadContextInfo) {
- return new Promise(resolve => {
- let cacheEntries = [];
- let cacheVisitor = {
- onCacheStorageInfo(num, consumption) {},
- onCacheEntryInfo(uri, idEnhance) {
- cacheEntries.push({ uri: uri,
- idEnhance: idEnhance });
- },
- onCacheEntryVisitCompleted() {
- resolve(cacheEntries);
- },
- QueryInterface(iid) {
- if (iid.equals(Ci.nsICacheStorageVisitor))
- return this;
-
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
- };
- // Visiting the disk cache also visits memory storage so we do not
- // need to use Services.cache2.memoryCacheStorage() here.
- let storage = Services.cache2.diskCacheStorage(loadContextInfo, false);
- storage.asyncVisitStorage(cacheVisitor, true);
- });
-}
-
-let countMatchingCacheEntries = function (cacheEntries, domain, fileSuffix) {
- return cacheEntries.map(entry => entry.uri.asciiSpec)
- .filter(spec => spec.includes(domain))
- .filter(spec => spec.includes("file_thirdPartyChild." + fileSuffix))
- .length;
-};
-
-function observeChannels(onChannel) {
- // We use a dummy proxy filter to catch all channels, even those that do not
- // generate an "http-on-modify-request" notification, such as link preconnects.
- let proxyFilter = {
- applyFilter : function (aProxyService, aChannel, aProxy) {
- // We have the channel; provide it to the callback.
- onChannel(aChannel);
- // Pass on aProxy unmodified.
- return aProxy;
- }
- };
- protocolProxyService.registerChannelFilter(proxyFilter, 0);
- // Return the stop() function:
- return () => protocolProxyService.unregisterChannelFilter(proxyFilter);
-}
-
-function startObservingChannels(aMode) {
- let stopObservingChannels = observeChannels(function (channel) {
- let originalURISpec = channel.originalURI.spec;
- if (originalURISpec.includes("example.net")) {
- let loadInfo = channel.loadInfo;
-
- switch (aMode) {
- case TEST_MODE_FIRSTPARTY:
- ok(loadInfo.originAttributes.firstPartyDomain === "example.com" ||
- loadInfo.originAttributes.firstPartyDomain === "example.org",
- "first party for " + originalURISpec + " is " + loadInfo.originAttributes.firstPartyDomain);
- break;
-
- case TEST_MODE_NO_ISOLATION:
- ok(ChromeUtils.isOriginAttributesEqual(loadInfo.originAttributes, ChromeUtils.fillNonDefaultOriginAttributes()),
- "OriginAttributes for " + originalURISpec + " is default.");
- break;
-
- case TEST_MODE_CONTAINERS:
- ok(loadInfo.originAttributes.userContextId === 1 ||
- loadInfo.originAttributes.userContextId === 2,
- "userContextId for " + originalURISpec + " is " + loadInfo.originAttributes.userContextId);
- break;
-
- default:
- ok(false, "Unknown test mode.");
- }
- }
- });
- return stopObservingChannels;
-}
-
-let stopObservingChannels;
-
-// The init function, which clears image and network caches, and generates
-// the random value for isolating video and audio elements across different
-// test runs.
-function* doInit(aMode) {
- yield SpecialPowers.pushPrefEnv({"set": [["network.predictor.enabled", false],
- ["network.predictor.enable-prefetch", false]]});
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- randomSuffix = Math.random();
- stopObservingChannels = startObservingChannels(aMode);
-}
-
-// In the test function, we dynamically generate the video and audio element,
-// and assign a random suffix to their URL to isolate them across different
-// test runs.
-function* doTest(aBrowser) {
-
- let argObj = {
- randomSuffix: randomSuffix,
- urlPrefix: TEST_DOMAIN + TEST_PATH,
- };
-
- yield ContentTask.spawn(aBrowser, argObj, function* (arg) {
- let videoURL = arg.urlPrefix + "file_thirdPartyChild.video.ogv";
- let audioURL = arg.urlPrefix + "file_thirdPartyChild.audio.ogg";
- let trackURL = arg.urlPrefix + "file_thirdPartyChild.track.vtt";
- let URLSuffix = "?r=" + arg.randomSuffix;
-
- // Create the audio and video elements.
- let audio = content.document.createElement('audio');
- let video = content.document.createElement('video');
- let audioSource = content.document.createElement('source');
- let audioTrack = content.document.createElement('track');
-
- // Append the audio and track element into the body, and wait until they're finished.
- yield new Promise(resolve => {
- let audioLoaded = false;
- let trackLoaded = false;
-
- let audioListener = () => {
- audio.removeEventListener("canplaythrough", audioListener);
-
- audioLoaded = true;
- if (audioLoaded && trackLoaded) {
- resolve();
- }
- };
-
- let trackListener = () => {
- audioTrack.removeEventListener("load", trackListener);
-
- trackLoaded = true;
- if (audioLoaded && trackLoaded) {
- resolve();
- }
- };
-
- // Add the event listeners before everything in case we lose events.
- audioTrack.addEventListener("load", trackListener, false);
- audio.addEventListener("canplaythrough", audioListener, false);
-
- // Assign attributes for the audio element.
- audioSource.setAttribute("src", audioURL + URLSuffix);
- audioSource.setAttribute("type", "audio/ogg");
- audioTrack.setAttribute("src", trackURL);
- audioTrack.setAttribute("kind", "subtitles");
-
- audio.appendChild(audioSource);
- audio.appendChild(audioTrack);
- audio.autoplay = true;
-
- content.document.body.appendChild(audio);
- });
-
- // Append the video element into the body, and wait until it's finished.
- yield new Promise(resolve => {
- let listener = () => {
- video.removeEventListener("canplaythrough", listener);
- resolve();
- };
-
- // Add the event listener before everything in case we lose the event.
- video.addEventListener("canplaythrough", listener, false);
-
- // Assign attributes for the video element.
- video.setAttribute("src", videoURL + URLSuffix);
- video.setAttribute("type", "video/ogg");
-
- content.document.body.appendChild(video);
- });
- });
-
- return 0;
-}
-
-// The check function, which checks the number of cache entries.
-function* doCheck(aShouldIsolate, aInputA, aInputB) {
- let expectedEntryCount = 1;
- let data = [];
- data = data.concat(yield cacheDataForContext(LoadContextInfo.default));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.private));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(true, {})));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(false, { userContextId: 1 })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(true, { userContextId: 1 })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(false, { userContextId: 2 })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(true, { userContextId: 2 })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(false, { firstPartyDomain: "example.com" })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(true, { firstPartyDomain: "example.com" })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(false, { firstPartyDomain: "example.org" })));
- data = data.concat(yield cacheDataForContext(LoadContextInfo.custom(true, { firstPartyDomain: "example.org" })));
-
- if (aShouldIsolate) {
- expectedEntryCount = 2;
- }
-
- for (let suffix of suffixes) {
- let foundEntryCount = countMatchingCacheEntries(data, "example.net", suffix);
- let result = (expectedEntryCount === foundEntryCount);
- ok(result, "Cache entries expected for " + suffix + ": " + expectedEntryCount +
- ", and found " + foundEntryCount);
- }
-
- stopObservingChannels();
- stopObservingChannels = undefined;
- return true;
-}
-
-let testArgs = {
- url: TEST_PAGE,
- firstFrameSetting: DEFAULT_FRAME_SETTING,
- secondFrameSetting: [TEST_TYPE_FRAME],
-};
-
-IsolationTestTools.runTests(testArgs, doTest, doCheck, doInit);
diff --git a/browser/components/originattributes/test/browser/browser_clientAuth.js b/browser/components/originattributes/test/browser/browser_clientAuth.js
deleted file mode 100644
index 48961dce0..000000000
--- a/browser/components/originattributes/test/browser/browser_clientAuth.js
+++ /dev/null
@@ -1,44 +0,0 @@
-let certCached = true;
-let secondTabStarted = false;
-
-function onCertDialogLoaded(subject) {
- certCached = false;
- // Click OK.
- subject.acceptDialog();
-}
-
-Services.obs.addObserver(onCertDialogLoaded, "cert-dialog-loaded", false);
-
-registerCleanupFunction(() => {
- Services.obs.removeObserver(onCertDialogLoaded, "cert-dialog-loaded");
-});
-
-function* setup() {
- yield SpecialPowers.pushPrefEnv({
- set: [["security.default_personal_cert", "Ask Every Time"]]
- });
-}
-
-function getResult() {
- // The first tab always returns true.
- if (!secondTabStarted) {
- certCached = true;
- secondTabStarted = true;
- return true;
- }
-
- // The second tab returns true if the cert is cached, so it will be different
- // from the result of the first tab, and considered isolated.
- let ret = certCached;
- certCached = true;
- secondTabStarted = false;
- return ret;
-}
-
-// aGetResultImmediately must be true because we need to get the result before
-// the next tab is opened.
-IsolationTestTools.runTests("https://requireclientcert.example.com",
- getResult,
- null, // aCompareResultFunc
- setup, // aBeginFunc
- true); // aGetResultImmediately
diff --git a/browser/components/originattributes/test/browser/browser_cookieIsolation.js b/browser/components/originattributes/test/browser/browser_cookieIsolation.js
deleted file mode 100644
index 6259723ba..000000000
--- a/browser/components/originattributes/test/browser/browser_cookieIsolation.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Bug 1312541 - A test case for document.cookie isolation.
- */
-
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/" +
- "originattributes/test/browser/file_firstPartyBasic.html";
-
-// Use a random key so we don't access it in later tests.
-const key = "key" + Math.random().toString();
-const re = new RegExp(key + "=([0-9\.]+)");
-
-// Define the testing function
-function* doTest(aBrowser) {
- return yield ContentTask.spawn(aBrowser, {key, re},
- function ({key, re}) {
- let result = re.exec(content.document.cookie);
- if (result) {
- return result[1];
- }
- // No value is found, so we create one.
- let value = Math.random().toString();
- content.document.cookie = key + "=" + value;
- return value;
- });
-}
-
-registerCleanupFunction(() => {
- Services.cookies.removeAll();
-});
-
-IsolationTestTools.runTests(TEST_PAGE, doTest);
diff --git a/browser/components/originattributes/test/browser/browser_favicon_firstParty.js b/browser/components/originattributes/test/browser/browser_favicon_firstParty.js
deleted file mode 100644
index b3a18947b..000000000
--- a/browser/components/originattributes/test/browser/browser_favicon_firstParty.js
+++ /dev/null
@@ -1,343 +0,0 @@
-/**
- * Bug 1277803 - A test case for testing favicon loading across different first party domains.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/PlacesUtils.jsm");
-
-const FIRST_PARTY_ONE = "example.com";
-const FIRST_PARTY_TWO = "example.org";
-const THIRD_PARTY = "mochi.test:8888";
-
-const TEST_SITE_ONE = "http://" + FIRST_PARTY_ONE;
-const TEST_SITE_TWO = "http://" + FIRST_PARTY_TWO;
-const THIRD_PARTY_SITE = "http://" + THIRD_PARTY;
-const TEST_DIRECTORY = "/browser/browser/components/originattributes/test/browser/";
-
-const TEST_PAGE = TEST_DIRECTORY + "file_favicon.html";
-const TEST_THIRD_PARTY_PAGE = TEST_DIRECTORY + "file_favicon_thirdParty.html";
-const TEST_CACHE_PAGE = TEST_DIRECTORY + "file_favicon_cache.html";
-
-const FAVICON_URI = TEST_DIRECTORY + "file_favicon.png";
-const TEST_FAVICON_CACHE_URI = TEST_DIRECTORY + "file_favicon_cache.png";
-
-let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-let makeURI = Cu.import("resource://gre/modules/BrowserUtils.jsm", {}).BrowserUtils.makeURI;
-
-function clearAllImageCaches() {
- let tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
- .getService(SpecialPowers.Ci.imgITools);
- let imageCache = tools.getImgCacheForDocument(window.document);
- imageCache.clearCache(true); // true=chrome
- imageCache.clearCache(false); // false=content
-}
-
-function clearAllPlacesFavicons() {
- let faviconService = Cc["@mozilla.org/browser/favicon-service;1"]
- .getService(Ci.nsIFaviconService);
-
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- if (aTopic === "places-favicons-expired") {
- resolve();
- Services.obs.removeObserver(observer, "places-favicons-expired", false);
- }
- }
- };
-
- Services.obs.addObserver(observer, "places-favicons-expired", false);
- faviconService.expireAllFavicons();
- });
-}
-
-function observeFavicon(aFirstPartyDomain, aExpectedCookie, aPageURI) {
- let faviconReqXUL = false;
- let faviconReqPlaces = false;
- let expectedPrincipal = Services.scriptSecurityManager
- .createCodebasePrincipal(aPageURI, { firstPartyDomain: aFirstPartyDomain });
-
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- // Make sure that the topic is 'http-on-modify-request'.
- if (aTopic === "http-on-modify-request") {
- // We check the firstPartyDomain for the originAttributes of the loading
- // channel. All requests for the favicon should contain the correct
- // firstPartyDomain. There are two requests for a favicon loading, one
- // from the Places library and one from the XUL image. The difference
- // of them is the loading principal. The Places will use the content
- // principal and the XUL image will use the system principal.
-
- let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
- let reqLoadInfo = httpChannel.loadInfo;
- let loadingPrincipal = reqLoadInfo.loadingPrincipal;
- let triggeringPrincipal = reqLoadInfo.triggeringPrincipal;
-
- // Make sure this is a favicon request.
- if (!httpChannel.URI.spec.endsWith(FAVICON_URI)) {
- return;
- }
-
- // Check the first party domain.
- is(reqLoadInfo.originAttributes.firstPartyDomain, aFirstPartyDomain,
- "The loadInfo has correct first party domain");
-
- if (loadingPrincipal.equals(systemPrincipal)) {
- faviconReqXUL = true;
- ok(triggeringPrincipal.equals(expectedPrincipal),
- "The triggeringPrincipal of favicon loading from XUL should be the content principal.");
- } else {
- faviconReqPlaces = true;
- ok(loadingPrincipal.equals(expectedPrincipal),
- "The loadingPrincipal of favicon loading from Places should be the content prinicpal");
- }
-
- let faviconCookie = httpChannel.getRequestHeader("cookie");
-
- is(faviconCookie, aExpectedCookie, "The cookie of the favicon loading is correct.");
- } else {
- ok(false, "Received unexpected topic: ", aTopic);
- }
-
- if (faviconReqXUL && faviconReqPlaces) {
- Services.obs.removeObserver(observer, "http-on-modify-request", false);
- resolve();
- }
- }
- };
-
- Services.obs.addObserver(observer, "http-on-modify-request", false);
- });
-}
-
-function waitOnFaviconResponse(aFaviconURL) {
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- if (aTopic === "http-on-examine-response" ||
- aTopic === "http-on-examine-cached-response") {
-
- let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
- let loadInfo = httpChannel.loadInfo;
-
- if (httpChannel.URI.spec !== aFaviconURL) {
- return;
- }
-
- let result = {
- topic: aTopic,
- firstPartyDomain: loadInfo.originAttributes.firstPartyDomain
- };
-
- resolve(result);
- Services.obs.removeObserver(observer, "http-on-examine-response", false);
- Services.obs.removeObserver(observer, "http-on-examine-cached-response", false);
- }
- }
- };
-
- Services.obs.addObserver(observer, "http-on-examine-response", false);
- Services.obs.addObserver(observer, "http-on-examine-cached-response", false);
- });
-}
-
-function waitOnFaviconLoaded(aFaviconURL) {
- return new Promise(resolve => {
- let observer = {
- onPageChanged(uri, attr, value, id) {
-
- if (attr === Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON &&
- value === aFaviconURL) {
- resolve();
- PlacesUtils.history.removeObserver(observer, false);
- }
- },
- };
-
- PlacesUtils.history.addObserver(observer, false);
- });
-}
-
-function* openTab(aURL) {
- let tab = gBrowser.addTab(aURL);
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-function* assignCookiesUnderFirstParty(aURL, aFirstParty, aCookieValue) {
- // Open a tab under the given aFirstParty, and this tab will have an
- // iframe which loads the aURL.
- let tabInfo = yield openTabInFirstParty(aURL, aFirstParty);
-
- // Add cookies into the iframe.
- yield ContentTask.spawn(tabInfo.browser, aCookieValue, function* (value) {
- content.document.cookie = value;
- });
-
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-}
-
-function* generateCookies(aThirdParty) {
- // we generate two different cookies for two first party domains.
- let cookies = [];
- cookies.push(Math.random().toString());
- cookies.push(Math.random().toString());
-
- let firstSiteURL;
- let secondSiteURL;
-
- if (aThirdParty) {
- // Add cookies into the third party site with different first party domain.
- firstSiteURL = THIRD_PARTY_SITE;
- secondSiteURL = THIRD_PARTY_SITE;
- } else {
- // Add cookies into sites.
- firstSiteURL = TEST_SITE_ONE;
- secondSiteURL = TEST_SITE_TWO;
- }
-
- yield assignCookiesUnderFirstParty(firstSiteURL, TEST_SITE_ONE, cookies[0]);
- yield assignCookiesUnderFirstParty(secondSiteURL, TEST_SITE_TWO, cookies[1]);
-
- return cookies;
-}
-
-function* doTest(aTestPage, aExpectedCookies, aFaviconURL) {
- let firstPageURI = makeURI(TEST_SITE_ONE + aTestPage);
- let secondPageURI = makeURI(TEST_SITE_TWO + aTestPage);
-
- // Start to observe the event of that favicon has been fully loaded.
- let promiseFaviconLoaded = waitOnFaviconLoaded(aFaviconURL);
-
- // Start to observe the favicon requests earlier in case we miss it.
- let promiseObserveFavicon = observeFavicon(FIRST_PARTY_ONE, aExpectedCookies[0], firstPageURI);
-
- // Open the tab for the first site.
- let tabInfo = yield openTab(TEST_SITE_ONE + aTestPage);
-
- // Waiting until favicon requests are all made.
- yield promiseObserveFavicon;
-
- // Waiting until favicon loaded.
- yield promiseFaviconLoaded;
-
- // Close the tab.
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-
- // Start to observe the favicon requests earlier in case we miss it.
- promiseObserveFavicon = observeFavicon(FIRST_PARTY_TWO, aExpectedCookies[1], secondPageURI);
-
- // Open the tab for the second site.
- tabInfo = yield openTab(TEST_SITE_TWO + aTestPage);
-
- // Waiting until favicon requests are all made.
- yield promiseObserveFavicon;
-
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-}
-
-add_task(function* setup() {
- // Make sure first party isolation is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [
- ["privacy.firstparty.isolate", true]
- ]});
-});
-
-// A clean up function to prevent affecting other tests.
-registerCleanupFunction(() => {
- // Clear all cookies.
- let cookieMgr = Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- cookieMgr.removeAll();
-
- // Clear all image caches and network caches.
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-});
-
-add_task(function* test_favicon_firstParty() {
- for (let testThirdParty of [false, true]) {
- // Clear all image caches and network caches before running the test.
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- // Clear Places favicon caches.
- yield clearAllPlacesFavicons();
-
- let cookies = yield generateCookies(testThirdParty);
-
- if (testThirdParty) {
- yield doTest(TEST_THIRD_PARTY_PAGE, cookies, THIRD_PARTY_SITE + FAVICON_URI);
- } else {
- yield doTest(TEST_PAGE, cookies, TEST_SITE_ONE + FAVICON_URI);
- }
- }
-});
-
-add_task(function* test_favicon_cache_firstParty() {
- // Clear all image caches and network caches before running the test.
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- // Start to observer the event of that favicon has been fully loaded and cached.
- let promiseForFaviconLoaded = waitOnFaviconLoaded(THIRD_PARTY_SITE + TEST_FAVICON_CACHE_URI);
-
- // Start to observer for the favicon response of the first tab.
- let responsePromise = waitOnFaviconResponse(THIRD_PARTY_SITE + TEST_FAVICON_CACHE_URI);
-
- // Open the tab for the first site.
- let tabInfoA = yield openTab(TEST_SITE_ONE + TEST_CACHE_PAGE);
-
- // Waiting for the favicon response.
- let response = yield responsePromise;
-
- // Make sure the favicon is loaded through the network and its first party domain is correct.
- is(response.topic, "http-on-examine-response", "The favicon image should be loaded through network.");
- is(response.firstPartyDomain, FIRST_PARTY_ONE, "We should only observe the network response for the first first party.");
-
- // Waiting until the favicon has been loaded and cached.
- yield promiseForFaviconLoaded;
-
- // Open the tab again for checking the image cache is working correctly.
- let tabInfoB = yield openTab(TEST_SITE_ONE + TEST_CACHE_PAGE);
-
- // Start to observe the favicon response, the second tab actually will not
- // make any network request since the favicon will be loaded by the cache for
- // both Places and XUL image. So here, we are going to observe the favicon
- // response for the third tab which opens with the second first party.
- let promiseForFaviconResponse = waitOnFaviconResponse(THIRD_PARTY_SITE + TEST_FAVICON_CACHE_URI);
-
- // Open the tab for the second site.
- let tabInfoC = yield openTab(TEST_SITE_TWO + TEST_CACHE_PAGE);
-
- // Wait for the favicon response. In this case, we suppose to catch the
- // response for the third tab but not the second tab since it will not
- // go through the network.
- response = yield promiseForFaviconResponse;
-
- // Check that the favicon response has came from the network and it has the
- // correct first party domain.
- is(response.topic, "http-on-examine-response", "The favicon image should be loaded through network again.");
- is(response.firstPartyDomain, FIRST_PARTY_TWO, "We should only observe the network response for the second first party.");
-
- yield BrowserTestUtils.removeTab(tabInfoA.tab);
- yield BrowserTestUtils.removeTab(tabInfoB.tab);
- yield BrowserTestUtils.removeTab(tabInfoC.tab);
-});
diff --git a/browser/components/originattributes/test/browser/browser_favicon_userContextId.js b/browser/components/originattributes/test/browser/browser_favicon_userContextId.js
deleted file mode 100644
index 507e0a6d4..000000000
--- a/browser/components/originattributes/test/browser/browser_favicon_userContextId.js
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * Bug 1277803 - A test caes for testing favicon loading across different userContextId.
- */
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-
-const TEST_SITE = "http://example.net";
-const TEST_THIRD_PARTY_SITE = "http://mochi.test:8888";
-
-const TEST_PAGE = TEST_SITE + "/browser/browser/components/originattributes/" +
- "test/browser/file_favicon.html";
-const FAVICON_URI = TEST_SITE + "/browser/browser/components/originattributes/" +
- "test/browser/file_favicon.png";
-const TEST_THIRD_PARTY_PAGE = "http://example.com/browser/browser/components/" +
- "originattributes/test/browser/file_favicon_thirdParty.html";
-const THIRD_PARTY_FAVICON_URI = TEST_THIRD_PARTY_SITE + "/browser/browser/components/" +
- "originattributes/test/browser/file_favicon.png";
-
-const USER_CONTEXT_ID_PERSONAL = 1;
-const USER_CONTEXT_ID_WORK = 2;
-
-let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-let makeURI = Cu.import("resource://gre/modules/BrowserUtils.jsm", {}).BrowserUtils.makeURI;
-
-function clearAllImageCaches() {
- var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
- .getService(SpecialPowers.Ci.imgITools);
- var imageCache = tools.getImgCacheForDocument(window.document);
- imageCache.clearCache(true); // true=chrome
- imageCache.clearCache(false); // false=content
-}
-
-function clearAllPlacesFavicons() {
- let faviconService = Cc["@mozilla.org/browser/favicon-service;1"]
- .getService(Ci.nsIFaviconService);
-
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- if (aTopic === "places-favicons-expired") {
- resolve();
- Services.obs.removeObserver(observer, "places-favicons-expired", false);
- }
- }
- };
-
- Services.obs.addObserver(observer, "places-favicons-expired", false);
- faviconService.expireAllFavicons();
- });
-}
-
-function FaviconObserver(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL) {
- this.reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL);
-}
-
-FaviconObserver.prototype = {
- observe(aSubject, aTopic, aData) {
- // Make sure that the topic is 'http-on-modify-request'.
- if (aTopic === "http-on-modify-request") {
- // We check the userContextId for the originAttributes of the loading
- // channel. All requests for the favicon should contain the correct
- // userContextId. There are two requests for a favicon loading, one
- // from the Places library and one from the XUL image. The difference
- // of them is the loading principal. The Places will use the content
- // principal and the XUL image will use the system principal.
-
- let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
- let reqLoadInfo = httpChannel.loadInfo;
- let loadingPrincipal;
- let triggeringPrincipal;
-
- // Make sure this is a favicon request.
- if (httpChannel.URI.spec !== this._faviconURL) {
- return;
- }
-
- if (reqLoadInfo) {
- loadingPrincipal = reqLoadInfo.loadingPrincipal;
- triggeringPrincipal = reqLoadInfo.triggeringPrincipal;
- }
-
- // Check the userContextId.
- is(reqLoadInfo.originAttributes.userContextId, this._curUserContextId,
- "The loadInfo has correct userContextId");
-
- if (loadingPrincipal.equals(systemPrincipal)) {
- this._faviconReqXUL = true;
- ok(triggeringPrincipal.equals(this._expectedPrincipal),
- "The triggeringPrincipal of favicon loading from XUL should be the content principal.");
- } else {
- this._faviconReqPlaces = true;
- ok(loadingPrincipal.equals(this._expectedPrincipal),
- "The loadingPrincipal of favicon loading from Places should be the content prinicpal");
- }
-
- let faviconCookie = httpChannel.getRequestHeader("cookie");
-
- is(faviconCookie, this._expectedCookie, "The cookie of the favicon loading is correct.");
- } else {
- ok(false, "Received unexpected topic: ", aTopic);
- }
-
- if (this._faviconReqXUL && this._faviconReqPlaces) {
- this._faviconLoaded.resolve();
- }
- },
-
- reset(aUserContextId, aExpectedCookie, aPageURI, aFaviconURL) {
- this._curUserContextId = aUserContextId;
- this._expectedCookie = aExpectedCookie;
- this._expectedPrincipal = Services.scriptSecurityManager
- .createCodebasePrincipal(aPageURI, { userContextId: aUserContextId });
- this._faviconReqXUL = false;
- this._faviconReqPlaces = false;
- this._faviconURL = aFaviconURL;
- this._faviconLoaded = new Promise.defer();
- },
-
- get promise() {
- return this._faviconLoaded.promise;
- }
-};
-
-function waitOnFaviconLoaded(aFaviconURL) {
- return new Promise(resolve => {
- let observer = {
- onPageChanged(uri, attr, value, id) {
-
- if (attr === Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON &&
- value === aFaviconURL) {
- resolve();
- PlacesUtils.history.removeObserver(observer, false);
- }
- },
- };
-
- PlacesUtils.history.addObserver(observer, false);
- });
-}
-
-function* generateCookies(aHost) {
- // we generate two different cookies for two userContextIds.
- let cookies = [];
- cookies.push(Math.random().toString());
- cookies.push(Math.random().toString());
-
- // Then, we add cookies into the site for 'personal' and 'work'.
- let tabInfoA = yield openTabInUserContext(aHost, USER_CONTEXT_ID_PERSONAL);
- let tabInfoB = yield openTabInUserContext(aHost, USER_CONTEXT_ID_WORK);
-
- yield ContentTask.spawn(tabInfoA.browser, cookies[0], function* (value) {
- content.document.cookie = value;
- });
-
- yield ContentTask.spawn(tabInfoB.browser, cookies[1], function* (value) {
- content.document.cookie = value;
- });
-
- yield BrowserTestUtils.removeTab(tabInfoA.tab);
- yield BrowserTestUtils.removeTab(tabInfoB.tab);
-
- return cookies;
-}
-
-function* doTest(aTestPage, aFaviconHost, aFaviconURL) {
- let cookies = yield generateCookies(aFaviconHost);
- let pageURI = makeURI(aTestPage);
-
- // Create the observer object for observing request channels of the personal
- // container.
- let observer = new FaviconObserver(USER_CONTEXT_ID_PERSONAL, cookies[0], pageURI, aFaviconURL);
-
- // Add the observer earlier in case we miss it.
- let promiseWaitOnFaviconLoaded = waitOnFaviconLoaded(aFaviconURL);
-
- Services.obs.addObserver(observer, "http-on-modify-request", false);
-
- // Open the tab with the personal container.
- let tabInfo = yield openTabInUserContext(aTestPage, USER_CONTEXT_ID_PERSONAL);
-
- // Waiting for favicon requests are all made.
- yield observer.promise;
- // Waiting for favicon loaded.
- yield promiseWaitOnFaviconLoaded;
-
- // Close the tab.
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-
- // Reset the observer for observing requests for the work container.
- observer.reset(USER_CONTEXT_ID_WORK, cookies[1], pageURI, aFaviconURL);
- tabInfo = yield openTabInUserContext(aTestPage, USER_CONTEXT_ID_WORK);
-
- // Waiting for favicon requests are all made.
- yield observer.promise;
-
- Services.obs.removeObserver(observer, "http-on-modify-request", false);
-
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-}
-
-add_task(function* setup() {
- // Make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({"set": [
- ["privacy.userContext.enabled", true]
- ]});
-});
-
-// A clean up function to prevent affecting other tests.
-registerCleanupFunction(() => {
- // Clear all cookies.
- let cookieMgr = Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- cookieMgr.removeAll();
-
- // Clear all image caches and network caches.
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- // Clear Places favicon caches.
- clearAllPlacesFavicons();
-});
-
-add_task(function* test_favicon_userContextId() {
- // Clear all image caches before running the test.
- clearAllImageCaches();
-
- // Clear all network caches.
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- // Clear Places favicon caches.
- yield clearAllPlacesFavicons();
-
- yield doTest(TEST_PAGE, TEST_SITE, FAVICON_URI);
-});
-
-add_task(function* test_thirdPartyFavicon_userContextId() {
- // Clear all image caches before running the test.
- clearAllImageCaches();
-
- // Clear all network caches.
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- // Clear Places favicon caches.
- yield clearAllPlacesFavicons();
-
- yield doTest(TEST_THIRD_PARTY_PAGE, TEST_THIRD_PARTY_SITE, THIRD_PARTY_FAVICON_URI);
-});
diff --git a/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js b/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js
deleted file mode 100644
index ddda6afae..000000000
--- a/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js
+++ /dev/null
@@ -1,174 +0,0 @@
-const BASE_URL = "http://mochi.test:8888/browser/browser/components/originattributes/test/browser/";
-const BASE_DOMAIN = "mochi.test";
-
-add_task(function* setup() {
- Services.prefs.setBoolPref("privacy.firstparty.isolate", true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("privacy.firstparty.isolate");
- });
-});
-
-/**
- * Test for the top-level document and child iframes should have the
- * firstPartyDomain attribute.
- */
-add_task(function* principal_test() {
- let tab = gBrowser.addTab(BASE_URL + "test_firstParty.html");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, function (url) {
- return url == BASE_URL + "test_firstParty.html";
- });
-
- yield ContentTask.spawn(tab.linkedBrowser, { firstPartyDomain: BASE_DOMAIN }, function* (attrs) {
- info("document principal: " + content.document.nodePrincipal.origin);
- Assert.equal(docShell.getOriginAttributes().firstPartyDomain, "",
- "top-level docShell shouldn't have firstPartyDomain attribute.");
- Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "The document should have firstPartyDomain");
-
- for (let i = 1; i < 4; i++) {
- let iframe = content.document.getElementById("iframe" + i);
- info("iframe principal: " + iframe.contentDocument.nodePrincipal.origin);
- Assert.equal(iframe.frameLoader.docShell.getOriginAttributes().firstPartyDomain,
- attrs.firstPartyDomain, "iframe's docshell should have firstPartyDomain");
- Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "iframe should have firstPartyDomain");
- }
- });
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * Test for the cookie jars of the top-level document and child iframe should be
- * isolated by firstPartyDomain.
- */
-add_task(function* cookie_test() {
- let tab = gBrowser.addTab(BASE_URL + "test_firstParty_cookie.html");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser, true);
-
- let iter = Services.cookies.enumerator;
- let count = 0;
- while (iter.hasMoreElements()) {
- count++;
- let cookie = iter.getNext().QueryInterface(Ci.nsICookie2);
- Assert.equal(cookie.value, "foo", "Cookie value should be foo");
- Assert.equal(cookie.originAttributes.firstPartyDomain, BASE_DOMAIN, "Cookie's origin attributes should be " + BASE_DOMAIN);
- }
-
- // one cookie is from requesting test.js from top-level doc, and the other from
- // requesting test2.js from iframe test2.html.
- Assert.equal(count, 2, "Should have two cookies");
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * Test for after redirect, the top-level document should update the firstPartyDomain
- * attribute. However if the redirect is happening on the iframe, the attribute
- * should remain the same.
- */
-add_task(function* redirect_test() {
- let tab = gBrowser.addTab(BASE_URL + "test_firstParty_http_redirect.html");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield ContentTask.spawn(tab.linkedBrowser, { firstPartyDomain: "example.com" }, function* (attrs) {
- info("document principal: " + content.document.nodePrincipal.origin);
- info("document uri: " + content.document.documentURI);
-
- Assert.equal(content.document.documentURI, "http://example.com/browser/browser/components/originattributes/test/browser/dummy.html",
- "The page should have been redirected to http://example.com/browser/browser/components/originattributes/test/browser/dummy.html");
- Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "The document should have firstPartyDomain");
- });
-
- // Since this is a HTML redirect, we wait until the final page is loaded.
- let tab2 = gBrowser.addTab(BASE_URL + "test_firstParty_html_redirect.html");
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser, false, function(url) {
- return url == "http://example.com/";
- });
-
- yield ContentTask.spawn(tab2.linkedBrowser, { firstPartyDomain: "example.com" }, function* (attrs) {
- info("2nd tab document principal: " + content.document.nodePrincipal.origin);
- info("2nd tab document uri: " + content.document.documentURI);
- Assert.equal(content.document.documentURI, "http://example.com/",
- "The page should have been redirected to http://example.com");
- Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "The document should have firstPartyDomain");
- });
-
- let tab3 = gBrowser.addTab(BASE_URL + "test_firstParty_iframe_http_redirect.html");
- yield BrowserTestUtils.browserLoaded(tab3.linkedBrowser, true, function(url) {
- return url == (BASE_URL + "test_firstParty_iframe_http_redirect.html");
- });
-
- // This redirect happens on the iframe, so unlike the two redirect tests above,
- // the firstPartyDomain should still stick to the current top-level document,
- // which is mochi.test.
- yield ContentTask.spawn(tab3.linkedBrowser, { firstPartyDomain: "mochi.test" }, function* (attrs) {
- let iframe = content.document.getElementById("iframe1");
- info("iframe document principal: " + iframe.contentDocument.nodePrincipal.origin);
- info("iframe document uri: " + iframe.contentDocument.documentURI);
-
- Assert.equal(iframe.contentDocument.documentURI, "http://example.com/browser/browser/components/originattributes/test/browser/dummy.html",
- "The page should have been redirected to http://example.com/browser/browser/components/originattributes/test/browser/dummy.html");
- Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "The iframe should have firstPartyDomain: " + attrs.firstPartyDomain);
- });
-
- gBrowser.removeTab(tab);
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab3);
-});
-
-/**
- * Test for postMessage between document and iframe.
- */
-add_task(function* postMessage_test() {
- let tab = gBrowser.addTab(BASE_URL + "test_firstParty_postMessage.html");
-
- // The top-level page will post a message to its child iframe, and wait for
- // another message from the iframe, once it receives the message, it will
- // create another iframe, dummy.html.
- // So we wait until dummy.html is loaded
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, function (url) {
- return url == BASE_URL + "dummy.html";
- });
-
- yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
- info("document principal: " + content.document.nodePrincipal.origin);
- let value = content.document.getElementById("message").textContent;
- Assert.equal(value, "OK");
- });
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * When the web page calls window.open, the new window should have the same
- * firstPartyDomain attribute.
- */
-add_task(function* openWindow_test() {
- Services.prefs.setIntPref("browser.link.open_newwindow", 2);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.link.open_newwindow");
- });
-
- let tab = gBrowser.addTab(BASE_URL + "window.html");
- let win = yield BrowserTestUtils.waitForNewWindow();
-
- yield ContentTask.spawn(win.gBrowser.selectedBrowser, { firstPartyDomain: "mochi.test" }, function* (attrs) {
- Assert.equal(docShell.getOriginAttributes().firstPartyDomain, attrs.firstPartyDomain,
- "window.open() should have firstPartyDomain attribute");
- Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "The document should have firstPartyDomain");
-
- let iframe = content.document.getElementById("iframe1");
- Assert.equal(iframe.frameLoader.docShell.getOriginAttributes().firstPartyDomain,
- attrs.firstPartyDomain, "iframe's docshell should have firstPartyDomain");
- Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
- attrs.firstPartyDomain, "iframe should have firstPartyDomain");
- });
-
- gBrowser.removeTab(tab);
- yield BrowserTestUtils.closeWindow(win);
-});
-
diff --git a/browser/components/originattributes/test/browser/browser_httpauth.js b/browser/components/originattributes/test/browser/browser_httpauth.js
deleted file mode 100644
index 0b7b1540e..000000000
--- a/browser/components/originattributes/test/browser/browser_httpauth.js
+++ /dev/null
@@ -1,54 +0,0 @@
-let Cu = Components.utils;
-let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
-
-let server = new HttpServer();
-server.registerPathHandler('/file.html', fileHandler);
-server.start(-1);
-
-let BASE_URI = 'http://localhost:' + server.identity.primaryPort;
-let FILE_URI = BASE_URI + '/file.html';
-
-let credentialQueue = [];
-
-// Ask the user agent for authorization.
-function fileHandler(metadata, response) {
- if (!metadata.hasHeader("Authorization")) {
- response.setStatusLine(metadata.httpVersion, 401, "Unauthorized");
- response.setHeader("WWW-Authenticate", "Basic realm=\"User Visible Realm\"");
- return;
- }
-
- // This will be "account:password" encoded in base64.
- credentialQueue.push(metadata.getHeader("Authorization"));
-
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/html", false);
- let body = "<html><body></body></html>";
- response.bodyOutputStream.write(body, body.length);
-}
-
-function onCommonDialogLoaded(subject) {
- // Submit random account and password
- let dialog = subject.Dialog;
- dialog.ui.loginTextbox.setAttribute("value", Math.random());
- dialog.ui.password1Textbox.setAttribute("value", Math.random());
- dialog.ui.button0.click();
-}
-
-Services.obs.addObserver(onCommonDialogLoaded, "common-dialog-loaded", false);
-
-registerCleanupFunction(() => {
- Services.obs.removeObserver(onCommonDialogLoaded, "common-dialog-loaded");
- server.stop(() => {
- server = null;
- });
-});
-
-function getResult() {
- // If two targets are isolated, they should get different credentials.
- // Otherwise, the credentials will be cached and therefore the same.
- return credentialQueue.shift();
-}
-
-IsolationTestTools.runTests(FILE_URI, getResult);
-
diff --git a/browser/components/originattributes/test/browser/browser_imageCacheIsolation.js b/browser/components/originattributes/test/browser/browser_imageCacheIsolation.js
deleted file mode 100644
index a24cec9ac..000000000
--- a/browser/components/originattributes/test/browser/browser_imageCacheIsolation.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Bug 1264572 - A test case for image cache isolation.
- */
-
-requestLongerTimeout(2);
-
-let Cu = Components.utils;
-let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
-
-const NUM_ISOLATION_LOADS = 2;
-const NUM_CACHED_LOADS = 1;
-
-let gHits = 0;
-
-let server = new HttpServer();
-server.registerPathHandler('/image.png', imageHandler);
-server.registerPathHandler('/file.html', fileHandler);
-server.start(-1);
-
-registerCleanupFunction(() => {
- server.stop(() => {
- server = null;
- });
-});
-
-let BASE_URI = 'http://localhost:' + server.identity.primaryPort;
-let IMAGE_URI = BASE_URI + '/image.png';
-let FILE_URI = BASE_URI + '/file.html';
-
-function imageHandler(metadata, response) {
- info('XXX: loading image from server');
- gHits++;
- response.setHeader("Cache-Control", "max-age=10000", false);
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "image/png", false);
- var body = "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
- response.bodyOutputStream.write(body, body.length);
-}
-
-function fileHandler(metadata, response) {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/html", false);
- let body = `<html><body><image src=${IMAGE_URI}></body></html>`;
- response.bodyOutputStream.write(body, body.length);
-}
-
-function doBefore() {
- // reset hit counter
- info('XXX resetting gHits');
- gHits = 0;
- info('XXX clearing image cache');
- let imageCache = Cc["@mozilla.org/image/tools;1"]
- .getService(Ci.imgITools)
- .getImgCacheForDocument(null);
- imageCache.clearCache(true);
- imageCache.clearCache(false);
- info('XXX clearning network cache');
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-}
-
-// the test function does nothing on purpose.
-function doTest(aBrowser) {
- return 0;
-}
-
-// the check function
-function doCheck(shouldIsolate, a, b) {
- // if we're doing first party isolation and the image cache isolation is
- // working, then gHits should be 2 because the image would have been loaded
- // one per first party domain. if first party isolation is disabled, then
- // gHits should be 1 since there would be one image load from the server and
- // one load from the image cache.
- info(`XXX check: gHits == ${gHits}, shouldIsolate == ${shouldIsolate}`);
- return shouldIsolate ? gHits == NUM_ISOLATION_LOADS
- : gHits == NUM_CACHED_LOADS;
-}
-
-IsolationTestTools.runTests(FILE_URI, doTest, doCheck, doBefore);
diff --git a/browser/components/originattributes/test/browser/browser_localStorageIsolation.js b/browser/components/originattributes/test/browser/browser_localStorageIsolation.js
deleted file mode 100644
index 41bde80e4..000000000
--- a/browser/components/originattributes/test/browser/browser_localStorageIsolation.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Bug 1264567 - A test case for localStorage isolation.
- */
-
-const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/" +
- "originattributes/test/browser/file_firstPartyBasic.html";
-
-// Use a random key so we don't access it in later tests.
-const key = Math.random().toString();
-
-// Define the testing function
-function* doTest(aBrowser) {
- return yield ContentTask.spawn(aBrowser, key, function (key) {
- let value = content.localStorage.getItem(key);
- if (value === null) {
- // No value is found, so we create one.
- value = Math.random().toString();
- content.localStorage.setItem(key, value);
- }
- return value;
- });
-}
-
-IsolationTestTools.runTests(TEST_PAGE, doTest);
diff --git a/browser/components/originattributes/test/browser/browser_sharedworker.js b/browser/components/originattributes/test/browser/browser_sharedworker.js
deleted file mode 100644
index 7049407f6..000000000
--- a/browser/components/originattributes/test/browser/browser_sharedworker.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Bug 1264593 - A test case for the shared worker by first party isolation.
- */
-
-const TEST_DOMAIN = "http://example.net/";
-const TEST_PATH = TEST_DOMAIN + "browser/browser/components/originattributes/test/browser/";
-const TEST_PAGE = TEST_PATH + "file_sharedworker.html";
-
-function* getResultFromSharedworker(aBrowser) {
- let response = yield ContentTask.spawn(aBrowser, null, function* () {
- let worker = new content.SharedWorker("file_sharedworker.js", "isolationSharedWorkerTest");
-
- let result = yield new Promise(resolve => {
- worker.port.onmessage = function (e) {
- content.document.getElementById("display").innerHTML = e.data;
- resolve(e.data);
- };
- });
-
- return result;
- });
-
- return response;
-}
-
-IsolationTestTools.runTests(TEST_PAGE, getResultFromSharedworker);
diff --git a/browser/components/originattributes/test/browser/dummy.html b/browser/components/originattributes/test/browser/dummy.html
deleted file mode 100644
index 1a87e2840..000000000
--- a/browser/components/originattributes/test/browser/dummy.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>Dummy test page</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<p>Dummy test page</p>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_broadcastChannel.html b/browser/components/originattributes/test/browser/file_broadcastChannel.html
deleted file mode 100644
index 14bd7a022..000000000
--- a/browser/components/originattributes/test/browser/file_broadcastChannel.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title>Page broadcast channel creator for first party isolation</title>
-</head>
-<body>
- <div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>
- <iframe id="iframe" src="file_broadcastChanneliFrame.html"></iframe>>
-<script type="text/javascript;version=1.7">
-let bc = new BroadcastChannel("testBroadcastChannel");
-bc.onmessage = function (e) {
- document.getElementById("display").innerHTML = e.data;
-};
-</script>
-</body>
diff --git a/browser/components/originattributes/test/browser/file_broadcastChanneliFrame.html b/browser/components/originattributes/test/browser/file_broadcastChanneliFrame.html
deleted file mode 100644
index a2140e617..000000000
--- a/browser/components/originattributes/test/browser/file_broadcastChanneliFrame.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title>Page broadcast channel responder for first party isolation</title>
-</head>
-<body>
- <div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>
-<script type="text/javascript;version=1.7">
-let bc = new BroadcastChannel("testBroadcastChannel");
-bc.onmessage = function (e) {
- window.parent.postMessage(e.data, "*");
-};
-</script>
-</body>
diff --git a/browser/components/originattributes/test/browser/file_cache.html b/browser/components/originattributes/test/browser/file_cache.html
deleted file mode 100644
index 788ec899d..000000000
--- a/browser/components/originattributes/test/browser/file_cache.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<head>
- <link rel="stylesheet" type="text/css"
- href="http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.link.css">
- <link rel="preconnect" href="http://example.net">
-</head>
-<body>
-<div>file_cache.html</div>
-
-<iframe src="http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.iframe.html">
-</iframe>
-
-<script src="http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.script.js">
-</script>
-
-<img src="http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.img.png">
-
-<embed src="http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.embed.png">
-
-<object data="http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.object.png"
- type="image/png"></object>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_favicon.html b/browser/components/originattributes/test/browser/file_favicon.html
deleted file mode 100644
index b571134e1..000000000
--- a/browser/components/originattributes/test/browser/file_favicon.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <meta charset='utf-8'>
- <title>Favicon Test for originAttributes</title>
- <link rel="icon" type="image/png" href="file_favicon.png" />
- </head>
- <body>
- Favicon!!
- </body>
-</html> \ No newline at end of file
diff --git a/browser/components/originattributes/test/browser/file_favicon.png b/browser/components/originattributes/test/browser/file_favicon.png
deleted file mode 100644
index 5535363c9..000000000
--- a/browser/components/originattributes/test/browser/file_favicon.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_favicon.png^headers^ b/browser/components/originattributes/test/browser/file_favicon.png^headers^
deleted file mode 100644
index 9e23c73b7..000000000
--- a/browser/components/originattributes/test/browser/file_favicon.png^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Cache-Control: no-cache
diff --git a/browser/components/originattributes/test/browser/file_favicon_cache.html b/browser/components/originattributes/test/browser/file_favicon_cache.html
deleted file mode 100644
index 2a7343b8e..000000000
--- a/browser/components/originattributes/test/browser/file_favicon_cache.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <meta charset='utf-8'>
- <title>Favicon Test for originAttributes</title>
- <link rel="icon" type="image/png" href="http://mochi.test:8888/browser/browser/components/originattributes/test/browser/file_favicon_cache.png" />
- </head>
- <body>
- Third Party Favicon!!
- </body>
-</html> \ No newline at end of file
diff --git a/browser/components/originattributes/test/browser/file_favicon_cache.png b/browser/components/originattributes/test/browser/file_favicon_cache.png
deleted file mode 100644
index 5535363c9..000000000
--- a/browser/components/originattributes/test/browser/file_favicon_cache.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_favicon_thirdParty.html b/browser/components/originattributes/test/browser/file_favicon_thirdParty.html
deleted file mode 100644
index 4a2dd680a..000000000
--- a/browser/components/originattributes/test/browser/file_favicon_thirdParty.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <meta charset='utf-8'>
- <title>Favicon Test for originAttributes</title>
- <link rel="icon" type="image/png" href="http://mochi.test:8888/browser/browser/components/originattributes/test/browser/file_favicon.png" />
- </head>
- <body>
- Third Party Favicon!!
- </body>
-</html> \ No newline at end of file
diff --git a/browser/components/originattributes/test/browser/file_firstPartyBasic.html b/browser/components/originattributes/test/browser/file_firstPartyBasic.html
deleted file mode 100644
index 713187fb2..000000000
--- a/browser/components/originattributes/test/browser/file_firstPartyBasic.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
- <head>
- <meta charset="UTF-8">
- <title>First Party Isolation Tests</title>
- </head>
- <body>
- </body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_sharedworker.html b/browser/components/originattributes/test/browser/file_sharedworker.html
deleted file mode 100644
index b9ff793bd..000000000
--- a/browser/components/originattributes/test/browser/file_sharedworker.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title>Page SharedWorker creator for first party isolation</title>
-</head>
-<body>
-<div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_sharedworker.js b/browser/components/originattributes/test/browser/file_sharedworker.js
deleted file mode 100644
index 82f075a37..000000000
--- a/browser/components/originattributes/test/browser/file_sharedworker.js
+++ /dev/null
@@ -1,9 +0,0 @@
-self.randomValue = Math.random();
-
-/* global onconnect:true */
-
-onconnect = function (e) {
- let port = e.ports[0];
- port.postMessage(self.randomValue);
- port.start();
-};
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.audio.ogg b/browser/components/originattributes/test/browser/file_thirdPartyChild.audio.ogg
deleted file mode 100644
index edda4e912..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.audio.ogg
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.embed.png b/browser/components/originattributes/test/browser/file_thirdPartyChild.embed.png
deleted file mode 100644
index c5916f289..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.embed.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.fetch.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.fetch.html
deleted file mode 100644
index 037901ad0..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.fetch.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.fetch.html</div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.iframe.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.iframe.html
deleted file mode 100644
index b047d5b41..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.iframe.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.html</div>
-<script>
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.xhr.html", true);
- xhr.send();
- var worker = new Worker("http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.js");
- var sharedWorker = new SharedWorker("http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.sharedworker.js");
-
- fetch("file_thirdPartyChild.fetch.html", {cache: "force-cache"} );
- fetch(new Request("file_thirdPartyChild.request.html"), {cache: "force-cache"} );
-</script>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.img.png b/browser/components/originattributes/test/browser/file_thirdPartyChild.img.png
deleted file mode 100644
index c5916f289..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.img.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.import.js b/browser/components/originattributes/test/browser/file_thirdPartyChild.import.js
deleted file mode 100644
index dbf8f8376..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.import.js
+++ /dev/null
@@ -1 +0,0 @@
-// dummy script, to be called by self.importScripts(...)
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.link.css b/browser/components/originattributes/test/browser/file_thirdPartyChild.link.css
deleted file mode 100644
index 06d6e2672..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.link.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Dummy CSS file, used by browser_cache.js. */ \ No newline at end of file
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.object.png b/browser/components/originattributes/test/browser/file_thirdPartyChild.object.png
deleted file mode 100644
index c5916f289..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.object.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.request.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.request.html
deleted file mode 100644
index 108ed2ffa..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.request.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.request.html</div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.script.js b/browser/components/originattributes/test/browser/file_thirdPartyChild.script.js
deleted file mode 100644
index 6ddf436c0..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.script.js
+++ /dev/null
@@ -1 +0,0 @@
-// Dummy child script, used by browser_cache.js
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.sharedworker.js b/browser/components/originattributes/test/browser/file_thirdPartyChild.sharedworker.js
deleted file mode 100644
index b262fa10a..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.sharedworker.js
+++ /dev/null
@@ -1 +0,0 @@
-// dummy file
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.track.vtt b/browser/components/originattributes/test/browser/file_thirdPartyChild.track.vtt
deleted file mode 100644
index b37cb40e4..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.track.vtt
+++ /dev/null
@@ -1,13 +0,0 @@
-WEBVTT FILE
-
-1
-00:00:00.500 --> 00:00:02.000 D:vertical A:start
-blah blah blah
-
-2
-00:00:02.500 --> 00:00:04.300
-this is a test
-
-3
-00:00:05.000 --> 00:00:07.000
-one more line
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.video.ogv b/browser/components/originattributes/test/browser/file_thirdPartyChild.video.ogv
deleted file mode 100644
index 68dee3cf2..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.video.ogv
+++ /dev/null
Binary files differ
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.fetch.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.fetch.html
deleted file mode 100644
index 47e42d1e5..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.fetch.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.worker.fetch.html</div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.js b/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.js
deleted file mode 100644
index b04e2c7de..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var xhr = new XMLHttpRequest();
-xhr.open("GET", "http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.xhr.html", true);
-xhr.send();
-
-fetch("http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.fetch.html", {cache: "force-cache"} );
-var myRequest = new Request("http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.request.html");
-fetch(myRequest, {cache: "force-cache"} );
-
-self.importScripts("http://example.net/browser/browser/components/originattributes/test/browser/file_thirdPartyChild.import.js");
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.request.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.request.html
deleted file mode 100644
index 5b5c55bfe..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.request.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.worker.request.html</div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.xhr.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.xhr.html
deleted file mode 100644
index 9fc107f37..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.worker.xhr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.worker.xhr.html</div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/file_thirdPartyChild.xhr.html b/browser/components/originattributes/test/browser/file_thirdPartyChild.xhr.html
deleted file mode 100644
index f56e7b3c1..000000000
--- a/browser/components/originattributes/test/browser/file_thirdPartyChild.xhr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-<!-- The child page, used by browser_cache.js -->
-<body>
-<div>thirdPartyChild.html</div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/head.js b/browser/components/originattributes/test/browser/head.js
deleted file mode 100644
index 96559a10d..000000000
--- a/browser/components/originattributes/test/browser/head.js
+++ /dev/null
@@ -1,365 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-const TEST_URL_PATH = "/browser/browser/components/originattributes/test/browser/";
-
-// The flags of test modes.
-const TEST_MODE_FIRSTPARTY = 0;
-const TEST_MODE_NO_ISOLATION = 1;
-const TEST_MODE_CONTAINERS = 2;
-
-// The name of each mode.
-const TEST_MODE_NAMES = [ "first party isolation",
- "no isolation",
- "containers" ];
-
-// The frame types.
-const TEST_TYPE_FRAME = 0;
-const TEST_TYPE_IFRAME = 1;
-
-// The default frame setting.
-const DEFAULT_FRAME_SETTING = [ TEST_TYPE_IFRAME ];
-
-let gFirstPartyBasicPage = TEST_URL_PATH + "file_firstPartyBasic.html";
-
-/**
- * Add a tab for the given url with the specific user context id.
- *
- * @param aURL
- * The url of the page.
- * @param aUserContextId
- * The user context id for this tab.
- *
- * @return tab - The tab object of this tab.
- * browser - The browser object of this tab.
- */
-function* openTabInUserContext(aURL, aUserContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab(aURL, {userContextId: aUserContextId});
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-/**
- * Add a tab for a page with the given first party domain. This page will have
- * an iframe which is loaded with the given url by default or you could specify
- * a frame setting to create nested frames. And this function will also modify
- * the 'content' in the ContentTask to the target frame's window object.
- *
- * @param aURL
- * The url of the iframe.
- * @param aFirstPartyDomain
- * The first party domain.
- * @param aFrameSetting
- * This setting controls how frames are organized within the page. The
- * setting is an array of frame types, the first item indicates the
- * frame type (iframe or frame) of the first layer of the frame structure,
- * and the second item indicates the second layer, and so on. The aURL will
- * be loaded at the deepest layer. This is optional.
- *
- * @return tab - The tab object of this tab.
- * browser - The browser object of this tab.
- */
-function* openTabInFirstParty(aURL, aFirstPartyDomain,
- aFrameSetting = DEFAULT_FRAME_SETTING) {
-
- // If the first party domain ends with '/', we remove it.
- if (aFirstPartyDomain.endsWith('/')) {
- aFirstPartyDomain = aFirstPartyDomain.slice(0, -1);
- }
-
- let basicPageURL = aFirstPartyDomain + gFirstPartyBasicPage;
-
- // Open the tab for the basic first party page.
- let tab = gBrowser.addTab(basicPageURL);
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
-
- let pageArgs = { url: aURL,
- frames: aFrameSetting,
- typeFrame: TEST_TYPE_FRAME,
- typeIFrame: TEST_TYPE_IFRAME,
- basicFrameSrc: basicPageURL};
-
- // Create the frame structure.
- yield ContentTask.spawn(browser, pageArgs, function* (arg) {
- let typeFrame = arg.typeFrame;
- let typeIFrame = arg.typeIFrame;
-
- // Redefine the 'content' for allowing us to change its target, and making
- // ContentTask.spawn can directly work on the frame element.
- this.frameWindow = content;
-
- Object.defineProperty(this, "content", {
- get: () => this.frameWindow
- });
-
- let frameElement;
- let numOfLayers = 0;
-
- for (let type of arg.frames) {
- let document = content.document;
- numOfLayers++;
-
- if (type === typeFrame) {
- // Add a frameset which carries the frame element.
- let frameSet = document.createElement('frameset');
- frameSet.cols = "50%,50%";
-
- let frame = document.createElement('frame');
- let dummyFrame = document.createElement('frame');
-
- frameSet.appendChild(frame);
- frameSet.appendChild(dummyFrame);
-
- document.body.appendChild(frameSet);
-
- frameElement = frame;
- } else if (type === typeIFrame) {
- // Add an iframe.
- let iframe = document.createElement('iframe');
- document.body.appendChild(iframe);
-
- 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);
- done();
- }, 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);
- }
- });
-
- // Redirect the 'content' to the frame's window.
- this.frameWindow = frameElement.contentWindow;
- }
- });
-
- return {tab, browser};
-}
-
-this.IsolationTestTools = {
- /**
- * Adds isolation tests for first party isolation, no isolation
- * and containers respectively.
- *
- * @param aTask
- * The testing task which will be run in different settings.
- */
- _add_task(aTask) {
- add_task(function* addTaskForIsolationTests() {
- let testSettings = [
- { mode: TEST_MODE_FIRSTPARTY,
- skip: false,
- prefs: [["privacy.firstparty.isolate", true]]
- },
- { mode: TEST_MODE_NO_ISOLATION,
- skip: false,
- prefs: [["privacy.firstparty.isolate", false]]
- },
- { mode: TEST_MODE_CONTAINERS,
- skip: false,
- prefs: [["privacy.userContext.enabled", true]]
- },
- ];
-
- // Add test tasks.
- for (let testSetting of testSettings) {
- IsolationTestTools._addTaskForMode(testSetting.mode,
- testSetting.prefs,
- testSetting.skip,
- aTask);
- }
- });
- },
-
- _addTaskForMode(aMode, aPref, aSkip, aTask) {
- if (aSkip) {
- return;
- }
-
- add_task(function* () {
- info("Starting the test for " + TEST_MODE_NAMES[aMode]);
-
- // Before run this task, reset the preferences first.
- yield SpecialPowers.flushPrefEnv();
-
- // Make sure preferences are set properly.
- yield SpecialPowers.pushPrefEnv({"set": aPref});
-
- yield SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]});
-
- yield aTask(aMode);
- });
- },
-
- /**
- * Add a tab with the given tab setting, this will open different types of
- * tabs according to the given test mode. A tab setting means a isolation
- * target in different test mode; a tab setting indicates a first party
- * domain when testing the first party isolation, it is a user context
- * id when testing containers.
- *
- * @param aMode
- * The test mode which decides what type of tabs will be opened.
- * @param aURL
- * The url which is going to open.
- * @param aTabSettingObj
- * The tab setting object includes 'firstPartyDomain' for the first party
- * domain and 'userContextId' for Containers.
- * @param aFrameSetting
- * This setting controls how frames are organized within the page. The
- * setting is an array of frame types, the first item indicates the
- * frame type (iframe or frame) of the first layer of the frame structure,
- * and the second item indicates the second layer, and so on. The aURL
- * will be loaded at the deepest layer. This is optional.
- *
- * @return tab - The tab object of this tab.
- * browser - The browser object of this tab.
- */
- _addTab(aMode, aURL, aTabSettingObj, aFrameSetting) {
- if (aMode === TEST_MODE_CONTAINERS) {
- return openTabInUserContext(aURL, aTabSettingObj.userContextId);
- }
-
- return openTabInFirstParty(aURL, aTabSettingObj.firstPartyDomain,
- aFrameSetting);
-
- },
-
- /**
- * Run isolation tests. The framework will run tests with standard combinations
- * of prefs and tab settings, and checks whether the isolation is working.
- *
- * @param aURL
- * The URL of the page that will be tested or an object contains 'url',
- * the tested page, 'firstFrameSetting' for the frame setting of the first
- * tab, and 'secondFrameSetting' for the second tab.
- * @param aGetResultFuncs
- * An array of functions or a single function which are responsible for
- * returning the isolation result back to the framework for further checking.
- * Each of these functions will be provided the browser object of the tab,
- * that allows modifying or fetchings results from the page content.
- * @param aCompareResultFunc
- * An optional function which allows modifying the way how does framework
- * check results. This function will be provided a boolean to indicate
- * the isolation is no or off and two results. This function should return
- * a boolean to tell that whether isolation is working. If this function
- * is not given, the framework will take case checking by itself.
- * @param aBeforeFunc
- * An optional function which is called before any tabs are created so
- * that the test case can set up/reset local state.
- * @param aGetResultImmediately
- * An optional boolean to ensure we get results before the next tab is opened.
- */
- runTests(aURL, aGetResultFuncs, aCompareResultFunc, aBeforeFunc,
- aGetResultImmediately) {
- let pageURL;
- let firstFrameSetting;
- let secondFrameSetting;
-
- // Request a longer timeout since the test will run a test for three times
- // with different settings. Thus, one test here represents three tests.
- // For this reason, we triple the timeout.
- requestLongerTimeout(3);
-
- if (typeof aURL === "string") {
- pageURL = aURL;
- } else if (typeof aURL === "object") {
- pageURL = aURL.url;
- firstFrameSetting = aURL.firstFrameSetting;
- secondFrameSetting = aURL.secondFrameSetting;
- }
-
- if (!Array.isArray(aGetResultFuncs)) {
- aGetResultFuncs = [aGetResultFuncs];
- }
-
- let tabSettings = [
- { firstPartyDomain: "http://example.com", userContextId: 1},
- { firstPartyDomain: "http://example.org", userContextId: 2}
- ];
-
- this._add_task(function* (aMode) {
- let tabSettingA = 0;
-
- for (let tabSettingB of [0, 1]) {
- // Give the test a chance to set up before each case is run.
- if (aBeforeFunc) {
- yield aBeforeFunc(aMode);
- }
-
- // Create Tabs.
- let tabInfoA = yield IsolationTestTools._addTab(aMode,
- pageURL,
- tabSettings[tabSettingA],
- firstFrameSetting);
- let resultsA = [];
- if (aGetResultImmediately) {
- for (let getResultFunc of aGetResultFuncs) {
- resultsA.push(yield getResultFunc(tabInfoA.browser));
- }
- }
- let tabInfoB = yield IsolationTestTools._addTab(aMode,
- pageURL,
- tabSettings[tabSettingB],
- secondFrameSetting);
- let i = 0;
- for (let getResultFunc of aGetResultFuncs) {
- // Fetch results from tabs.
- let resultA = aGetResultImmediately ? resultsA[i++] :
- yield getResultFunc(tabInfoA.browser);
- let resultB = yield getResultFunc(tabInfoB.browser);
-
- // Compare results.
- let result = false;
- let shouldIsolate = (aMode !== TEST_MODE_NO_ISOLATION) &&
- tabSettingA !== tabSettingB;
- if (aCompareResultFunc) {
- result = yield aCompareResultFunc(shouldIsolate, resultA, resultB);
- } else {
- result = shouldIsolate ? resultA !== resultB :
- resultA === resultB;
- }
-
- let msg = `Testing ${TEST_MODE_NAMES[aMode]} for ` +
- `isolation ${shouldIsolate ? "on" : "off"} with TabSettingA ` +
- `${tabSettingA} and tabSettingB ${tabSettingB}` +
- `, resultA = ${resultA}, resultB = ${resultB}`;
-
- ok(result, msg);
- }
-
- // Close Tabs.
- yield BrowserTestUtils.removeTab(tabInfoA.tab);
- yield BrowserTestUtils.removeTab(tabInfoB.tab);
- }
- });
- }
-};
diff --git a/browser/components/originattributes/test/browser/test.html b/browser/components/originattributes/test/browser/test.html
deleted file mode 100644
index 214daa4b7..000000000
--- a/browser/components/originattributes/test/browser/test.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 1260931</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script>
- window.onmessage = function (evt) {
- if (evt.data != "HI") {
- return;
- }
-
- window.parent.postMessage("OK", "http://mochi.test:8888");
- };
- </script>
-</head>
-<body>
- Hello World.
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test.js b/browser/components/originattributes/test/browser/test.js
deleted file mode 100644
index d290af9b0..000000000
--- a/browser/components/originattributes/test/browser/test.js
+++ /dev/null
@@ -1 +0,0 @@
-var i = 1;
diff --git a/browser/components/originattributes/test/browser/test.js^headers^ b/browser/components/originattributes/test/browser/test.js^headers^
deleted file mode 100644
index 881f5bff0..000000000
--- a/browser/components/originattributes/test/browser/test.js^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Set-Cookie: test=foo
diff --git a/browser/components/originattributes/test/browser/test2.html b/browser/components/originattributes/test/browser/test2.html
deleted file mode 100644
index 370be1560..000000000
--- a/browser/components/originattributes/test/browser/test2.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 1260931</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script src="test2.js"></script>
-</head>
-<body>
- Hello World.
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test2.js b/browser/components/originattributes/test/browser/test2.js
deleted file mode 100644
index d290af9b0..000000000
--- a/browser/components/originattributes/test/browser/test2.js
+++ /dev/null
@@ -1 +0,0 @@
-var i = 1;
diff --git a/browser/components/originattributes/test/browser/test2.js^headers^ b/browser/components/originattributes/test/browser/test2.js^headers^
deleted file mode 100644
index 43604be7f..000000000
--- a/browser/components/originattributes/test/browser/test2.js^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Set-Cookie: test2=foo
diff --git a/browser/components/originattributes/test/browser/test_firstParty.html b/browser/components/originattributes/test/browser/test_firstParty.html
deleted file mode 100644
index a90e01c4c..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8"/>
- <title>Test for Bug 1260931</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
- <div>
- <iframe id="iframe1" src="http://example.com"></iframe>
- <iframe id="iframe2" sandbox="" src="http://example.com"></iframe>
- <iframe id="iframe3" sandbox="allow-same-origin" src="http://example.com"></iframe>
- </div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test_firstParty_cookie.html b/browser/components/originattributes/test/browser/test_firstParty_cookie.html
deleted file mode 100644
index 44547c0d7..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty_cookie.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 1260931</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
- <script src="test.js"></script>
-</head>
-<body>
- Hello World.
- <iframe id="iframe1" src="test2.html"></iframe>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test_firstParty_html_redirect.html b/browser/components/originattributes/test/browser/test_firstParty_html_redirect.html
deleted file mode 100644
index 3c52d4f8c..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty_html_redirect.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf8" http-equiv="refresh" content="0; url=http://example.com/"/>
- <title>Test for Bug 1260931</title>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html b/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html
deleted file mode 100644
index 7b794a011..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8"/>
- <title>Test for Bug 1260931</title>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html^headers^ b/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html^headers^
deleted file mode 100644
index c6d2757aa..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty_http_redirect.html^headers^
+++ /dev/null
@@ -1,2 +0,0 @@
-HTTP 302 Found
-Location: http://example.com/browser/browser/components/originattributes/test/browser/dummy.html
diff --git a/browser/components/originattributes/test/browser/test_firstParty_iframe_http_redirect.html b/browser/components/originattributes/test/browser/test_firstParty_iframe_http_redirect.html
deleted file mode 100644
index fd7df46c1..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty_iframe_http_redirect.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8"/>
- <title>Test for Bug 1260931</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
- <div>
- <iframe id="iframe1" src="test_firstParty_http_redirect.html"></iframe>
- </div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/test_firstParty_postMessage.html b/browser/components/originattributes/test/browser/test_firstParty_postMessage.html
deleted file mode 100644
index 5df8a5950..000000000
--- a/browser/components/originattributes/test/browser/test_firstParty_postMessage.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8"/>
- <title>Test for Bug 1260931</title>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function onload() {
- let iframe1 = document.getElementById("iframe1");
- iframe1.contentWindow.postMessage("HI", "http://mochi.test:8888");
-}
-
-window.onmessage = function (evt) {
- document.getElementById("message").textContent = evt.data;
-
- let iframe2 = document.createElement("iframe");
- iframe2.src = "dummy.html";
- document.body.appendChild(iframe2);
-};
-</script>
-<body onload="onload()">
- <div>
- <iframe id="iframe1" src="test.html"></iframe>
- <span id="message"></span>
- </div>
-</body>
-</html>
diff --git a/browser/components/originattributes/test/browser/window.html b/browser/components/originattributes/test/browser/window.html
deleted file mode 100644
index 34216030c..000000000
--- a/browser/components/originattributes/test/browser/window.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <meta charset="utf8">
- <title>Page creating a popup</title>
- </head>
- <body>
- <script type="text/javascript">
- var w = window.open();
- w.document.body.innerHTML = "<iframe id='iframe1' src='data:text/plain,test2'></iframe>";
- </script>
- </body>
-</html>
diff --git a/browser/components/originattributes/test/browser/worker_blobify.js b/browser/components/originattributes/test/browser/worker_blobify.js
deleted file mode 100644
index 56c0996a3..000000000
--- a/browser/components/originattributes/test/browser/worker_blobify.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Wait for a string to be posted to this worker.
-// Create a blob containing this string, and then
-// post back a blob URL pointing to the blob.
-self.addEventListener("message", function (e) {
- try {
- var blobURL = URL.createObjectURL(new Blob([e.data]));
- postMessage({ blobURL });
- } catch (e) {
- postMessage({ error: e.message });
- }
-}, false);
diff --git a/browser/components/originattributes/test/browser/worker_deblobify.js b/browser/components/originattributes/test/browser/worker_deblobify.js
deleted file mode 100644
index 1d6511a20..000000000
--- a/browser/components/originattributes/test/browser/worker_deblobify.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Wait for a blob URL to be posted to this worker.
-// Obtain the blob, and read the string contained in it.
-// Post back the string.
-
-var postStringInBlob = function (blobObject) {
- var fileReader = new FileReaderSync();
- var result = fileReader.readAsText(blobObject);
- postMessage(result);
-};
-
-self.addEventListener("message", function (e) {
- if ("error" in e.data) {
- postMessage(e.data);
- return;
- }
- var blobURL = e.data.blobURL,
- xhr = new XMLHttpRequest();
- try {
- xhr.open("GET", blobURL, true);
- xhr.onload = function () {
- postStringInBlob(xhr.response);
- };
- xhr.onerror = function () {
- postMessage({ error: "xhr error" });
- };
- xhr.responseType = "blob";
- xhr.send();
- } catch (e) {
- postMessage({ error: e.message });
- }
-}, false);
diff --git a/browser/components/originattributes/test/mochitest/file_empty.html b/browser/components/originattributes/test/mochitest/file_empty.html
deleted file mode 100644
index bc98b4d2e..000000000
--- a/browser/components/originattributes/test/mochitest/file_empty.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<h1>I'm just a support file</h1>
-<p>I get loaded to do permission testing.</p> \ No newline at end of file
diff --git a/browser/components/originattributes/test/mochitest/mochitest.ini b/browser/components/originattributes/test/mochitest/mochitest.ini
deleted file mode 100644
index 5df9998ca..000000000
--- a/browser/components/originattributes/test/mochitest/mochitest.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-support-files =
- file_empty.html
-
-[test_permissions_api.html]
diff --git a/browser/components/originattributes/test/mochitest/test_permissions_api.html b/browser/components/originattributes/test/mochitest/test_permissions_api.html
deleted file mode 100644
index 63c74d1fe..000000000
--- a/browser/components/originattributes/test/mochitest/test_permissions_api.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-
-<head>
- <meta charset="utf-8">
- <title>Test for Permissions API</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" href="/tests/SimpleTest/test.css">
-</head>
-
-<body>
- <pre id="test"></pre>
- <script type="application/javascript;version=1.8">
- /*globals SpecialPowers, SimpleTest, is, ok, */
- 'use strict';
-
- const {
- UNKNOWN_ACTION,
- PROMPT_ACTION,
- ALLOW_ACTION,
- DENY_ACTION
- } = SpecialPowers.Ci.nsIPermissionManager;
-
- SimpleTest.waitForExplicitFinish();
-
- const PERMISSIONS = [{
- name: 'geolocation',
- type: 'geo'
- }, {
- name: 'notifications',
- type: 'desktop-notification'
- }, {
- name: 'push',
- type: 'desktop-notification'
- }, ];
-
- const UNSUPPORTED_PERMISSIONS = [
- 'foobarbaz', // Not in spec, for testing only.
- 'midi',
- ];
-
- // Create a closure, so that tests are run on the correct window object.
- function createPermissionTester(aWindow) {
- return {
- setPermissions(allow) {
- const permissions = PERMISSIONS.map(({ type }) => {
- return {
- type,
- allow,
- 'context': aWindow.document
- };
- });
- return new Promise((resolve) => {
- SpecialPowers.popPermissions(() => {
- SpecialPowers.pushPermissions(permissions, resolve);
- });
- });
- },
- revokePermissions() {
- const promisesToRevoke = PERMISSIONS.map(({ name }) => {
- return aWindow.navigator.permissions
- .revoke({ name })
- .then(
- ({ state }) => is(state, 'prompt', `correct state for '${name}'`),
- () => ok(false, `revoke should not have rejected for '${name}'`)
- );
- });
- return Promise.all(promisesToRevoke);
- },
- revokeUnsupportedPermissions() {
- const promisesToRevoke = UNSUPPORTED_PERMISSIONS.map(({ name }) => {
- return aWindow.navigator.permissions
- .revoke({ name })
- .then(
- () => ok(false, `revoke should not have resolved for '${name}'`),
- error => is(error.name, 'TypeError', `revoke should have thrown TypeError for '${name}'`)
- );
- });
- return Promise.all(promisesToRevoke);
- },
- checkPermissions(state) {
- const promisesToQuery = PERMISSIONS.map(({ name }) => {
- return aWindow.navigator.permissions
- .query({ name })
- .then(
- () => is(state, state, `correct state for '${name}'`),
- () => ok(false, `query should not have rejected for '${name}'`)
- );
- });
- return Promise.all(promisesToQuery);
- },
- checkUnsupportedPermissions() {
- const promisesToQuery = UNSUPPORTED_PERMISSIONS.map(({ name }) => {
- return aWindow.navigator.permissions
- .query({ name })
- .then(
- () => ok(false, `query should not have resolved for '${name}'`),
- error => {
- is(error.name, 'TypeError',
- `query should have thrown TypeError for '${name}'`);
- }
- );
- });
- return Promise.all(promisesToQuery);
- },
- promiseStateChanged(name, state) {
- return aWindow.navigator.permissions
- .query({ name })
- .then(status => {
- return new Promise( resolve => {
- status.onchange = () => {
- status.onchange = null;
- is(status.state, state, `state changed for '${name}'`);
- resolve();
- };
- });
- },
- () => ok(false, `query should not have rejected for '${name}'`));
- },
- testStatusOnChange() {
- return new Promise((resolve) => {
- SpecialPowers.popPermissions(() => {
- const permission = 'geolocation';
- const promiseGranted = this.promiseStateChanged(permission, 'granted');
- this.setPermissions(ALLOW_ACTION);
- promiseGranted.then(() => {
- const promisePrompt = this.promiseStateChanged(permission, 'prompt');
- SpecialPowers.popPermissions();
- return promisePrompt;
- }).then(resolve);
- });
- });
- },
- testInvalidQuery() {
- return aWindow.navigator.permissions
- .query({ name: 'invalid' })
- .then(
- () => ok(false, 'invalid query should not have resolved'),
- () => ok(true, 'invalid query should have rejected')
- );
- },
- testInvalidRevoke() {
- return aWindow.navigator.permissions
- .revoke({ name: 'invalid' })
- .then(
- () => ok(false, 'invalid revoke should not have resolved'),
- () => ok(true, 'invalid revoke should have rejected')
- );
- },
- };
- }
-
- function enablePrefs() {
- const ops = {
- 'set': [
- ['dom.permissions.revoke.enable', true],
- ['privacy.firstparty.isolate', true],
- ],
- };
- return SpecialPowers.pushPrefEnv(ops);
- }
-
- function createIframe() {
- return new Promise((resolve) => {
- const iframe = document.createElement('iframe');
- iframe.src = 'file_empty.html';
- iframe.onload = () => resolve(iframe.contentWindow);
- document.body.appendChild(iframe);
- });
- }
- debugger;
- window.onload = () => {
- enablePrefs()
- .then(createIframe)
- .then(createPermissionTester)
- .then((tester) => {
- return tester
- .checkUnsupportedPermissions()
- .then(() => tester.setPermissions(UNKNOWN_ACTION))
- .then(() => tester.checkPermissions('prompt'))
- .then(() => tester.setPermissions(PROMPT_ACTION))
- .then(() => tester.checkPermissions('prompt'))
- .then(() => tester.setPermissions(ALLOW_ACTION))
- .then(() => tester.checkPermissions('granted'))
- .then(() => tester.setPermissions(DENY_ACTION))
- .then(() => tester.checkPermissions('denied'))
- .then(() => tester.testStatusOnChange())
- .then(() => tester.testInvalidQuery())
- .then(() => tester.revokeUnsupportedPermissions())
- .then(() => tester.revokePermissions())
- .then(() => tester.checkPermissions('prompt'))
- .then(() => tester.testInvalidRevoke());
- })
- .then(SimpleTest.finish)
- .catch((e) => {
- ok(false, `Unexpected error ${e}`);
- SimpleTest.finish();
- });
- };
- </script>
-</body>
-
-</html>
diff --git a/browser/components/places/moz.build b/browser/components/places/moz.build
index e6f88b318..9e5a2c074 100644
--- a/browser/components/places/moz.build
+++ b/browser/components/places/moz.build
@@ -4,15 +4,8 @@
# 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/.
-XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
-MOCHITEST_CHROME_MANIFESTS += ['tests/chrome/chrome.ini']
-BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
EXTRA_JS_MODULES += [
'PlacesUIUtils.jsm',
]
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Bookmarks & History')
diff --git a/browser/components/places/tests/browser/.eslintrc.js b/browser/components/places/tests/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/places/tests/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/places/tests/browser/bookmark_dummy_1.html b/browser/components/places/tests/browser/bookmark_dummy_1.html
deleted file mode 100644
index c03e0c18c..000000000
--- a/browser/components/places/tests/browser/bookmark_dummy_1.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>Bookmark Dummy 1</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<p>Bookmark Dummy 1</p>
-</body>
-</html>
diff --git a/browser/components/places/tests/browser/bookmark_dummy_2.html b/browser/components/places/tests/browser/bookmark_dummy_2.html
deleted file mode 100644
index 229a730b3..000000000
--- a/browser/components/places/tests/browser/bookmark_dummy_2.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-<title>Bookmark Dummy 2</title>
-<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
-</head>
-<body>
-<p>Bookmark Dummy 2</p>
-</body>
-</html>
diff --git a/browser/components/places/tests/browser/browser.ini b/browser/components/places/tests/browser/browser.ini
deleted file mode 100644
index 5dce31653..000000000
--- a/browser/components/places/tests/browser/browser.ini
+++ /dev/null
@@ -1,58 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-[DEFAULT]
-support-files =
- head.js
- framedPage.html
- frameLeft.html
- frameRight.html
- sidebarpanels_click_test_page.html
- keyword_form.html
-
-[browser_0_library_left_pane_migration.js]
-[browser_410196_paste_into_tags.js]
-subsuite = clipboard
-[browser_416459_cut.js]
-subsuite = clipboard
-[browser_423515.js]
-[browser_425884.js]
-[browser_435851_copy_query.js]
-subsuite = clipboard
-[browser_475045.js]
-[browser_555547.js]
-[browser_bookmarklet_windowOpen.js]
-support-files =
- pageopeningwindow.html
-[browser_bookmarkProperties_addFolderDefaultButton.js]
-[browser_bookmarkProperties_addKeywordForThisSearch.js]
-[browser_bookmarkProperties_addLivemark.js]
-[browser_bookmarkProperties_editTagContainer.js]
-[browser_bookmarkProperties_readOnlyRoot.js]
-[browser_bookmarksProperties.js]
-[browser_drag_bookmarks_on_toolbar.js]
-[browser_forgetthissite_single.js]
-[browser_history_sidebar_search.js]
-[browser_library_batch_delete.js]
-[browser_library_commands.js]
-[browser_library_downloads.js]
-[browser_library_infoBox.js]
-[browser_library_left_pane_fixnames.js]
-[browser_library_left_pane_select_hierarchy.js]
-[browser_library_middleclick.js]
-[browser_library_open_leak.js]
-[browser_library_openFlatContainer.js]
-[browser_library_panel_leak.js]
-[browser_library_search.js]
-[browser_library_views_liveupdate.js]
-[browser_markPageAsFollowedLink.js]
-[browser_sidebarpanels_click.js]
-skip-if = true # temporarily disabled for breaking the treeview - bug 658744
-[browser_sort_in_library.js]
-[browser_toolbarbutton_menu_context.js]
-[browser_views_liveupdate.js]
-[browser_bookmark_all_tabs.js]
-support-files =
- bookmark_dummy_1.html
- bookmark_dummy_2.html
diff --git a/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js b/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js
deleted file mode 100644
index a7089b497..000000000
--- a/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * Test we correctly migrate Library left pane to the latest version.
- * Note: this test MUST be the first between browser chrome tests, or results
- * of next tests could be unexpected due to PlacesUIUtils getters.
- */
-
-const TEST_URI = "http://www.mozilla.org/";
-
-add_task(function* () {
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils is running in chrome context");
- ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
- ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0,
- "Left pane version in chrome context, current version is: " + PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION );
-
- // Check if we have any left pane folder already set, remove it eventually.
- let leftPaneItems = PlacesUtils.annotations
- .getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- if (leftPaneItems.length > 0) {
- // The left pane has already been created, touching it now would cause
- // next tests to rely on wrong values (and possibly crash)
- is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
- // Check version.
- let version = PlacesUtils.annotations.getItemAnnotation(leftPaneItems[0],
- PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION, "Left pane version is actual");
- ok(true, "left pane has already been created, skipping test");
- return;
- }
-
- // Create a fake left pane folder with an old version (current version - 1).
- let folder = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.rootGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- title: ""
- });
-
- let folderId = yield PlacesUtils.promiseItemId(folder.guid);
- PlacesUtils.annotations.setItemAnnotation(folderId,
- PlacesUIUtils.ORGANIZER_FOLDER_ANNO,
- PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION - 1,
- 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
-
- // Check fake left pane root has been correctly created.
- leftPaneItems =
- PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
- is(leftPaneItems[0], folderId, "left pane root itemId is correct");
-
- // Check version.
- let version = PlacesUtils.annotations.getItemAnnotation(folderId,
- PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION - 1, "Left pane version correctly set");
-
- // Open Library, this will upgrade our left pane version.
- let organizer = yield promiseLibrary();
-
- // Check left pane.
- ok(PlacesUIUtils.leftPaneFolderId > 0, "Left pane folder correctly created");
- leftPaneItems =
- PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
- let leftPaneRoot = leftPaneItems[0];
- is(leftPaneRoot, PlacesUIUtils.leftPaneFolderId,
- "leftPaneFolderId getter has correct value");
-
- // Check version has been upgraded.
- version = PlacesUtils.annotations.getItemAnnotation(leftPaneRoot,
- PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION,
- "Left pane version has been correctly upgraded");
-
- // Check left pane is populated.
- organizer.PlacesOrganizer.selectLeftPaneQuery("History");
- is(organizer.PlacesOrganizer._places.selectedNode.itemId,
- PlacesUIUtils.leftPaneQueries["History"],
- "Library left pane is populated and working");
-
- yield promiseLibraryClosed(organizer);
-});
diff --git a/browser/components/places/tests/browser/browser_410196_paste_into_tags.js b/browser/components/places/tests/browser/browser_410196_paste_into_tags.js
deleted file mode 100644
index 2acb1d9b7..000000000
--- a/browser/components/places/tests/browser/browser_410196_paste_into_tags.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-"use strict";
-
-const TEST_URL = Services.io.newURI("http://example.com/", null, null);
-const MOZURISPEC = Services.io.newURI("http://mozilla.com/", null, null);
-
-add_task(function* () {
- let organizer = yield promiseLibrary();
-
- ok(PlacesUtils, "PlacesUtils in scope");
- ok(PlacesUIUtils, "PlacesUIUtils in scope");
-
- let PlacesOrganizer = organizer.PlacesOrganizer;
- ok(PlacesOrganizer, "Places organizer in scope");
-
- let ContentTree = organizer.ContentTree;
- ok(ContentTree, "ContentTree is in scope");
-
- let visits = {uri: MOZURISPEC, transition: PlacesUtils.history.TRANSITION_TYPED};
- yield PlacesTestUtils.addVisits(visits);
-
- // create an initial tag to work with
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- title: "bookmark/" + TEST_URL.spec,
- url: TEST_URL
- });
-
- ok(bm, "A bookmark was added");
- PlacesUtils.tagging.tagURI(TEST_URL, ["foo"]);
- let tags = PlacesUtils.tagging.getTagsForURI(TEST_URL);
- is(tags[0], "foo", "tag is foo");
-
- // focus the new tag
- focusTag(PlacesOrganizer);
-
- let populate = () => copyHistNode(PlacesOrganizer, ContentTree);
- yield promiseClipboard(populate, PlacesUtils.TYPE_X_MOZ_PLACE);
-
- focusTag(PlacesOrganizer);
- PlacesOrganizer._places.controller.paste();
-
- // re-focus the history again
- PlacesOrganizer.selectLeftPaneQuery("History");
- let histContainer = PlacesOrganizer._places.selectedNode;
- PlacesUtils.asContainer(histContainer);
- histContainer.containerOpen = true;
- PlacesOrganizer._places.selectNode(histContainer.getChild(0));
- let histNode = ContentTree.view.view.nodeForTreeIndex(0);
- ok(histNode, "histNode exists: " + histNode.title);
-
- // check to see if the history node is tagged!
- tags = PlacesUtils.tagging.getTagsForURI(MOZURISPEC);
- ok(tags.length == 1, "history node is tagged: " + tags.length);
-
- // check if a bookmark was created
- let bookmarks = [];
- yield PlacesUtils.bookmarks.fetch({url: MOZURISPEC}, bm => {
- bookmarks.push(bm);
- });
- ok(bookmarks.length > 0, "bookmark exists for the tagged history item");
-
- // is the bookmark visible in the UI?
- // get the Unsorted Bookmarks node
- PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
-
- // now we can see what is in the ContentTree tree
- let unsortedNode = ContentTree.view.view.nodeForTreeIndex(1);
- ok(unsortedNode, "unsortedNode is not null: " + unsortedNode.uri);
- is(unsortedNode.uri, MOZURISPEC.spec, "node uri's are the same");
-
- yield promiseLibraryClosed(organizer);
-
- // Remove new Places data we created.
- PlacesUtils.tagging.untagURI(MOZURISPEC, ["foo"]);
- PlacesUtils.tagging.untagURI(TEST_URL, ["foo"]);
- tags = PlacesUtils.tagging.getTagsForURI(TEST_URL);
- is(tags.length, 0, "tags are gone");
-
- yield PlacesUtils.bookmarks.eraseEverything();
- yield PlacesTestUtils.clearHistory();
-});
-
-function focusTag(PlacesOrganizer) {
- PlacesOrganizer.selectLeftPaneQuery("Tags");
- let tags = PlacesOrganizer._places.selectedNode;
- tags.containerOpen = true;
- let fooTag = tags.getChild(0);
- let tagNode = fooTag;
- PlacesOrganizer._places.selectNode(fooTag);
- is(tagNode.title, 'foo', "tagNode title is foo");
- let ip = PlacesOrganizer._places.insertionPoint;
- ok(ip.isTag, "IP is a tag");
-}
-
-function copyHistNode(PlacesOrganizer, ContentTree) {
- // focus the history object
- PlacesOrganizer.selectLeftPaneQuery("History");
- let histContainer = PlacesOrganizer._places.selectedNode;
- PlacesUtils.asContainer(histContainer);
- histContainer.containerOpen = true;
- PlacesOrganizer._places.selectNode(histContainer.getChild(0));
- let histNode = ContentTree.view.view.nodeForTreeIndex(0);
- ContentTree.view.selectNode(histNode);
- is(histNode.uri, MOZURISPEC.spec,
- "historyNode exists: " + histNode.uri);
- // copy the history node
- ContentTree.view.controller.copy();
-}
diff --git a/browser/components/places/tests/browser/browser_416459_cut.js b/browser/components/places/tests/browser/browser_416459_cut.js
deleted file mode 100644
index 6f3f8cdd5..000000000
--- a/browser/components/places/tests/browser/browser_416459_cut.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const TEST_URL = "http://example.com/";
-
-add_task(function* () {
- yield PlacesUtils.bookmarks.eraseEverything();
- let organizer = yield promiseLibrary();
-
- registerCleanupFunction(function* () {
- yield promiseLibraryClosed(organizer);
- yield PlacesUtils.bookmarks.eraseEverything();
- });
-
- let PlacesOrganizer = organizer.PlacesOrganizer;
- let ContentTree = organizer.ContentTree;
-
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils in scope");
- ok(PlacesUIUtils, "PlacesUIUtils in scope");
- ok(PlacesOrganizer, "PlacesOrganizer in scope");
- ok(ContentTree, "ContentTree is in scope");
-
- // Test with multiple entries to ensure they retain their order.
- let bookmarks = [];
- bookmarks.push(yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: TEST_URL,
- title: "0"
- }));
- bookmarks.push(yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: TEST_URL,
- title: "1"
- }));
- bookmarks.push(yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: TEST_URL,
- title: "2"
- }));
-
- yield selectBookmarksIn(organizer, bookmarks, "BookmarksToolbar");
-
- yield promiseClipboard(() => {
- info("Cutting selection");
- ContentTree.view.controller.cut();
- }, PlacesUtils.TYPE_X_MOZ_PLACE);
-
- info("Selecting UnfiledBookmarks in the left pane");
- PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- info("Pasting clipboard");
- ContentTree.view.controller.paste();
-
- yield selectBookmarksIn(organizer, bookmarks, "UnfiledBookmarks");
-});
-
-var selectBookmarksIn = Task.async(function* (organizer, bookmarks, aLeftPaneQuery) {
- let PlacesOrganizer = organizer.PlacesOrganizer;
- let ContentTree = organizer.ContentTree;
- info("Selecting " + aLeftPaneQuery + " in the left pane");
- PlacesOrganizer.selectLeftPaneQuery(aLeftPaneQuery);
-
- let ids = [];
- for (let {guid} of bookmarks) {
- let bookmark = yield PlacesUtils.bookmarks.fetch(guid);
- is (bookmark.parentGuid, PlacesOrganizer._places.selectedNode.targetFolderGuid,
- "Bookmark has the right parent");
- ids.push(yield PlacesUtils.promiseItemId(bookmark.guid));
- }
-
- info("Selecting the bookmarks in the right pane");
- ContentTree.view.selectItems(ids);
-
- for (let node of ContentTree.view.selectedNodes) {
- is(node.bookmarkIndex, node.title,
- "Found the expected bookmark in the expected position");
- }
-});
diff --git a/browser/components/places/tests/browser/browser_423515.js b/browser/components/places/tests/browser/browser_423515.js
deleted file mode 100644
index 4d3da8fc1..000000000
--- a/browser/components/places/tests/browser/browser_423515.js
+++ /dev/null
@@ -1,173 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- // sanity check
- ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
- ok(PlacesUIUtils, "checking PlacesUIUtils, running in chrome context?");
- ok(PlacesControllerDragHelper, "checking PlacesControllerDragHelper, running in chrome context?");
-
- const IDX = PlacesUtils.bookmarks.DEFAULT_INDEX;
-
- // setup
- var rootId = PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId, "", IDX);
- var rootNode = PlacesUtils.getFolderContents(rootId, false, true).root;
- is(rootNode.childCount, 0, "confirm test root is empty");
-
- var tests = [];
-
- // add a regular folder, should be moveable
- tests.push({
- populate: function() {
- this.id =
- PlacesUtils.bookmarks.createFolder(rootId, "", IDX);
- },
- validate: function() {
- is(rootNode.childCount, 1,
- "populate added data to the test root");
- is(PlacesControllerDragHelper.canMoveNode(rootNode.getChild(0)),
- true, "can move regular folder node");
- }
- });
-
- // add a regular folder shortcut, should be moveable
- tests.push({
- populate: function() {
- this.folderId =
- PlacesUtils.bookmarks.createFolder(rootId, "foo", IDX);
- this.shortcutId =
- PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("place:folder="+this.folderId), IDX, "bar");
- },
- validate: function() {
- is(rootNode.childCount, 2,
- "populated data to the test root");
-
- var folderNode = rootNode.getChild(0);
- is(folderNode.type, 6, "node is folder");
- is(this.folderId, folderNode.itemId, "folder id and folder node item id match");
-
- var shortcutNode = rootNode.getChild(1);
- is(shortcutNode.type, 9, "node is folder shortcut");
- is(this.shortcutId, shortcutNode.itemId, "shortcut id and shortcut node item id match");
-
- var concreteId = PlacesUtils.getConcreteItemId(shortcutNode);
- is(concreteId, folderNode.itemId, "shortcut node id and concrete id match");
-
- is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
- true, "can move folder shortcut node");
- }
- });
-
- // add a regular query, should be moveable
- tests.push({
- populate: function() {
- this.bookmarkId =
- PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("http://foo.com"), IDX, "foo");
- this.queryId =
- PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("place:terms=foo"), IDX, "bar");
- },
- validate: function() {
- is(rootNode.childCount, 2,
- "populated data to the test root");
-
- var bmNode = rootNode.getChild(0);
- is(bmNode.itemId, this.bookmarkId, "bookmark id and bookmark node item id match");
-
- var queryNode = rootNode.getChild(1);
- is(queryNode.itemId, this.queryId, "query id and query node item id match");
-
- is(PlacesControllerDragHelper.canMoveNode(queryNode),
- true, "can move query node");
- }
- });
-
- // test that special folders cannot be moved
- // test that special folders shortcuts can be moved
- tests.push({
- folders: [PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.tagsFolderId, PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.toolbarFolderId],
- shortcuts: {},
- populate: function() {
- for (var i = 0; i < this.folders.length; i++) {
- var id = this.folders[i];
- this.shortcuts[id] =
- PlacesUtils.bookmarks.insertBookmark(rootId, makeURI("place:folder=" + id), IDX, "");
- }
- },
- validate: function() {
- // test toolbar shortcut node
- is(rootNode.childCount, this.folders.length,
- "populated data to the test root");
-
- function getRootChildNode(aId) {
- var node = PlacesUtils.getFolderContents(PlacesUtils.placesRootId, false, true).root;
- for (var i = 0; i < node.childCount; i++) {
- var child = node.getChild(i);
- if (child.itemId == aId) {
- node.containerOpen = false;
- return child;
- }
- }
- node.containerOpen = false;
- ok(false, "Unable to find child node");
- return null;
- }
-
- for (var i = 0; i < this.folders.length; i++) {
- var id = this.folders[i];
-
- var node = getRootChildNode(id);
- isnot(node, null, "Node found");
- is(PlacesControllerDragHelper.canMoveNode(node),
- false, "shouldn't be able to move special folder node");
-
- var shortcutId = this.shortcuts[id];
- var shortcutNode = rootNode.getChild(i);
-
- is(shortcutNode.itemId, shortcutId, "shortcut id and shortcut node item id match");
-
- dump("can move shortcut node?\n");
- is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
- true, "should be able to move special folder shortcut node");
- }
- }
- });
-
- // test that a tag container cannot be moved
- tests.push({
- populate: function() {
- // tag a uri
- this.uri = makeURI("http://foo.com");
- PlacesUtils.tagging.tagURI(this.uri, ["bar"]);
- registerCleanupFunction(() => PlacesUtils.tagging.untagURI(this.uri, ["bar"]));
- },
- validate: function() {
- // get tag root
- var query = PlacesUtils.history.getNewQuery();
- var options = PlacesUtils.history.getNewQueryOptions();
- options.resultType = Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY;
- var tagsNode = PlacesUtils.history.executeQuery(query, options).root;
-
- tagsNode.containerOpen = true;
- is(tagsNode.childCount, 1, "has new tag");
-
- var tagNode = tagsNode.getChild(0);
-
- is(PlacesControllerDragHelper.canMoveNode(tagNode),
- false, "should not be able to move tag container node");
- tagsNode.containerOpen = false;
- }
- });
-
- tests.forEach(function(aTest) {
- PlacesUtils.bookmarks.removeFolderChildren(rootId);
- aTest.populate();
- aTest.validate();
- });
-
- rootNode.containerOpen = false;
- PlacesUtils.bookmarks.removeItem(rootId);
-}
diff --git a/browser/components/places/tests/browser/browser_425884.js b/browser/components/places/tests/browser/browser_425884.js
deleted file mode 100644
index 655eb1ffd..000000000
--- a/browser/components/places/tests/browser/browser_425884.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/*
- Deep copy of bookmark data, using the front-end codepath:
-
- - create test folder A
- - add a subfolder to folder A, and add items to it
- - validate folder A (sanity check)
- - copy folder A, creating new folder B, using the front-end path
- - validate folder B
- - undo copy transaction
- - validate folder B (empty)
- - redo copy transaction
- - validate folder B's contents
-*/
-
-add_task(function* () {
- // sanity check
- ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
- ok(PlacesUIUtils, "checking PlacesUIUtils, running in chrome context?");
-
- let toolbarId = PlacesUtils.toolbarFolderId;
- let toolbarNode = PlacesUtils.getFolderContents(toolbarId).root;
-
- let oldCount = toolbarNode.childCount;
- let testRoot = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- title: "test root"
- });
- is(toolbarNode.childCount, oldCount+1, "confirm test root node is a container, and is empty");
-
- let testRootNode = toolbarNode.getChild(toolbarNode.childCount-1);
- testRootNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
- testRootNode.containerOpen = true;
- is(testRootNode.childCount, 0, "confirm test root node is a container, and is empty");
-
- // create folder A, fill it, validate its contents
- let folderA = yield PlacesUtils.bookmarks.insert({
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- parentGuid: testRoot.guid,
- title: "A"
- });
-
- yield populate(folderA);
-
- let folderAId = yield PlacesUtils.promiseItemId(folderA.guid);
- let folderANode = PlacesUtils.getFolderContents(folderAId).root;
- validate(folderANode);
- is(testRootNode.childCount, 1, "create test folder");
-
- // copy it, using the front-end helper functions
- let serializedNode = PlacesUtils.wrapNode(folderANode, PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER);
- let rawNode = PlacesUtils.unwrapNodes(serializedNode, PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER).shift();
- // confirm serialization
- ok(rawNode.type, "confirm json node");
- folderANode.containerOpen = false;
-
- let testRootId = yield PlacesUtils.promiseItemId(testRoot.guid);
- let transaction = PlacesUIUtils.makeTransaction(rawNode,
- PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
- testRootId,
- -1,
- true);
- ok(transaction, "create transaction");
- PlacesUtils.transactionManager.doTransaction(transaction);
- // confirm copy
- is(testRootNode.childCount, 2, "create test folder via copy");
-
- // validate the copy
- let folderBNode = testRootNode.getChild(1);
- validate(folderBNode);
-
- // undo the transaction, confirm the removal
- PlacesUtils.transactionManager.undoTransaction();
- is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
-
- // redo the transaction
- PlacesUtils.transactionManager.redoTransaction();
- is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
- folderBNode = testRootNode.getChild(1);
- validate(folderBNode);
-
- // Close containers, cleaning up their observers.
- testRootNode.containerOpen = false;
- toolbarNode.containerOpen = false;
-
- // clean up
- PlacesUtils.transactionManager.undoTransaction();
- yield PlacesUtils.bookmarks.remove(folderA.guid);
-});
-
-var populate = Task.async(function* (parentFolder) {
- let folder = yield PlacesUtils.bookmarks.insert({
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- parentGuid: parentFolder.guid,
- title: "test folder"
- });
-
- yield PlacesUtils.bookmarks.insert({
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- parentGuid: folder.guid,
- title: "test bookmark",
- url: "http://foo"
- });
-
- yield PlacesUtils.bookmarks.insert({
- type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
- parentGuid: folder.guid
- });
-});
-
-function validate(aNode) {
- PlacesUtils.asContainer(aNode);
- aNode.containerOpen = true;
- is(aNode.childCount, 1, "confirm child count match");
- var folderNode = aNode.getChild(0);
- is(folderNode.title, "test folder", "confirm folder title");
- PlacesUtils.asContainer(folderNode);
- folderNode.containerOpen = true;
- is(folderNode.childCount, 2, "confirm child count match");
- folderNode.containerOpen = false;
- aNode.containerOpen = false;
-}
diff --git a/browser/components/places/tests/browser/browser_435851_copy_query.js b/browser/components/places/tests/browser/browser_435851_copy_query.js
deleted file mode 100644
index 92f818b41..000000000
--- a/browser/components/places/tests/browser/browser_435851_copy_query.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/* test that copying a non movable query or folder shortcut makes a new query with the same url, not a deep copy */
-
-const SHORTCUT_URL = "place:folder=2";
-const QUERY_URL = "place:sort=8&maxResults=10";
-
-add_task(function* copy_toolbar_shortcut() {
- let library = yield promiseLibrary();
-
- registerCleanupFunction(function () {
- library.close();
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- });
-
- library.PlacesOrganizer.selectLeftPaneQuery("BookmarksToolbar");
-
- yield promiseClipboard(function () { library.PlacesOrganizer._places.controller.copy(); },
- PlacesUtils.TYPE_X_MOZ_PLACE);
-
- library.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- library.ContentTree.view.controller.paste();
-
- let toolbarCopyNode = library.ContentTree.view.view.nodeForTreeIndex(0);
- is(toolbarCopyNode.type,
- Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
- "copy is still a folder shortcut");
-
- PlacesUtils.bookmarks.removeItem(toolbarCopyNode.itemId);
- library.PlacesOrganizer.selectLeftPaneQuery("BookmarksToolbar");
- is(library.PlacesOrganizer._places.selectedNode.type,
- Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
- "original is still a folder shortcut");
-});
-
-add_task(function* copy_history_query() {
- let library = yield promiseLibrary();
-
- library.PlacesOrganizer.selectLeftPaneQuery("History");
-
- yield promiseClipboard(function () { library.PlacesOrganizer._places.controller.copy(); },
- PlacesUtils.TYPE_X_MOZ_PLACE);
-
- library.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- library.ContentTree.view.controller.paste();
-
- let historyCopyNode = library.ContentTree.view.view.nodeForTreeIndex(0);
- is(historyCopyNode.type,
- Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
- "copy is still a query");
-
- PlacesUtils.bookmarks.removeItem(historyCopyNode.itemId);
- library.PlacesOrganizer.selectLeftPaneQuery("History");
- is(library.PlacesOrganizer._places.selectedNode.type,
- Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
- "original is still a query");
-});
diff --git a/browser/components/places/tests/browser/browser_475045.js b/browser/components/places/tests/browser/browser_475045.js
deleted file mode 100644
index 7d562349b..000000000
--- a/browser/components/places/tests/browser/browser_475045.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-// Instead of loading EventUtils.js into the test scope in browser-test.js for all tests,
-// we only need EventUtils.js for a few files which is why we are using loadSubScript.
-var EventUtils = {};
-this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
-add_task(function* test() {
- // Make sure the bookmarks bar is visible and restore its state on cleanup.
- let toolbar = document.getElementById("PersonalToolbar");
- ok(toolbar, "PersonalToolbar should not be null");
-
- if (toolbar.collapsed) {
- yield promiseSetToolbarVisibility(toolbar, true);
- registerCleanupFunction(function() {
- return promiseSetToolbarVisibility(toolbar, false);
- });
- }
-
- // Setup the node we will use to be dropped. The actual node used does not
- // matter because we will set its data, effect, and mimeType manually.
- let placesItems = document.getElementById("PlacesToolbarItems");
- ok(placesItems, "PlacesToolbarItems should not be null");
- ok(placesItems.localName == "scrollbox", "PlacesToolbarItems should not be null");
- ok(placesItems.childNodes[0], "PlacesToolbarItems must have at least one child");
-
- /**
- * Simulates a drop of a URI onto the bookmarks bar.
- *
- * @param aEffect
- * The effect to use for the drop operation: move, copy, or link.
- * @param aMimeType
- * The mime type to use for the drop operation.
- */
- let simulateDragDrop = function(aEffect, aMimeType) {
- const uriSpec = "http://www.mozilla.org/D1995729-A152-4e30-8329-469B01F30AA7";
- let uri = makeURI(uriSpec);
- EventUtils.synthesizeDrop(placesItems.childNodes[0],
- placesItems,
- [[{type: aMimeType,
- data: uriSpec}]],
- aEffect, window);
-
- // Verify that the drop produces exactly one bookmark.
- let bookmarkIds = PlacesUtils.bookmarks
- .getBookmarkIdsForURI(uri);
- ok(bookmarkIds.length == 1, "There should be exactly one bookmark");
-
- PlacesUtils.bookmarks.removeItem(bookmarkIds[0]);
-
- // Verify that we removed the bookmark successfully.
- ok(!PlacesUtils.bookmarks.isBookmarked(uri), "URI should be removed");
- }
-
- // Simulate a bookmark drop for all of the mime types and effects.
- let mimeTypes = ["text/plain", "text/unicode", "text/x-moz-url"];
- let effects = ["move", "copy", "link"];
- effects.forEach(function (effect) {
- mimeTypes.forEach(function (mimeType) {
- simulateDragDrop(effect, mimeType);
- });
- });
-});
diff --git a/browser/components/places/tests/browser/browser_555547.js b/browser/components/places/tests/browser/browser_555547.js
deleted file mode 100644
index 0654139cb..000000000
--- a/browser/components/places/tests/browser/browser_555547.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-"use strict";
-
-add_task(function* test() {
- let sidebarBox = document.getElementById("sidebar-box");
- is(sidebarBox.hidden, true, "The sidebar should be hidden");
-
- // Uncollapse the personal toolbar if needed.
- let toolbar = document.getElementById("PersonalToolbar");
- let wasCollapsed = toolbar.collapsed;
- if (wasCollapsed) {
- yield promiseSetToolbarVisibility(toolbar, true);
- }
-
- let sidebar = yield promiseLoadedSidebar("viewBookmarksSidebar");
- registerCleanupFunction(() => {
- SidebarUI.hide();
- });
-
- // Focus the tree and check if its controller is returned.
- let tree = sidebar.contentDocument.getElementById("bookmarks-view");
- tree.focus();
-
- let controller = doGetPlacesControllerForCommand("placesCmd_copy");
- let treeController = tree.controllers
- .getControllerForCommand("placesCmd_copy");
- ok(controller == treeController, "tree controller was returned");
-
- // Open the context menu for a toolbar item, and check if the toolbar's
- // controller is returned.
- let toolbarItems = document.getElementById("PlacesToolbarItems");
- EventUtils.synthesizeMouse(toolbarItems.childNodes[0],
- 4, 4, { type: "contextmenu", button: 2 },
- window);
- controller = doGetPlacesControllerForCommand("placesCmd_copy");
- let toolbarController = document.getElementById("PlacesToolbar")
- .controllers
- .getControllerForCommand("placesCmd_copy");
- ok(controller == toolbarController, "the toolbar controller was returned");
-
- document.getElementById("placesContext").hidePopup();
-
- // Now that the context menu is closed, try to get the tree controller again.
- tree.focus();
- controller = doGetPlacesControllerForCommand("placesCmd_copy");
- ok(controller == treeController, "tree controller was returned");
-
- 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);
- resolve(sidebar);
- }, true);
-
- SidebarUI.show(cmd);
- });
-}
diff --git a/browser/components/places/tests/browser/browser_bookmarkProperties_addFolderDefaultButton.js b/browser/components/places/tests/browser/browser_bookmarkProperties_addFolderDefaultButton.js
deleted file mode 100644
index a1f091ebe..000000000
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_addFolderDefaultButton.js
+++ /dev/null
@@ -1,53 +0,0 @@
-"use strict"
-
-add_task(function* () {
- info("Bug 475529 - Add is the default button for the new folder dialog + " +
- "Bug 1206376 - Changing properties of a new bookmark while adding it " +
- "acts on the last bookmark in the current container");
-
- // Add a new bookmark at index 0 in the unfiled folder.
- let insertionIndex = 0;
- let newBookmark = yield PlacesUtils.bookmarks.insert({
- index: insertionIndex,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- url: "http://example.com/",
- });
- let newBookmarkId = yield PlacesUtils.promiseItemId(newBookmark.guid);
-
- yield withSidebarTree("bookmarks", function* (tree) {
- // Select the new bookmark in the sidebar.
- tree.selectItems([newBookmarkId]);
- ok(tree.controller.isCommandEnabled("placesCmd_new:folder"),
- "'placesCmd_new:folder' on current selected node is enabled");
-
- // Create a new folder. Since the new bookmark is selected, and new items
- // are inserted at the index of the currently selected item, the new folder
- // will be inserted at index 0.
- yield withBookmarksDialog(
- false,
- function openDialog() {
- tree.controller.doCommand("placesCmd_new:folder");
- },
- function* test(dialogWin) {
- let promiseTitleChangeNotification = promiseBookmarksNotification(
- "onItemChanged", (itemId, prop, isAnno, val) => prop == "title" && val =="n");
-
- fillBookmarkTextField("editBMPanel_namePicker", "n", dialogWin, false);
-
- // Confirm and close the dialog.
- EventUtils.synthesizeKey("VK_RETURN", {}, dialogWin);
- yield promiseTitleChangeNotification;
-
- let newFolder = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: insertionIndex,
- });
-
- is(newFolder.title, "n", "folder name has been edited");
- yield PlacesUtils.bookmarks.remove(newFolder);
- yield PlacesUtils.bookmarks.remove(newBookmark);
- }
- );
- });
-});
diff --git a/browser/components/places/tests/browser/browser_bookmarkProperties_addKeywordForThisSearch.js b/browser/components/places/tests/browser/browser_bookmarkProperties_addKeywordForThisSearch.js
deleted file mode 100644
index 5283a1610..000000000
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_addKeywordForThisSearch.js
+++ /dev/null
@@ -1,110 +0,0 @@
-"use strict"
-
-const TEST_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser/keyword_form.html";
-
-add_task(function* () {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: TEST_URL,
- }, function* (browser) {
- // We must wait for the context menu code to build metadata.
- yield openContextMenuForContentSelector(browser, '#form1 > input[name="search"]');
-
- yield withBookmarksDialog(true, AddKeywordForSearchField, function* (dialogWin) {
- let acceptBtn = dialogWin.document.documentElement.getButton("accept");
- ok(acceptBtn.disabled, "Accept button is disabled");
-
- let promiseKeywordNotification = promiseBookmarksNotification(
- "onItemChanged", (itemId, prop, isAnno, val) => prop == "keyword" && val =="kw");
-
- fillBookmarkTextField("editBMPanel_keywordField", "kw", dialogWin);
-
- ok(!acceptBtn.disabled, "Accept button is enabled");
-
- // The dialog is instant apply.
- yield promiseKeywordNotification;
-
- // After the notification, the keywords cache will update asynchronously.
- info("Check the keyword entry has been created");
- let entry;
- yield waitForCondition(function* () {
- entry = yield PlacesUtils.keywords.fetch("kw");
- return !!entry;
- }, "Unable to find the expected keyword");
- is(entry.keyword, "kw", "keyword is correct");
- is(entry.url.href, TEST_URL, "URL is correct");
- is(entry.postData, "accenti%3D%E0%E8%EC%F2%F9&search%3D%25s", "POST data is correct");
-
- info("Check the charset has been saved");
- let charset = yield PlacesUtils.getCharsetForURI(NetUtil.newURI(TEST_URL));
- is(charset, "windows-1252", "charset is correct");
-
- // Now check getShortcutOrURI.
- let data = yield getShortcutOrURIAndPostData("kw test");
- is(getPostDataString(data.postData), "accenti=\u00E0\u00E8\u00EC\u00F2\u00F9&search=test", "getShortcutOrURI POST data is correct");
- is(data.url, TEST_URL, "getShortcutOrURI URL is correct");
- });
- });
-});
-
-add_task(function* reopen_same_field() {
- yield PlacesUtils.keywords.insert({
- url: TEST_URL,
- keyword: "kw",
- postData: "accenti%3D%E0%E8%EC%F2%F9&search%3D%25s"
- });
- registerCleanupFunction(function* () {
- yield PlacesUtils.keywords.remove("kw");
- });
- // Reopening on the same input field should show the existing keyword.
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: TEST_URL,
- }, function* (browser) {
- // We must wait for the context menu code to build metadata.
- yield openContextMenuForContentSelector(browser, '#form1 > input[name="search"]');
-
- yield withBookmarksDialog(true, AddKeywordForSearchField, function* (dialogWin) {
- let acceptBtn = dialogWin.document.documentElement.getButton("accept");
- ok(acceptBtn.disabled, "Accept button is disabled");
-
- let elt = dialogWin.document.getElementById("editBMPanel_keywordField");
- is(elt.value, "kw");
- });
- });
-});
-
-add_task(function* open_other_field() {
- yield PlacesUtils.keywords.insert({
- url: TEST_URL,
- keyword: "kw2",
- postData: "search%3D%25s"
- });
- registerCleanupFunction(function* () {
- yield PlacesUtils.keywords.remove("kw2");
- });
- // Reopening on another field of the same page that has different postData
- // should not show the existing keyword.
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: TEST_URL,
- }, function* (browser) {
- // We must wait for the context menu code to build metadata.
- yield openContextMenuForContentSelector(browser, '#form2 > input[name="search"]');
-
- yield withBookmarksDialog(true, AddKeywordForSearchField, function* (dialogWin) {
- let acceptBtn = dialogWin.document.documentElement.getButton("accept");
- ok(acceptBtn.disabled, "Accept button is disabled");
-
- let elt = dialogWin.document.getElementById("editBMPanel_keywordField");
- is(elt.value, "");
- });
- });
-});
-
-function getPostDataString(stream) {
- let sis = Cc["@mozilla.org/scriptableinputstream;1"]
- .createInstance(Ci.nsIScriptableInputStream);
- sis.init(stream);
- return sis.read(stream.available()).split("\n").pop();
-}
diff --git a/browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js b/browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js
deleted file mode 100644
index d9f4c07d7..000000000
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js
+++ /dev/null
@@ -1,39 +0,0 @@
-"use strict"
-
-add_task(function* () {
- info("Add a live bookmark editing its data");
-
- yield withSidebarTree("bookmarks", function* (tree) {
- let itemId = PlacesUIUtils.leftPaneQueries["UnfiledBookmarks"];
- tree.selectItems([itemId]);
-
- yield withBookmarksDialog(
- true,
- function openDialog() {
- PlacesCommandHook.addLiveBookmark("http://livemark.com/",
- "livemark", "description");
- },
- function* test(dialogWin) {
- let promiseTitleChangeNotification = promiseBookmarksNotification(
- "onItemChanged", (itemId, prop, isAnno, val) => prop == "title" && val == "modified");
-
- fillBookmarkTextField("editBMPanel_namePicker", "modified", dialogWin);
-
- yield promiseTitleChangeNotification;
-
- let bookmark = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX
- });
-
- is(bookmark.title, "modified", "folder name has been edited");
-
- let livemark = yield PlacesUtils.livemarks.getLivemark({
- guid: bookmark.guid
- });
- is(livemark.feedURI.spec, "http://livemark.com/", "livemark has the correct url");
- is(livemark.title, "modified", "livemark has the correct title");
- }
- );
- });
-});
diff --git a/browser/components/places/tests/browser/browser_bookmarkProperties_editTagContainer.js b/browser/components/places/tests/browser/browser_bookmarkProperties_editTagContainer.js
deleted file mode 100644
index fde9ea272..000000000
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_editTagContainer.js
+++ /dev/null
@@ -1,71 +0,0 @@
-"use strict"
-
-add_task(function* () {
- info("Bug 479348 - Properties on a root should be read-only.");
- let uri = NetUtil.newURI("http://example.com/");
- let bm = yield PlacesUtils.bookmarks.insert({
- url: uri.spec,
- parentGuid: PlacesUtils.bookmarks.unfiledGuid
- });
- registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.remove(bm);
- });
-
- PlacesUtils.tagging.tagURI(uri, ["tag1"]);
-
- let library = yield promiseLibrary();
- let PlacesOrganizer = library.PlacesOrganizer;
- registerCleanupFunction(function* () {
- yield promiseLibraryClosed(library);
- });
-
- PlacesOrganizer.selectLeftPaneQuery("Tags");
- let tree = PlacesOrganizer._places;
- let tagsContainer = tree.selectedNode;
- tagsContainer.containerOpen = true;
- let fooTag = tagsContainer.getChild(0);
- let tagNode = fooTag;
- tree.selectNode(fooTag);
- is(tagNode.title, 'tag1', "tagNode title is correct");
-
- ok(tree.controller.isCommandEnabled("placesCmd_show:info"),
- "'placesCmd_show:info' on current selected node is enabled");
-
- yield withBookmarksDialog(
- true,
- function openDialog() {
- tree.controller.doCommand("placesCmd_show:info");
- },
- function* test(dialogWin) {
- // Check that the dialog is not read-only.
- ok(!dialogWin.gEditItemOverlay.readOnly, "Dialog should not be read-only");
-
- // Check that name picker is not read only
- let namepicker = dialogWin.document.getElementById("editBMPanel_namePicker");
- ok(!namepicker.readOnly, "Name field should not be read-only");
- is(namepicker.value, "tag1", "Node title is correct");
-
- let promiseTitleChangeNotification = promiseBookmarksNotification(
- "onItemChanged", (itemId, prop, isAnno, val) => prop == "title" && val == "tag2");
-
- fillBookmarkTextField("editBMPanel_namePicker", "tag2", dialogWin);
-
- yield promiseTitleChangeNotification;
-
- is(namepicker.value, "tag2", "Node title has been properly edited");
-
- // Check the shortcut's title.
- is(tree.selectedNode.title, "tag2", "The node has the correct title");
-
- // Check the tags have been edited.
- let tags = PlacesUtils.tagging.getTagsForURI(uri);
- is(tags.length, 1, "Found the right number of tags");
- ok(tags.includes("tag2"), "Found the expected tag");
- }
- );
-
- // Check the tag change has been reverted.
- let tags = PlacesUtils.tagging.getTagsForURI(uri);
- is(tags.length, 1, "Found the right number of tags");
- ok(tags.includes("tag1"), "Found the expected tag");
-});
diff --git a/browser/components/places/tests/browser/browser_bookmarkProperties_readOnlyRoot.js b/browser/components/places/tests/browser/browser_bookmarkProperties_readOnlyRoot.js
deleted file mode 100644
index 6f499888c..000000000
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_readOnlyRoot.js
+++ /dev/null
@@ -1,42 +0,0 @@
-"use strict"
-
-add_task(function* () {
- info("Bug 479348 - Properties on a root should be read-only.");
-
- yield withSidebarTree("bookmarks", function* (tree) {
- let itemId = PlacesUIUtils.leftPaneQueries["UnfiledBookmarks"];
- tree.selectItems([itemId]);
- ok(tree.controller.isCommandEnabled("placesCmd_show:info"),
- "'placesCmd_show:info' on current selected node is enabled");
-
- yield withBookmarksDialog(
- true,
- function openDialog() {
- tree.controller.doCommand("placesCmd_show:info");
- },
- function* test(dialogWin) {
- // Check that the dialog is read-only.
- ok(dialogWin.gEditItemOverlay.readOnly, "Dialog is read-only");
- // Check that accept button is disabled
- let acceptButton = dialogWin.document.documentElement.getButton("accept");
- ok(acceptButton.disabled, "Accept button is disabled");
-
- // Check that name picker is read only
- let namepicker = dialogWin.document.getElementById("editBMPanel_namePicker");
- ok(namepicker.readOnly, "Name field is read-only");
- is(namepicker.value,
- PlacesUtils.bookmarks.getItemTitle(PlacesUtils.unfiledBookmarksFolderId),
- "Node title is correct");
- // Blur the field and ensure root's name has not been changed.
- namepicker.blur();
- is(namepicker.value,
- PlacesUtils.bookmarks.getItemTitle(PlacesUtils.unfiledBookmarksFolderId),
- "Root title is correct");
- // Check the shortcut's title.
- let bookmark = yield PlacesUtils.bookmarks.fetch(tree.selectedNode.bookmarkGuid);
- is(bookmark.title, null,
- "Shortcut title is null");
- }
- );
- });
-});
diff --git a/browser/components/places/tests/browser/browser_bookmark_all_tabs.js b/browser/components/places/tests/browser/browser_bookmark_all_tabs.js
deleted file mode 100644
index afd32b78a..000000000
--- a/browser/components/places/tests/browser/browser_bookmark_all_tabs.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Test for Bug 446171 - Name field of bookmarks saved via 'Bookmark All Tabs'
- * has '(null)' value if history is disabled or just in private browsing mode
- */
-"use strict"
-
-add_task(function* () {
- const BASE_URL = "http://example.org/browser/browser/components/places/tests/browser/";
- const TEST_PAGES = [
- BASE_URL + "bookmark_dummy_1.html",
- BASE_URL + "bookmark_dummy_2.html",
- BASE_URL + "bookmark_dummy_1.html"
- ];
-
- function promiseAddTab(url) {
- return BrowserTestUtils.openNewForegroundTab(gBrowser, url);
- }
-
- let tabs = yield Promise.all(TEST_PAGES.map(promiseAddTab));
-
- let URIs = PlacesCommandHook.uniqueCurrentPages;
- is(URIs.length, 3, "Only unique pages are returned");
-
- Assert.deepEqual(URIs.map(URI => URI.uri.spec), [
- "about:blank",
- BASE_URL + "bookmark_dummy_1.html",
- BASE_URL + "bookmark_dummy_2.html"
- ], "Correct URIs are returned");
-
- Assert.deepEqual(URIs.map(URI => URI.title), [
- "New Tab", "Bookmark Dummy 1", "Bookmark Dummy 2"
- ], "Correct titles are returned");
-
- registerCleanupFunction(function* () {
- yield Promise.all(tabs.map(BrowserTestUtils.removeTab));
- });
-});
diff --git a/browser/components/places/tests/browser/browser_bookmarklet_windowOpen.js b/browser/components/places/tests/browser/browser_bookmarklet_windowOpen.js
deleted file mode 100644
index 85ce25311..000000000
--- a/browser/components/places/tests/browser/browser_bookmarklet_windowOpen.js
+++ /dev/null
@@ -1,61 +0,0 @@
-"use strict";
-
-const TEST_URL = 'http://example.com/browser/browser/components/places/tests/browser/pageopeningwindow.html';
-
-function makeBookmarkFor(url, keyword) {
- return Promise.all([
- PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- title: "bookmarklet",
- url: url }),
- PlacesUtils.keywords.insert({url: url,
- keyword: keyword})
- ]);
-
-}
-
-add_task(function* openKeywordBookmarkWithWindowOpen() {
- // This is the current default, but let's not assume that...
- yield new Promise((resolve, reject) => {
- SpecialPowers.pushPrefEnv({ 'set': [[ 'browser.link.open_newwindow', 3 ],
- [ 'dom.disable_open_during_load', true ]] },
- resolve);
- });
-
- let moztab;
- let tabOpened = BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla")
- .then((tab) => { moztab = tab; });
- let keywordForBM = "openmeatab";
-
- let bookmarkInfo;
- let bookmarkCreated =
- makeBookmarkFor("javascript:void open('" + TEST_URL + "')", keywordForBM)
- .then((values) => {
- bookmarkInfo = values[0];
- });
- yield Promise.all([tabOpened, bookmarkCreated]);
-
- registerCleanupFunction(function() {
- return Promise.all([
- PlacesUtils.bookmarks.remove(bookmarkInfo),
- PlacesUtils.keywords.remove(keywordForBM)
- ]);
- });
- gURLBar.value = keywordForBM;
- gURLBar.focus();
-
- let tabCreatedPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
- EventUtils.synthesizeKey("VK_RETURN", {});
-
- info("Waiting for tab being created");
- let {target: tab} = yield tabCreatedPromise;
- info("Got tab");
- let browser = tab.linkedBrowser;
- if (!browser.currentURI || browser.currentURI.spec != TEST_URL) {
- info("Waiting for browser load");
- yield BrowserTestUtils.browserLoaded(browser);
- }
- is(browser.currentURI && browser.currentURI.spec, TEST_URL, "Tab with expected URL loaded.");
- info("Waiting to remove tab");
- yield Promise.all([ BrowserTestUtils.removeTab(tab),
- BrowserTestUtils.removeTab(moztab) ]);
-});
diff --git a/browser/components/places/tests/browser/browser_bookmarksProperties.js b/browser/components/places/tests/browser/browser_bookmarksProperties.js
deleted file mode 100644
index f7f9f4762..000000000
--- a/browser/components/places/tests/browser/browser_bookmarksProperties.js
+++ /dev/null
@@ -1,450 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests the bookmarks Properties dialog.
- */
-
-// DOM ids of Places sidebar trees.
-const SIDEBAR_HISTORY_TREE_ID = "historyTree";
-const SIDEBAR_BOOKMARKS_TREE_ID = "bookmarks-view";
-
-const SIDEBAR_HISTORY_ID = "viewHistorySidebar";
-const SIDEBAR_BOOKMARKS_ID = "viewBookmarksSidebar";
-
-// For history sidebar.
-const SIDEBAR_HISTORY_BYLASTVISITED_VIEW = "bylastvisited";
-const SIDEBAR_HISTORY_BYMOSTVISITED_VIEW = "byvisited";
-const SIDEBAR_HISTORY_BYDATE_VIEW = "byday";
-const SIDEBAR_HISTORY_BYSITE_VIEW = "bysite";
-const SIDEBAR_HISTORY_BYDATEANDSITE_VIEW = "bydateandsite";
-
-// Action to execute on the current node.
-const ACTION_EDIT = 0;
-const ACTION_ADD = 1;
-
-// If action is ACTION_ADD, set type to one of those, to define what do you
-// want to create.
-const TYPE_FOLDER = 0;
-const TYPE_BOOKMARK = 1;
-
-const TEST_URL = "http://www.example.com/";
-
-const DIALOG_URL = "chrome://browser/content/places/bookmarkProperties.xul";
-const DIALOG_URL_MINIMAL_UI = "chrome://browser/content/places/bookmarkProperties2.xul";
-
-Cu.import("resource:///modules/RecentWindow.jsm");
-var win = RecentWindow.getMostRecentBrowserWindow();
-var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIWindowWatcher);
-
-function add_bookmark(aURI) {
- var bId = PlacesUtils.bookmarks
- .insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- aURI,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- "bookmark/" + aURI.spec);
- return bId;
-}
-
-// Each test is an obj w/ a desc property and run method.
-var gTests = [];
-var gCurrentTest = null;
-
-// ------------------------------------------------------------------------------
-// Bug 462662 - Pressing Enter to select tag from autocomplete closes bookmarks properties dialog
-gTests.push({
- desc: "Bug 462662 - Pressing Enter to select tag from autocomplete closes bookmarks properties dialog",
- sidebar: SIDEBAR_BOOKMARKS_ID,
- action: ACTION_EDIT,
- itemType: null,
- window: null,
- _itemId: null,
- _cleanShutdown: false,
-
- setup: function(aCallback) {
- // Add a bookmark in unsorted bookmarks folder.
- this._itemId = add_bookmark(PlacesUtils._uri(TEST_URL));
- ok(this._itemId > 0, "Correctly added a bookmark");
- // Add a tag to this bookmark.
- PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL),
- ["testTag"]);
- var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(TEST_URL));
- is(tags[0], "testTag", "Correctly added a tag");
- aCallback();
- },
-
- selectNode: function(tree) {
- tree.selectItems([PlacesUtils.unfiledBookmarksFolderId]);
- PlacesUtils.asContainer(tree.selectedNode).containerOpen = true;
- tree.selectItems([this._itemId]);
- is(tree.selectedNode.itemId, this._itemId, "Bookmark has been selected");
- },
-
- run: function() {
- // 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);
-
- var popupListener = {
- handleEvent: function(aEvent) {
- switch (aEvent.type) {
- case "popuphidden":
- // Everything worked fine, we can stop observing the window.
- self._cleanShutdown = true;
- self.window.document.documentElement.cancelDialog();
- break;
- case "popupshown":
- tagsField.popup.removeEventListener("popupshown", this, true);
- // In case this test fails the window will close, the test will fail
- // since we didn't set _cleanShutdown.
- var tree = tagsField.popup.tree;
- // Focus and select first result.
- isnot(tree, null, "Autocomplete results tree exists");
- is(tree.view.rowCount, 1, "We have 1 autocomplete result");
- tagsField.popup.selectedIndex = 0;
- is(tree.view.selection.count, 1,
- "We have selected a tag from the autocomplete popup");
- info("About to focus the autocomplete results tree");
- tree.focus();
- EventUtils.synthesizeKey("VK_RETURN", {}, self.window);
- break;
- default:
- ok(false, "unknown event: " + aEvent.type);
- return;
- }
- }
- };
- tagsField.popup.addEventListener("popupshown", popupListener, true);
- tagsField.popup.addEventListener("popuphidden", popupListener, true);
-
- // Open tags autocomplete popup.
- info("About to focus the tagsField");
- executeSoon(() => {
- tagsField.focus();
- tagsField.value = "";
- EventUtils.synthesizeKey("t", {}, this.window);
- });
- },
-
- finish: function() {
- SidebarUI.hide();
- runNextTest();
- },
-
- cleanup: function() {
- // Check tags have not changed.
- var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(TEST_URL));
- is(tags[0], "testTag", "Tag on node has not changed");
-
- // Cleanup.
- PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["testTag"]);
- PlacesUtils.bookmarks.removeItem(this._itemId);
- }
-});
-
-// ------------------------------------------------------------------------------
-// Bug 476020 - Pressing Esc while having the tag autocomplete open closes the bookmarks panel
-
-gTests.push({
- desc: "Bug 476020 - Pressing Esc while having the tag autocomplete open closes the bookmarks panel",
- sidebar: SIDEBAR_BOOKMARKS_ID,
- action: ACTION_EDIT,
- itemType: null,
- window: null,
- _itemId: null,
- _cleanShutdown: false,
-
- setup: function(aCallback) {
- // Add a bookmark in unsorted bookmarks folder.
- this._itemId = add_bookmark(PlacesUtils._uri(TEST_URL));
- ok(this._itemId > 0, "Correctly added a bookmark");
- // Add a tag to this bookmark.
- PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL),
- ["testTag"]);
- var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(TEST_URL));
- is(tags[0], "testTag", "Correctly added a tag");
- aCallback();
- },
-
- selectNode: function(tree) {
- tree.selectItems([PlacesUtils.unfiledBookmarksFolderId]);
- PlacesUtils.asContainer(tree.selectedNode).containerOpen = true;
- tree.selectItems([this._itemId]);
- is(tree.selectedNode.itemId, this._itemId, "Bookmark has been selected");
- },
-
- run: function() {
- // 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);
-
- var popupListener = {
- handleEvent: function(aEvent) {
- switch (aEvent.type) {
- case "popuphidden":
- // Everything worked fine.
- self._cleanShutdown = true;
- self.window.document.documentElement.cancelDialog();
- break;
- case "popupshown":
- tagsField.popup.removeEventListener("popupshown", this, true);
- // In case this test fails the window will close, the test will fail
- // since we didn't set _cleanShutdown.
- var tree = tagsField.popup.tree;
- // Focus and select first result.
- isnot(tree, null, "Autocomplete results tree exists");
- is(tree.view.rowCount, 1, "We have 1 autocomplete result");
- tagsField.popup.selectedIndex = 0;
- is(tree.view.selection.count, 1,
- "We have selected a tag from the autocomplete popup");
- info("About to focus the autocomplete results tree");
- tree.focus();
- EventUtils.synthesizeKey("VK_ESCAPE", {}, self.window);
- break;
- default:
- ok(false, "unknown event: " + aEvent.type);
- return;
- }
- }
- };
- tagsField.popup.addEventListener("popupshown", popupListener, true);
- tagsField.popup.addEventListener("popuphidden", popupListener, true);
-
- // Open tags autocomplete popup.
- info("About to focus the tagsField");
- tagsField.focus();
- tagsField.value = "";
- EventUtils.synthesizeKey("t", {}, this.window);
- },
-
- finish: function() {
- SidebarUI.hide();
- runNextTest();
- },
-
- cleanup: function() {
- // Check tags have not changed.
- var tags = PlacesUtils.tagging.getTagsForURI(PlacesUtils._uri(TEST_URL));
- is(tags[0], "testTag", "Tag on node has not changed");
-
- // Cleanup.
- PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL),
- ["testTag"]);
- PlacesUtils.bookmarks.removeItem(this._itemId);
- }
-});
-
-// ------------------------------------------------------------------------------
-// Bug 491269 - Test that editing folder name in bookmarks properties dialog does not accept the dialog
-
-gTests.push({
- desc: " Bug 491269 - Test that editing folder name in bookmarks properties dialog does not accept the dialog",
- sidebar: SIDEBAR_HISTORY_ID,
- action: ACTION_ADD,
- historyView: SIDEBAR_HISTORY_BYLASTVISITED_VIEW,
- window: null,
-
- setup: function(aCallback) {
- // Add a visit.
- PlacesTestUtils.addVisits(
- {uri: PlacesUtils._uri(TEST_URL),
- transition: PlacesUtils.history.TRANSITION_TYPED}
- ).then(aCallback);
- },
-
- selectNode: function(tree) {
- var visitNode = tree.view.nodeForTreeIndex(0);
- tree.selectNode(visitNode);
- is(tree.selectedNode.uri, TEST_URL, "The correct visit has been selected");
- is(tree.selectedNode.itemId, -1, "The selected node is not bookmarked");
- },
-
- run: function() {
- // 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);
-
- folderTree.addEventListener("DOMAttrModified", function onDOMAttrModified(event) {
- if (event.attrName != "place")
- return;
- folderTree.removeEventListener("DOMAttrModified", arguments.callee, false);
- executeSoon(function () {
- // Create a new folder.
- var newFolderButton = self.window.document.getElementById("editBMPanel_newFolderButton");
- newFolderButton.doCommand();
- ok(folderTree.hasAttribute("editing"),
- "We are editing new folder name in folder tree");
-
- // Press Escape to discard editing new folder name.
- EventUtils.synthesizeKey("VK_ESCAPE", {}, self.window);
- ok(!folderTree.hasAttribute("editing"),
- "We have finished editing folder name in folder tree");
- self._cleanShutdown = true;
- self.window.document.documentElement.cancelDialog();
- });
- }, false);
- foldersExpander.doCommand();
- },
-
- finish: function() {
- SidebarUI.hide();
- runNextTest();
- },
-
- cleanup: function() {
- return PlacesTestUtils.clearHistory();
- }
-});
-
-// ------------------------------------------------------------------------------
-
-function test() {
- waitForExplicitFinish();
- // This test can take some time, if we timeout too early it could run
- // in the middle of other tests, or hang them.
- requestLongerTimeout(2);
-
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils in context");
- ok(PlacesUIUtils, "PlacesUIUtils in context");
-
- // kick off tests
- runNextTest();
-}
-
-function runNextTest() {
- // Cleanup from previous test.
- if (gCurrentTest) {
- Promise.resolve(gCurrentTest.cleanup()).then(() => {
- info("End of test: " + gCurrentTest.desc);
- gCurrentTest = null;
- waitForAsyncUpdates(runNextTest);
- });
- return;
- }
-
- if (gTests.length > 0) {
- // Goto next tests.
- gCurrentTest = gTests.shift();
- info("Start of test: " + gCurrentTest.desc);
- gCurrentTest.setup(function() {
- execute_test_in_sidebar();
- });
- }
- else {
- // Finished all tests.
- finish();
- }
-}
-
-/**
- * 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);
- 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)
- sidebar.contentDocument.getElementById(gCurrentTest.historyView).doCommand();
-
- // Get sidebar's Places tree.
- var sidebarTreeID = gCurrentTest.sidebar == SIDEBAR_BOOKMARKS_ID ?
- SIDEBAR_BOOKMARKS_TREE_ID :
- SIDEBAR_HISTORY_TREE_ID;
- var tree = sidebar.contentDocument.getElementById(sidebarTreeID);
- ok(tree, "Sidebar tree has been loaded");
-
- // Ask current test to select the node to edit.
- gCurrentTest.selectNode(tree);
- ok(tree.selectedNode,
- "We have a places node selected: " + tree.selectedNode.title);
-
- // Wait for the Properties dialog.
- function windowObserver(aSubject, aTopic, aData) {
- if (aTopic != "domwindowopened")
- return;
- ww.unregisterNotification(windowObserver);
- let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
- waitForFocus(() => {
- // Windows has been loaded, execute our test now.
- executeSoon(function () {
- // Ensure overlay is loaded
- ok(win.gEditItemOverlay.initialized, "EditItemOverlay is initialized");
- gCurrentTest.window = win;
- try {
- gCurrentTest.run();
- } catch (ex) {
- ok(false, "An error occured during test run: " + ex.message);
- }
- });
- }, win);
- }
- ww.registerNotification(windowObserver);
-
- var command = null;
- switch (gCurrentTest.action) {
- case ACTION_EDIT:
- command = "placesCmd_show:info";
- break;
- case ACTION_ADD:
- if (gCurrentTest.sidebar == SIDEBAR_BOOKMARKS_ID) {
- if (gCurrentTest.itemType == TYPE_FOLDER)
- command = "placesCmd_new:folder";
- else if (gCurrentTest.itemType == TYPE_BOOKMARK)
- command = "placesCmd_new:bookmark";
- else
- ok(false, "You didn't set a valid itemType for adding an item");
- }
- else
- command = "placesCmd_createBookmark";
- break;
- default:
- ok(false, "You didn't set a valid action for this test");
- }
- // Ensure command is enabled for this node.
- ok(tree.controller.isCommandEnabled(command),
- " command '" + command + "' on current selected node is enabled");
-
- // This will open the dialog.
- tree.controller.doCommand(command);
-}
diff --git a/browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js b/browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js
deleted file mode 100644
index 1ab9411f3..000000000
--- a/browser/components/places/tests/browser/browser_drag_bookmarks_on_toolbar.js
+++ /dev/null
@@ -1,256 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const TEST_URL = "http://www.mozilla.org";
-const TEST_TITLE = "example_title";
-
-var gBookmarksToolbar = window.document.getElementById("PlacesToolbar");
-var dragDirections = { LEFT: 0, UP: 1, RIGHT: 2, DOWN: 3 };
-
-/**
- * Tests dragging on toolbar.
- *
- * We must test these 2 cases:
- * - Dragging toward left, top, right should start a drag.
- * - Dragging toward down should should open the container if the item is a
- * container, drag the item otherwise.
- *
- * @param aElement
- * DOM node element we will drag
- * @param aExpectedDragData
- * Array of flavors and values in the form:
- * [ ["text/plain: sometext", "text/html: <b>sometext</b>"], [...] ]
- * Pass an empty array to check that drag even has been canceled.
- * @param aDirection
- * Direction for the dragging gesture, see dragDirections helper object.
- */
-function synthesizeDragWithDirection(aElement, aExpectedDragData, aDirection, aCallback) {
- // Dragstart listener function.
- gBookmarksToolbar.addEventListener("dragstart", function(event)
- {
- info("A dragstart event has been trapped.");
- var dataTransfer = event.dataTransfer;
- is(dataTransfer.mozItemCount, aExpectedDragData.length,
- "Number of dragged items should be the same.");
-
- for (var t = 0; t < dataTransfer.mozItemCount; t++) {
- var types = dataTransfer.mozTypesAt(t);
- var expecteditem = aExpectedDragData[t];
- is(types.length, expecteditem.length,
- "Number of flavors for item " + t + " should be the same.");
-
- for (var f = 0; f < types.length; f++) {
- is(types[f], expecteditem[f].substring(0, types[f].length),
- "Flavor " + types[f] + " for item " + t + " should be the same.");
- is(dataTransfer.mozGetDataAt(types[f], t),
- expecteditem[f].substring(types[f].length + 2),
- "Contents for item " + t + " with flavor " + types[f] + " should be the same.");
- }
- }
-
- if (!aExpectedDragData.length)
- ok(event.defaultPrevented, "Drag has been canceled.");
-
- event.preventDefault();
- event.stopPropagation();
-
- gBookmarksToolbar.removeEventListener("dragstart", arguments.callee, false);
-
- // This is likely to cause a click event, and, in case we are dragging a
- // bookmark, an unwanted page visit. Prevent the click event.
- aElement.addEventListener("click", prevent, false);
- EventUtils.synthesizeMouse(aElement,
- startingPoint.x + xIncrement * 9,
- startingPoint.y + yIncrement * 9,
- { type: "mouseup" });
- aElement.removeEventListener("click", prevent, false);
-
- // Cleanup eventually opened menus.
- if (aElement.localName == "menu" && aElement.open)
- aElement.open = false;
- aCallback()
- }, false);
-
- var prevent = function(aEvent) { aEvent.preventDefault(); }
-
- var xIncrement = 0;
- var yIncrement = 0;
-
- switch (aDirection) {
- case dragDirections.LEFT:
- xIncrement = -1;
- break;
- case dragDirections.RIGHT:
- xIncrement = +1;
- break;
- case dragDirections.UP:
- yIncrement = -1;
- break;
- case dragDirections.DOWN:
- yIncrement = +1;
- break;
- }
-
- var rect = aElement.getBoundingClientRect();
- var startingPoint = { x: (rect.right - rect.left)/2,
- y: (rect.bottom - rect.top)/2 };
-
- EventUtils.synthesizeMouse(aElement,
- startingPoint.x,
- startingPoint.y,
- { type: "mousedown" });
- EventUtils.synthesizeMouse(aElement,
- startingPoint.x + xIncrement * 1,
- startingPoint.y + yIncrement * 1,
- { type: "mousemove" });
- EventUtils.synthesizeMouse(aElement,
- startingPoint.x + xIncrement * 9,
- startingPoint.y + yIncrement * 9,
- { type: "mousemove" });
-}
-
-function getToolbarNodeForItemId(aItemId) {
- var children = document.getElementById("PlacesToolbarItems").childNodes;
- var node = null;
- for (var i = 0; i < children.length; i++) {
- if (aItemId == children[i]._placesNode.itemId) {
- node = children[i];
- break;
- }
- }
- return node;
-}
-
-function getExpectedDataForPlacesNode(aNode) {
- var wrappedNode = [];
- var flavors = ["text/x-moz-place",
- "text/x-moz-url",
- "text/plain",
- "text/html"];
-
- flavors.forEach(function(aFlavor) {
- var wrappedFlavor = aFlavor + ": " +
- PlacesUtils.wrapNode(aNode, aFlavor);
- wrappedNode.push(wrappedFlavor);
- });
-
- return [wrappedNode];
-}
-
-var gTests = [
-
-// ------------------------------------------------------------------------------
-
- {
- desc: "Drag a folder on toolbar",
- run: function() {
- // Create a test folder to be dragged.
- var folderId = PlacesUtils.bookmarks
- .createFolder(PlacesUtils.toolbarFolderId,
- TEST_TITLE,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- var element = getToolbarNodeForItemId(folderId);
- isnot(element, null, "Found node on toolbar");
-
- isnot(element._placesNode, null, "Toolbar node has an associated Places node.");
- var expectedData = getExpectedDataForPlacesNode(element._placesNode);
-
- info("Dragging left");
- synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT,
- function ()
- {
- info("Dragging right");
- synthesizeDragWithDirection(element, expectedData, dragDirections.RIGHT,
- function ()
- {
- info("Dragging up");
- synthesizeDragWithDirection(element, expectedData, dragDirections.UP,
- function ()
- {
- info("Dragging down");
- synthesizeDragWithDirection(element, new Array(), dragDirections.DOWN,
- function () {
- // Cleanup.
- PlacesUtils.bookmarks.removeItem(folderId);
- nextTest();
- });
- });
- });
- });
- }
- },
-
-// ------------------------------------------------------------------------------
-
- {
- desc: "Drag a bookmark on toolbar",
- run: function() {
- // Create a test bookmark to be dragged.
- var itemId = PlacesUtils.bookmarks
- .insertBookmark(PlacesUtils.toolbarFolderId,
- PlacesUtils._uri(TEST_URL),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- TEST_TITLE);
- var element = getToolbarNodeForItemId(itemId);
- isnot(element, null, "Found node on toolbar");
-
- isnot(element._placesNode, null, "Toolbar node has an associated Places node.");
- var expectedData = getExpectedDataForPlacesNode(element._placesNode);
-
- info("Dragging left");
- synthesizeDragWithDirection(element, expectedData, dragDirections.LEFT,
- function ()
- {
- info("Dragging right");
- synthesizeDragWithDirection(element, expectedData, dragDirections.RIGHT,
- function ()
- {
- info("Dragging up");
- synthesizeDragWithDirection(element, expectedData, dragDirections.UP,
- function ()
- {
- info("Dragging down");
- synthesizeDragWithDirection(element, expectedData, dragDirections.DOWN,
- function () {
- // Cleanup.
- PlacesUtils.bookmarks.removeItem(itemId);
- nextTest();
- });
- });
- });
- });
- }
- },
-];
-
-function nextTest() {
- if (gTests.length) {
- var test = gTests.shift();
- waitForFocus(function() {
- info("Start of test: " + test.desc);
- test.run();
- });
- }
- else if (wasCollapsed) {
- // Collapse the personal toolbar if needed.
- promiseSetToolbarVisibility(toolbar, false).then(finish);
- } else {
- finish();
- }
-}
-
-var toolbar = document.getElementById("PersonalToolbar");
-var wasCollapsed = toolbar.collapsed;
-
-function test() {
- waitForExplicitFinish();
-
- // Uncollapse the personal toolbar if needed.
- if (wasCollapsed) {
- promiseSetToolbarVisibility(toolbar, true).then(nextTest);
- } else {
- nextTest();
- }
-}
-
diff --git a/browser/components/places/tests/browser/browser_forgetthissite_single.js b/browser/components/places/tests/browser/browser_forgetthissite_single.js
deleted file mode 100644
index b1d7936e9..000000000
--- a/browser/components/places/tests/browser/browser_forgetthissite_single.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TEST_URIs = [
- "http://www.mozilla.org/test1",
- "http://www.mozilla.org/test2"
-];
-
-// This test makes sure that the Forget This Site command is hidden for multiple
-// selections.
-add_task(function* () {
- // Add a history entry.
- ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
-
- let places = [];
- let transition = PlacesUtils.history.TRANSITION_TYPED;
- TEST_URIs.forEach(uri => places.push({uri: PlacesUtils._uri(uri), transition}));
-
- yield PlacesTestUtils.addVisits(places);
- yield testForgetThisSiteVisibility(1);
- yield testForgetThisSiteVisibility(2);
-
- // Cleanup.
- yield PlacesTestUtils.clearHistory();
-});
-
-var testForgetThisSiteVisibility = Task.async(function* (selectionCount) {
- let organizer = yield promiseLibrary();
-
- // Select History in the left pane.
- organizer.PlacesOrganizer.selectLeftPaneQuery("History");
- let PO = organizer.PlacesOrganizer;
- let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
- histContainer.containerOpen = true;
- PO._places.selectNode(histContainer.getChild(0));
-
- // Select the first history entry.
- let doc = organizer.document;
- let tree = doc.getElementById("placeContent");
- let selection = tree.view.selection;
- selection.clearSelection();
- selection.rangedSelect(0, selectionCount - 1, true);
- is(selection.count, selectionCount, "The selected range is as big as expected");
-
- // Open the context menu.
- let contextmenu = doc.getElementById("placesContext");
- let popupShown = promisePopupShown(contextmenu);
-
- // Get cell coordinates.
- let rect = tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "text");
- // Initiate a context menu for the selected cell.
- EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {type: "contextmenu", button: 2}, organizer);
- yield popupShown;
-
- let forgetThisSite = doc.getElementById("placesContext_deleteHost");
- let hideForgetThisSite = (selectionCount != 1);
- is(forgetThisSite.hidden, hideForgetThisSite,
- `The Forget this site menu item should ${hideForgetThisSite ? "" : "not "}` +
- ` be hidden with ${selectionCount} items selected`);
-
- // Close the context menu.
- 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);
- resolve();
- }, true);
- });
-}
diff --git a/browser/components/places/tests/browser/browser_history_sidebar_search.js b/browser/components/places/tests/browser/browser_history_sidebar_search.js
deleted file mode 100644
index 89472c4ab..000000000
--- a/browser/components/places/tests/browser/browser_history_sidebar_search.js
+++ /dev/null
@@ -1,64 +0,0 @@
-add_task(function* test () {
- let sidebar = document.getElementById("sidebar");
-
- // Visited pages listed by descending visit date.
- let pages = [
- "http://sidebar.mozilla.org/a",
- "http://sidebar.mozilla.org/b",
- "http://sidebar.mozilla.org/c",
- "http://www.mozilla.org/d",
- ];
-
- // Number of pages that will be filtered out by the search.
- const FILTERED_COUNT = 1;
-
- yield PlacesTestUtils.clearHistory();
-
- // Add some visited page.
- let time = Date.now();
- let places = [];
- for (let i = 0; i < pages.length; i++) {
- places.push({ uri: NetUtil.newURI(pages[i]),
- visitDate: (time - i) * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED });
- }
- yield PlacesTestUtils.addVisits(places);
-
- yield withSidebarTree("history", function* () {
- info("Set 'by last visited' view");
- sidebar.contentDocument.getElementById("bylastvisited").doCommand();
- let tree = sidebar.contentDocument.getElementById("historyTree");
- check_tree_order(tree, pages);
-
- // Set a search value.
- let searchBox = sidebar.contentDocument.getElementById("search-box");
- ok(searchBox, "search box is in context");
- searchBox.value = "sidebar.mozilla";
- searchBox.doCommand();
- check_tree_order(tree, pages, -FILTERED_COUNT);
-
- info("Reset the search");
- searchBox.value = "";
- searchBox.doCommand();
- check_tree_order(tree, pages);
- });
-
- yield PlacesTestUtils.clearHistory();
-});
-
-function check_tree_order(tree, pages, aNumberOfRowsDelta = 0) {
- let treeView = tree.view;
- let columns = tree.columns;
- is(columns.count, 1, "There should be only 1 column in the sidebar");
-
- let found = 0;
- for (let i = 0; i < treeView.rowCount; i++) {
- let node = treeView.nodeForTreeIndex(i);
- // We could inherit delayed visits from previous tests, skip them.
- if (!pages.includes(node.uri))
- continue;
- is(node.uri, pages[i], "Node is in correct position based on its visit date");
- found++;
- }
- ok(found, pages.length + aNumberOfRowsDelta, "Found all expected results");
-}
diff --git a/browser/components/places/tests/browser/browser_library_batch_delete.js b/browser/components/places/tests/browser/browser_library_batch_delete.js
deleted file mode 100644
index 6a907c70f..000000000
--- a/browser/components/places/tests/browser/browser_library_batch_delete.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that Library handles correctly batch deletes.
- */
-
-const TEST_URL = "http://www.batch.delete.me/";
-
-var gTests = [];
-var gLibrary;
-
-// ------------------------------------------------------------------------------
-
-gTests.push({
- desc: "Create and batch remove bookmarks",
- run: function() {
- let testURI = makeURI(TEST_URL);
- PlacesUtils.history.runInBatchMode({
- runBatched: function (aUserData) {
- // Create a folder in unserted and populate it with bookmarks.
- let folder = PlacesUtils.bookmarks.createFolder(
- PlacesUtils.unfiledBookmarksFolderId, "deleteme",
- PlacesUtils.bookmarks.DEFAULT_INDEX
- );
- PlacesUtils.bookmarks.createFolder(
- PlacesUtils.unfiledBookmarksFolderId, "keepme",
- PlacesUtils.bookmarks.DEFAULT_INDEX
- );
- for (let i = 0; i < 10; i++) {
- PlacesUtils.bookmarks.insertBookmark(folder,
- testURI,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- "bm" + i);
- }
- }
- }, null);
-
- // Select and open the left pane "History" query.
- let PO = gLibrary.PlacesOrganizer;
- PO.selectLeftPaneQuery("UnfiledBookmarks");
- isnot(PO._places.selectedNode, null, "Selected unsorted bookmarks");
-
- let unsortedNode = PlacesUtils.asContainer(PO._places.selectedNode);
- unsortedNode.containerOpen = true;
- is(unsortedNode.childCount, 2, "Unsorted node has 2 children");
- let folderNode = unsortedNode.getChild(0);
- is(folderNode.title, "deleteme", "Folder found in unsorted bookmarks");
- // Check delete command is available.
- PO._places.selectNode(folderNode);
- is(PO._places.selectedNode.title, "deleteme", "Folder node selected");
- ok(PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is enabled");
- // Execute the delete command and check bookmark has been removed.
- PO._places.controller.doCommand("cmd_delete");
- ok(!PlacesUtils.bookmarks.isBookmarked(testURI),
- "Bookmark has been correctly removed");
- // Test live update.
- is(unsortedNode.childCount, 1, "Unsorted node has 1 child");
- is(PO._places.selectedNode.title, "keepme", "Folder node selected");
- unsortedNode.containerOpen = false;
- nextTest();
- }
-});
-
-// ------------------------------------------------------------------------------
-
-gTests.push({
- desc: "Ensure correct selection and functionality in Library",
- run: function() {
- let PO = gLibrary.PlacesOrganizer;
- let ContentTree = gLibrary.ContentTree;
- // Move selection forth and back.
- PO.selectLeftPaneQuery("History");
- PO.selectLeftPaneQuery("UnfiledBookmarks");
- // Now select the "keepme" folder in the right pane and delete it.
- ContentTree.view.selectNode(ContentTree.view.result.root.getChild(0));
- is(ContentTree.view.selectedNode.title, "keepme",
- "Found folder in content pane");
- // Test live update.
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- makeURI(TEST_URL),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- "bm");
- is(ContentTree.view.result.root.childCount, 2,
- "Right pane was correctly updated");
- nextTest();
- }
-});
-
-// ------------------------------------------------------------------------------
-
-function test() {
- waitForExplicitFinish();
- registerCleanupFunction(function () {
- PlacesUtils.bookmarks
- .removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- });
-
- gLibrary = openLibrary(nextTest);
-}
-
-function nextTest() {
- if (gTests.length) {
- var test = gTests.shift();
- info("Start of test: " + test.desc);
- test.run();
- }
- else {
- // Close Library window.
- gLibrary.close();
- finish();
- }
-}
diff --git a/browser/components/places/tests/browser/browser_library_commands.js b/browser/components/places/tests/browser/browser_library_commands.js
deleted file mode 100644
index e3bb75a34..000000000
--- a/browser/components/places/tests/browser/browser_library_commands.js
+++ /dev/null
@@ -1,235 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Test enabled commands in the left pane folder of the Library.
- */
-
-const TEST_URI = NetUtil.newURI("http://www.mozilla.org/");
-
-registerCleanupFunction(function* () {
- yield PlacesUtils.bookmarks.eraseEverything();
- yield PlacesTestUtils.clearHistory();
-});
-
-add_task(function* test_date_container() {
- let library = yield promiseLibrary();
- info("Ensure date containers under History cannot be cut but can be deleted");
-
- yield PlacesTestUtils.addVisits(TEST_URI);
-
- // Select and open the left pane "History" query.
- let PO = library.PlacesOrganizer;
-
- PO.selectLeftPaneQuery('History');
- isnot(PO._places.selectedNode, null, "We correctly selected History");
-
- // Check that both delete and cut commands are disabled, cause this is
- // a child of the left pane folder.
- ok(PO._places.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
- "Cut command is disabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is disabled");
- let historyNode = PlacesUtils.asContainer(PO._places.selectedNode);
- historyNode.containerOpen = true;
-
- // Check that we have a child container. It is "Today" container.
- is(historyNode.childCount, 1, "History node has one child");
- let todayNode = historyNode.getChild(0);
- let todayNodeExpectedTitle = PlacesUtils.getString("finduri-AgeInDays-is-0");
- is(todayNode.title, todayNodeExpectedTitle,
- "History child is the expected container");
-
- // Select "Today" container.
- PO._places.selectNode(todayNode);
- is(PO._places.selectedNode, todayNode,
- "We correctly selected Today container");
- // Check that delete command is enabled but cut command is disabled, cause
- // this is an history item.
- ok(PO._places.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
- "Cut command is disabled");
- ok(PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is enabled");
-
- // Execute the delete command and check visit has been removed.
- let promiseURIRemoved = promiseHistoryNotification("onDeleteURI",
- v => TEST_URI.equals(v));
- PO._places.controller.doCommand("cmd_delete");
- yield promiseURIRemoved;
-
- // Test live update of "History" query.
- is(historyNode.childCount, 0, "History node has no more children");
-
- historyNode.containerOpen = false;
-
- ok(!(yield promiseIsURIVisited(TEST_URI)), "Visit has been removed");
-
- library.close();
-});
-
-add_task(function* test_query_on_toolbar() {
- let library = yield promiseLibrary();
- info("Ensure queries can be cut or deleted");
-
- // Select and open the left pane "Bookmarks Toolbar" folder.
- let PO = library.PlacesOrganizer;
-
- PO.selectLeftPaneQuery('BookmarksToolbar');
- isnot(PO._places.selectedNode, null, "We have a valid selection");
- is(PlacesUtils.getConcreteItemId(PO._places.selectedNode),
- PlacesUtils.toolbarFolderId,
- "We have correctly selected bookmarks toolbar node.");
-
- // Check that both cut and delete commands are disabled, cause this is a child
- // of AllBookmarksFolderId.
- ok(PO._places.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
- "Cut command is disabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is disabled");
-
- let toolbarNode = PlacesUtils.asContainer(PO._places.selectedNode);
- toolbarNode.containerOpen = true;
-
- // Add an History query to the toolbar.
- let query = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "place:sort=4",
- title: "special_query",
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0 });
-
- // Get first child and check it is the just inserted query.
- ok(toolbarNode.childCount > 0, "Toolbar node has children");
- let queryNode = toolbarNode.getChild(0);
- is(queryNode.title, "special_query", "Query node is correctly selected");
-
- // Select query node.
- PO._places.selectNode(queryNode);
- is(PO._places.selectedNode, queryNode, "We correctly selected query node");
-
- // Check that both cut and delete commands are enabled.
- ok(PO._places.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(PO._places.controller.isCommandEnabled("cmd_cut"),
- "Cut command is enabled");
- ok(PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is enabled");
-
- // Execute the delete command and check bookmark has been removed.
- let promiseItemRemoved = promiseBookmarksNotification("onItemRemoved",
- (...args) => query.guid == args[5]);
- PO._places.controller.doCommand("cmd_delete");
- yield promiseItemRemoved;
-
- is((yield PlacesUtils.bookmarks.fetch(query.guid)), null,
- "Query node bookmark has been correctly removed");
-
- toolbarNode.containerOpen = false;
-
- library.close();
-});
-
-add_task(function* test_search_contents() {
- yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "http://example.com/",
- title: "example page",
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: 0 });
-
- let library = yield promiseLibrary();
- info("Ensure query contents can be cut or deleted");
-
- // Select and open the left pane "Bookmarks Toolbar" folder.
- let PO = library.PlacesOrganizer;
-
- PO.selectLeftPaneQuery('BookmarksToolbar');
- isnot(PO._places.selectedNode, null, "We have a valid selection");
- is(PlacesUtils.getConcreteItemId(PO._places.selectedNode),
- PlacesUtils.toolbarFolderId,
- "We have correctly selected bookmarks toolbar node.");
-
- let searchBox = library.document.getElementById("searchFilter");
- searchBox.value = "example";
- library.PlacesSearchBox.search(searchBox.value);
-
- let bookmarkNode = library.ContentTree.view.selectedNode;
- is(bookmarkNode.uri, "http://example.com/", "Found the expected bookmark");
-
- // Check that both cut and delete commands are enabled.
- ok(library.ContentTree.view.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(library.ContentTree.view.controller.isCommandEnabled("cmd_cut"),
- "Cut command is enabled");
- ok(library.ContentTree.view.controller.isCommandEnabled("cmd_delete"),
- "Delete command is enabled");
-
- library.close();
-});
-
-add_task(function* test_tags() {
- yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "http://example.com/",
- title: "example page",
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: 0 });
- PlacesUtils.tagging.tagURI(NetUtil.newURI("http://example.com/"), ["test"]);
-
- let library = yield promiseLibrary();
- info("Ensure query contents can be cut or deleted");
-
- // Select and open the left pane "Bookmarks Toolbar" folder.
- let PO = library.PlacesOrganizer;
-
- PO.selectLeftPaneQuery('Tags');
- let tagsNode = PO._places.selectedNode;
- isnot(tagsNode, null, "We have a valid selection");
- let tagsTitle = PlacesUtils.getString("TagsFolderTitle");
- is(tagsNode.title, tagsTitle,
- "Tags has been properly selected");
-
- // Check that both cut and delete commands are disabled.
- ok(PO._places.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
- "Cut command is disabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is disabled");
-
- // Now select the tag.
- PlacesUtils.asContainer(tagsNode).containerOpen = true;
- let tag = tagsNode.getChild(0);
- PO._places.selectNode(tag);
- is(PO._places.selectedNode.title, "test",
- "The created tag has been properly selected");
-
- // Check that cut is disabled but delete is enabled.
- ok(PO._places.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(!PO._places.controller.isCommandEnabled("cmd_cut"),
- "Cut command is disabled");
- ok(PO._places.controller.isCommandEnabled("cmd_delete"),
- "Delete command is enabled");
-
- let bookmarkNode = library.ContentTree.view.selectedNode;
- is(bookmarkNode.uri, "http://example.com/", "Found the expected bookmark");
-
- // Check that both cut and delete commands are enabled.
- ok(library.ContentTree.view.controller.isCommandEnabled("cmd_copy"),
- "Copy command is enabled");
- ok(!library.ContentTree.view.controller.isCommandEnabled("cmd_cut"),
- "Cut command is disabled");
- ok(library.ContentTree.view.controller.isCommandEnabled("cmd_delete"),
- "Delete command is enabled");
-
- tagsNode.containerOpen = false;
-
- library.close();
-});
diff --git a/browser/components/places/tests/browser/browser_library_downloads.js b/browser/components/places/tests/browser/browser_library_downloads.js
deleted file mode 100644
index 81daadd71..000000000
--- a/browser/components/places/tests/browser/browser_library_downloads.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Tests bug 564900: Add folder specifically for downloads to Library left pane.
- * https://bugzilla.mozilla.org/show_bug.cgi?id=564900
- * This test visits various pages then opens the Library and ensures
- * that both the Downloads folder shows up and that the correct visits
- * are shown in it.
- */
-
-var now = Date.now();
-
-function test() {
- waitForExplicitFinish();
-
- let onLibraryReady = function(win) {
- // Add visits to compare contents with.
- let places = [
- { uri: NetUtil.newURI("http://mozilla.com"),
- visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_TYPED) ]
- },
- { uri: NetUtil.newURI("http://google.com"),
- visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_DOWNLOAD) ]
- },
- { uri: NetUtil.newURI("http://en.wikipedia.org"),
- visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_TYPED) ]
- },
- { uri: NetUtil.newURI("http://ubuntu.org"),
- visits: [ new VisitInfo(PlacesUtils.history.TRANSITION_DOWNLOAD) ]
- },
- ]
- PlacesUtils.asyncHistory.updatePlaces(places, {
- handleResult: function () {},
- handleError: function () {
- ok(false, "gHistory.updatePlaces() failed");
- },
- handleCompletion: function () {
- // Make sure Downloads is present.
- isnot(win.PlacesOrganizer._places.selectedNode, null,
- "Downloads is present and selected");
-
-
- // Check results.
- let contentRoot = win.ContentArea.currentView.result.root;
- let len = contentRoot.childCount;
- const TEST_URIS = ["http://ubuntu.org/", "http://google.com/"];
- for (let i = 0; i < len; i++) {
- is(contentRoot.getChild(i).uri, TEST_URIS[i],
- "Comparing downloads shown at index " + i);
- }
-
- win.close();
- PlacesTestUtils.clearHistory().then(finish);
- }
- })
- }
-
- openLibrary(onLibraryReady, "Downloads");
-}
-
-function VisitInfo(aTransitionType)
-{
- this.transitionType =
- aTransitionType === undefined ?
- PlacesUtils.history.TRANSITION_LINK : aTransitionType;
- this.visitDate = now++ * 1000;
-}
-VisitInfo.prototype = {}
diff --git a/browser/components/places/tests/browser/browser_library_infoBox.js b/browser/components/places/tests/browser/browser_library_infoBox.js
deleted file mode 100644
index 17cd78f8c..000000000
--- a/browser/components/places/tests/browser/browser_library_infoBox.js
+++ /dev/null
@@ -1,197 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Test appropriate visibility of infoBoxExpanderWrapper and
- * additionalInfoFields in infoBox section of library
- */
-
-const TEST_URI = "http://www.mozilla.org/";
-
-var gTests = [];
-var gLibrary;
-
-// ------------------------------------------------------------------------------
-
-gTests.push({
- desc: "Bug 430148 - Remove or hide the more/less button in details pane...",
- run: function() {
- var PO = gLibrary.PlacesOrganizer;
- let ContentTree = gLibrary.ContentTree;
- var infoBoxExpanderWrapper = getAndCheckElmtById("infoBoxExpanderWrapper");
-
- function addVisitsCallback() {
- // open all bookmarks node
- PO.selectLeftPaneQuery("AllBookmarks");
- isnot(PO._places.selectedNode, null,
- "Correctly selected all bookmarks node.");
- checkInfoBoxSelected(PO);
- ok(infoBoxExpanderWrapper.hidden,
- "Expander button is hidden for all bookmarks node.");
- checkAddInfoFieldsCollapsed(PO);
-
- // open history node
- PO.selectLeftPaneQuery("History");
- isnot(PO._places.selectedNode, null, "Correctly selected history node.");
- checkInfoBoxSelected(PO);
- ok(infoBoxExpanderWrapper.hidden,
- "Expander button is hidden for history node.");
- checkAddInfoFieldsCollapsed(PO);
-
- // open history child node
- var historyNode = PO._places.selectedNode.
- QueryInterface(Ci.nsINavHistoryContainerResultNode);
- historyNode.containerOpen = true;
- var childNode = historyNode.getChild(0);
- isnot(childNode, null, "History node first child is not null.");
- PO._places.selectNode(childNode);
- checkInfoBoxSelected(PO);
- ok(infoBoxExpanderWrapper.hidden,
- "Expander button is hidden for history child node.");
- checkAddInfoFieldsCollapsed(PO);
-
- // open history item
- var view = ContentTree.view.view;
- ok(view.rowCount > 0, "History item exists.");
- view.selection.select(0);
- ok(infoBoxExpanderWrapper.hidden,
- "Expander button is hidden for history item.");
- checkAddInfoFieldsCollapsed(PO);
-
- historyNode.containerOpen = false;
-
- // open bookmarks menu node
- PO.selectLeftPaneQuery("BookmarksMenu");
- isnot(PO._places.selectedNode, null,
- "Correctly selected bookmarks menu node.");
- checkInfoBoxSelected(PO);
- ok(infoBoxExpanderWrapper.hidden,
- "Expander button is hidden for bookmarks menu node.");
- checkAddInfoFieldsCollapsed(PO);
-
- // open recently bookmarked node
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarksMenuFolderId,
- NetUtil.newURI("place:folder=BOOKMARKS_MENU" +
- "&folder=UNFILED_BOOKMARKS" +
- "&folder=TOOLBAR" +
- "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
- "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
- "&maxResults=10" +
- "&excludeQueries=1"),
- 0, "Recent Bookmarks");
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarksMenuFolderId,
- NetUtil.newURI("http://mozilla.org/"),
- 1, "Mozilla");
- var menuNode = PO._places.selectedNode.
- QueryInterface(Ci.nsINavHistoryContainerResultNode);
- menuNode.containerOpen = true;
- childNode = menuNode.getChild(0);
- isnot(childNode, null, "Bookmarks menu child node exists.");
- is(childNode.title, "Recent Bookmarks",
- "Correctly selected recently bookmarked node.");
- PO._places.selectNode(childNode);
- checkInfoBoxSelected(PO);
- ok(!infoBoxExpanderWrapper.hidden,
- "Expander button is not hidden for recently bookmarked node.");
- checkAddInfoFieldsNotCollapsed(PO);
-
- // open first bookmark
- view = ContentTree.view.view;
- ok(view.rowCount > 0, "Bookmark item exists.");
- view.selection.select(0);
- checkInfoBoxSelected(PO);
- ok(!infoBoxExpanderWrapper.hidden,
- "Expander button is not hidden for bookmark item.");
- checkAddInfoFieldsNotCollapsed(PO);
- checkAddInfoFields(PO, "bookmark item");
-
- menuNode.containerOpen = false;
-
- PlacesTestUtils.clearHistory().then(nextTest);
- }
- // add a visit to browser history
- PlacesTestUtils.addVisits(
- { uri: PlacesUtils._uri(TEST_URI), visitDate: Date.now() * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED }
- ).then(addVisitsCallback);
- }
-});
-
-function checkInfoBoxSelected(PO) {
- is(getAndCheckElmtById("detailsDeck").selectedIndex, 1,
- "Selected element in detailsDeck is infoBox.");
-}
-
-function checkAddInfoFieldsCollapsed(PO) {
- PO._additionalInfoFields.forEach(function (id) {
- ok(getAndCheckElmtById(id).collapsed,
- "Additional info field correctly collapsed: #" + id);
- });
-}
-
-function checkAddInfoFieldsNotCollapsed(PO) {
- ok(PO._additionalInfoFields.some(function (id) {
- return !getAndCheckElmtById(id).collapsed;
- }), "Some additional info field correctly not collapsed");
-}
-
-function checkAddInfoFields(PO, nodeName) {
- ok(true, "Checking additional info fields visibiity for node: " + nodeName);
- var expanderButton = getAndCheckElmtById("infoBoxExpander");
-
- // make sure additional fields are hidden by default
- PO._additionalInfoFields.forEach(function (id) {
- ok(getAndCheckElmtById(id).hidden,
- "Additional info field correctly hidden by default: #" + id);
- });
-
- // toggle fields and make sure they are hidden/unhidden as expected
- expanderButton.click();
- PO._additionalInfoFields.forEach(function (id) {
- ok(!getAndCheckElmtById(id).hidden,
- "Additional info field correctly unhidden after toggle: #" + id);
- });
- expanderButton.click();
- PO._additionalInfoFields.forEach(function (id) {
- ok(getAndCheckElmtById(id).hidden,
- "Additional info field correctly hidden after toggle: #" + id);
- });
-}
-
-function getAndCheckElmtById(id) {
- var elmt = gLibrary.document.getElementById(id);
- isnot(elmt, null, "Correctly got element: #" + id);
- return elmt;
-}
-
-// ------------------------------------------------------------------------------
-
-function nextTest() {
- if (gTests.length) {
- var test = gTests.shift();
- ok(true, "TEST: " + test.desc);
- dump("TEST: " + test.desc + "\n");
- test.run();
- }
- else {
- // Close Library window.
- gLibrary.close();
- // No need to cleanup anything, we have a correct left pane now.
- finish();
- }
-}
-
-function test() {
- waitForExplicitFinish();
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils is running in chrome context");
- ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
-
- // Open Library.
- openLibrary(function (library) {
- gLibrary = library;
- gLibrary.PlacesOrganizer._places.focus();
- nextTest(gLibrary);
- });
-}
diff --git a/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js b/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
deleted file mode 100644
index 7cea38f20..000000000
--- a/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Test we correctly fix broken Library left pane queries names.
- */
-
-// Array of left pane queries objects, each one has the following properties:
-// name: query's identifier got from annotations,
-// itemId: query's itemId,
-// correctTitle: original and correct query's title.
-var leftPaneQueries = [];
-
-function onLibraryReady(organizer) {
- // Check titles have been fixed.
- for (var i = 0; i < leftPaneQueries.length; i++) {
- var query = leftPaneQueries[i];
- is(PlacesUtils.bookmarks.getItemTitle(query.itemId),
- query.correctTitle, "Title is correct for query " + query.name);
- if ("concreteId" in query) {
- is(PlacesUtils.bookmarks.getItemTitle(query.concreteId),
- query.concreteTitle, "Concrete title is correct for query " + query.name);
- }
- }
-
- // Close Library window.
- organizer.close();
- // No need to cleanup anything, we have a correct left pane now.
- finish();
-}
-
-function test() {
- waitForExplicitFinish();
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils is running in chrome context");
- ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
- ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0,
- "Left pane version in chrome context, current version is: " + PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION );
-
- // Ensure left pane is initialized.
- ok(PlacesUIUtils.leftPaneFolderId > 0, "left pane folder is initialized");
-
- // Get the left pane folder.
- var leftPaneItems = PlacesUtils.annotations
- .getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
-
- is(leftPaneItems.length, 1, "We correctly have only 1 left pane folder");
- // Check version.
- var version = PlacesUtils.annotations
- .getItemAnnotation(leftPaneItems[0],
- PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION, "Left pane version is actual");
-
- // Get all left pane queries.
- var items = PlacesUtils.annotations
- .getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_QUERY_ANNO);
- // Get current queries names.
- for (var i = 0; i < items.length; i++) {
- var itemId = items[i];
- var queryName = PlacesUtils.annotations
- .getItemAnnotation(items[i],
- PlacesUIUtils.ORGANIZER_QUERY_ANNO);
- var query = { name: queryName,
- itemId: itemId,
- correctTitle: PlacesUtils.bookmarks.getItemTitle(itemId) }
- switch (queryName) {
- case "BookmarksToolbar":
- query.concreteId = PlacesUtils.toolbarFolderId;
- query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
- break;
- case "BookmarksMenu":
- query.concreteId = PlacesUtils.bookmarksMenuFolderId;
- query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
- break;
- case "UnfiledBookmarks":
- query.concreteId = PlacesUtils.unfiledBookmarksFolderId;
- query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
- break;
- }
- leftPaneQueries.push(query);
- // Rename to a bad title.
- PlacesUtils.bookmarks.setItemTitle(query.itemId, "badName");
- if ("concreteId" in query)
- PlacesUtils.bookmarks.setItemTitle(query.concreteId, "badName");
- }
-
- PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter);
-
- // Open Library, this will kick-off left pane code.
- openLibrary(onLibraryReady);
-}
diff --git a/browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js b/browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js
deleted file mode 100644
index b90df120c..000000000
--- a/browser/components/places/tests/browser/browser_library_left_pane_select_hierarchy.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-function test() {
- waitForExplicitFinish();
- openLibrary(onLibraryReady);
-}
-
-function onLibraryReady(aLibrary) {
- let hierarchy = [ "AllBookmarks", "BookmarksMenu" ];
-
- let folder1 = PlacesUtils.bookmarks
- .createFolder(PlacesUtils.bookmarksMenuFolderId,
- "Folder 1",
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- hierarchy.push(folder1);
- let folder2 = PlacesUtils.bookmarks
- .createFolder(folder1, "Folder 2",
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- hierarchy.push(folder2);
- let bookmark = PlacesUtils.bookmarks
- .insertBookmark(folder2, NetUtil.newURI("http://example.com/"),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- "Bookmark");
-
- registerCleanupFunction(function() {
- PlacesUtils.bookmarks.removeItem(folder1);
- aLibrary.close();
- });
-
- aLibrary.PlacesOrganizer.selectLeftPaneContainerByHierarchy(hierarchy);
-
- is(aLibrary.PlacesOrganizer._places.selectedNode.itemId, folder2,
- "Found the expected left pane selected node");
-
- is(aLibrary.ContentTree.view.view.nodeForTreeIndex(0).itemId, bookmark,
- "Found the expected right pane contents");
-
- finish();
-}
diff --git a/browser/components/places/tests/browser/browser_library_middleclick.js b/browser/components/places/tests/browser/browser_library_middleclick.js
deleted file mode 100644
index 894f89446..000000000
--- a/browser/components/places/tests/browser/browser_library_middleclick.js
+++ /dev/null
@@ -1,279 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
- /**
- * Tests middle-clicking items in the Library.
- */
-
-const ENABLE_HISTORY_PREF = "places.history.enabled";
-
-var gLibrary = null;
-var gTests = [];
-var gCurrentTest = null;
-
-// Listener for TabOpen and tabs progress.
-var gTabsListener = {
- _loadedURIs: [],
- _openTabsCount: 0,
-
- handleEvent: function(aEvent) {
- if (aEvent.type != "TabOpen")
- return;
-
- if (++this._openTabsCount == gCurrentTest.URIs.length) {
- is(gBrowser.tabs.length, gCurrentTest.URIs.length + 1,
- "We have opened " + gCurrentTest.URIs.length + " new tab(s)");
- }
-
- var tab = aEvent.target;
- is(tab.ownerGlobal, window,
- "Tab has been opened in current browser window");
- },
-
- onLocationChange: function(aBrowser, aWebProgress, aRequest, aLocationURI,
- aFlags) {
- var spec = aLocationURI.spec;
- ok(true, spec);
- // When a new tab is opened, location is first set to "about:blank", so
- // we can ignore those calls.
- // Ignore multiple notifications for the same URI too.
- if (spec == "about:blank" || this._loadedURIs.includes(spec))
- return;
-
- ok(gCurrentTest.URIs.includes(spec),
- "Opened URI found in list: " + spec);
-
- if (gCurrentTest.URIs.includes(spec))
- this._loadedURIs.push(spec);
-
- if (this._loadedURIs.length == gCurrentTest.URIs.length) {
- // We have correctly opened all URIs.
-
- // Reset arrays.
- this._loadedURIs.length = 0;
-
- this._openTabsCount = 0;
-
- executeSoon(function () {
- // Close all tabs.
- while (gBrowser.tabs.length > 1)
- gBrowser.removeCurrentTab();
-
- // Test finished. This will move to the next one.
- waitForFocus(gCurrentTest.finish, gBrowser.ownerGlobal);
- });
- }
- }
-}
-
-// ------------------------------------------------------------------------------
-// Open bookmark in a new tab.
-
-gTests.push({
- desc: "Open bookmark in a new tab.",
- URIs: ["about:buildconfig"],
- _itemId: -1,
-
- setup: function() {
- var bs = PlacesUtils.bookmarks;
- // Add a new unsorted bookmark.
- this._itemId = bs.insertBookmark(bs.unfiledBookmarksFolder,
- PlacesUtils._uri(this.URIs[0]),
- bs.DEFAULT_INDEX,
- "Title");
- // Select unsorted bookmarks root in the left pane.
- gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
- "We correctly have selection in the Library left pane");
- // Get our bookmark in the right pane.
- var bookmarkNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
- is(bookmarkNode.uri, this.URIs[0], "Found bookmark in the right pane");
- },
-
- finish: function() {
- setTimeout(runNextTest, 0);
- },
-
- cleanup: function() {
- PlacesUtils.bookmarks.removeItem(this._itemId);
- }
-});
-
-// ------------------------------------------------------------------------------
-// Open a folder in tabs.
-
-gTests.push({
- desc: "Open a folder in tabs.",
- URIs: ["about:buildconfig", "about:"],
- _folderId: -1,
-
- setup: function() {
- var bs = PlacesUtils.bookmarks;
- // Create a new folder.
- var folderId = bs.createFolder(bs.unfiledBookmarksFolder,
- "Folder",
- bs.DEFAULT_INDEX);
- this._folderId = folderId;
-
- // Add bookmarks in folder.
- this.URIs.forEach(function(aURI) {
- bs.insertBookmark(folderId,
- PlacesUtils._uri(aURI),
- bs.DEFAULT_INDEX,
- "Title");
- });
-
- // Select unsorted bookmarks root in the left pane.
- gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
- "We correctly have selection in the Library left pane");
- // Get our bookmark in the right pane.
- var folderNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
- is(folderNode.title, "Folder", "Found folder in the right pane");
- },
-
- finish: function() {
- setTimeout(runNextTest, 0);
- },
-
- cleanup: function() {
- PlacesUtils.bookmarks.removeItem(this._folderId);
- }
-});
-
-// ------------------------------------------------------------------------------
-// Open a query in tabs.
-
-gTests.push({
- desc: "Open a query in tabs.",
- URIs: ["about:buildconfig", "about:"],
- _folderId: -1,
- _queryId: -1,
-
- setup: function() {
- var bs = PlacesUtils.bookmarks;
- // Create a new folder.
- var folderId = bs.createFolder(bs.unfiledBookmarksFolder,
- "Folder",
- bs.DEFAULT_INDEX);
- this._folderId = folderId;
-
- // Add bookmarks in folder.
- this.URIs.forEach(function(aURI) {
- bs.insertBookmark(folderId,
- PlacesUtils._uri(aURI),
- bs.DEFAULT_INDEX,
- "Title");
- });
-
- // Create a bookmarks query containing our bookmarks.
- var hs = PlacesUtils.history;
- var options = hs.getNewQueryOptions();
- options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
- var query = hs.getNewQuery();
- // The colon included in the terms selects only about: URIs. If not included
- // we also may get pages like about.html included in the query result.
- query.searchTerms = "about:";
- var queryString = hs.queriesToQueryString([query], 1, options);
- this._queryId = bs.insertBookmark(bs.unfiledBookmarksFolder,
- PlacesUtils._uri(queryString),
- 0, // It must be the first.
- "Query");
-
- // Select unsorted bookmarks root in the left pane.
- gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
- "We correctly have selection in the Library left pane");
- // Get our bookmark in the right pane.
- var folderNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
- is(folderNode.title, "Query", "Found query in the right pane");
- },
-
- finish: function() {
- setTimeout(runNextTest, 0);
- },
-
- cleanup: function() {
- PlacesUtils.bookmarks.removeItem(this._folderId);
- PlacesUtils.bookmarks.removeItem(this._queryId);
- }
-});
-
-// ------------------------------------------------------------------------------
-
-function test() {
- waitForExplicitFinish();
- // Increase timeout, this test can be quite slow due to waitForFocus calls.
- requestLongerTimeout(2);
-
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils in context");
- ok(PlacesUIUtils, "PlacesUIUtils in context");
-
- // Add tabs listeners.
- gBrowser.tabContainer.addEventListener("TabOpen", gTabsListener, false);
- gBrowser.addTabsProgressListener(gTabsListener);
-
- // Temporary disable history, so we won't record pages navigation.
- gPrefService.setBoolPref(ENABLE_HISTORY_PREF, false);
-
- // Open Library window.
- openLibrary(function (library) {
- gLibrary = library;
- // Kick off tests.
- runNextTest();
- });
-}
-
-function runNextTest() {
- // Cleanup from previous test.
- if (gCurrentTest)
- gCurrentTest.cleanup();
-
- if (gTests.length > 0) {
- // Goto next test.
- gCurrentTest = gTests.shift();
- info("Start of test: " + gCurrentTest.desc);
- // Test setup will set Library so that the bookmark to be opened is the
- // first node in the content (right pane) tree.
- gCurrentTest.setup();
-
- // Middle click on first node in the content tree of the Library.
- gLibrary.focus();
- waitForFocus(function() {
- mouseEventOnCell(gLibrary.ContentTree.view, 0, 0, { button: 1 });
- }, gLibrary);
- }
- else {
- // No more tests.
-
- // Close Library window.
- gLibrary.close();
-
- // Remove tabs listeners.
- gBrowser.tabContainer.removeEventListener("TabOpen", gTabsListener, false);
- gBrowser.removeTabsProgressListener(gTabsListener);
-
- // Restore history.
- try {
- gPrefService.clearUserPref(ENABLE_HISTORY_PREF);
- } catch (ex) {}
-
- finish();
- }
-}
-
-function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
- var selection = aTree.view.selection;
- selection.select(aRowIndex);
- aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
- var column = aTree.columns[aColumnIndex];
-
- // get cell coordinates
- var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
-
- EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
- aEventDetails, gLibrary);
-}
diff --git a/browser/components/places/tests/browser/browser_library_openFlatContainer.js b/browser/components/places/tests/browser/browser_library_openFlatContainer.js
deleted file mode 100644
index 167b33031..000000000
--- a/browser/components/places/tests/browser/browser_library_openFlatContainer.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/**
- * Test opening a flat container in the right pane even if its parent in the
- * left pane is closed.
- */
-
-add_task(function* () {
- let folder = PlacesUtils.bookmarks
- .createFolder(PlacesUtils.unfiledBookmarksFolderId,
- "Folder",
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- let bookmark = PlacesUtils.bookmarks
- .insertBookmark(folder, NetUtil.newURI("http://example.com/"),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- "Bookmark");
-
- let library = yield promiseLibrary("AllBookmarks");
- registerCleanupFunction(function () {
- library.close();
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- });
-
- // Select unfiled later, to ensure it's closed.
- library.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
- ok(!library.PlacesOrganizer._places.selectedNode.containerOpen,
- "Unfiled container is closed");
-
- let folderNode = library.ContentTree.view.view.nodeForTreeIndex(0);
- is(folderNode.itemId, folder,
- "Found the expected folder in the right pane");
- // Select the folder node in the right pane.
- library.ContentTree.view.selectNode(folderNode);
-
- synthesizeClickOnSelectedTreeCell(library.ContentTree.view,
- { clickCount: 2 });
-
- is(library.ContentTree.view.view.nodeForTreeIndex(0).itemId, bookmark,
- "Found the expected bookmark in the right pane");
-});
diff --git a/browser/components/places/tests/browser/browser_library_open_leak.js b/browser/components/places/tests/browser/browser_library_open_leak.js
deleted file mode 100644
index f002236a9..000000000
--- a/browser/components/places/tests/browser/browser_library_open_leak.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Bug 474831
- * https://bugzilla.mozilla.org/show_bug.cgi?id=474831
- *
- * Tests for leaks caused by simply opening and closing the Places Library
- * window. Opens the Places Library window, waits for it to load, closes it,
- * and finishes.
- */
-
-function test() {
- waitForExplicitFinish();
- openLibrary(function (win) {
- ok(true, "Library has been correctly opened");
- win.close();
- finish();
- });
-}
diff --git a/browser/components/places/tests/browser/browser_library_panel_leak.js b/browser/components/places/tests/browser/browser_library_panel_leak.js
deleted file mode 100644
index 643a261fb..000000000
--- a/browser/components/places/tests/browser/browser_library_panel_leak.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Bug 433231 - Places Library leaks the nsGlobalWindow when closed with a
- * history entry selected.
- * https://bugzilla.mozilla.org/show_bug.cgi?id=433231
- *
- * STRs: Open Library, select an history entry in History, close Library.
- * ISSUE: We were adding a bookmarks observer when editing a bookmark, when
- * selecting an history entry the panel was not un-initialized, and
- * since an histroy entry does not have an itemId, the observer was
- * never removed.
- */
-
-const TEST_URI = "http://www.mozilla.org/";
-
-function test() {
- function onLibraryReady(organizer) {
- let contentTree = organizer.document.getElementById("placeContent");
- isnot(contentTree, null, "Sanity check: placeContent tree should exist");
- isnot(organizer.PlacesOrganizer, null, "Sanity check: PlacesOrganizer should exist");
- isnot(organizer.gEditItemOverlay, null, "Sanity check: gEditItemOverlay should exist");
-
- ok(organizer.gEditItemOverlay.initialized, "gEditItemOverlay is initialized");
- isnot(organizer.gEditItemOverlay.itemId, -1, "Editing a bookmark");
-
- // Select History in the left pane.
- organizer.PlacesOrganizer.selectLeftPaneQuery('History');
- // Select the first history entry.
- let selection = contentTree.view.selection;
- selection.clearSelection();
- selection.rangedSelect(0, 0, true);
- // Check the panel is editing the history entry.
- is(organizer.gEditItemOverlay.itemId, -1, "Editing an history entry");
- // Close Library window.
- organizer.close();
- // Clean up history.
- PlacesTestUtils.clearHistory().then(finish);
- }
-
- waitForExplicitFinish();
- // Add an history entry.
- ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
- PlacesTestUtils.addVisits(
- {uri: PlacesUtils._uri(TEST_URI), visitDate: Date.now() * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED}
- ).then(() => {
- openLibrary(onLibraryReady);
- });
-}
diff --git a/browser/components/places/tests/browser/browser_library_search.js b/browser/components/places/tests/browser/browser_library_search.js
deleted file mode 100644
index 93af22363..000000000
--- a/browser/components/places/tests/browser/browser_library_search.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Bug 451151
- * https://bugzilla.mozilla.org/show_bug.cgi?id=451151
- *
- * Summary:
- * Tests frontend Places Library searching -- search, search reset, search scope
- * consistency.
- *
- * Details:
- * Each test below
- * 1. selects a folder in the left pane and ensures that the content tree is
- * appropriately updated,
- * 2. performs a search and ensures that the content tree is correct for the
- * folder and search and that the search UI is visible and appropriate to
- * folder,
- * 5. resets the search and ensures that the content tree is correct and that
- * the search UI is hidden, and
- * 6. if folder scope was clicked, searches again and ensures folder scope
- * remains selected.
- */
-
-const TEST_URL = "http://dummy.mozilla.org/";
-const TEST_DOWNLOAD_URL = "http://dummy.mozilla.org/dummy.pdf";
-
-var gLibrary;
-
-var testCases = [
- function allBookmarksScope() {
- let defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId);
- search(PlacesUIUtils.allBookmarksFolderId, "dummy", defScope);
- },
-
- function historyScope() {
- let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
- search(PlacesUIUtils.leftPaneQueries["History"], "dummy", defScope);
- },
-
- function downloadsScope() {
- let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["Downloads"]);
- search(PlacesUIUtils.leftPaneQueries["Downloads"], "dummy", defScope);
- },
-];
-
-/**
- * Returns the default search scope for a given folder.
- *
- * @param aFolderId
- * the item ID of a node in the left pane's tree
- * @return the default scope when the folder is newly selected
- */
-function getDefaultScope(aFolderId) {
- switch (aFolderId) {
- case PlacesUIUtils.leftPaneQueries["History"]:
- return "scopeBarHistory"
- case PlacesUIUtils.leftPaneQueries["Downloads"]:
- return "scopeBarDownloads";
- default:
- return "scopeBarAll";
- }
-}
-
-/**
- * Returns the single nsINavHistoryQuery represented by a given place URI.
- *
- * @param aPlaceURI
- * a URI that represents a single query
- * @return an nsINavHistoryQuery object
- */
-function queryStringToQuery(aPlaceURI) {
- let queries = {};
- PlacesUtils.history.queryStringToQueries(aPlaceURI, queries, {}, {});
- return queries.value[0];
-}
-
-/**
- * Resets the search by clearing the search box's text and ensures that the
- * search scope remains as expected.
- *
- * @param aExpectedScopeButtonId
- * this button should be selected after the reset
- */
-function resetSearch(aExpectedScopeButtonId) {
- search(null, "", aExpectedScopeButtonId);
-}
-
-/**
- * Performs a search for a given folder and search string and ensures that the
- * URI of the right pane's content tree is as expected for the folder and search
- * string. Also ensures that the search scope button is as expected after the
- * search.
- *
- * @param aFolderId
- * the item ID of a node in the left pane's tree
- * @param aSearchStr
- * the search text; may be empty to reset the search
- * @param aExpectedScopeButtonId
- * after searching the selected scope button should be this
- */
-function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
- let doc = gLibrary.document;
- let folderTree = doc.getElementById("placesList");
- let contentTree = doc.getElementById("placeContent");
-
- // First, ensure that selecting the folder in the left pane updates the
- // content tree properly.
- if (aFolderId) {
- folderTree.selectItems([aFolderId]);
- isnot(folderTree.selectedNode, null,
- "Sanity check: left pane tree should have selection after selecting!");
-
- // getFolders() on a History query returns an empty array, so no use
- // comparing against aFolderId in that case.
- if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"] &&
- aFolderId !== PlacesUIUtils.leftPaneQueries["Downloads"]) {
- // contentTree.place should be equal to contentTree.result.root.uri,
- // but it's not until bug 476952 is fixed.
- let query = queryStringToQuery(contentTree.result.root.uri);
- is(query.getFolders()[0], aFolderId,
- "Content tree's folder should be what was selected in the left pane");
- }
- }
-
- // Second, ensure that searching updates the content tree and search UI
- // properly.
- let searchBox = doc.getElementById("searchFilter");
- searchBox.value = aSearchStr;
- gLibrary.PlacesSearchBox.search(searchBox.value);
- let query = queryStringToQuery(contentTree.result.root.uri);
- if (aSearchStr) {
- is(query.searchTerms, aSearchStr,
- "Content tree's searchTerms should be text in search box");
- }
- else {
- is(query.hasSearchTerms, false,
- "Content tree's searchTerms should not exist after search reset");
- }
-}
-
-/**
- * test() contains window-launching boilerplate that calls this to really kick
- * things off. Add functions to the testCases array, and this will call them.
- */
-function onLibraryAvailable() {
- testCases.forEach(aTest => aTest());
-
- gLibrary.close();
- gLibrary = null;
-
- // Cleanup.
- PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- PlacesTestUtils.clearHistory().then(finish);
-}
-
-function test() {
- waitForExplicitFinish();
-
- // Sanity:
- ok(PlacesUtils, "PlacesUtils in context");
-
- // Add visits, a bookmark and a tag.
- PlacesTestUtils.addVisits(
- [{ uri: PlacesUtils._uri(TEST_URL), visitDate: Date.now() * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED },
- { uri: PlacesUtils._uri(TEST_DOWNLOAD_URL), visitDate: Date.now() * 1000,
- transition: PlacesUtils.history.TRANSITION_DOWNLOAD }]
- ).then(() => {
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils._uri(TEST_URL),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- "dummy");
- PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
-
- gLibrary = openLibrary(onLibraryAvailable);
- });
-}
diff --git a/browser/components/places/tests/browser/browser_library_views_liveupdate.js b/browser/components/places/tests/browser/browser_library_views_liveupdate.js
deleted file mode 100644
index c78ed641a..000000000
--- a/browser/components/places/tests/browser/browser_library_views_liveupdate.js
+++ /dev/null
@@ -1,300 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests Library Left pane view for liveupdate.
- */
-
-var gLibrary = null;
-
-function test() {
- waitForExplicitFinish();
- // This test takes quite some time, and timeouts frequently, so we require
- // more time to run.
- // See Bug 525610.
- requestLongerTimeout(2);
-
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils in context");
- ok(PlacesUIUtils, "PlacesUIUtils in context");
-
- // Open Library, we will check the left pane.
- openLibrary(function (library) {
- gLibrary = library;
- startTest();
- });
-}
-
-/**
- * Adds bookmarks observer, and executes a bunch of bookmarks operations.
- */
-function startTest() {
- var bs = PlacesUtils.bookmarks;
- // Add observers.
- bs.addObserver(bookmarksObserver, false);
- PlacesUtils.annotations.addObserver(bookmarksObserver, false);
- var addedBookmarks = [];
-
- // MENU
- ok(true, "*** Acting on menu bookmarks");
- var id = bs.insertBookmark(bs.bookmarksMenuFolder,
- PlacesUtils._uri("http://bm1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "bm1");
- addedBookmarks.push(id);
- id = bs.insertBookmark(bs.bookmarksMenuFolder,
- PlacesUtils._uri("place:"),
- bs.DEFAULT_INDEX,
- "bm2");
- bs.setItemTitle(id, "bm2_edited");
- addedBookmarks.push(id);
- id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
- addedBookmarks.push(id);
- id = bs.createFolder(bs.bookmarksMenuFolder,
- "bmf",
- bs.DEFAULT_INDEX);
- bs.setItemTitle(id, "bmf_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(id,
- PlacesUtils._uri("http://bmf1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "bmf1");
- addedBookmarks.push(id);
- bs.moveItem(id, bs.bookmarksMenuFolder, 0);
-
- // TOOLBAR
- ok(true, "*** Acting on toolbar bookmarks");
- bs.insertBookmark(bs.toolbarFolder,
- PlacesUtils._uri("http://tb1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "tb1");
- bs.setItemTitle(id, "tb1_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(bs.toolbarFolder,
- PlacesUtils._uri("place:"),
- bs.DEFAULT_INDEX,
- "tb2");
- bs.setItemTitle(id, "tb2_edited");
- addedBookmarks.push(id);
- id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
- addedBookmarks.push(id);
- id = bs.createFolder(bs.toolbarFolder,
- "tbf",
- bs.DEFAULT_INDEX);
- bs.setItemTitle(id, "tbf_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(id,
- PlacesUtils._uri("http://tbf1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "bmf1");
- addedBookmarks.push(id);
- bs.moveItem(id, bs.toolbarFolder, 0);
-
- // UNSORTED
- ok(true, "*** Acting on unsorted bookmarks");
- id = bs.insertBookmark(bs.unfiledBookmarksFolder,
- PlacesUtils._uri("http://ub1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "ub1");
- bs.setItemTitle(id, "ub1_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(bs.unfiledBookmarksFolder,
- PlacesUtils._uri("place:"),
- bs.DEFAULT_INDEX,
- "ub2");
- bs.setItemTitle(id, "ub2_edited");
- addedBookmarks.push(id);
- id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
- addedBookmarks.push(id);
- id = bs.createFolder(bs.unfiledBookmarksFolder,
- "ubf",
- bs.DEFAULT_INDEX);
- bs.setItemTitle(id, "ubf_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(id,
- PlacesUtils._uri("http://ubf1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "ubf1");
- addedBookmarks.push(id);
- bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
-
- // Remove all added bookmarks.
- addedBookmarks.forEach(function (aItem) {
- // If we remove an item after its containing folder has been removed,
- // this will throw, but we can ignore that.
- try {
- bs.removeItem(aItem);
- } catch (ex) {}
- });
-
- // Remove observers.
- bs.removeObserver(bookmarksObserver);
- PlacesUtils.annotations.removeObserver(bookmarksObserver);
- finishTest();
-}
-
-/**
- * Restores browser state and calls finish.
- */
-function finishTest() {
- // Close Library window.
- gLibrary.close();
- finish();
-}
-
-/**
- * The observer is where magic happens, for every change we do it will look for
- * nodes positions in the affected views.
- */
-var bookmarksObserver = {
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsINavBookmarkObserver
- , Ci.nsIAnnotationObserver
- ]),
-
- // nsIAnnotationObserver
- onItemAnnotationSet: function() {},
- onItemAnnotationRemoved: function() {},
- onPageAnnotationSet: function() {},
- onPageAnnotationRemoved: function() {},
-
- // nsINavBookmarkObserver
- onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex, aItemType,
- aURI) {
- var node = null;
- var index = null;
- [node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
- // Left pane should not be updated for normal bookmarks or separators.
- switch (aItemType) {
- case PlacesUtils.bookmarks.TYPE_BOOKMARK:
- var uriString = aURI.spec;
- var isQuery = uriString.substr(0, 6) == "place:";
- if (isQuery) {
- isnot(node, null, "Found new Places node in left pane");
- ok(index >= 0, "Node is at index " + index);
- break;
- }
- // Fallback to separator case if this is not a query.
- case PlacesUtils.bookmarks.TYPE_SEPARATOR:
- is(node, null, "New Places node not added in left pane");
- break;
- default:
- isnot(node, null, "Found new Places node in left pane");
- ok(index >= 0, "Node is at index " + index);
- }
- },
-
- onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
- var node = null;
- [node, ] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
- is(node, null, "Places node not found in left pane");
- },
-
- onItemMoved: function(aItemId,
- aOldFolderId, aOldIndex,
- aNewFolderId, aNewIndex, aItemType) {
- var node = null;
- var index = null;
- [node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
- // Left pane should not be updated for normal bookmarks or separators.
- switch (aItemType) {
- case PlacesUtils.bookmarks.TYPE_BOOKMARK:
- var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
- var isQuery = uriString.substr(0, 6) == "place:";
- if (isQuery) {
- isnot(node, null, "Found new Places node in left pane");
- ok(index >= 0, "Node is at index " + index);
- break;
- }
- // Fallback to separator case if this is not a query.
- case PlacesUtils.bookmarks.TYPE_SEPARATOR:
- is(node, null, "New Places node not added in left pane");
- break;
- default:
- isnot(node, null, "Found new Places node in left pane");
- ok(index >= 0, "Node is at index " + index);
- }
- },
-
- onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
- onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
- onItemVisited: function() {},
- onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
- aIsAnnotationProperty, aNewValue) {
- if (aProperty == "title") {
- let validator = function(aTreeRowIndex) {
- let tree = gLibrary.PlacesOrganizer._places;
- let cellText = tree.view.getCellText(aTreeRowIndex,
- tree.columns.getColumnAt(0));
- return cellText == aNewValue;
- }
- let [node, , valid] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places, validator);
- if (node) // Only visible nodes.
- ok(valid, "Title cell value has been correctly updated");
- }
- }
-};
-
-
-/**
- * Get places node and index for an itemId in a tree view.
- *
- * @param aItemId
- * item id of the item to search.
- * @param aTree
- * Tree to search in.
- * @param aValidator [optional]
- * function to check row validity if found. Defaults to {return true;}.
- * @returns [node, index, valid] or [null, null, false] if not found.
- */
-function getNodeForTreeItem(aItemId, aTree, aValidator) {
-
- function findNode(aContainerIndex) {
- if (aTree.view.isContainerEmpty(aContainerIndex))
- return [null, null, false];
-
- // The rowCount limit is just for sanity, but we will end looping when
- // we have checked the last child of this container or we have found node.
- for (var i = aContainerIndex + 1; i < aTree.view.rowCount; i++) {
- var node = aTree.view.nodeForTreeIndex(i);
-
- if (node.itemId == aItemId) {
- // Minus one because we want relative index inside the container.
- let valid = aValidator ? aValidator(i) : true;
- return [node, i - aTree.view.getParentIndex(i) - 1, valid];
- }
-
- if (PlacesUtils.nodeIsFolder(node)) {
- // Open container.
- aTree.view.toggleOpenState(i);
- // Search inside it.
- var foundNode = findNode(i);
- // Close container.
- aTree.view.toggleOpenState(i);
- // Return node if found.
- if (foundNode[0] != null)
- return foundNode;
- }
-
- // We have finished walking this container.
- if (!aTree.view.hasNextSibling(aContainerIndex + 1, i))
- break;
- }
- return [null, null, false]
- }
-
- // Root node is hidden, so we need to manually walk the first level.
- for (var i = 0; i < aTree.view.rowCount; i++) {
- // Open container.
- aTree.view.toggleOpenState(i);
- // Search inside it.
- var foundNode = findNode(i);
- // Close container.
- aTree.view.toggleOpenState(i);
- // Return node if found.
- if (foundNode[0] != null)
- return foundNode;
- }
- return [null, null, false];
-}
diff --git a/browser/components/places/tests/browser/browser_markPageAsFollowedLink.js b/browser/components/places/tests/browser/browser_markPageAsFollowedLink.js
deleted file mode 100644
index 02d564e28..000000000
--- a/browser/components/places/tests/browser/browser_markPageAsFollowedLink.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Tests that visits across frames are correctly represented in the database.
- */
-
-const BASE_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser";
-const PAGE_URL = BASE_URL + "/framedPage.html";
-const LEFT_URL = BASE_URL + "/frameLeft.html";
-const RIGHT_URL = BASE_URL + "/frameRight.html";
-
-add_task(function* test() {
- // We must wait for both frames to be loaded and the visits to be registered.
- let deferredLeftFrameVisit = PromiseUtils.defer();
- let deferredRightFrameVisit = PromiseUtils.defer();
-
- Services.obs.addObserver(function observe(subject) {
- Task.spawn(function* () {
- let url = subject.QueryInterface(Ci.nsIURI).spec;
- if (url == LEFT_URL ) {
- is((yield getTransitionForUrl(url)), null,
- "Embed visits should not get a database entry.");
- deferredLeftFrameVisit.resolve();
- }
- else if (url == RIGHT_URL ) {
- is((yield getTransitionForUrl(url)),
- PlacesUtils.history.TRANSITION_FRAMED_LINK,
- "User activated visits should get a FRAMED_LINK transition.");
- Services.obs.removeObserver(observe, "uri-visit-saved");
- deferredRightFrameVisit.resolve();
- }
- });
- }, "uri-visit-saved", false);
-
- // Open a tab and wait for all the subframes to load.
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE_URL);
-
- // Wait for the left frame visit to be registered.
- info("Waiting left frame visit");
- yield deferredLeftFrameVisit.promise;
-
- // Click on the link in the left frame to cause a page load in the
- // right frame.
- info("Clicking link");
- yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
- content.frames[0].document.getElementById("clickme").click();
- });
-
- // Wait for the right frame visit to be registered.
- info("Waiting right frame visit");
- yield deferredRightFrameVisit.promise;
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-function* getTransitionForUrl(url) {
- // Ensure all the transactions completed.
- yield PlacesTestUtils.promiseAsyncUpdates();
- let db = yield PlacesUtils.promiseDBConnection();
- let rows = yield db.execute(`
- SELECT visit_type
- FROM moz_historyvisits
- JOIN moz_places h ON place_id = h.id
- WHERE url_hash = hash(:url) AND url = :url`,
- { url });
- if (rows.length) {
- return rows[0].getResultByName("visit_type");
- }
- return null;
-}
diff --git a/browser/components/places/tests/browser/browser_sidebarpanels_click.js b/browser/components/places/tests/browser/browser_sidebarpanels_click.js
deleted file mode 100644
index 80ed2eb2b..000000000
--- a/browser/components/places/tests/browser/browser_sidebarpanels_click.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the items in the bookmarks and history sidebar
-// panels are clickable in both LTR and RTL modes.
-
-function test() {
- waitForExplicitFinish();
- ignoreAllUncaughtExceptions();
-
- const BOOKMARKS_SIDEBAR_ID = "viewBookmarksSidebar";
- const BOOKMARKS_SIDEBAR_TREE_ID = "bookmarks-view";
- const HISTORY_SIDEBAR_ID = "viewHistorySidebar";
- const HISTORY_SIDEBAR_TREE_ID = "historyTree";
- const TEST_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser/sidebarpanels_click_test_page.html";
-
- // If a sidebar is already open, close it.
- if (!document.getElementById("sidebar-box").hidden) {
- info("Unexpected sidebar found - a previous test failed to cleanup correctly");
- SidebarUI.hide();
- }
-
- let sidebar = document.getElementById("sidebar");
- let tests = [];
- let currentTest;
-
- tests.push({
- _itemID: null,
- init: function(aCallback) {
- // Add a bookmark to the Unfiled Bookmarks folder.
- this._itemID = PlacesUtils.bookmarks.insertBookmark(
- PlacesUtils.unfiledBookmarksFolderId, PlacesUtils._uri(TEST_URL),
- PlacesUtils.bookmarks.DEFAULT_INDEX, "test"
- );
- aCallback();
- },
- prepare: function() {
- },
- selectNode: function(tree) {
- tree.selectItems([this._itemID]);
- },
- cleanup: function(aCallback) {
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
- executeSoon(aCallback);
- },
- sidebarName: BOOKMARKS_SIDEBAR_ID,
- treeName: BOOKMARKS_SIDEBAR_TREE_ID,
- desc: "Bookmarks sidebar test"
- });
-
- tests.push({
- init: function(aCallback) {
- // Add a history entry.
- let uri = PlacesUtils._uri(TEST_URL);
- PlacesTestUtils.addVisits({
- uri: uri, visitDate: Date.now() * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED
- }).then(aCallback);
- },
- prepare: function() {
- sidebar.contentDocument.getElementById("byvisited").doCommand();
- },
- selectNode: function(tree) {
- tree.selectNode(tree.view.nodeForTreeIndex(0));
- is(tree.selectedNode.uri, TEST_URL, "The correct visit has been selected");
- is(tree.selectedNode.itemId, -1, "The selected node is not bookmarked");
- },
- cleanup: function(aCallback) {
- PlacesTestUtils.clearHistory().then(aCallback);
- },
- sidebarName: HISTORY_SIDEBAR_ID,
- treeName: HISTORY_SIDEBAR_TREE_ID,
- desc: "History sidebar 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");
- Services.obs.removeObserver(observer, "common-dialog-loaded");
- Services.obs.removeObserver(observer, "tabmodal-dialog-loaded");
-
- aSubject.Dialog.ui.button0.click();
-
- executeSoon(function () {
- SidebarUI.hide();
- currentTest.cleanup(postFunc);
- });
- }
- Services.obs.addObserver(observer, "common-dialog-loaded", false);
- Services.obs.addObserver(observer, "tabmodal-dialog-loaded", false);
-
- let tree = sidebar.contentDocument.getElementById(currentTest.treeName);
-
- // Select the inserted places item.
- currentTest.selectNode(tree);
-
- 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);
- }
-
- function changeSidebarDirection(aDirection) {
- sidebar.contentDocument.documentElement.style.direction = aDirection;
- }
-
- function runNextTest() {
- // Remove eventual tabs created by previous sub-tests.
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeTab(gBrowser.tabContainer.lastChild);
- }
-
- if (tests.length == 0) {
- finish();
- }
- else {
- // Create a new tab and run the test.
- gBrowser.selectedTab = gBrowser.addTab();
- currentTest = tests.shift();
- testPlacesPanel(function() {
- changeSidebarDirection("ltr");
- info("Running " + currentTest.desc + " in LTR mode");
- },
- function() {
- testPlacesPanel(function() {
- // Run the test in RTL mode.
- changeSidebarDirection("rtl");
- info("Running " + currentTest.desc + " in RTL mode");
- },
- function() {
- runNextTest();
- });
- });
- }
- }
-
- // Ensure history is clean before starting the test.
- PlacesTestUtils.clearHistory().then(runNextTest);
-}
diff --git a/browser/components/places/tests/browser/browser_sort_in_library.js b/browser/components/places/tests/browser/browser_sort_in_library.js
deleted file mode 100644
index af9c35e59..000000000
--- a/browser/components/places/tests/browser/browser_sort_in_library.js
+++ /dev/null
@@ -1,249 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests the following bugs:
- *
- * Bug 443745 - View>Sort>of "alpha" sort items is default to Z>A instead of A>Z
- * https://bugzilla.mozilla.org/show_bug.cgi?id=443745
- *
- * Bug 444179 - Library>Views>Sort>Sort by Tags does nothing
- * https://bugzilla.mozilla.org/show_bug.cgi?id=444179
- *
- * Basically, fully tests sorting the placeContent tree in the Places Library
- * window. Sorting is verified by comparing the nsINavHistoryResult returned by
- * placeContent.result to the expected sort values.
- */
-
-// Two properties of nsINavHistoryResult control the sort of the tree:
-// sortingMode and sortingAnnotation. sortingMode's value is one of the
-// nsINavHistoryQueryOptions.SORT_BY_* constants. sortingAnnotation is the
-// annotation used to sort for SORT_BY_ANNOTATION_* mode.
-//
-// This lookup table maps the possible values of anonid's of the treecols to
-// objects that represent the treecols' correct state after the user sorts the
-// previously unsorted tree by selecting a column from the Views > Sort menu.
-// sortingMode is constructed from the key and dir properties (i.e.,
-// SORT_BY_<key>_<dir>) and sortingAnnotation is checked against anno. anno
-// may be undefined if key is not "ANNOTATION".
-const SORT_LOOKUP_TABLE = {
- title: { key: "TITLE", dir: "ASCENDING" },
- tags: { key: "TAGS", dir: "ASCENDING" },
- url: { key: "URI", dir: "ASCENDING" },
- date: { key: "DATE", dir: "DESCENDING" },
- visitCount: { key: "VISITCOUNT", dir: "DESCENDING" },
- dateAdded: { key: "DATEADDED", dir: "DESCENDING" },
- lastModified: { key: "LASTMODIFIED", dir: "DESCENDING" },
- description: { key: "ANNOTATION",
- dir: "ASCENDING",
- anno: "bookmarkProperties/description" }
-};
-
-// This is the column that's sorted if one is not specified and the tree is
-// currently unsorted. Set it to a key substring in the name of one of the
-// nsINavHistoryQueryOptions.SORT_BY_* constants, e.g., "TITLE", "URI".
-// Method ViewMenu.setSortColumn in browser/components/places/content/places.js
-// determines this value.
-const DEFAULT_SORT_KEY = "TITLE";
-
-// Part of the test is checking that sorts stick, so each time we sort we need
-// to remember it.
-var prevSortDir = null;
-var prevSortKey = null;
-
-/**
- * Ensures that the sort of aTree is aSortingMode and aSortingAnno.
- *
- * @param aTree
- * the tree to check
- * @param aSortingMode
- * one of the Ci.nsINavHistoryQueryOptions.SORT_BY_* constants
- * @param aSortingAnno
- * checked only if sorting mode is one of the
- * Ci.nsINavHistoryQueryOptions.SORT_BY_ANNOTATION_* constants
- */
-function checkSort(aTree, aSortingMode, aSortingAnno) {
- // The placeContent tree's sort is determined by the nsINavHistoryResult it
- // stores. Get it and check that the sort is what the caller expects.
- let res = aTree.result;
- isnot(res, null,
- "sanity check: placeContent.result should not return null");
-
- // Check sortingMode.
- is(res.sortingMode, aSortingMode,
- "column should now have sortingMode " + aSortingMode);
-
- // Check sortingAnnotation, but only if sortingMode is ANNOTATION.
- if ([Ci.nsINavHistoryQueryOptions.SORT_BY_ANNOTATION_ASCENDING,
- Ci.nsINavHistoryQueryOptions.SORT_BY_ANNOTATION_DESCENDING].
- indexOf(aSortingMode) >= 0) {
- is(res.sortingAnnotation, aSortingAnno,
- "column should now have sorting annotation " + aSortingAnno);
- }
-}
-
-/**
- * Sets the sort of aTree.
- *
- * @param aOrganizerWin
- * the Places window
- * @param aTree
- * the tree to sort
- * @param aUnsortFirst
- * true if the sort should be set to SORT_BY_NONE before sorting by aCol
- * and aDir
- * @param aShouldFail
- * true if setSortColumn should fail on aCol or aDir
- * @param aCol
- * the column of aTree by which to sort
- * @param aDir
- * either "ascending" or "descending"
- */
-function setSort(aOrganizerWin, aTree, aUnsortFirst, aShouldFail, aCol, aDir) {
- if (aUnsortFirst) {
- aOrganizerWin.ViewMenu.setSortColumn();
- checkSort(aTree, Ci.nsINavHistoryQueryOptions.SORT_BY_NONE, "");
-
- // Remember the sort key and direction.
- prevSortKey = null;
- prevSortDir = null;
- }
-
- let failed = false;
- try {
- aOrganizerWin.ViewMenu.setSortColumn(aCol, aDir);
-
- // Remember the sort key and direction.
- if (!aCol && !aDir) {
- prevSortKey = null;
- prevSortDir = null;
- }
- else {
- if (aCol)
- prevSortKey = SORT_LOOKUP_TABLE[aCol.getAttribute("anonid")].key;
- else if (prevSortKey === null)
- prevSortKey = DEFAULT_SORT_KEY;
-
- if (aDir)
- prevSortDir = aDir.toUpperCase();
- else if (prevSortDir === null)
- prevSortDir = SORT_LOOKUP_TABLE[aCol.getAttribute("anonid")].dir;
- }
- } catch (exc) {
- failed = true;
- }
-
- is(failed, !!aShouldFail,
- "setSortColumn on column " +
- (aCol ? aCol.getAttribute("anonid") : "(no column)") +
- " with direction " + (aDir || "(no direction)") +
- " and table previously " + (aUnsortFirst ? "unsorted" : "sorted") +
- " should " + (aShouldFail ? "" : "not ") + "fail");
-}
-
-/**
- * Tries sorting by an invalid column and sort direction.
- *
- * @param aOrganizerWin
- * the Places window
- * @param aPlaceContentTree
- * the placeContent tree in aOrganizerWin
- */
-function testInvalid(aOrganizerWin, aPlaceContentTree) {
- // Invalid column should fail by throwing an exception.
- let bogusCol = document.createElement("treecol");
- bogusCol.setAttribute("anonid", "bogusColumn");
- setSort(aOrganizerWin, aPlaceContentTree, true, true, bogusCol, "ascending");
-
- // Invalid direction reverts to SORT_BY_NONE.
- setSort(aOrganizerWin, aPlaceContentTree, false, false, null, "bogus dir");
- checkSort(aPlaceContentTree, Ci.nsINavHistoryQueryOptions.SORT_BY_NONE, "");
-}
-
-/**
- * Tests sorting aPlaceContentTree by column only and then by both column
- * and direction.
- *
- * @param aOrganizerWin
- * the Places window
- * @param aPlaceContentTree
- * the placeContent tree in aOrganizerWin
- * @param aUnsortFirst
- * true if, before each sort we try, we should sort to SORT_BY_NONE
- */
-function testSortByColAndDir(aOrganizerWin, aPlaceContentTree, aUnsortFirst) {
- let cols = aPlaceContentTree.getElementsByTagName("treecol");
- ok(cols.length > 0, "sanity check: placeContent should contain columns");
-
- for (let i = 0; i < cols.length; i++) {
- let col = cols.item(i);
- ok(col.hasAttribute("anonid"),
- "sanity check: column " + col.id + " should have anonid");
-
- let colId = col.getAttribute("anonid");
- ok(colId in SORT_LOOKUP_TABLE,
- "sanity check: unexpected placeContent column anonid");
-
- let sortConst =
- "SORT_BY_" + SORT_LOOKUP_TABLE[colId].key + "_" +
- (aUnsortFirst ? SORT_LOOKUP_TABLE[colId].dir : prevSortDir);
- let expectedSortMode = Ci.nsINavHistoryQueryOptions[sortConst];
- let expectedAnno = SORT_LOOKUP_TABLE[colId].anno || "";
-
- // Test sorting by only a column.
- setSort(aOrganizerWin, aPlaceContentTree, aUnsortFirst, false, col);
- checkSort(aPlaceContentTree, expectedSortMode, expectedAnno);
-
- // Test sorting by both a column and a direction.
- ["ascending", "descending"].forEach(function (dir) {
- let sortConst =
- "SORT_BY_" + SORT_LOOKUP_TABLE[colId].key + "_" + dir.toUpperCase();
- let expectedSortMode = Ci.nsINavHistoryQueryOptions[sortConst];
- setSort(aOrganizerWin, aPlaceContentTree, aUnsortFirst, false, col, dir);
- checkSort(aPlaceContentTree, expectedSortMode, expectedAnno);
- });
- }
-}
-
-/**
- * Tests sorting aPlaceContentTree by direction only.
- *
- * @param aOrganizerWin
- * the Places window
- * @param aPlaceContentTree
- * the placeContent tree in aOrganizerWin
- * @param aUnsortFirst
- * true if, before each sort we try, we should sort to SORT_BY_NONE
- */
-function testSortByDir(aOrganizerWin, aPlaceContentTree, aUnsortFirst) {
- ["ascending", "descending"].forEach(function (dir) {
- let key = (aUnsortFirst ? DEFAULT_SORT_KEY : prevSortKey);
- let sortConst = "SORT_BY_" + key + "_" + dir.toUpperCase();
- let expectedSortMode = Ci.nsINavHistoryQueryOptions[sortConst];
- setSort(aOrganizerWin, aPlaceContentTree, aUnsortFirst, false, null, dir);
- checkSort(aPlaceContentTree, expectedSortMode, "");
- });
-}
-
-function test() {
- waitForExplicitFinish();
-
- openLibrary(function (win) {
- let tree = win.document.getElementById("placeContent");
- isnot(tree, null, "sanity check: placeContent tree should exist");
- // Run the tests.
- testSortByColAndDir(win, tree, true);
- testSortByColAndDir(win, tree, false);
- testSortByDir(win, tree, true);
- testSortByDir(win, tree, false);
- testInvalid(win, tree);
- // Reset the sort to SORT_BY_NONE.
- setSort(win, tree, false, false);
- // Close the window and finish.
- win.close();
- finish();
- });
-}
diff --git a/browser/components/places/tests/browser/browser_toolbarbutton_menu_context.js b/browser/components/places/tests/browser/browser_toolbarbutton_menu_context.js
deleted file mode 100644
index 7a0eec22f..000000000
--- a/browser/components/places/tests/browser/browser_toolbarbutton_menu_context.js
+++ /dev/null
@@ -1,53 +0,0 @@
-var bookmarksMenuButton = document.getElementById("bookmarks-menu-button");
-var BMB_menuPopup = document.getElementById("BMB_bookmarksPopup");
-var BMB_showAllBookmarks = document.getElementById("BMB_bookmarksShowAll");
-var contextMenu = document.getElementById("placesContext");
-var newBookmarkItem = document.getElementById("placesContext_new:bookmark");
-
-waitForExplicitFinish();
-add_task(function* testPopup() {
- info("Checking popup context menu before moving the bookmarks button");
- yield checkPopupContextMenu();
- let pos = CustomizableUI.getPlacementOfWidget("bookmarks-menu-button").position;
- CustomizableUI.addWidgetToArea("bookmarks-menu-button", CustomizableUI.AREA_PANEL);
- CustomizableUI.addWidgetToArea("bookmarks-menu-button", CustomizableUI.AREA_NAVBAR, pos);
- info("Checking popup context menu after moving the bookmarks button");
- yield checkPopupContextMenu();
-});
-
-function* checkPopupContextMenu() {
- let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton, "anonid", "dropmarker");
- BMB_menuPopup.setAttribute("style", "transition: none;");
- let popupShownPromise = onPopupEvent(BMB_menuPopup, "shown");
- EventUtils.synthesizeMouseAtCenter(dropmarker, {});
- info("Waiting for bookmarks menu to be shown.");
- yield popupShownPromise;
- let contextMenuShownPromise = onPopupEvent(contextMenu, "shown");
- EventUtils.synthesizeMouseAtCenter(BMB_showAllBookmarks, {type: "contextmenu", button: 2 });
- info("Waiting for context menu on bookmarks menu to be shown.");
- yield contextMenuShownPromise;
- ok(!newBookmarkItem.hasAttribute("disabled"), "New bookmark item shouldn't be disabled");
- let contextMenuHiddenPromise = onPopupEvent(contextMenu, "hidden");
- contextMenu.hidePopup();
- BMB_menuPopup.removeAttribute("style");
- info("Waiting for context menu on bookmarks menu to be hidden.");
- yield contextMenuHiddenPromise;
- let popupHiddenPromise = onPopupEvent(BMB_menuPopup, "hidden");
- // Can't use synthesizeMouseAtCenter because the dropdown panel is in the way
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- info("Waiting for bookmarks menu to be hidden.");
- yield popupHiddenPromise;
-}
-
-function onPopupEvent(popup, evt) {
- let fullEvent = "popup" + evt;
- let deferred = new Promise.defer();
- let onPopupHandler = (e) => {
- if (e.target == popup) {
- popup.removeEventListener(fullEvent, onPopupHandler);
- deferred.resolve();
- }
- };
- popup.addEventListener(fullEvent, onPopupHandler);
- return deferred.promise;
-}
diff --git a/browser/components/places/tests/browser/browser_views_liveupdate.js b/browser/components/places/tests/browser/browser_views_liveupdate.js
deleted file mode 100644
index 735d6b168..000000000
--- a/browser/components/places/tests/browser/browser_views_liveupdate.js
+++ /dev/null
@@ -1,475 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests Places views (menu, toolbar, tree) for liveupdate.
- */
-
-var toolbar = document.getElementById("PersonalToolbar");
-var wasCollapsed = toolbar.collapsed;
-
-function test() {
- waitForExplicitFinish();
-
- // Uncollapse the personal toolbar if needed.
- if (wasCollapsed) {
- promiseSetToolbarVisibility(toolbar, true).then(openBookmarksSidebar);
- } else {
- openBookmarksSidebar();
- }
-}
-
-function openBookmarksSidebar() {
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils in context");
- ok(PlacesUIUtils, "PlacesUIUtils in context");
-
- // 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);
- 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) {
- var popupEvent = document.createEvent("MouseEvent");
- popupEvent.initMouseEvent("popupshowing", true, true, window, 0,
- 0, 0, 0, 0, false, false, false, false,
- 0, null);
- aPopup.dispatchEvent(popupEvent);
-}
-
-/**
- * Adds bookmarks observer, and executes a bunch of bookmarks operations.
- */
-function startTest() {
- var bs = PlacesUtils.bookmarks;
- // Add observers.
- bs.addObserver(bookmarksObserver, false);
- PlacesUtils.annotations.addObserver(bookmarksObserver, false);
- var addedBookmarks = [];
-
- // MENU
- info("*** Acting on menu bookmarks");
- var id = bs.insertBookmark(bs.bookmarksMenuFolder,
- PlacesUtils._uri("http://bm1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "bm1");
- bs.setItemTitle(id, "bm1_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(bs.bookmarksMenuFolder,
- PlacesUtils._uri("place:"),
- bs.DEFAULT_INDEX,
- "bm2");
- bs.setItemTitle(id, "");
- addedBookmarks.push(id);
- id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
- addedBookmarks.push(id);
- id = bs.createFolder(bs.bookmarksMenuFolder,
- "bmf",
- bs.DEFAULT_INDEX);
- bs.setItemTitle(id, "bmf_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(id,
- PlacesUtils._uri("http://bmf1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "bmf1");
- bs.setItemTitle(id, "bmf1_edited");
- addedBookmarks.push(id);
- bs.moveItem(id, bs.bookmarksMenuFolder, 0);
-
- // TOOLBAR
- info("*** Acting on toolbar bookmarks");
- id = bs.insertBookmark(bs.toolbarFolder,
- PlacesUtils._uri("http://tb1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "tb1");
- bs.setItemTitle(id, "tb1_edited");
- addedBookmarks.push(id);
- // Test live update of title.
- bs.setItemTitle(id, "tb1_edited");
- id = bs.insertBookmark(bs.toolbarFolder,
- PlacesUtils._uri("place:"),
- bs.DEFAULT_INDEX,
- "tb2");
- bs.setItemTitle(id, "");
- addedBookmarks.push(id);
- id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
- addedBookmarks.push(id);
- id = bs.createFolder(bs.toolbarFolder,
- "tbf",
- bs.DEFAULT_INDEX);
- bs.setItemTitle(id, "tbf_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(id,
- PlacesUtils._uri("http://tbf1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "tbf1");
- bs.setItemTitle(id, "tbf1_edited");
- addedBookmarks.push(id);
- bs.moveItem(id, bs.toolbarFolder, 0);
-
- // UNSORTED
- info("*** Acting on unsorted bookmarks");
- id = bs.insertBookmark(bs.unfiledBookmarksFolder,
- PlacesUtils._uri("http://ub1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "ub1");
- bs.setItemTitle(id, "ub1_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(bs.unfiledBookmarksFolder,
- PlacesUtils._uri("place:"),
- bs.DEFAULT_INDEX,
- "ub2");
- bs.setItemTitle(id, "ub2_edited");
- addedBookmarks.push(id);
- id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
- addedBookmarks.push(id);
- id = bs.createFolder(bs.unfiledBookmarksFolder,
- "ubf",
- bs.DEFAULT_INDEX);
- bs.setItemTitle(id, "ubf_edited");
- addedBookmarks.push(id);
- id = bs.insertBookmark(id,
- PlacesUtils._uri("http://ubf1.mozilla.org/"),
- bs.DEFAULT_INDEX,
- "bubf1");
- bs.setItemTitle(id, "bubf1_edited");
- addedBookmarks.push(id);
- bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
-
- // Remove all added bookmarks.
- addedBookmarks.forEach(function (aItem) {
- // If we remove an item after its containing folder has been removed,
- // this will throw, but we can ignore that.
- try {
- bs.removeItem(aItem);
- } catch (ex) {}
- });
-
- // Remove observers.
- bs.removeObserver(bookmarksObserver);
- PlacesUtils.annotations.removeObserver(bookmarksObserver);
- finishTest();
-}
-
-/**
- * Restores browser state and calls finish.
- */
-function finishTest() {
- // Close bookmarks sidebar.
- SidebarUI.hide();
-
- // Collapse the personal toolbar if needed.
- if (wasCollapsed) {
- promiseSetToolbarVisibility(toolbar, false).then(finish);
- } else {
- finish();
- }
-}
-
-/**
- * The observer is where magic happens, for every change we do it will look for
- * nodes positions in the affected views.
- */
-var bookmarksObserver = {
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsINavBookmarkObserver
- , Ci.nsIAnnotationObserver
- ]),
-
- // nsIAnnotationObserver
- onItemAnnotationSet: function() {},
- onItemAnnotationRemoved: function() {},
- onPageAnnotationSet: function() {},
- onPageAnnotationRemoved: function() {},
-
- // nsINavBookmarkObserver
- onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex,
- aItemType, aURI) {
- var views = getViewsForFolder(aFolderId);
- ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
-
- // Check that item has been added in the correct position.
- for (var i = 0; i < views.length; i++) {
- var [node, index] = searchItemInView(aItemId, views[i]);
- isnot(node, null, "Found new Places node in " + views[i]);
- is(index, aIndex, "Node is at index " + index);
- }
- },
-
- onItemRemoved: function PSB_onItemRemoved(aItemId, aFolderId, aIndex,
- aItemType) {
- var views = getViewsForFolder(aFolderId);
- ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
- // Check that item has been removed.
- for (var i = 0; i < views.length; i++) {
- var node = null;
- [node, ] = searchItemInView(aItemId, views[i]);
- is(node, null, "Places node not found in " + views[i]);
- }
- },
-
- onItemMoved: function(aItemId,
- aOldFolderId, aOldIndex,
- aNewFolderId, aNewIndex,
- aItemType) {
- var views = getViewsForFolder(aNewFolderId);
- ok(views.length > 0, "Found affected views: " + views);
-
- // Check that item has been moved in the correct position.
- for (var i = 0; i < views.length; i++) {
- var node = null;
- var index = null;
- [node, index] = searchItemInView(aItemId, views[i]);
- isnot(node, null, "Found new Places node in " + views[i]);
- is(index, aNewIndex, "Node is at index " + index);
- }
- },
-
- onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
- onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
- onItemVisited: function() {},
-
- onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
- aIsAnnotationProperty, aNewValue,
- aLastModified, aItemType,
- aParentId) {
- if (aProperty !== "title")
- return;
-
- var views = getViewsForFolder(aParentId);
- ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
-
- // Check that item has been moved in the correct position.
- let validator = function(aElementOrTreeIndex) {
- if (typeof(aElementOrTreeIndex) == "number") {
- var sidebar = document.getElementById("sidebar");
- var tree = sidebar.contentDocument.getElementById("bookmarks-view");
- let cellText = tree.view.getCellText(aElementOrTreeIndex,
- tree.columns.getColumnAt(0));
- if (!aNewValue)
- return cellText == PlacesUIUtils.getBestTitle(tree.view.nodeForTreeIndex(aElementOrTreeIndex), true);
- return cellText == aNewValue;
- }
- if (!aNewValue && aElementOrTreeIndex.localName != "toolbarbutton") {
- return aElementOrTreeIndex.getAttribute("label") == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
- }
- return aElementOrTreeIndex.getAttribute("label") == aNewValue;
- };
-
- for (var i = 0; i < views.length; i++) {
- var [node, , valid] = searchItemInView(aItemId, views[i], validator);
- isnot(node, null, "Found changed Places node in " + views[i]);
- is(node.title, aNewValue, "Node has correct title: " + aNewValue);
- ok(valid, "Node element has correct label: " + aNewValue);
- }
- }
-};
-
-/**
- * Search an item id in a view.
- *
- * @param aItemId
- * item id of the item to search.
- * @param aView
- * either "toolbar", "menu" or "sidebar"
- * @param aValidator
- * function to check validity of the found node element.
- * @returns [node, index, valid] or [null, null, false] if not found.
- */
-function searchItemInView(aItemId, aView, aValidator) {
- switch (aView) {
- case "toolbar":
- return getNodeForToolbarItem(aItemId, aValidator);
- case "menu":
- return getNodeForMenuItem(aItemId, aValidator);
- case "sidebar":
- return getNodeForSidebarItem(aItemId, aValidator);
- }
-
- return [null, null, false];
-}
-
-/**
- * Get places node and index for an itemId in bookmarks toolbar view.
- *
- * @param aItemId
- * item id of the item to search.
- * @returns [node, index] or [null, null] if not found.
- */
-function getNodeForToolbarItem(aItemId, aValidator) {
- var toolbar = document.getElementById("PlacesToolbarItems");
-
- function findNode(aContainer) {
- var children = aContainer.childNodes;
- for (var i = 0, staticNodes = 0; i < children.length; i++) {
- var child = children[i];
-
- // Is this a Places node?
- if (!child._placesNode || child.hasAttribute("simulated-places-node")) {
- staticNodes++;
- continue;
- }
-
- if (child._placesNode.itemId == aItemId) {
- let valid = aValidator ? aValidator(child) : true;
- return [child._placesNode, i - staticNodes, valid];
- }
-
- // Don't search in queries, they could contain our item in a
- // different position. Search only folders
- if (PlacesUtils.nodeIsFolder(child._placesNode)) {
- var popup = child.lastChild;
- popup.showPopup(popup);
- var foundNode = findNode(popup);
- popup.hidePopup();
- if (foundNode[0] != null)
- return foundNode;
- }
- }
- return [null, null];
- }
-
- return findNode(toolbar);
-}
-
-/**
- * Get places node and index for an itemId in bookmarks menu view.
- *
- * @param aItemId
- * item id of the item to search.
- * @returns [node, index] or [null, null] if not found.
- */
-function getNodeForMenuItem(aItemId, aValidator) {
- var menu = document.getElementById("bookmarksMenu");
-
- function findNode(aContainer) {
- var children = aContainer.childNodes;
- for (var i = 0, staticNodes = 0; i < children.length; i++) {
- var child = children[i];
-
- // Is this a Places node?
- if (!child._placesNode || child.hasAttribute("simulated-places-node")) {
- staticNodes++;
- continue;
- }
-
- if (child._placesNode.itemId == aItemId) {
- let valid = aValidator ? aValidator(child) : true;
- return [child._placesNode, i - staticNodes, valid];
- }
-
- // Don't search in queries, they could contain our item in a
- // different position. Search only folders
- if (PlacesUtils.nodeIsFolder(child._placesNode)) {
- var popup = child.lastChild;
- fakeOpenPopup(popup);
- var foundNode = findNode(popup);
-
- child.open = false;
- if (foundNode[0] != null)
- return foundNode;
- }
- }
- return [null, null, false];
- }
-
- return findNode(menu.lastChild);
-}
-
-/**
- * Get places node and index for an itemId in sidebar tree view.
- *
- * @param aItemId
- * item id of the item to search.
- * @returns [node, index] or [null, null] if not found.
- */
-function getNodeForSidebarItem(aItemId, aValidator) {
- var sidebar = document.getElementById("sidebar");
- var tree = sidebar.contentDocument.getElementById("bookmarks-view");
-
- function findNode(aContainerIndex) {
- if (tree.view.isContainerEmpty(aContainerIndex))
- return [null, null, false];
-
- // The rowCount limit is just for sanity, but we will end looping when
- // we have checked the last child of this container or we have found node.
- for (var i = aContainerIndex + 1; i < tree.view.rowCount; i++) {
- var node = tree.view.nodeForTreeIndex(i);
-
- if (node.itemId == aItemId) {
- // Minus one because we want relative index inside the container.
- let valid = aValidator ? aValidator(i) : true;
- return [node, i - tree.view.getParentIndex(i) - 1, valid];
- }
-
- if (PlacesUtils.nodeIsFolder(node)) {
- // Open container.
- tree.view.toggleOpenState(i);
- // Search inside it.
- var foundNode = findNode(i);
- // Close container.
- tree.view.toggleOpenState(i);
- // Return node if found.
- if (foundNode[0] != null)
- return foundNode;
- }
-
- // We have finished walking this container.
- if (!tree.view.hasNextSibling(aContainerIndex + 1, i))
- break;
- }
- return [null, null, false]
- }
-
- // Root node is hidden, so we need to manually walk the first level.
- for (var i = 0; i < tree.view.rowCount; i++) {
- // Open container.
- tree.view.toggleOpenState(i);
- // Search inside it.
- var foundNode = findNode(i);
- // Close container.
- tree.view.toggleOpenState(i);
- // Return node if found.
- if (foundNode[0] != null)
- return foundNode;
- }
- return [null, null, false];
-}
-
-/**
- * Get views affected by changes to a folder.
- *
- * @param aFolderId:
- * item id of the folder we have changed.
- * @returns a subset of views: ["toolbar", "menu", "sidebar"]
- */
-function getViewsForFolder(aFolderId) {
- var rootId = aFolderId;
- while (!PlacesUtils.isRootItem(rootId))
- rootId = PlacesUtils.bookmarks.getFolderIdForItem(rootId);
-
- switch (rootId) {
- case PlacesUtils.toolbarFolderId:
- return ["toolbar", "sidebar"]
- case PlacesUtils.bookmarksMenuFolderId:
- return ["menu", "sidebar"]
- case PlacesUtils.unfiledBookmarksFolderId:
- return ["sidebar"]
- }
- return new Array();
-}
diff --git a/browser/components/places/tests/browser/frameLeft.html b/browser/components/places/tests/browser/frameLeft.html
deleted file mode 100644
index 5a54fe353..000000000
--- a/browser/components/places/tests/browser/frameLeft.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
- <head>
- <title>Left frame</title>
- </head>
- <body>
- <a id="clickme" href="frameRight.html" target="right">Open page in the right frame.</a>
- </body>
-</html>
diff --git a/browser/components/places/tests/browser/frameRight.html b/browser/components/places/tests/browser/frameRight.html
deleted file mode 100644
index 226accc34..000000000
--- a/browser/components/places/tests/browser/frameRight.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
- <head>
- <title>Right Frame</title>
- </head>
- <body>
- This is the right frame.
- </body>
-</html>
diff --git a/browser/components/places/tests/browser/framedPage.html b/browser/components/places/tests/browser/framedPage.html
deleted file mode 100644
index d388562e6..000000000
--- a/browser/components/places/tests/browser/framedPage.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
- <head>
- <title>Framed page</title>
- </head>
- <frameset cols="*,*">
- <frame name="left" src="frameLeft.html">
- <frame name="right" src="about:mozilla">
- </frameset>
-</html>
diff --git a/browser/components/places/tests/browser/head.js b/browser/components/places/tests/browser/head.js
deleted file mode 100644
index aaf78332e..000000000
--- a/browser/components/places/tests/browser/head.js
+++ /dev/null
@@ -1,460 +0,0 @@
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
- "resource://gre/modules/NetUtil.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-// We need to cache this before test runs...
-var cachedLeftPaneFolderIdGetter;
-var getter = PlacesUIUtils.__lookupGetter__("leftPaneFolderId");
-if (!cachedLeftPaneFolderIdGetter && typeof(getter) == "function") {
- cachedLeftPaneFolderIdGetter = getter;
-}
-
-// ...And restore it when test ends.
-registerCleanupFunction(function() {
- let getter = PlacesUIUtils.__lookupGetter__("leftPaneFolderId");
- if (cachedLeftPaneFolderIdGetter && typeof(getter) != "function") {
- PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter);
- }
-});
-
-function openLibrary(callback, aLeftPaneRoot) {
- let library = window.openDialog("chrome://browser/content/places/places.xul",
- "", "chrome,toolbar=yes,dialog=no,resizable",
- aLeftPaneRoot);
- waitForFocus(function () {
- callback(library);
- }, library);
-
- return library;
-}
-
-/**
- * Returns a handle to a Library window.
- * If one is opens returns itm otherwise it opens a new one.
- *
- * @param aLeftPaneRoot
- * Hierarchy to open and select in the left pane.
- */
-function promiseLibrary(aLeftPaneRoot) {
- return new Promise(resolve => {
- let library = Services.wm.getMostRecentWindow("Places:Organizer");
- if (library && !library.closed) {
- if (aLeftPaneRoot) {
- library.PlacesOrganizer.selectLeftPaneContainerByHierarchy(aLeftPaneRoot);
- }
- resolve(library);
- }
- else {
- 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);
- resolve();
- });
-
- // Close Library window.
- organizer.close();
- });
-}
-
-/**
- * Waits for a clipboard operation to complete, looking for the expected type.
- *
- * @see waitForClipboard
- *
- * @param aPopulateClipboardFn
- * Function to populate the clipboard.
- * @param aFlavor
- * Data flavor to expect.
- */
-function promiseClipboard(aPopulateClipboardFn, aFlavor) {
- return new Promise(resolve => {
- waitForClipboard(data => !!data, aPopulateClipboardFn, resolve, aFlavor);
- });
-}
-
-/**
- * Waits for all pending async statements on the default connection, before
- * proceeding with aCallback.
- *
- * @param aCallback
- * Function to be called when done.
- * @param aScope
- * Scope for the callback.
- * @param aArguments
- * Arguments array for the callback.
- *
- * @note The result is achieved by asynchronously executing a query requiring
- * a write lock. Since all statements on the same connection are
- * serialized, the end of this write operation means that all writes are
- * complete. Note that WAL makes so that writers don't block readers, but
- * this is a problem only across different connections.
- */
-function waitForAsyncUpdates(aCallback, aScope, aArguments)
-{
- let scope = aScope || this;
- let args = aArguments || [];
- let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
- .DBConnection;
- let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
- begin.executeAsync();
- begin.finalize();
-
- let commit = db.createAsyncStatement("COMMIT");
- commit.executeAsync({
- handleResult: function() {},
- handleError: function() {},
- handleCompletion: function(aReason)
- {
- aCallback.apply(scope, args);
- }
- });
- commit.finalize();
-}
-
-function synthesizeClickOnSelectedTreeCell(aTree, aOptions) {
- let tbo = aTree.treeBoxObject;
- if (tbo.view.selection.count != 1)
- throw new Error("The test node should be successfully selected");
- // Get selection rowID.
- let min = {}, max = {};
- tbo.view.selection.getRangeAt(0, min, max);
- let rowID = min.value;
- tbo.ensureRowIsVisible(rowID);
- // Calculate the click coordinates.
- var rect = tbo.getCoordsForCellItem(rowID, aTree.columns[0], "text");
- var x = rect.x + rect.width / 2;
- var y = rect.y + rect.height / 2;
- // Simulate the click.
- EventUtils.synthesizeMouse(aTree.body, x, y, aOptions || {},
- aTree.ownerGlobal);
-}
-
-/**
- * Asynchronously check a url is visited.
- *
- * @param aURI The URI.
- * @return {Promise}
- * @resolves When the check has been added successfully.
- * @rejects JavaScript exception.
- */
-function promiseIsURIVisited(aURI) {
- let deferred = Promise.defer();
-
- PlacesUtils.asyncHistory.isURIVisited(aURI, function(aURI, aIsVisited) {
- deferred.resolve(aIsVisited);
- });
-
- return deferred.promise;
-}
-
-function promiseBookmarksNotification(notification, conditionFn) {
- info(`promiseBookmarksNotification: waiting for ${notification}`);
- return new Promise((resolve) => {
- let proxifiedObserver = new Proxy({}, {
- get: (target, name) => {
- if (name == "QueryInterface")
- return XPCOMUtils.generateQI([ Ci.nsINavBookmarkObserver ]);
- info(`promiseBookmarksNotification: got ${name} notification`);
- if (name == notification)
- return (...args) => {
- if (conditionFn.apply(this, args)) {
- PlacesUtils.bookmarks.removeObserver(proxifiedObserver, false);
- executeSoon(resolve);
- } else {
- info(`promiseBookmarksNotification: skip cause condition doesn't apply to ${JSON.stringify(args)}`);
- }
- }
- return () => {};
- }
- });
- PlacesUtils.bookmarks.addObserver(proxifiedObserver, false);
- });
-}
-
-function promiseHistoryNotification(notification, conditionFn) {
- info(`Waiting for ${notification}`);
- return new Promise((resolve) => {
- let proxifiedObserver = new Proxy({}, {
- get: (target, name) => {
- if (name == "QueryInterface")
- return XPCOMUtils.generateQI([ Ci.nsINavHistoryObserver ]);
- if (name == notification)
- return (...args) => {
- if (conditionFn.apply(this, args)) {
- PlacesUtils.history.removeObserver(proxifiedObserver, false);
- executeSoon(resolve);
- }
- }
- return () => {};
- }
- });
- PlacesUtils.history.addObserver(proxifiedObserver, false);
- });
-}
-
-/**
- * Makes the specified toolbar visible or invisible and returns a Promise object
- * that is resolved when the toolbar has completed any animations associated
- * with hiding or showing the toolbar.
- *
- * Note that this code assumes that changes to a toolbar's visibility trigger
- * a transition on the max-height property of the toolbar element.
- * Changes to this styling could cause the returned Promise object to be
- * resolved too early or not at all.
- *
- * @param aToolbar
- * The toolbar to update.
- * @param aVisible
- * True to make the toolbar visible, false to make it hidden.
- *
- * @return {Promise}
- * @resolves Any animation associated with updating the toolbar's visibility has
- * finished.
- * @rejects Never.
- */
-function promiseSetToolbarVisibility(aToolbar, aVisible, aCallback) {
- return new Promise((resolve, reject) => {
- function listener(event) {
- if (event.propertyName == "max-height") {
- aToolbar.removeEventListener("transitionend", listener);
- resolve();
- }
- }
-
- let transitionProperties =
- window.getComputedStyle(aToolbar).transitionProperty.split(", ");
- if (isToolbarVisible(aToolbar) != aVisible &&
- transitionProperties.some(
- prop => prop == "max-height" || prop == "all"
- )) {
- // Just because max-height is a transitionable property doesn't mean
- // a transition will be triggered, but it's more likely.
- aToolbar.addEventListener("transitionend", listener);
- setToolbarVisibility(aToolbar, aVisible);
- return;
- }
-
- // No animation to wait for
- setToolbarVisibility(aToolbar, aVisible);
- resolve();
- });
-}
-
-/**
- * Helper function to determine if the given toolbar is in the visible
- * state according to its autohide/collapsed attribute.
- *
- * @aToolbar The toolbar to query.
- *
- * @returns True if the relevant attribute on |aToolbar| indicates it is
- * visible, false otherwise.
- */
-function isToolbarVisible(aToolbar) {
- let hidingAttribute = aToolbar.getAttribute("type") == "menubar"
- ? "autohide"
- : "collapsed";
- let hidingValue = aToolbar.getAttribute(hidingAttribute).toLowerCase();
- // Check for both collapsed="true" and collapsed="collapsed"
- return hidingValue !== "true" && hidingValue !== hidingAttribute;
-}
-
-/**
- * Executes a task after opening the bookmarks dialog, then cancels the dialog.
- *
- * @param autoCancel
- * whether to automatically cancel the dialog at the end of the task
- * @param openFn
- * generator function causing the dialog to open
- * @param task
- * 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);
- 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);
- });
- } else if (topic == "domwindowclosed") {
- Services.ww.unregisterNotification(winObserver);
- closed = true;
- }
- });
- });
-
- info("withBookmarksDialog: opening the dialog");
- // The dialog might be modal and could block our events loop, so executeSoon.
- executeSoon(openFn);
-
- info("withBookmarksDialog: waiting for the dialog");
- let dialogWin = yield dialogPromise;
-
- // Ensure overlay is loaded
- info("waiting for the overlay to be loaded");
- yield waitForCondition(() => dialogWin.gEditItemOverlay.initialized,
- "EditItemOverlay should be initialized");
-
- // Check the first textbox is focused.
- let doc = dialogWin.document;
- let elt = doc.querySelector("textbox:not([collapsed=true])");
- if (elt) {
- info("waiting for focus on the first textfield");
- yield waitForCondition(() => doc.activeElement == elt.inputField,
- "The first non collapsed textbox should have been focused");
- }
-
- info("withBookmarksDialog: executing the task");
- try {
- yield taskFn(dialogWin);
- } finally {
- if (!closed) {
- if (!autoCancel) {
- ok(false, "The test should have closed the dialog!");
- }
- info("withBookmarksDialog: canceling the dialog");
- doc.documentElement.cancelDialog();
- }
- }
-});
-
-/**
- * Opens the contextual menu on the element pointed by the given selector.
- *
- * @param selector
- * Valid selector syntax
- * @return Promise
- * Returns a Promise that resolves once the context menu has been
- * opened.
- */
-var openContextMenuForContentSelector = Task.async(function* (browser, selector) {
- info("wait for the context menu");
- let contextPromise = BrowserTestUtils.waitForEvent(document.getElementById("contentAreaContextMenu"),
- "popupshown");
- yield ContentTask.spawn(browser, { selector }, function* (args) {
- let doc = content.document;
- let elt = doc.querySelector(args.selector)
- dump(`openContextMenuForContentSelector: found ${elt}\n`);
-
- /* Open context menu so chrome can access the element */
- const domWindowUtils =
- content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils);
- let rect = elt.getBoundingClientRect();
- let left = rect.left + rect.width / 2;
- let top = rect.top + rect.height / 2;
- domWindowUtils.sendMouseEvent("contextmenu", left, top, 2,
- 1, 0, false, 0, 0, true);
- });
- yield contextPromise;
-});
-
-/**
- * Waits for a specified condition to happen.
- *
- * @param conditionFn
- * a Function or a generator function, returning a boolean for whether
- * the condition is fulfilled.
- * @param errorMsg
- * Error message to use if the condition has not been satisfied after a
- * meaningful amount of tries.
- */
-var waitForCondition = Task.async(function* (conditionFn, errorMsg) {
- for (let tries = 0; tries < 100; ++tries) {
- if ((yield conditionFn()))
- return;
- yield new Promise(resolve => {
- if (!waitForCondition._timers) {
- waitForCondition._timers = new Set();
- registerCleanupFunction(() => {
- is(waitForCondition._timers.size, 0, "All the wait timers have been removed");
- delete waitForCondition._timers;
- });
- }
- let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- waitForCondition._timers.add(timer);
- timer.init(() => {
- waitForCondition._timers.delete(timer);
- resolve();
- }, 100, Ci.nsITimer.TYPE_ONE_SHOT);
- });
- }
- ok(false, errorMsg);
-});
-
-/**
- * Fills a bookmarks dialog text field ensuring to cause expected edit events.
- *
- * @param id
- * id of the text field
- * @param text
- * text to fill in
- * @param win
- * dialog window
- * @param [optional] blur
- * whether to blur at the end.
- */
-function fillBookmarkTextField(id, text, win, blur = true) {
- let elt = win.document.getElementById(id);
- elt.focus();
- elt.select();
- for (let c of text.split("")) {
- EventUtils.synthesizeKey(c, {}, win);
- }
- if (blur)
- elt.blur();
-}
-
-/**
- * Executes a task after opening the bookmarks or history sidebar. Takes care
- * of closing the sidebar once done.
- *
- * @param type
- * either "bookmarks" or "history".
- * @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);
- resolve();
- }, true);
- });
- let sidebarId = type == "bookmarks" ? "viewBookmarksSidebar"
- : "viewHistorySidebar";
- SidebarUI.show(sidebarId);
- yield sidebarLoadedPromise;
-
- let treeId = type == "bookmarks" ? "bookmarks-view"
- : "historyTree";
- let tree = sidebar.contentDocument.getElementById(treeId);
-
- // Need to executeSoon since the tree is initialized on sidebar load.
- info("withSidebarTree: executing the task");
- try {
- yield taskFn(tree);
- } finally {
- SidebarUI.hide();
- }
-});
diff --git a/browser/components/places/tests/browser/keyword_form.html b/browser/components/places/tests/browser/keyword_form.html
deleted file mode 100644
index a881c0d5a..000000000
--- a/browser/components/places/tests/browser/keyword_form.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML>
-
-<html lang="en">
-<head>
- <meta http-equiv="Content-Type" content="text/html;charset=windows-1252">
-</head>
-<body>
- <form id="form1" method="POST" action="keyword_form.html">
- <input type="hidden" name="accenti" value="àèìòù">
- <input type="text" name="search">
- </form>
- <form id="form2" method="POST" action="keyword_form.html">
- <input type="hidden" name="accenti" value="ùòìèà">
- <input type="text" name="search">
- </form>
-</body>
-</html>
diff --git a/browser/components/places/tests/browser/pageopeningwindow.html b/browser/components/places/tests/browser/pageopeningwindow.html
deleted file mode 100644
index 282f9c593..000000000
--- a/browser/components/places/tests/browser/pageopeningwindow.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<meta charset="UTF-8">
-Hi, I was opened via a <script>document.write(location.search ?
- "popup call from the opened window... uh oh, that shouldn't happen!" :
- "bookmarklet, and I will open a new window myself.")</script><br>
-<script>
- if (!location.search) {
- open(location.href + "?donotopen=true", '_blank');
- }
-</script>
diff --git a/browser/components/places/tests/browser/sidebarpanels_click_test_page.html b/browser/components/places/tests/browser/sidebarpanels_click_test_page.html
deleted file mode 100644
index c73eaa540..000000000
--- a/browser/components/places/tests/browser/sidebarpanels_click_test_page.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
-<head>
- <title>browser_sidebarpanels_click.js test page</title>
-</head>
-<body onload="alert('test');">
-</body>
-</html>
diff --git a/browser/components/places/tests/chrome/.eslintrc.js b/browser/components/places/tests/chrome/.eslintrc.js
deleted file mode 100644
index 8c0f4f574..000000000
--- a/browser/components/places/tests/chrome/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/chrome.eslintrc.js"
- ]
-};
diff --git a/browser/components/places/tests/chrome/chrome.ini b/browser/components/places/tests/chrome/chrome.ini
deleted file mode 100644
index d7b4a55c8..000000000
--- a/browser/components/places/tests/chrome/chrome.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-[DEFAULT]
-support-files = head.js
-
-[test_0_bug510634.xul]
-[test_0_multiple_left_pane.xul]
-[test_bug1163447_selectItems_through_shortcut.xul]
-[test_bug427633_no_newfolder_if_noip.xul]
-[test_bug485100-change-case-loses-tag.xul]
-[test_bug549192.xul]
-[test_bug549491.xul]
-[test_bug631374_tags_selector_scroll.xul]
-[test_editBookmarkOverlay_keywords.xul]
-[test_editBookmarkOverlay_tags_liveUpdate.xul]
-[test_selectItems_on_nested_tree.xul]
-[test_treeview_date.xul]
diff --git a/browser/components/places/tests/chrome/head.js b/browser/components/places/tests/chrome/head.js
deleted file mode 100644
index 26b97f6d7..000000000
--- a/browser/components/places/tests/chrome/head.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
diff --git a/browser/components/places/tests/chrome/test_0_bug510634.xul b/browser/components/places/tests/chrome/test_0_bug510634.xul
deleted file mode 100644
index 86e102180..000000000
--- a/browser/components/places/tests/chrome/test_0_bug510634.xul
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="510634: Wrong icons on bookmarks sidebar"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <tree id="tree"
- type="places"
- flex="1">
- <treecols>
- <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
- </treecols>
- <treechildren flex="1"/>
- </tree>
-
- <script type="application/javascript">
- <![CDATA[
-
- /**
- * Bug 510634 - Wrong icons on bookmarks sidebar
- * https://bugzilla.mozilla.org/show_bug.cgi?id=510634
- *
- * Ensures that properties for special queries are set on their tree nodes,
- * even if PlacesUIUtils.leftPaneFolderId was not initialized.
- */
-
- SimpleTest.waitForExplicitFinish();
-
- function runTest() {
- // We need to cache and restore this getter in order to simulate
- // Bug 510634
- let cachedLeftPaneFolderIdGetter =
- PlacesUIUtils.__lookupGetter__("leftPaneFolderId");
- // Must also cache and restore this getter as it is affected by
- // leftPaneFolderId, from bug 564900.
- let cachedAllBookmarksFolderIdGetter =
- PlacesUIUtils.__lookupGetter__("allBookmarksFolderId");
-
- let leftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
-
- // restore the getter
- PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter);
-
- // Setup the places tree contents.
- let tree = document.getElementById("tree");
- tree.place = "place:queryType=1&folder=" + leftPaneFolderId;
-
- // The query-property is set on the title column for each row.
- let titleColumn = tree.treeBoxObject.columns.getColumnAt(0);
-
- // Open All Bookmarks
- tree.selectItems([PlacesUIUtils.leftPaneQueries["AllBookmarks"]]);
- PlacesUtils.asContainer(tree.selectedNode).containerOpen = true;
- is(PlacesUIUtils.allBookmarksFolderId, tree.selectedNode.itemId,
- "Opened All Bookmarks");
-
- ["History", "Downloads", "Tags", "AllBookmarks", "BookmarksToolbar",
- "BookmarksMenu", "UnfiledBookmarks"].forEach(
- function(aQueryName, aRow) {
- let found = false;
- for (let i = 0; i < tree.view.rowCount && !found; i++) {
- rowProperties = tree.view.getCellProperties(i, titleColumn).split(" ");
- found = rowProperties.includes("OrganizerQuery_" + aQueryName);
- }
- ok(found, "OrganizerQuery_" + aQueryName + " is set");
- }
- );
-
- // Close the root node
- tree.result.root.containerOpen = false;
-
- // Restore the getters for the next test.
- PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter);
- PlacesUIUtils.__defineGetter__("allBookmarksFolderId",
- cachedAllBookmarksFolderIdGetter);
-
- SimpleTest.finish();
- }
-
- ]]>
- </script>
-</window>
diff --git a/browser/components/places/tests/chrome/test_0_multiple_left_pane.xul b/browser/components/places/tests/chrome/test_0_multiple_left_pane.xul
deleted file mode 100644
index 09a4d2054..000000000
--- a/browser/components/places/tests/chrome/test_0_multiple_left_pane.xul
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!-- Bug 466422:
- - Check that we replace the left pane with a correct one if it gets corrupted
- - and we end up having more than one. -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Test handling of multiple left pane folders"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml">
- <p id="display"></p>
- <div id="content" style="display: none"></div>
- <pre id="test"></pre>
- </body>
-
- <script type="application/javascript">
- <![CDATA[
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- // Sanity checks.
- ok(PlacesUtils, "PlacesUtils is running in chrome context");
- ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
- ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0,
- "Left pane version in chrome context, " +
- "current version is: " + PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION );
-
- let fakeLeftPanes = [];
- // We need 2 left pane folders to simulate a corrupt profile.
- do {
- let leftPaneItems = PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
-
- // Create a fake left pane folder.
- let folder = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.rootGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER
- });
-
- let fakeLeftPaneRoot = yield PlacesUtils.promiseItemId(folder.guid);
- PlacesUtils.annotations.setItemAnnotation(fakeLeftPaneRoot, PlacesUIUtils.ORGANIZER_FOLDER_ANNO,
- PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION, 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
- fakeLeftPanes.push(folder.guid);
- } while (fakeLeftPanes.length < 2);
-
- // Initialize the left pane queries.
- PlacesUIUtils.leftPaneFolderId;
-
- // Check left pane.
- ok(PlacesUIUtils.leftPaneFolderId > 0,
- "Left pane folder correctly created");
- let leftPaneItems = PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
- is(leftPaneItems.length, 1,
- "We correctly have only 1 left pane folder");
-
- // Check that all old left pane items have been removed.
- for (let guid of fakeLeftPanes) {
- ok(!(yield PlacesUtils.bookmarks.fetch({guid})), "This folder should have been removed");
- }
- }).then(() => SimpleTest.finish());
- }
- ]]>
- </script>
-
-</window>
diff --git a/browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul b/browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul
deleted file mode 100644
index 8e3a99533..000000000
--- a/browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/licenses/publicdomain/
- -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="1163447: selectItems in Places no longer selects items within Toolbar or Sidebar folders"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript" src="head.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <tree id="tree"
- type="places"
- flex="1">
- <treecols>
- <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
- </treecols>
- <treechildren flex="1"/>
- </tree>
-
- <script type="application/javascript"><![CDATA[
-
- /**
- * Bug 1163447: places-tree should be able to select an item within the toolbar, and
- * unfiled bookmarks. Yet not follow recursive folder-shortcuts infinitely.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- let bmu = PlacesUtils.bookmarks;
-
- yield bmu.insert({
- parentGuid: bmu.toolbarGuid,
- index: bmu.DEFAULT_INDEX,
- type: bmu.TYPE_BOOKMARK,
- url: "place:folder=TOOLBAR",
- title: "shortcut to self - causing infinite recursion if not handled properly"
- });
-
- yield bmu.insert({
- parentGuid: bmu.toolbarGuid,
- index: bmu.DEFAULT_INDEX,
- type: bmu.TYPE_BOOKMARK,
- url: "place:folder=UNFILED_BOOKMARKS",
- title: "shortcut to unfiled, within toolbar"
- });
-
- let folder = yield bmu.insert({
- parentGuid: bmu.unfiledGuid,
- index: bmu.DEFAULT_INDEX,
- type: bmu.TYPE_FOLDER,
- title: "folder within unfiled"
- });
-
- // Setup the places tree contents.
- let tree = document.getElementById("tree");
- tree.place = "place:folder=TOOLBAR";
-
- // Select the folder via the selectItems(itemId) API being tested
- let itemId = yield PlacesUtils.promiseItemId(folder.guid);
- tree.selectItems([itemId]);
-
- is(tree.selectedNode && tree.selectedNode.itemId, itemId, "The node was selected through the shortcut");
-
- // Cleanup
- yield bmu.eraseEverything();
-
- }).catch(err => {
- ok(false, `Uncaught error: ${err}`);
- }).then(SimpleTest.finish);
- }
- ]]></script>
-</window>
diff --git a/browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul b/browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul
deleted file mode 100644
index b659b2b46..000000000
--- a/browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?>
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
-
-<!DOCTYPE window [
- <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd">
- %editBookmarkOverlayDTD;
-]>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Bug 427633 - Disable creating a New Folder in the bookmarks dialogs if insertionPoint is invalid"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript"
- src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <vbox id="editBookmarkPanelContent"/>
-
- <script type="application/javascript">
- <![CDATA[
-
- /**
- * Bug 427633 - Disable creating a New Folder in the bookmarks dialogs if
- * insertionPoint is invalid.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- // Add a bookmark.
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- url: "http://www.example.com/",
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- title: "mozilla"
- });
-
- // Init panel.
- ok(gEditItemOverlay, "gEditItemOverlay is in context");
- let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm);
- gEditItemOverlay.initPanel({ node });
- ok(gEditItemOverlay.initialized, "gEditItemOverlay is initialized");
-
- let tree = gEditItemOverlay._element("folderTree");
- yield openFolderTree(tree);
-
- tree.view.selection.clearSelection();
- ok(document.getElementById("editBMPanel_newFolderButton").disabled,
- "New folder button is disabled if there's no selection");
-
- // Cleanup.
- yield PlacesUtils.bookmarks.remove(bm.guid);
- }).then(() => SimpleTest.finish());
- }
-
- function openFolderTree(tree) {
- return new Promise(resolve => {
- tree.addEventListener("DOMAttrModified", function onAttrModified(event) {
- if (event.attrName == "place") {
- tree.removeEventListener("DOMAttrModified", onAttrModified);
- resolve();
- }
- });
-
- // Open the folder tree.
- document.getElementById("editBMPanel_foldersExpander").doCommand();
- });
- }
- ]]>
- </script>
-
-</window>
diff --git a/browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul b/browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul
deleted file mode 100644
index afad950cb..000000000
--- a/browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?>
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
-
-<!DOCTYPE window [
- <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd">
- %editBookmarkOverlayDTD;
-]>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="485100: Exchanging a letter of a tag name with its big/small equivalent removes tag from bookmark"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript"
- src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <vbox id="editBookmarkPanelContent"/>
-
- <script type="application/javascript">
- <![CDATA[
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- let testTag = "foo";
- let testTagUpper = "Foo";
- let testURI = Services.io.newURI("http://www.example.com/", null, null);
-
- // Add a bookmark.
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- title: "mozilla",
- url: testURI
- });
-
- // Init panel
- ok(gEditItemOverlay, "gEditItemOverlay is in context");
- let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm);
- gEditItemOverlay.initPanel({ node });
-
- // add a tag
- document.getElementById("editBMPanel_tagsField").value = testTag;
- gEditItemOverlay.onTagsFieldChange();
-
- // test that the tag has been added in the backend
- is(PlacesUtils.tagging.getTagsForURI(testURI)[0], testTag, "tags match");
-
- // change the tag
- document.getElementById("editBMPanel_tagsField").value = testTagUpper;
- gEditItemOverlay.onTagsFieldChange();
-
- // test that the tag has been added in the backend
- is(PlacesUtils.tagging.getTagsForURI(testURI)[0], testTagUpper, "tags match");
-
- // Cleanup.
- PlacesUtils.tagging.untagURI(testURI, [testTag]);
- yield PlacesUtils.bookmarks.remove(bm.guid);
- }).then(() => SimpleTest.finish());
- }
- ]]>
- </script>
-
-</window>
diff --git a/browser/components/places/tests/chrome/test_bug549192.xul b/browser/components/places/tests/chrome/test_bug549192.xul
deleted file mode 100644
index 4e6a89bb1..000000000
--- a/browser/components/places/tests/chrome/test_bug549192.xul
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/licenses/publicdomain/
- -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="549192: History view not updated after deleting entry"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript" src="head.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <tree id="tree"
- type="places"
- flatList="true"
- flex="1">
- <treecols>
- <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
- </treecols>
- <treechildren flex="1"/>
- </tree>
-
- <script type="application/javascript"><![CDATA[
- /**
- * Bug 874407
- * Ensures that history views are updated properly after visits.
- * Bug 549192
- * Ensures that history views are updated after deleting entries.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- yield PlacesTestUtils.clearHistory();
-
- // Add some visits.
- let timeInMicroseconds = PlacesUtils.toPRTime(Date.now() - 10000);
-
- function newTimeInMicroseconds() {
- timeInMicroseconds = timeInMicroseconds + 1000;
- return timeInMicroseconds;
- }
-
- let vtime = Date.now() * 1000;
- const ttype = PlacesUtils.history.TRANSITION_TYPED;
- let places =
- [{ uri: Services.io.newURI("http://example.tld/", null, null),
- visitDate: newTimeInMicroseconds(), transition: ttype },
- { uri: Services.io.newURI("http://example2.tld/", null, null),
- visitDate: newTimeInMicroseconds(), transition: ttype },
- { uri: Services.io.newURI("http://example3.tld/", null, null),
- visitDate: newTimeInMicroseconds(), transition: ttype }];
-
- yield PlacesTestUtils.addVisits(places);
-
- // Make a history query.
- let query = PlacesUtils.history.getNewQuery();
- let opts = PlacesUtils.history.getNewQueryOptions();
- opts.sortingMode = opts.SORT_BY_DATE_DESCENDING;
- let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
-
- // Setup the places tree contents.
- var tree = document.getElementById("tree");
- tree.place = queryURI;
-
- // loop through the rows and check them.
- let treeView = tree.view;
- let selection = treeView.selection;
- let rc = treeView.rowCount;
-
- for (let i = 0; i < rc; i++) {
- selection.select(i);
- let node = tree.selectedNode;
- is(node.uri, places[rc - i - 1].uri.spec,
- "Found expected node at position " + i + ".");
- }
-
- is(rc, 3, "Found expected number of rows.");
-
- // First check live-update of the view when adding visits.
- places.forEach(place => place.visitDate = newTimeInMicroseconds());
- yield PlacesTestUtils.addVisits(places);
-
- for (let i = 0; i < rc; i++) {
- selection.select(i);
- let node = tree.selectedNode;
- is(node.uri, places[rc - i - 1].uri.spec,
- "Found expected node at position " + i + ".");
- }
-
- // Now remove the pages and verify live-update again.
- for (let i = 0; i < rc; i++) {
- selection.select(0);
- let node = tree.selectedNode;
- tree.controller.remove("Removing page");
- ok(treeView.treeIndexForNode(node) == Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE,
- node.uri + " removed.");
- ok(treeView.rowCount == rc - i - 1, "Rows count decreased");
- }
-
- // Cleanup.
- yield PlacesTestUtils.clearHistory();
- }).then(() => SimpleTest.finish());
- }
- ]]></script>
-</window>
diff --git a/browser/components/places/tests/chrome/test_bug549491.xul b/browser/components/places/tests/chrome/test_bug549491.xul
deleted file mode 100644
index 5ec7a765a..000000000
--- a/browser/components/places/tests/chrome/test_bug549491.xul
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/licenses/publicdomain/
- -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="549491: 'The root node is never visible' exception when details of the root node are modified "
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript" src="head.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <tree id="tree"
- type="places"
- flatList="true"
- flex="1">
- <treecols>
- <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
- <splitter class="tree-splitter"/>
- <treecol label="Date" anonid="date" flex="1"/>
- </treecols>
- <treechildren flex="1"/>
- </tree>
-
- <script type="application/javascript"><![CDATA[
- /**
- * Bug 549491
- * https://bugzilla.mozilla.org/show_bug.cgi?id=549491
- *
- * Ensures that changing the details of places tree's root-node doesn't
- * throw.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- yield PlacesTestUtils.clearHistory();
-
- yield PlacesTestUtils.addVisits({
- uri: Services.io.newURI("http://example.tld/", null, null),
- transition: PlacesUtils.history.TRANSITION_TYPED
- });
-
- // Make a history query.
- let query = PlacesUtils.history.getNewQuery();
- let opts = PlacesUtils.history.getNewQueryOptions();
- let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
-
- // Setup the places tree contents.
- let tree = document.getElementById("tree");
- tree.place = queryURI;
-
- let rootNode = tree.result.root;
- let obs = tree.view.QueryInterface(Ci.nsINavHistoryResultObserver);
- obs.nodeHistoryDetailsChanged(rootNode, rootNode.time, rootNode.accessCount);
- obs.nodeTitleChanged(rootNode, rootNode.title);
- ok(true, "No exceptions thrown");
-
- // Cleanup.
- yield PlacesTestUtils.clearHistory();
- }).then(SimpleTest.finish);
- }
- ]]></script>
-</window>
diff --git a/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul b/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul
deleted file mode 100644
index b1d73017f..000000000
--- a/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?>
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
-
-<!DOCTYPE window [
- <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd">
- %editBookmarkOverlayDTD;
-]>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Bug 631374 - Editing tags in the selector scrolls up the listbox"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript"
- src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <vbox id="editBookmarkPanelContent"/>
-
- <script type="application/javascript">
- <![CDATA[
-
- /**
- * This test checks that editing tags doesn't scroll the tags selector
- * listbox to wrong positions.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- let bs = PlacesUtils.bookmarks;
-
- let tags = ["a", "b", "c", "d", "e", "f", "g",
- "h", "i", "l", "m", "n", "o", "p"];
-
- // Add a bookmark and tag it.
- let uri1 = Services.io.newURI("http://www1.mozilla.org/", null, null);
- let bm1 = yield bs.insert({
- parentGuid: bs.toolbarGuid,
- index: bs.DEFAULT_INDEX,
- type: bs.TYPE_BOOKMARK,
- title: "mozilla",
- url: uri1.spec
- });
- PlacesUtils.tagging.tagURI(uri1, tags);
-
- // Add a second bookmark so that tags won't disappear when unchecked.
- let uri2 = Services.io.newURI("http://www2.mozilla.org/", null, null);
- let bm2 = yield bs.insert({
- parentGuid: bs.toolbarGuid,
- index: bs.DEFAULT_INDEX,
- type: bs.TYPE_BOOKMARK,
- title: "mozilla",
- url: uri2.spec
- });
- PlacesUtils.tagging.tagURI(uri2, tags);
-
- // Init panel.
- ok(gEditItemOverlay, "gEditItemOverlay is in context");
- let node1 = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm1);
- gEditItemOverlay.initPanel({ node: node1 });
- ok(gEditItemOverlay.initialized, "gEditItemOverlay is initialized");
-
- yield openTagSelector();
- let tagsSelector = document.getElementById("editBMPanel_tagsSelector");
-
- // Go by two so there is some untouched tag in the middle.
- for (let i = 8; i < tags.length; i += 2) {
- tagsSelector.selectedIndex = i;
- let listItem = tagsSelector.selectedItem;
- isnot(listItem, null, "Valid listItem found");
-
- tagsSelector.ensureElementIsVisible(listItem);
- let visibleIndex = tagsSelector.getIndexOfFirstVisibleRow();
-
- ok(listItem.checked, "Item is checked " + i);
- let selectedTag = listItem.label;
-
- // Uncheck the tag.
- listItem.checked = false;
- is(visibleIndex, tagsSelector.getIndexOfFirstVisibleRow(),
- "Scroll position did not change");
-
- // The listbox is rebuilt, so we have to get the new element.
- let newItem = tagsSelector.selectedItem;
- isnot(newItem, null, "Valid new listItem found");
- ok(!newItem.checked, "New listItem is unchecked " + i);
- is(newItem.label, selectedTag, "Correct tag is still selected");
-
- // Check the tag.
- newItem.checked = true;
- is(visibleIndex, tagsSelector.getIndexOfFirstVisibleRow(),
- "Scroll position did not change");
- }
-
- // Remove the second bookmark, then nuke some of the tags.
- yield bs.remove(bm2.guid);
-
- // Doing this backwords tests more interesting paths.
- for (let i = tags.length - 1; i >= 0 ; i -= 2) {
- tagsSelector.selectedIndex = i;
- let listItem = tagsSelector.selectedItem;
- isnot(listItem, null, "Valid listItem found");
-
- tagsSelector.ensureElementIsVisible(listItem);
- let firstVisibleTag = tags[tagsSelector.getIndexOfFirstVisibleRow()];
-
- ok(listItem.checked, "Item is checked " + i);
- let selectedTag = listItem.label;
-
- // Uncheck the tag.
- listItem.checked = false;
-
- // Ensure the first visible tag is still visible in the list.
- let firstVisibleIndex = tagsSelector.getIndexOfFirstVisibleRow();
- let lastVisibleIndex = firstVisibleIndex + tagsSelector.getNumberOfVisibleRows() -1;
- let expectedTagIndex = tags.indexOf(firstVisibleTag);
- ok(expectedTagIndex >= firstVisibleIndex &&
- expectedTagIndex <= lastVisibleIndex,
- "Scroll position is correct");
-
- // The listbox is rebuilt, so we have to get the new element.
- let newItem = tagsSelector.selectedItem;
- isnot(newItem, null, "Valid new listItem found");
- ok(newItem.checked, "New listItem is checked " + i);
- is(tagsSelector.selectedItem.label,
- tags[Math.min(i + 1, tags.length - 2)],
- "The next tag is now selected");
- }
-
- // Cleanup.
- yield bs.remove(bm1.guid);
- }).then(SimpleTest.finish).catch(alert);
- }
-
- function openTagSelector() {
- // Wait for the tags selector to be open.
- let promise = new Promise(resolve => {
- let row = document.getElementById("editBMPanel_tagsSelectorRow");
- row.addEventListener("DOMAttrModified", function onAttrModified() {
- row.removeEventListener("DOMAttrModified", onAttrModified);
- resolve();
- });
- });
-
- // Open the tags selector.
- document.getElementById("editBMPanel_tagsSelectorExpander").doCommand();
-
- return promise;
- }
- ]]>
- </script>
-
-</window>
diff --git a/browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul b/browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul
deleted file mode 100644
index f553d018b..000000000
--- a/browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?>
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
-
-<!DOCTYPE window [
- <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd">
- %editBookmarkOverlayDTD;
-]>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Bug 1343256 - Bookmark keywords disappear from one bookmark when adding a keyword to another bookmark"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
- <script type="application/javascript"
- src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <vbox id="editBookmarkPanelContent"/>
-
- <script type="application/javascript">
- <![CDATA[
- function runTest() {
- SimpleTest.waitForExplicitFinish();
- Task.spawn(test.bind(this))
- .catch(ex => ok(false, ex))
- .then(() => PlacesUtils.bookmarks.eraseEverything())
- .then(SimpleTest.finish);
- }
-
- function promiseOnItemChanged() {
- return new Promise(resolve => {
- PlacesUtils.bookmarks.addObserver({
- onBeginUpdateBatch() {},
- onEndUpdateBatch() {},
- onItemAdded() {},
- onItemRemoved() {},
- onItemVisited() {},
- onItemMoved() {},
- onItemChanged(id, property, isAnno, value) {
- PlacesUtils.bookmarks.removeObserver(this);
- resolve({ property, value });
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
- }, false);
- });
- }
-
- function* test() {
- ok(gEditItemOverlay, "Sanity check: gEditItemOverlay is in context");
- let keywordField = document.getElementById("editBMPanel_keywordField");
-
- for (let i = 0; i < 2; ++i) {
- let bm = yield PlacesUtils.bookmarks.insert({
- url: `http://www.test${i}.me/`,
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- });
- info(`Init panel on bookmark #${i+1}`);
- let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm);
- gEditItemOverlay.initPanel({ node });
- is(document.getElementById("editBMPanel_keywordField").value, "",
- "The keyword field should be empty");
- info("Add a keyword to the bookmark");
- let promise = promiseOnItemChanged();
- keywordField.focus();
- keywordField.value = "kw";
- synthesizeKey(i.toString(), {});
- synthesizeKey("VK_RETURN", {});
- keywordField.blur();
- let {property, value} = yield promise;
- is(property, "keyword", "The keyword should have been changed");
- is(value, `kw${i}`, "The new keyword value is correct");
- }
-
- for (let i = 0; i < 2; ++i) {
- let entry = yield PlacesUtils.keywords.fetch({ url: `http://www.test${i}.me/` });
- is(entry.keyword, `kw${i}`, `The keyword for http://www.test${i}.me/ is correct`);
- }
- };
- ]]>
- </script>
-
-</window>
diff --git a/browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul b/browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul
deleted file mode 100644
index 1b1cc6473..000000000
--- a/browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul
+++ /dev/null
@@ -1,204 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?>
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
-
-<!DOCTYPE window [
- <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd">
- %editBookmarkOverlayDTD;
-]>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="485100: Exchanging a letter of a tag name with its big/small equivalent removes tag from bookmark"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript"
- src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <vbox id="editBookmarkPanelContent"/>
-
- <script type="application/javascript">
- <![CDATA[
- function checkTagsSelector(aAvailableTags, aCheckedTags) {
- is(PlacesUtils.tagging.allTags.length, aAvailableTags.length,
- "tagging service is in sync.");
- let tagsSelector = document.getElementById("editBMPanel_tagsSelector");
- let children = tagsSelector.childNodes;
- is(children.length, aAvailableTags.length,
- "Found expected number of tags in the tags selector");
-
- Array.prototype.forEach.call(children, function (aChild) {
- let tag = aChild.getAttribute("label");
- ok(true, "Found tag '" + tag + "' in the selector");
- ok(aAvailableTags.includes(tag), "Found expected tag");
- let checked = aChild.getAttribute("checked") == "true";
- is(checked, aCheckedTags.includes(tag),
- "Tag is correctly marked");
- });
- }
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- const TEST_URI = Services.io.newURI("http://www.test.me/", null, null);
- const TEST_URI2 = Services.io.newURI("http://www.test.again.me/", null, null);
- const TEST_TAG = "test-tag";
-
- ok(gEditItemOverlay, "Sanity check: gEditItemOverlay is in context");
-
- // Open the tags selector.
- document.getElementById("editBMPanel_tagsSelectorRow").collapsed = false;
-
- // Add a bookmark.
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: TEST_URI.spec,
- title: "test.me"
- });
-
- // Init panel.
- let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm);
- gEditItemOverlay.initPanel({ node });
-
- // Add a tag.
- PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]);
-
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG,
- "Correctly added tag to a single bookmark");
- is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG,
- "Editing a single bookmark shows the added tag");
- checkTagsSelector([TEST_TAG], [TEST_TAG]);
-
- // Remove tag.
- PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined,
- "The tag has been removed");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing a single bookmark should not show any tag");
- checkTagsSelector([], []);
-
- // Add a second bookmark.
- let bm2 = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- title: "test.again.me",
- url: TEST_URI2.spec
- });
-
- // Init panel with multiple uris.
- gEditItemOverlay.initPanel({ uris: [TEST_URI, TEST_URI2] });
-
- // Add a tag to the first uri.
- PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG,
- "Correctly added a tag to the first bookmark.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing multiple bookmarks without matching tags should not show any tag.");
- checkTagsSelector([TEST_TAG], []);
-
- // Add a tag to the second uri.
- PlacesUtils.tagging.tagURI(TEST_URI2, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], TEST_TAG,
- "Correctly added a tag to the second bookmark.");
- is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG,
- "Editing multiple bookmarks should show matching tags.");
- checkTagsSelector([TEST_TAG], [TEST_TAG]);
-
- // Remove tag from the first bookmark.
- PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined,
- "Correctly removed tag from the first bookmark.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing multiple bookmarks without matching tags should not show any tag.");
- checkTagsSelector([TEST_TAG], []);
-
- // Remove tag from the second bookmark.
- PlacesUtils.tagging.untagURI(TEST_URI2, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], undefined,
- "Correctly removed tag from the second bookmark.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing multiple bookmarks without matching tags should not show any tag.");
- checkTagsSelector([], []);
-
- // Init panel with a nsIURI entry.
- gEditItemOverlay.initPanel({ uris: [TEST_URI] });
-
- // Add a tag.
- PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG,
- "Correctly added tag to the first entry.");
- is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG,
- "Editing a single nsIURI entry shows the added tag");
- checkTagsSelector([TEST_TAG], [TEST_TAG]);
-
- // Remove tag.
- PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined,
- "Correctly removed tag from the nsIURI entry.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing a single nsIURI entry should not show any tag");
- checkTagsSelector([], []);
-
- // Init panel with multiple nsIURI entries.
- gEditItemOverlay.initPanel({ uris: [TEST_URI, TEST_URI2] });
-
- // Add a tag to the first entry.
- PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG,
- "Tag correctly added.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing multiple nsIURIs without matching tags should not show any tag.");
- checkTagsSelector([TEST_TAG], []);
-
- // Add a tag to the second entry.
- PlacesUtils.tagging.tagURI(TEST_URI2, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], TEST_TAG,
- "Tag correctly added.");
- is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG,
- "Editing multiple nsIURIs should show matching tags");
- checkTagsSelector([TEST_TAG], [TEST_TAG]);
-
- // Remove tag from the first entry.
- PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined,
- "Correctly removed tag from the first entry.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing multiple nsIURIs without matching tags should not show any tag.");
- checkTagsSelector([TEST_TAG], []);
-
- // Remove tag from the second entry.
- PlacesUtils.tagging.untagURI(TEST_URI2, [TEST_TAG]);
- is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], undefined,
- "Correctly removed tag from the second entry.");
- is(document.getElementById("editBMPanel_tagsField").value, "",
- "Editing multiple nsIURIs without matching tags should not show any tag.");
- checkTagsSelector([], []);
-
- // Cleanup.
- yield PlacesUtils.bookmarks.remove(bm.guid);
- yield PlacesUtils.bookmarks.remove(bm2.guid);
- }).then(SimpleTest.finish);
- }
- ]]>
- </script>
-
-</window>
diff --git a/browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul b/browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul
deleted file mode 100644
index 032c7a258..000000000
--- a/browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/licenses/publicdomain/
- -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="549192: History view not updated after deleting entry"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript" src="head.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <tree id="tree"
- type="places"
- flex="1">
- <treecols>
- <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
- </treecols>
- <treechildren flex="1"/>
- </tree>
-
- <script type="application/javascript"><![CDATA[
- /**
- * Ensure that selectItems doesn't recurse infinitely in nested trees.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- Task.spawn(function* () {
- yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "place:folder=UNFILED_BOOKMARKS",
- title: "shortcut"
- });
-
- yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "place:folder=UNFILED_BOOKMARKS&maxResults=10",
- title: "query"
- });
-
- let folder = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- title: "folder"
- });
-
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: folder.guid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "http://www.mozilla.org/",
- title: "bookmark"
- });
-
- // Setup the places tree contents.
- let tree = document.getElementById("tree");
- tree.place = "place:folder=UNFILED_BOOKMARKS";
-
- // Select the last bookmark.
- let itemId = yield PlacesUtils.promiseItemId(bm.guid);
- tree.selectItems([itemId]);
- is (tree.selectedNode.itemId, itemId, "The right node was selected");
- }).then(SimpleTest.finish);
- }
- ]]></script>
-</window>
diff --git a/browser/components/places/tests/chrome/test_treeview_date.xul b/browser/components/places/tests/chrome/test_treeview_date.xul
deleted file mode 100644
index 559232611..000000000
--- a/browser/components/places/tests/chrome/test_treeview_date.xul
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
- type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="435322: Places tree view's formatting"
- onload="runTest();">
-
- <script type="application/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
- <script type="application/javascript" src="head.js" />
-
- <body xmlns="http://www.w3.org/1999/xhtml" />
-
- <tree id="tree"
- type="places"
- flatList="true"
- flex="1">
- <treecols>
- <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
- <splitter class="tree-splitter"/>
- <treecol label="Tags" id="tags" anonid="tags" flex="1"/>
- <splitter class="tree-splitter"/>
- <treecol label="Url" id="url" anonid="url" flex="1"/>
- <splitter class="tree-splitter"/>
- <treecol label="Visit Date" id="date" anonid="date" flex="1"/>
- <splitter class="tree-splitter"/>
- <treecol label="Visit Count" id="visitCount" anonid="visitCount" flex="1"/>
- </treecols>
- <treechildren flex="1"/>
- </tree>
-
- <script type="application/javascript">
- <![CDATA[
-
- /**
- * Bug 435322
- * https://bugzilla.mozilla.org/show_bug.cgi?id=435322
- *
- * Ensures that date in places treeviews is correctly formatted.
- */
-
- function runTest() {
- SimpleTest.waitForExplicitFinish();
-
- function uri(spec) {
- return Services.io.newURI(spec, null, null);
- }
-
- Task.spawn(function* () {
- yield PlacesTestUtils.clearHistory();
-
- let midnight = new Date();
- midnight.setHours(0);
- midnight.setMinutes(0);
- midnight.setSeconds(0);
- midnight.setMilliseconds(0);
-
- // Add a visit 1ms before midnight, a visit at midnight, and
- // a visit 1ms after midnight.
- yield PlacesTestUtils.addVisits([
- {uri: uri("http://before.midnight.com/"),
- visitDate: (midnight.getTime() - 1) * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED},
- {uri: uri("http://at.midnight.com/"),
- visitDate: (midnight.getTime()) * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED},
- {uri: uri("http://after.midnight.com/"),
- visitDate: (midnight.getTime() + 1) * 1000,
- transition: PlacesUtils.history.TRANSITION_TYPED}
- ]);
-
- // add a bookmark to the midnight visit
- let bm = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- url: "http://at.midnight.com/",
- title: "A bookmark at midnight",
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK
- });
-
- // Make a history query.
- let query = PlacesUtils.history.getNewQuery();
- let opts = PlacesUtils.history.getNewQueryOptions();
- let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
-
- // Setup the places tree contents.
- let tree = document.getElementById("tree");
- tree.place = queryURI;
-
- // loop through the rows and check formatting
- let treeView = tree.view;
- let rc = treeView.rowCount;
- ok(rc >= 3, "Rows found");
- let columns = tree.columns;
- ok(columns.count > 0, "Columns found");
- const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Ci.nsIXULChromeRegistry)
- .getSelectedLocale("global", true);
- for (let r = 0; r < rc; r++) {
- let node = treeView.nodeForTreeIndex(r);
- ok(node, "Places node found");
- for (let ci = 0; ci < columns.count; ci++) {
- let c = columns.getColumnAt(ci);
- let text = treeView.getCellText(r, c);
- switch (c.element.getAttribute("anonid")) {
- case "title":
- // The title can differ, we did not set any title so we would
- // expect null, but in such a case the view will generate a title
- // through PlacesUIUtils.getBestTitle.
- if (node.title)
- is(text, node.title, "Title is correct");
- break;
- case "url":
- is(text, node.uri, "Uri is correct");
- break;
- case "date":
- let timeObj = new Date(node.time / 1000);
- // Default is short date format.
- let dtOptions = { year: 'numeric', month: 'numeric', day: 'numeric',
- hour: 'numeric', minute: 'numeric' };
- // For today's visits we don't show date portion.
- if (node.uri == "http://at.midnight.com/" ||
- node.uri == "http://after.midnight.com/") {
- dtOptions = { hour: 'numeric', minute: 'numeric' };
- } else if (node.uri != "http://before.midnight.com/") {
- // Avoid to test spurious uris, due to how the test works
- // a redirecting uri could be put in the tree while we test.
- break;
- }
- let timeStr = timeObj.toLocaleString(locale, dtOptions);
-
- is(text, timeStr, "Date format is correct");
- break;
- case "visitCount":
- is(text, 1, "Visit count is correct");
- break;
- }
- }
- }
-
- // Cleanup.
- yield PlacesUtils.bookmarks.remove(bm.guid);
- yield PlacesTestUtils.clearHistory();
- }).then(SimpleTest.finish);
- }
- ]]>
- </script>
-</window>
diff --git a/browser/components/places/tests/unit/.eslintrc.js b/browser/components/places/tests/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/places/tests/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/places/tests/unit/bookmarks.glue.html b/browser/components/places/tests/unit/bookmarks.glue.html
deleted file mode 100644
index 07b22e9b3..000000000
--- a/browser/components/places/tests/unit/bookmarks.glue.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE NETSCAPE-Bookmark-file-1>
-<!-- This is an automatically generated file.
- It will be read and overwritten.
- DO NOT EDIT! -->
-<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
-<TITLE>Bookmarks</TITLE>
-<H1>Bookmarks Menu</H1>
-
-<DL><p>
- <DT><A HREF="http://example.com/" ADD_DATE="1233157972" LAST_MODIFIED="1233157984">example</A>
- <DT><H3 ADD_DATE="1233157910" LAST_MODIFIED="1233157972" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar</H3>
-<DD>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
- <DL><p>
- <DT><A HREF="http://example.com/" ADD_DATE="1233157972" LAST_MODIFIED="1233157984">example</A>
- </DL><p>
-</DL><p>
diff --git a/browser/components/places/tests/unit/bookmarks.glue.json b/browser/components/places/tests/unit/bookmarks.glue.json
deleted file mode 100644
index 95900e176..000000000
--- a/browser/components/places/tests/unit/bookmarks.glue.json
+++ /dev/null
@@ -1 +0,0 @@
-{"title":"","id":1,"dateAdded":1233157910552624,"lastModified":1233157955206833,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"title":"Bookmarks Menu","id":2,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157993171424,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"title":"examplejson","id":27,"parent":2,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":1,"title":"Bookmarks Toolbar","id":3,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157972101126,"annos":[{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar"}],"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"title":"examplejson","id":26,"parent":3,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":2,"title":"Tags","id":4,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157910582667,"type":"text/x-moz-place-container","root":"tagsFolder","children":[]},{"index":3,"title":"Other Bookmarks","id":5,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157911033315,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[]}]}
diff --git a/browser/components/places/tests/unit/corruptDB.sqlite b/browser/components/places/tests/unit/corruptDB.sqlite
deleted file mode 100644
index b234246ca..000000000
--- a/browser/components/places/tests/unit/corruptDB.sqlite
+++ /dev/null
Binary files differ
diff --git a/browser/components/places/tests/unit/distribution.ini b/browser/components/places/tests/unit/distribution.ini
deleted file mode 100644
index 93e73cb5c..000000000
--- a/browser/components/places/tests/unit/distribution.ini
+++ /dev/null
@@ -1,27 +0,0 @@
-# Distribution Configuration File
-# Bug 516444 demo
-
-[Global]
-id=516444
-version=1.0
-about=Test distribution file
-
-[BookmarksToolbar]
-item.1.title=Toolbar Link Before
-item.1.link=https://example.org/toolbar/before/
-item.1.keyword=e:t:b
-item.1.icon=https://example.org/favicon.png
-item.1.iconData=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==
-item.2.type=default
-item.3.title=Toolbar Link After
-item.3.link=https://example.org/toolbar/after/
-item.3.keyword=e:t:a
-
-[BookmarksMenu]
-item.1.title=Menu Link Before
-item.1.link=https://example.org/menu/before/
-item.1.icon=https://example.org/favicon.png
-item.1.iconData=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==
-item.2.type=default
-item.3.title=Menu Link After
-item.3.link=https://example.org/menu/after/
diff --git a/browser/components/places/tests/unit/head_bookmarks.js b/browser/components/places/tests/unit/head_bookmarks.js
deleted file mode 100644
index 460295f96..000000000
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var Ci = Components.interfaces;
-var Cc = Components.classes;
-var Cr = Components.results;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/LoadContextInfo.jsm");
-
-// Import common head.
-var commonFile = do_get_file("../../../../../toolkit/components/places/tests/head_common.js", false);
-if (commonFile) {
- let uri = Services.io.newFileURI(commonFile);
- Services.scriptloader.loadSubScript(uri.spec, this);
-}
-
-// Put any other stuff relative to this test folder below.
-
-XPCOMUtils.defineLazyGetter(this, "PlacesUIUtils", function() {
- Cu.import("resource:///modules/PlacesUIUtils.jsm");
- return PlacesUIUtils;
-});
-
-const ORGANIZER_FOLDER_ANNO = "PlacesOrganizer/OrganizerFolder";
-const ORGANIZER_QUERY_ANNO = "PlacesOrganizer/OrganizerQuery";
-
-// Needed by some test that relies on having an app registered.
-Cu.import("resource://testing-common/AppInfo.jsm", this);
-updateAppInfo({
- name: "PlacesTest",
- ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
- version: "1",
- platformVersion: "",
-});
-
-// Smart bookmarks constants.
-const SMART_BOOKMARKS_VERSION = 8;
-const SMART_BOOKMARKS_ON_TOOLBAR = 1;
-const SMART_BOOKMARKS_ON_MENU = 2; // Takes into account the additional separator.
-
-// Default bookmarks constants.
-const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1;
-const DEFAULT_BOOKMARKS_ON_MENU = 1;
-
-const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
-
-function checkItemHasAnnotation(guid, name) {
- return PlacesUtils.promiseItemId(guid).then(id => {
- let hasAnnotation = PlacesUtils.annotations.itemHasAnnotation(id, name);
- Assert.ok(hasAnnotation, `Expected annotation ${name}`);
- });
-}
-
-var createCorruptDB = Task.async(function* () {
- let dbPath = OS.Path.join(OS.Constants.Path.profileDir, "places.sqlite");
- yield OS.File.remove(dbPath);
-
- // Create a corrupt database.
- let dir = yield OS.File.getCurrentDirectory();
- let src = OS.Path.join(dir, "corruptDB.sqlite");
- yield OS.File.copy(src, dbPath);
-
- // Check there's a DB now.
- Assert.ok((yield OS.File.exists(dbPath)), "should have a DB now");
-});
-
-/**
- * Rebuilds smart bookmarks listening to console output to report any message or
- * exception generated.
- *
- * @return {Promise}
- * Resolved when done.
- */
-function rebuildSmartBookmarks() {
- let consoleListener = {
- observe(aMsg) {
- if (aMsg.message.startsWith("[JavaScript Warning:")) {
- // TODO (Bug 1300416): Ignore spurious strict warnings.
- return;
- }
- do_throw("Got console message: " + aMsg.message);
- },
- QueryInterface: XPCOMUtils.generateQI([ Ci.nsIConsoleListener ]),
- };
- Services.console.reset();
- Services.console.registerListener(consoleListener);
- do_register_cleanup(() => {
- try {
- Services.console.unregisterListener(consoleListener);
- } catch (ex) { /* will likely fail */ }
- });
- Cc["@mozilla.org/browser/browserglue;1"]
- .getService(Ci.nsIObserver)
- .observe(null, "browser-glue-test", "smart-bookmarks-init");
- return promiseTopicObserved("test-smart-bookmarks-done").then(() => {
- Services.console.unregisterListener(consoleListener);
- });
-}
-
-const SINGLE_TRY_TIMEOUT = 100;
-const NUMBER_OF_TRIES = 30;
-
-/**
- * Similar to waitForConditionPromise, but poll for an asynchronous value
- * every SINGLE_TRY_TIMEOUT ms, for no more than tryCount times.
- *
- * @param promiseFn
- * A function to generate a promise, which resolves to the expected
- * asynchronous value.
- * @param timeoutMsg
- * The reason to reject the returned promise with.
- * @param [optional] tryCount
- * Maximum times to try before rejecting the returned promise with
- * timeoutMsg, defaults to NUMBER_OF_TRIES.
- * @return {Promise}
- * @resolves to the asynchronous value being polled.
- * @rejects if the asynchronous value is not available after tryCount attempts.
- */
-var waitForResolvedPromise = Task.async(function* (promiseFn, timeoutMsg, tryCount=NUMBER_OF_TRIES) {
- let tries = 0;
- do {
- try {
- let value = yield promiseFn();
- return value;
- } catch (ex) {}
- yield new Promise(resolve => do_timeout(SINGLE_TRY_TIMEOUT, resolve));
- } while (++tries <= tryCount);
- throw new Error(timeoutMsg);
-});
diff --git a/browser/components/places/tests/unit/test_421483.js b/browser/components/places/tests/unit/test_421483.js
deleted file mode 100644
index a0d138372..000000000
--- a/browser/components/places/tests/unit/test_421483.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
-
-var gluesvc = Cc["@mozilla.org/browser/browserglue;1"].
- getService(Ci.nsIObserver);
-// Avoid default bookmarks import.
-gluesvc.observe(null, "initial-migration-will-import-default-bookmarks", "");
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* smart_bookmarks_disabled() {
- Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1);
- yield rebuildSmartBookmarks();
-
- let smartBookmarkItemIds =
- PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
- Assert.equal(smartBookmarkItemIds.length, 0);
-
- do_print("check that pref has not been bumped up");
- Assert.equal(Services.prefs.getIntPref("browser.places.smartBookmarksVersion"), -1);
-});
-
-add_task(function* create_smart_bookmarks() {
- Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
- yield rebuildSmartBookmarks();
-
- let smartBookmarkItemIds =
- PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
- Assert.notEqual(smartBookmarkItemIds.length, 0);
-
- do_print("check that pref has been bumped up");
- Assert.ok(Services.prefs.getIntPref("browser.places.smartBookmarksVersion") > 0);
-});
-
-add_task(function* remove_smart_bookmark_and_restore() {
- let smartBookmarkItemIds =
- PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
- let smartBookmarksCount = smartBookmarkItemIds.length;
- do_print("remove one smart bookmark and restore");
-
- let guid = yield PlacesUtils.promiseItemGuid(smartBookmarkItemIds[0]);
- yield PlacesUtils.bookmarks.remove(guid);
- Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
-
- yield rebuildSmartBookmarks();
- smartBookmarkItemIds =
- PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
- Assert.equal(smartBookmarkItemIds.length, smartBookmarksCount);
-
- do_print("check that pref has been bumped up");
- Assert.ok(Services.prefs.getIntPref("browser.places.smartBookmarksVersion") > 0);
-});
-
-add_task(function* move_smart_bookmark_rename_and_restore() {
- let smartBookmarkItemIds =
- PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
- let smartBookmarksCount = smartBookmarkItemIds.length;
- do_print("smart bookmark should be restored in place");
-
- let guid = yield PlacesUtils.promiseItemGuid(smartBookmarkItemIds[0]);
- let bm = yield PlacesUtils.bookmarks.fetch(guid);
- let oldTitle = bm.title;
-
- // create a subfolder and move inside it
- let subfolder = yield PlacesUtils.bookmarks.insert({
- parentGuid: bm.parentGuid,
- title: "test",
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER
- });
-
- // change title and move into new subfolder
- yield PlacesUtils.bookmarks.update({
- guid: guid,
- parentGuid: subfolder.guid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- title: "new title"
- });
-
- // restore
- Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
- yield rebuildSmartBookmarks();
-
- smartBookmarkItemIds =
- PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO);
- Assert.equal(smartBookmarkItemIds.length, smartBookmarksCount);
-
- guid = yield PlacesUtils.promiseItemGuid(smartBookmarkItemIds[0]);
- bm = yield PlacesUtils.bookmarks.fetch(guid);
- Assert.equal(bm.parentGuid, subfolder.guid);
- Assert.equal(bm.title, oldTitle);
-
- do_print("check that pref has been bumped up");
- Assert.ok(Services.prefs.getIntPref("browser.places.smartBookmarksVersion") > 0);
-});
diff --git a/browser/components/places/tests/unit/test_PUIU_makeTransaction.js b/browser/components/places/tests/unit/test_PUIU_makeTransaction.js
deleted file mode 100644
index c0626f53b..000000000
--- a/browser/components/places/tests/unit/test_PUIU_makeTransaction.js
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function waitForBookmarkNotification(aNotification, aCallback, aProperty)
-{
- PlacesUtils.bookmarks.addObserver({
- validate: function (aMethodName, aData)
- {
- if (aMethodName == aNotification &&
- (!aProperty || aProperty == aData.property)) {
- PlacesUtils.bookmarks.removeObserver(this);
- aCallback(aData);
- }
- },
-
- // nsINavBookmarkObserver
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]),
- onBeginUpdateBatch: function onBeginUpdateBatch() {
- return this.validate(arguments.callee.name, arguments);
- },
- onEndUpdateBatch: function onEndUpdateBatch() {
- return this.validate(arguments.callee.name, arguments);
- },
- onItemAdded: function onItemAdded(aItemId, aParentId, aIndex, aItemType,
- aURI, aTitle)
- {
- return this.validate(arguments.callee.name, { id: aItemId,
- index: aIndex,
- type: aItemType,
- url: aURI ? aURI.spec : null,
- title: aTitle });
- },
- onItemRemoved: function onItemRemoved() {
- return this.validate(arguments.callee.name, arguments);
- },
- onItemChanged: function onItemChanged(id, property, aIsAnno,
- aNewValue, aLastModified, type)
- {
- return this.validate(arguments.callee.name,
- { id,
- get index() {
- return PlacesUtils.bookmarks.getItemIndex(this.id);
- },
- type,
- property,
- get url() {
- return type == PlacesUtils.bookmarks.TYPE_BOOKMARK ?
- PlacesUtils.bookmarks.getBookmarkURI(this.id).spec :
- null;
- },
- get title() {
- return PlacesUtils.bookmarks.getItemTitle(this.id);
- },
- });
- },
- onItemVisited: function onItemVisited() {
- return this.validate(arguments.callee.name, arguments);
- },
- onItemMoved: function onItemMoved(aItemId, aOldParentId, aOldIndex,
- aNewParentId, aNewIndex, aItemType)
- {
- this.validate(arguments.callee.name, { id: aItemId,
- index: aNewIndex,
- type: aItemType });
- }
- }, false);
-}
-
-function wrapNodeByIdAndParent(aItemId, aParentId)
-{
- let wrappedNode;
- let root = PlacesUtils.getFolderContents(aParentId, false, false).root;
- for (let i = 0; i < root.childCount; ++i) {
- let node = root.getChild(i);
- if (node.itemId == aItemId) {
- let type;
- if (PlacesUtils.nodeIsContainer(node)) {
- type = PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER;
- }
- else if (PlacesUtils.nodeIsURI(node)) {
- type = PlacesUtils.TYPE_X_MOZ_PLACE;
- }
- else if (PlacesUtils.nodeIsSeparator(node)) {
- type = PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR;
- }
- else {
- do_throw("Unknown node type");
- }
- wrappedNode = PlacesUtils.wrapNode(node, type);
- }
- }
- root.containerOpen = false;
- return JSON.parse(wrappedNode);
-}
-
-add_test(function test_text_paste()
-{
- const TEST_URL = "http://places.moz.org/"
- const TEST_TITLE = "Places bookmark"
-
- waitForBookmarkNotification("onItemAdded", function(aData)
- {
- do_check_eq(aData.title, TEST_TITLE);
- do_check_eq(aData.url, TEST_URL);
- do_check_eq(aData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
- do_check_eq(aData.index, 0);
- run_next_test();
- });
-
- let txn = PlacesUIUtils.makeTransaction(
- { title: TEST_TITLE, uri: TEST_URL },
- PlacesUtils.TYPE_X_MOZ_URL,
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- true // Unused for text.
- );
- PlacesUtils.transactionManager.doTransaction(txn);
-});
-
-add_test(function test_container()
-{
- const TEST_TITLE = "Places folder"
-
- waitForBookmarkNotification("onItemChanged", function(aChangedData)
- {
- do_check_eq(aChangedData.title, TEST_TITLE);
- do_check_eq(aChangedData.type, PlacesUtils.bookmarks.TYPE_FOLDER);
- do_check_eq(aChangedData.index, 1);
-
- waitForBookmarkNotification("onItemAdded", function(aAddedData)
- {
- do_check_eq(aAddedData.title, TEST_TITLE);
- do_check_eq(aAddedData.type, PlacesUtils.bookmarks.TYPE_FOLDER);
- do_check_eq(aAddedData.index, 2);
- let id = aAddedData.id;
-
- waitForBookmarkNotification("onItemMoved", function(aMovedData)
- {
- do_check_eq(aMovedData.id, id);
- do_check_eq(aMovedData.type, PlacesUtils.bookmarks.TYPE_FOLDER);
- do_check_eq(aMovedData.index, 1);
-
- run_next_test();
- });
-
- let txn = PlacesUIUtils.makeTransaction(
- wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId),
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- 1, // Move to position 1.
- false
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- });
-
- try {
- let txn = PlacesUIUtils.makeTransaction(
- wrapNodeByIdAndParent(aChangedData.id, PlacesUtils.unfiledBookmarksFolderId),
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- true
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- } catch (ex) {
- do_throw(ex);
- }
- }, "random-anno");
-
- let id = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
- TEST_TITLE,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- PlacesUtils.annotations.setItemAnnotation(id, PlacesUIUtils.DESCRIPTION_ANNO,
- "description", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
- PlacesUtils.annotations.setItemAnnotation(id, "random-anno",
- "random-value", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
-});
-
-
-add_test(function test_separator()
-{
- waitForBookmarkNotification("onItemChanged", function(aChangedData)
- {
- do_check_eq(aChangedData.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
- do_check_eq(aChangedData.index, 3);
-
- waitForBookmarkNotification("onItemAdded", function(aAddedData)
- {
- do_check_eq(aAddedData.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
- do_check_eq(aAddedData.index, 4);
- let id = aAddedData.id;
-
- waitForBookmarkNotification("onItemMoved", function(aMovedData)
- {
- do_check_eq(aMovedData.id, id);
- do_check_eq(aMovedData.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
- do_check_eq(aMovedData.index, 1);
-
- run_next_test();
- });
-
- let txn = PlacesUIUtils.makeTransaction(
- wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId),
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- 1, // Move to position 1.
- false
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- });
-
- try {
- let txn = PlacesUIUtils.makeTransaction(
- wrapNodeByIdAndParent(aChangedData.id, PlacesUtils.unfiledBookmarksFolderId),
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- true
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- } catch (ex) {
- do_throw(ex);
- }
- }, "random-anno");
-
- let id = PlacesUtils.bookmarks.insertSeparator(PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- PlacesUtils.annotations.setItemAnnotation(id, "random-anno",
- "random-value", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
-});
-
-add_test(function test_bookmark()
-{
- const TEST_URL = "http://places.moz.org/"
- const TEST_TITLE = "Places bookmark"
-
- waitForBookmarkNotification("onItemChanged", function(aChangedData)
- {
- do_check_eq(aChangedData.title, TEST_TITLE);
- do_check_eq(aChangedData.url, TEST_URL);
- do_check_eq(aChangedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
- do_check_eq(aChangedData.index, 5);
-
- waitForBookmarkNotification("onItemAdded", function(aAddedData)
- {
- do_check_eq(aAddedData.title, TEST_TITLE);
- do_check_eq(aAddedData.url, TEST_URL);
- do_check_eq(aAddedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
- do_check_eq(aAddedData.index, 6);
- let id = aAddedData.id;
-
- waitForBookmarkNotification("onItemMoved", function(aMovedData)
- {
- do_check_eq(aMovedData.id, id);
- do_check_eq(aMovedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
- do_check_eq(aMovedData.index, 1);
-
- run_next_test();
- });
-
- let txn = PlacesUIUtils.makeTransaction(
- wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId),
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- 1, // Move to position 1.
- false
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- });
-
- try {
- let txn = PlacesUIUtils.makeTransaction(
- wrapNodeByIdAndParent(aChangedData.id, PlacesUtils.unfiledBookmarksFolderId),
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- true
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- } catch (ex) {
- do_throw(ex);
- }
- }, "random-anno");
-
- let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- NetUtil.newURI(TEST_URL),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- TEST_TITLE);
- PlacesUtils.annotations.setItemAnnotation(id, PlacesUIUtils.DESCRIPTION_ANNO,
- "description", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
- PlacesUtils.annotations.setItemAnnotation(id, "random-anno",
- "random-value", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
-});
-
-add_test(function test_visit()
-{
- const TEST_URL = "http://places.moz.org/"
- const TEST_TITLE = "Places bookmark"
-
- waitForBookmarkNotification("onItemAdded", function(aAddedData)
- {
- do_check_eq(aAddedData.title, TEST_TITLE);
- do_check_eq(aAddedData.url, TEST_URL);
- do_check_eq(aAddedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
- do_check_eq(aAddedData.index, 7);
-
- waitForBookmarkNotification("onItemAdded", function(aAddedData2)
- {
- do_check_eq(aAddedData2.title, TEST_TITLE);
- do_check_eq(aAddedData2.url, TEST_URL);
- do_check_eq(aAddedData2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
- do_check_eq(aAddedData2.index, 8);
- run_next_test();
- });
-
- try {
- let node = wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId);
- // Simulate a not-bookmarked node, will copy it to a new bookmark.
- node.id = -1;
- let txn = PlacesUIUtils.makeTransaction(
- node,
- 0, // Unused for real nodes.
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- true
- );
- PlacesUtils.transactionManager.doTransaction(txn);
- } catch (ex) {
- do_throw(ex);
- }
- });
-
- PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
- NetUtil.newURI(TEST_URL),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- TEST_TITLE);
-});
-
-add_test(function check_annotations() {
- // As last step check how many items for each annotation exist.
-
- // Copies should retain the description annotation.
- let descriptions =
- PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.DESCRIPTION_ANNO, {});
- do_check_eq(descriptions.length, 4);
-
- // Only the original bookmarks should have this annotation.
- let others = PlacesUtils.annotations.getItemsWithAnnotation("random-anno", {});
- do_check_eq(others.length, 3);
- run_next_test();
-});
-
-function run_test()
-{
- run_next_test();
-}
diff --git a/browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js b/browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js
deleted file mode 100644
index 4db21555f..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that nsBrowserGlue correctly exports bookmarks.html at shutdown if
- * browser.bookmarks.autoExportHTML is set to true.
- */
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* () {
- remove_bookmarks_html();
-
- Services.prefs.setBoolPref("browser.bookmarks.autoExportHTML", true);
- do_register_cleanup(() => Services.prefs.clearUserPref("browser.bookmarks.autoExportHTML"));
-
- // Initialize nsBrowserGlue before Places.
- Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports);
-
- // Initialize Places through the History Service.
- Cc["@mozilla.org/browser/nav-history-service;1"]
- .getService(Ci.nsINavHistoryService);
-
- Services.obs.addObserver(function observer() {
- Services.obs.removeObserver(observer, "profile-before-change");
- check_bookmarks_html();
- }, "profile-before-change", false);
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_corrupt.js b/browser/components/places/tests/unit/test_browserGlue_corrupt.js
deleted file mode 100644
index 5b2a09068..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that nsBrowserGlue correctly restores bookmarks from a JSON backup if
- * database is corrupt and one backup is available.
- */
-
-function run_test() {
- // Create our bookmarks.html from bookmarks.glue.html.
- create_bookmarks_html("bookmarks.glue.html");
-
- remove_all_JSON_backups();
-
- // Create our JSON backup from bookmarks.glue.json.
- create_JSON_backup("bookmarks.glue.json");
-
- run_next_test();
-}
-
-do_register_cleanup(function () {
- remove_bookmarks_html();
- remove_all_JSON_backups();
- return PlacesUtils.bookmarks.eraseEverything();
-});
-
-add_task(function* test_main() {
- // Create a corrupt database.
- yield createCorruptDB();
-
- // Initialize nsBrowserGlue before Places.
- Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports);
-
- // Check the database was corrupt.
- // nsBrowserGlue uses databaseStatus to manage initialization.
- Assert.equal(PlacesUtils.history.databaseStatus,
- PlacesUtils.history.DATABASE_STATUS_CORRUPT);
-
- // The test will continue once restore has finished and smart bookmarks
- // have been created.
- yield promiseTopicObserved("places-browser-init-complete");
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
-
- // Check that JSON backup has been restored.
- // Notice restore from JSON notification is fired before smart bookmarks creation.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- });
- Assert.equal(bm.title, "examplejson");
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js
deleted file mode 100644
index 7cb4e5e4c..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that nsBrowserGlue correctly imports from bookmarks.html if database
- * is corrupt but a JSON backup is not available.
- */
-
-function run_test() {
- // Create our bookmarks.html from bookmarks.glue.html.
- create_bookmarks_html("bookmarks.glue.html");
-
- // Remove JSON backup from profile.
- remove_all_JSON_backups();
-
- run_next_test();
-}
-
-do_register_cleanup(remove_bookmarks_html);
-
-add_task(function* () {
- // Create a corrupt database.
- yield createCorruptDB();
-
- // Initialize nsBrowserGlue before Places.
- Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports);
-
- // Check the database was corrupt.
- // nsBrowserGlue uses databaseStatus to manage initialization.
- Assert.equal(PlacesUtils.history.databaseStatus,
- PlacesUtils.history.DATABASE_STATUS_CORRUPT);
-
- // The test will continue once import has finished and smart bookmarks
- // have been created.
- yield promiseTopicObserved("places-browser-init-complete");
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
-
- // Check that bookmarks html has been restored.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- });
- Assert.equal(bm.title, "example");
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js
deleted file mode 100644
index 480420091..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that nsBrowserGlue correctly restores default bookmarks if database is
- * corrupt, nor a JSON backup nor bookmarks.html are available.
- */
-
-Components.utils.import("resource://gre/modules/AppConstants.jsm");
-
-function run_test() {
- // Remove bookmarks.html from profile.
- remove_bookmarks_html();
-
- // Remove JSON backup from profile.
- remove_all_JSON_backups();
-
- run_next_test();
-}
-
-add_task(function* () {
- // Create a corrupt database.
- yield createCorruptDB();
-
- // Initialize nsBrowserGlue before Places.
- Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports);
-
- // Check the database was corrupt.
- // nsBrowserGlue uses databaseStatus to manage initialization.
- Assert.equal(PlacesUtils.history.databaseStatus,
- PlacesUtils.history.DATABASE_STATUS_CORRUPT);
-
- // The test will continue once import has finished and smart bookmarks
- // have been created.
- yield promiseTopicObserved("places-browser-init-complete");
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
-
- // Check that default bookmarks have been restored.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- });
-
- // Bug 1283076: Nightly bookmark points to Get Involved page, not Getting Started one
- let chanTitle = AppConstants.NIGHTLY_BUILD ? "Get Involved" : "Getting Started";
- do_check_eq(bm.title, chanTitle);
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_distribution.js b/browser/components/places/tests/unit/test_browserGlue_distribution.js
deleted file mode 100644
index c3d6e1d9e..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_distribution.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that nsBrowserGlue correctly imports bookmarks from distribution.ini.
- */
-
-const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
-const PREF_BMPROCESSED = "distribution.516444.bookmarksProcessed";
-const PREF_DISTRIBUTION_ID = "distribution.id";
-
-const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization";
-const TOPIC_CUSTOMIZATION_COMPLETE = "distribution-customization-complete";
-const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
-
-function run_test() {
- // Set special pref to load distribution.ini from the profile folder.
- Services.prefs.setBoolPref("distribution.testing.loadFromProfile", true);
-
- // Copy distribution.ini file to the profile dir.
- let distroDir = gProfD.clone();
- distroDir.leafName = "distribution";
- let iniFile = distroDir.clone();
- iniFile.append("distribution.ini");
- if (iniFile.exists()) {
- iniFile.remove(false);
- print("distribution.ini already exists, did some test forget to cleanup?");
- }
-
- let testDistributionFile = gTestDir.clone();
- testDistributionFile.append("distribution.ini");
- testDistributionFile.copyTo(distroDir, "distribution.ini");
- Assert.ok(testDistributionFile.exists());
-
- run_next_test();
-}
-
-do_register_cleanup(function () {
- // Remove the distribution file, even if the test failed, otherwise all
- // next tests will import it.
- let iniFile = gProfD.clone();
- iniFile.leafName = "distribution";
- iniFile.append("distribution.ini");
- if (iniFile.exists()) {
- iniFile.remove(false);
- }
- Assert.ok(!iniFile.exists());
-});
-
-add_task(function* () {
- // Disable Smart Bookmarks creation.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, -1);
-
- // Initialize Places through the History Service and check that a new
- // database has been created.
- Assert.equal(PlacesUtils.history.databaseStatus,
- PlacesUtils.history.DATABASE_STATUS_CREATE);
-
- // Force distribution.
- let glue = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver)
- glue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_DISTRIBUTION_CUSTOMIZATION);
-
- // Test will continue on customization complete notification.
- yield promiseTopicObserved(TOPIC_CUSTOMIZATION_COMPLETE);
-
- // Check the custom bookmarks exist on menu.
- let menuItem = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: 0
- });
- Assert.equal(menuItem.title, "Menu Link Before");
-
- menuItem = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: 1 + DEFAULT_BOOKMARKS_ON_MENU
- });
- Assert.equal(menuItem.title, "Menu Link After");
-
- // Check no favicon or keyword exists for this bookmark
- yield Assert.rejects(waitForResolvedPromise(() => {
- return PlacesUtils.promiseFaviconData(menuItem.url.href);
- }, "Favicon not found", 10), /Favicon\snot\sfound/, "Favicon not found");
-
- let keywordItem = yield PlacesUtils.keywords.fetch({
- url: menuItem.url.href
- });
- Assert.strictEqual(keywordItem, null);
-
- // Check the custom bookmarks exist on toolbar.
- let toolbarItem = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- Assert.equal(toolbarItem.title, "Toolbar Link Before");
-
- // Check the custom favicon and keyword exist for this bookmark
- let faviconItem = yield waitForResolvedPromise(() => {
- return PlacesUtils.promiseFaviconData(toolbarItem.url.href);
- }, "Favicon not found", 10);
- Assert.equal(faviconItem.uri.spec, "https://example.org/favicon.png");
- Assert.greater(faviconItem.dataLen, 0);
- Assert.equal(faviconItem.mimeType, "image/png");
-
- let base64Icon = "data:image/png;base64," +
- base64EncodeString(String.fromCharCode.apply(String, faviconItem.data));
- Assert.equal(base64Icon, SMALLPNG_DATA_URI.spec);
-
- keywordItem = yield PlacesUtils.keywords.fetch({
- url: toolbarItem.url.href
- });
- Assert.notStrictEqual(keywordItem, null);
- Assert.equal(keywordItem.keyword, "e:t:b");
-
- toolbarItem = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 1 + DEFAULT_BOOKMARKS_ON_TOOLBAR
- });
- Assert.equal(toolbarItem.title, "Toolbar Link After");
-
- // Check the bmprocessed pref has been created.
- Assert.ok(Services.prefs.getBoolPref(PREF_BMPROCESSED));
-
- // Check distribution prefs have been created.
- Assert.equal(Services.prefs.getCharPref(PREF_DISTRIBUTION_ID), "516444");
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_migrate.js b/browser/components/places/tests/unit/test_browserGlue_migrate.js
deleted file mode 100644
index 817f10c81..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_migrate.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that nsBrowserGlue does not overwrite bookmarks imported from the
- * migrators. They usually run before nsBrowserGlue, so if we find any
- * bookmark on init, we should not try to import.
- */
-
-const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
-
-function run_test() {
- // Create our bookmarks.html from bookmarks.glue.html.
- create_bookmarks_html("bookmarks.glue.html");
-
- // Remove current database file.
- clearDB();
-
- run_next_test();
-}
-
-do_register_cleanup(remove_bookmarks_html);
-
-add_task(function* test_migrate_bookmarks() {
- // Initialize Places through the History Service and check that a new
- // database has been created.
- Assert.equal(PlacesUtils.history.databaseStatus,
- PlacesUtils.history.DATABASE_STATUS_CREATE);
-
- // A migrator would run before nsBrowserGlue Places initialization, so mimic
- // that behavior adding a bookmark and notifying the migration.
- let bg = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver);
- bg.observe(null, "initial-migration-will-import-default-bookmarks", null);
-
- yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
- url: "http://mozilla.org/",
- title: "migrated"
- });
-
- let promise = promiseTopicObserved("places-browser-init-complete");
- bg.observe(null, "initial-migration-did-import-default-bookmarks", null);
- yield promise;
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
-
- // Check the created bookmark still exists.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: SMART_BOOKMARKS_ON_MENU
- });
- Assert.equal(bm.title, "migrated");
-
- // Check that we have not imported any new bookmark.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: SMART_BOOKMARKS_ON_MENU + 1
- })));
-
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_MENU
- })));
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_prefs.js b/browser/components/places/tests/unit/test_browserGlue_prefs.js
deleted file mode 100644
index 9f3504636..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_prefs.js
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that nsBrowserGlue is correctly interpreting the preferences settable
- * by the user or by other components.
- */
-
-const PREF_IMPORT_BOOKMARKS_HTML = "browser.places.importBookmarksHTML";
-const PREF_RESTORE_DEFAULT_BOOKMARKS = "browser.bookmarks.restore_default_bookmarks";
-const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
-const PREF_AUTO_EXPORT_HTML = "browser.bookmarks.autoExportHTML";
-
-const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
-const TOPICDATA_FORCE_PLACES_INIT = "force-places-init";
-
-var bg = Cc["@mozilla.org/browser/browserglue;1"].
- getService(Ci.nsIObserver);
-
-function run_test() {
- // Create our bookmarks.html from bookmarks.glue.html.
- create_bookmarks_html("bookmarks.glue.html");
-
- remove_all_JSON_backups();
-
- // Create our JSON backup from bookmarks.glue.json.
- create_JSON_backup("bookmarks.glue.json");
-
- run_next_test();
-}
-
-do_register_cleanup(function () {
- remove_bookmarks_html();
- remove_all_JSON_backups();
-
- return PlacesUtils.bookmarks.eraseEverything();
-});
-
-function simulatePlacesInit() {
- do_print("Simulate Places init");
- // Force nsBrowserGlue::_initPlaces().
- bg.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_FORCE_PLACES_INIT);
- return promiseTopicObserved("places-browser-init-complete");
-}
-
-add_task(function* test_checkPreferences() {
- // Initialize Places through the History Service and check that a new
- // database has been created.
- Assert.equal(PlacesUtils.history.databaseStatus,
- PlacesUtils.history.DATABASE_STATUS_CREATE);
-
- // Wait for Places init notification.
- yield promiseTopicObserved("places-browser-init-complete");
-
- // Ensure preferences status.
- Assert.ok(!Services.prefs.getBoolPref(PREF_AUTO_EXPORT_HTML));
-
- Assert.throws(() => Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
- Assert.throws(() => Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
-});
-
-add_task(function* test_import() {
- do_print("Import from bookmarks.html if importBookmarksHTML is true.");
-
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check: we should not have any bookmark on the toolbar.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- })));
-
- // Set preferences.
- Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
-
- yield simulatePlacesInit();
-
- // Check bookmarks.html has been imported, and a smart bookmark has been
- // created.
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- });
- Assert.equal(bm.title, "example");
-
- // Check preferences have been reverted.
- Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-});
-
-add_task(function* test_import_noSmartBookmarks() {
- do_print("import from bookmarks.html, but don't create smart bookmarks " +
- "if they are disabled");
-
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check: we should not have any bookmark on the toolbar.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- })));
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, -1);
- Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
-
- yield simulatePlacesInit();
-
- // Check bookmarks.html has been imported, but smart bookmarks have not
- // been created.
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- Assert.equal(bm.title, "example");
-
- // Check preferences have been reverted.
- Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-});
-
-add_task(function* test_import_autoExport_updatedSmartBookmarks() {
- do_print("Import from bookmarks.html, but don't create smart bookmarks " +
- "if autoExportHTML is true and they are at latest version");
-
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check: we should not have any bookmark on the toolbar.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- })));
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 999);
- Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
- Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
-
- yield simulatePlacesInit();
-
- // Check bookmarks.html has been imported, but smart bookmarks have not
- // been created.
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- Assert.equal(bm.title, "example");
-
- // Check preferences have been reverted.
- Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-
- Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
-});
-
-add_task(function* test_import_autoExport_oldSmartBookmarks() {
- do_print("Import from bookmarks.html, and create smart bookmarks if " +
- "autoExportHTML is true and they are not at latest version.");
-
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check: we should not have any bookmark on the toolbar.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- })));
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 0);
- Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
- Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
-
- yield simulatePlacesInit();
-
- // Check bookmarks.html has been imported, but smart bookmarks have not
- // been created.
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- });
- Assert.equal(bm.title, "example");
-
- // Check preferences have been reverted.
- Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-
- Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
-});
-
-add_task(function* test_restore() {
- do_print("restore from default bookmarks.html if " +
- "restore_default_bookmarks is true.");
-
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check: we should not have any bookmark on the toolbar.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- })));
-
- // Set preferences.
- Services.prefs.setBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS, true);
-
- yield simulatePlacesInit();
-
- // Check bookmarks.html has been restored.
- Assert.ok(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- }));
-
- // Check preferences have been reverted.
- Assert.ok(!Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
-});
-
-add_task(function* test_restore_import() {
- do_print("setting both importBookmarksHTML and " +
- "restore_default_bookmarks should restore defaults.");
-
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check: we should not have any bookmark on the toolbar.
- Assert.ok(!(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- })));
-
- // Set preferences.
- Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true);
- Services.prefs.setBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS, true);
-
- yield simulatePlacesInit();
-
- // Check bookmarks.html has been restored.
- Assert.ok(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- }));
-
- // Check preferences have been reverted.
- Assert.ok(!Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
- Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_restore.js b/browser/components/places/tests/unit/test_browserGlue_restore.js
deleted file mode 100644
index 9d7ac5ac1..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_restore.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that nsBrowserGlue correctly restores bookmarks from a JSON backup if
- * database has been created and one backup is available.
- */
-
-function run_test() {
- // Create our bookmarks.html from bookmarks.glue.html.
- create_bookmarks_html("bookmarks.glue.html");
-
- remove_all_JSON_backups();
-
- // Create our JSON backup from bookmarks.glue.json.
- create_JSON_backup("bookmarks.glue.json");
-
- // Remove current database file.
- clearDB();
-
- run_next_test();
-}
-
-do_register_cleanup(function () {
- remove_bookmarks_html();
- remove_all_JSON_backups();
- return PlacesUtils.bookmarks.eraseEverything();
-});
-
-add_task(function* test_main() {
- // Initialize nsBrowserGlue before Places.
- Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports);
-
- // Initialize Places through the History Service.
- let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
- getService(Ci.nsINavHistoryService);
-
- // Check a new database has been created.
- // nsBrowserGlue uses databaseStatus to manage initialization.
- Assert.equal(hs.databaseStatus, hs.DATABASE_STATUS_CREATE);
-
- // The test will continue once restore has finished and smart bookmarks
- // have been created.
- yield promiseTopicObserved("places-browser-init-complete");
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
-
- // Check that JSON backup has been restored.
- // Notice restore from JSON notification is fired before smart bookmarks creation.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: SMART_BOOKMARKS_ON_TOOLBAR
- });
- Assert.equal(bm.title, "examplejson");
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js b/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js
deleted file mode 100644
index 6ecaec4fe..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js
+++ /dev/null
@@ -1,285 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that nsBrowserGlue is correctly interpreting the preferences settable
- * by the user or by other components.
- */
-
-const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
-const PREF_AUTO_EXPORT_HTML = "browser.bookmarks.autoExportHTML";
-const PREF_IMPORT_BOOKMARKS_HTML = "browser.places.importBookmarksHTML";
-const PREF_RESTORE_DEFAULT_BOOKMARKS = "browser.bookmarks.restore_default_bookmarks";
-
-function run_test() {
- remove_bookmarks_html();
- remove_all_JSON_backups();
- run_next_test();
-}
-
-do_register_cleanup(() => PlacesUtils.bookmarks.eraseEverything());
-
-function countFolderChildren(aFolderItemId) {
- let rootNode = PlacesUtils.getFolderContents(aFolderItemId).root;
- let cc = rootNode.childCount;
- // Dump contents.
- for (let i = 0; i < cc ; i++) {
- let node = rootNode.getChild(i);
- let title = PlacesUtils.nodeIsSeparator(node) ? "---" : node.title;
- print("Found child(" + i + "): " + title);
- }
- rootNode.containerOpen = false;
- return cc;
-}
-
-add_task(function* setup() {
- // Initialize browserGlue, but remove it's listener to places-init-complete.
- Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver);
-
- // Initialize Places.
- PlacesUtils.history;
-
- // Wait for Places init notification.
- yield promiseTopicObserved("places-browser-init-complete");
-
- // Ensure preferences status.
- Assert.ok(!Services.prefs.getBoolPref(PREF_AUTO_EXPORT_HTML));
- Assert.ok(!Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
- Assert.throws(() => Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
-});
-
-add_task(function* test_version_0() {
- do_print("All smart bookmarks are created if smart bookmarks version is 0.");
-
- // Sanity check: we should have default bookmark.
- Assert.ok(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- }));
-
- Assert.ok(yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: 0
- }));
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 0);
-
- yield rebuildSmartBookmarks();
-
- // Count items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Check version has been updated.
- Assert.equal(Services.prefs.getIntPref(PREF_SMART_BOOKMARKS_VERSION),
- SMART_BOOKMARKS_VERSION);
-});
-
-add_task(function* test_version_change() {
- do_print("An existing smart bookmark is replaced when version changes.");
-
- // Sanity check: we have a smart bookmark on the toolbar.
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
-
- // Change its title.
- yield PlacesUtils.bookmarks.update({guid: bm.guid, title: "new title"});
- bm = yield PlacesUtils.bookmarks.fetch({guid: bm.guid});
- Assert.equal(bm.title, "new title");
-
- // Sanity check items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 1);
-
- yield rebuildSmartBookmarks();
-
- // Count items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Check smart bookmark has been replaced, itemId has changed.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
- Assert.notEqual(bm.title, "new title");
-
- // Check version has been updated.
- Assert.equal(Services.prefs.getIntPref(PREF_SMART_BOOKMARKS_VERSION),
- SMART_BOOKMARKS_VERSION);
-});
-
-add_task(function* test_version_change_pos() {
- do_print("bookmarks position is retained when version changes.");
-
- // Sanity check items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
- let firstItemTitle = bm.title;
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 1);
-
- yield rebuildSmartBookmarks();
-
- // Count items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Check smart bookmarks are still in correct position.
- bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm.guid, SMART_BOOKMARKS_ANNO);
- Assert.equal(bm.title, firstItemTitle);
-
- // Check version has been updated.
- Assert.equal(Services.prefs.getIntPref(PREF_SMART_BOOKMARKS_VERSION),
- SMART_BOOKMARKS_VERSION);
-});
-
-add_task(function* test_version_change_pos_moved() {
- do_print("moved bookmarks position is retained when version changes.");
-
- // Sanity check items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- let bm1 = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: 0
- });
- yield checkItemHasAnnotation(bm1.guid, SMART_BOOKMARKS_ANNO);
- let firstItemTitle = bm1.title;
-
- // Move the first smart bookmark to the end of the menu.
- yield PlacesUtils.bookmarks.update({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- guid: bm1.guid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX
- });
-
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX
- });
- Assert.equal(bm.guid, bm1.guid);
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 1);
-
- yield rebuildSmartBookmarks();
-
- // Count items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- bm1 = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- index: PlacesUtils.bookmarks.DEFAULT_INDEX
- });
- yield checkItemHasAnnotation(bm1.guid, SMART_BOOKMARKS_ANNO);
- Assert.equal(bm1.title, firstItemTitle);
-
- // Move back the smart bookmark to the original position.
- yield PlacesUtils.bookmarks.update({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- guid: bm1.guid,
- index: 1
- });
-
- // Check version has been updated.
- Assert.equal(Services.prefs.getIntPref(PREF_SMART_BOOKMARKS_VERSION),
- SMART_BOOKMARKS_VERSION);
-});
-
-add_task(function* test_recreation() {
- do_print("An explicitly removed smart bookmark should not be recreated.");
-
- // Remove toolbar's smart bookmarks
- let bm = yield PlacesUtils.bookmarks.fetch({
- parentGuid: PlacesUtils.bookmarks.toolbarGuid,
- index: 0
- });
- yield PlacesUtils.bookmarks.remove(bm.guid);
-
- // Sanity check items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 1);
-
- yield rebuildSmartBookmarks();
-
- // Count items.
- // We should not have recreated the smart bookmark on toolbar.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Check version has been updated.
- Assert.equal(Services.prefs.getIntPref(PREF_SMART_BOOKMARKS_VERSION),
- SMART_BOOKMARKS_VERSION);
-});
-
-add_task(function* test_recreation_version_0() {
- do_print("Even if a smart bookmark has been removed recreate it if version is 0.");
-
- // Sanity check items.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Set preferences.
- Services.prefs.setIntPref(PREF_SMART_BOOKMARKS_VERSION, 0);
-
- yield rebuildSmartBookmarks();
-
- // Count items.
- // We should not have recreated the smart bookmark on toolbar.
- Assert.equal(countFolderChildren(PlacesUtils.toolbarFolderId),
- SMART_BOOKMARKS_ON_TOOLBAR + DEFAULT_BOOKMARKS_ON_TOOLBAR);
- Assert.equal(countFolderChildren(PlacesUtils.bookmarksMenuFolderId),
- SMART_BOOKMARKS_ON_MENU + DEFAULT_BOOKMARKS_ON_MENU);
-
- // Check version has been updated.
- Assert.equal(Services.prefs.getIntPref(PREF_SMART_BOOKMARKS_VERSION),
- SMART_BOOKMARKS_VERSION);
-});
diff --git a/browser/components/places/tests/unit/test_browserGlue_urlbar_defaultbehavior_migration.js b/browser/components/places/tests/unit/test_browserGlue_urlbar_defaultbehavior_migration.js
deleted file mode 100644
index 072056b3f..000000000
--- a/browser/components/places/tests/unit/test_browserGlue_urlbar_defaultbehavior_migration.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const UI_VERSION = 26;
-const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
-const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
-const DEFAULT_BEHAVIOR_PREF = "browser.urlbar.default.behavior";
-const AUTOCOMPLETE_PREF = "browser.urlbar.autocomplete.enabled";
-
-var gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"]
- .getService(Ci.nsIObserver);
-var gGetBoolPref = Services.prefs.getBoolPref;
-
-function run_test() {
- run_next_test();
-}
-
-do_register_cleanup(cleanup);
-
-function cleanup() {
- let prefix = "browser.urlbar.suggest.";
- for (let type of ["history", "bookmark", "openpage", "history.onlyTyped"]) {
- Services.prefs.clearUserPref(prefix + type);
- }
- Services.prefs.clearUserPref("browser.migration.version");
- Services.prefs.clearUserPref(AUTOCOMPLETE_PREF);
-}
-
-function setupBehaviorAndMigrate(aDefaultBehavior, aAutocompleteEnabled = true) {
- cleanup();
- // Migrate browser.urlbar.default.behavior preference.
- Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
- Services.prefs.setIntPref(DEFAULT_BEHAVIOR_PREF, aDefaultBehavior);
- Services.prefs.setBoolPref(AUTOCOMPLETE_PREF, aAutocompleteEnabled);
- // Simulate a migration.
- gBrowserGlue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_BROWSERGLUE_TEST);
-}
-
-add_task(function*() {
- do_print("Migrate default.behavior = 0");
- setupBehaviorAndMigrate(0);
-
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history"),
- "History preference should be true.");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.bookmark"),
- "Bookmark preference should be true.");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.openpage"),
- "Openpage preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false.");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 1");
- setupBehaviorAndMigrate(1);
-
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history"),
- "History preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.bookmark"), false,
- "Bookmark preference should be false.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.openpage"), false,
- "Openpage preference should be false");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 2");
- setupBehaviorAndMigrate(2);
-
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history"), false,
- "History preference should be false.");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.bookmark"),
- "Bookmark preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.openpage"), false,
- "Openpage preference should be false");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 3");
- setupBehaviorAndMigrate(3);
-
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history"),
- "History preference should be true.");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.bookmark"),
- "Bookmark preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.openpage"), false,
- "Openpage preference should be false");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 19");
- setupBehaviorAndMigrate(19);
-
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history"),
- "History preference should be true.");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.bookmark"),
- "Bookmark preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.openpage"), false,
- "Openpage preference should be false");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 33");
- setupBehaviorAndMigrate(33);
-
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history"),
- "History preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.bookmark"), false,
- "Bookmark preference should be false.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.openpage"), false,
- "Openpage preference should be false");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"),
- "Typed preference should be true");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 129");
- setupBehaviorAndMigrate(129);
-
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.history"),
- "History preference should be true.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.bookmark"), false,
- "Bookmark preference should be false.");
- Assert.ok(gGetBoolPref("browser.urlbar.suggest.openpage"),
- "Openpage preference should be true");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false");
-});
-
-add_task(function*() {
- do_print("Migrate default.behavior = 0, autocomplete.enabled = false");
- setupBehaviorAndMigrate(0, false);
-
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history"), false,
- "History preference should be false.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.bookmark"), false,
- "Bookmark preference should be false.");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.openpage"), false,
- "Openpage preference should be false");
- Assert.equal(gGetBoolPref("browser.urlbar.suggest.history.onlyTyped"), false,
- "Typed preference should be false");
-});
diff --git a/browser/components/places/tests/unit/test_clearHistory_shutdown.js b/browser/components/places/tests/unit/test_clearHistory_shutdown.js
deleted file mode 100644
index 0c1d78801..000000000
--- a/browser/components/places/tests/unit/test_clearHistory_shutdown.js
+++ /dev/null
@@ -1,181 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that requesting clear history at shutdown will really clear history.
- */
-
-const URIS = [
- "http://a.example1.com/"
-, "http://b.example1.com/"
-, "http://b.example2.com/"
-, "http://c.example3.com/"
-];
-
-const TOPIC_CONNECTION_CLOSED = "places-connection-closed";
-
-var EXPECTED_NOTIFICATIONS = [
- "places-shutdown"
-, "places-will-close-connection"
-, "places-expiration-finished"
-, "places-connection-closed"
-];
-
-const UNEXPECTED_NOTIFICATIONS = [
- "xpcom-shutdown"
-];
-
-const FTP_URL = "ftp://localhost/clearHistoryOnShutdown/";
-
-// Send the profile-after-change notification to the form history component to ensure
-// that it has been initialized.
-var formHistoryStartup = Cc["@mozilla.org/satchel/form-history-startup;1"].
- getService(Ci.nsIObserver);
-formHistoryStartup.observe(null, "profile-after-change", null);
-XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
- "resource://gre/modules/FormHistory.jsm");
-
-var timeInMicroseconds = Date.now() * 1000;
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* test_execute() {
- do_print("Initialize browserglue before Places");
-
- // Avoid default bookmarks import.
- let glue = Cc["@mozilla.org/browser/browserglue;1"].
- getService(Ci.nsIObserver);
- glue.observe(null, "initial-migration-will-import-default-bookmarks", null);
- glue.observe(null, "test-initialize-sanitizer", null);
-
-
- Services.prefs.setBoolPref("privacy.clearOnShutdown.cache", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.offlineApps", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.history", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.downloads", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.formData", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.sessions", true);
- Services.prefs.setBoolPref("privacy.clearOnShutdown.siteSettings", true);
-
- Services.prefs.setBoolPref("privacy.sanitize.sanitizeOnShutdown", true);
-
- do_print("Add visits.");
- for (let aUrl of URIS) {
- yield PlacesTestUtils.addVisits({
- uri: uri(aUrl), visitDate: timeInMicroseconds++,
- transition: PlacesUtils.history.TRANSITION_TYPED
- });
- }
- do_print("Add cache.");
- yield storeCache(FTP_URL, "testData");
- do_print("Add form history.");
- yield addFormHistory();
- Assert.equal((yield getFormHistoryCount()), 1, "Added form history");
-
- do_print("Simulate and wait shutdown.");
- yield shutdownPlaces();
-
- Assert.equal((yield getFormHistoryCount()), 0, "Form history cleared");
-
- let stmt = DBConn(true).createStatement(
- "SELECT id FROM moz_places WHERE url = :page_url "
- );
-
- try {
- URIS.forEach(function(aUrl) {
- stmt.params.page_url = aUrl;
- do_check_false(stmt.executeStep());
- stmt.reset();
- });
- } finally {
- stmt.finalize();
- }
-
- do_print("Check cache");
- // Check cache.
- yield checkCache(FTP_URL);
-});
-
-function addFormHistory() {
- return new Promise(resolve => {
- let now = Date.now() * 1000;
- FormHistory.update({ op: "add",
- fieldname: "testfield",
- value: "test",
- timesUsed: 1,
- firstUsed: now,
- lastUsed: now
- },
- { handleCompletion(reason) { resolve(); } });
- });
-}
-
-function getFormHistoryCount() {
- return new Promise((resolve, reject) => {
- let count = -1;
- FormHistory.count({ fieldname: "testfield" },
- { handleResult(result) { count = result; },
- handleCompletion(reason) { resolve(count); }
- });
- });
-}
-
-function storeCache(aURL, aContent) {
- let cache = Services.cache2;
- let storage = cache.diskCacheStorage(LoadContextInfo.default, false);
-
- return new Promise(resolve => {
- let storeCacheListener = {
- onCacheEntryCheck: function (entry, appcache) {
- return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
- },
-
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- do_check_eq(status, Cr.NS_OK);
-
- entry.setMetaDataElement("servertype", "0");
- var os = entry.openOutputStream(0);
-
- var written = os.write(aContent, aContent.length);
- if (written != aContent.length) {
- do_throw("os.write has not written all data!\n" +
- " Expected: " + written + "\n" +
- " Actual: " + aContent.length + "\n");
- }
- os.close();
- entry.close();
- resolve();
- }
- };
-
- storage.asyncOpenURI(Services.io.newURI(aURL, null, null), "",
- Ci.nsICacheStorage.OPEN_NORMALLY,
- storeCacheListener);
- });
-}
-
-
-function checkCache(aURL) {
- let cache = Services.cache2;
- let storage = cache.diskCacheStorage(LoadContextInfo.default, false);
-
- return new Promise(resolve => {
- let checkCacheListener = {
- onCacheEntryAvailable: function (entry, isnew, appcache, status) {
- do_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
- resolve();
- }
- };
-
- storage.asyncOpenURI(Services.io.newURI(aURL, null, null), "",
- Ci.nsICacheStorage.OPEN_READONLY,
- checkCacheListener);
- });
-}
diff --git a/browser/components/places/tests/unit/test_leftpane_corruption_handling.js b/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
deleted file mode 100644
index 0af6f4e95..000000000
--- a/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Tests that we build a working leftpane in various corruption situations.
- */
-
-// Used to store the original leftPaneFolderId getter.
-var gLeftPaneFolderIdGetter;
-var gAllBookmarksFolderIdGetter;
-// Used to store the original left Pane status as a JSON string.
-var gReferenceHierarchy;
-var gLeftPaneFolderId;
-
-add_task(function* () {
- // We want empty roots.
- yield PlacesUtils.bookmarks.eraseEverything();
-
- // Sanity check.
- Assert.ok(!!PlacesUIUtils);
-
- // Check getters.
- gLeftPaneFolderIdGetter = Object.getOwnPropertyDescriptor(PlacesUIUtils, "leftPaneFolderId");
- Assert.equal(typeof(gLeftPaneFolderIdGetter.get), "function");
- gAllBookmarksFolderIdGetter = Object.getOwnPropertyDescriptor(PlacesUIUtils, "allBookmarksFolderId");
- Assert.equal(typeof(gAllBookmarksFolderIdGetter.get), "function");
-
- do_register_cleanup(() => PlacesUtils.bookmarks.eraseEverything());
-});
-
-add_task(function* () {
- // Add a third party bogus annotated item. Should not be removed.
- let folder = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- title: "test",
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER
- });
-
- let folderId = yield PlacesUtils.promiseItemId(folder.guid);
- PlacesUtils.annotations.setItemAnnotation(folderId, ORGANIZER_QUERY_ANNO,
- "test", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
-
- // Create the left pane, and store its current status, it will be used
- // as reference value.
- gLeftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
- gReferenceHierarchy = folderIdToHierarchy(gLeftPaneFolderId);
-
- while (gTests.length) {
- // Run current test.
- yield Task.spawn(gTests.shift());
-
- // Regenerate getters.
- Object.defineProperty(PlacesUIUtils, "leftPaneFolderId", gLeftPaneFolderIdGetter);
- gLeftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
- Object.defineProperty(PlacesUIUtils, "allBookmarksFolderId", gAllBookmarksFolderIdGetter);
-
- // Check the new left pane folder.
- let leftPaneHierarchy = folderIdToHierarchy(gLeftPaneFolderId)
- Assert.equal(gReferenceHierarchy, leftPaneHierarchy);
-
- folder = yield PlacesUtils.bookmarks.fetch({guid: folder.guid});
- Assert.equal(folder.title, "test");
- }
-});
-
-// Corruption cases.
-var gTests = [
-
- function* test1() {
- print("1. Do nothing, checks test calibration.");
- },
-
- function* test2() {
- print("2. Delete the left pane folder.");
- let guid = yield PlacesUtils.promiseItemGuid(gLeftPaneFolderId);
- yield PlacesUtils.bookmarks.remove(guid);
- },
-
- function* test3() {
- print("3. Delete a child of the left pane folder.");
- let guid = yield PlacesUtils.promiseItemGuid(gLeftPaneFolderId);
- let bm = yield PlacesUtils.bookmarks.fetch({parentGuid: guid, index: 0});
- yield PlacesUtils.bookmarks.remove(bm.guid);
- },
-
- function* test4() {
- print("4. Delete AllBookmarks.");
- let guid = yield PlacesUtils.promiseItemGuid(PlacesUIUtils.allBookmarksFolderId);
- yield PlacesUtils.bookmarks.remove(guid);
- },
-
- function* test5() {
- print("5. Create a duplicated left pane folder.");
- let folder = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- title: "PlacesRoot",
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER
- });
-
- let folderId = yield PlacesUtils.promiseItemId(folder.guid);
- PlacesUtils.annotations.setItemAnnotation(folderId, ORGANIZER_FOLDER_ANNO,
- "PlacesRoot", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
- },
-
- function* test6() {
- print("6. Create a duplicated left pane query.");
- let folder = yield PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.unfiledGuid,
- title: "AllBookmarks",
- index: PlacesUtils.bookmarks.DEFAULT_INDEX,
- type: PlacesUtils.bookmarks.TYPE_FOLDER
- });
-
- let folderId = yield PlacesUtils.promiseItemId(folder.guid);
- PlacesUtils.annotations.setItemAnnotation(folderId, ORGANIZER_QUERY_ANNO,
- "AllBookmarks", 0,
- PlacesUtils.annotations.EXPIRE_NEVER);
- },
-
- function* test7() {
- print("7. Remove the left pane folder annotation.");
- PlacesUtils.annotations.removeItemAnnotation(gLeftPaneFolderId,
- ORGANIZER_FOLDER_ANNO);
- },
-
- function* test8() {
- print("8. Remove a left pane query annotation.");
- PlacesUtils.annotations.removeItemAnnotation(PlacesUIUtils.allBookmarksFolderId,
- ORGANIZER_QUERY_ANNO);
- },
-
- function* test9() {
- print("9. Remove a child of AllBookmarks.");
- let guid = yield PlacesUtils.promiseItemGuid(PlacesUIUtils.allBookmarksFolderId);
- let bm = yield PlacesUtils.bookmarks.fetch({parentGuid: guid, index: 0});
- yield PlacesUtils.bookmarks.remove(bm.guid);
- }
-
-];
-
-/**
- * Convert a folder item id to a JSON representation of it and its contents.
- */
-function folderIdToHierarchy(aFolderId) {
- let root = PlacesUtils.getFolderContents(aFolderId).root;
- let hier = JSON.stringify(hierarchyToObj(root));
- root.containerOpen = false;
- return hier;
-}
-
-function hierarchyToObj(aNode) {
- let o = {}
- o.title = aNode.title;
- o.annos = PlacesUtils.getAnnotationsForItem(aNode.itemId)
- if (PlacesUtils.nodeIsURI(aNode)) {
- o.uri = aNode.uri;
- }
- else if (PlacesUtils.nodeIsFolder(aNode)) {
- o.children = [];
- PlacesUtils.asContainer(aNode).containerOpen = true;
- for (let i = 0; i < aNode.childCount; ++i) {
- o.children.push(hierarchyToObj(aNode.getChild(i)));
- }
- aNode.containerOpen = false;
- }
- return o;
-}
diff --git a/browser/components/places/tests/unit/xpcshell.ini b/browser/components/places/tests/unit/xpcshell.ini
deleted file mode 100644
index 1c40e1c53..000000000
--- a/browser/components/places/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,25 +0,0 @@
-[DEFAULT]
-head = head_bookmarks.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-support-files =
- bookmarks.glue.html
- bookmarks.glue.json
- corruptDB.sqlite
- distribution.ini
-
-[test_421483.js]
-[test_browserGlue_bookmarkshtml.js]
-[test_browserGlue_corrupt.js]
-[test_browserGlue_corrupt_nobackup.js]
-[test_browserGlue_corrupt_nobackup_default.js]
-[test_browserGlue_distribution.js]
-[test_browserGlue_migrate.js]
-[test_browserGlue_prefs.js]
-[test_browserGlue_restore.js]
-[test_browserGlue_smartBookmarks.js]
-[test_browserGlue_urlbar_defaultbehavior_migration.js]
-[test_clearHistory_shutdown.js]
-[test_leftpane_corruption_handling.js]
-[test_PUIU_makeTransaction.js]
diff --git a/browser/components/preferences/in-content/tests/.eslintrc.js b/browser/components/preferences/in-content/tests/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/preferences/in-content/tests/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/preferences/in-content/tests/browser.ini b/browser/components/preferences/in-content/tests/browser.ini
deleted file mode 100644
index 6cba02599..000000000
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ /dev/null
@@ -1,43 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
- privacypane_tests_perwindow.js
-
-[browser_advanced_update.js]
-[browser_basic_rebuild_fonts_test.js]
-[browser_bug410900.js]
-[browser_bug705422.js]
-[browser_bug731866.js]
-[browser_bug795764_cachedisabled.js]
-[browser_bug1018066_resetScrollPosition.js]
-[browser_bug1020245_openPreferences_to_paneContent.js]
-[browser_bug1184989_prevent_scrolling_when_preferences_flipped.js]
-support-files =
- browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul
-[browser_change_app_handler.js]
-skip-if = os != "win" # This test tests the windows-specific app selection dialog, so can't run on non-Windows
-[browser_connection.js]
-[browser_connection_bug388287.js]
-[browser_cookies_exceptions.js]
-[browser_defaultbrowser_alwayscheck.js]
-[browser_healthreport.js]
-skip-if = true || !healthreport # Bug 1185403 for the "true"
-[browser_homepages_filter_aboutpreferences.js]
-[browser_notifications_do_not_disturb.js]
-[browser_permissions_urlFieldHidden.js]
-[browser_proxy_backup.js]
-[browser_privacypane_1.js]
-[browser_privacypane_3.js]
-[browser_privacypane_4.js]
-[browser_privacypane_5.js]
-[browser_privacypane_8.js]
-[browser_sanitizeOnShutdown_prefLocked.js]
-[browser_searchsuggestions.js]
-[browser_security.js]
-[browser_subdialogs.js]
-support-files =
- subdialog.xul
- subdialog2.xul
-[browser_telemetry.js]
-# Skip this test on Android as FHR and Telemetry are separate systems there.
-skip-if = !healthreport || !telemetry || (os == 'linux' && debug) || (os == 'android')
diff --git a/browser/components/preferences/in-content/tests/browser_advanced_update.js b/browser/components/preferences/in-content/tests/browser_advanced_update.js
deleted file mode 100644
index e9d0e8652..000000000
--- a/browser/components/preferences/in-content/tests/browser_advanced_update.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
-
-const mockUpdateManager = {
- contractId: "@mozilla.org/updates/update-manager;1",
-
- _mockClassId: uuidGenerator.generateUUID(),
-
- _originalClassId: "",
-
- _originalFactory: null,
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateManager]),
-
- createInstance: function(outer, iiD) {
- if (outer) {
- throw Cr.NS_ERROR_NO_AGGREGATION;
- }
- return this.QueryInterface(iiD);
- },
-
- register: function () {
- let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
- if (!registrar.isCIDRegistered(this._mockClassId)) {
- this._originalClassId = registrar.contractIDToCID(this.contractId);
- this._originalFactory = Cm.getClassObject(Cc[this.contractId], Ci.nsIFactory);
- registrar.unregisterFactory(this._originalClassId, this._originalFactory);
- registrar.registerFactory(this._mockClassId, "Unregister after testing", this.contractId, this);
- }
- },
-
- unregister: function () {
- let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
- registrar.unregisterFactory(this._mockClassId, this);
- registrar.registerFactory(this._originalClassId, "", this.contractId, this._originalFactory);
- },
-
- get updateCount() {
- return this._updates.length;
- },
-
- getUpdateAt: function (index) {
- return this._updates[index];
- },
-
- _updates: [
- {
- name: "Firefox Developer Edition 49.0a2",
- statusText: "The Update was successfully installed",
- buildID: "20160728004010",
- type: "minor",
- installDate: 1469763105156,
- detailsURL: "https://www.mozilla.org/firefox/aurora/"
- },
- {
- name: "Firefox Developer Edition 43.0a2",
- statusText: "The Update was successfully installed",
- buildID: "20150929004011",
- type: "minor",
- installDate: 1443585886224,
- detailsURL: "https://www.mozilla.org/firefox/aurora/"
- },
- {
- name: "Firefox Developer Edition 42.0a2",
- statusText: "The Update was successfully installed",
- buildID: "20150920004018",
- type: "major",
- installDate: 1442818147544,
- detailsURL: "https://www.mozilla.org/firefox/aurora/"
- }
- ]
-};
-
-function resetPreferences() {
- Services.prefs.clearUserPref("browser.search.update");
-}
-
-function formatInstallDate(sec) {
- var date = new Date(sec);
- const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Ci.nsIXULChromeRegistry)
- .getSelectedLocale("global", true);
- const dtOptions = { year: 'numeric', month: 'long', day: 'numeric',
- hour: 'numeric', minute: 'numeric', second: 'numeric' };
- return date.toLocaleString(locale, dtOptions);
-}
-
-registerCleanupFunction(resetPreferences);
-
-add_task(function*() {
- yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
- resetPreferences();
- Services.prefs.setBoolPref("browser.search.update", false);
-
- let doc = gBrowser.selectedBrowser.contentDocument;
- let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
- is_element_visible(enableSearchUpdate, "Check search update preference is visible");
-
- // Ensure that the update pref dialog reflects the actual pref value.
- ok(!enableSearchUpdate.checked, "Ensure search updates are disabled");
- Services.prefs.setBoolPref("browser.search.update", true);
- ok(enableSearchUpdate.checked, "Ensure search updates are enabled");
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function*() {
- mockUpdateManager.register();
-
- yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
- let doc = gBrowser.selectedBrowser.contentDocument;
-
- let showBtn = doc.getElementById("showUpdateHistory");
- let dialogOverlay = doc.getElementById("dialogOverlay");
-
- // Test the dialog window opens
- is(dialogOverlay.style.visibility, "", "The dialog should be invisible");
- showBtn.doCommand();
- yield promiseLoadSubDialog("chrome://mozapps/content/update/history.xul");
- is(dialogOverlay.style.visibility, "visible", "The dialog should be visible");
-
- let dialogFrame = doc.getElementById("dialogFrame");
- let frameDoc = dialogFrame.contentDocument;
- let updates = frameDoc.querySelectorAll("update");
-
- // Test the update history numbers are correct
- is(updates.length, mockUpdateManager.updateCount, "The update count is incorrect.");
-
- // Test the updates are displayed correctly
- let update = null;
- let updateData = null;
- for (let i = 0; i < updates.length; ++i) {
- update = updates[i];
- updateData = mockUpdateManager.getUpdateAt(i);
-
- is(update.name, updateData.name + " (" + updateData.buildID + ")", "Wrong update name");
- is(update.type, updateData.type == "major" ? "New Version" : "Security Update", "Wrong update type");
- is(update.installDate, formatInstallDate(updateData.installDate), "Wrong update installDate");
- is(update.detailsURL, updateData.detailsURL, "Wrong update detailsURL");
- is(update.status, updateData.statusText, "Wrong update status");
- }
-
- // Test the dialog window closes
- let closeBtn = doc.getElementById("dialogClose");
- closeBtn.doCommand();
- is(dialogOverlay.style.visibility, "", "The dialog should be invisible");
-
- mockUpdateManager.unregister();
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js b/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
deleted file mode 100644
index 32c1bd726..000000000
--- a/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
+++ /dev/null
@@ -1,76 +0,0 @@
-Services.prefs.setBoolPref("browser.preferences.instantApply", true);
-
-registerCleanupFunction(function() {
- Services.prefs.clearUserPref("browser.preferences.instantApply");
-});
-
-add_task(function*() {
- yield openPreferencesViaOpenPreferencesAPI("paneContent", null, {leaveOpen: true});
- let doc = gBrowser.contentDocument;
- var langGroup = Services.prefs.getComplexValue("font.language.group", Ci.nsIPrefLocalizedString).data
- is(doc.getElementById("font.language.group").value, langGroup,
- "Language group should be set correctly.");
-
- let defaultFontType = Services.prefs.getCharPref("font.default." + langGroup);
- let fontFamily = Services.prefs.getCharPref("font.name." + defaultFontType + "." + langGroup);
- let fontFamilyField = doc.getElementById("defaultFont");
- is(fontFamilyField.value, fontFamily, "Font family should be set correctly.");
-
- let defaultFontSize = Services.prefs.getIntPref("font.size.variable." + langGroup);
- let fontSizeField = doc.getElementById("defaultFontSize");
- is(fontSizeField.value, defaultFontSize, "Font size should be set correctly.");
-
- doc.getElementById("advancedFonts").click();
- let win = yield promiseLoadSubDialog("chrome://browser/content/preferences/fonts.xul");
- doc = win.document;
-
- // Simulate a dumb font backend.
- win.FontBuilder._enumerator = {
- _list: ["MockedFont1", "MockedFont2", "MockedFont3"],
- EnumerateFonts: function(lang, type, list) {
- return this._list;
- },
- EnumerateAllFonts: function() {
- return this._list;
- },
- getDefaultFont: function() { return null; },
- getStandardFamilyName: function(name) { return name; },
- };
- win.FontBuilder._allFonts = null;
- win.FontBuilder._langGroupSupported = false;
-
- let langGroupElement = doc.getElementById("font.language.group");
- let selectLangsField = doc.getElementById("selectLangs");
- let serifField = doc.getElementById("serif");
- let armenian = "x-armn";
- let western = "x-western";
-
- langGroupElement.value = armenian;
- selectLangsField.value = armenian;
- is(serifField.value, "", "Font family should not be set.");
-
- langGroupElement.value = western;
- selectLangsField.value = western;
-
- // Simulate a font backend supporting language-specific enumeration.
- // NB: FontBuilder has cached the return value from EnumerateAllFonts(),
- // so _allFonts will always have 3 elements regardless of subsequent
- // _list changes.
- win.FontBuilder._enumerator._list = ["MockedFont2"];
-
- langGroupElement.value = armenian;
- selectLangsField.value = armenian;
- is(serifField.value, "MockedFont2", "Font family should be set.");
-
- langGroupElement.value = western;
- selectLangsField.value = western;
-
- // Simulate a system that has no fonts for the specified language.
- win.FontBuilder._enumerator._list = [];
-
- langGroupElement.value = armenian;
- selectLangsField.value = armenian;
- is(serifField.value, "", "Font family should not be set.");
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/preferences/in-content/tests/browser_bug1018066_resetScrollPosition.js b/browser/components/preferences/in-content/tests/browser_bug1018066_resetScrollPosition.js
deleted file mode 100644
index 9d938fdd4..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug1018066_resetScrollPosition.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var originalWindowHeight;
-registerCleanupFunction(function() {
- window.resizeTo(window.outerWidth, originalWindowHeight);
- while (gBrowser.tabs[1])
- gBrowser.removeTab(gBrowser.tabs[1]);
-});
-
-add_task(function*() {
- originalWindowHeight = window.outerHeight;
- window.resizeTo(window.outerWidth, 300);
- let prefs = yield openPreferencesViaOpenPreferencesAPI("paneApplications", undefined, {leaveOpen: true});
- is(prefs.selectedPane, "paneApplications", "Applications pane was selected");
- let mainContent = gBrowser.contentDocument.querySelector(".main-content");
- mainContent.scrollTop = 50;
- is(mainContent.scrollTop, 50, "main-content should be scrolled 50 pixels");
-
- gBrowser.contentWindow.gotoPref("paneGeneral");
- is(mainContent.scrollTop, 0,
- "Switching to a different category should reset the scroll position");
-});
-
diff --git 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
deleted file mode 100644
index bc2c6d800..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Services.prefs.setBoolPref("browser.preferences.instantApply", true);
-
-registerCleanupFunction(function() {
- Services.prefs.clearUserPref("browser.preferences.instantApply");
-});
-
-add_task(function*() {
- let prefs = yield openPreferencesViaOpenPreferencesAPI("paneContent");
- is(prefs.selectedPane, "paneContent", "Content pane was selected");
- prefs = yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab");
- is(prefs.selectedPane, "paneAdvanced", "Advanced pane was selected");
- is(prefs.selectedAdvancedTab, "updateTab", "The update tab within the advanced prefs should be selected");
- prefs = yield openPreferencesViaHash("privacy");
- is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected when hash is 'privacy'");
- prefs = yield openPreferencesViaOpenPreferencesAPI("nonexistant-category");
- is(prefs.selectedPane, "paneGeneral", "General pane is selected by default when a nonexistant-category is requested");
- prefs = yield openPreferencesViaHash("nonexistant-category");
- is(prefs.selectedPane, "paneGeneral", "General pane is selected when hash is a nonexistant-category");
- prefs = yield openPreferencesViaHash();
- 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);
- let win = gBrowser.contentWindow;
- let selectedPane = win.history.state;
- gBrowser.removeCurrentTab();
- deferred.resolve({selectedPane: selectedPane});
- });
- }, true);
-
- return deferred.promise;
-}
diff --git a/browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.js b/browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.js
deleted file mode 100644
index 0972b2de4..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-
-add_task(function* () {
- waitForExplicitFinish();
-
- const tabURL = getRootDirectory(gTestPath) + "browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul";
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: tabURL }, function* (browser) {
- let doc = browser.contentDocument;
- let container = doc.getElementById("container");
-
- // Test button
- let button = doc.getElementById("button");
- button.focus();
- EventUtils.synthesizeKey(" ", {});
- yield checkPageScrolling(container, "button");
-
- // Test checkbox
- let checkbox = doc.getElementById("checkbox");
- checkbox.focus();
- EventUtils.synthesizeKey(" ", {});
- ok(checkbox.checked, "Checkbox is checked");
- yield checkPageScrolling(container, "checkbox");
-
- // Test listbox
- let listbox = doc.getElementById("listbox");
- let listitem = doc.getElementById("listitem");
- listbox.focus();
- EventUtils.synthesizeKey(" ", {});
- ok(listitem.selected, "Listitem is selected");
- yield checkPageScrolling(container, "listbox");
-
- // Test radio
- let radiogroup = doc.getElementById("radiogroup");
- radiogroup.focus();
- EventUtils.synthesizeKey(" ", {});
- yield checkPageScrolling(container, "radio");
- });
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:preferences#search" }, function* (browser) {
- let doc = browser.contentDocument;
- let container = doc.getElementsByClassName("main-content")[0];
-
- // Test search
- let engineList = doc.getElementById("engineList");
- engineList.focus();
- EventUtils.synthesizeKey(" ", {});
- is(engineList.view.selection.currentIndex, 0, "Search engineList is selected");
- EventUtils.synthesizeKey(" ", {});
- yield checkPageScrolling(container, "search engineList");
- });
-
- // Test session restore
- const CRASH_URL = "about:mozilla";
- const CRASH_FAVICON = "chrome://branding/content/icon32.png";
- const CRASH_SHENTRY = {url: CRASH_URL};
- const CRASH_TAB = {entries: [CRASH_SHENTRY], image: CRASH_FAVICON};
- const CRASH_STATE = {windows: [{tabs: [CRASH_TAB]}]};
-
- const TAB_URL = "about:sessionrestore";
- const TAB_FORMDATA = {url: TAB_URL, id: {sessionData: CRASH_STATE}};
- const TAB_SHENTRY = {url: TAB_URL};
- const TAB_STATE = {entries: [TAB_SHENTRY], formdata: TAB_FORMDATA};
-
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
-
- // Fake a post-crash tab
- ss.setTabState(tab, JSON.stringify(TAB_STATE));
-
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- let doc = tab.linkedBrowser.contentDocument;
-
- // Make body scrollable
- doc.body.style.height = (doc.body.clientHeight + 100) + "px";
-
- let tabList = doc.getElementById("tabList");
- tabList.focus();
- EventUtils.synthesizeKey(" ", {});
- yield checkPageScrolling(doc.documentElement, "session restore");
-
- gBrowser.removeCurrentTab();
- finish();
-});
-
-function checkPageScrolling(container, type) {
- return new Promise(resolve => {
- setTimeout(() => {
- is(container.scrollTop, 0, "Page should not scroll when " + type + " flipped");
- resolve();
- }, 0);
- });
-}
diff --git a/browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul b/browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul
deleted file mode 100644
index 59b644c8f..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<!--
- XUL Widget Test for Bug 1184989
- -->
-<page title="Bug 1184989 Test"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<vbox id="container" style="height: 200px; overflow: auto;">
- <vbox style="height: 500px;">
- <hbox>
- <button id="button" label="button" />
- </hbox>
-
- <hbox>
- <checkbox id="checkbox" label="checkbox" />
- </hbox>
-
- <hbox style="height: 50px;">
- <listbox id="listbox">
- <listitem id="listitem" label="listitem" />
- <listitem label="listitem" />
- </listbox>
- </hbox>
-
- <hbox>
- <radiogroup id="radiogroup">
- <radio id="radio" label="radio" />
- </radiogroup>
- </hbox>
- </vbox>
-</vbox>
-
-</page>
diff --git a/browser/components/preferences/in-content/tests/browser_bug410900.js b/browser/components/preferences/in-content/tests/browser_bug410900.js
deleted file mode 100644
index 5b100966d..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug410900.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
-Components.utils.import("resource://gre/modules/NetUtil.jsm");
-
-function test() {
- waitForExplicitFinish();
-
- // Setup a phony handler to ensure the app pane will be populated.
- var handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
- createInstance(Ci.nsIWebHandlerApp);
- handler.name = "App pane alive test";
- handler.uriTemplate = "http://test.mozilla.org/%s";
-
- var extps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
- getService(Ci.nsIExternalProtocolService);
- var info = extps.getProtocolHandlerInfo("apppanetest");
- info.possibleApplicationHandlers.appendElement(handler, false);
-
- var hserv = Cc["@mozilla.org/uriloader/handler-service;1"].
- getService(Ci.nsIHandlerService);
- hserv.store(info);
-
- openPreferencesViaOpenPreferencesAPI("applications", null, {leaveOpen: true}).then(
- () => runTest(gBrowser.selectedBrowser.contentWindow)
- );
-}
-
-function runTest(win) {
- var rbox = win.document.getElementById("handlersView");
- ok(rbox, "handlersView is present");
-
- var items = rbox && rbox.getElementsByTagName("richlistitem");
- ok(items && items.length > 0, "App handler list populated");
-
- var handlerAdded = false;
- for (let i = 0; i < items.length; i++) {
- if (items[i].getAttribute('type') == "apppanetest")
- handlerAdded = true;
- }
- ok(handlerAdded, "apppanetest protocol handler was successfully added");
-
- gBrowser.removeCurrentTab();
- finish();
-}
diff --git a/browser/components/preferences/in-content/tests/browser_bug705422.js b/browser/components/preferences/in-content/tests/browser_bug705422.js
deleted file mode 100644
index 24732083b..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug705422.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- waitForExplicitFinish();
- // Allow all cookies, then actually set up the test
- SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, initTest);
-}
-
-function initTest() {
- const searchTerm = "example";
- const dummyTerm = "elpmaxe";
-
- var cm = Components.classes["@mozilla.org/cookiemanager;1"]
- .getService(Components.interfaces.nsICookieManager);
-
- // delete all cookies (might be left over from other tests)
- cm.removeAll();
-
- // data for cookies
- var vals = [[searchTerm+".com", dummyTerm, dummyTerm], // match
- [searchTerm+".org", dummyTerm, dummyTerm], // match
- [dummyTerm+".com", searchTerm, dummyTerm], // match
- [dummyTerm+".edu", searchTerm+dummyTerm, dummyTerm], // match
- [dummyTerm+".net", dummyTerm, searchTerm], // match
- [dummyTerm+".org", dummyTerm, searchTerm+dummyTerm], // match
- [dummyTerm+".int", dummyTerm, dummyTerm]]; // no match
-
- // matches must correspond to above data
- const matches = 6;
-
- var ios = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var cookieSvc = Components.classes["@mozilla.org/cookieService;1"]
- .getService(Components.interfaces.nsICookieService);
- var v;
- // inject cookies
- for (v in vals) {
- let [host, name, value] = vals[v];
- var cookieUri = ios.newURI("http://"+host, null, null);
- cookieSvc.setCookieString(cookieUri, null, name+"="+value+";", null);
- }
-
- // open cookie manager
- var cmd = window.openDialog("chrome://browser/content/preferences/cookies.xul",
- "Browser:Cookies", "", {});
-
- // when it has loaded, run actual tests
- cmd.addEventListener("load", function() { executeSoon(function() { runTest(cmd, searchTerm, vals.length, matches); }); }, false);
-}
-
-function isDisabled(win, expectation) {
- var disabled = win.document.getElementById("removeAllCookies").disabled;
- is(disabled, expectation, "Remove all cookies button has correct state: "+(expectation?"disabled":"enabled"));
-}
-
-function runTest(win, searchTerm, cookies, matches) {
- var cm = Components.classes["@mozilla.org/cookiemanager;1"]
- .getService(Components.interfaces.nsICookieManager);
-
-
- // number of cookies should match injected cookies
- var injectedCookies = 0,
- injectedEnumerator = cm.enumerator;
- while (injectedEnumerator.hasMoreElements()) {
- injectedCookies++;
- injectedEnumerator.getNext();
- }
- is(injectedCookies, cookies, "Number of cookies match injected cookies");
-
- // "delete all cookies" should be enabled
- isDisabled(win, false);
-
- // filter cookies and count matches
- win.gCookiesWindow.setFilter(searchTerm);
- is(win.gCookiesWindow._view.rowCount, matches, "Correct number of cookies shown after filter is applied");
-
- // "delete all cookies" should be enabled
- isDisabled(win, false);
-
-
- // select first cookie and delete
- var tree = win.document.getElementById("cookiesList");
- var deleteButton = win.document.getElementById("removeSelectedCookies");
- var rect = tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "cell");
- EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {}, win);
- EventUtils.synthesizeMouseAtCenter(deleteButton, {}, win);
-
- // count cookies should be matches-1
- is(win.gCookiesWindow._view.rowCount, matches-1, "Deleted selected cookie");
-
- // select two adjacent cells and delete
- EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {}, win);
- var eventObj = {};
- if (navigator.platform.indexOf("Mac") >= 0)
- eventObj.metaKey = true;
- else
- eventObj.ctrlKey = true;
- rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[0], "cell");
- EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, eventObj, win);
- EventUtils.synthesizeMouseAtCenter(deleteButton, {}, win);
-
- // count cookies should be matches-3
- is(win.gCookiesWindow._view.rowCount, matches-3, "Deleted selected two adjacent cookies");
-
- // "delete all cookies" should be enabled
- isDisabled(win, false);
-
- // delete all cookies and count
- var deleteAllButton = win.document.getElementById("removeAllCookies");
- EventUtils.synthesizeMouseAtCenter(deleteAllButton, {}, win);
- is(win.gCookiesWindow._view.rowCount, 0, "Deleted all matching cookies");
-
- // "delete all cookies" should be disabled
- isDisabled(win, true);
-
- // clear filter and count should be cookies-matches
- win.gCookiesWindow.setFilter("");
- is(win.gCookiesWindow._view.rowCount, cookies-matches, "Unmatched cookies remain");
-
- // "delete all cookies" should be enabled
- isDisabled(win, false);
-
- // delete all cookies and count should be 0
- EventUtils.synthesizeMouseAtCenter(deleteAllButton, {}, win);
- is(win.gCookiesWindow._view.rowCount, 0, "Deleted all cookies");
-
- // check that datastore is also at 0
- var remainingCookies = 0,
- remainingEnumerator = cm.enumerator;
- while (remainingEnumerator.hasMoreElements()) {
- remainingCookies++;
- remainingEnumerator.getNext();
- }
- is(remainingCookies, 0, "Zero cookies remain");
-
- // "delete all cookies" should be disabled
- isDisabled(win, true);
-
- // clean up
- win.close();
- finish();
-}
-
diff --git a/browser/components/preferences/in-content/tests/browser_bug731866.js b/browser/components/preferences/in-content/tests/browser_bug731866.js
deleted file mode 100644
index c1031d412..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug731866.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
-Components.utils.import("resource://gre/modules/NetUtil.jsm");
-
-function test() {
- waitForExplicitFinish();
- open_preferences(runTest);
-}
-
-var gElements;
-
-function checkElements(expectedPane) {
- for (let element of gElements) {
- // keyset and preferences elements fail is_element_visible checks because they are never visible.
- // special-case the drmGroup item because its visibility depends on pref + OS version
- if (element.nodeName == "keyset" ||
- element.nodeName == "preferences" ||
- element.id === "drmGroup") {
- continue;
- }
- let attributeValue = element.getAttribute("data-category");
- let suffix = " (id=" + element.id + ")";
- if (attributeValue == "pane" + expectedPane) {
- is_element_visible(element, expectedPane + " elements should be visible" + suffix);
- } else {
- is_element_hidden(element, "Elements not in " + expectedPane + " should be hidden" + suffix);
- }
- }
-}
-
-function runTest(win) {
- is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
-
- let tab = win.document;
- gElements = tab.getElementById("mainPrefPane").children;
-
- let panes = [
- "General", "Search", "Content", "Applications",
- "Privacy", "Security", "Sync", "Advanced",
- ];
-
- for (let pane of panes) {
- win.gotoPref("pane" + pane);
- checkElements(pane);
- }
-
- gBrowser.removeCurrentTab();
- win.close();
- finish();
-}
diff --git a/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js b/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js
deleted file mode 100644
index 21f92db8d..000000000
--- a/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
-Components.utils.import("resource://gre/modules/NetUtil.jsm");
-
-function test() {
- waitForExplicitFinish();
-
- let prefs = [
- "browser.cache.offline.enable",
- "browser.cache.disk.enable",
- "browser.cache.memory.enable",
- ];
-
- registerCleanupFunction(function() {
- for (let pref of prefs) {
- Services.prefs.clearUserPref(pref);
- }
- });
-
- for (let pref of prefs) {
- Services.prefs.setBoolPref(pref, false);
- }
-
- open_preferences(runTest);
-}
-
-function runTest(win) {
- is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
-
- let tab = win.document;
- let elements = tab.getElementById("mainPrefPane").children;
-
- // Test if advanced pane is opened correctly
- win.gotoPref("paneAdvanced");
- for (let element of elements) {
- if (element.nodeName == "preferences") {
- continue;
- }
- let attributeValue = element.getAttribute("data-category");
- if (attributeValue == "paneAdvanced") {
- is_element_visible(element, "Advanced elements should be visible");
- } else {
- is_element_hidden(element, "Non-Advanced elements should be hidden");
- }
- }
-
- gBrowser.removeCurrentTab();
- win.close();
- finish();
-}
diff --git a/browser/components/preferences/in-content/tests/browser_change_app_handler.js b/browser/components/preferences/in-content/tests/browser_change_app_handler.js
deleted file mode 100644
index f66cdfd37..000000000
--- a/browser/components/preferences/in-content/tests/browser_change_app_handler.js
+++ /dev/null
@@ -1,98 +0,0 @@
-var gMimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
-var gHandlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
-
-SimpleTest.requestCompleteLog();
-
-function setupFakeHandler() {
- let info = gMimeSvc.getFromTypeAndExtension("text/plain", "foo.txt");
- ok(info.possibleLocalHandlers.length, "Should have at least one known handler");
- let handler = info.possibleLocalHandlers.queryElementAt(0, Ci.nsILocalHandlerApp);
-
- let infoToModify = gMimeSvc.getFromTypeAndExtension("text/x-test-handler", null);
- infoToModify.possibleApplicationHandlers.appendElement(handler, false);
-
- gHandlerSvc.store(infoToModify);
-}
-
-add_task(function*() {
- setupFakeHandler();
- yield openPreferencesViaOpenPreferencesAPI("applications", null, {leaveOpen: true});
- info("Preferences page opened on the applications pane.");
- let win = gBrowser.selectedBrowser.contentWindow;
-
- let container = win.document.getElementById("handlersView");
- let ourItem = container.querySelector("richlistitem[type='text/x-test-handler']");
- ok(ourItem, "handlersView is present");
- ourItem.scrollIntoView();
- container.selectItem(ourItem);
- ok(ourItem.selected, "Should be able to select our item.");
-
- let list = yield waitForCondition(() => win.document.getAnonymousElementByAttribute(ourItem, "class", "actionsMenu"));
- info("Got list after item was selected");
-
- let chooseItem = list.firstChild.querySelector(".choose-app-item");
- let dialogLoadedPromise = promiseLoadSubDialog("chrome://global/content/appPicker.xul");
- let cmdEvent = win.document.createEvent("xulcommandevent");
- cmdEvent.initCommandEvent("command", true, true, win, 0, false, false, false, false, null);
- chooseItem.dispatchEvent(cmdEvent);
-
- let dialog = yield dialogLoadedPromise;
- info("Dialog loaded");
-
- let dialogDoc = dialog.document;
- let dialogList = dialogDoc.getElementById("app-picker-listbox");
- dialogList.selectItem(dialogList.firstChild);
- let selectedApp = dialogList.firstChild.handlerApp;
- dialogDoc.documentElement.acceptDialog();
-
- // Verify results are correct in mime service:
- let mimeInfo = gMimeSvc.getFromTypeAndExtension("text/x-test-handler", null);
- ok(mimeInfo.preferredApplicationHandler.equals(selectedApp), "App should be set as preferred.");
-
- // Check that we display this result:
- list = yield waitForCondition(() => win.document.getAnonymousElementByAttribute(ourItem, "class", "actionsMenu"));
- info("Got list after item was selected");
- ok(list.selectedItem, "Should have a selected item");
- ok(mimeInfo.preferredApplicationHandler.equals(list.selectedItem.handlerApp),
- "App should be visible as preferred item.");
-
-
- // Now try to 'manage' this list:
- dialogLoadedPromise = promiseLoadSubDialog("chrome://browser/content/preferences/applicationManager.xul");
-
- let manageItem = list.firstChild.querySelector(".manage-app-item");
- cmdEvent = win.document.createEvent("xulcommandevent");
- cmdEvent.initCommandEvent("command", true, true, win, 0, false, false, false, false, null);
- manageItem.dispatchEvent(cmdEvent);
-
- dialog = yield dialogLoadedPromise;
- info("Dialog loaded the second time");
-
- dialogDoc = dialog.document;
- dialogList = dialogDoc.getElementById("appList");
- let itemToRemove = dialogList.querySelector('listitem[label="' + selectedApp.name + '"]');
- dialogList.selectItem(itemToRemove);
- let itemsBefore = dialogList.children.length;
- dialogDoc.getElementById("remove").click();
- ok(!itemToRemove.parentNode, "Item got removed from DOM");
- is(dialogList.children.length, itemsBefore - 1, "Item got removed");
- dialogDoc.documentElement.acceptDialog();
-
- // Verify results are correct in mime service:
- mimeInfo = gMimeSvc.getFromTypeAndExtension("text/x-test-handler", null);
- ok(!mimeInfo.preferredApplicationHandler, "App should no longer be set as preferred.");
-
- // Check that we display this result:
- list = yield waitForCondition(() => win.document.getAnonymousElementByAttribute(ourItem, "class", "actionsMenu"));
- ok(list.selectedItem, "Should have a selected item");
- ok(!list.selectedItem.handlerApp,
- "No app should be visible as preferred item.");
-
- gBrowser.removeCurrentTab();
-});
-
-registerCleanupFunction(function() {
- let infoToModify = gMimeSvc.getFromTypeAndExtension("text/x-test-handler", null);
- gHandlerSvc.remove(infoToModify);
-});
-
diff --git a/browser/components/preferences/in-content/tests/browser_connection.js b/browser/components/preferences/in-content/tests/browser_connection.js
deleted file mode 100644
index 50438aed1..000000000
--- a/browser/components/preferences/in-content/tests/browser_connection.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/Task.jsm");
-
-function test() {
- waitForExplicitFinish();
-
- // network.proxy.type needs to be backed up and restored because mochitest
- // changes this setting from the default
- let oldNetworkProxyType = Services.prefs.getIntPref("network.proxy.type");
- registerCleanupFunction(function() {
- Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
- Services.prefs.clearUserPref("network.proxy.no_proxies_on");
- Services.prefs.clearUserPref("browser.preferences.instantApply");
- });
-
- let connectionURL = "chrome://browser/content/preferences/connection.xul";
-
- /*
- The connection dialog alone won't save onaccept since it uses type="child",
- so it has to be opened as a sub dialog of the main pref tab.
- Open the main tab here.
- */
- open_preferences(Task.async(function* tabOpened(aContentWindow) {
- is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
- let dialog = yield openAndLoadSubDialog(connectionURL);
- let dialogClosingPromise = waitForEvent(dialog.document.documentElement, "dialogclosing");
-
- ok(dialog, "connection window opened");
- runConnectionTests(dialog);
- dialog.document.documentElement.acceptDialog();
-
- let dialogClosingEvent = yield dialogClosingPromise;
- ok(dialogClosingEvent, "connection window closed");
- // runConnectionTests will have changed this pref - make sure it was
- // sanitized correctly when the dialog was accepted
- is(Services.prefs.getCharPref("network.proxy.no_proxies_on"),
- ".a.com,.b.com,.c.com", "no_proxies_on pref has correct value");
- gBrowser.removeCurrentTab();
- finish();
- }));
-}
-
-// run a bunch of tests on the window containing connection.xul
-function runConnectionTests(win) {
- let doc = win.document;
- let networkProxyNone = doc.getElementById("networkProxyNone");
- let networkProxyNonePref = doc.getElementById("network.proxy.no_proxies_on");
- let networkProxyTypePref = doc.getElementById("network.proxy.type");
-
- // make sure the networkProxyNone textbox is formatted properly
- is(networkProxyNone.getAttribute("multiline"), "true",
- "networkProxyNone textbox is multiline");
- is(networkProxyNone.getAttribute("rows"), "2",
- "networkProxyNone textbox has two rows");
-
- // check if sanitizing the given input for the no_proxies_on pref results in
- // expected string
- function testSanitize(input, expected, errorMessage) {
- networkProxyNonePref.value = input;
- win.gConnectionsDialog.sanitizeNoProxiesPref();
- is(networkProxyNonePref.value, expected, errorMessage);
- }
-
- // change this pref so proxy exceptions are actually configurable
- networkProxyTypePref.value = 1;
- is(networkProxyNone.disabled, false, "networkProxyNone textbox is enabled");
-
- testSanitize(".a.com", ".a.com",
- "sanitize doesn't mess up single filter");
- testSanitize(".a.com, .b.com, .c.com", ".a.com, .b.com, .c.com",
- "sanitize doesn't mess up multiple comma/space sep filters");
- testSanitize(".a.com\n.b.com", ".a.com,.b.com",
- "sanitize turns line break into comma");
- testSanitize(".a.com,\n.b.com", ".a.com,.b.com",
- "sanitize doesn't add duplicate comma after comma");
- testSanitize(".a.com\n,.b.com", ".a.com,.b.com",
- "sanitize doesn't add duplicate comma before comma");
- testSanitize(".a.com,\n,.b.com", ".a.com,,.b.com",
- "sanitize doesn't add duplicate comma surrounded by commas");
- testSanitize(".a.com, \n.b.com", ".a.com, .b.com",
- "sanitize doesn't add comma after comma/space");
- testSanitize(".a.com\n .b.com", ".a.com, .b.com",
- "sanitize adds comma before space");
- testSanitize(".a.com\n\n\n;;\n;\n.b.com", ".a.com,.b.com",
- "sanitize only adds one comma per substring of bad chars");
- testSanitize(".a.com,,.b.com", ".a.com,,.b.com",
- "duplicate commas from user are untouched");
- testSanitize(".a.com\n.b.com\n.c.com,\n.d.com,\n.e.com",
- ".a.com,.b.com,.c.com,.d.com,.e.com",
- "sanitize replaces things globally");
-
- // will check that this was sanitized properly after window closes
- networkProxyNonePref.value = ".a.com;.b.com\n.c.com";
-}
diff --git a/browser/components/preferences/in-content/tests/browser_connection_bug388287.js b/browser/components/preferences/in-content/tests/browser_connection_bug388287.js
deleted file mode 100644
index 5a348876e..000000000
--- a/browser/components/preferences/in-content/tests/browser_connection_bug388287.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/Task.jsm");
-
-function test() {
- waitForExplicitFinish();
- const connectionURL = "chrome://browser/content/preferences/connection.xul";
- let closeable = false;
- let finalTest = false;
-
- // The changed preferences need to be backed up and restored because this mochitest
- // changes them setting from the default
- let oldNetworkProxyType = Services.prefs.getIntPref("network.proxy.type");
- registerCleanupFunction(function() {
- Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
- Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
- for (let proxyType of ["http", "ssl", "ftp", "socks"]) {
- Services.prefs.clearUserPref("network.proxy." + proxyType);
- Services.prefs.clearUserPref("network.proxy." + proxyType + "_port");
- if (proxyType == "http") {
- continue;
- }
- Services.prefs.clearUserPref("network.proxy.backup." + proxyType);
- Services.prefs.clearUserPref("network.proxy.backup." + proxyType + "_port");
- }
- });
-
- /*
- The connection dialog alone won't save onaccept since it uses type="child",
- so it has to be opened as a sub dialog of the main pref tab.
- Open the main tab here.
- */
- open_preferences(Task.async(function* tabOpened(aContentWindow) {
- let dialog, dialogClosingPromise;
- let doc, proxyTypePref, sharePref, httpPref, httpPortPref, ftpPref, ftpPortPref;
-
- // Convenient function to reset the variables for the new window
- function* setDoc() {
- if (closeable) {
- let dialogClosingEvent = yield dialogClosingPromise;
- ok(dialogClosingEvent, "Connection dialog closed");
- }
-
- if (finalTest) {
- gBrowser.removeCurrentTab();
- finish();
- return;
- }
-
- dialog = yield openAndLoadSubDialog(connectionURL);
- dialogClosingPromise = waitForEvent(dialog.document.documentElement, "dialogclosing");
-
- doc = dialog.document;
- proxyTypePref = doc.getElementById("network.proxy.type");
- sharePref = doc.getElementById("network.proxy.share_proxy_settings");
- httpPref = doc.getElementById("network.proxy.http");
- httpPortPref = doc.getElementById("network.proxy.http_port");
- ftpPref = doc.getElementById("network.proxy.ftp");
- ftpPortPref = doc.getElementById("network.proxy.ftp_port");
- }
-
- // This batch of tests should not close the dialog
- yield setDoc();
-
- // Testing HTTP port 0 with share on
- proxyTypePref.value = 1;
- sharePref.value = true;
- httpPref.value = "localhost";
- httpPortPref.value = 0;
- doc.documentElement.acceptDialog();
-
- // Testing HTTP port 0 + FTP port 80 with share off
- sharePref.value = false;
- ftpPref.value = "localhost";
- ftpPortPref.value = 80;
- doc.documentElement.acceptDialog();
-
- // Testing HTTP port 80 + FTP port 0 with share off
- httpPortPref.value = 80;
- ftpPortPref.value = 0;
- doc.documentElement.acceptDialog();
-
- // From now on, the dialog should close since we are giving it legitimate inputs.
- // The test will timeout if the onbeforeaccept kicks in erroneously.
- closeable = true;
-
- // Both ports 80, share on
- httpPortPref.value = 80;
- ftpPortPref.value = 80;
- doc.documentElement.acceptDialog();
-
- // HTTP 80, FTP 0, with share on
- yield setDoc();
- proxyTypePref.value = 1;
- sharePref.value = true;
- ftpPref.value = "localhost";
- httpPref.value = "localhost";
- httpPortPref.value = 80;
- ftpPortPref.value = 0;
- doc.documentElement.acceptDialog();
-
- // HTTP host empty, port 0 with share on
- yield setDoc();
- proxyTypePref.value = 1;
- sharePref.value = true;
- httpPref.value = "";
- httpPortPref.value = 0;
- doc.documentElement.acceptDialog();
-
- // HTTP 0, but in no proxy mode
- yield setDoc();
- proxyTypePref.value = 0;
- sharePref.value = true;
- httpPref.value = "localhost";
- httpPortPref.value = 0;
-
- // This is the final test, don't spawn another connection window
- finalTest = true;
- doc.documentElement.acceptDialog();
- yield setDoc();
- }));
-}
diff --git a/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js b/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js
deleted file mode 100644
index 89313d736..000000000
--- a/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-requestLongerTimeout(2);
-
-function test() {
- waitForExplicitFinish();
- requestLongerTimeout(3);
- testRunner.runTests();
-}
-
-var testRunner = {
-
- tests:
- [
- {
- test: function(params) {
- params.url.value = "test.com";
- params.btnAllow.doCommand();
- is(params.tree.view.rowCount, 1, "added exception shows up in treeview");
- is(params.tree.view.getCellText(0, params.nameCol), "http://test.com",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.allowText,
- "permission text should be set correctly");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://test.com", data: "added",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "test.com";
- params.btnBlock.doCommand();
- is(params.tree.view.getCellText(0, params.nameCol), "http://test.com",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.denyText,
- "permission should change to deny in UI");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://test.com", data: "changed",
- capability: Ci.nsIPermissionManager.DENY_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "test.com";
- params.btnAllow.doCommand();
- is(params.tree.view.getCellText(0, params.nameCol), "http://test.com",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.allowText,
- "permission should revert back to allow");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://test.com", data: "changed",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "test.com";
- params.btnRemove.doCommand();
- is(params.tree.view.rowCount, 0, "exception should be removed");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://test.com", data: "deleted" }],
- },
- {
- expectPermObservancesDuringTestFunction: true,
- test: function(params) {
- let uri = params.ioService.newURI("http://test.com", null, null);
- params.pm.add(uri, "popup", Ci.nsIPermissionManager.DENY_ACTION);
- is(params.tree.view.rowCount, 0, "adding unrelated permission should not change display");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "popup", origin: "http://test.com", data: "added",
- capability: Ci.nsIPermissionManager.DENY_ACTION }],
- cleanUp: function(params) {
- let uri = params.ioService.newURI("http://test.com", null, null);
- params.pm.remove(uri, "popup");
- },
- },
- {
- test: function(params) {
- params.url.value = "https://test.com:12345";
- params.btnAllow.doCommand();
- is(params.tree.view.rowCount, 1, "added exception shows up in treeview");
- is(params.tree.view.getCellText(0, params.nameCol), "https://test.com:12345",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.allowText,
- "permission text should be set correctly");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "https://test.com:12345", data: "added",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "https://test.com:12345";
- params.btnBlock.doCommand();
- is(params.tree.view.getCellText(0, params.nameCol), "https://test.com:12345",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.denyText,
- "permission should change to deny in UI");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "https://test.com:12345", data: "changed",
- capability: Ci.nsIPermissionManager.DENY_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "https://test.com:12345";
- params.btnAllow.doCommand();
- is(params.tree.view.getCellText(0, params.nameCol), "https://test.com:12345",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.allowText,
- "permission should revert back to allow");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "https://test.com:12345", data: "changed",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "https://test.com:12345";
- params.btnRemove.doCommand();
- is(params.tree.view.rowCount, 0, "exception should be removed");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "https://test.com:12345", data: "deleted" }],
- },
- {
- test: function(params) {
- params.url.value = "localhost:12345";
- params.btnAllow.doCommand();
- is(params.tree.view.rowCount, 1, "added exception shows up in treeview");
- is(params.tree.view.getCellText(0, params.nameCol), "http://localhost:12345",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.allowText,
- "permission text should be set correctly");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://localhost:12345", data: "added",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "localhost:12345";
- params.btnBlock.doCommand();
- is(params.tree.view.getCellText(0, params.nameCol), "http://localhost:12345",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.denyText,
- "permission should change to deny in UI");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://localhost:12345", data: "changed",
- capability: Ci.nsIPermissionManager.DENY_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "localhost:12345";
- params.btnAllow.doCommand();
- is(params.tree.view.getCellText(0, params.nameCol), "http://localhost:12345",
- "origin name should be set correctly");
- is(params.tree.view.getCellText(0, params.statusCol), params.allowText,
- "permission should revert back to allow");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://localhost:12345", data: "changed",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- },
- {
- test: function(params) {
- params.url.value = "localhost:12345";
- params.btnRemove.doCommand();
- is(params.tree.view.rowCount, 0, "exception should be removed");
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://localhost:12345", data: "deleted" }],
- },
- {
- expectPermObservancesDuringTestFunction: true,
- test(params) {
- for (let URL of ["http://a", "http://z", "http://b"]) {
- let URI = params.ioService.newURI(URL, null, null);
- params.pm.add(URI, "cookie", Ci.nsIPermissionManager.ALLOW_ACTION);
- }
-
- is(params.tree.view.rowCount, 3, "Three permissions should be present");
- is(params.tree.view.getCellText(0, params.nameCol), "http://a",
- "site should be sorted. 'a' should be first");
- is(params.tree.view.getCellText(1, params.nameCol), "http://b",
- "site should be sorted. 'b' should be second");
- is(params.tree.view.getCellText(2, params.nameCol), "http://z",
- "site should be sorted. 'z' should be third");
-
- // Sort descending then check results in cleanup since sorting isn't synchronous.
- EventUtils.synthesizeMouseAtCenter(params.doc.getElementById("siteCol"), {},
- params.doc.defaultView);
- params.btnApplyChanges.doCommand();
- },
- observances: [{ type: "cookie", origin: "http://a", data: "added",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION },
- { type: "cookie", origin: "http://z", data: "added",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION },
- { type: "cookie", origin: "http://b", data: "added",
- capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
- cleanUp(params) {
- is(params.tree.view.getCellText(0, params.nameCol), "http://z",
- "site should be sorted. 'z' should be first");
- is(params.tree.view.getCellText(1, params.nameCol), "http://b",
- "site should be sorted. 'b' should be second");
- is(params.tree.view.getCellText(2, params.nameCol), "http://a",
- "site should be sorted. 'a' should be third");
-
- for (let URL of ["http://a", "http://z", "http://b"]) {
- let uri = params.ioService.newURI(URL, null, null);
- params.pm.remove(uri, "cookie");
- }
- },
- },
- ],
-
- _currentTest: -1,
-
- runTests: function() {
- this._currentTest++;
-
- info("Running test #" + (this._currentTest + 1) + "\n");
- let that = this;
- let p = this.runCurrentTest(this._currentTest + 1);
- p.then(function() {
- if (that._currentTest == that.tests.length - 1) {
- finish();
- }
- else {
- that.runTests();
- }
- });
- },
-
- runCurrentTest: function(testNumber) {
- return new Promise(function(resolve, reject) {
-
- let helperFunctions = {
- windowLoad: function(win) {
- let doc = win.document;
- let params = {
- doc,
- tree: doc.getElementById("permissionsTree"),
- nameCol: doc.getElementById("permissionsTree").treeBoxObject.columns.getColumnAt(0),
- statusCol: doc.getElementById("permissionsTree").treeBoxObject.columns.getColumnAt(1),
- url: doc.getElementById("url"),
- btnAllow: doc.getElementById("btnAllow"),
- btnBlock: doc.getElementById("btnBlock"),
- btnApplyChanges: doc.getElementById("btnApplyChanges"),
- btnRemove: doc.getElementById("removePermission"),
- pm: Cc["@mozilla.org/permissionmanager;1"]
- .getService(Ci.nsIPermissionManager),
- ioService: Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService),
- allowText: win.gPermissionManager._getCapabilityString(
- Ci.nsIPermissionManager.ALLOW_ACTION),
- denyText: win.gPermissionManager._getCapabilityString(
- Ci.nsIPermissionManager.DENY_ACTION),
- allow: Ci.nsIPermissionManager.ALLOW_ACTION,
- deny: Ci.nsIPermissionManager.DENY_ACTION,
- };
-
- let permObserver = {
- observe: function(aSubject, aTopic, aData) {
- if (aTopic != "perm-changed")
- return;
-
- if (testRunner.tests[testRunner._currentTest].observances.length == 0) {
- // Should fail here as we are not expecting a notification, but we don't.
- // See bug 1063410.
- return;
- }
-
- let permission = aSubject.QueryInterface(Ci.nsIPermission);
- let expected = testRunner.tests[testRunner._currentTest].observances.shift();
-
- is(aData, expected.data, "type of message should be the same");
- for (let prop of ["type", "capability"]) {
- if (expected[prop])
- is(permission[prop], expected[prop],
- "property: \"" + prop + "\" should be equal");
- }
-
- if (expected.origin) {
- is(permission.principal.origin, expected.origin,
- "property: \"origin\" should be equal");
- }
-
- os.removeObserver(permObserver, "perm-changed");
-
- let test = testRunner.tests[testRunner._currentTest];
- if (!test.expectPermObservancesDuringTestFunction) {
- if (test.cleanUp) {
- test.cleanUp(params);
- }
-
- gBrowser.removeCurrentTab();
- resolve();
- }
- },
- };
-
- let os = Cc["@mozilla.org/observer-service;1"]
- .getService(Ci.nsIObserverService);
-
- os.addObserver(permObserver, "perm-changed", false);
-
- if (testRunner._currentTest == 0) {
- is(params.tree.view.rowCount, 0, "no cookie exceptions");
- }
-
- try {
- let test = testRunner.tests[testRunner._currentTest];
- test.test(params);
- if (test.expectPermObservancesDuringTestFunction) {
- if (test.cleanUp) {
- test.cleanUp(params);
- }
-
- gBrowser.removeCurrentTab();
- resolve();
- }
- } catch (ex) {
- ok(false, "exception while running test #" +
- testNumber + ": " + ex);
- }
- },
- };
-
- openPreferencesViaOpenPreferencesAPI("panePrivacy", null, {leaveOpen: true}).then(function() {
- let doc = gBrowser.contentDocument;
- let historyMode = doc.getElementById("historyMode");
- historyMode.value = "custom";
- historyMode.doCommand();
- doc.getElementById("cookieExceptions").doCommand();
-
- let subDialogURL = "chrome://browser/content/preferences/permissions.xul";
- promiseLoadSubDialog(subDialogURL).then(function(win) {
- helperFunctions.windowLoad(win);
- });
- });
- });
- },
-};
diff --git a/browser/components/preferences/in-content/tests/browser_defaultbrowser_alwayscheck.js b/browser/components/preferences/in-content/tests/browser_defaultbrowser_alwayscheck.js
deleted file mode 100644
index b30b6d9e2..000000000
--- a/browser/components/preferences/in-content/tests/browser_defaultbrowser_alwayscheck.js
+++ /dev/null
@@ -1,103 +0,0 @@
-"use strict";
-
-const CHECK_DEFAULT_INITIAL = Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser");
-
-add_task(function* clicking_make_default_checks_alwaysCheck_checkbox() {
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
-
- yield test_with_mock_shellservice({isDefault: false}, function*() {
- let setDefaultPane = content.document.getElementById("setDefaultPane");
- Assert.equal(setDefaultPane.selectedIndex, "0",
- "The 'make default' pane should be visible when not default");
- let alwaysCheck = content.document.getElementById("alwaysCheckDefault");
- Assert.ok(!alwaysCheck.checked, "Always Check is unchecked by default");
- Assert.ok(!Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser"),
- "alwaysCheck pref should be false by default in test runs");
-
- let setDefaultButton = content.document.getElementById("setDefaultButton");
- setDefaultButton.click();
- content.window.gMainPane.updateSetDefaultBrowser();
-
- yield ContentTaskUtils.waitForCondition(() => alwaysCheck.checked,
- "'Always Check' checkbox should get checked after clicking the 'Set Default' button");
-
- Assert.ok(alwaysCheck.checked,
- "Clicking 'Make Default' checks the 'Always Check' checkbox");
- Assert.ok(Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser"),
- "Checking the checkbox should set the pref to true");
- Assert.ok(alwaysCheck.disabled,
- "'Always Check' checkbox is locked with default browser and alwaysCheck=true");
- Assert.equal(setDefaultPane.selectedIndex, "1",
- "The 'make default' pane should not be visible when default");
- Assert.ok(Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser"),
- "checkDefaultBrowser pref is now enabled");
- });
-
- gBrowser.removeCurrentTab();
- Services.prefs.clearUserPref("browser.shell.checkDefaultBrowser");
-});
-
-add_task(function* clicking_make_default_checks_alwaysCheck_checkbox() {
- Services.prefs.lockPref("browser.shell.checkDefaultBrowser");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
-
- yield test_with_mock_shellservice({isDefault: false}, function*() {
- let setDefaultPane = content.document.getElementById("setDefaultPane");
- Assert.equal(setDefaultPane.selectedIndex, "0",
- "The 'make default' pane should be visible when not default");
- let alwaysCheck = content.document.getElementById("alwaysCheckDefault");
- Assert.ok(alwaysCheck.disabled, "Always Check is disabled when locked");
- Assert.ok(alwaysCheck.checked,
- "Always Check is checked because defaultPref is true and pref is locked");
- Assert.ok(Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser"),
- "alwaysCheck pref should ship with 'true' by default");
-
- let setDefaultButton = content.document.getElementById("setDefaultButton");
- setDefaultButton.click();
- content.window.gMainPane.updateSetDefaultBrowser();
-
- yield ContentTaskUtils.waitForCondition(() => setDefaultPane.selectedIndex == "1",
- "Browser is now default");
-
- Assert.ok(alwaysCheck.checked,
- "'Always Check' is still checked because it's locked");
- Assert.ok(alwaysCheck.disabled,
- "'Always Check is disabled because it's locked");
- Assert.ok(Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser"),
- "The pref is locked and so doesn't get changed");
- });
-
- Services.prefs.unlockPref("browser.shell.checkDefaultBrowser");
- gBrowser.removeCurrentTab();
-});
-
-registerCleanupFunction(function() {
- Services.prefs.unlockPref("browser.shell.checkDefaultBrowser");
- Services.prefs.setBoolPref("browser.shell.checkDefaultBrowser", CHECK_DEFAULT_INITIAL);
-});
-
-function* test_with_mock_shellservice(options, testFn) {
- yield ContentTask.spawn(gBrowser.selectedBrowser, options, function*(options) {
- let doc = content.document;
- let win = doc.defaultView;
- win.oldShellService = win.getShellService();
- let mockShellService = {
- _isDefault: false,
- isDefaultBrowser() {
- return this._isDefault;
- },
- setDefaultBrowser() {
- this._isDefault = true;
- },
- };
- win.getShellService = function() {
- return mockShellService;
- }
- mockShellService._isDefault = options.isDefault;
- win.gMainPane.updateSetDefaultBrowser();
- });
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, null, testFn);
-
- Services.prefs.setBoolPref("browser.shell.checkDefaultBrowser", CHECK_DEFAULT_INITIAL);
-}
diff --git a/browser/components/preferences/in-content/tests/browser_healthreport.js b/browser/components/preferences/in-content/tests/browser_healthreport.js
deleted file mode 100644
index bbfae9707..000000000
--- a/browser/components/preferences/in-content/tests/browser_healthreport.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-* http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
-
-function runPaneTest(fn) {
- open_preferences((win) => {
- let doc = win.document;
- win.gotoPref("paneAdvanced");
- let advancedPrefs = doc.getElementById("advancedPrefs");
- let tab = doc.getElementById("dataChoicesTab");
- advancedPrefs.selectedTab = tab;
- fn(win, doc);
- });
-}
-
-function test() {
- waitForExplicitFinish();
- resetPreferences();
- registerCleanupFunction(resetPreferences);
- runPaneTest(testBasic);
-}
-
-function testBasic(win, doc) {
- is(Services.prefs.getBoolPref(FHR_UPLOAD_ENABLED), true,
- "Health Report upload enabled on app first run.");
-
- let checkbox = doc.getElementById("submitHealthReportBox");
- ok(checkbox);
- is(checkbox.checked, true, "Health Report checkbox is checked on app first run.");
-
- checkbox.checked = false;
- checkbox.doCommand();
- is(Services.prefs.getBoolPref(FHR_UPLOAD_ENABLED), false,
- "Unchecking checkbox opts out of FHR upload.");
-
- checkbox.checked = true;
- checkbox.doCommand();
- is(Services.prefs.getBoolPref(FHR_UPLOAD_ENABLED), true,
- "Checking checkbox allows FHR upload.");
-
- win.close();
- Services.prefs.lockPref(FHR_UPLOAD_ENABLED);
- runPaneTest(testUploadDisabled);
-}
-
-function testUploadDisabled(win, doc) {
- ok(Services.prefs.prefIsLocked(FHR_UPLOAD_ENABLED), "Upload enabled flag is locked.");
- let checkbox = doc.getElementById("submitHealthReportBox");
- is(checkbox.getAttribute("disabled"), "true", "Checkbox is disabled if upload flag is locked.");
- Services.prefs.unlockPref(FHR_UPLOAD_ENABLED);
-
- win.close();
- finish();
-}
-
-function resetPreferences() {
- Services.prefs.clearUserPref(FHR_UPLOAD_ENABLED);
-}
-
diff --git a/browser/components/preferences/in-content/tests/browser_homepages_filter_aboutpreferences.js b/browser/components/preferences/in-content/tests/browser_homepages_filter_aboutpreferences.js
deleted file mode 100644
index 366454fcc..000000000
--- a/browser/components/preferences/in-content/tests/browser_homepages_filter_aboutpreferences.js
+++ /dev/null
@@ -1,20 +0,0 @@
-add_task(function*() {
- is(gBrowser.currentURI.spec, "about:blank", "Test starts with about:blank open");
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home");
- yield openPreferencesViaOpenPreferencesAPI("paneGeneral", null, {leaveOpen: true});
- let doc = gBrowser.contentDocument;
- is(gBrowser.currentURI.spec, "about:preferences#general",
- "#general should be in the URI for about:preferences");
- let oldHomepagePref = Services.prefs.getCharPref("browser.startup.homepage");
-
- let useCurrent = doc.getElementById("useCurrent");
- useCurrent.click();
-
- is(gBrowser.tabs.length, 3, "Three tabs should be open");
- is(Services.prefs.getCharPref("browser.startup.homepage"), "about:blank|about:home",
- "about:blank and about:home should be the only homepages set");
-
- Services.prefs.setCharPref("browser.startup.homepage", oldHomepagePref);
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
diff --git a/browser/components/preferences/in-content/tests/browser_notifications_do_not_disturb.js b/browser/components/preferences/in-content/tests/browser_notifications_do_not_disturb.js
deleted file mode 100644
index 68f9653f6..000000000
--- a/browser/components/preferences/in-content/tests/browser_notifications_do_not_disturb.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-registerCleanupFunction(function() {
- while (gBrowser.tabs[1])
- gBrowser.removeTab(gBrowser.tabs[1]);
-});
-
-add_task(function*() {
- let prefs = yield openPreferencesViaOpenPreferencesAPI("paneContent", undefined, {leaveOpen: true});
- is(prefs.selectedPane, "paneContent", "Content pane was selected");
-
- let doc = gBrowser.contentDocument;
- let notificationsDoNotDisturbRow = doc.getElementById("notificationsDoNotDisturbRow");
- if (notificationsDoNotDisturbRow.hidden) {
- todo(false, "Do not disturb is not available on this platform");
- return;
- }
-
- let alertService;
- try {
- alertService = Cc["@mozilla.org/alerts-service;1"]
- .getService(Ci.nsIAlertsService)
- .QueryInterface(Ci.nsIAlertsDoNotDisturb);
- } catch (ex) {
- ok(true, "Do not disturb is not available on this platform: " + ex.message);
- return;
- }
-
- let checkbox = doc.getElementById("notificationsDoNotDisturb");
- ok(!checkbox.checked, "Checkbox should not be checked by default");
- ok(!alertService.manualDoNotDisturb, "Do not disturb should be off by default");
-
- let checkboxChanged = waitForEvent(checkbox, "command")
- checkbox.click();
- yield checkboxChanged;
- ok(alertService.manualDoNotDisturb, "Do not disturb should be enabled when checked");
-
- checkboxChanged = waitForEvent(checkbox, "command")
- checkbox.click();
- yield checkboxChanged;
- ok(!alertService.manualDoNotDisturb, "Do not disturb should be disabled when unchecked");
-});
diff --git a/browser/components/preferences/in-content/tests/browser_permissions_urlFieldHidden.js b/browser/components/preferences/in-content/tests/browser_permissions_urlFieldHidden.js
deleted file mode 100644
index d9253735a..000000000
--- a/browser/components/preferences/in-content/tests/browser_permissions_urlFieldHidden.js
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-const PERMISSIONS_URL = "chrome://browser/content/preferences/permissions.xul";
-
-add_task(function* urlFieldVisibleForPopupPermissions(finish) {
- yield openPreferencesViaOpenPreferencesAPI("paneContent", null, {leaveOpen: true});
- let win = gBrowser.selectedBrowser.contentWindow;
- let doc = win.document;
- let popupPolicyCheckbox = doc.getElementById("popupPolicy");
- ok(!popupPolicyCheckbox.checked, "popupPolicyCheckbox should be unchecked by default");
- popupPolicyCheckbox.click();
- let popupPolicyButton = doc.getElementById("popupPolicyButton");
- ok(popupPolicyButton, "popupPolicyButton found");
- let dialogPromise = promiseLoadSubDialog(PERMISSIONS_URL);
- popupPolicyButton.click();
- let dialog = yield dialogPromise;
- ok(dialog, "dialog loaded");
-
- let urlLabel = dialog.document.getElementById("urlLabel");
- ok(!urlLabel.hidden, "urlLabel should be visible when one of block/session/allow visible");
- let url = dialog.document.getElementById("url");
- ok(!url.hidden, "url should be visible when one of block/session/allow visible");
-
- popupPolicyCheckbox.click();
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* urlFieldHiddenForNotificationPermissions() {
- yield openPreferencesViaOpenPreferencesAPI("paneContent", null, {leaveOpen: true});
- let win = gBrowser.selectedBrowser.contentWindow;
- let doc = win.document;
- let notificationsPolicyButton = doc.getElementById("notificationsPolicyButton");
- ok(notificationsPolicyButton, "notificationsPolicyButton found");
- let dialogPromise = promiseLoadSubDialog(PERMISSIONS_URL);
- notificationsPolicyButton.click();
- let dialog = yield dialogPromise;
- ok(dialog, "dialog loaded");
-
- let urlLabel = dialog.document.getElementById("urlLabel");
- ok(urlLabel.hidden, "urlLabel should be hidden as requested");
- let url = dialog.document.getElementById("url");
- ok(url.hidden, "url should be hidden as requested");
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/preferences/in-content/tests/browser_privacypane_1.js b/browser/components/preferences/in-content/tests/browser_privacypane_1.js
deleted file mode 100644
index 0df60c6ac..000000000
--- a/browser/components/preferences/in-content/tests/browser_privacypane_1.js
+++ /dev/null
@@ -1,18 +0,0 @@
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-
-let rootDir = getRootDirectory(gTestPath);
-let jar = getJar(rootDir);
-if (jar) {
- let tmpdir = extractJarToTmp(jar);
- rootDir = "file://" + tmpdir.path + '/';
-}
-loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
-
-run_test_subset([
- test_pane_visibility,
- test_dependent_elements,
- test_dependent_cookie_elements,
- test_dependent_clearonclose_elements,
- test_dependent_prefs,
-]);
diff --git a/browser/components/preferences/in-content/tests/browser_privacypane_3.js b/browser/components/preferences/in-content/tests/browser_privacypane_3.js
deleted file mode 100644
index 8fe6f0825..000000000
--- a/browser/components/preferences/in-content/tests/browser_privacypane_3.js
+++ /dev/null
@@ -1,17 +0,0 @@
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-let rootDir = getRootDirectory(gTestPath);
-let jar = getJar(rootDir);
-if (jar) {
- let tmpdir = extractJarToTmp(jar);
- rootDir = "file://" + tmpdir.path + '/';
-}
-loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
-
-run_test_subset([
- test_custom_retention("rememberHistory", "remember"),
- test_custom_retention("rememberHistory", "custom"),
- test_custom_retention("rememberForms", "remember"),
- test_custom_retention("rememberForms", "custom"),
- test_historymode_retention("remember", "remember"),
-]);
diff --git a/browser/components/preferences/in-content/tests/browser_privacypane_4.js b/browser/components/preferences/in-content/tests/browser_privacypane_4.js
deleted file mode 100644
index b7ef3deda..000000000
--- a/browser/components/preferences/in-content/tests/browser_privacypane_4.js
+++ /dev/null
@@ -1,25 +0,0 @@
-requestLongerTimeout(2);
-
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-let rootDir = getRootDirectory(gTestPath);
-let jar = getJar(rootDir);
-if (jar) {
- let tmpdir = extractJarToTmp(jar);
- rootDir = "file://" + tmpdir.path + '/';
-}
-loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
-let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
-
-run_test_subset([
- test_custom_retention("acceptCookies", "remember"),
- test_custom_retention("acceptCookies", "custom"),
- test_custom_retention("acceptThirdPartyMenu", "remember", "visited"),
- test_custom_retention("acceptThirdPartyMenu", "custom", "always"),
- test_custom_retention("keepCookiesUntil", "remember", 1),
- test_custom_retention("keepCookiesUntil", "custom", 2),
- test_custom_retention("keepCookiesUntil", "custom", 0),
- test_custom_retention("alwaysClear", "remember"),
- test_custom_retention("alwaysClear", "custom"),
- test_historymode_retention("remember", "remember"),
-]);
diff --git a/browser/components/preferences/in-content/tests/browser_privacypane_5.js b/browser/components/preferences/in-content/tests/browser_privacypane_5.js
deleted file mode 100644
index a07530010..000000000
--- a/browser/components/preferences/in-content/tests/browser_privacypane_5.js
+++ /dev/null
@@ -1,17 +0,0 @@
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-let rootDir = getRootDirectory(gTestPath);
-let jar = getJar(rootDir);
-if (jar) {
- let tmpdir = extractJarToTmp(jar);
- rootDir = "file://" + tmpdir.path + '/';
-}
-loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
-
-run_test_subset([
- test_locbar_suggestion_retention("history", true),
- test_locbar_suggestion_retention("bookmark", true),
- test_locbar_suggestion_retention("openpage", false),
- test_locbar_suggestion_retention("history", true),
- test_locbar_suggestion_retention("history", false),
-]);
diff --git a/browser/components/preferences/in-content/tests/browser_privacypane_8.js b/browser/components/preferences/in-content/tests/browser_privacypane_8.js
deleted file mode 100644
index 756b19a2f..000000000
--- a/browser/components/preferences/in-content/tests/browser_privacypane_8.js
+++ /dev/null
@@ -1,26 +0,0 @@
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-let rootDir = getRootDirectory(gTestPath);
-let jar = getJar(rootDir);
-if (jar) {
- let tmpdir = extractJarToTmp(jar);
- rootDir = "file://" + tmpdir.path + '/';
-}
-loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
-
-run_test_subset([
- // history mode should be initialized to remember
- test_historymode_retention("remember", undefined),
-
- // history mode should remain remember; toggle acceptCookies checkbox
- test_custom_retention("acceptCookies", "remember"),
-
- // history mode should now be custom; set history mode to dontremember
- test_historymode_retention("dontremember", "custom"),
-
- // history mode should remain custom; set history mode to remember
- test_historymode_retention("remember", "custom"),
-
- // history mode should now be remember
- test_historymode_retention("remember", "remember"),
-]);
diff --git a/browser/components/preferences/in-content/tests/browser_proxy_backup.js b/browser/components/preferences/in-content/tests/browser_proxy_backup.js
deleted file mode 100644
index 3ad24c7ec..000000000
--- a/browser/components/preferences/in-content/tests/browser_proxy_backup.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/Task.jsm");
-
-function test() {
- waitForExplicitFinish();
-
- // network.proxy.type needs to be backed up and restored because mochitest
- // changes this setting from the default
- let oldNetworkProxyType = Services.prefs.getIntPref("network.proxy.type");
- registerCleanupFunction(function() {
- Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
- Services.prefs.clearUserPref("browser.preferences.instantApply");
- Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
- for (let proxyType of ["http", "ssl", "ftp", "socks"]) {
- Services.prefs.clearUserPref("network.proxy." + proxyType);
- Services.prefs.clearUserPref("network.proxy." + proxyType + "_port");
- if (proxyType == "http") {
- continue;
- }
- Services.prefs.clearUserPref("network.proxy.backup." + proxyType);
- Services.prefs.clearUserPref("network.proxy.backup." + proxyType + "_port");
- }
- });
-
- let connectionURL = "chrome://browser/content/preferences/connection.xul";
-
- // Set a shared proxy and a SOCKS backup
- Services.prefs.setIntPref("network.proxy.type", 1);
- Services.prefs.setBoolPref("network.proxy.share_proxy_settings", true);
- Services.prefs.setCharPref("network.proxy.http", "example.com");
- Services.prefs.setIntPref("network.proxy.http_port", 1200);
- Services.prefs.setCharPref("network.proxy.socks", "example.com");
- Services.prefs.setIntPref("network.proxy.socks_port", 1200);
- Services.prefs.setCharPref("network.proxy.backup.socks", "127.0.0.1");
- Services.prefs.setIntPref("network.proxy.backup.socks_port", 9050);
-
- /*
- The connection dialog alone won't save onaccept since it uses type="child",
- so it has to be opened as a sub dialog of the main pref tab.
- Open the main tab here.
- */
- open_preferences(Task.async(function* tabOpened(aContentWindow) {
- is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
- let dialog = yield openAndLoadSubDialog(connectionURL);
- let dialogClosingPromise = waitForEvent(dialog.document.documentElement, "dialogclosing");
-
- ok(dialog, "connection window opened");
- dialog.document.documentElement.acceptDialog();
-
- let dialogClosingEvent = yield dialogClosingPromise;
- ok(dialogClosingEvent, "connection window closed");
-
- // The SOCKS backup should not be replaced by the shared value
- is(Services.prefs.getCharPref("network.proxy.backup.socks"), "127.0.0.1", "Shared proxy backup shouldn't be replaced");
- is(Services.prefs.getIntPref("network.proxy.backup.socks_port"), 9050, "Shared proxy port backup shouldn't be replaced");
-
- gBrowser.removeCurrentTab();
- finish();
- }));
-}
diff --git a/browser/components/preferences/in-content/tests/browser_sanitizeOnShutdown_prefLocked.js b/browser/components/preferences/in-content/tests/browser_sanitizeOnShutdown_prefLocked.js
deleted file mode 100644
index 6b587e036..000000000
--- a/browser/components/preferences/in-content/tests/browser_sanitizeOnShutdown_prefLocked.js
+++ /dev/null
@@ -1,37 +0,0 @@
-"use strict";
-
-function switchToCustomHistoryMode(doc) {
- // Select the last item in the menulist.
- let menulist = doc.getElementById("historyMode");
- menulist.focus();
- EventUtils.sendKey("UP");
-}
-
-function testPrefStateMatchesLockedState() {
- let win = gBrowser.contentWindow;
- let doc = win.document;
- switchToCustomHistoryMode(doc);
-
- let checkbox = doc.getElementById("alwaysClear");
- let preference = doc.getElementById("privacy.sanitize.sanitizeOnShutdown");
- is(checkbox.disabled, preference.locked, "Always Clear checkbox should be enabled when preference is not locked.");
-
- gBrowser.removeCurrentTab();
-}
-
-add_task(function setup() {
- registerCleanupFunction(function resetPreferences() {
- Services.prefs.unlockPref("privacy.sanitize.sanitizeOnShutdown");
- });
-});
-
-add_task(function* test_preference_enabled_when_unlocked() {
- yield openPreferencesViaOpenPreferencesAPI("panePrivacy", undefined, {leaveOpen: true});
- testPrefStateMatchesLockedState();
-});
-
-add_task(function* test_preference_disabled_when_locked() {
- Services.prefs.lockPref("privacy.sanitize.sanitizeOnShutdown");
- yield openPreferencesViaOpenPreferencesAPI("panePrivacy", undefined, {leaveOpen: true});
- testPrefStateMatchesLockedState();
-});
diff --git a/browser/components/preferences/in-content/tests/browser_searchsuggestions.js b/browser/components/preferences/in-content/tests/browser_searchsuggestions.js
deleted file mode 100644
index 0185a23b9..000000000
--- a/browser/components/preferences/in-content/tests/browser_searchsuggestions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-var original = Services.prefs.getBoolPref("browser.search.suggest.enabled");
-
-registerCleanupFunction(() => {
- Services.prefs.setBoolPref("browser.search.suggest.enabled", original);
-});
-
-// Open with suggestions enabled
-add_task(function*() {
- Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
-
- yield openPreferencesViaOpenPreferencesAPI("search", undefined, { leaveOpen: true });
-
- let doc = gBrowser.selectedBrowser.contentDocument;
- let urlbarBox = doc.getElementById("urlBarSuggestion");
- ok(!urlbarBox.disabled, "Checkbox should be enabled");
-
- Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
-
- ok(urlbarBox.disabled, "Checkbox should be disabled");
-
- gBrowser.removeCurrentTab();
-});
-
-// Open with suggestions disabled
-add_task(function*() {
- Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
-
- yield openPreferencesViaOpenPreferencesAPI("search", undefined, { leaveOpen: true });
-
- let doc = gBrowser.selectedBrowser.contentDocument;
- let urlbarBox = doc.getElementById("urlBarSuggestion");
- ok(urlbarBox.disabled, "Checkbox should be disabled");
-
- Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
-
- ok(!urlbarBox.disabled, "Checkbox should be enabled");
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function*() {
- Services.prefs.setBoolPref("browser.search.suggest.enabled", original);
-});
diff --git a/browser/components/preferences/in-content/tests/browser_security.js b/browser/components/preferences/in-content/tests/browser_security.js
deleted file mode 100644
index e6eb2a91d..000000000
--- a/browser/components/preferences/in-content/tests/browser_security.js
+++ /dev/null
@@ -1,130 +0,0 @@
-const PREFS = [
- "browser.safebrowsing.phishing.enabled",
- "browser.safebrowsing.malware.enabled",
-
- "browser.safebrowsing.downloads.enabled",
-
- "browser.safebrowsing.downloads.remote.block_potentially_unwanted",
- "browser.safebrowsing.downloads.remote.block_uncommon"
-];
-
-let originals = PREFS.map(pref => [pref, Services.prefs.getBoolPref(pref)])
-let originalMalwareTable = Services.prefs.getCharPref("urlclassifier.malwareTable");
-registerCleanupFunction(function() {
- originals.forEach(([pref, val]) => Services.prefs.setBoolPref(pref, val))
- Services.prefs.setCharPref("urlclassifier.malwareTable", originalMalwareTable);
-});
-
-// test the safebrowsing preference
-add_task(function*() {
- function* checkPrefSwitch(val1, val2) {
- Services.prefs.setBoolPref("browser.safebrowsing.phishing.enabled", val1);
- Services.prefs.setBoolPref("browser.safebrowsing.malware.enabled", val2);
-
- yield openPreferencesViaOpenPreferencesAPI("security", undefined, { leaveOpen: true });
-
- let doc = gBrowser.selectedBrowser.contentDocument;
- let checkbox = doc.getElementById("enableSafeBrowsing");
- let blockDownloads = doc.getElementById("blockDownloads");
- let blockUncommon = doc.getElementById("blockUncommonUnwanted");
- let checked = checkbox.checked;
- is(checked, val1 && val2, "safebrowsing preference is initialized correctly");
- // should be disabled when checked is false (= pref is turned off)
- is(blockDownloads.hasAttribute("disabled"), !checked, "block downloads checkbox is set correctly");
- is(blockUncommon.hasAttribute("disabled"), !checked, "block uncommon checkbox is set correctly");
-
- // click the checkbox
- EventUtils.synthesizeMouseAtCenter(checkbox, {}, gBrowser.selectedBrowser.contentWindow);
-
- // check that both settings are now turned on or off
- is(Services.prefs.getBoolPref("browser.safebrowsing.phishing.enabled"), !checked,
- "safebrowsing.enabled is set correctly");
- is(Services.prefs.getBoolPref("browser.safebrowsing.malware.enabled"), !checked,
- "safebrowsing.malware.enabled is set correctly");
-
- // check if the other checkboxes have updated
- checked = checkbox.checked;
- is(blockDownloads.hasAttribute("disabled"), !checked, "block downloads checkbox is set correctly");
- is(blockUncommon.hasAttribute("disabled"), !checked || !blockDownloads.checked, "block uncommon checkbox is set correctly");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- }
-
- yield checkPrefSwitch(true, true);
- yield checkPrefSwitch(false, true);
- yield checkPrefSwitch(true, false);
- yield checkPrefSwitch(false, false);
-});
-
-// test the download protection preference
-add_task(function*() {
- function* checkPrefSwitch(val) {
- Services.prefs.setBoolPref("browser.safebrowsing.downloads.enabled", val);
-
- yield openPreferencesViaOpenPreferencesAPI("security", undefined, { leaveOpen: true });
-
- let doc = gBrowser.selectedBrowser.contentDocument;
- let checkbox = doc.getElementById("blockDownloads");
- let blockUncommon = doc.getElementById("blockUncommonUnwanted");
- let checked = checkbox.checked;
- is(checked, val, "downloads preference is initialized correctly");
- // should be disabled when val is false (= pref is turned off)
- is(blockUncommon.hasAttribute("disabled"), !val, "block uncommon checkbox is set correctly");
-
- // click the checkbox
- EventUtils.synthesizeMouseAtCenter(checkbox, {}, gBrowser.selectedBrowser.contentWindow);
-
- // check that setting is now turned on or off
- is(Services.prefs.getBoolPref("browser.safebrowsing.downloads.enabled"), !checked,
- "safebrowsing.downloads preference is set correctly");
-
- // check if the uncommon warning checkbox has updated
- is(blockUncommon.hasAttribute("disabled"), val, "block uncommon checkbox is set correctly");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- }
-
- yield checkPrefSwitch(true);
- yield checkPrefSwitch(false);
-});
-
-// test the unwanted/uncommon software warning preference
-add_task(function*() {
- function* checkPrefSwitch(val1, val2) {
- Services.prefs.setBoolPref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", val1);
- Services.prefs.setBoolPref("browser.safebrowsing.downloads.remote.block_uncommon", val2);
-
- yield openPreferencesViaOpenPreferencesAPI("security", undefined, { leaveOpen: true });
-
- let doc = gBrowser.selectedBrowser.contentDocument;
- let checkbox = doc.getElementById("blockUncommonUnwanted");
- let checked = checkbox.checked;
- is(checked, val1 && val2, "unwanted/uncommon preference is initialized correctly");
-
- // click the checkbox
- EventUtils.synthesizeMouseAtCenter(checkbox, {}, gBrowser.selectedBrowser.contentWindow);
-
- // check that both settings are now turned on or off
- is(Services.prefs.getBoolPref("browser.safebrowsing.downloads.remote.block_potentially_unwanted"), !checked,
- "block_potentially_unwanted is set correctly");
- is(Services.prefs.getBoolPref("browser.safebrowsing.downloads.remote.block_uncommon"), !checked,
- "block_uncommon is set correctly");
-
- // when the preference is on, the malware table should include these ids
- let malwareTable = Services.prefs.getCharPref("urlclassifier.malwareTable").split(",");
- is(malwareTable.includes("goog-unwanted-shavar"), !checked,
- "malware table doesn't include goog-unwanted-shavar");
- is(malwareTable.includes("test-unwanted-simple"), !checked,
- "malware table doesn't include test-unwanted-simple");
- let sortedMalware = malwareTable.slice(0);
- sortedMalware.sort();
- Assert.deepEqual(malwareTable, sortedMalware, "malware table has been sorted");
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- }
-
- yield* checkPrefSwitch(true, true);
- yield* checkPrefSwitch(false, true);
- yield* checkPrefSwitch(true, false);
- yield* checkPrefSwitch(false, false);
-});
diff --git a/browser/components/preferences/in-content/tests/browser_subdialogs.js b/browser/components/preferences/in-content/tests/browser_subdialogs.js
deleted file mode 100644
index ff0c1f8ae..000000000
--- a/browser/components/preferences/in-content/tests/browser_subdialogs.js
+++ /dev/null
@@ -1,293 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-* http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * Tests for the sub-dialog infrastructure, not for actual sub-dialog functionality.
- */
-
-const gDialogURL = getRootDirectory(gTestPath) + "subdialog.xul";
-const gDialogURL2 = getRootDirectory(gTestPath) + "subdialog2.xul";
-
-function* open_subdialog_and_test_generic_start_state(browser, domcontentloadedFn, url = gDialogURL) {
- let domcontentloadedFnStr = domcontentloadedFn ?
- "(" + domcontentloadedFn.toString() + ")()" :
- "";
- return ContentTask.spawn(browser, {url, domcontentloadedFnStr}, function*(args) {
- let {url, domcontentloadedFnStr} = args;
- let rv = { acceptCount: 0 };
- let win = content.window;
- let subdialog = win.gSubDialog;
- subdialog.open(url, null, rv);
-
- info("waiting for subdialog DOMFrameContentLoaded");
- yield ContentTaskUtils.waitForEvent(win, "DOMFrameContentLoaded", true);
- let result;
- if (domcontentloadedFnStr) {
- result = eval(domcontentloadedFnStr);
- }
-
- info("waiting for subdialog load");
- yield ContentTaskUtils.waitForEvent(subdialog._frame, "load");
- info("subdialog window is loaded");
-
- let expectedStyleSheetURLs = subdialog._injectedStyleSheets.slice(0);
- for (let styleSheet of subdialog._frame.contentDocument.styleSheets) {
- let index = expectedStyleSheetURLs.indexOf(styleSheet.href);
- if (index >= 0) {
- expectedStyleSheetURLs.splice(index, 1);
- }
- }
-
- Assert.ok(!!subdialog._frame.contentWindow, "The dialog should be non-null");
- Assert.notEqual(subdialog._frame.contentWindow.location.toString(), "about:blank",
- "Subdialog URL should not be about:blank");
- Assert.equal(win.getComputedStyle(subdialog._overlay, "").visibility, "visible",
- "Overlay should be visible");
- Assert.equal(expectedStyleSheetURLs.length, 0,
- "No stylesheets that were expected are missing");
- return result;
- });
-}
-
-function* close_subdialog_and_test_generic_end_state(browser, closingFn, closingButton, acceptCount, options) {
- let dialogclosingPromise = ContentTask.spawn(browser, {closingButton, acceptCount}, function*(expectations) {
- let win = content.window;
- let subdialog = win.gSubDialog;
- let frame = subdialog._frame;
- info("waiting for dialogclosing");
- let closingEvent =
- yield ContentTaskUtils.waitForEvent(frame.contentWindow, "dialogclosing");
- let closingButton = closingEvent.detail.button;
- let actualAcceptCount = frame.contentWindow.arguments &&
- frame.contentWindow.arguments[0].acceptCount;
-
- info("waiting for about:blank load");
- yield ContentTaskUtils.waitForEvent(frame, "load");
-
- Assert.notEqual(win.getComputedStyle(subdialog._overlay, "").visibility, "visible",
- "overlay is not visible");
- Assert.equal(frame.getAttribute("style"), "", "inline styles should be cleared");
- Assert.equal(frame.contentWindow.location.href.toString(), "about:blank",
- "sub-dialog should be unloaded");
- Assert.equal(closingButton, expectations.closingButton,
- "closing event should indicate button was '" + expectations.closingButton + "'");
- Assert.equal(actualAcceptCount, expectations.acceptCount,
- "should be 1 if accepted, 0 if canceled, undefined if closed w/out button");
- });
-
- if (options && options.runClosingFnOutsideOfContentTask) {
- yield closingFn();
- } else {
- ContentTask.spawn(browser, null, closingFn);
- }
-
- yield dialogclosingPromise;
-}
-
-let tab;
-
-add_task(function* test_initialize() {
- tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
-});
-
-add_task(function* check_titlebar_focus_returnval_titlechanges_accepting() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- let domtitlechangedPromise = BrowserTestUtils.waitForEvent(tab.linkedBrowser, "DOMTitleChanged");
- yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
- let dialog = content.window.gSubDialog._frame.contentWindow;
- let dialogTitleElement = content.document.getElementById("dialogTitle");
- Assert.equal(dialogTitleElement.textContent, "Sample sub-dialog",
- "Title should be correct initially");
- Assert.equal(dialog.document.activeElement.value, "Default text",
- "Textbox with correct text is focused");
- dialog.document.title = "Updated title";
- });
-
- info("waiting for DOMTitleChanged event");
- yield domtitlechangedPromise;
-
- ContentTask.spawn(tab.linkedBrowser, null, function*() {
- let dialogTitleElement = content.document.getElementById("dialogTitle");
- Assert.equal(dialogTitleElement.textContent, "Updated title",
- "subdialog should have updated title");
- });
-
- // Accept the dialog
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
- "accept", 1);
-});
-
-add_task(function* check_canceling_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- info("canceling the dialog");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentDocument.documentElement.cancelDialog(); },
- "cancel", 0);
-});
-
-add_task(function* check_reopening_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
- info("opening another dialog which will close the first");
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, "", gDialogURL2);
- info("closing as normal");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
- "accept", 1);
-});
-
-add_task(function* check_opening_while_closing() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
- info("closing");
- content.window.gSubDialog.close();
- info("reopening immediately after calling .close()");
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentDocument.documentElement.acceptDialog(); },
- "accept", 1);
-
-});
-
-add_task(function* window_close_on_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- info("canceling the dialog");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
- null, 0);
-});
-
-add_task(function* click_close_button_on_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- info("canceling the dialog");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { return BrowserTestUtils.synthesizeMouseAtCenter("#dialogClose", {}, tab.linkedBrowser); },
- null, 0, {runClosingFnOutsideOfContentTask: true});
-});
-
-add_task(function* back_navigation_on_subdialog_should_close_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- info("canceling the dialog");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.goBack(); },
- null, undefined);
-});
-
-add_task(function* back_navigation_on_browser_tab_should_close_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- info("canceling the dialog");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { tab.linkedBrowser.goBack(); },
- null, undefined, {runClosingFnOutsideOfContentTask: true});
-});
-
-add_task(function* escape_should_close_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- info("canceling the dialog");
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { return BrowserTestUtils.synthesizeKey("VK_ESCAPE", {}, tab.linkedBrowser); },
- "cancel", 0, {runClosingFnOutsideOfContentTask: true});
-});
-
-add_task(function* correct_width_and_height_should_be_used_for_dialog() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser);
-
- yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
- let frameStyle = content.window.gSubDialog._frame.style;
- Assert.equal(frameStyle.width, "32em",
- "Width should be set on the frame from the dialog");
- Assert.equal(frameStyle.height, "5em",
- "Height should be set on the frame from the dialog");
- });
-
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
- null, 0);
-});
-
-add_task(function* wrapped_text_in_dialog_should_have_expected_scrollHeight() {
- let oldHeight = yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
- let frame = content.window.gSubDialog._frame;
- let doc = frame.contentDocument;
- let oldHeight = doc.documentElement.scrollHeight;
- doc.documentElement.style.removeProperty("height");
- doc.getElementById("desc").textContent = `
- Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
- laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
- architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
- sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
- laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
- architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
- sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
- laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
- architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
- sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
- voluptatem sequi nesciunt.`
- return oldHeight;
- });
-
- yield ContentTask.spawn(tab.linkedBrowser, oldHeight, function*(oldHeight) {
- let frame = content.window.gSubDialog._frame;
- let docEl = frame.contentDocument.documentElement;
- Assert.equal(frame.style.width, "32em",
- "Width should be set on the frame from the dialog");
- Assert.ok(docEl.scrollHeight > oldHeight,
- "Content height increased (from " + oldHeight + " to " + docEl.scrollHeight + ").");
- Assert.equal(frame.style.height, docEl.scrollHeight + "px",
- "Height on the frame should be higher now");
- });
-
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
- null, 0);
-});
-
-add_task(function* dialog_too_tall_should_get_reduced_in_height() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
- let frame = content.window.gSubDialog._frame;
- frame.contentDocument.documentElement.style.height = '100000px';
- });
-
- yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
- let frame = content.window.gSubDialog._frame;
- Assert.equal(frame.style.width, "32em", "Width should be set on the frame from the dialog");
- Assert.ok(parseInt(frame.style.height, 10) < content.window.innerHeight,
- "Height on the frame should be smaller than window's innerHeight");
- });
-
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
- null, 0);
-});
-
-add_task(function* scrollWidth_and_scrollHeight_from_subdialog_should_size_the_browser() {
- yield open_subdialog_and_test_generic_start_state(tab.linkedBrowser, function domcontentloadedFn() {
- let frame = content.window.gSubDialog._frame;
- frame.contentDocument.documentElement.style.removeProperty("height");
- frame.contentDocument.documentElement.style.removeProperty("width");
- });
-
- yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
- let frame = content.window.gSubDialog._frame;
- Assert.ok(frame.style.width.endsWith("px"),
- "Width (" + frame.style.width + ") should be set to a px value of the scrollWidth from the dialog");
- Assert.ok(frame.style.height.endsWith("px"),
- "Height (" + frame.style.height + ") should be set to a px value of the scrollHeight from the dialog");
- });
-
- yield close_subdialog_and_test_generic_end_state(tab.linkedBrowser,
- function() { content.window.gSubDialog._frame.contentWindow.window.close(); },
- null, 0);
-});
-
-add_task(function* test_shutdown() {
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/preferences/in-content/tests/browser_telemetry.js b/browser/components/preferences/in-content/tests/browser_telemetry.js
deleted file mode 100644
index d8139d87a..000000000
--- a/browser/components/preferences/in-content/tests/browser_telemetry.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-* http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
-
-function runPaneTest(fn) {
- open_preferences((win) => {
- let doc = win.document;
- win.gotoPref("paneAdvanced");
- let advancedPrefs = doc.getElementById("advancedPrefs");
- let tab = doc.getElementById("dataChoicesTab");
- advancedPrefs.selectedTab = tab;
- fn(win, doc);
- });
-}
-
-function test() {
- waitForExplicitFinish();
- resetPreferences();
- registerCleanupFunction(resetPreferences);
- runPaneTest(testTelemetryState);
-}
-
-function testTelemetryState(win, doc) {
- let fhrCheckbox = doc.getElementById("submitHealthReportBox");
- Assert.ok(fhrCheckbox.checked, "Health Report checkbox is checked on app first run.");
-
- let telmetryCheckbox = doc.getElementById("submitTelemetryBox");
- Assert.ok(!telmetryCheckbox.disabled,
- "Telemetry checkbox must be enabled if FHR is checked.");
- Assert.ok(Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED),
- "Telemetry must be enabled if the checkbox is ticked.");
-
- // Uncheck the FHR checkbox and make sure that Telemetry checkbox gets disabled.
- fhrCheckbox.click();
-
- Assert.ok(telmetryCheckbox.disabled,
- "Telemetry checkbox must be disabled if FHR is unchecked.");
- Assert.ok(!Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED),
- "Telemetry must be disabled if the checkbox is unticked.");
-
- win.close();
- finish();
-}
-
-function resetPreferences() {
- Services.prefs.clearUserPref("datareporting.healthreport.uploadEnabled");
- Services.prefs.clearUserPref(PREF_TELEMETRY_ENABLED);
-}
-
diff --git a/browser/components/preferences/in-content/tests/head.js b/browser/components/preferences/in-content/tests/head.js
deleted file mode 100644
index 0ed811e94..000000000
--- a/browser/components/preferences/in-content/tests/head.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Components.utils.import("resource://gre/modules/Promise.jsm");
-
-const kDefaultWait = 2000;
-
-function is_hidden(aElement) {
- var style = aElement.ownerGlobal.getComputedStyle(aElement);
- if (style.display == "none")
- return true;
- if (style.visibility != "visible")
- return true;
-
- // Hiding a parent element will hide all its children
- if (aElement.parentNode != aElement.ownerDocument)
- return is_hidden(aElement.parentNode);
-
- return false;
-}
-
-function is_element_visible(aElement, aMsg) {
- isnot(aElement, null, "Element should not be null, when checking visibility");
- ok(!is_hidden(aElement), aMsg);
-}
-
-function is_element_hidden(aElement, aMsg) {
- 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);
-}
-
-function openAndLoadSubDialog(aURL, aFeatures = null, aParams = null, aClosingCallback = null) {
- let promise = promiseLoadSubDialog(aURL);
- content.gSubDialog.open(aURL, aFeatures, aParams, aClosingCallback);
- return promise;
-}
-
-function promiseLoadSubDialog(aURL) {
- return new Promise((resolve, reject) => {
- content.gSubDialog._frame.addEventListener("load", function load(aEvent) {
- if (aEvent.target.contentWindow.location == "about:blank")
- return;
- content.gSubDialog._frame.removeEventListener("load", load);
-
- is(content.gSubDialog._frame.contentWindow.location.toString(), aURL,
- "Check the proper URL is loaded");
-
- // Check visibility
- is_element_visible(content.gSubDialog._overlay, "Overlay is visible");
-
- // Check that stylesheets were injected
- let expectedStyleSheetURLs = content.gSubDialog._injectedStyleSheets.slice(0);
- for (let styleSheet of content.gSubDialog._frame.contentDocument.styleSheets) {
- let i = expectedStyleSheetURLs.indexOf(styleSheet.href);
- if (i >= 0) {
- info("found " + styleSheet.href);
- expectedStyleSheetURLs.splice(i, 1);
- }
- }
- is(expectedStyleSheetURLs.length, 0, "All expectedStyleSheetURLs should have been found");
-
- resolve(content.gSubDialog._frame.contentWindow);
- });
- });
-}
-
-/**
- * Waits a specified number of miliseconds for a specified event to be
- * fired on a specified element.
- *
- * Usage:
- * let receivedEvent = waitForEvent(element, "eventName");
- * // Do some processing here that will cause the event to be fired
- * // ...
- * // Now yield until the Promise is fulfilled
- * yield receivedEvent;
- * if (receivedEvent && !(receivedEvent instanceof Error)) {
- * receivedEvent.msg == "eventName";
- * // ...
- * }
- *
- * @param aSubject the element that should receive the event
- * @param aEventName the event to wait for
- * @param aTimeoutMs the number of miliseconds to wait before giving up
- * @returns a Promise that resolves to the received event, or to an Error
- */
-function waitForEvent(aSubject, aEventName, aTimeoutMs, aTarget) {
- let eventDeferred = Promise.defer();
- let timeoutMs = aTimeoutMs || kDefaultWait;
- let stack = new Error().stack;
- let timerID = setTimeout(function wfe_canceller() {
- aSubject.removeEventListener(aEventName, listener);
- eventDeferred.reject(new Error(aEventName + " event timeout at " + stack));
- }, timeoutMs);
-
- var listener = function (aEvent) {
- if (aTarget && aTarget !== aEvent.target)
- return;
-
- // stop the timeout clock and resume
- clearTimeout(timerID);
- eventDeferred.resolve(aEvent);
- };
-
- function cleanup(aEventOrError) {
- // unhook listener in case of success or failure
- aSubject.removeEventListener(aEventName, listener);
- return aEventOrError;
- }
- aSubject.addEventListener(aEventName, listener, false);
- return eventDeferred.promise.then(cleanup, cleanup);
-}
-
-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);
- 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: selectedPane, selectedAdvancedTab: selectedAdvancedTab});
- });
- }, true);
-
- return deferred.promise;
-}
-
-function waitForCondition(aConditionFn, aMaxTries=50, aCheckInterval=100) {
- return new Promise((resolve, reject) => {
- function tryNow() {
- tries++;
- let rv = aConditionFn();
- if (rv) {
- resolve(rv);
- } else if (tries < aMaxTries) {
- tryAgain();
- } else {
- reject("Condition timed out: " + aConditionFn.toSource());
- }
- }
- function tryAgain() {
- setTimeout(tryNow, aCheckInterval);
- }
- let tries = 0;
- tryAgain();
- });
-}
diff --git a/browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js b/browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js
deleted file mode 100644
index 53c6d7d8a..000000000
--- a/browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js
+++ /dev/null
@@ -1,330 +0,0 @@
-function* runTestOnPrivacyPrefPane(testFunc) {
- info("runTestOnPrivacyPrefPane entered");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences", true, true);
- let browser = tab.linkedBrowser;
- info("loaded about:preferences");
- browser.contentWindow.gotoPref("panePrivacy");
- info("viewing privacy pane, executing testFunc");
- testFunc(browser.contentWindow);
- yield BrowserTestUtils.removeTab(tab);
-}
-
-function controlChanged(element) {
- element.doCommand();
-}
-
-// We can only test the panes that don't trigger a preference update
-function test_pane_visibility(win) {
- let modes = {
- "remember": "historyRememberPane",
- "custom": "historyCustomPane"
- };
-
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
- let historypane = win.document.getElementById("historyPane");
- ok(historypane, "history mode pane should exist");
-
- for (let mode in modes) {
- historymode.value = mode;
- controlChanged(historymode);
- is(historypane.selectedPanel, win.document.getElementById(modes[mode]),
- "The correct pane should be selected for the " + mode + " mode");
- is_element_visible(historypane.selectedPanel,
- "Correct pane should be visible for the " + mode + " mode");
- }
-}
-
-function test_dependent_elements(win) {
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
- let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
- ok(pbautostart, "the private browsing auto-start checkbox should exist");
- let controls = [
- win.document.getElementById("rememberHistory"),
- win.document.getElementById("rememberForms"),
- win.document.getElementById("keepUntil"),
- win.document.getElementById("keepCookiesUntil"),
- win.document.getElementById("alwaysClear"),
- ];
- controls.forEach(function(control) {
- ok(control, "the dependent controls should exist");
- });
- let independents = [
- win.document.getElementById("acceptCookies"),
- win.document.getElementById("acceptThirdPartyLabel"),
- win.document.getElementById("acceptThirdPartyMenu")
- ];
- independents.forEach(function(control) {
- ok(control, "the independent controls should exist");
- });
- let cookieexceptions = win.document.getElementById("cookieExceptions");
- ok(cookieexceptions, "the cookie exceptions button should exist");
- let keepuntil = win.document.getElementById("keepCookiesUntil");
- ok(keepuntil, "the keep cookies until menulist should exist");
- let alwaysclear = win.document.getElementById("alwaysClear");
- ok(alwaysclear, "the clear data on close checkbox should exist");
- let rememberhistory = win.document.getElementById("rememberHistory");
- ok(rememberhistory, "the remember history checkbox should exist");
- let rememberforms = win.document.getElementById("rememberForms");
- ok(rememberforms, "the remember forms checkbox should exist");
- let alwaysclearsettings = win.document.getElementById("clearDataSettings");
- ok(alwaysclearsettings, "the clear data settings button should exist");
-
- function expect_disabled(disabled) {
- controls.forEach(function(control) {
- is(control.disabled, disabled,
- control.getAttribute("id") + " should " + (disabled ? "" : "not ") + "be disabled");
- });
- is(keepuntil.value, disabled ? 2 : 0,
- "the keep cookies until menulist value should be as expected");
- if (disabled) {
- ok(!alwaysclear.checked,
- "the clear data on close checkbox value should be as expected");
- ok(!rememberhistory.checked,
- "the remember history checkbox value should be as expected");
- ok(!rememberforms.checked,
- "the remember forms checkbox value should be as expected");
- }
- }
- function check_independents(expected) {
- independents.forEach(function(control) {
- is(control.disabled, expected,
- control.getAttribute("id") + " should " + (expected ? "" : "not ") + "be disabled");
- });
-
- ok(!cookieexceptions.disabled,
- "the cookie exceptions button should never be disabled");
- ok(alwaysclearsettings.disabled,
- "the clear data settings button should always be disabled");
- }
-
- // controls should only change in custom mode
- historymode.value = "remember";
- controlChanged(historymode);
- expect_disabled(false);
- check_independents(false);
-
- // setting the mode to custom shouldn't change anything
- historymode.value = "custom";
- controlChanged(historymode);
- expect_disabled(false);
- check_independents(false);
-}
-
-function test_dependent_cookie_elements(win) {
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
- let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
- ok(pbautostart, "the private browsing auto-start checkbox should exist");
- let controls = [
- win.document.getElementById("acceptThirdPartyLabel"),
- win.document.getElementById("acceptThirdPartyMenu"),
- win.document.getElementById("keepUntil"),
- win.document.getElementById("keepCookiesUntil"),
- ];
- controls.forEach(function(control) {
- ok(control, "the dependent cookie controls should exist");
- });
- let acceptcookies = win.document.getElementById("acceptCookies");
- ok(acceptcookies, "the accept cookies checkbox should exist");
-
- function expect_disabled(disabled) {
- controls.forEach(function(control) {
- is(control.disabled, disabled,
- control.getAttribute("id") + " should " + (disabled ? "" : "not ") + "be disabled");
- });
- }
-
- historymode.value = "custom";
- controlChanged(historymode);
- pbautostart.checked = false;
- controlChanged(pbautostart);
- expect_disabled(false);
-
- acceptcookies.checked = false;
- controlChanged(acceptcookies);
- expect_disabled(true);
-
- acceptcookies.checked = true;
- controlChanged(acceptcookies);
- expect_disabled(false);
-
- let accessthirdparty = controls.shift();
- acceptcookies.checked = false;
- controlChanged(acceptcookies);
- expect_disabled(true);
- ok(accessthirdparty.disabled, "access third party button should be disabled");
-
- pbautostart.checked = false;
- controlChanged(pbautostart);
- expect_disabled(true);
- ok(accessthirdparty.disabled, "access third party button should be disabled");
-
- acceptcookies.checked = true;
- controlChanged(acceptcookies);
- expect_disabled(false);
- ok(!accessthirdparty.disabled, "access third party button should be enabled");
-}
-
-function test_dependent_clearonclose_elements(win) {
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
- let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
- ok(pbautostart, "the private browsing auto-start checkbox should exist");
- let alwaysclear = win.document.getElementById("alwaysClear");
- ok(alwaysclear, "the clear data on close checkbox should exist");
- let alwaysclearsettings = win.document.getElementById("clearDataSettings");
- ok(alwaysclearsettings, "the clear data settings button should exist");
-
- function expect_disabled(disabled) {
- is(alwaysclearsettings.disabled, disabled,
- "the clear data settings should " + (disabled ? "" : "not ") + "be disabled");
- }
-
- historymode.value = "custom";
- controlChanged(historymode);
- pbautostart.checked = false;
- controlChanged(pbautostart);
- alwaysclear.checked = false;
- controlChanged(alwaysclear);
- expect_disabled(true);
-
- alwaysclear.checked = true;
- controlChanged(alwaysclear);
- expect_disabled(false);
-
- alwaysclear.checked = false;
- controlChanged(alwaysclear);
- expect_disabled(true);
-}
-
-function test_dependent_prefs(win) {
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
- let controls = [
- win.document.getElementById("rememberHistory"),
- win.document.getElementById("rememberForms"),
- win.document.getElementById("acceptCookies")
- ];
- controls.forEach(function(control) {
- ok(control, "the micro-management controls should exist");
- });
-
- let thirdPartyCookieMenu = win.document.getElementById("acceptThirdPartyMenu");
- ok(thirdPartyCookieMenu, "the third-party cookie control should exist");
-
- function expect_checked(checked) {
- controls.forEach(function(control) {
- is(control.checked, checked,
- control.getAttribute("id") + " should " + (checked ? "not " : "") + "be checked");
- });
-
- is(thirdPartyCookieMenu.value == "always" || thirdPartyCookieMenu.value == "visited", checked, "third-party cookies should " + (checked ? "not " : "") + "be limited");
- }
-
- // controls should be checked in remember mode
- historymode.value = "remember";
- controlChanged(historymode);
- expect_checked(true);
-
- // even if they're unchecked in custom mode
- historymode.value = "custom";
- controlChanged(historymode);
- thirdPartyCookieMenu.value = "never";
- controlChanged(thirdPartyCookieMenu);
- controls.forEach(function(control) {
- control.checked = false;
- controlChanged(control);
- });
- expect_checked(false);
- historymode.value = "remember";
- controlChanged(historymode);
- expect_checked(true);
-}
-
-function test_historymode_retention(mode, expect) {
- return function test_historymode_retention_fn(win) {
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
-
- if ((historymode.value == "remember" && mode == "dontremember") ||
- (historymode.value == "dontremember" && mode == "remember") ||
- (historymode.value == "custom" && mode == "dontremember")) {
- return;
- }
-
- if (expect !== undefined) {
- is(historymode.value, expect,
- "history mode is expected to remain " + expect);
- }
-
- historymode.value = mode;
- controlChanged(historymode);
- };
-}
-
-function test_custom_retention(controlToChange, expect, valueIncrement) {
- return function test_custom_retention_fn(win) {
- let historymode = win.document.getElementById("historyMode");
- ok(historymode, "history mode menulist should exist");
-
- if (expect !== undefined) {
- is(historymode.value, expect,
- "history mode is expected to remain " + expect);
- }
-
- historymode.value = "custom";
- controlChanged(historymode);
-
- controlToChange = win.document.getElementById(controlToChange);
- ok(controlToChange, "the control to change should exist");
- switch (controlToChange.localName) {
- case "checkbox":
- controlToChange.checked = !controlToChange.checked;
- break;
- case "textbox":
- controlToChange.value = parseInt(controlToChange.value) + valueIncrement;
- break;
- case "menulist":
- controlToChange.value = valueIncrement;
- break;
- }
- controlChanged(controlToChange);
- };
-}
-
-function test_locbar_suggestion_retention(suggestion, autocomplete) {
- return function(win) {
- let elem = win.document.getElementById(suggestion + "Suggestion");
- ok(elem, "Suggest " + suggestion + " checkbox should exist.");
- elem.click();
-
- is(Services.prefs.getBoolPref("browser.urlbar.autocomplete.enabled"), autocomplete,
- "browser.urlbar.autocomplete.enabled pref should be " + autocomplete);
- };
-}
-
-const gPrefCache = new Map();
-
-function cache_preferences(win) {
- let prefs = win.document.querySelectorAll("#privacyPreferences > preference");
- for (let pref of prefs)
- gPrefCache.set(pref.name, pref.value);
-}
-
-function reset_preferences(win) {
- let prefs = win.document.querySelectorAll("#privacyPreferences > preference");
- for (let pref of prefs)
- pref.value = gPrefCache.get(pref.name);
-}
-
-function run_test_subset(subset) {
- info("subset: " + Array.from(subset, x => x.name).join(",") + "\n");
- SpecialPowers.pushPrefEnv({"set": [["browser.preferences.instantApply", true]]});
-
- let tests = [cache_preferences, ...subset, reset_preferences];
- for (let test of tests) {
- add_task(runTestOnPrivacyPrefPane.bind(undefined, test));
- }
-}
diff --git a/browser/components/preferences/in-content/tests/subdialog.xul b/browser/components/preferences/in-content/tests/subdialog.xul
deleted file mode 100644
index 48d297b73..000000000
--- a/browser/components/preferences/in-content/tests/subdialog.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<dialog id="subDialog"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Sample sub-dialog" style="width: 32em; height: 5em;"
- onload="document.getElementById('textbox').focus();"
- ondialogaccept="acceptSubdialog();">
- <script>
- function acceptSubdialog() {
- window.arguments[0].acceptCount++;
- }
- </script>
-
- <description id="desc">A sample sub-dialog for testing</description>
-
- <textbox id="textbox" value="Default text" />
-
- <separator class="thin"/>
-
- <button oncommand="close();" icon="close" label="Close" />
-
-</dialog>
diff --git a/browser/components/preferences/in-content/tests/subdialog2.xul b/browser/components/preferences/in-content/tests/subdialog2.xul
deleted file mode 100644
index 89803c250..000000000
--- a/browser/components/preferences/in-content/tests/subdialog2.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<dialog id="subDialog"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Sample sub-dialog #2" style="width: 32em; height: 5em;"
- onload="document.getElementById('textbox').focus();"
- ondialogaccept="acceptSubdialog();">
- <script>
- function acceptSubdialog() {
- window.arguments[0].acceptCount++;
- }
- </script>
-
- <description id="desc">A sample sub-dialog for testing</description>
-
- <textbox id="textbox" value="Default text" />
-
- <separator class="thin"/>
-
- <button oncommand="close();" icon="close" label="Close" />
-
-</dialog>
diff --git a/browser/components/preferences/moz.build b/browser/components/preferences/moz.build
index 5415399a0..adee51e3b 100644
--- a/browser/components/preferences/moz.build
+++ b/browser/components/preferences/moz.build
@@ -6,10 +6,6 @@
DIRS += ['in-content']
-BROWSER_CHROME_MANIFESTS += [
- 'in-content/tests/browser.ini',
-]
-
for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
DEFINES[var] = CONFIG[var]
@@ -17,6 +13,3 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn']
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Preferences')
diff --git a/browser/components/privatebrowsing/moz.build b/browser/components/privatebrowsing/moz.build
index 486737a7f..aac3a838c 100644
--- a/browser/components/privatebrowsing/moz.build
+++ b/browser/components/privatebrowsing/moz.build
@@ -4,11 +4,4 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser/browser.ini',
-]
-
JAR_MANIFESTS += ['jar.mn']
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Private Browsing')
diff --git a/browser/components/privatebrowsing/test/browser/.eslintrc.js b/browser/components/privatebrowsing/test/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/privatebrowsing/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/privatebrowsing/test/browser/browser.ini b/browser/components/privatebrowsing/test/browser/browser.ini
deleted file mode 100644
index 5efca4c0e..000000000
--- a/browser/components/privatebrowsing/test/browser/browser.ini
+++ /dev/null
@@ -1,54 +0,0 @@
-[DEFAULT]
-tags = openwindow
-support-files =
- browser_privatebrowsing_concurrent_page.html
- browser_privatebrowsing_geoprompt_page.html
- browser_privatebrowsing_localStorage_before_after_page.html
- browser_privatebrowsing_localStorage_before_after_page2.html
- browser_privatebrowsing_localStorage_page1.html
- browser_privatebrowsing_localStorage_page2.html
- browser_privatebrowsing_placesTitleNoUpdate.html
- browser_privatebrowsing_protocolhandler_page.html
- browser_privatebrowsing_windowtitle_page.html
- head.js
- popup.html
- title.sjs
- empty_file.html
- file_favicon.html
- file_favicon.png
- file_favicon.png^headers^
-
-[browser_privatebrowsing_DownloadLastDirWithCPS.js]
-[browser_privatebrowsing_about.js]
-tags = trackingprotection
-[browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js]
-[browser_privatebrowsing_aboutSessionRestore.js]
-[browser_privatebrowsing_cache.js]
-[browser_privatebrowsing_certexceptionsui.js]
-[browser_privatebrowsing_concurrent.js]
-[browser_privatebrowsing_context_and_chromeFlags.js]
-[browser_privatebrowsing_crh.js]
-[browser_privatebrowsing_downloadLastDir.js]
-[browser_privatebrowsing_downloadLastDir_c.js]
-[browser_privatebrowsing_downloadLastDir_toggle.js]
-[browser_privatebrowsing_favicon.js]
-[browser_privatebrowsing_geoprompt.js]
-[browser_privatebrowsing_lastpbcontextexited.js]
-[browser_privatebrowsing_localStorage.js]
-[browser_privatebrowsing_localStorage_before_after.js]
-[browser_privatebrowsing_noSessionRestoreMenuOption.js]
-[browser_privatebrowsing_nonbrowser.js]
-[browser_privatebrowsing_opendir.js]
-[browser_privatebrowsing_placesTitleNoUpdate.js]
-[browser_privatebrowsing_placestitle.js]
-[browser_privatebrowsing_popupblocker.js]
-[browser_privatebrowsing_protocolhandler.js]
-[browser_privatebrowsing_sidebar.js]
-[browser_privatebrowsing_theming.js]
-[browser_privatebrowsing_ui.js]
-[browser_privatebrowsing_urlbarfocus.js]
-[browser_privatebrowsing_windowtitle.js]
-[browser_privatebrowsing_zoom.js]
-[browser_privatebrowsing_zoomrestore.js]
-[browser_privatebrowsing_newtab_from_popup.js]
-[browser_privatebrowsing_blobUrl.js]
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_DownloadLastDirWithCPS.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_DownloadLastDirWithCPS.js
deleted file mode 100644
index bcd19b192..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_DownloadLastDirWithCPS.js
+++ /dev/null
@@ -1,282 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var gTests;
-function test() {
- waitForExplicitFinish();
- requestLongerTimeout(2);
- gTests = runTest();
- gTests.next();
-}
-
-/*
- * ================
- * Helper functions
- * ================
- */
-
-function moveAlong(aResult) {
- try {
- gTests.send(aResult);
- } catch (x if x instanceof StopIteration) {
- finish();
- }
-}
-
-function createWindow(aOptions) {
- whenNewWindowLoaded(aOptions, function(win) {
- moveAlong(win);
- });
-}
-
-function getFile(downloadLastDir, aURI) {
- downloadLastDir.getFileAsync(aURI, function(result) {
- moveAlong(result);
- });
-}
-
-function setFile(downloadLastDir, aURI, aValue) {
- downloadLastDir.setFile(aURI, aValue);
- executeSoon(moveAlong);
-}
-
-function clearHistoryAndWait() {
- clearHistory();
- executeSoon(() => executeSoon(moveAlong));
-}
-
-/*
- * ===================
- * Function with tests
- * ===================
- */
-
-function runTest() {
- let FileUtils =
- Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
- let DownloadLastDir =
- Cu.import("resource://gre/modules/DownloadLastDir.jsm", {}).DownloadLastDir;
-
- let tmpDir = FileUtils.getDir("TmpD", [], true);
- let dir1 = newDirectory();
- let dir2 = newDirectory();
- let dir3 = newDirectory();
-
- let uri1 = Services.io.newURI("http://test1.com/", null, null);
- let uri2 = Services.io.newURI("http://test2.com/", null, null);
- let uri3 = Services.io.newURI("http://test3.com/", null, null);
- let uri4 = Services.io.newURI("http://test4.com/", null, null);
-
- // cleanup functions registration
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.download.lastDir.savePerSite");
- Services.prefs.clearUserPref("browser.download.lastDir");
- [dir1, dir2, dir3].forEach(dir => dir.remove(true));
- win.close();
- pbWin.close();
- });
-
- function checkDownloadLastDir(gDownloadLastDir, aLastDir) {
- is(gDownloadLastDir.file.path, aLastDir.path,
- "gDownloadLastDir should point to the expected last directory");
- getFile(gDownloadLastDir, uri1);
- }
-
- function checkDownloadLastDirNull(gDownloadLastDir) {
- is(gDownloadLastDir.file, null, "gDownloadLastDir should be null");
- getFile(gDownloadLastDir, uri1);
- }
-
- /*
- * ================================
- * Create a regular and a PB window
- * ================================
- */
-
- let win = yield createWindow({private: false});
- let pbWin = yield createWindow({private: true});
-
- let downloadLastDir = new DownloadLastDir(win);
- let pbDownloadLastDir = new DownloadLastDir(pbWin);
-
- /*
- * ==================
- * Beginning of tests
- * ==================
- */
-
- is(typeof downloadLastDir, "object",
- "downloadLastDir should be a valid object");
- is(downloadLastDir.file, null,
- "LastDir pref should be null to start with");
-
- // set up last dir
- yield setFile(downloadLastDir, null, tmpDir);
- is(downloadLastDir.file.path, tmpDir.path,
- "LastDir should point to the tmpDir");
- isnot(downloadLastDir.file, tmpDir,
- "downloadLastDir.file should not be pointing to tmpDir");
-
- // set uri1 to dir1, all should now return dir1
- // also check that a new object is returned
- yield setFile(downloadLastDir, uri1, dir1);
- is(downloadLastDir.file.path, dir1.path,
- "downloadLastDir should return dir1");
- isnot(downloadLastDir.file, dir1,
- "downloadLastDir.file should not return dir1");
- is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
- "uri1 should return dir1"); // set in CPS
- isnot((yield getFile(downloadLastDir, uri1)), dir1,
- "getFile on uri1 should not return dir1");
- is((yield getFile(downloadLastDir, uri2)).path, dir1.path,
- "uri2 should return dir1"); // fallback
- isnot((yield getFile(downloadLastDir, uri2)), dir1,
- "getFile on uri2 should not return dir1");
- is((yield getFile(downloadLastDir, uri3)).path, dir1.path,
- "uri3 should return dir1"); // fallback
- isnot((yield getFile(downloadLastDir, uri3)), dir1,
- "getFile on uri3 should not return dir1");
- is((yield getFile(downloadLastDir, uri4)).path, dir1.path,
- "uri4 should return dir1"); // fallback
- isnot((yield getFile(downloadLastDir, uri4)), dir1,
- "getFile on uri4 should not return dir1");
-
- // set uri2 to dir2, all except uri1 should now return dir2
- yield setFile(downloadLastDir, uri2, dir2);
- is(downloadLastDir.file.path, dir2.path,
- "downloadLastDir should point to dir2");
- is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
- "uri1 should return dir1"); // set in CPS
- is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
- "uri2 should return dir2"); // set in CPS
- is((yield getFile(downloadLastDir, uri3)).path, dir2.path,
- "uri3 should return dir2"); // fallback
- is((yield getFile(downloadLastDir, uri4)).path, dir2.path,
- "uri4 should return dir2"); // fallback
-
- // set uri3 to dir3, all except uri1 and uri2 should now return dir3
- yield setFile(downloadLastDir, uri3, dir3);
- is(downloadLastDir.file.path, dir3.path,
- "downloadLastDir should point to dir3");
- is((yield getFile(downloadLastDir, uri1)).path, dir1.path,
- "uri1 should return dir1"); // set in CPS
- is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
- "uri2 should return dir2"); // set in CPS
- is((yield getFile(downloadLastDir, uri3)).path, dir3.path,
- "uri3 should return dir3"); // set in CPS
- is((yield getFile(downloadLastDir, uri4)).path, dir3.path,
- "uri4 should return dir4"); // fallback
-
- // set uri1 to dir2, all except uri3 should now return dir2
- yield setFile(downloadLastDir, uri1, dir2);
- is(downloadLastDir.file.path, dir2.path,
- "downloadLastDir should point to dir2");
- is((yield getFile(downloadLastDir, uri1)).path, dir2.path,
- "uri1 should return dir2"); // set in CPS
- is((yield getFile(downloadLastDir, uri2)).path, dir2.path,
- "uri2 should return dir2"); // set in CPS
- is((yield getFile(downloadLastDir, uri3)).path, dir3.path,
- "uri3 should return dir3"); // set in CPS
- is((yield getFile(downloadLastDir, uri4)).path, dir2.path,
- "uri4 should return dir2"); // fallback
-
- yield clearHistoryAndWait();
-
- // check clearHistory removes all data
- is(downloadLastDir.file, null, "clearHistory removes all data");
- //is(Services.contentPrefs.hasPref(uri1, "browser.download.lastDir", null),
- // false, "LastDir preference should be absent");
- is((yield getFile(downloadLastDir, uri1)), null, "uri1 should point to null");
- is((yield getFile(downloadLastDir, uri2)), null, "uri2 should point to null");
- is((yield getFile(downloadLastDir, uri3)), null, "uri3 should point to null");
- is((yield getFile(downloadLastDir, uri4)), null, "uri4 should point to null");
-
- yield setFile(downloadLastDir, null, tmpDir);
-
- // check data set outside PB mode is remembered
- is((yield checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
- is((yield checkDownloadLastDir(downloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
- yield clearHistoryAndWait();
-
- yield setFile(downloadLastDir, uri1, dir1);
-
- // check data set using CPS outside PB mode is remembered
- is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
- is((yield checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
- yield clearHistoryAndWait();
-
- // check data set inside PB mode is forgotten
- yield setFile(pbDownloadLastDir, null, tmpDir);
-
- is((yield checkDownloadLastDir(pbDownloadLastDir, tmpDir)).path, tmpDir.path, "uri1 should return the expected last directory");
- is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
-
- yield clearHistoryAndWait();
-
- // check data set using CPS inside PB mode is forgotten
- yield setFile(pbDownloadLastDir, uri1, dir1);
-
- is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
- is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
-
- // check data set outside PB mode but changed inside is remembered correctly
- yield setFile(downloadLastDir, uri1, dir1);
- yield setFile(pbDownloadLastDir, uri1, dir2);
- is((yield checkDownloadLastDir(pbDownloadLastDir, dir2)).path, dir2.path, "uri1 should return the expected last directory");
- is((yield checkDownloadLastDir(downloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
-
- /*
- * ====================
- * Create new PB window
- * ====================
- */
-
- // check that the last dir store got cleared in a new PB window
- pbWin.close();
- // And give it time to close
- executeSoon(moveAlong);
- yield;
- pbWin = yield createWindow({private: true});
- pbDownloadLastDir = new DownloadLastDir(pbWin);
-
- is((yield checkDownloadLastDir(pbDownloadLastDir, dir1)).path, dir1.path, "uri1 should return the expected last directory");
-
- yield clearHistoryAndWait();
-
- // check clearHistory inside PB mode clears data outside PB mode
- yield setFile(pbDownloadLastDir, uri1, dir2);
-
- yield clearHistoryAndWait();
-
- is((yield checkDownloadLastDirNull(downloadLastDir)), null, "uri1 should return the expected last directory");
- is((yield checkDownloadLastDirNull(pbDownloadLastDir)), null, "uri1 should return the expected last directory");
-
- // check that disabling CPS works
- Services.prefs.setBoolPref("browser.download.lastDir.savePerSite", false);
-
- yield setFile(downloadLastDir, uri1, dir1);
- is(downloadLastDir.file.path, dir1.path, "LastDir should be set to dir1");
- is((yield getFile(downloadLastDir, uri1)).path, dir1.path, "uri1 should return dir1");
- is((yield getFile(downloadLastDir, uri2)).path, dir1.path, "uri2 should return dir1");
- is((yield getFile(downloadLastDir, uri3)).path, dir1.path, "uri3 should return dir1");
- is((yield getFile(downloadLastDir, uri4)).path, dir1.path, "uri4 should return dir1");
-
- downloadLastDir.setFile(uri2, dir2);
- is(downloadLastDir.file.path, dir2.path, "LastDir should be set to dir2");
- is((yield getFile(downloadLastDir, uri1)).path, dir2.path, "uri1 should return dir2");
- is((yield getFile(downloadLastDir, uri2)).path, dir2.path, "uri2 should return dir2");
- is((yield getFile(downloadLastDir, uri3)).path, dir2.path, "uri3 should return dir2");
- is((yield getFile(downloadLastDir, uri4)).path, dir2.path, "uri4 should return dir2");
-
- Services.prefs.clearUserPref("browser.download.lastDir.savePerSite");
-
- // check that passing null to setFile clears the stored value
- yield setFile(downloadLastDir, uri3, dir3);
- is((yield getFile(downloadLastDir, uri3)).path, dir3.path, "LastDir should be set to dir3");
- yield setFile(downloadLastDir, uri3, null);
- is((yield getFile(downloadLastDir, uri3)), null, "uri3 should return null");
-
- yield clearHistoryAndWait();
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js
deleted file mode 100644
index e00f3f67a..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Opens a new private window and loads "about:privatebrowsing" there.
- */
-function* openAboutPrivateBrowsing() {
- let win = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- let tab = win.gBrowser.selectedBrowser;
- tab.loadURI("about:privatebrowsing");
- yield BrowserTestUtils.browserLoaded(tab);
- return { win, tab };
-}
-
-/**
- * Clicks the given link and checks this opens a new tab with the given URI.
- */
-function* testLinkOpensTab({ win, tab, elementId, expectedUrl }) {
- let newTabPromise = BrowserTestUtils.waitForNewTab(win.gBrowser, expectedUrl);
- yield ContentTask.spawn(tab, { elementId }, function* ({ elementId }) {
- content.document.getElementById(elementId).click();
- });
- let newTab = yield newTabPromise;
- ok(true, `Clicking ${elementId} opened ${expectedUrl} in a new tab.`);
- yield BrowserTestUtils.removeTab(newTab);
-}
-
-/**
- * Clicks the given link and checks this opens the given URI in the same tab.
- *
- * This function does not return to the previous page.
- */
-function* testLinkOpensUrl({ win, tab, elementId, expectedUrl }) {
- let loadedPromise = BrowserTestUtils.browserLoaded(tab);
- yield ContentTask.spawn(tab, { elementId }, function* ({ elementId }) {
- content.document.getElementById(elementId).click();
- });
- yield loadedPromise;
- is(tab.currentURI.spec, expectedUrl,
- `Clicking ${elementId} opened ${expectedUrl} in the same tab.`);
-}
-
-/**
- * Tests the links in "about:privatebrowsing".
- */
-add_task(function* test_links() {
- // Use full version and change the remote URLs to prevent network access.
- Services.prefs.setCharPref("app.support.baseURL", "https://example.com/");
- Services.prefs.setCharPref("privacy.trackingprotection.introURL",
- "https://example.com/tour");
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("privacy.trackingprotection.introURL");
- Services.prefs.clearUserPref("app.support.baseURL");
- });
-
- let { win, tab } = yield openAboutPrivateBrowsing();
-
- yield testLinkOpensTab({ win, tab,
- elementId: "learnMore",
- expectedUrl: "https://example.com/private-browsing",
- });
-
- yield testLinkOpensUrl({ win, tab,
- elementId: "startTour",
- expectedUrl: "https://example.com/tour",
- });
-
- yield BrowserTestUtils.closeWindow(win);
-});
-
-/**
- * Tests the action to disable and re-enable Tracking Protection in
- * "about:privatebrowsing".
- */
-add_task(function* test_toggleTrackingProtection() {
- // Use tour version but disable Tracking Protection.
- Services.prefs.setBoolPref("privacy.trackingprotection.pbmode.enabled",
- true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("privacy.trackingprotection.pbmode.enabled");
- });
-
- let { win, tab } = yield openAboutPrivateBrowsing();
-
- // Set up the observer for the preference change before triggering the action.
- let prefBranch =
- Services.prefs.getBranch("privacy.trackingprotection.pbmode.");
- let waitForPrefChanged = () => new Promise(resolve => {
- let prefObserver = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
- observe: function () {
- prefBranch.removeObserver("enabled", prefObserver);
- resolve();
- },
- };
- prefBranch.addObserver("enabled", prefObserver, false);
- });
-
- let promisePrefChanged = waitForPrefChanged();
- yield ContentTask.spawn(tab, {}, function* () {
- content.document.getElementById("tpButton").click();
- });
- yield promisePrefChanged;
- ok(!prefBranch.getBoolPref("enabled"), "Tracking Protection is disabled.");
-
- promisePrefChanged = waitForPrefChanged();
- yield ContentTask.spawn(tab, {}, function* () {
- content.document.getElementById("tpButton").click();
- });
- yield promisePrefChanged;
- ok(prefBranch.getBoolPref("enabled"), "Tracking Protection is enabled.");
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js
deleted file mode 100644
index 6f52f7719..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test checks that the Session Restore "Restore Previous Session"
-// button on about:home is disabled in private mode
-add_task(function* test_no_sessionrestore_button() {
- // Opening, then closing, a private window shouldn't create session data.
- (yield BrowserTestUtils.openNewBrowserWindow({private: true})).close();
-
- let win = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let tab = win.gBrowser.addTab("about:home");
- let browser = tab.linkedBrowser;
-
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- let button = content.document.getElementById("restorePreviousSession");
- Assert.equal(content.getComputedStyle(button).display, "none",
- "The Session Restore about:home button should be disabled");
- });
-
- win.close();
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutSessionRestore.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutSessionRestore.js
deleted file mode 100644
index 5f6a91836..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_aboutSessionRestore.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test checks that the session restore button from about:sessionrestore
-// is disabled in private mode
-add_task(function* testNoSessionRestoreButton() {
- // Opening, then closing, a private window shouldn't create session data.
- (yield BrowserTestUtils.openNewBrowserWindow({private: true})).close();
-
- let win = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let tab = win.gBrowser.addTab("about:sessionrestore");
- let browser = tab.linkedBrowser;
-
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield ContentTask.spawn(browser, null, function* () {
- Assert.ok(content.document.getElementById("errorTryAgain").disabled,
- "The Restore about:sessionrestore button should be disabled");
- });
-
- win.close();
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_blobUrl.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_blobUrl.js
deleted file mode 100644
index 2ceb1032b..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_blobUrl.js
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-// Here we want to test that blob URLs are not available between private and
-// non-private browsing.
-
-const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
- + "privatebrowsing/test/browser/empty_file.html";
-
-add_task(function* test() {
- info("Creating a normal window...");
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let tab = win.gBrowser.selectedBrowser;
- tab.loadURI(BASE_URI);
- yield BrowserTestUtils.browserLoaded(tab);
-
- let blobURL;
-
- info("Creating a blob URL...");
- yield ContentTask.spawn(tab, null, function() {
- return Promise.resolve(content.window.URL.createObjectURL(new content.window.Blob([123])));
- }).then(newURL => { blobURL = newURL });
-
- info("Blob URL: " + blobURL);
-
- info("Creating a private window...");
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- let privateTab = privateWin.gBrowser.selectedBrowser;
- privateTab.loadURI(BASE_URI);
- yield BrowserTestUtils.browserLoaded(privateTab);
-
- yield ContentTask.spawn(privateTab, blobURL, function(url) {
- return new Promise(resolve => {
- var xhr = new content.window.XMLHttpRequest();
- xhr.onerror = function() { resolve("SendErrored"); }
- xhr.onload = function() { resolve("SendLoaded"); }
- xhr.open("GET", url);
- xhr.send();
- });
- }).then(status => {
- is(status, "SendErrored", "Using a blob URI from one user context id in another should not work");
- });
-
- yield BrowserTestUtils.closeWindow(win);
- yield BrowserTestUtils.closeWindow(privateWin);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js
deleted file mode 100644
index 4990f6d3b..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Check about:cache after private browsing
-// This test covers MozTrap test 6047
-// bug 880621
-
-var {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", null);
-
-var tmp = {};
-
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://browser/content/sanitize.js", tmp);
-
-var Sanitizer = tmp.Sanitizer;
-
-function test() {
-
- waitForExplicitFinish();
-
- sanitizeCache();
-
- let nrEntriesR1 = getStorageEntryCount("regular", function(nrEntriesR1) {
- is(nrEntriesR1, 0, "Disk cache reports 0KB and has no entries");
-
- get_cache_for_private_window();
- });
-}
-
-function cleanup() {
- let prefs = Services.prefs.getBranch("privacy.cpd.");
-
- prefs.clearUserPref("history");
- prefs.clearUserPref("downloads");
- prefs.clearUserPref("cache");
- prefs.clearUserPref("cookies");
- prefs.clearUserPref("formdata");
- prefs.clearUserPref("offlineApps");
- prefs.clearUserPref("passwords");
- prefs.clearUserPref("sessions");
- prefs.clearUserPref("siteSettings");
-}
-
-function sanitizeCache() {
-
- let s = new Sanitizer();
- s.ignoreTimespan = false;
- s.prefDomain = "privacy.cpd.";
-
- let prefs = gPrefService.getBranch(s.prefDomain);
- prefs.setBoolPref("history", false);
- prefs.setBoolPref("downloads", false);
- prefs.setBoolPref("cache", true);
- prefs.setBoolPref("cookies", false);
- prefs.setBoolPref("formdata", false);
- prefs.setBoolPref("offlineApps", false);
- prefs.setBoolPref("passwords", false);
- prefs.setBoolPref("sessions", false);
- prefs.setBoolPref("siteSettings", false);
-
- s.sanitize();
-}
-
-function get_cache_service() {
- return Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Components.interfaces.nsICacheStorageService);
-}
-
-function getStorageEntryCount(device, goon) {
- var cs = get_cache_service();
-
- var storage;
- switch (device) {
- case "private":
- storage = cs.diskCacheStorage(LoadContextInfo.private, false);
- break;
- case "regular":
- storage = cs.diskCacheStorage(LoadContextInfo.default, false);
- break;
- default:
- throw "Unknown device " + device + " at getStorageEntryCount";
- }
-
- var visitor = {
- entryCount: 0,
- onCacheStorageInfo: function (aEntryCount, aConsumption) {
- },
- onCacheEntryInfo: function(uri)
- {
- var urispec = uri.asciiSpec;
- info(device + ":" + urispec + "\n");
- if (urispec.match(/^http:\/\/example.org\//))
- ++this.entryCount;
- },
- onCacheEntryVisitCompleted: function()
- {
- goon(this.entryCount);
- }
- };
-
- storage.asyncVisitStorage(visitor, true);
-}
-
-function get_cache_for_private_window () {
- let win = whenNewWindowLoaded({private: true}, function() {
-
- 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);
-
- 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);
- });
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
deleted file mode 100644
index 519f43475..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that certificate exceptions UI behaves correctly
-// in private browsing windows, based on whether it's opened from the prefs
-// window or from the SSL error page (see bug 461627).
-
-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, false);
- doTest();
- }, false);
-
- // Test the certificate exceptions dialog
- function doTest() {
- let params = {
- exceptionAdded : false,
- location: INVALID_CERT_LOCATION,
- prefetchCert: true,
- };
- function testCheckbox() {
- win.removeEventListener("load", testCheckbox, false);
- Services.obs.addObserver(function onCertUI(aSubject, aTopic, aData) {
- Services.obs.removeObserver(onCertUI, "cert-exception-ui-ready");
- ok(win.gCert, "The certificate information should be available now");
-
- let checkbox = win.document.getElementById("permanent");
- ok(checkbox.hasAttribute("disabled"),
- "the permanent checkbox should be disabled when handling the private browsing mode");
- ok(!checkbox.hasAttribute("checked"),
- "the permanent checkbox should not be checked when handling the private browsing mode");
- win.close();
- cleanup();
- }, "cert-exception-ui-ready", false);
- }
- var win = pbWin.openDialog(EXCEPTIONS_DLG_URL, "", EXCEPTIONS_DLG_FEATURES, params);
- win.addEventListener("load", testCheckbox, false);
- }
-
- function cleanup() {
- // close the private browsing window
- pbWin.close();
- finish();
- }
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
deleted file mode 100644
index b73bbf219..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test opening two tabs that share a localStorage, but keep one in private mode.
-// Ensure that values from one don't leak into the other, and that values from
-// earlier private storage sessions aren't visible later.
-
-// Step 1: create new tab, load a page that sets test=value in non-private storage
-// Step 2: create a new tab, load a page that sets test2=value2 in private storage
-// Step 3: load a page in the tab from step 1 that checks the value of test2 is value2 and the total count in non-private storage is 1
-// Step 4: load a page in the tab from step 2 that checks the value of test is value and the total count in private storage is 1
-
-add_task(function* setup() {
- yield SpecialPowers.pushPrefEnv({
- set: [["dom.ipc.processCount", 1]]
- });
-});
-
-add_task(function test() {
- let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html';
-
- function getElts(browser) {
- return browser.contentTitle.split('|');
- };
-
- // Step 1
- let non_private_browser = gBrowser.selectedBrowser;
- non_private_browser.loadURI(prefix + '?action=set&name=test&value=value&initial=true');
- yield BrowserTestUtils.browserLoaded(non_private_browser);
-
-
- // Step 2
- let private_window = yield BrowserTestUtils.openNewBrowserWindow({ private : true });
- let private_browser = private_window.getBrowser().selectedBrowser;
- private_browser.loadURI(prefix + '?action=set&name=test2&value=value2');
- yield BrowserTestUtils.browserLoaded(private_browser);
-
-
- // Step 3
- non_private_browser.loadURI(prefix + '?action=get&name=test2');
- yield BrowserTestUtils.browserLoaded(non_private_browser);
- let elts = yield getElts(non_private_browser);
- isnot(elts[0], 'value2', "public window shouldn't see private storage");
- is(elts[1], '1', "public window should only see public items");
-
-
- // Step 4
- private_browser.loadURI(prefix + '?action=get&name=test');
- yield BrowserTestUtils.browserLoaded(private_browser);
- elts = yield getElts(private_browser);
- isnot(elts[0], 'value', "private window shouldn't see public storage");
- is(elts[1], '1', "private window should only see private items");
-
-
- // Reopen the private window again, without privateBrowsing, which should clear the
- // the private storage.
- private_window.close();
- private_window = yield BrowserTestUtils.openNewBrowserWindow({ private : false });
- private_browser = null;
- yield new Promise(resolve => Cu.schedulePreciseGC(resolve));
- private_browser = private_window.getBrowser().selectedBrowser;
-
- private_browser.loadURI(prefix + '?action=get&name=test2');
- yield BrowserTestUtils.browserLoaded(private_browser);
- elts = yield getElts(private_browser);
- isnot(elts[0], 'value2', "public window shouldn't see cleared private storage");
- is(elts[1], '1', "public window should only see public items");
-
-
- // Making it private again should clear the storage and it shouldn't
- // be able to see the old private storage as well.
- private_window.close();
- private_window = yield BrowserTestUtils.openNewBrowserWindow({ private : true });
- private_browser = null;
- yield new Promise(resolve => Cu.schedulePreciseGC(resolve));
- private_browser = private_window.getBrowser().selectedBrowser;
-
- private_browser.loadURI(prefix + '?action=set&name=test3&value=value3');
- yield BrowserTestUtils.browserLoaded(private_browser);
- elts = yield getElts(private_browser);
- is(elts[1], '1', "private window should only see new private items");
-
- // Cleanup.
- non_private_browser.loadURI(prefix + '?final=true');
- yield BrowserTestUtils.browserLoaded(non_private_browser);
- private_window.close();
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html
deleted file mode 100644
index db35b114d..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script type="text/javascript">
- var oGetVars = {};
-
- if (window.location.search.length > 1) {
- for (var aItKey, nKeyId = 0, aCouples = window.location.search.substr(1).split("&");
- nKeyId < aCouples.length;
- nKeyId++) {
- aItKey = aCouples[nKeyId].split("=");
- oGetVars[unescape(aItKey[0])] = aItKey.length > 1 ? unescape(aItKey[1]) : "";
- }
- }
-
- if (oGetVars.initial == 'true') {
- localStorage.clear();
- }
-
- if (oGetVars.action == 'set') {
- localStorage.setItem(oGetVars.name, oGetVars.value);
- document.title = localStorage.getItem(oGetVars.name) + "|" + localStorage.length;
- } else if (oGetVars.action == 'get') {
- document.title = localStorage.getItem(oGetVars.name) + "|" + localStorage.length;
- }
-
- if (oGetVars.final == 'true') {
- localStorage.clear();
- }
-</script>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_context_and_chromeFlags.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_context_and_chromeFlags.js
deleted file mode 100644
index 30f7ee025..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_context_and_chromeFlags.js
+++ /dev/null
@@ -1,60 +0,0 @@
-"use strict";
-
-/**
- * Given some window in the parent process, ensure that
- * the nsIXULWindow has the CHROME_PRIVATE_WINDOW chromeFlag,
- * and that the usePrivateBrowsing property is set to true on
- * both the window's nsILoadContext, as well as on the initial
- * browser's content docShell nsILoadContext.
- *
- * @param win (nsIDOMWindow)
- * An nsIDOMWindow in the parent process.
- * @return Promise
- */
-function assertWindowIsPrivate(win) {
- let winDocShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDocShell);
- let chromeFlags = winDocShell.QueryInterface(Ci.nsIDocShellTreeItem)
- .treeOwner
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIXULWindow)
- .chromeFlags;
-
- if (!win.gBrowser.selectedBrowser.hasContentOpener) {
- Assert.ok(chromeFlags & Ci.nsIWebBrowserChrome.CHROME_PRIVATE_WINDOW,
- "Should have the private window chrome flag");
- }
-
- let loadContext = winDocShell.QueryInterface(Ci.nsILoadContext);
- Assert.ok(loadContext.usePrivateBrowsing,
- "The parent window should be using private browsing");
-
- return ContentTask.spawn(win.gBrowser.selectedBrowser, null, function*() {
- let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
- Assert.ok(loadContext.usePrivateBrowsing,
- "Content docShell should be using private browsing");
- });
-}
-
-/**
- * Tests that chromeFlags bits and the nsILoadContext.usePrivateBrowsing
- * attribute are properly set when opening a new private browsing
- * window.
- */
-add_task(function* test_context_and_chromeFlags() {
- let win = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- yield assertWindowIsPrivate(win);
-
- let browser = win.gBrowser.selectedBrowser;
-
- let newWinPromise = BrowserTestUtils.waitForNewWindow();
- yield ContentTask.spawn(browser, null, function*() {
- content.open("http://example.com", "_blank", "width=100,height=100");
- });
-
- let win2 = yield newWinPromise;
- yield assertWindowIsPrivate(win2);
-
- yield BrowserTestUtils.closeWindow(win2);
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js
deleted file mode 100644
index cd316d1fb..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the Clear Recent History menu item and command
-// is disabled inside the private browsing mode.
-
-add_task(function test() {
- function checkDisableOption(aPrivateMode, aWindow) {
- let crhCommand = aWindow.document.getElementById("Tools:Sanitize");
- ok(crhCommand, "The clear recent history command should exist");
-
- is(PrivateBrowsingUtils.isWindowPrivate(aWindow), aPrivateMode,
- "PrivateBrowsingUtils should report the correct per-window private browsing status");
- is(crhCommand.hasAttribute("disabled"), aPrivateMode,
- "Clear Recent History command should be disabled according to the private browsing mode");
- };
-
- let testURI = "http://mochi.test:8888/";
-
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let privateBrowser = privateWin.gBrowser.selectedBrowser;
- privateBrowser.loadURI(testURI);
- yield BrowserTestUtils.browserLoaded(privateBrowser);
-
- info("Test on private window");
- checkDisableOption(true, privateWin);
-
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let browser = win.gBrowser.selectedBrowser;
- browser.loadURI(testURI);
- yield BrowserTestUtils.browserLoaded(browser);
-
- info("Test on public window");
- checkDisableOption(false, win);
-
-
- // Cleanup
- yield BrowserTestUtils.closeWindow(privateWin);
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js
deleted file mode 100644
index 81b2943ee..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- let FileUtils =
- Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
- let DownloadLastDir =
- Cu.import("resource://gre/modules/DownloadLastDir.jsm", {}).DownloadLastDir;
- let MockFilePicker = SpecialPowers.MockFilePicker;
- let launcher = {
- source: Services.io.newURI("http://test1.com/file", null, null)
- };
-
- MockFilePicker.init(window);
- MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
-
- let prefs = Services.prefs.getBranch("browser.download.");
- let launcherDialog =
- Cc["@mozilla.org/helperapplauncherdialog;1"].
- getService(Ci.nsIHelperAppLauncherDialog);
- let tmpDir = FileUtils.getDir("TmpD", [], true);
- let dir1 = newDirectory();
- let dir2 = newDirectory();
- let dir3 = newDirectory();
- let file1 = newFileInDirectory(dir1);
- let file2 = newFileInDirectory(dir2);
- let file3 = newFileInDirectory(dir3);
-
- // cleanup functions registration
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.download.lastDir");
- [dir1, dir2, dir3].forEach(dir => dir.remove(true));
- MockFilePicker.cleanup();
- });
- prefs.setComplexValue("lastDir", Ci.nsIFile, tmpDir);
-
- function testOnWindow(aPrivate, aCallback) {
- whenNewWindowLoaded({private: aPrivate}, function(win) {
- let gDownloadLastDir = new DownloadLastDir(win);
- aCallback(win, gDownloadLastDir);
- gDownloadLastDir.cleanupPrivateFile();
- });
- }
-
- function testDownloadDir(aWin, gDownloadLastDir, aFile, aDisplayDir, aLastDir,
- aGlobalLastDir, aCallback) {
- // Check lastDir preference.
- is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aDisplayDir.path,
- "LastDir should be the expected display dir");
- // Check gDownloadLastDir value.
- is(gDownloadLastDir.file.path, aDisplayDir.path,
- "gDownloadLastDir should be the expected display dir");
-
- MockFilePicker.returnFiles = [aFile];
- MockFilePicker.displayDirectory = null;
-
- launcher.saveDestinationAvailable = function (file) {
- ok(!!file, "promptForSaveToFile correctly returned a file");
-
- // File picker should start with expected display dir.
- is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
- "File picker should start with browser.download.lastDir");
- // browser.download.lastDir should be modified on not private windows
- is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
- "LastDir should be the expected last dir");
- // gDownloadLastDir should be usable outside of private windows
- is(gDownloadLastDir.file.path, aGlobalLastDir.path,
- "gDownloadLastDir should be the expected global last dir");
-
- launcher.saveDestinationAvailable = null;
- aWin.close();
- aCallback();
- };
-
- launcherDialog.promptForSaveToFileAsync(launcher, aWin, null, null, null);
- }
-
- testOnWindow(false, function(win, downloadDir) {
- testDownloadDir(win, downloadDir, file1, tmpDir, dir1, dir1, function() {
- testOnWindow(true, function(win, downloadDir) {
- testDownloadDir(win, downloadDir, file2, dir1, dir1, dir2, function() {
- testOnWindow(false, function(win, downloadDir) {
- testDownloadDir(win, downloadDir, file3, dir1, dir3, dir3, finish);
- });
- });
- });
- });
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
deleted file mode 100644
index 5a04d1999..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_c.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- let FileUtils =
- Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
- let DownloadLastDir =
- Cu.import("resource://gre/modules/DownloadLastDir.jsm", {}).DownloadLastDir;
- let MockFilePicker = SpecialPowers.MockFilePicker;
-
- MockFilePicker.init(window);
- MockFilePicker.returnValue = Ci.nsIFilePicker.returnOK;
-
- let validateFileNameToRestore = validateFileName;
- let prefs = Services.prefs.getBranch("browser.download.");
- let tmpDir = FileUtils.getDir("TmpD", [], true);
- let dir1 = newDirectory();
- let dir2 = newDirectory();
- let dir3 = newDirectory();
- let file1 = newFileInDirectory(dir1);
- let file2 = newFileInDirectory(dir2);
- let file3 = newFileInDirectory(dir3);
-
- // cleanup function registration
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.download.lastDir");
- [dir1, dir2, dir3].forEach(dir => dir.remove(true));
- MockFilePicker.cleanup();
- validateFileName = validateFileNameToRestore;
- });
-
- // Overwrite validateFileName to validate everything
- validateFileName = foo => foo;
-
- let params = {
- fileInfo: new FileInfo("test.txt", "test.txt", "test", "txt", "http://mozilla.org/test.txt"),
- contentType: "text/plain",
- saveMode: SAVEMODE_FILEONLY,
- saveAsType: kSaveAsType_Complete,
- file: null
- };
-
- prefs.setComplexValue("lastDir", Ci.nsIFile, tmpDir);
-
- function testOnWindow(aPrivate, aCallback) {
- whenNewWindowLoaded({private: aPrivate}, function(win) {
- let gDownloadLastDir = new DownloadLastDir(win);
- aCallback(win, gDownloadLastDir);
- });
- }
-
- function testDownloadDir(aWin, gDownloadLastDir, aFile, aDisplayDir, aLastDir,
- aGlobalLastDir, aCallback) {
- // Check lastDir preference.
- is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aDisplayDir.path,
- "LastDir should be the expected display dir");
- // Check gDownloadLastDir value.
- is(gDownloadLastDir.file.path, aDisplayDir.path,
- "gDownloadLastDir should be the expected display dir");
-
- MockFilePicker.returnFiles = [aFile];
- MockFilePicker.displayDirectory = null;
- aWin.promiseTargetFile(params).then(function() {
- // File picker should start with expected display dir.
- is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
- "File picker should start with browser.download.lastDir");
- // browser.download.lastDir should be modified on not private windows
- is(prefs.getComplexValue("lastDir", Ci.nsIFile).path, aLastDir.path,
- "LastDir should be the expected last dir");
- // gDownloadLastDir should be usable outside of private windows
- is(gDownloadLastDir.file.path, aGlobalLastDir.path,
- "gDownloadLastDir should be the expected global last dir");
-
- gDownloadLastDir.cleanupPrivateFile();
- aWin.close();
- aCallback();
- }).then(null, function() { ok(false); });
- }
-
- testOnWindow(false, function(win, downloadDir) {
- testDownloadDir(win, downloadDir, file1, tmpDir, dir1, dir1, function() {
- testOnWindow(true, function(win, downloadDir) {
- testDownloadDir(win, downloadDir, file2, dir1, dir1, dir2, function() {
- testOnWindow(false, function(win, downloadDir) {
- testDownloadDir(win, downloadDir, file3, dir1, dir3, dir3, finish);
- });
- });
- });
- });
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_toggle.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_toggle.js
deleted file mode 100644
index b192c08f7..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadLastDir_toggle.js
+++ /dev/null
@@ -1,105 +0,0 @@
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/DownloadLastDir.jsm");
-
-/**
- * Tests how the browser remembers the last download folder
- * from download to download, with a particular emphasis
- * on how it behaves when private browsing windows open.
- */
-add_task(function* test_downloads_last_dir_toggle() {
- let tmpDir = FileUtils.getDir("TmpD", [], true);
- let dir1 = newDirectory();
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.download.lastDir");
- dir1.remove(true);
- });
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let gDownloadLastDir = new DownloadLastDir(win);
- is(typeof gDownloadLastDir, "object",
- "gDownloadLastDir should be a valid object");
- is(gDownloadLastDir.file, null,
- "gDownloadLastDir.file should be null to start with");
-
- gDownloadLastDir.file = tmpDir;
- is(gDownloadLastDir.file.path, tmpDir.path,
- "LastDir should point to the temporary directory");
- isnot(gDownloadLastDir.file, tmpDir,
- "gDownloadLastDir.file should not be pointing to the tmpDir");
-
- gDownloadLastDir.file = 1; // not an nsIFile
- is(gDownloadLastDir.file, null, "gDownloadLastDir.file should be null");
-
- gDownloadLastDir.file = tmpDir;
- clearHistory();
- is(gDownloadLastDir.file, null, "gDownloadLastDir.file should be null");
-
- gDownloadLastDir.file = tmpDir;
- yield BrowserTestUtils.closeWindow(win);
-
- info("Opening the first private window");
- yield testHelper({ private: true, expectedDir: tmpDir });
- info("Opening a non-private window");
- yield testHelper({ private: false, expectedDir: tmpDir });
- info("Opening a private window and setting download directory");
- yield testHelper({ private: true, setDir: dir1, expectedDir: dir1 });
- info("Opening a non-private window and checking download directory");
- yield testHelper({ private: false, expectedDir: tmpDir });
- info("Opening private window and clearing history");
- yield testHelper({ private: true, clearHistory: true, expectedDir: null });
- info("Opening a non-private window and checking download directory");
- yield testHelper({ private: true, expectedDir: null });
-});
-
-/**
- * Opens a new window and performs some test actions on it based
- * on the options object that have been passed in.
- *
- * @param options (Object)
- * An object with the following properties:
- *
- * clearHistory (bool, optional):
- * Whether or not to simulate clearing session history.
- * Defaults to false.
- *
- * setDir (nsIFile, optional):
- * An nsIFile for setting the last download directory.
- * If not set, the load download directory is not changed.
- *
- * expectedDir (nsIFile, expectedDir):
- * An nsIFile for what we expect the last download directory
- * should be. The nsIFile is not compared directly - only
- * paths are compared. If expectedDir is not set, then the
- * last download directory is expected to be null.
- *
- * @returns Promise
- */
-function testHelper(options) {
- return new Task.spawn(function() {
- let win = yield BrowserTestUtils.openNewBrowserWindow(options);
- let gDownloadLastDir = new DownloadLastDir(win);
-
- if (options.clearHistory) {
- clearHistory();
- }
-
- if (options.setDir) {
- gDownloadLastDir.file = options.setDir;
- }
-
- let expectedDir = options.expectedDir;
-
- if (expectedDir) {
- is(gDownloadLastDir.file.path, expectedDir.path,
- "gDownloadLastDir should point to the expected last directory");
- isnot(gDownloadLastDir.file, expectedDir,
- "gDownloadLastDir.file should not be pointing to the last directory");
- } else {
- is(gDownloadLastDir.file, null, "gDownloadLastDir should be null");
- }
-
- gDownloadLastDir.cleanupPrivateFile();
- yield BrowserTestUtils.closeWindow(win);
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_favicon.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_favicon.js
deleted file mode 100644
index 86f714082..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_favicon.js
+++ /dev/null
@@ -1,293 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test make sure that the favicon of the private browsing is isolated.
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-const TEST_SITE = "http://mochi.test:8888";
-const TEST_CACHE_SITE = "http://www.example.com";
-const TEST_DIRECTORY = "/browser/browser/components/privatebrowsing/test/browser/";
-
-const TEST_PAGE = TEST_SITE + TEST_DIRECTORY + "file_favicon.html";
-const TEST_CACHE_PAGE = TEST_CACHE_SITE + TEST_DIRECTORY + "file_favicon.html";
-const FAVICON_URI = TEST_SITE + TEST_DIRECTORY + "file_favicon.png";
-const FAVICON_CACHE_URI = TEST_CACHE_SITE + TEST_DIRECTORY + "file_favicon.png";
-
-let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-let makeURI = Cu.import("resource://gre/modules/BrowserUtils.jsm", {}).BrowserUtils.makeURI;
-
-function clearAllImageCaches() {
- let tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
- .getService(SpecialPowers.Ci.imgITools);
- let imageCache = tools.getImgCacheForDocument(window.document);
- imageCache.clearCache(true); // true=chrome
- imageCache.clearCache(false); // false=content
-}
-
-function clearAllPlacesFavicons() {
- let faviconService = Cc["@mozilla.org/browser/favicon-service;1"]
- .getService(Ci.nsIFaviconService);
-
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- if (aTopic === "places-favicons-expired") {
- resolve();
- Services.obs.removeObserver(observer, "places-favicons-expired", false);
- }
- }
- };
-
- Services.obs.addObserver(observer, "places-favicons-expired", false);
- faviconService.expireAllFavicons();
- });
-}
-
-function observeFavicon(aIsPrivate, aExpectedCookie, aPageURI) {
- let faviconReqXUL = false;
- let faviconReqPlaces = false;
- let attr = {};
-
- if (aIsPrivate) {
- attr.privateBrowsingId = 1;
- }
-
- let expectedPrincipal = Services.scriptSecurityManager
- .createCodebasePrincipal(aPageURI, attr);
-
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- // Make sure that the topic is 'http-on-modify-request'.
- if (aTopic === "http-on-modify-request") {
- // We check the privateBrowsingId for the originAttributes of the loading
- // channel. All requests for the favicon should contain the correct
- // privateBrowsingId. There are two requests for a favicon loading, one
- // from the Places library and one from the XUL image. The difference
- // of them is the loading principal. The Places will use the content
- // principal and the XUL image will use the system principal.
-
- let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
- let reqLoadInfo = httpChannel.loadInfo;
- let loadingPrincipal = reqLoadInfo.loadingPrincipal;
- let triggeringPrincipal = reqLoadInfo.triggeringPrincipal;
-
- // Make sure this is a favicon request.
- if (httpChannel.URI.spec !== FAVICON_URI) {
- return;
- }
-
- // Check the privateBrowsingId.
- if (aIsPrivate) {
- is(reqLoadInfo.originAttributes.privateBrowsingId, 1, "The loadInfo has correct privateBrowsingId");
- } else {
- is(reqLoadInfo.originAttributes.privateBrowsingId, 0, "The loadInfo has correct privateBrowsingId");
- }
-
- if (loadingPrincipal.equals(systemPrincipal)) {
- faviconReqXUL = true;
- ok(triggeringPrincipal.equals(expectedPrincipal),
- "The triggeringPrincipal of favicon loading from XUL should be the content principal.");
- } else {
- faviconReqPlaces = true;
- ok(loadingPrincipal.equals(expectedPrincipal),
- "The loadingPrincipal of favicon loading from Places should be the content prinicpal");
- }
-
- let faviconCookie = httpChannel.getRequestHeader("cookie");
-
- is(faviconCookie, aExpectedCookie, "The cookie of the favicon loading is correct.");
- } else {
- ok(false, "Received unexpected topic: ", aTopic);
- }
-
- if (faviconReqXUL && faviconReqPlaces) {
- resolve();
- Services.obs.removeObserver(observer, "http-on-modify-request", false);
- }
- }
- };
-
- Services.obs.addObserver(observer, "http-on-modify-request", false);
- });
-}
-
-function waitOnFaviconResponse(aFaviconURL) {
- return new Promise(resolve => {
- let observer = {
- observe(aSubject, aTopic, aData) {
- if (aTopic === "http-on-examine-response" ||
- aTopic === "http-on-examine-cached-response") {
-
- let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
- let loadInfo = httpChannel.loadInfo;
-
- if (httpChannel.URI.spec !== aFaviconURL) {
- return;
- }
-
- let result = {
- topic: aTopic,
- privateBrowsingId: loadInfo.originAttributes.privateBrowsingId
- };
-
- resolve(result);
- Services.obs.removeObserver(observer, "http-on-examine-response", false);
- Services.obs.removeObserver(observer, "http-on-examine-cached-response", false);
- }
- }
- };
-
- Services.obs.addObserver(observer, "http-on-examine-response", false);
- Services.obs.addObserver(observer, "http-on-examine-cached-response", false);
- });
-}
-
-function waitOnFaviconLoaded(aFaviconURL) {
- return new Promise(resolve => {
- let observer = {
- onPageChanged(uri, attr, value, id) {
-
- if (attr === Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON &&
- value === aFaviconURL) {
- resolve();
- PlacesUtils.history.removeObserver(observer, false);
- }
- },
- };
-
- PlacesUtils.history.addObserver(observer, false);
- });
-}
-
-function* assignCookies(aBrowser, aURL, aCookieValue){
- let tabInfo = yield openTab(aBrowser, aURL);
-
- yield ContentTask.spawn(tabInfo.browser, aCookieValue, function* (value) {
- content.document.cookie = value;
- });
-
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-}
-
-function* openTab(aBrowser, aURL) {
- let tab = aBrowser.addTab(aURL);
-
- // Select tab and make sure its browser is focused.
- aBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = aBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return {tab, browser};
-}
-
-// A clean up function to prevent affecting other tests.
-registerCleanupFunction(() => {
- // Clear all cookies.
- let cookieMgr = Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- cookieMgr.removeAll();
-
- // Clear all image caches and network caches.
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-});
-
-add_task(function* test_favicon_privateBrowsing() {
- // Clear all image caches before running the test.
- clearAllImageCaches();
-
- // Clear all favicons in Places.
- yield clearAllPlacesFavicons();
-
- // Create a private browsing window.
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- let pageURI = makeURI(TEST_PAGE);
-
- // Generate two random cookies for non-private window and private window
- // respectively.
- let cookies = [];
- cookies.push(Math.random().toString());
- cookies.push(Math.random().toString());
-
- // Open a tab in private window and add a cookie into it.
- yield assignCookies(privateWindow.gBrowser, TEST_SITE, cookies[0]);
-
- // Open a tab in non-private window and add a cookie into it.
- yield assignCookies(gBrowser, TEST_SITE, cookies[1]);
-
- // Add the observer earlier in case we don't capture events in time.
- let promiseObserveFavicon = observeFavicon(true, cookies[0], pageURI);
-
- // Open a tab for the private window.
- let tabInfo = yield openTab(privateWindow.gBrowser, TEST_PAGE);
-
- // Waiting until favicon requests are all made.
- yield promiseObserveFavicon;
-
- // Close the tab.
- yield BrowserTestUtils.removeTab(tabInfo.tab);
-
- // Add the observer earlier in case we don't capture events in time.
- promiseObserveFavicon = observeFavicon(false, cookies[1], pageURI);
-
- // Open a tab for the non-private window.
- tabInfo = yield openTab(gBrowser, TEST_PAGE);
-
- // Waiting until favicon requests are all made.
- yield promiseObserveFavicon;
-
- // Close the tab.
- yield BrowserTestUtils.removeTab(tabInfo.tab);
- yield BrowserTestUtils.closeWindow(privateWindow);
-});
-
-add_task(function* test_favicon_cache_privateBrowsing() {
- // Clear all image cahces and network cache before running the test.
- clearAllImageCaches();
-
- let networkCache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
- .getService(Ci.nsICacheStorageService);
- networkCache.clear();
-
- // Clear all favicons in Places.
- yield clearAllPlacesFavicons();
-
- // Add an observer for making sure the favicon has been loaded and cached.
- let promiseFaviconLoaded = waitOnFaviconLoaded(FAVICON_CACHE_URI);
-
- // Open a tab for the non-private window.
- let tabInfoNonPrivate = yield openTab(gBrowser, TEST_CACHE_PAGE);
-
- let response = yield waitOnFaviconResponse(FAVICON_CACHE_URI);
-
- yield promiseFaviconLoaded;
-
- // Check that the favicon response has come from the network and it has the
- // correct privateBrowsingId.
- is(response.topic, "http-on-examine-response", "The favicon image should be loaded through network.");
- is(response.privateBrowsingId, 0, "We should observe the network response for the non-private tab.");
-
- // Create a private browsing window.
- let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
-
- // Open a tab for the private window.
- let tabInfoPrivate = yield openTab(privateWindow.gBrowser, TEST_CACHE_PAGE);
-
- // Wait for the favicon response of the private tab.
- response = yield waitOnFaviconResponse(FAVICON_CACHE_URI);
-
- // Make sure the favicon is loaded through the network and its privateBrowsingId is correct.
- is(response.topic, "http-on-examine-response", "The favicon image should be loaded through the network again.");
- is(response.privateBrowsingId, 1, "We should observe the network response for the private tab.");
-
- yield BrowserTestUtils.removeTab(tabInfoPrivate.tab);
- yield BrowserTestUtils.removeTab(tabInfoNonPrivate.tab);
- yield BrowserTestUtils.closeWindow(privateWindow);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
deleted file mode 100644
index 3a078ffc1..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the geolocation prompt does not show a remember
-// control inside the private browsing mode.
-
-add_task(function* test() {
- const testPageURL = "http://mochi.test:8888/browser/" +
- "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html";
-
- function checkGeolocation(aPrivateMode, aWindow) {
- return Task.spawn(function* () {
- aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab(testPageURL);
- yield BrowserTestUtils.browserLoaded(aWindow.gBrowser.selectedBrowser);
-
- let notification = aWindow.PopupNotifications.getNotification("geolocation");
-
- // Wait until the notification is available.
- while (!notification){
- yield new Promise(resolve => { executeSoon(resolve); });
- let notification = aWindow.PopupNotifications.getNotification("geolocation");
- }
-
- if (aPrivateMode) {
- // Make sure the notification is correctly displayed without a remember control
- is(notification.secondaryActions.length, 0, "Secondary actions shouldn't exist (always/never remember)");
- } else {
- ok(notification.secondaryActions.length > 1, "Secondary actions should exist (always/never remember)");
- }
- notification.remove();
-
- aWindow.gBrowser.removeCurrentTab();
- });
- };
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let browser = win.gBrowser.selectedBrowser;
- browser.loadURI(testPageURL);
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield checkGeolocation(false, win);
-
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let privateBrowser = privateWin.gBrowser.selectedBrowser;
- privateBrowser.loadURI(testPageURL);
- yield BrowserTestUtils.browserLoaded(privateBrowser);
-
- yield checkGeolocation(true, privateWin);
-
- // Cleanup
- yield BrowserTestUtils.closeWindow(win);
- yield BrowserTestUtils.closeWindow(privateWin);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html
deleted file mode 100644
index 36d5e3cec..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <title>Geolocation invoker</title>
- </head>
- <body>
- <script type="text/javascript">
- navigator.geolocation.getCurrentPosition(function (pos) {
- // ignore
- });
- </script>
- </body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_lastpbcontextexited.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_lastpbcontextexited.js
deleted file mode 100644
index dbe8ed060..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_lastpbcontextexited.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- // We need to open a new window for this so that its docshell would get destroyed
- // when clearing the PB mode flag.
- function runTest(aCloseWindow, aCallback) {
- let newWin = OpenBrowserWindow({private: true});
- SimpleTest.waitForFocus(function() {
- let expectedExiting = true;
- let expectedExited = false;
- let observerExiting = {
- observe: function(aSubject, aTopic, aData) {
- is(aTopic, "last-pb-context-exiting", "Correct topic should be dispatched (exiting)");
- is(expectedExiting, true, "notification not expected yet (exiting)");
- expectedExited = true;
- Services.obs.removeObserver(observerExiting, "last-pb-context-exiting");
- }
- };
- let observerExited = {
- observe: function(aSubject, aTopic, aData) {
- is(aTopic, "last-pb-context-exited", "Correct topic should be dispatched (exited)");
- is(expectedExited, true, "notification not expected yet (exited)");
- Services.obs.removeObserver(observerExited, "last-pb-context-exited");
- aCallback();
- }
- };
- Services.obs.addObserver(observerExiting, "last-pb-context-exiting", false);
- Services.obs.addObserver(observerExited, "last-pb-context-exited", false);
- expectedExiting = true;
- aCloseWindow(newWin);
- newWin = null;
- SpecialPowers.forceGC();
- }, newWin);
- }
-
- waitForExplicitFinish();
-
- runTest(function(newWin) {
- // Simulate pressing the window close button
- newWin.document.getElementById("cmd_closeWindow").doCommand();
- }, function () {
- runTest(function(newWin) {
- // Simulate closing the last tab
- newWin.document.getElementById("cmd_close").doCommand();
- }, finish);
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
deleted file mode 100644
index acccb5e2d..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
- add_task(function test() {
- requestLongerTimeout(2);
- const page1 = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
- 'browser_privatebrowsing_localStorage_page1.html'
-
- let win = yield BrowserTestUtils.openNewBrowserWindow({private: true});
-
- let tab = win.gBrowser.selectedTab = win.gBrowser.addTab(page1);
- let browser = win.gBrowser.selectedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- browser.loadURI(
- 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/' +
- 'browser_privatebrowsing_localStorage_page2.html');
- yield BrowserTestUtils.browserLoaded(browser);
-
- is(browser.contentTitle, '2', "localStorage should contain 2 items");
-
- // Cleanup
- yield BrowserTestUtils.closeWindow(win);
- });
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js
deleted file mode 100644
index 3bcb6e5c9..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Ensure that a storage instance used by both private and public sessions at different times does not
-// allow any data to leak due to cached values.
-
-// Step 1: Load browser_privatebrowsing_localStorage_before_after_page.html in a private tab, causing a storage
-// item to exist. Close the tab.
-// Step 2: Load the same page in a non-private tab, ensuring that the storage instance reports only one item
-// existing.
-
-add_task(function test() {
- let testURI = "about:blank";
- let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/';
-
- // Step 1.
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let privateBrowser = privateWin.gBrowser.addTab(
- prefix + 'browser_privatebrowsing_localStorage_before_after_page.html').linkedBrowser;
- yield BrowserTestUtils.browserLoaded(privateBrowser);
-
- is(privateBrowser.contentTitle, '1', "localStorage should contain 1 item");
-
- // Step 2.
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let browser = win.gBrowser.addTab(
- prefix + 'browser_privatebrowsing_localStorage_before_after_page2.html').linkedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- is(browser.contentTitle, 'null|0', 'localStorage should contain 0 items');
-
- // Cleanup
- yield BrowserTestUtils.closeWindow(privateWin);
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page.html
deleted file mode 100644
index 143fea4e7..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script type="text/javascript">
- localStorage.clear();
- localStorage.setItem('zzztest', 'zzzvalue');
- document.title = localStorage.length;
-</script>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page2.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page2.html
deleted file mode 100644
index 9a7e2da63..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page2.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script type="text/javascript">
- document.title = localStorage.getItem('zzztest', 'zzzvalue') + '|' + localStorage.length;
- localStorage.clear();
-</script>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page1.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page1.html
deleted file mode 100644
index 3e79a01bf..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page1.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script type="text/javascript">
- localStorage.clear();
- localStorage.setItem('test1', 'value1');
-</script>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page2.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page2.html
deleted file mode 100644
index 8c9b28fd8..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page2.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<script type="text/javascript">
- localStorage.setItem('test2', 'value2');
- document.title = localStorage.length;
-</script>
-</head>
-<body>
-</body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_newtab_from_popup.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_newtab_from_popup.js
deleted file mode 100644
index b09ec0368..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_newtab_from_popup.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Tests that a popup window in private browsing window opens
- * new tab links in the original private browsing window as
- * new tabs.
- *
- * This is a regression test for bug 1202634.
- */
-
-// We're able to sidestep some quote-escaping issues when
-// nesting data URI's by encoding the second data URI in
-// base64.
-const POPUP_BODY_BASE64 = btoa(`<a href="http://example.com/" target="_blank"
- id="second">
- Now click this
- </a>`);
-const POPUP_LINK = `data:text/html;charset=utf-8;base64,${POPUP_BODY_BASE64}`;
-const WINDOW_BODY = `data:text/html,
- <a href="%23" id="first"
- onclick="window.open('${POPUP_LINK}', '_blank',
- 'width=630,height=500')">
- First click this.
- </a>`;
-
-add_task(function* test_private_popup_window_opens_private_tabs() {
- let privWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
-
- // Sanity check - this browser better be private.
- ok(PrivateBrowsingUtils.isWindowPrivate(privWin),
- "Opened a private browsing window.");
-
- // First, open a private browsing window, and load our
- // testing page.
- let privBrowser = privWin.gBrowser.selectedBrowser;
- yield BrowserTestUtils.loadURI(privBrowser, WINDOW_BODY);
- yield BrowserTestUtils.browserLoaded(privBrowser);
-
- // Next, click on the link in the testing page, and ensure
- // that a private popup window is opened.
- let openedPromise = BrowserTestUtils.waitForNewWindow(true, POPUP_LINK);
-
- yield BrowserTestUtils.synthesizeMouseAtCenter("#first", {}, privBrowser);
- let popupWin = yield openedPromise;
- ok(PrivateBrowsingUtils.isWindowPrivate(popupWin),
- "Popup window was private.");
-
- // Now click on the link in the popup, and ensure that a new
- // tab is opened in the original private browsing window.
- let newTabPromise = BrowserTestUtils.waitForNewTab(privWin.gBrowser);
- let popupBrowser = popupWin.gBrowser.selectedBrowser;
- yield BrowserTestUtils.synthesizeMouseAtCenter("#second", {}, popupBrowser);
- let newPrivTab = yield newTabPromise;
-
- // Ensure that the newly created tab's browser is private.
- ok(PrivateBrowsingUtils.isBrowserPrivate(newPrivTab.linkedBrowser),
- "Newly opened tab should be private.");
-
- // Clean up
- yield BrowserTestUtils.removeTab(newPrivTab);
- yield BrowserTestUtils.closeWindow(popupWin);
- yield BrowserTestUtils.closeWindow(privWin);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_noSessionRestoreMenuOption.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_noSessionRestoreMenuOption.js
deleted file mode 100644
index ae6e8a6a3..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_noSessionRestoreMenuOption.js
+++ /dev/null
@@ -1,23 +0,0 @@
-"use strict";
-
-/**
- * Tests that if we open a tab within a private browsing window, and then
- * close that private browsing window, that subsequent private browsing
- * windows do not allow the command for restoring the last session.
- */
-add_task(function* test_no_session_restore_menu_option() {
- let win = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- ok(true, "The first private window got loaded");
- win.gBrowser.addTab("about:mozilla");
- yield BrowserTestUtils.closeWindow(win);
-
- win = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- let srCommand = win.document.getElementById("Browser:RestoreLastSession");
- ok(srCommand, "The Session Restore command should exist");
- is(PrivateBrowsingUtils.isWindowPrivate(win), true,
- "PrivateBrowsingUtils should report the correct per-window private browsing status");
- is(srCommand.hasAttribute("disabled"), true,
- "The Session Restore command should be disabled in private browsing mode");
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_nonbrowser.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_nonbrowser.js
deleted file mode 100644
index d2a69dd4e..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_nonbrowser.js
+++ /dev/null
@@ -1,19 +0,0 @@
-"use strict";
-
-/**
- * Tests that we fire the last-pb-context-exited observer notification
- * when the last private browsing window closes, even if a chrome window
- * was opened from that private browsing window.
- */
-add_task(function* () {
- let win = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- let chromeWin = win.open("chrome://browser/content/places/places.xul", "_blank",
- "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
- yield BrowserTestUtils.waitForEvent(chromeWin, "load");
- let obsPromise = TestUtils.topicObserved("last-pb-context-exited");
- yield BrowserTestUtils.closeWindow(win);
- yield obsPromise;
- Assert.ok(true, "Got the last-pb-context-exited notification");
- chromeWin.close();
-});
-
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
deleted file mode 100644
index 0b1369b11..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// 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, false);
- windowsToClose.push(win);
- callback(win);
- }, false);
-}
-
-registerCleanupFunction(function() {
- windowsToClose.forEach(function(win) {
- win.close();
- });
-});
-
-function test() {
- // initialization
- waitForExplicitFinish();
- let ds = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIProperties);
- let dir1 = ds.get("ProfD", Ci.nsIFile);
- let dir2 = ds.get("TmpD", Ci.nsIFile);
- let file = dir2.clone();
- file.append("pbtest.file");
- file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
-
- const kPrefName = "browser.open.lastDir";
-
- function setupCleanSlate(win) {
- win.gLastOpenDirectory.reset();
- gPrefService.clearUserPref(kPrefName);
- }
-
- setupCleanSlate(window);
-
- // open one regular and one private window
- testOnWindow(undefined, function(nonPrivateWindow) {
- setupCleanSlate(nonPrivateWindow);
- testOnWindow({private: true}, function(privateWindow) {
- setupCleanSlate(privateWindow);
-
- // Test 1: general workflow test
-
- // initial checks
- ok(!nonPrivateWindow.gLastOpenDirectory.path,
- "Last open directory path should be initially empty");
- nonPrivateWindow.gLastOpenDirectory.path = dir2;
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir2.path,
- "The path should be successfully set");
- nonPrivateWindow.gLastOpenDirectory.path = null;
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir2.path,
- "The path should be not change when assigning it to null");
- nonPrivateWindow.gLastOpenDirectory.path = dir1;
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The path should be successfully outside of the private browsing mode");
-
- // test the private window
- is(privateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The path should not change when entering the private browsing mode");
- privateWindow.gLastOpenDirectory.path = dir2;
- is(privateWindow.gLastOpenDirectory.path.path, dir2.path,
- "The path should successfully change inside the private browsing mode");
-
- // test the non-private window
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The path should be reset to the same path as before entering the private browsing mode");
-
- setupCleanSlate(nonPrivateWindow);
- setupCleanSlate(privateWindow);
-
- // Test 2: the user first tries to open a file inside the private browsing mode
-
- // test the private window
- ok(!privateWindow.gLastOpenDirectory.path,
- "No original path should exist inside the private browsing mode");
- privateWindow.gLastOpenDirectory.path = dir1;
- is(privateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The path should be successfully set inside the private browsing mode");
- // test the non-private window
- ok(!nonPrivateWindow.gLastOpenDirectory.path,
- "The path set inside the private browsing mode should not leak when leaving that mode");
-
- setupCleanSlate(nonPrivateWindow);
- setupCleanSlate(privateWindow);
-
- // Test 3: the last open directory is set from a previous session, it should be used
- // in normal mode
-
- gPrefService.setComplexValue(kPrefName, Ci.nsILocalFile, dir1);
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The pref set from last session should take effect outside the private browsing mode");
-
- setupCleanSlate(nonPrivateWindow);
- setupCleanSlate(privateWindow);
-
- // Test 4: the last open directory is set from a previous session, it should be used
- // in private browsing mode mode
-
- gPrefService.setComplexValue(kPrefName, Ci.nsILocalFile, dir1);
- // test the private window
- is(privateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The pref set from last session should take effect inside the private browsing mode");
- // test the non-private window
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir1.path,
- "The pref set from last session should remain in effect after leaving the private browsing mode");
-
- setupCleanSlate(nonPrivateWindow);
- setupCleanSlate(privateWindow);
-
- // Test 5: setting the path to a file shouldn't work
-
- nonPrivateWindow.gLastOpenDirectory.path = file;
- ok(!nonPrivateWindow.gLastOpenDirectory.path,
- "Setting the path to a file shouldn't work when it's originally null");
- nonPrivateWindow.gLastOpenDirectory.path = dir1;
- nonPrivateWindow.gLastOpenDirectory.path = file;
- is(nonPrivateWindow.gLastOpenDirectory.path.path, dir1.path,
- "Setting the path to a file shouldn't work when it's not originally null");
-
- // cleanup
- file.remove(false);
- finish();
- });
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html
deleted file mode 100644
index f5bb3212f..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <title>Title 1</title>
- </head>
- <body>
- </body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.js
deleted file mode 100644
index 32436b3cc..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test to make sure that the visited page titles do not get updated inside the
-// private browsing mode.
-"use strict";
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PlacesUtils.jsm");
-
-add_task(function* test() {
- const TEST_URL = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placesTitleNoUpdate.html"
- const TEST_URI = Services.io.newURI(TEST_URL, null, null);
- const TITLE_1 = "Title 1";
- const TITLE_2 = "Title 2";
-
- function waitForTitleChanged() {
- return new Promise(resolve => {
- let historyObserver = {
- onTitleChanged: function(uri, pageTitle) {
- PlacesUtils.history.removeObserver(historyObserver, false);
- resolve({uri: uri, pageTitle: pageTitle});
- },
- onBeginUpdateBatch: function () {},
- onEndUpdateBatch: function () {},
- onVisit: function () {},
- onDeleteURI: function () {},
- onClearHistory: function () {},
- onPageChanged: function () {},
- onDeleteVisits: function() {},
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
- };
-
- PlacesUtils.history.addObserver(historyObserver, false);
- });
- };
-
- yield PlacesTestUtils.clearHistory();
-
- let tabToClose = gBrowser.selectedTab = gBrowser.addTab(TEST_URL);
- yield waitForTitleChanged();
- is(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1, "The title matches the orignal title after first visit");
-
- let place = {
- uri: TEST_URI,
- title: TITLE_2,
- visits: [{
- visitDate: Date.now() * 1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
- }]
- };
- PlacesUtils.asyncHistory.updatePlaces(place, {
- handleError: () => ok(false, "Unexpected error in adding visit."),
- handleResult: function () { },
- handleCompletion: function () {}
- });
-
- yield waitForTitleChanged();
- is(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_2, "The title matches the updated title after updating visit");
-
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private:true});
- yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.addTab(TEST_URL).linkedBrowser);
-
- is(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_2, "The title remains the same after visiting in private window");
- yield PlacesTestUtils.clearHistory();
-
- // Cleanup
- BrowserTestUtils.closeWindow(privateWin);
- gBrowser.removeTab(tabToClose);
-});
-
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js
deleted file mode 100644
index a70019976..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the title of existing history entries does not
-// change inside a private window.
-
-add_task(function* test() {
- const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
- "privatebrowsing/test/browser/title.sjs";
- let cm = Services.cookies;
-
- function cleanup() {
- // delete all cookies
- cm.removeAll();
- // delete all history items
- return PlacesTestUtils.clearHistory();
- }
-
- yield cleanup();
-
- let deferredFirst = PromiseUtils.defer();
- let deferredSecond = PromiseUtils.defer();
- let deferredThird = PromiseUtils.defer();
-
- let testNumber = 0;
- let historyObserver = {
- onTitleChanged: function(aURI, aPageTitle) {
- if (aURI.spec != TEST_URL)
- return;
- switch (++testNumber) {
- case 1:
- // The first time that the page is loaded
- deferredFirst.resolve(aPageTitle);
- break;
- case 2:
- // The second time that the page is loaded
- deferredSecond.resolve(aPageTitle);
- break;
- case 3:
- // After clean up
- deferredThird.resolve(aPageTitle);
- break;
- default:
- // Checks that opening the page in a private window should not fire a
- // title change.
- ok(false, "Title changed. Unexpected pass: " + testNumber);
- }
- },
-
- onBeginUpdateBatch: function () {},
- onEndUpdateBatch: function () {},
- onVisit: function () {},
- onDeleteURI: function () {},
- onClearHistory: function () {},
- onPageChanged: function () {},
- onDeleteVisits: function() {},
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
- };
- PlacesUtils.history.addObserver(historyObserver, false);
-
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- win.gBrowser.selectedTab = win.gBrowser.addTab(TEST_URL);
- let aPageTitle = yield deferredFirst.promise;
- // The first time that the page is loaded
- is(aPageTitle, "No Cookie",
- "The page should be loaded without any cookie for the first time");
-
- win.gBrowser.selectedTab = win.gBrowser.addTab(TEST_URL);
- aPageTitle = yield deferredSecond.promise;
- // The second time that the page is loaded
- is(aPageTitle, "Cookie",
- "The page should be loaded with a cookie for the second time");
-
- yield cleanup();
-
- win.gBrowser.selectedTab = win.gBrowser.addTab(TEST_URL);
- aPageTitle = yield deferredThird.promise;
- // After clean up
- is(aPageTitle, "No Cookie",
- "The page should be loaded without any cookie again");
-
- let win2 = yield BrowserTestUtils.openNewBrowserWindow({private: true});
-
- let private_tab = win2.gBrowser.addTab(TEST_URL);
- win2.gBrowser.selectedTab = private_tab;
- yield BrowserTestUtils.browserLoaded(private_tab.linkedBrowser);
-
- // Cleanup
- yield cleanup();
- PlacesUtils.history.removeObserver(historyObserver);
- yield BrowserTestUtils.closeWindow(win);
- yield BrowserTestUtils.closeWindow(win2);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
deleted file mode 100644
index 71d85f296..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that private browsing mode disables the remember option
-// for the popup blocker menu.
-add_task(function* test() {
- let testURI = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/popup.html";
- let oldPopupPolicy = gPrefService.getBoolPref("dom.disable_open_during_load");
- gPrefService.setBoolPref("dom.disable_open_during_load", true);
-
- 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, false);
-
- 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");
- aWindow.document.removeEventListener("popupshown", arguments.callee, false);
-
- if (aExpectedDisabled)
- is(aWindow.document.getElementById("blockedPopupAllowSite").getAttribute("disabled"), "true",
- "The allow popups menu item should be disabled");
-
- event.originalTarget.hidePopup();
- dump("CMI: calling back\n");
- callback();
- dump("CMI: called back\n");
- }, false);
- dump("CMI: out\n");
- }
-
- checkMenuItem(function() {
- aCallback();
- });
- notification.querySelector("button").doCommand();
- });
-
- }, false);
-
- 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));
-
- let win2 = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield new Promise(resolve => waitForFocus(resolve, win2));
- yield new Promise(resolve => testPopupBlockerMenuItem(true, win2, resolve));
-
- let win3 = yield BrowserTestUtils.openNewBrowserWindow();
- yield new Promise(resolve => waitForFocus(resolve, win3));
- yield new Promise(resolve => testPopupBlockerMenuItem(false, win3, resolve));
-
- // Cleanup
- yield BrowserTestUtils.closeWindow(win1);
- yield BrowserTestUtils.closeWindow(win2);
- yield BrowserTestUtils.closeWindow(win3);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js
deleted file mode 100644
index fe69a2234..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the web pages can't register protocol handlers
-// inside the private browsing mode.
-
-add_task(function* test() {
- let notificationValue = "Protocol Registration: testprotocol";
- let testURI = "http://example.com/browser/" +
- "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html";
-
- let doTest = Task.async(function* (aIsPrivateMode, aWindow) {
- let tab = aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab(testURI);
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- let promiseFinished = PromiseUtils.defer();
- setTimeout(function() {
- let notificationBox = aWindow.gBrowser.getNotificationBox();
- let notification = notificationBox.getNotificationWithValue(notificationValue);
-
- if (aIsPrivateMode) {
- // Make sure the notification is correctly displayed without a remember control
- ok(!notification, "Notification box should not be displayed inside of private browsing mode");
- } else {
- // Make sure the notification is correctly displayed with a remember control
- ok(notification, "Notification box should be displaying outside of private browsing mode");
- }
-
- promiseFinished.resolve();
- }, 100); // remember control is added in a setTimeout(0) call
-
- yield promiseFinished.promise;
- });
-
- // test first when not on private mode
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield doTest(false, win);
-
- // then test when on private mode
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield doTest(true, privateWin);
-
- // Cleanup
- yield BrowserTestUtils.closeWindow(win);
- yield BrowserTestUtils.closeWindow(privateWin);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html
deleted file mode 100644
index 74f846d54..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <title>Protocol registrar page</title>
- </head>
- <body>
- <script type="text/javascript">
- navigator.registerProtocolHandler("testprotocol",
- "https://example.com/foobar?uri=%s",
- "Test Protocol");
- </script>
- </body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sidebar.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sidebar.js
deleted file mode 100644
index dbd74029d..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sidebar.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that Sidebars do not migrate across windows with
-// different privacy states
-
-// See Bug 885054: https://bugzilla.mozilla.org/show_bug.cgi?id=885054
-
-function test() {
- waitForExplicitFinish();
-
- let { utils: Cu } = Components;
-
- let { Promise: { defer } } = Cu.import("resource://gre/modules/Promise.jsm", {});
-
- // opens a sidebar
- function openSidebar(win) {
- let { promise, resolve } = defer();
- let doc = win.document;
-
- let sidebarID = 'viewBookmarksSidebar';
-
- let sidebar = doc.getElementById('sidebar');
-
- let sidebarurl = doc.getElementById(sidebarID).getAttribute('sidebarurl');
-
- sidebar.addEventListener('load', function onSidebarLoad() {
- if (sidebar.contentWindow.location.href != sidebarurl)
- return;
- sidebar.removeEventListener('load', onSidebarLoad, true);
-
- resolve(win);
- }, true);
-
- win.SidebarUI.show(sidebarID);
-
- return promise;
- }
-
- let windowCache = [];
- function cacheWindow(w) {
- windowCache.push(w);
- return w;
- }
- function closeCachedWindows () {
- windowCache.forEach(w => w.close());
- }
-
- // Part 1: NON PRIVATE WINDOW -> PRIVATE WINDOW
- openWindow(window, {}, 1).
- then(cacheWindow).
- then(openSidebar).
- then(win => openWindow(win, { private: true })).
- then(cacheWindow).
- then(function({ document }) {
- let sidebarBox = document.getElementById("sidebar-box");
- is(sidebarBox.hidden, true, 'Opening a private window from reg window does not open the sidebar');
- }).
- // Part 2: NON PRIVATE WINDOW -> NON PRIVATE WINDOW
- then(() => openWindow(window)).
- then(cacheWindow).
- then(openSidebar).
- then(win => openWindow(win)).
- then(cacheWindow).
- then(function({ document }) {
- let sidebarBox = document.getElementById("sidebar-box");
- is(sidebarBox.hidden, false, 'Opening a reg window from reg window does open the sidebar');
- }).
- // Part 3: PRIVATE WINDOW -> NON PRIVATE WINDOW
- then(() => openWindow(window, { private: true })).
- then(cacheWindow).
- then(openSidebar).
- then(win => openWindow(win)).
- then(cacheWindow).
- then(function({ document }) {
- let sidebarBox = document.getElementById("sidebar-box");
- is(sidebarBox.hidden, true, 'Opening a reg window from a private window does not open the sidebar');
- }).
- // Part 4: PRIVATE WINDOW -> PRIVATE WINDOW
- then(() => openWindow(window, { private: true })).
- then(cacheWindow).
- then(openSidebar).
- then(win => openWindow(win, { private: true })).
- then(cacheWindow).
- then(function({ document }) {
- let sidebarBox = document.getElementById("sidebar-box");
- is(sidebarBox.hidden, false, 'Opening a private window from private window does open the sidebar');
- }).
- then(closeCachedWindows).
- then(finish);
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
deleted file mode 100644
index e2b8593d6..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// 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, false);
- windowsToClose.push(win);
- executeSoon(() => callback(win));
- }, false);
-}
-
-registerCleanupFunction(function() {
- windowsToClose.forEach(function(win) {
- win.close();
- });
-});
-
-function test() {
- // initialization
- waitForExplicitFinish();
-
- ok(!document.documentElement.hasAttribute("privatebrowsingmode"),
- "privatebrowsingmode should not be present in normal mode");
-
- // open a private window
- testOnWindow({private: true}, function(win) {
- is(win.document.documentElement.getAttribute("privatebrowsingmode"), "temporary",
- "privatebrowsingmode should be \"temporary\" inside the private browsing mode");
-
- finish();
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
deleted file mode 100644
index cbd2c60f8..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the gPrivateBrowsingUI object, the Private Browsing
-// menu item and its XUL <command> element work correctly.
-
-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);
-
- 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);
-
- 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");
- windowsToClose.push(aSubject);
- aCallback(aSubject);
- }, false);
- }, "domwindowopened", false);
-
- cmd = aWindow.document.getElementById("Tools:PrivateBrowsing");
- var func = new Function("", cmd.getAttribute("oncommand"));
- func.call(cmd);
- };
-
- function testOnWindow(aOptions, aCallback) {
- whenNewWindowLoaded(aOptions, function(aWin) {
- windowsToClose.push(aWin);
- // execute should only be called when need, like when you are opening
- // web pages on the test. If calling executeSoon() is not necesary, then
- // call whenNewWindowLoaded() instead of testOnWindow() on your test.
- executeSoon(() => aCallback(aWin));
- });
- };
-
- // this function is called after calling finish() on the test.
- registerCleanupFunction(function() {
- windowsToClose.forEach(function(aWin) {
- aWin.close();
- });
- });
-
- // test first when not on private mode
- testOnWindow({}, function(aWin) {
- doTest(false, aWin, function() {
- // then test when on private mode, opening a new private window from the
- // user interface.
- openPrivateBrowsingModeByUI(aWin, function(aPrivateWin) {
- doTest(true, aPrivateWin, finish);
- });
- });
- });
-}
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js
deleted file mode 100644
index 2be701bcd..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the URL bar is focused when entering the private window.
-
-"use strict";
-Components.utils.import("resource://gre/modules/Promise.jsm", this);
-let aboutNewTabService = Components.classes["@mozilla.org/browser/aboutnewtab-service;1"]
- .getService(Components.interfaces.nsIAboutNewTabService);
-
-function checkUrlbarFocus(win) {
- let urlbar = win.gURLBar;
- is(win.document.activeElement, urlbar.inputField, "URL Bar should be focused");
- is(urlbar.value, "", "URL Bar should be empty");
-}
-
-function openNewPrivateWindow() {
- let deferred = Promise.defer();
- whenNewWindowLoaded({private: true}, win => {
- executeSoon(() => deferred.resolve(win));
- });
- return deferred.promise;
-}
-
-add_task(function* () {
- let win = yield openNewPrivateWindow();
- checkUrlbarFocus(win);
- win.close();
-});
-
-add_task(function* () {
- aboutNewTabService.newTabURL = "about:blank";
- registerCleanupFunction(() => {
- aboutNewTabService.resetNewTabURL();
- });
-
- let win = yield openNewPrivateWindow();
- checkUrlbarFocus(win);
- win.close();
-
- aboutNewTabService.resetNewTabURL();
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
deleted file mode 100644
index aca8d0c7b..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that the window title changes correctly while switching
-// from and to private browsing mode.
-
-add_task(function test() {
- const testPageURL = "http://mochi.test:8888/browser/" +
- "browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html";
- requestLongerTimeout(2);
-
- // initialization of expected titles
- let test_title = "Test title";
- let app_name = document.documentElement.getAttribute("title");
- const isOSX = ("nsILocalFileMac" in Ci);
- let page_with_title;
- let page_without_title;
- let about_pb_title;
- let pb_page_with_title;
- let pb_page_without_title;
- let pb_about_pb_title;
- if (isOSX) {
- page_with_title = test_title;
- page_without_title = app_name;
- about_pb_title = "Open a private window?";
- pb_page_with_title = test_title + " - (Private Browsing)";
- pb_page_without_title = app_name + " - (Private Browsing)";
- pb_about_pb_title = "Private Browsing - (Private Browsing)";
- }
- else {
- page_with_title = test_title + " - " + app_name;
- page_without_title = app_name;
- about_pb_title = "Open a private window?" + " - " + app_name;
- pb_page_with_title = test_title + " - " + app_name + " (Private Browsing)";
- pb_page_without_title = app_name + " (Private Browsing)";
- pb_about_pb_title = "Private Browsing - " + app_name + " (Private Browsing)";
- }
-
- function* testTabTitle(aWindow, url, insidePB, expected_title) {
- let tab = (yield BrowserTestUtils.openNewForegroundTab(aWindow.gBrowser));
- yield BrowserTestUtils.loadURI(tab.linkedBrowser, url);
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- yield BrowserTestUtils.waitForCondition(() => {
- return aWindow.document.title === expected_title;
- }, `Window title should be ${expected_title}, got ${aWindow.document.title}`);
-
- is(aWindow.document.title, expected_title, "The window title for " + url +
- " is correct (" + (insidePB ? "inside" : "outside") +
- " private browsing mode)");
-
- let win = aWindow.gBrowser.replaceTabWithWindow(tab);
- yield BrowserTestUtils.waitForEvent(win, "load", false);
-
- yield BrowserTestUtils.waitForCondition(() => {
- return win.document.title === expected_title;
- }, `Window title should be ${expected_title}, got ${aWindow.document.title}`);
-
- is(win.document.title, expected_title, "The window title for " + url +
- " detached tab is correct (" + (insidePB ? "inside" : "outside") +
- " private browsing mode)");
-
- yield Promise.all([ BrowserTestUtils.closeWindow(win),
- BrowserTestUtils.closeWindow(aWindow) ]);
- }
-
- function openWin(private) {
- return BrowserTestUtils.openNewBrowserWindow({ private });
- }
- yield Task.spawn(testTabTitle((yield openWin(false)), "about:blank", false, page_without_title));
- yield Task.spawn(testTabTitle((yield openWin(false)), testPageURL, false, page_with_title));
- yield Task.spawn(testTabTitle((yield openWin(false)), "about:privatebrowsing", false, about_pb_title));
- yield Task.spawn(testTabTitle((yield openWin(true)), "about:blank", true, pb_page_without_title));
- yield Task.spawn(testTabTitle((yield openWin(true)), testPageURL, true, pb_page_with_title));
- yield Task.spawn(testTabTitle((yield openWin(true)), "about:privatebrowsing", true, pb_about_pb_title));
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html
deleted file mode 100644
index 760bde7d1..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <title>Test title</title>
- </head>
- <body>
- Test page for the window title test
- </body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
deleted file mode 100644
index f5afcbd61..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that private browsing turns off doesn't cause zoom
-// settings to be reset on tab switch (bug 464962)
-
-add_task(function* test() {
- let win = (yield BrowserTestUtils.openNewBrowserWindow({ private: true }));
- let tabAbout = (yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:"));
- let tabMozilla = (yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:"));
-
- let mozillaZoom = win.ZoomManager.zoom;
-
- // change the zoom on the mozilla page
- win.FullZoom.enlarge();
- // make sure the zoom level has been changed
- isnot(win.ZoomManager.zoom, mozillaZoom, "Zoom level can be changed");
- mozillaZoom = win.ZoomManager.zoom;
-
- // switch to about: tab
- yield BrowserTestUtils.switchTab(win.gBrowser, tabAbout);
-
- // switch back to mozilla tab
- yield BrowserTestUtils.switchTab(win.gBrowser, tabMozilla);
-
- // make sure the zoom level has not changed
- is(win.ZoomManager.zoom, mozillaZoom,
- "Entering private browsing should not reset the zoom on a tab");
-
- // cleanup
- win.FullZoom.reset();
- yield Promise.all([ BrowserTestUtils.removeTab(tabMozilla),
- BrowserTestUtils.removeTab(tabAbout) ]);
-
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
deleted file mode 100644
index b67bfc229..000000000
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test makes sure that about:privatebrowsing does not appear zoomed in
-// if there is already a zoom site pref for about:blank (bug 487656).
-
-add_task(function* test() {
- // initialization
- let windowsToClose = [];
- let windowsToReset = [];
-
- function promiseLocationChange() {
- return new Promise(resolve => {
- Services.obs.addObserver(function onLocationChange(subj, topic, data) {
- Services.obs.removeObserver(onLocationChange, topic);
- resolve();
- }, "browser-fullZoom:location-change", false);
- });
- }
-
- function promiseTestReady(aIsZoomedWindow, aWindow) {
- // Need to wait on two things, the ordering of which is not guaranteed:
- // (1) the page load, and (2) FullZoom's update to the new page's zoom
- // level. FullZoom broadcasts "browser-fullZoom:location-change" when its
- // update is done. (See bug 856366 for details.)
-
-
- let browser = aWindow.gBrowser.selectedBrowser;
- return BrowserTestUtils.loadURI(browser, "about:blank").then(() => {
- return Promise.all([ BrowserTestUtils.browserLoaded(browser),
- promiseLocationChange() ]);
- }).then(() => doTest(aIsZoomedWindow, aWindow));
- }
-
- function doTest(aIsZoomedWindow, aWindow) {
- if (aIsZoomedWindow) {
- is(aWindow.ZoomManager.zoom, 1,
- "Zoom level for freshly loaded about:blank should be 1");
- // change the zoom on the blank page
- aWindow.FullZoom.enlarge();
- isnot(aWindow.ZoomManager.zoom, 1, "Zoom level for about:blank should be changed");
- return;
- }
-
- // make sure the zoom level is set to 1
- is(aWindow.ZoomManager.zoom, 1, "Zoom level for about:privatebrowsing should be reset");
- }
-
- function testOnWindow(options, callback) {
- return BrowserTestUtils.openNewBrowserWindow(options).then((win) => {
- windowsToClose.push(win);
- windowsToReset.push(win);
- return win;
- });
- }
-
- yield testOnWindow({}).then(win => promiseTestReady(true, win));
- yield testOnWindow({private: true}).then(win => promiseTestReady(false, win));
-
- // cleanup
- windowsToReset.forEach((win) => win.FullZoom.reset());
- yield Promise.all(windowsToClose.map(win => BrowserTestUtils.closeWindow(win)));
-});
diff --git a/browser/components/privatebrowsing/test/browser/empty_file.html b/browser/components/privatebrowsing/test/browser/empty_file.html
deleted file mode 100644
index 42682b474..000000000
--- a/browser/components/privatebrowsing/test/browser/empty_file.html
+++ /dev/null
@@ -1 +0,0 @@
-<html><body></body></html> \ No newline at end of file
diff --git a/browser/components/privatebrowsing/test/browser/file_favicon.html b/browser/components/privatebrowsing/test/browser/file_favicon.html
deleted file mode 100644
index b571134e1..000000000
--- a/browser/components/privatebrowsing/test/browser/file_favicon.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <meta charset='utf-8'>
- <title>Favicon Test for originAttributes</title>
- <link rel="icon" type="image/png" href="file_favicon.png" />
- </head>
- <body>
- Favicon!!
- </body>
-</html> \ No newline at end of file
diff --git a/browser/components/privatebrowsing/test/browser/file_favicon.png b/browser/components/privatebrowsing/test/browser/file_favicon.png
deleted file mode 100644
index 5535363c9..000000000
--- a/browser/components/privatebrowsing/test/browser/file_favicon.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/privatebrowsing/test/browser/file_favicon.png^headers^ b/browser/components/privatebrowsing/test/browser/file_favicon.png^headers^
deleted file mode 100644
index 9e23c73b7..000000000
--- a/browser/components/privatebrowsing/test/browser/file_favicon.png^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Cache-Control: no-cache
diff --git a/browser/components/privatebrowsing/test/browser/head.js b/browser/components/privatebrowsing/test/browser/head.js
deleted file mode 100644
index c822ba8d1..000000000
--- a/browser/components/privatebrowsing/test/browser/head.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var {PromiseUtils} = Cu.import("resource://gre/modules/PromiseUtils.jsm", {});
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-function whenNewWindowLoaded(aOptions, aCallback) {
- let win = OpenBrowserWindow(aOptions);
- let focused = SimpleTest.promiseFocus(win);
- let startupFinished = TestUtils.topicObserved("browser-delayed-startup-finished",
- subject => subject == win).then(() => win);
- Promise.all([focused, startupFinished])
- .then(results => executeSoon(() => aCallback(results[1])));
-
- return win;
-}
-
-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, false);
- resolve(win);
- }, false);
-
- return promise;
-}
-
-function newDirectory() {
- let FileUtils =
- Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
- let tmpDir = FileUtils.getDir("TmpD", [], true);
- let dir = tmpDir.clone();
- dir.append("testdir");
- dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
- return dir;
-}
-
-function newFileInDirectory(aDir) {
- let FileUtils =
- Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
- let file = aDir.clone();
- file.append("testfile");
- file.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_FILE);
- return file;
-}
-
-function clearHistory() {
- // simulate clearing the private data
- Services.obs.notifyObservers(null, "browser:purge-session-history", "");
-}
-
-function _initTest() {
- // Don't use about:home as the homepage for new windows
- Services.prefs.setIntPref("browser.startup.page", 0);
- registerCleanupFunction(() => Services.prefs.clearUserPref("browser.startup.page"));
-}
-
-_initTest();
diff --git a/browser/components/privatebrowsing/test/browser/popup.html b/browser/components/privatebrowsing/test/browser/popup.html
deleted file mode 100644
index 68bbbfa26..000000000
--- a/browser/components/privatebrowsing/test/browser/popup.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
- <head>
- <meta charset="utf8">
- <title>Page creating a popup</title>
- </head>
- <body>
- <script type="text/javascript">
- window.open("data:text/plain,test", "testwin");
- </script>
- </body>
-</html>
diff --git a/browser/components/privatebrowsing/test/browser/title.sjs b/browser/components/privatebrowsing/test/browser/title.sjs
deleted file mode 100644
index 568e235be..000000000
--- a/browser/components/privatebrowsing/test/browser/title.sjs
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This provides the tests with a page with different titles based on whether
-// a cookie is present or not.
-
-function handleRequest(request, response) {
- response.setStatusLine(request.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/html", false);
-
- var cookie = "name=value";
- var title = "No Cookie";
- if (request.hasHeader("Cookie") && request.getHeader("Cookie") == cookie)
- title = "Cookie";
- else
- response.setHeader("Set-Cookie", cookie, false);
-
- response.write("<html><head><title>");
- response.write(title);
- response.write("</title><body>test page</body></html>");
-}
diff --git a/browser/components/safebrowsing/content/test/.eslintrc.js b/browser/components/safebrowsing/content/test/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/safebrowsing/content/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/safebrowsing/content/test/browser.ini b/browser/components/safebrowsing/content/test/browser.ini
deleted file mode 100644
index 1ce19118e..000000000
--- a/browser/components/safebrowsing/content/test/browser.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[DEFAULT]
-support-files = head.js
-
-[browser_bug400731.js]
-[browser_bug415846.js]
-# Disabled on Mac because of its bizarre special-and-unique snowflake of a help menu.
-skip-if = os == "mac" || e10s # e10s: Bug 1248632
-[browser_whitelisted.js]
diff --git a/browser/components/safebrowsing/content/test/browser_bug400731.js b/browser/components/safebrowsing/content/test/browser_bug400731.js
deleted file mode 100644
index fac187753..000000000
--- a/browser/components/safebrowsing/content/test/browser_bug400731.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Check presence of the "Ignore this warning" button */
-
-function onDOMContentLoaded(callback) {
- function complete({ data }) {
- mm.removeMessageListener("Test:DOMContentLoaded", complete);
- callback(data);
- }
-
- let mm = gBrowser.selectedBrowser.messageManager;
- mm.addMessageListener("Test:DOMContentLoaded", complete);
-
- function contentScript() {
- let listener = function () {
- removeEventListener("DOMContentLoaded", listener);
-
- let button = content.document.getElementById("ignoreWarningButton");
-
- sendAsyncMessage("Test:DOMContentLoaded", { buttonPresent: !!button });
- };
- addEventListener("DOMContentLoaded", listener);
- }
- mm.loadFrameScript("data:,(" + contentScript.toString() + ")();", true);
-}
-
-function test() {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab("http://www.itisatrap.org/firefox/its-an-attack.html");
- onDOMContentLoaded(testMalware);
-}
-
-function testMalware(data) {
- ok(data.buttonPresent, "Ignore warning button should be present for malware");
-
- Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", false);
-
- // Now launch the unwanted software test
- onDOMContentLoaded(testUnwanted);
- gBrowser.loadURI("http://www.itisatrap.org/firefox/unwanted.html");
-}
-
-function testUnwanted(data) {
- // Confirm that "Ignore this warning" is visible - bug 422410
- ok(!data.buttonPresent, "Ignore warning button should be missing for unwanted software");
-
- Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", true);
-
- // Now launch the phishing test
- onDOMContentLoaded(testPhishing);
- gBrowser.loadURI("http://www.itisatrap.org/firefox/its-a-trap.html");
-}
-
-function testPhishing(data) {
- ok(data.buttonPresent, "Ignore warning button should be present for phishing");
-
- gBrowser.removeCurrentTab();
- finish();
-}
diff --git a/browser/components/safebrowsing/content/test/browser_bug415846.js b/browser/components/safebrowsing/content/test/browser_bug415846.js
deleted file mode 100644
index fc2e3472f..000000000
--- a/browser/components/safebrowsing/content/test/browser_bug415846.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Check for the correct behaviour of the report web forgery/not a web forgery
-menu items.
-
-Mac makes this astonishingly painful to test since their help menu is special magic,
-but we can at least test it on the other platforms.*/
-
-const NORMAL_PAGE = "http://example.com";
-const PHISH_PAGE = "http://www.itisatrap.org/firefox/its-a-trap.html";
-
-/**
- * Opens a new tab and browses to some URL, tests for the existence
- * of the phishing menu items, and then runs a test function to check
- * the state of the menu once opened. This function will take care of
- * opening and closing the menu.
- *
- * @param url (string)
- * The URL to browse the tab to.
- * @param testFn (function)
- * The function to run once the menu has been opened. This
- * function will be passed the "reportMenu" and "errorMenu"
- * DOM nodes as arguments, in that order. This function
- * should not yield anything.
- * @returns Promise
- */
-function check_menu_at_page(url, testFn) {
- return BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:blank",
- }, function*(browser) {
- // We don't get load events when the DocShell redirects to error
- // pages, but we do get DOMContentLoaded, so we'll wait for that.
- let dclPromise = ContentTask.spawn(browser, null, function*() {
- yield ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", false);
- });
- browser.loadURI(url);
- yield dclPromise;
-
- let menu = document.getElementById("menu_HelpPopup");
- ok(menu, "Help menu should exist");
-
- let reportMenu =
- document.getElementById("menu_HelpPopup_reportPhishingtoolmenu");
- ok(reportMenu, "Report phishing menu item should exist");
-
- let errorMenu =
- document.getElementById("menu_HelpPopup_reportPhishingErrortoolmenu");
- ok(errorMenu, "Report phishing error menu item should exist");
-
- let menuOpen = BrowserTestUtils.waitForEvent(menu, "popupshown");
- menu.openPopup(null, "", 0, 0, false, null);
- yield menuOpen;
-
- testFn(reportMenu, errorMenu);
-
- let menuClose = BrowserTestUtils.waitForEvent(menu, "popuphidden");
- menu.hidePopup();
- yield menuClose;
- });
-}
-
-/**
- * Tests that we show the "Report this page" menu item at a normal
- * page.
- */
-add_task(function*() {
- yield check_menu_at_page(NORMAL_PAGE, (reportMenu, errorMenu) => {
- ok(!reportMenu.hidden,
- "Report phishing menu should be visible on normal sites");
- ok(errorMenu.hidden,
- "Report error menu item should be hidden on normal sites");
- });
-});
-
-/**
- * Tests that we show the "Report this page is okay" menu item at
- * a reported attack site.
- */
-add_task(function*() {
- yield check_menu_at_page(PHISH_PAGE, (reportMenu, errorMenu) => {
- ok(reportMenu.hidden,
- "Report phishing menu should be hidden on phishing sites");
- ok(!errorMenu.hidden,
- "Report error menu item should be visible on phishing sites");
- });
-});
-
diff --git a/browser/components/safebrowsing/content/test/browser_whitelisted.js b/browser/components/safebrowsing/content/test/browser_whitelisted.js
deleted file mode 100644
index afb647a81..000000000
--- a/browser/components/safebrowsing/content/test/browser_whitelisted.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Ensure that hostnames in the whitelisted pref are not blocked. */
-
-const PREF_WHITELISTED_HOSTNAMES = "urlclassifier.skipHostnames";
-const TEST_PAGE = "http://www.itisatrap.org/firefox/its-an-attack.html";
-var tabbrowser = null;
-
-registerCleanupFunction(function() {
- tabbrowser = null;
- Services.prefs.clearUserPref(PREF_WHITELISTED_HOSTNAMES);
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-});
-
-function testBlockedPage(window) {
- info("Non-whitelisted pages must be blocked");
- ok(true, "about:blocked was shown");
-}
-
-function testWhitelistedPage(window) {
- info("Whitelisted pages must be skipped");
- var getmeout_button = window.document.getElementById("getMeOutButton");
- var ignorewarning_button = window.document.getElementById("ignoreWarningButton");
- ok(!getmeout_button, "GetMeOut button not present");
- ok(!ignorewarning_button, "IgnoreWarning button not present");
-}
-
-add_task(function* testNormalBrowsing() {
- tabbrowser = gBrowser;
- let tab = tabbrowser.selectedTab = tabbrowser.addTab();
-
- info("Load a test page that's whitelisted");
- Services.prefs.setCharPref(PREF_WHITELISTED_HOSTNAMES, "example.com,www.ItIsaTrap.org,example.net");
- yield promiseTabLoadEvent(tab, TEST_PAGE, "load");
- testWhitelistedPage(tab.ownerGlobal);
-
- info("Load a test page that's no longer whitelisted");
- Services.prefs.setCharPref(PREF_WHITELISTED_HOSTNAMES, "");
- yield promiseTabLoadEvent(tab, TEST_PAGE, "AboutBlockedLoaded");
- testBlockedPage(tab.ownerGlobal);
-});
diff --git a/browser/components/safebrowsing/content/test/head.js b/browser/components/safebrowsing/content/test/head.js
deleted file mode 100644
index 90eef0a3f..000000000
--- a/browser/components/safebrowsing/content/test/head.js
+++ /dev/null
@@ -1,55 +0,0 @@
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-
-/**
- * Waits for a load (or custom) event to finish in a given tab. If provided
- * load an uri into the tab.
- *
- * @param tab
- * The tab to load into.
- * @param [optional] url
- * The url to load, or the current url.
- * @param [optional] event
- * The load event type to wait for. Defaults to "load".
- * @return {Promise} resolved when the event is handled.
- * @resolves to the received event
- * @rejects if a valid load event is not received within a meaningful interval
- */
-function promiseTabLoadEvent(tab, url, eventType="load")
-{
- info(`Wait tab event: ${eventType}`);
-
- function handle(loadedUrl) {
- if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
- info(`Skipping spurious load event for ${loadedUrl}`);
- return false;
- }
-
- info("Tab event received: load");
- return true;
- }
-
- let loaded;
- if (eventType === "load") {
- loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
- } else {
- // No need to use handle.
- loaded =
- BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, eventType,
- true, undefined, true);
- }
-
- if (url)
- BrowserTestUtils.loadURI(tab.linkedBrowser, url);
-
- return loaded;
-}
-
-Services.prefs.setCharPref("urlclassifier.malwareTable", "test-malware-simple,test-unwanted-simple");
-Services.prefs.setCharPref("urlclassifier.phishTable", "test-phish-simple");
-Services.prefs.setCharPref("urlclassifier.blockedTable", "test-block-simple");
-SafeBrowsing.init();
diff --git a/browser/components/search/moz.build b/browser/components/search/moz.build
index 618cd7657..aac3a838c 100644
--- a/browser/components/search/moz.build
+++ b/browser/components/search/moz.build
@@ -4,11 +4,4 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser.ini',
-]
-
JAR_MANIFESTS += ['jar.mn']
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Search')
diff --git a/browser/components/search/test/.eslintrc.js b/browser/components/search/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/search/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/search/test/426329.xml b/browser/components/search/test/426329.xml
deleted file mode 100644
index e4545cc77..000000000
--- a/browser/components/search/test/426329.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
- xmlns:moz="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Bug 426329</ShortName>
- <Description>426329 Search</Description>
- <InputEncoding>utf-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/test.html">
- <Param name="test" value="{searchTerms}"/>
- </Url>
- <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/test.html</moz:SearchForm>
-</OpenSearchDescription>
diff --git a/browser/components/search/test/483086-1.xml b/browser/components/search/test/483086-1.xml
deleted file mode 100644
index 9dbba4886..000000000
--- a/browser/components/search/test/483086-1.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
- xmlns:moz="http://www.mozilla.org/2006/browser/search/">
- <ShortName>483086a</ShortName>
- <Description>Bug 483086 Test 1</Description>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
- <Param name="test" value="{searchTerms}"/>
- </Url>
- <moz:SearchForm>foo://example.com</moz:SearchForm>
-</OpenSearchDescription>
diff --git a/browser/components/search/test/483086-2.xml b/browser/components/search/test/483086-2.xml
deleted file mode 100644
index f130b9068..000000000
--- a/browser/components/search/test/483086-2.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
- xmlns:moz="http://www.mozilla.org/2006/browser/search/">
- <ShortName>483086b</ShortName>
- <Description>Bug 483086 Test 2</Description>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
- <Param name="test" value="{searchTerms}"/>
- </Url>
- <moz:SearchForm>http://example.com</moz:SearchForm>
-</OpenSearchDescription>
diff --git a/browser/components/search/test/browser.ini b/browser/components/search/test/browser.ini
deleted file mode 100644
index f1070264d..000000000
--- a/browser/components/search/test/browser.ini
+++ /dev/null
@@ -1,44 +0,0 @@
-[DEFAULT]
-support-files =
- 426329.xml
- 483086-1.xml
- 483086-2.xml
- head.js
- opensearch.html
- test.html
- testEngine.xml
- testEngine_diacritics.xml
- testEngine_dupe.xml
- testEngine_mozsearch.xml
- webapi.html
-
-[browser_426329.js]
-[browser_483086.js]
-[browser_addEngine.js]
-[browser_amazon.js]
-[browser_amazon_behavior.js]
-[browser_bing.js]
-[browser_bing_behavior.js]
-[browser_contextmenu.js]
-[browser_contextSearchTabPosition.js]
-skip-if = os == "mac" # bug 967013
-[browser_google.js]
-[browser_google_codes.js]
-[browser_google_behavior.js]
-[browser_healthreport.js]
-[browser_hiddenOneOffs_cleanup.js]
-[browser_hiddenOneOffs_diacritics.js]
-[browser_oneOffContextMenu.js]
-[browser_oneOffContextMenu_setDefault.js]
-[browser_oneOffHeader.js]
-[browser_private_search_perwindowpb.js]
-[browser_yahoo.js]
-[browser_yahoo_behavior.js]
-[browser_abouthome_behavior.js]
-skip-if = true # Bug ??????, Bug 1100301 - leaks windows until shutdown when --run-by-dir
-[browser_aboutSearchReset.js]
-[browser_searchbar_openpopup.js]
-skip-if = os == "linux" # Linux has different focus behaviours.
-[browser_searchbar_keyboard_navigation.js]
-[browser_searchbar_smallpanel_keyboard_navigation.js]
-[browser_webapi.js]
diff --git a/browser/components/search/test/browser_426329.js b/browser/components/search/test/browser_426329.js
deleted file mode 100644
index d9cbd3f7a..000000000
--- a/browser/components/search/test/browser_426329.js
+++ /dev/null
@@ -1,250 +0,0 @@
-XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
- "resource://gre/modules/FormHistory.jsm");
-
-function expectedURL(aSearchTerms) {
- const ENGINE_HTML_BASE = "http://mochi.test:8888/browser/browser/components/search/test/test.html";
- var textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"].
- getService(Ci.nsITextToSubURI);
- var searchArg = textToSubURI.ConvertAndEscape("utf-8", aSearchTerms);
- return ENGINE_HTML_BASE + "?test=" + searchArg;
-}
-
-function simulateClick(aEvent, aTarget) {
- var event = document.createEvent("MouseEvent");
- var ctrlKeyArg = aEvent.ctrlKey || false;
- var altKeyArg = aEvent.altKey || false;
- var shiftKeyArg = aEvent.shiftKey || false;
- var metaKeyArg = aEvent.metaKey || false;
- var buttonArg = aEvent.button || 0;
- event.initMouseEvent("click", true, true, window,
- 0, 0, 0, 0, 0,
- ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg,
- buttonArg, null);
- aTarget.dispatchEvent(event);
-}
-
-// modified from toolkit/components/satchel/test/test_form_autocomplete.html
-function checkMenuEntries(expectedValues) {
- var actualValues = getMenuEntries();
- is(actualValues.length, expectedValues.length, "Checking length of expected menu");
- for (var i = 0; i < expectedValues.length; i++)
- is(actualValues[i], expectedValues[i], "Checking menu entry #" + i);
-}
-
-function getMenuEntries() {
- var entries = [];
- var autocompleteMenu = searchBar.textbox.popup;
- // Could perhaps pull values directly from the controller, but it seems
- // more reliable to test the values that are actually in the tree?
- var column = autocompleteMenu.tree.columns[0];
- var numRows = autocompleteMenu.tree.view.rowCount;
- for (var i = 0; i < numRows; i++) {
- entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
- }
- return entries;
-}
-
-function countEntries(name, value) {
- return new Promise(resolve => {
- let count = 0;
- let obj = name && value ? {fieldname: name, value: value} : {};
- FormHistory.count(obj,
- { handleResult: function(result) { count = result; },
- handleError: function(error) { throw error; },
- handleCompletion: function(reason) {
- if (!reason) {
- resolve(count);
- }
- }
- });
- });
-}
-
-var searchBar;
-var searchButton;
-var searchEntries = ["test"];
-function promiseSetEngine() {
- return new Promise(resolve => {
- var ss = Services.search;
-
- function observer(aSub, aTopic, aData) {
- switch (aData) {
- case "engine-added":
- var engine = ss.getEngineByName("Bug 426329");
- ok(engine, "Engine was added.");
- ss.currentEngine = engine;
- break;
- case "engine-current":
- ok(ss.currentEngine.name == "Bug 426329", "currentEngine set");
- searchBar = BrowserSearch.searchBar;
- searchButton = document.getAnonymousElementByAttribute(searchBar,
- "anonid", "search-go-button");
- ok(searchButton, "got search-go-button");
- searchBar.value = "test";
-
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- resolve();
- break;
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/426329.xml",
- null, "data:image/x-icon,%00", false);
- });
-}
-
-function promiseRemoveEngine() {
- return new Promise(resolve => {
- var ss = Services.search;
-
- function observer(aSub, aTopic, aData) {
- if (aData == "engine-removed") {
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- resolve();
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- var engine = ss.getEngineByName("Bug 426329");
- ss.removeEngine(engine);
- });
-}
-
-
-var preSelectedBrowser;
-var preTabNo;
-function* prepareTest() {
- preSelectedBrowser = gBrowser.selectedBrowser;
- preTabNo = gBrowser.tabs.length;
- searchBar = BrowserSearch.searchBar;
-
- yield SimpleTest.promiseFocus();
-
- if (document.activeElement == searchBar)
- return;
-
- let focusPromise = BrowserTestUtils.waitForEvent(searchBar, "focus");
- gURLBar.focus();
- searchBar.focus();
- yield focusPromise;
-}
-
-add_task(function* testSetupEngine() {
- yield promiseSetEngine();
-});
-
-add_task(function* testReturn() {
- yield* prepareTest();
- EventUtils.synthesizeKey("VK_RETURN", {});
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
-
- is(gBrowser.tabs.length, preTabNo, "Return key did not open new tab");
- is(gBrowser.currentURI.spec, expectedURL(searchBar.value), "testReturn opened correct search page");
-});
-
-add_task(function* testAltReturn() {
- yield* prepareTest();
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- EventUtils.synthesizeKey("VK_RETURN", { altKey: true });
- });
-
- is(gBrowser.tabs.length, preTabNo + 1, "Alt+Return key added new tab");
- is(gBrowser.currentURI.spec, expectedURL(searchBar.value), "testAltReturn opened correct search page");
-});
-
-// Shift key has no effect for now, so skip it
-add_task(function* testShiftAltReturn() {
- return;
- /*
- yield* prepareTest();
-
- let url = expectedURL(searchBar.value);
-
- let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, url);
- EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true, altKey: true });
- yield newTabPromise;
-
- is(gBrowser.tabs.length, preTabNo + 1, "Shift+Alt+Return key added new tab");
- is(gBrowser.currentURI.spec, url, "testShiftAltReturn opened correct search page");
- */
-});
-
-add_task(function* testLeftClick() {
- yield* prepareTest();
- simulateClick({ button: 0 }, searchButton);
- yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- is(gBrowser.tabs.length, preTabNo, "LeftClick did not open new tab");
- is(gBrowser.currentURI.spec, expectedURL(searchBar.value), "testLeftClick opened correct search page");
-});
-
-add_task(function* testMiddleClick() {
- yield* prepareTest();
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- simulateClick({ button: 1 }, searchButton);
- });
- is(gBrowser.tabs.length, preTabNo + 1, "MiddleClick added new tab");
- is(gBrowser.currentURI.spec, expectedURL(searchBar.value), "testMiddleClick opened correct search page");
-});
-
-add_task(function* testShiftMiddleClick() {
- yield* prepareTest();
-
- let url = expectedURL(searchBar.value);
-
- let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, url);
- simulateClick({ button: 1, shiftKey: true }, searchButton);
- let newTab = yield newTabPromise;
-
- is(gBrowser.tabs.length, preTabNo + 1, "Shift+MiddleClick added new tab");
- is(newTab.linkedBrowser.currentURI.spec, url, "testShiftMiddleClick opened correct search page");
-});
-
-add_task(function* testRightClick() {
- preTabNo = gBrowser.tabs.length;
- gBrowser.selectedBrowser.loadURI("about:blank");
- yield new Promise(resolve => {
- setTimeout(function() {
- is(gBrowser.tabs.length, preTabNo, "RightClick did not open new tab");
- is(gBrowser.currentURI.spec, "about:blank", "RightClick did nothing");
- resolve();
- }, 5000);
- simulateClick({ button: 2 }, searchButton);
- });
- // The click in the searchbox focuses it, which opens the suggestion
- // panel. Clean up after ourselves.
- searchBar.textbox.popup.hidePopup();
-});
-
-add_task(function* testSearchHistory() {
- var textbox = searchBar._textbox;
- for (var i = 0; i < searchEntries.length; i++) {
- let count = yield countEntries(textbox.getAttribute("autocompletesearchparam"), searchEntries[i]);
- ok(count > 0, "form history entry '" + searchEntries[i] + "' should exist");
- }
-});
-
-add_task(function* testAutocomplete() {
- var popup = searchBar.textbox.popup;
- let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
- searchBar.textbox.showHistoryPopup();
- yield popupShownPromise;
- checkMenuEntries(searchEntries);
-});
-
-add_task(function* testClearHistory() {
- let controller = searchBar.textbox.controllers.getControllerForCommand("cmd_clearhistory")
- ok(controller.isCommandEnabled("cmd_clearhistory"), "Clear history command enabled");
- controller.doCommand("cmd_clearhistory");
- let count = yield countEntries();
- ok(count == 0, "History cleared");
-});
-
-add_task(function* asyncCleanup() {
- searchBar.value = "";
- while (gBrowser.tabs.length != 1) {
- gBrowser.removeTab(gBrowser.tabs[0], {animate: false});
- }
- gBrowser.selectedBrowser.loadURI("about:blank");
- yield promiseRemoveEngine();
-});
diff --git a/browser/components/search/test/browser_483086.js b/browser/components/search/test/browser_483086.js
deleted file mode 100644
index 208add867..000000000
--- a/browser/components/search/test/browser_483086.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-var gSS = Services.search;
-
-function test() {
- waitForExplicitFinish();
-
- function observer(aSubject, aTopic, aData) {
- switch (aData) {
- case "engine-added":
- let engine = gSS.getEngineByName("483086a");
- ok(engine, "Test engine 1 installed");
- isnot(engine.searchForm, "foo://example.com",
- "Invalid SearchForm URL dropped");
- gSS.removeEngine(engine);
- break;
- case "engine-removed":
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- test2();
- break;
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/483086-1.xml",
- null, "data:image/x-icon;%00", false);
-}
-
-function test2() {
- function observer(aSubject, aTopic, aData) {
- switch (aData) {
- case "engine-added":
- let engine = gSS.getEngineByName("483086b");
- ok(engine, "Test engine 2 installed");
- is(engine.searchForm, "http://example.com", "SearchForm is correct");
- gSS.removeEngine(engine);
- break;
- case "engine-removed":
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- finish();
- break;
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/483086-2.xml",
- null, "data:image/x-icon;%00", false);
-}
diff --git a/browser/components/search/test/browser_aboutSearchReset.js b/browser/components/search/test/browser_aboutSearchReset.js
deleted file mode 100644
index 64376d6da..000000000
--- a/browser/components/search/test/browser_aboutSearchReset.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const TELEMETRY_RESULT_ENUM = {
- RESTORED_DEFAULT: 0,
- KEPT_CURRENT: 1,
- CHANGED_ENGINE: 2,
- CLOSED_PAGE: 3,
- OPENED_SETTINGS: 4
-};
-
-const kSearchStr = "a search";
-const kSearchPurpose = "searchbar";
-
-const kTestEngine = "testEngine.xml";
-
-function checkTelemetryRecords(expectedValue) {
- let histogram = Services.telemetry.getHistogramById("SEARCH_RESET_RESULT");
- let snapshot = histogram.snapshot();
- // The probe is declared with 5 values, but we get 6 back from .counts
- let expectedCounts = [0, 0, 0, 0, 0, 0];
- if (expectedValue != null) {
- expectedCounts[expectedValue] = 1;
- }
- Assert.deepEqual(snapshot.counts, expectedCounts,
- "histogram has expected content");
- histogram.clear();
-}
-
-function promiseStoppedLoad(expectedURL) {
- return new Promise(resolve => {
- let browser = gBrowser.selectedBrowser;
- let original = browser.loadURIWithFlags;
- browser.loadURIWithFlags = function(URI) {
- if (URI == expectedURL) {
- browser.loadURIWithFlags = original;
- ok(true, "loaded expected url: " + URI);
- resolve();
- return;
- }
-
- original.apply(browser, arguments);
- };
- });
-}
-
-var gTests = [
-
-{
- desc: "Test the 'Keep Current Settings' button.",
- run: function* () {
- let engine = yield promiseNewEngine(kTestEngine, {setAsCurrent: true});
-
- let expectedURL = engine.
- getSubmission(kSearchStr, null, kSearchPurpose).
- uri.spec;
-
- let rawEngine = engine.wrappedJSObject;
- let initialHash = rawEngine.getAttr("loadPathHash");
- rawEngine.setAttr("loadPathHash", "broken");
-
- let loadPromise = promiseStoppedLoad(expectedURL);
- gBrowser.contentDocument.getElementById("searchResetKeepCurrent").click();
- yield loadPromise;
-
- is(engine, Services.search.currentEngine,
- "the custom engine is still default");
- is(rawEngine.getAttr("loadPathHash"), initialHash,
- "the loadPathHash has been fixed");
-
- checkTelemetryRecords(TELEMETRY_RESULT_ENUM.KEPT_CURRENT);
- }
-},
-
-{
- desc: "Test the 'Restore Search Defaults' button.",
- run: function* () {
- let currentEngine = Services.search.currentEngine;
- let originalEngine = Services.search.originalDefaultEngine;
- let doc = gBrowser.contentDocument;
- let defaultEngineSpan = doc.getElementById("defaultEngine");
- is(defaultEngineSpan.textContent, originalEngine.name,
- "the name of the original default engine is displayed");
-
- let expectedURL = originalEngine.
- getSubmission(kSearchStr, null, kSearchPurpose).
- uri.spec;
- let loadPromise = promiseStoppedLoad(expectedURL);
- let button = doc.getElementById("searchResetChangeEngine");
- is(doc.activeElement, button,
- "the 'Change Search Engine' button is focused");
- button.click();
- yield loadPromise;
-
- is(originalEngine, Services.search.currentEngine,
- "the default engine is back to the original one");
-
- checkTelemetryRecords(TELEMETRY_RESULT_ENUM.RESTORED_DEFAULT);
- Services.search.currentEngine = currentEngine;
- }
-},
-
-{
- desc: "Click the settings link.",
- run: function* () {
- let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser,
- false,
- "about:preferences#search")
- gBrowser.contentDocument.getElementById("linkSettingsPage").click();
- yield loadPromise;
-
- checkTelemetryRecords(TELEMETRY_RESULT_ENUM.OPENED_SETTINGS);
- }
-},
-
-{
- desc: "Load another page without clicking any of the buttons.",
- run: function* () {
- yield promiseTabLoadEvent(gBrowser.selectedTab, "about:mozilla");
-
- checkTelemetryRecords(TELEMETRY_RESULT_ENUM.CLOSED_PAGE);
- }
-},
-
-];
-
-function test()
-{
- waitForExplicitFinish();
- Task.spawn(function* () {
- let oldCanRecord = Services.telemetry.canRecordExtended;
- Services.telemetry.canRecordExtended = true;
- checkTelemetryRecords();
-
- for (let test of gTests) {
- info(test.desc);
-
- // Create a tab to run the test.
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
-
- // Start loading about:searchreset and wait for it to complete.
- let url = "about:searchreset?data=" + encodeURIComponent(kSearchStr) +
- "&purpose=" + kSearchPurpose;
- yield promiseTabLoadEvent(tab, url);
-
- info("Running test");
- yield test.run();
-
- info("Cleanup");
- gBrowser.removeCurrentTab();
- }
-
- Services.telemetry.canRecordExtended = oldCanRecord;
- }).then(finish, ex => {
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
-}
diff --git a/browser/components/search/test/browser_abouthome_behavior.js b/browser/components/search/test/browser_abouthome_behavior.js
deleted file mode 100644
index 3291b41f4..000000000
--- a/browser/components/search/test/browser_abouthome_behavior.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test home page search for all plugin URLs
- */
-
-"use strict";
-
-function test() {
- // Bug 992270: Ignore uncaught about:home exceptions (related to snippets from IndexedDB)
- ignoreAllUncaughtExceptions(true);
-
- let previouslySelectedEngine = Services.search.currentEngine;
-
- function replaceUrl(base) {
- return base;
- }
-
- let gMutationObserver = null;
-
- function verify_about_home_search(engine_name) {
- let engine = Services.search.getEngineByName(engine_name);
- ok(engine, engine_name + " is installed");
-
- Services.search.currentEngine = engine;
-
- // load about:home, but remove the listener first so it doesn't
- // get in the way
- gBrowser.removeProgressListener(listener);
- gBrowser.loadURI("about:home");
- info("Waiting for about:home load");
- tab.linkedBrowser.addEventListener("load", function load(event) {
- if (event.originalTarget != tab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank") {
- info("skipping spurious load event");
- return;
- }
- tab.linkedBrowser.removeEventListener("load", load, true);
-
- // Observe page setup
- let doc = gBrowser.contentDocument;
- gMutationObserver = new MutationObserver(function (mutations) {
- for (let mutation of mutations) {
- if (mutation.attributeName == "searchEngineName") {
- // Re-add the listener, and perform a search
- gBrowser.addProgressListener(listener);
- gMutationObserver.disconnect()
- gMutationObserver = null;
- executeSoon(function() {
- doc.getElementById("searchText").value = "foo";
- doc.getElementById("searchSubmit").click();
- });
- }
- }
- });
- gMutationObserver.observe(doc.documentElement, { attributes: true });
- }, true);
- }
- waitForExplicitFinish();
-
- let gCurrTest;
- let gTests = [
- {
- name: "Search with Bing from about:home",
- searchURL: replaceUrl("http://www.bing.com/search?q=foo&pc=MOZI&form=MOZSPG"),
- run: function () {
- verify_about_home_search("Bing");
- }
- },
- {
- name: "Search with Yahoo from about:home",
- searchURL: replaceUrl("https://search.yahoo.com/search?p=foo&ei=UTF-8&fr=moz35"),
- run: function () {
- verify_about_home_search("Yahoo");
- }
- },
- {
- name: "Search with Google from about:home",
- searchURL: replaceUrl("https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"),
- run: function () {
- verify_about_home_search("Google");
- }
- },
- {
- name: "Search with Amazon.com from about:home",
- searchURL: replaceUrl("https://www.amazon.com/exec/obidos/external-search/?field-keywords=foo&mode=blended&tag=mozilla-20&sourceid=Mozilla-search"),
- run: function () {
- verify_about_home_search("Amazon.com");
- }
- }
- ];
-
- function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- info("Running : " + gCurrTest.name);
- executeSoon(gCurrTest.run);
- } else {
- // Make sure we listen again for uncaught exceptions in the next test or cleanup.
- executeSoon(finish);
- }
- }
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let listener = {
- onStateChange: function onStateChange(webProgress, req, flags, status) {
- info("onStateChange");
- // Only care about top-level document starts
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if (!(flags & docStart) || !webProgress.isTopLevel)
- return;
-
- if (req.originalURI.spec == "about:blank")
- return;
-
- info("received document start");
-
- ok(req instanceof Ci.nsIChannel, "req is a channel");
- is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
- info("Actual URI: " + req.URI.spec);
-
- req.cancel(Components.results.NS_ERROR_FAILURE);
-
- executeSoon(nextTest);
- }
- }
-
- 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);
- gBrowser.addProgressListener(listener);
- nextTest();
- }, true);
-}
diff --git a/browser/components/search/test/browser_addEngine.js b/browser/components/search/test/browser_addEngine.js
deleted file mode 100644
index b971ea5f7..000000000
--- a/browser/components/search/test/browser_addEngine.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-var gSS = Services.search;
-
-function observer(aSubject, aTopic, aData) {
- if (!gCurrentTest) {
- info("Observer called with no test active");
- return;
- }
-
- let engine = aSubject.QueryInterface(Ci.nsISearchEngine);
- info("Observer: " + aData + " for " + engine.name);
- let method;
- switch (aData) {
- case "engine-added":
- if (gCurrentTest.added)
- method = "added"
- break;
- case "engine-current":
- if (gCurrentTest.current)
- method = "current";
- break;
- case "engine-removed":
- if (gCurrentTest.removed)
- method = "removed";
- break;
- }
-
- if (method)
- gCurrentTest[method](engine);
-}
-
-function checkEngine(checkObj, engineObj) {
- info("Checking engine");
- for (var prop in checkObj)
- is(checkObj[prop], engineObj[prop], prop + " is correct");
-}
-
-var gTests = [
- {
- name: "opensearch install",
- engine: {
- name: "Foo",
- alias: null,
- description: "Foo Search",
- searchForm: "http://mochi.test:8888/browser/browser/components/search/test/"
- },
- run: function () {
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
-
- gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
- null, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
- false);
- },
- added: function (engine) {
- ok(engine, "engine was added.");
-
- checkEngine(this.engine, engine);
-
- let engineFromSS = gSS.getEngineByName(this.engine.name);
- is(engine, engineFromSS, "engine is obtainable via getEngineByName");
-
- let aEngine = gSS.getEngineByAlias("fooalias");
- ok(!aEngine, "Alias was not parsed from engine description");
-
- gSS.currentEngine = engine;
- },
- current: function (engine) {
- let currentEngine = gSS.currentEngine;
- is(engine, currentEngine, "engine is current");
- is(engine.name, this.engine.name, "current engine was changed successfully");
-
- gSS.removeEngine(engine);
- },
- removed: function (engine) {
- // Remove the observer before calling the currentEngine getter,
- // as that getter will set the currentEngine to the original default
- // which will trigger a notification causing the test to loop over all
- // engines.
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
-
- let currentEngine = gSS.currentEngine;
- ok(currentEngine, "An engine is present.");
- isnot(currentEngine.name, this.engine.name, "Current engine reset after removal");
-
- nextTest();
- }
- }
-];
-
-var gCurrentTest = null;
-function nextTest() {
- if (gTests.length) {
- gCurrentTest = gTests.shift();
- info("Running " + gCurrentTest.name);
- gCurrentTest.run();
- } else
- executeSoon(finish);
-}
-
-function test() {
- waitForExplicitFinish();
- nextTest();
-}
diff --git a/browser/components/search/test/browser_amazon.js b/browser/components/search/test/browser_amazon.js
deleted file mode 100644
index 965a3dcf8..000000000
--- a/browser/components/search/test/browser_amazon.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Amazon search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-function test() {
- let engine = Services.search.getEngineByName("Amazon.com");
- ok(engine, "Amazon.com");
-
- let base = "https://www.amazon.com/exec/obidos/external-search/?field-keywords=foo&ie=UTF-8&mode=blended&tag=mozilla-20&sourceid=Mozilla-search";
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base, "Check search URL for 'foo'");
-
- // Check search suggestion URL.
- url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
- is(url, "https://completion.amazon.com/search/complete?q=foo&search-alias=aps&mkt=1", "Check search suggestion URL for 'foo'");
-
- // Check all other engine properties.
- const EXPECTED_ENGINE = {
- name: "Amazon.com",
- alias: null,
- description: "Amazon.com Search",
- searchForm: "https://www.amazon.com/exec/obidos/external-search/?field-keywords=&ie=UTF-8&mode=blended&tag=mozilla-20&sourceid=Mozilla-search",
- hidden: false,
- wrappedJSObject: {
- queryCharset: "UTF-8",
- "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==",
- _urls : [
- {
- type: "application/x-suggestions+json",
- method: "GET",
- template: "https://completion.amazon.com/search/complete?q={searchTerms}&search-alias=aps&mkt=1",
- params: "",
- },
- {
- type: "text/html",
- method: "GET",
- template: "https://www.amazon.com/exec/obidos/external-search/",
- params: [
- {
- name: "field-keywords",
- value: "{searchTerms}",
- purpose: undefined,
- },
- {
- name: "ie",
- value: "{inputEncoding}",
- purpose: undefined,
- },
- {
- name: "mode",
- value: "blended",
- purpose: undefined,
- },
- {
- name: "tag",
- value: "mozilla-20",
- purpose: undefined,
- },
- {
- name: "sourceid",
- value: "Mozilla-search",
- purpose: undefined,
- },
- ],
- mozparams: {},
- },
- ],
- },
- };
-
- isSubObjectOf(EXPECTED_ENGINE, engine, "Amazon");
-}
diff --git a/browser/components/search/test/browser_amazon_behavior.js b/browser/components/search/test/browser_amazon_behavior.js
deleted file mode 100644
index 22d16581a..000000000
--- a/browser/components/search/test/browser_amazon_behavior.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Amazon search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-
-function test() {
- let engine = Services.search.getEngineByName("Amazon.com");
- ok(engine, "Amazon is installed");
-
- let previouslySelectedEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- engine.alias = "a";
-
- let base = "https://www.amazon.com/exec/obidos/external-search/?field-keywords=foo&ie=UTF-8&mode=blended&tag=mozilla-20&sourceid=Mozilla-search";
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base, "Check search URL for 'foo'");
-
- waitForExplicitFinish();
-
- var gCurrTest;
- var gTests = [
- {
- name: "context menu search",
- searchURL: base,
- run: function () {
- // Simulate a contextmenu search
- // FIXME: This is a bit "low-level"...
- BrowserSearch.loadSearch("foo", false, "contextmenu");
- }
- },
- {
- name: "keyword search",
- searchURL: base,
- run: function () {
- gURLBar.value = "? foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "keyword search",
- searchURL: base,
- run: function () {
- gURLBar.value = "a foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "search bar search",
- searchURL: base,
- run: function () {
- let sb = BrowserSearch.searchBar;
- sb.focus();
- sb.value = "foo";
- registerCleanupFunction(function () {
- sb.value = "";
- });
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "new tab search",
- searchURL: base,
- run: function () {
- function doSearch(doc) {
- // Re-add the listener, and perform a search
- gBrowser.addProgressListener(listener);
- doc.getElementById("newtab-search-text").value = "foo";
- doc.getElementById("newtab-search-submit").click();
- }
-
- // load about:newtab, but remove the listener first so it doesn't
- // get in the way
- gBrowser.removeProgressListener(listener);
- gBrowser.loadURI("about:newtab");
- info("Waiting for about:newtab load");
- tab.linkedBrowser.addEventListener("load", function load(event) {
- if (event.originalTarget != tab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank") {
- info("skipping spurious load event");
- return;
- }
- tab.linkedBrowser.removeEventListener("load", load, true);
-
- // Observe page setup
- let win = gBrowser.contentWindow;
- if (win.gSearch.currentEngineName ==
- Services.search.currentEngine.name) {
- doSearch(win.document);
- }
- else {
- info("Waiting for newtab search init");
- win.addEventListener("ContentSearchService", function done(event) {
- info("Got newtab search event " + event.detail.type);
- if (event.detail.type == "State") {
- win.removeEventListener("ContentSearchService", done);
- // Let gSearch respond to the event before continuing.
- executeSoon(() => doSearch(win.document));
- }
- });
- }
- }, true);
- }
- }
- ];
-
- function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- info("Running : " + gCurrTest.name);
- executeSoon(gCurrTest.run);
- } else {
- finish();
- }
- }
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let listener = {
- onStateChange: function onStateChange(webProgress, req, flags, status) {
- info("onStateChange");
- // Only care about top-level document starts
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if (!(flags & docStart) || !webProgress.isTopLevel)
- return;
-
- if (req.originalURI.spec == "about:blank")
- return;
-
- info("received document start");
-
- ok(req instanceof Ci.nsIChannel, "req is a channel");
- is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
- info("Actual URI: " + req.URI.spec);
-
- req.cancel(Components.results.NS_ERROR_FAILURE);
-
- executeSoon(nextTest);
- }
- }
-
- 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);
- gBrowser.addProgressListener(listener);
- nextTest();
- }, true);
-}
diff --git a/browser/components/search/test/browser_bing.js b/browser/components/search/test/browser_bing.js
deleted file mode 100644
index 3a41ae0ac..000000000
--- a/browser/components/search/test/browser_bing.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Bing search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-function test() {
- let engine = Services.search.getEngineByName("Bing");
- ok(engine, "Bing");
-
- let base = "https://www.bing.com/search?q=foo&pc=MOZI";
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base + "&form=MOZSBR", "Check search URL for 'foo'");
- url = engine.getSubmission("foo", null, "contextmenu").uri.spec;
- is(url, base + "&form=MOZCON", "Check context menu search URL for 'foo'");
- url = engine.getSubmission("foo", null, "keyword").uri.spec;
- is(url, base + "&form=MOZLBR", "Check keyword search URL for 'foo'");
- url = engine.getSubmission("foo", null, "searchbar").uri.spec;
- is(url, base + "&form=MOZSBR", "Check search bar search URL for 'foo'");
- url = engine.getSubmission("foo", null, "homepage").uri.spec;
- is(url, base + "&form=MOZSPG", "Check homepage search URL for 'foo'");
- url = engine.getSubmission("foo", null, "newtab").uri.spec;
- is(url, base + "&form=MOZTSB", "Check newtab search URL for 'foo'");
-
- // Check search suggestion URL.
- url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
- is(url, "https://www.bing.com/osjson.aspx?query=foo&form=OSDJAS&language=" + getLocale(), "Check search suggestion URL for 'foo'");
-
- // Check all other engine properties.
- const EXPECTED_ENGINE = {
- name: "Bing",
- alias: null,
- description: "Bing. Search by Microsoft.",
- searchForm: "https://www.bing.com/search?q=&pc=MOZI&form=MOZSBR",
- hidden: false,
- wrappedJSObject: {
- queryCharset: "UTF-8",
- "_iconURL": "data:image/x-icon;base64,AAABAAIAICAAAAEACACoCAAAJgAAABAQAAABAAgAaAUAAM4IAAAoAAAAIAAAAEAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAABAAAAAAAAhIQMAI+PIwCXlzEAn59BAKioUwCurl8AtbVuAL6+fwDJyZMA0tKlANjYsgDe3r4A5eXMAOzs2QDy8uUA+fnzAP///wAAGi8AAC1QAAA/cAAAUZAAAGOwAAB2zwAAiPAAEZj/ADGm/wBRs/8AccH/AJHP/wCx3f8A0ev/AP///wAAAAAAACwvAABLUAAAaHAAAIaQAAClsAAAw88AAOHwABHv/wAx8f8AUfP/AHH1/wCR9/8Asfn/ANH7/wD///8AAAAAAAAvIQAAUDcAAHBMAACQYwAAsHkAAM+PAADwpgAR/7QAMf++AFH/yABx/9MAkf/cALH/5QDR//AA////AAAAAAAALw4AAFAYAABwIgAAkCwAALA2AADPQAAA8EoAEf9bADH/cQBR/4cAcf+dAJH/sgCx/8kA0f/fAP///wAAAAAAAi8AAARQAAAGcAAACJAAAAqwAAALzwAADvAAACD/EgA9/zEAW/9RAHn/cQCY/5EAtf+xANT/0QD///8AAAAAABQvAAAiUAAAMHAAAD2QAABMsAAAWc8AAGfwAAB4/xEAiv8xAJz/UQCu/3EAwP+RANL/sQDk/9EA////AAAAAAAmLwAAQFAAAFpwAAB0kAAAjrAAAKnPAADC8AAA0f8RANj/MQDe/1EA4/9xAOn/kQDv/7EA9v/RAP///wAAAAAALyYAAFBBAABwWwAAkHQAALCOAADPqQAA8MMAAP/SEQD/2DEA/91RAP/kcQD/6pEA//CxAP/20QD///8AAAAAAC8UAABQIgAAcDAAAJA+AACwTQAAz1sAAPBpAAD/eREA/4oxAP+dUQD/r3EA/8GRAP/SsQD/5dEA////AAAAAAAvAwAAUAQAAHAGAACQCQAAsAoAAM8MAADwDgAA/yASAP8+MQD/XFEA/3pxAP+XkQD/trEA/9TRAP///wAAAAAALwAOAFAAFwBwACEAkAArALAANgDPAEAA8ABJAP8RWgD/MXAA/1GGAP9xnAD/kbIA/7HIAP/R3wD///8AAAAAAC8AIABQADYAcABMAJAAYgCwAHgAzwCOAPAApAD/EbMA/zG+AP9RxwD/cdEA/5HcAP+x5QD/0fAA////AAAAAAAsAC8ASwBQAGkAcACHAJAApQCwAMQAzwDhAPAA8BH/APIx/wD0Uf8A9nH/APeR/wD5sf8A+9H/AP///wAAAAAAGwAvAC0AUAA/AHAAUgCQAGMAsAB2AM8AiADwAJkR/wCmMf8AtFH/AMJx/wDPkf8A3LH/AOvR/wD///8AAAAAAAgALwAOAFAAFQBwABsAkAAhALAAJgDPACwA8AA+Ef8AWDH/AHFR/wCMcf8AppH/AL+x/wDa0f8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBggCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAsQEA0HAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwkPEBAQEBALBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMEBAQEBAQEBAPCQMAAAAAAAAAAAAAAAAAAAAAAAAAAQ0QEBAQEBAQEBAQDQgBAAAAAAAAAAAAAAAAAAAAAAABDRAQEBAQEBAQEBAQEA0GAQAAAAAAAAAAAAAAAAAAAAENEBAQDgcLEBAQEBAQEBALBAAAAAAAAAAAAAAAAAAAAQ0QEBANAQEHDRAQEBAQEBAOCAAAAAAAAAAAAAAAAAABDRAQEA4BAAACCA4QEBAQEBANAQAAAAAAAAAAAAAAAAENEBAQDgEAAAAABAsQEBAQEA0BAAAAAAAAAAAAAAAAAQ0QEBAOAQAAAAABBw4QEBAQDQEAAAAAAAAAAAAAAAABDRAQEA4BAAABBw0QEBAQEBANAQAAAAAAAAAAAAAAAAENEBAQDgEAAAcQEBAQEBAQEA0BAAAAAAAAAAAAAAAAAQ0QEBAOAQABCxAQEBAQEBANBwAAAAAAAAAAAAAAAAABDRAQEA4BAAQPEBAQEA0IBAEAAAAAAAAAAAAAAAAAAAENEBAQDgEACRAQDQkGAQAAAAAAAAAAAAAAAAAAAAAAAQ0QEBAOAQILCgYCAAAAAAAAAAAAAAAAAAAAAAAAAAABDRAQEA4BAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENEBAQDgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ0QEBAOAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRAQEA4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENEBAQDgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ0QEBAOAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRAQEA0BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENEA0IBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQcFAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAAAACEhAAAjIwAAJKSFgCZmSgAqqpRALKyYgC+vnsAxsaKAM3NmQDU1KgA4ODBAOjozwDw8OEA+fnyAP///wD///8AAAAAAAAaLwAALVAAAD9wAABRkAAAY7AAAHbPAACI8AARmP8AMab/AFGz/wBxwf8Akc//ALHd/wDR6/8A////AAAAAAAALC8AAEtQAABocAAAhpAAAKWwAADDzwAA4fAAEe//ADHx/wBR8/8AcfX/AJH3/wCx+f8A0fv/AP///wAAAAAAAC8hAABQNwAAcEwAAJBjAACweQAAz48AAPCmABH/tAAx/74AUf/IAHH/0wCR/9wAsf/lANH/8AD///8AAAAAAAAvDgAAUBgAAHAiAACQLAAAsDYAAM9AAADwSgAR/1sAMf9xAFH/hwBx/50Akf+yALH/yQDR/98A////AAAAAAACLwAABFAAAAZwAAAIkAAACrAAAAvPAAAO8AAAIP8SAD3/MQBb/1EAef9xAJj/kQC1/7EA1P/RAP///wAAAAAAFC8AACJQAAAwcAAAPZAAAEywAABZzwAAZ/AAAHj/EQCK/zEAnP9RAK7/cQDA/5EA0v+xAOT/0QD///8AAAAAACYvAABAUAAAWnAAAHSQAACOsAAAqc8AAMLwAADR/xEA2P8xAN7/UQDj/3EA6f+RAO//sQD2/9EA////AAAAAAAvJgAAUEEAAHBbAACQdAAAsI4AAM+pAADwwwAA/9IRAP/YMQD/3VEA/+RxAP/qkQD/8LEA//bRAP///wAAAAAALxQAAFAiAABwMAAAkD4AALBNAADPWwAA8GkAAP95EQD/ijEA/51RAP+vcQD/wZEA/9KxAP/l0QD///8AAAAAAC8DAABQBAAAcAYAAJAJAACwCgAAzwwAAPAOAAD/IBIA/z4xAP9cUQD/enEA/5eRAP+2sQD/1NEA////AAAAAAAvAA4AUAAXAHAAIQCQACsAsAA2AM8AQADwAEkA/xFaAP8xcAD/UYYA/3GcAP+RsgD/scgA/9HfAP///wAAAAAALwAgAFAANgBwAEwAkABiALAAeADPAI4A8ACkAP8RswD/Mb4A/1HHAP9x0QD/kdwA/7HlAP/R8AD///8AAAAAACwALwBLAFAAaQBwAIcAkAClALAAxADPAOEA8ADwEf8A8jH/APRR/wD2cf8A95H/APmx/wD70f8A////AAAAAAAbAC8ALQBQAD8AcABSAJAAYwCwAHYAzwCIAPAAmRH/AKYx/wC0Uf8AwnH/AM+R/wDcsf8A69H/AP///wAAAAAACAAvAA4AUAAVAHAAGwCQACEAsAAmAM8ALADwAD4R/wBYMf8AcVH/AIxx/wCmkf8Av7H/ANrR/wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMAAAAAAAAAAAAAAAACBgwMBwIAAAAAAAAAAAAABg4ODg4MBgIAAAAAAAAAAAYODQoODg4KBAAAAAAAAAAGDgwDBQsODg4FAAAAAAAABg4MAgADCg4OBgAAAAAAAAYODAICCg4ODgYAAAAAAAAGDgwCBg4OCwcCAAAAAAAABg4MAwkIBAIAAAAAAAAAAAYODAICAAAAAAAAAAAAAAAGDgwCAAAAAAAAAAAAAAAABg4MAgAAAAAAAAAAAAAAAAYMCAEAAAAAAAAAAAAAAAACAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
- _urls : [
- {
- type: "application/x-suggestions+json",
- method: "GET",
- template: "https://www.bing.com/osjson.aspx",
- params: [
- {
- name: "query",
- value: "{searchTerms}",
- purpose: undefined,
- },
- {
- name: "form",
- value: "OSDJAS",
- purpose: undefined,
- },
- {
- name: "language",
- value: "{moz:locale}",
- purpose: undefined,
- },
- ],
- },
- {
- type: "text/html",
- method: "GET",
- template: "https://www.bing.com/search",
- params: [
- {
- name: "q",
- value: "{searchTerms}",
- purpose: undefined,
- },
- {
- name: "pc",
- value: "MOZI",
- purpose: undefined,
- },
- {
- name: "form",
- value: "MOZCON",
- purpose: "contextmenu",
- },
- {
- name: "form",
- value: "MOZSBR",
- purpose: "searchbar",
- },
- {
- name: "form",
- value: "MOZSPG",
- purpose: "homepage",
- },
- {
- name: "form",
- value: "MOZLBR",
- purpose:"keyword",
- },
- {
- name: "form",
- value: "MOZTSB",
- purpose: "newtab",
- },
- ],
- mozparams: {},
- },
- ],
- },
- };
-
- isSubObjectOf(EXPECTED_ENGINE, engine, "Bing");
-}
diff --git a/browser/components/search/test/browser_bing_behavior.js b/browser/components/search/test/browser_bing_behavior.js
deleted file mode 100644
index bc9b187ec..000000000
--- a/browser/components/search/test/browser_bing_behavior.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Bing search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-
-function test() {
- let engine = Services.search.getEngineByName("Bing");
- ok(engine, "Bing is installed");
-
- let previouslySelectedEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- engine.alias = "b";
-
- let base = "https://www.bing.com/search?q=foo&pc=MOZI";
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base + "&form=MOZSBR", "Check search URL for 'foo'");
-
- waitForExplicitFinish();
-
- var gCurrTest;
- var gTests = [
- {
- name: "context menu search",
- searchURL: base + "&form=MOZCON",
- run: function () {
- // Simulate a contextmenu search
- // FIXME: This is a bit "low-level"...
- BrowserSearch.loadSearch("foo", false, "contextmenu");
- }
- },
- {
- name: "keyword search",
- searchURL: base + "&form=MOZLBR",
- run: function () {
- gURLBar.value = "? foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "keyword search with alias",
- searchURL: base + "&form=MOZLBR",
- run: function () {
- gURLBar.value = "b foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "search bar search",
- searchURL: base + "&form=MOZSBR",
- run: function () {
- let sb = BrowserSearch.searchBar;
- sb.focus();
- sb.value = "foo";
- registerCleanupFunction(function () {
- sb.value = "";
- });
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "new tab search",
- searchURL: base + "&form=MOZTSB",
- run: function () {
- function doSearch(doc) {
- // Re-add the listener, and perform a search
- gBrowser.addProgressListener(listener);
- doc.getElementById("newtab-search-text").value = "foo";
- doc.getElementById("newtab-search-submit").click();
- }
-
- // load about:newtab, but remove the listener first so it doesn't
- // get in the way
- gBrowser.removeProgressListener(listener);
- gBrowser.loadURI("about:newtab");
- info("Waiting for about:newtab load");
- tab.linkedBrowser.addEventListener("load", function load(event) {
- if (event.originalTarget != tab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank") {
- info("skipping spurious load event");
- return;
- }
- tab.linkedBrowser.removeEventListener("load", load, true);
-
- // Observe page setup
- let win = gBrowser.contentWindow;
- if (win.gSearch.currentEngineName ==
- Services.search.currentEngine.name) {
- doSearch(win.document);
- }
- else {
- info("Waiting for newtab search init");
- win.addEventListener("ContentSearchService", function done(event) {
- info("Got newtab search event " + event.detail.type);
- if (event.detail.type == "State") {
- win.removeEventListener("ContentSearchService", done);
- // Let gSearch respond to the event before continuing.
- executeSoon(() => doSearch(win.document));
- }
- });
- }
- }, true);
- }
- }
- ];
-
- function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- info("Running : " + gCurrTest.name);
- executeSoon(gCurrTest.run);
- } else {
- finish();
- }
- }
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let listener = {
- onStateChange: function onStateChange(webProgress, req, flags, status) {
- info("onStateChange");
- // Only care about top-level document starts
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if (!(flags & docStart) || !webProgress.isTopLevel)
- return;
-
- if (req.originalURI.spec == "about:blank")
- return;
-
- info("received document start");
-
- ok(req instanceof Ci.nsIChannel, "req is a channel");
- is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
- info("Actual URI: " + req.URI.spec);
-
- req.cancel(Components.results.NS_ERROR_FAILURE);
-
- executeSoon(nextTest);
- }
- }
-
- 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);
- gBrowser.addProgressListener(listener);
- nextTest();
- }, true);
-}
diff --git a/browser/components/search/test/browser_contextSearchTabPosition.js b/browser/components/search/test/browser_contextSearchTabPosition.js
deleted file mode 100644
index 21a8c1130..000000000
--- a/browser/components/search/test/browser_contextSearchTabPosition.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test() {
- yield SpecialPowers.pushPrefEnv({set: [["toolkit.telemetry.enabled", true]]});
- let engine = yield promiseNewEngine("testEngine.xml");
- let histogramKey = "other-" + engine.name + ".contextmenu";
- let numSearchesBefore = 0;
-
- try {
- let hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
- if (histogramKey in hs) {
- numSearchesBefore = hs[histogramKey].sum;
- }
- } catch (ex) {
- // No searches performed yet, not a problem, |numSearchesBefore| is 0.
- }
-
- let tabs = [];
- let tabsLoadedDeferred = new Deferred();
-
- function tabAdded(event) {
- let tab = event.target;
- tabs.push(tab);
-
- // We wait for the blank tab and the two context searches tabs to open.
- if (tabs.length == 3) {
- tabsLoadedDeferred.resolve();
- }
- }
-
- let container = gBrowser.tabContainer;
- container.addEventListener("TabOpen", tabAdded, false);
-
- gBrowser.addTab("about:blank");
- BrowserSearch.loadSearchFromContext("mozilla");
- BrowserSearch.loadSearchFromContext("firefox");
-
- // Wait for all the tabs to open.
- yield tabsLoadedDeferred.promise;
-
- is(tabs[0], gBrowser.tabs[3], "blank tab has been pushed to the end");
- is(tabs[1], gBrowser.tabs[1], "first search tab opens next to the current tab");
- is(tabs[2], gBrowser.tabs[2], "second search tab opens next to the first search tab");
-
- container.removeEventListener("TabOpen", tabAdded, false);
- tabs.forEach(gBrowser.removeTab, gBrowser);
-
- // Make sure that the context searches are correctly recorded.
- let hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
- Assert.ok(histogramKey in hs, "The histogram must contain the correct key");
- Assert.equal(hs[histogramKey].sum, numSearchesBefore + 2,
- "The histogram must contain the correct search count");
-});
-
-function Deferred() {
- this.promise = new Promise((resolve, reject) => {
- this.resolve = resolve;
- this.reject = reject;
- });
-}
diff --git a/browser/components/search/test/browser_contextmenu.js b/browser/components/search/test/browser_contextmenu.js
deleted file mode 100644
index c485242b4..000000000
--- a/browser/components/search/test/browser_contextmenu.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * * http://creativecommons.org/publicdomain/zero/1.0/ */
-/*
- * Test searching for the selected text using the context menu
- */
-
-add_task(function* () {
- const ss = Services.search;
- const ENGINE_NAME = "Foo";
- var contextMenu;
-
- // We want select events to be fired.
- yield new Promise(resolve => SpecialPowers.pushPrefEnv({"set": [["dom.select_events.enabled", true]]}, resolve));
-
- let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
- let originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR");
- envService.set("XPCSHELL_TEST_PROFILE_DIR", "1");
-
- let url = "chrome://mochitests/content/browser/browser/components/search/test/";
- let resProt = Services.io.getProtocolHandler("resource")
- .QueryInterface(Ci.nsIResProtocolHandler);
- let originalSubstitution = resProt.getSubstitution("search-plugins");
- resProt.setSubstitution("search-plugins",
- Services.io.newURI(url, null, null));
-
- let searchDonePromise;
- yield new Promise(resolve => {
- function observer(aSub, aTopic, aData) {
- switch (aData) {
- case "engine-added":
- var engine = ss.getEngineByName(ENGINE_NAME);
- ok(engine, "Engine was added.");
- ss.currentEngine = engine;
- envService.set("XPCSHELL_TEST_PROFILE_DIR", originalValue);
- resProt.setSubstitution("search-plugins", originalSubstitution);
- break;
- case "engine-current":
- is(ss.currentEngine.name, ENGINE_NAME, "currentEngine set");
- resolve();
- break;
- case "engine-removed":
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- if (searchDonePromise) {
- searchDonePromise();
- }
- break;
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- ss.addEngine("resource://search-plugins/testEngine_mozsearch.xml",
- null, "data:image/x-icon,%00", false);
- });
-
- 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);
- resolve();
- });
- 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);
- yield popupPromise;
-
- info("checkContextMenu");
- var searchItem = contextMenu.getElementsByAttribute("id", "context-searchselect")[0];
- ok(searchItem, "Got search context menu item");
- is(searchItem.label, 'Search ' + ENGINE_NAME + ' for \u201ctest search\u201d', "Check context menu label");
- is(searchItem.disabled, false, "Check that search context menu item is enabled");
-
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
- searchItem.click();
- });
-
- is(gBrowser.currentURI.spec,
- "http://mochi.test:8888/browser/browser/components/search/test/?test=test+search&ie=utf-8&channel=contextsearch",
- "Checking context menu search URL");
-
- contextMenu.hidePopup();
-
- // Remove the tab opened by the search
- gBrowser.removeCurrentTab();
-
- yield new Promise(resolve => {
- searchDonePromise = resolve;
- ss.removeEngine(ss.currentEngine);
- });
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/search/test/browser_google.js b/browser/components/search/test/browser_google.js
deleted file mode 100644
index 2b0cabea7..000000000
--- a/browser/components/search/test/browser_google.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Google search plugin URLs
- */
-
-"use strict";
-
-function test() {
- let engine = Services.search.getEngineByName("Google");
- ok(engine, "Google");
-
- let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b";
- let keywordBase = base + "-ab";
-
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base, "Check search URL for 'foo'");
- url = engine.getSubmission("foo", null, "contextmenu").uri.spec;
- is(url, base, "Check context menu search URL for 'foo'");
- url = engine.getSubmission("foo", null, "keyword").uri.spec;
- is(url, keywordBase, "Check keyword search URL for 'foo'");
- url = engine.getSubmission("foo", null, "searchbar").uri.spec;
- is(url, base, "Check search bar search URL for 'foo'");
- url = engine.getSubmission("foo", null, "homepage").uri.spec;
- is(url, base, "Check homepage search URL for 'foo'");
- url = engine.getSubmission("foo", null, "newtab").uri.spec;
- is(url, base, "Check newtab search URL for 'foo'");
-
- // Check search suggestion URL.
- url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
- is(url, "https://www.google.com/complete/search?client=firefox&q=foo", "Check search suggestion URL for 'foo'");
-
- // Check result parsing and alternate domains.
- let alternateBase = base.replace("www.google.com", "www.google.fr");
- is(Services.search.parseSubmissionURL(base).terms, "foo",
- "Check result parsing");
- is(Services.search.parseSubmissionURL(alternateBase).terms, "foo",
- "Check alternate domain");
-
- // Check all other engine properties.
- const EXPECTED_ENGINE = {
- name: "Google",
- alias: null,
- description: "Google Search",
- searchForm: "https://www.google.com/search?q=&ie=utf-8&oe=utf-8&client=firefox-b",
- hidden: false,
- wrappedJSObject: {
- queryCharset: "UTF-8",
- "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD9/f2W/f392P39/fn9/f35/f391/39/ZT+/v4uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Cf39/Zn///////////////////////////////////////////39/ZX///8IAAAAAAAAAAAAAAAA/v7+Cf39/cH/////+v35/7TZp/92ul3/WKs6/1iqOv9yuFn/rNWd//j79v///////f39v////wgAAAAAAAAAAP39/Zn/////7PXp/3G3WP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP+Or1j//vDo///////9/f2VAAAAAP///zD/////+vz5/3G3V/9TqDT/WKo6/6LQkf/U6cz/1urO/6rUm/+Zo0r/8IZB//adZ////v7///////7+/i79/f2Y/////4nWzf9Lqkj/Vqo4/9Xqzv///////////////////////ebY//SHRv/0hUL//NjD///////9/f2U/f392v////8sxPH/Ebzt/43RsP/////////////////////////////////4roL/9IVC//i1jf///////f391/39/fr/////Cr37/wW8+/+16/7/////////////////9IVC//SFQv/0hUL/9IVC//SFQv/3pnX///////39/fn9/f36/////wu++/8FvPv/tuz+//////////////////SFQv/0hUL/9IVC//SFQv/0hUL/96p7///////9/f35/f392/////81yfz/CrL5/2uk9v///////////////////////////////////////////////////////f392P39/Zn/////ks/7/zdS7P84Rur/0NT6///////////////////////9/f////////////////////////39/Zb+/v4y//////n5/v9WYu3/NUPq/ztJ6/+VnPT/z9L6/9HU+v+WnfT/Ul7t/+Hj/P////////////////////8wAAAAAP39/Z3/////6Or9/1hj7v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9sdvD////////////9/f2YAAAAAAAAAAD///8K/f39w//////5+f7/paz2/11p7v88Suv/Okfq/1pm7v+iqfX/+fn+///////9/f3B/v7+CQAAAAAAAAAAAAAAAP///wr9/f2d///////////////////////////////////////////9/f2Z/v7+CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f2Z/f392/39/fr9/f36/f392v39/Zj///8wAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/g3+/v5X/f39mf39/cj9/f3q/f39+f39/fn9/f3q/f39yP39/Zn+/v5W////DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f2c/f399f/////////////////////////////////////////////////////9/f31/f39mv7+/iMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/gn9/f2K/f39+////////////////////////////////////////////////////////////////////////////f39+v39/Yf///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4k/f390v////////////////////////////////////////////////////////////////////////////////////////////////39/dD///8iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////MP39/er//////////////////////////+r05v+v16H/gsBs/2WxSf9Wqjj/Vqk3/2OwRv99vWX/pdKV/97u2P////////////////////////////39/ej+/v4vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f3q/////////////////////+v15/+Pxnv/VKk2/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/36+Z//d7tf///////////////////////39/ej///8iAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K/f390//////////////////////E4bn/XKw+/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1apN/+x0pv///////////////////////39/dD///8IAAAAAAAAAAAAAAAAAAAAAP39/Yv/////////////////////sdij/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/YKU1/8qOPv/5wZ////////////////////////39/YcAAAAAAAAAAAAAAAD+/v4l/f39+////////////////8Lgt/9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9utlT/n86N/7faqv+426v/pdKV/3u8ZP9UqDX/U6g0/3egN//jiUH/9IVC//SFQv/82MP//////////////////f39+v7+/iMAAAAAAAAAAP39/Z3////////////////q9Ob/W6w+/1OoNP9TqDT/U6g0/1OoNP9nskz/zOXC/////////////////////////////////+Dv2v+osWP/8YVC//SFQv/0hUL/9IVC//WQVP/++fb//////////////////f39mgAAAAD+/v4O/f399v///////////////4LHj/9TqDT/U6g0/1OoNP9TqDT/dblc//L58P/////////////////////////////////////////////8+v/3p3f/9IVC//SFQv/0hUL/9IVC//rIqf/////////////////9/f31////DP7+/ln////////////////f9v7/Cbz2/zOwhv9TqDT/U6g0/2KwRv/v9+z///////////////////////////////////////////////////////738//1kFT/9IVC//SFQv/0hUL/9plg///////////////////////+/v5W/f39nP///////////////4jf/f8FvPv/Bbz7/yG1s/9QqDz/vN2w//////////////////////////////////////////////////////////////////rHqP/0hUL/9IVC//SFQv/0hUL//vDn//////////////////39/Zn9/f3L////////////////R878/wW8+/8FvPv/Bbz7/y7C5P/7/fr//////////////////////////////////////////////////////////////////ere//SFQv/0hUL/9IVC//SFQv/718H//////////////////f39yP39/ez///////////////8cwvv/Bbz7/wW8+/8FvPv/WNL8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rIqv/////////////////9/f3q/f39+v///////////////we9+/8FvPv/Bbz7/wW8+/993P3///////////////////////////////////////SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+cGf//////////////////39/fn9/f36////////////////B737/wW8+/8FvPv/Bbz7/33c/f//////////////////////////////////////9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6xaX//////////////////f39+f39/e3///////////////8cwvv/Bbz7/wW8+/8FvPv/WdP8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vVv//////////////////9/f3q/f39y////////////////0bN/P8FvPv/Bbz7/wW8+/8hrvn/+/v///////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/cj9/f2c////////////////ht/9/wW8+/8FvPv/FZP1/zRJ6/+zuPf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////f39mf7+/lr////////////////d9v7/B7n7/yB38f81Q+r/NUPq/0hV7P/u8P3////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v5X////D/39/ff///////////////9tkPT/NUPq/zVD6v81Q+r/NUPq/2Fs7//y8v7////////////////////////////////////////////09f7//////////////////////////////////////////////////f399f7+/g0AAAAA/f39n////////////////+Tm/P89Suv/NUPq/zVD6v81Q+r/NUPq/1Bc7f/IzPn/////////////////////////////////x8v5/0xY7P+MlPP////////////////////////////////////////////9/f2cAAAAAAAAAAD+/v4n/f39/P///////////////7W69/81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9ZZe7/k5v0/6609/+vtff/lJv0/1pm7v81Q+r/NUPq/zVD6v+GjvL//v7//////////////////////////////f39+/7+/iQAAAAAAAAAAAAAAAD9/f2N/////////////////////6Cn9f81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v+BivL////////////////////////////9/f2KAAAAAAAAAAAAAAAAAAAAAP7+/gv9/f3V/////////////////////7W69/8+S+v/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/P0zr/7q/+P///////////////////////f390v7+/gkAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3r/////////////////////+Xn/P94gfH/NkTq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NkTq/3Z/8f/l5/z///////////////////////39/er+/v4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f3r///////////////////////////k5vz/nqX1/2p08P9IVez/OEbq/zdF6v9GU+z/aHLv/5qh9f/i5Pz////////////////////////////9/f3q////MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3V/////////////////////////////////////////////////////////////////////////////////////////////////f390v7+/iQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr9/f2N/f39/P///////////////////////////////////////////////////////////////////////////f39+/39/Yv+/v4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4n/f39n/39/ff//////////////////////////////////////////////////////f399v39/Z3+/v4lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Dv7+/lr9/f2c/f39y/39/e39/f36/f39+v39/ez9/f3L/f39nP7+/ln+/v4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/",
- _urls : [
- {
- type: "application/x-suggestions+json",
- method: "GET",
- template: "https://www.google.com/complete/search?client=firefox&q={searchTerms}",
- params: "",
- },
- {
- type: "text/html",
- method: "GET",
- template: "https://www.google.com/search",
- params: [
- {
- "name": "q",
- "value": "{searchTerms}",
- "purpose": undefined,
- },
- {
- "name": "ie",
- "value": "utf-8",
- "purpose": undefined,
- },
- {
- "name": "oe",
- "value": "utf-8",
- "purpose": undefined,
- },
- {
- "name": "client",
- "value": "firefox-b-ab",
- "purpose": "keyword",
- },
- {
- "name": "client",
- "value": "firefox-b",
- "purpose": "searchbar",
- },
- ],
- mozparams: {
- },
- },
- ],
- },
- };
-
- isSubObjectOf(EXPECTED_ENGINE, engine, "Google");
-}
diff --git a/browser/components/search/test/browser_google_behavior.js b/browser/components/search/test/browser_google_behavior.js
deleted file mode 100644
index 55405bb29..000000000
--- a/browser/components/search/test/browser_google_behavior.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Google search plugin URLs
- */
-
-"use strict";
-
-function test() {
- let engine = Services.search.getEngineByName("Google");
- ok(engine, "Google is installed");
-
- let previouslySelectedEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- engine.alias = "g";
-
- let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b";
- let keywordBase = base + "-ab";
-
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base, "Check search URL for 'foo'");
-
- waitForExplicitFinish();
-
- var gCurrTest;
- var gTests = [
- {
- name: "context menu search",
- searchURL: base,
- run: function () {
- // Simulate a contextmenu search
- // FIXME: This is a bit "low-level"...
- BrowserSearch.loadSearch("foo", false, "contextmenu");
- }
- },
- {
- name: "keyword search",
- searchURL: keywordBase,
- run: function () {
- gURLBar.value = "? foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "keyword search",
- searchURL: keywordBase,
- run: function () {
- gURLBar.value = "g foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "search bar search",
- searchURL: base,
- run: function () {
- let sb = BrowserSearch.searchBar;
- sb.focus();
- sb.value = "foo";
- registerCleanupFunction(function () {
- sb.value = "";
- });
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "new tab search",
- searchURL: base,
- run: function () {
- function doSearch(doc) {
- // Re-add the listener, and perform a search
- gBrowser.addProgressListener(listener);
- doc.getElementById("newtab-search-text").value = "foo";
- doc.getElementById("newtab-search-submit").click();
- }
-
- // load about:newtab, but remove the listener first so it doesn't
- // get in the way
- gBrowser.removeProgressListener(listener);
- gBrowser.loadURI("about:newtab");
- info("Waiting for about:newtab load");
- tab.linkedBrowser.addEventListener("load", function load(event) {
- if (event.originalTarget != tab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank") {
- info("skipping spurious load event");
- return;
- }
- tab.linkedBrowser.removeEventListener("load", load, true);
-
- // Observe page setup
- let win = gBrowser.contentWindow;
- if (win.gSearch.currentEngineName ==
- Services.search.currentEngine.name) {
- doSearch(win.document);
- }
- else {
- info("Waiting for newtab search init");
- win.addEventListener("ContentSearchService", function done(event) {
- info("Got newtab search event " + event.detail.type);
- if (event.detail.type == "State") {
- win.removeEventListener("ContentSearchService", done);
- // Let gSearch respond to the event before continuing.
- executeSoon(() => doSearch(win.document));
- }
- });
- }
- }, true);
- }
- }
- ];
-
- function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- info("Running : " + gCurrTest.name);
- executeSoon(gCurrTest.run);
- } else {
- finish();
- }
- }
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let listener = {
- onStateChange: function onStateChange(webProgress, req, flags, status) {
- info("onStateChange");
- // Only care about top-level document starts
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if (!(flags & docStart) || !webProgress.isTopLevel)
- return;
-
- if (req.originalURI.spec == "about:blank")
- return;
-
- info("received document start");
-
- ok(req instanceof Ci.nsIChannel, "req is a channel");
- is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
- info("Actual URI: " + req.URI.spec);
-
- req.cancel(Components.results.NS_ERROR_FAILURE);
-
- executeSoon(nextTest);
- }
- }
-
- 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);
- gBrowser.addProgressListener(listener);
- nextTest();
- }, true);
-}
diff --git a/browser/components/search/test/browser_google_codes.js b/browser/components/search/test/browser_google_codes.js
deleted file mode 100644
index e166b6868..000000000
--- a/browser/components/search/test/browser_google_codes.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const kUrlPref = "geoSpecificDefaults.url";
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-var originalGeoURL;
-
-/**
- * Clean the profile of any cache file left from a previous run.
- * Returns a boolean indicating if the cache file existed.
- */
-function removeCacheFile()
-{
- const CACHE_FILENAME = "search.json.mozlz4";
-
- let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
- file.append(CACHE_FILENAME);
- if (file.exists()) {
- file.remove(false);
- return true;
- }
- return false;
-}
-
-/**
- * Returns a promise that is resolved when an observer notification from the
- * search service fires with the specified data.
- *
- * @param aExpectedData
- * The value the observer notification sends that causes us to resolve
- * the promise.
- */
-function waitForSearchNotification(aExpectedData, aCallback) {
- const SEARCH_SERVICE_TOPIC = "browser-search-service";
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
- if (aData != aExpectedData)
- return;
-
- Services.obs.removeObserver(observer, SEARCH_SERVICE_TOPIC);
- aCallback();
- }, SEARCH_SERVICE_TOPIC, false);
-}
-
-function asyncInit() {
- return new Promise(resolve => {
- Services.search.init(function() {
- ok(Services.search.isInitialized, "search service should be initialized");
- resolve();
- });
- });
-}
-
-function asyncReInit() {
- const kLocalePref = "general.useragent.locale";
-
- let promise = new Promise(resolve => {
- waitForSearchNotification("reinit-complete", resolve);
- });
-
- Services.search.QueryInterface(Ci.nsIObserver)
- .observe(null, "nsPref:changed", kLocalePref);
-
- return promise;
-}
-
-let gEngineCount;
-
-add_task(function* preparation() {
- // ContentSearch is interferring with our async re-initializations of the
- // search service: once _initServicePromise has resolved, it will access
- // the search service, thus causing unpredictable behavior due to
- // synchronous initializations of the service.
- let originalContentSearchPromise = ContentSearch._initServicePromise;
- ContentSearch._initServicePromise = new Promise(resolve => {
- registerCleanupFunction(() => {
- ContentSearch._initServicePromise = originalContentSearchPromise;
- resolve();
- });
- });
-
- yield asyncInit();
- gEngineCount = Services.search.getVisibleEngines().length;
-
- waitForSearchNotification("uninit-complete", () => {
- // Verify search service is not initialized
- is(Services.search.isInitialized, false, "Search service should NOT be initialized");
-
- removeCacheFile();
-
- // Geo specific defaults won't be fetched if there's no country code.
- Services.prefs.setCharPref("browser.search.geoip.url",
- 'data:application/json,{"country_code": "US"}');
-
- Services.prefs.setBoolPref("browser.search.geoSpecificDefaults", true);
-
- // Make the new Google the only engine
- originalGeoURL = Services.prefs.getCharPref(BROWSER_SEARCH_PREF + kUrlPref);
- let geoUrl = 'data:application/json,{"interval": 31536000, "settings": {"searchDefault": "Google", "visibleDefaultEngines": ["google"]}}';
- Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF).setCharPref(kUrlPref, geoUrl);
- });
-
- yield asyncReInit();
-
- yield new Promise(resolve => {
- waitForSearchNotification("write-cache-to-disk-complete", resolve);
- });
-});
-
-add_task(function* tests() {
- let engines = Services.search.getEngines();
- is(Services.search.currentEngine.name, "Google", "Search engine should be Google");
- is(engines.length, 1, "There should only be one engine");
-
- let engine = Services.search.getEngineByName("Google");
- ok(engine, "Google");
-
- let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b";
-
- // Keyword uses a slightly different code
- let keywordBase = base + "-ab";
-
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo", null, "contextmenu").uri.spec;
- is(url, base, "Check context menu search URL for 'foo'");
- url = engine.getSubmission("foo", null, "keyword").uri.spec;
- is(url, keywordBase, "Check keyword search URL for 'foo'");
- url = engine.getSubmission("foo", null, "searchbar").uri.spec;
- is(url, base, "Check search bar search URL for 'foo'");
- url = engine.getSubmission("foo", null, "homepage").uri.spec;
- is(url, base, "Check homepage search URL for 'foo'");
- url = engine.getSubmission("foo", null, "newtab").uri.spec;
- is(url, base, "Check newtab search URL for 'foo'");
- url = engine.getSubmission("foo", null, "system").uri.spec;
- is(url, base, "Check system search URL for 'foo'");
-});
-
-
-add_task(function* cleanup() {
- waitForSearchNotification("uninit-complete", () => {
- // Verify search service is not initialized
- is(Services.search.isInitialized, false,
- "Search service should NOT be initialized");
- removeCacheFile();
-
- Services.prefs.clearUserPref("browser.search.geoip.url");
-
- // We can't clear the pref because it's set to false by testing/profiles/prefs_general.js
- Services.prefs.setBoolPref("browser.search.geoSpecificDefaults", false);
-
- Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF).setCharPref(kUrlPref, originalGeoURL);
- });
-
- yield asyncReInit();
- is(gEngineCount, Services.search.getVisibleEngines().length,
- "correct engine count after cleanup");
-});
diff --git a/browser/components/search/test/browser_healthreport.js b/browser/components/search/test/browser_healthreport.js
deleted file mode 100644
index c68ad174c..000000000
--- a/browser/components/search/test/browser_healthreport.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
-
-function test() {
- waitForExplicitFinish();
- resetPreferences();
-
- function testTelemetry() {
- // Find the right bucket for the "Foo" engine.
- let engine = Services.search.getEngineByName("Foo");
- let histogramKey = (engine.identifier || "other-Foo") + ".searchbar";
- let numSearchesBefore = 0;
- try {
- let hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
- if (histogramKey in hs) {
- numSearchesBefore = hs[histogramKey].sum;
- }
- } catch (ex) {
- // No searches performed yet, not a problem, |numSearchesBefore| is 0.
- }
-
- // Now perform a search and ensure the count is incremented.
- let tab = gBrowser.addTab();
- gBrowser.selectedTab = tab;
- let searchBar = BrowserSearch.searchBar;
-
- searchBar.value = "firefox health report";
- searchBar.focus();
-
- function afterSearch() {
- searchBar.value = "";
- gBrowser.removeTab(tab);
-
- // Make sure that the context searches are correctly recorded.
- let hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot();
- Assert.ok(histogramKey in hs, "The histogram must contain the correct key");
- Assert.equal(hs[histogramKey].sum, numSearchesBefore + 1,
- "Performing a search increments the related SEARCH_COUNTS key by 1.");
-
- let engine = Services.search.getEngineByName("Foo");
- Services.search.removeEngine(engine);
- }
-
- EventUtils.synthesizeKey("VK_RETURN", {});
- executeSoon(() => executeSoon(afterSearch));
- }
-
- function observer(subject, topic, data) {
- switch (data) {
- case "engine-added":
- let engine = Services.search.getEngineByName("Foo");
- ok(engine, "Engine was added.");
- Services.search.currentEngine = engine;
- break;
-
- case "engine-current":
- is(Services.search.currentEngine.name, "Foo", "Current engine is Foo");
- testTelemetry();
- break;
-
- case "engine-removed":
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- finish();
- break;
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- SpecialPowers.pushPrefEnv({set: [["toolkit.telemetry.enabled", true]]}).then(function() {
- Services.search.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
- null, "data:image/x-icon,%00", false);
- });
-}
-
-function resetPreferences() {
- Preferences.resetBranch("datareporting.policy.");
- Preferences.set("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
-}
diff --git a/browser/components/search/test/browser_hiddenOneOffs_cleanup.js b/browser/components/search/test/browser_hiddenOneOffs_cleanup.js
deleted file mode 100644
index 9a584feb6..000000000
--- a/browser/components/search/test/browser_hiddenOneOffs_cleanup.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const testPref = "Foo,FooDupe";
-
-function promiseNewEngine(basename) {
- return new Promise((resolve, reject) => {
- info("Waiting for engine to be added: " + basename);
- Services.search.init({
- onInitComplete: function() {
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- resolve(engine);
- },
- onError: function (errCode) {
- ok(false, "addEngine failed with error code " + errCode);
- reject();
- }
- });
- }
- });
- });
-}
-
-add_task(function* test_remove() {
- yield promiseNewEngine("testEngine_dupe.xml");
- yield promiseNewEngine("testEngine.xml");
- Services.prefs.setCharPref("browser.search.hiddenOneOffs", testPref);
-
- info("Removing testEngine_dupe.xml");
- Services.search.removeEngine(Services.search.getEngineByName("FooDupe"));
-
- let hiddenOneOffs =
- Services.prefs.getCharPref("browser.search.hiddenOneOffs").split(",");
-
- is(hiddenOneOffs.length, 1,
- "hiddenOneOffs has the correct engine count post removal.");
- is(hiddenOneOffs.some(x => x == "FooDupe"), false,
- "Removed Engine is not in hiddenOneOffs after removal");
- is(hiddenOneOffs.some(x => x == "Foo"), true,
- "Current hidden engine is not affected by removal.");
-
- info("Removing testEngine.xml");
- Services.search.removeEngine(Services.search.getEngineByName("Foo"));
-
- is(Services.prefs.getCharPref("browser.search.hiddenOneOffs"), "",
- "hiddenOneOffs is empty after removing all hidden engines.");
-});
-
-add_task(function* test_add() {
- yield promiseNewEngine("testEngine.xml");
- info("setting prefs to " + testPref);
- Services.prefs.setCharPref("browser.search.hiddenOneOffs", testPref);
- yield promiseNewEngine("testEngine_dupe.xml");
-
- let hiddenOneOffs =
- Services.prefs.getCharPref("browser.search.hiddenOneOffs").split(",");
-
- is(hiddenOneOffs.length, 1,
- "hiddenOneOffs has the correct number of hidden engines present post add.");
- is(hiddenOneOffs.some(x => x == "FooDupe"), false,
- "Added engine is not present in hidden list.");
- is(hiddenOneOffs.some(x => x == "Foo"), true,
- "Adding an engine does not remove engines from hidden list.");
-});
-
-add_task(function* test_diacritics() {
- const diacritic_engine = "Foo \u2661";
- let Preferences =
- Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
-
- Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
- yield promiseNewEngine("testEngine_diacritics.xml");
-
- let hiddenOneOffs =
- Preferences.get("browser.search.hiddenOneOffs").split(",");
- is(hiddenOneOffs.some(x => x == diacritic_engine), false,
- "Observer cleans up added hidden engines that include a diacritic.");
-
- Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
-
- info("Removing testEngine_diacritics.xml");
- Services.search.removeEngine(Services.search.getEngineByName(diacritic_engine));
-
- hiddenOneOffs =
- Preferences.get("browser.search.hiddenOneOffs").split(",");
- is(hiddenOneOffs.some(x => x == diacritic_engine), false,
- "Observer cleans up removed hidden engines that include a diacritic.");
-});
-
-registerCleanupFunction(() => {
- info("Removing testEngine.xml");
- Services.search.removeEngine(Services.search.getEngineByName("Foo"));
- info("Removing testEngine_dupe.xml");
- Services.search.removeEngine(Services.search.getEngineByName("FooDupe"));
- Services.prefs.clearUserPref("browser.search.hiddenOneOffs");
-});
diff --git a/browser/components/search/test/browser_hiddenOneOffs_diacritics.js b/browser/components/search/test/browser_hiddenOneOffs_diacritics.js
deleted file mode 100644
index db24c7192..000000000
--- a/browser/components/search/test/browser_hiddenOneOffs_diacritics.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-// Tests that keyboard navigation in the search panel works as designed.
-
-const searchbar = document.getElementById("searchbar");
-const textbox = searchbar._textbox;
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
- "searchbar-search-button");
-
-const diacritic_engine = "Foo \u2661";
-
-var Preferences =
- Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
-
-add_task(function* init() {
- let currentEngine = Services.search.currentEngine;
- yield promiseNewEngine("testEngine_diacritics.xml", {setAsCurrent: false});
- registerCleanupFunction(() => {
- Services.search.currentEngine = currentEngine;
- Services.prefs.clearUserPref("browser.search.hiddenOneOffs");
- });
-});
-
-add_task(function* test_hidden() {
- Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
-
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- yield promise;
-
- ok(!getOneOffs().some(x => x.getAttribute("tooltiptext") == diacritic_engine),
- "Search engines with diacritics are hidden when added to hiddenOneOffs preference.");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- info("Closing search panel");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-});
-
-add_task(function* test_shown() {
- Preferences.set("browser.search.hiddenOneOffs", "");
-
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- SimpleTest.executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- });
- yield promise;
-
- ok(getOneOffs().some(x => x.getAttribute("tooltiptext") == diacritic_engine),
- "Search engines with diacritics are shown when removed from hiddenOneOffs preference.");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-});
diff --git a/browser/components/search/test/browser_oneOffContextMenu.js b/browser/components/search/test/browser_oneOffContextMenu.js
deleted file mode 100644
index 69207923b..000000000
--- a/browser/components/search/test/browser_oneOffContextMenu.js
+++ /dev/null
@@ -1,105 +0,0 @@
-"use strict";
-
-const TEST_ENGINE_NAME = "Foo";
-const TEST_ENGINE_BASENAME = "testEngine.xml";
-
-const searchbar = document.getElementById("searchbar");
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const searchIcon = document.getAnonymousElementByAttribute(
- searchbar, "anonid", "searchbar-search-button"
-);
-const oneOffBinding = document.getAnonymousElementByAttribute(
- searchPopup, "anonid", "search-one-off-buttons"
-);
-const contextMenu = document.getAnonymousElementByAttribute(
- oneOffBinding, "anonid", "search-one-offs-context-menu"
-);
-const oneOffButtons = document.getAnonymousElementByAttribute(
- oneOffBinding, "anonid", "search-panel-one-offs"
-);
-const searchInNewTabMenuItem = document.getAnonymousElementByAttribute(
- oneOffBinding, "anonid", "search-one-offs-context-open-in-new-tab"
-);
-
-add_task(function* init() {
- yield promiseNewEngine(TEST_ENGINE_BASENAME, {
- setAsCurrent: false,
- });
-});
-
-add_task(function* extendedTelemetryDisabled() {
- yield SpecialPowers.pushPrefEnv({set: [["toolkit.telemetry.enabled", false]]});
- yield doTest();
- checkTelemetry("other");
-});
-
-add_task(function* extendedTelemetryEnabled() {
- yield SpecialPowers.pushPrefEnv({set: [["toolkit.telemetry.enabled", true]]});
- yield doTest();
- checkTelemetry("other-" + TEST_ENGINE_NAME);
-});
-
-function* doTest() {
- // Open the popup.
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- yield promise;
-
- // Get the one-off button for the test engine.
- let oneOffButton;
- for (let node of oneOffButtons.childNodes) {
- if (node.engine && node.engine.name == TEST_ENGINE_NAME) {
- oneOffButton = node;
- break;
- }
- }
- Assert.notEqual(oneOffButton, undefined,
- "One-off for test engine should exist");
-
- // Open the context menu on the one-off.
- promise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- EventUtils.synthesizeMouseAtCenter(oneOffButton, {
- type: "contextmenu",
- button: 2,
- });
- yield promise;
-
- // Click the Search in New Tab menu item.
- promise = BrowserTestUtils.waitForNewTab(gBrowser);
- EventUtils.synthesizeMouseAtCenter(searchInNewTabMenuItem, {});
- let tab = yield promise;
-
- // By default the search will open in the background and the popup will stay open:
- promise = promiseEvent(searchPopup, "popuphidden");
- info("Closing search panel");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-
- // Check the loaded tab.
- Assert.equal(tab.linkedBrowser.currentURI.spec,
- "http://mochi.test:8888/browser/browser/components/search/test/",
- "Expected search tab should have loaded");
-
- yield BrowserTestUtils.removeTab(tab);
-
- // Move the cursor out of the panel area to avoid messing with other tests.
- yield EventUtils.synthesizeNativeMouseMove(searchbar);
-}
-
-function checkTelemetry(expectedEngineName) {
- let propertyPath = [
- "countableEvents",
- "__DEFAULT__",
- "search-oneoff",
- expectedEngineName + ".oneoff-context-searchbar",
- "unknown",
- "tab-background",
- ];
- let telem = BrowserUITelemetry.getToolbarMeasures();
- for (let prop of propertyPath) {
- Assert.ok(prop in telem, "Property " + prop + " should be in the telemetry");
- telem = telem[prop];
- }
- Assert.equal(telem, 1, "Click count");
-}
diff --git a/browser/components/search/test/browser_oneOffContextMenu_setDefault.js b/browser/components/search/test/browser_oneOffContextMenu_setDefault.js
deleted file mode 100644
index ff49cb0c6..000000000
--- a/browser/components/search/test/browser_oneOffContextMenu_setDefault.js
+++ /dev/null
@@ -1,195 +0,0 @@
-"use strict";
-
-const TEST_ENGINE_NAME = "Foo";
-const TEST_ENGINE_BASENAME = "testEngine.xml";
-const SEARCHBAR_BASE_ID = "searchbar-engine-one-off-item-";
-const URLBAR_BASE_ID = "urlbar-engine-one-off-item-";
-const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
-
-const searchbar = document.getElementById("searchbar");
-const urlbar = document.getElementById("urlbar");
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const urlbarPopup = document.getElementById("PopupAutoCompleteRichResult");
-const searchIcon = document.getAnonymousElementByAttribute(
- searchbar, "anonid", "searchbar-search-button"
-);
-const searchOneOffBinding = document.getAnonymousElementByAttribute(
- searchPopup, "anonid", "search-one-off-buttons"
-);
-const urlBarOneOffBinding = document.getAnonymousElementByAttribute(
- urlbarPopup, "anonid", "one-off-search-buttons"
-);
-
-let originalEngine = Services.search.currentEngine;
-
-function resetEngine() {
- Services.search.currentEngine = originalEngine;
-}
-
-registerCleanupFunction(resetEngine);
-
-add_task(function* init() {
- yield promiseNewEngine(TEST_ENGINE_BASENAME, {
- setAsCurrent: false,
- });
-});
-
-add_task(function* test_searchBarChangeEngine() {
- let oneOffButton = yield openPopupAndGetEngineButton(true, searchPopup,
- searchOneOffBinding,
- SEARCHBAR_BASE_ID);
-
- const setDefaultEngineMenuItem = document.getAnonymousElementByAttribute(
- searchOneOffBinding, "anonid", "search-one-offs-context-set-default"
- );
-
- // Click the set default engine menu item.
- let promise = promiseCurrentEngineChanged();
- EventUtils.synthesizeMouseAtCenter(setDefaultEngineMenuItem, {});
-
- // This also checks the engine correctly changed.
- yield promise;
-
- Assert.equal(oneOffButton.id, SEARCHBAR_BASE_ID + originalEngine.name,
- "Should now have the original engine's id for the button");
- Assert.equal(oneOffButton.getAttribute("tooltiptext"), originalEngine.name,
- "Should now have the original engine's name for the tooltip");
- Assert.equal(oneOffButton.image, originalEngine.iconURI.spec,
- "Should now have the original engine's uri for the image");
-
- yield promiseClosePopup(searchPopup);
-});
-
-add_task(function* test_urlBarChangeEngine() {
- Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true);
- registerCleanupFunction(function* () {
- Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF);
- });
-
- // Ensure the engine is reset.
- resetEngine();
-
- let oneOffButton = yield openPopupAndGetEngineButton(false, urlbarPopup,
- urlBarOneOffBinding,
- URLBAR_BASE_ID);
-
- const setDefaultEngineMenuItem = document.getAnonymousElementByAttribute(
- urlBarOneOffBinding, "anonid", "search-one-offs-context-set-default"
- );
-
- // Click the set default engine menu item.
- let promise = promiseCurrentEngineChanged();
- EventUtils.synthesizeMouseAtCenter(setDefaultEngineMenuItem, {});
-
- // This also checks the engine correctly changed.
- yield promise;
-
- let currentEngine = Services.search.currentEngine;
-
- // For the urlbar, we should keep the new engine's icon.
- Assert.equal(oneOffButton.id, URLBAR_BASE_ID + currentEngine.name,
- "Should now have the original engine's id for the button");
- Assert.equal(oneOffButton.getAttribute("tooltiptext"), currentEngine.name,
- "Should now have the original engine's name for the tooltip");
- Assert.equal(oneOffButton.image, currentEngine.iconURI.spec,
- "Should now have the original engine's uri for the image");
-
- yield promiseClosePopup(urlbarPopup);
-});
-
-/**
- * Promises that an engine change has happened for the current engine, which
- * has resulted in the test engine now being the current engine.
- *
- * @return {Promise} Resolved once the test engine is set as the current engine.
- */
-function promiseCurrentEngineChanged() {
- return new Promise(resolve => {
- function observer(aSub, aTopic, aData) {
- if (aData == "engine-current") {
- Assert.ok(Services.search.currentEngine.name, TEST_ENGINE_NAME, "currentEngine set");
- Services.obs.removeObserver(observer, "browser-search-engine-modified");
- resolve();
- }
- }
-
- Services.obs.addObserver(observer, "browser-search-engine-modified", false);
- });
-}
-
-/**
- * Opens the specified urlbar/search popup and gets the test engine from the
- * one-off buttons.
- *
- * @param {Boolean} isSearch true if the search popup should be opened; false
- * for the urlbar popup.
- * @param {Object} popup The expected popup.
- * @param {Object} oneOffBinding The expected one-off-binding for the popup.
- * @param {String} baseId The expected string for the id of the current
- * engine button, without the engine name.
- * @return {Object} Returns an object that represents the one off button for the
- * test engine.
- */
-function* openPopupAndGetEngineButton(isSearch, popup, oneOffBinding, baseId) {
- // Open the popup.
- let promise = promiseEvent(popup, "popupshown");
- info("Opening panel");
-
- // We have to open the popups in differnt ways.
- if (isSearch) {
- // Use the search icon to avoid hitting the network.
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- } else {
- // There's no history at this stage, so we need to press a key.
- urlbar.focus();
- EventUtils.synthesizeKey("a", {});
- }
- yield promise;
-
- const contextMenu = document.getAnonymousElementByAttribute(
- oneOffBinding, "anonid", "search-one-offs-context-menu"
- );
- const oneOffButtons = document.getAnonymousElementByAttribute(
- oneOffBinding, "anonid", "search-panel-one-offs"
- );
-
- // Get the one-off button for the test engine.
- let oneOffButton;
- for (let node of oneOffButtons.childNodes) {
- if (node.engine && node.engine.name == TEST_ENGINE_NAME) {
- oneOffButton = node;
- break;
- }
- }
- Assert.notEqual(oneOffButton, undefined,
- "One-off for test engine should exist");
- Assert.equal(oneOffButton.getAttribute("tooltiptext"), TEST_ENGINE_NAME,
- "One-off should have the tooltip set to the engine name");
- Assert.equal(oneOffButton.id, baseId + TEST_ENGINE_NAME,
- "Should have the correct id");
-
- // Open the context menu on the one-off.
- promise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- EventUtils.synthesizeMouseAtCenter(oneOffButton, {
- type: "contextmenu",
- button: 2,
- });
- yield promise;
-
- return oneOffButton;
-}
-
-/**
- * Closes the popup and moves the mouse away from it.
- *
- * @param {Button} popup The popup to close.
- */
-function* promiseClosePopup(popup) {
- // close the panel using the escape key.
- let promise = promiseEvent(popup, "popuphidden");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-
- // Move the cursor out of the panel area to avoid messing with other tests.
- yield EventUtils.synthesizeNativeMouseMove(popup);
-}
diff --git a/browser/components/search/test/browser_oneOffHeader.js b/browser/components/search/test/browser_oneOffHeader.js
deleted file mode 100644
index 3a209bf56..000000000
--- a/browser/components/search/test/browser_oneOffHeader.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-// Tests that keyboard navigation in the search panel works as designed.
-
-const isMac = ("nsILocalFileMac" in Ci);
-
-const searchbar = document.getElementById("searchbar");
-const textbox = searchbar._textbox;
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
- "searchbar-search-button");
-
-const oneOffsContainer =
- document.getAnonymousElementByAttribute(searchPopup, "anonid",
- "search-one-off-buttons");
-const searchSettings =
- document.getAnonymousElementByAttribute(oneOffsContainer, "anonid",
- "search-settings");
-var header =
- document.getAnonymousElementByAttribute(oneOffsContainer, "anonid",
- "search-panel-one-offs-header");
-function getHeaderText() {
- let headerChild = header.selectedPanel;
- while (headerChild.hasChildNodes()) {
- headerChild = headerChild.firstChild;
- }
- let headerStrings = [];
- for (let label = headerChild; label; label = label.nextSibling) {
- headerStrings.push(label.value);
- }
- return headerStrings.join("");
-}
-
-const msg = isMac ? 5 : 1;
-const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-const scale = utils.screenPixelsPerCSSPixel;
-function* synthesizeNativeMouseMove(aElement) {
- let rect = aElement.getBoundingClientRect();
- let win = aElement.ownerGlobal;
- let x = win.mozInnerScreenX + (rect.left + rect.right) / 2;
- let y = win.mozInnerScreenY + (rect.top + rect.bottom) / 2;
-
- // Wait for the mouseup event to occur before continuing.
- return new Promise((resolve, reject) => {
- function eventOccurred(e)
- {
- aElement.removeEventListener("mouseover", eventOccurred, true);
- resolve();
- }
-
- aElement.addEventListener("mouseover", eventOccurred, true);
-
- utils.sendNativeMouseEvent(x * scale, y * scale, msg, 0, null);
- });
-}
-
-
-add_task(function* init() {
- yield promiseNewEngine("testEngine.xml");
-});
-
-add_task(function* test_notext() {
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- yield promise;
-
- is(header.getAttribute("selectedIndex"), 0,
- "Header has the correct index selected with no search terms.");
-
- is(getHeaderText(), "Search with:",
- "Search header string is correct when no search terms have been entered");
-
- yield synthesizeNativeMouseMove(searchSettings);
- is(header.getAttribute("selectedIndex"), 0,
- "Header has the correct index when no search terms have been entered and the Change Search Settings button is selected.");
- is(getHeaderText(), "Search with:",
- "Header has the correct text when no search terms have been entered and the Change Search Settings button is selected.");
-
- let buttons = getOneOffs();
- yield synthesizeNativeMouseMove(buttons[0]);
- is(header.getAttribute("selectedIndex"), 2,
- "Header has the correct index selected when a search engine has been selected");
- is(getHeaderText(), "Search " + buttons[0].engine.name,
- "Is the header text correct when a search engine is selected and no terms have been entered.");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- info("Closing search panel");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-});
-
-add_task(function* test_text() {
- textbox.value = "foo";
- registerCleanupFunction(() => {
- textbox.value = "";
- });
-
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- SimpleTest.executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- });
- yield promise;
-
- is(header.getAttribute("selectedIndex"), 1,
- "Header has the correct index selected with a search term.");
- is(getHeaderText(), "Search for foo with:",
- "Search header string is correct when a search term has been entered");
-
- let buttons = getOneOffs();
- yield synthesizeNativeMouseMove(buttons[0]);
- is(header.getAttribute("selectedIndex"), 2,
- "Header has the correct index selected when a search engine has been selected");
- is(getHeaderText(), "Search " + buttons[0].engine.name,
- "Is the header text correct when search terms are entered after a search engine has been selected.");
-
- yield synthesizeNativeMouseMove(searchSettings);
- is(header.getAttribute("selectedIndex"), 1,
- "Header has the correct index selected when search terms have been entered and the Change Search Settings button is selected.");
- is(getHeaderText(), "Search for foo with:",
- "Header has the correct text when search terms have been entered and the Change Search Settings button is selected.");
-
- // Click the "Foo Search" header at the top of the popup and make sure it
- // loads the search results.
- let searchbarEngine =
- document.getAnonymousElementByAttribute(searchPopup, "anonid",
- "searchbar-engine");
-
- yield synthesizeNativeMouseMove(searchbarEngine);
- SimpleTest.executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(searchbarEngine, {});
- });
-
- let url = Services.search.currentEngine.getSubmission(textbox.value).uri.spec;
- yield promiseTabLoadEvent(gBrowser.selectedTab, url);
-
- // Move the cursor out of the panel area to avoid messing with other tests.
- yield synthesizeNativeMouseMove(searchbar);
-});
diff --git a/browser/components/search/test/browser_private_search_perwindowpb.js b/browser/components/search/test/browser_private_search_perwindowpb.js
deleted file mode 100644
index c0410371b..000000000
--- a/browser/components/search/test/browser_private_search_perwindowpb.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// This test performs a search in a public window, then a different
-// search in a private window, and then checks in the public window
-// whether there is an autocomplete entry for the private search.
-
-add_task(function* () {
- // Don't use about:home as the homepage for new windows
- Services.prefs.setIntPref("browser.startup.page", 0);
- registerCleanupFunction(() => Services.prefs.clearUserPref("browser.startup.page"));
-
- let windowsToClose = [];
-
- function performSearch(aWin, aIsPrivate) {
- let searchBar = aWin.BrowserSearch.searchBar;
- ok(searchBar, "got search bar");
-
- let loadPromise = BrowserTestUtils.browserLoaded(aWin.gBrowser.selectedBrowser);
-
- searchBar.value = aIsPrivate ? "private test" : "public test";
- searchBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {}, aWin);
-
- return loadPromise;
- }
-
- function* testOnWindow(aIsPrivate) {
- let win = yield BrowserTestUtils.openNewBrowserWindow({ private: aIsPrivate });
- yield SimpleTest.promiseFocus(win);
- windowsToClose.push(win);
- return win;
- }
-
- yield promiseNewEngine("426329.xml", { iconURL: "data:image/x-icon,%00" });
-
- let newWindow = yield* testOnWindow(false);
- yield performSearch(newWindow, false);
-
- newWindow = yield* testOnWindow(true);
- yield performSearch(newWindow, true);
-
- newWindow = yield* testOnWindow(false);
-
- let searchBar = newWindow.BrowserSearch.searchBar;
- searchBar.value = "p";
- searchBar.focus();
-
- let popup = searchBar.textbox.popup;
- let popupPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
- searchBar.textbox.showHistoryPopup();
- yield popupPromise;
-
- let entries = getMenuEntries(searchBar);
- for (let i = 0; i < entries.length; i++) {
- isnot(entries[i], "private test",
- "shouldn't see private autocomplete entries");
- }
-
- searchBar.textbox.toggleHistoryPopup();
- searchBar.value = "";
-
- windowsToClose.forEach(function(win) {
- win.close();
- });
-});
-
-function getMenuEntries(searchBar) {
- let entries = [];
- let autocompleteMenu = searchBar.textbox.popup;
- // Could perhaps pull values directly from the controller, but it seems
- // more reliable to test the values that are actually in the tree?
- let column = autocompleteMenu.tree.columns[0];
- let numRows = autocompleteMenu.tree.view.rowCount;
- for (let i = 0; i < numRows; i++) {
- entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
- }
- return entries;
-}
diff --git a/browser/components/search/test/browser_searchbar_keyboard_navigation.js b/browser/components/search/test/browser_searchbar_keyboard_navigation.js
deleted file mode 100644
index d395dfdc2..000000000
--- a/browser/components/search/test/browser_searchbar_keyboard_navigation.js
+++ /dev/null
@@ -1,425 +0,0 @@
-// Tests that keyboard navigation in the search panel works as designed.
-
-const searchbar = document.getElementById("searchbar");
-const textbox = searchbar._textbox;
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const oneOffsContainer =
- document.getAnonymousElementByAttribute(searchPopup, "anonid",
- "search-one-off-buttons");
-
-const kValues = ["foo1", "foo2", "foo3"];
-const kUserValue = "foo";
-
-function getOpenSearchItems() {
- let os = [];
-
- let addEngineList =
- document.getAnonymousElementByAttribute(oneOffsContainer, "anonid",
- "add-engines");
- for (let item = addEngineList.firstChild; item; item = item.nextSibling)
- os.push(item);
-
- return os;
-}
-
-add_task(function* init() {
- yield promiseNewEngine("testEngine.xml");
-
- // First cleanup the form history in case other tests left things there.
- yield new Promise((resolve, reject) => {
- info("cleanup the search history");
- searchbar.FormHistory.update({op: "remove", fieldname: "searchbar-history"},
- {handleCompletion: resolve,
- handleError: reject});
- });
-
- yield new Promise((resolve, reject) => {
- info("adding search history values: " + kValues);
- let ops = kValues.map(value => { return {op: "add",
- fieldname: "searchbar-history",
- value: value}
- });
- searchbar.FormHistory.update(ops, {
- handleCompletion: function() {
- registerCleanupFunction(() => {
- info("removing search history values: " + kValues);
- let ops =
- kValues.map(value => { return {op: "remove",
- fieldname: "searchbar-history",
- value: value}
- });
- searchbar.FormHistory.update(ops);
- });
- resolve();
- },
- handleError: reject
- });
- });
-
- textbox.value = kUserValue;
- registerCleanupFunction(() => { textbox.value = ""; });
-});
-
-
-add_task(function* test_arrows() {
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- searchbar.focus();
- yield promise;
- is(textbox.mController.searchString, kUserValue, "The search string should be 'foo'");
-
- // Check the initial state of the panel before sending keyboard events.
- is(searchPopup.view.rowCount, kValues.length, "There should be 3 suggestions");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
-
- // The tests will be less meaningful if the first, second, last, and
- // before-last one-off buttons aren't different. We should always have more
- // than 4 default engines, but it's safer to check this assumption.
- let oneOffs = getOneOffs();
- ok(oneOffs.length >= 4, "we have at least 4 one-off buttons displayed")
-
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // The down arrow should first go through the suggestions.
- for (let i = 0; i < kValues.length; ++i) {
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(searchPopup.selectedIndex, i,
- "the suggestion at index " + i + " should be selected");
- is(textbox.value, kValues[i],
- "the textfield value should be " + kValues[i]);
- }
-
- // Pressing down again should remove suggestion selection and change the text
- // field value back to what the user typed, and select the first one-off.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue,
- "the textfield value should be back to initial value");
-
- // now cycle through the one-off items, the first one is already selected.
- for (let i = 0; i < oneOffs.length; ++i) {
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- EventUtils.synthesizeKey("VK_DOWN", {});
- }
-
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
- EventUtils.synthesizeKey("VK_DOWN", {});
-
- // We should now be back to the initial situation.
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- info("now test the up arrow key");
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // cycle through the one-off items, the first one is already selected.
- for (let i = oneOffs.length; i; --i) {
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton, oneOffs[i - 1],
- "the one-off button #" + i + " should be selected");
- }
-
- // Another press on up should clear the one-off selection and select the
- // last suggestion.
- EventUtils.synthesizeKey("VK_UP", {});
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- for (let i = kValues.length - 1; i >= 0; --i) {
- is(searchPopup.selectedIndex, i,
- "the suggestion at index " + i + " should be selected");
- is(textbox.value, kValues[i],
- "the textfield value should be " + kValues[i]);
- EventUtils.synthesizeKey("VK_UP", {});
- }
-
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue,
- "the textfield value should be back to initial value");
-});
-
-add_task(function* test_typing_clears_button_selection() {
- is(Services.focus.focusedElement, textbox.inputField,
- "the search bar should be focused"); // from the previous test.
- ok(!textbox.selectedButton, "no button should be selected");
-
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // Type a character.
- EventUtils.synthesizeKey("a", {});
- ok(!textbox.selectedButton, "the settings item should be de-selected");
-
- // Remove the character.
- EventUtils.synthesizeKey("VK_BACK_SPACE", {});
-});
-
-add_task(function* test_tab() {
- is(Services.focus.focusedElement, textbox.inputField,
- "the search bar should be focused"); // from the previous test.
-
- let oneOffs = getOneOffs();
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // Pressing tab should select the first one-off without selecting suggestions.
- // now cycle through the one-off items, the first one is already selected.
- for (let i = 0; i < oneOffs.length; ++i) {
- EventUtils.synthesizeKey("VK_TAB", {});
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- }
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue, "the textfield value should be unmodified");
-
- // One more <tab> selects the settings button.
- EventUtils.synthesizeKey("VK_TAB", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // Pressing tab again should close the panel...
- let promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_TAB", {});
- yield promise;
-
- // ... and move the focus out of the searchbox.
- isnot(Services.focus.focusedElement, textbox.inputField,
- "the search bar no longer be focused");
-});
-
-add_task(function* test_shift_tab() {
- // First reopen the panel.
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- searchbar.focus();
- yield promise;
-
- let oneOffs = getOneOffs();
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // Press up once to select the last button.
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // Press up again to select the last one-off button.
- EventUtils.synthesizeKey("VK_UP", {});
-
- // Pressing shift+tab should cycle through the one-off items.
- for (let i = oneOffs.length - 1; i >= 0; --i) {
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- if (i)
- EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
- }
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue, "the textfield value should be unmodified");
-
- // Pressing shift+tab again should close the panel...
- promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
- yield promise;
-
- // ... and move the focus out of the searchbox.
- isnot(Services.focus.focusedElement, textbox.inputField,
- "the search bar no longer be focused");
-});
-
-add_task(function* test_alt_down() {
- // First refocus the panel.
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- searchbar.focus();
- yield promise;
-
- // close the panel using the escape key.
- promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-
- // check that alt+down opens the panel...
- promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- yield promise;
-
- // ... and does nothing else.
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue, "the textfield value should be unmodified");
-
- // Pressing alt+down should select the first one-off without selecting suggestions
- // and cycle through the one-off items.
- let oneOffs = getOneOffs();
- for (let i = 0; i < oneOffs.length; ++i) {
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- }
-
- // One more alt+down keypress and nothing should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // another one and the first one-off should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should be selected");
-});
-
-add_task(function* test_alt_up() {
- // close the panel using the escape key.
- let promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-
- // check that alt+up opens the panel...
- promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- yield promise;
-
- // ... and does nothing else.
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue, "the textfield value should be unmodified");
-
- // Pressing alt+up should select the last one-off without selecting suggestions
- // and cycle up through the one-off items.
- let oneOffs = getOneOffs();
- for (let i = oneOffs.length - 1; i >= 0; --i) {
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- }
-
- // One more alt+down keypress and nothing should be selected.
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // another one and the last one-off should be selected.
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- is(textbox.selectedButton, oneOffs[oneOffs.length - 1],
- "the last one-off button should be selected");
-
- // Cleanup for the next test.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
- EventUtils.synthesizeKey("VK_DOWN", {});
- ok(!textbox.selectedButton, "no one-off should be selected anymore");
-});
-
-add_task(function* test_tab_and_arrows() {
- // Check the initial state is as expected.
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue, "the textfield value should be unmodified");
-
- // After pressing down, the first sugggestion should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(searchPopup.selectedIndex, 0, "first suggestion should be selected");
- is(textbox.value, kValues[0], "the textfield value should have changed");
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // After pressing tab, the first one-off should be selected,
- // and the first suggestion still selected.
- let oneOffs = getOneOffs();
- EventUtils.synthesizeKey("VK_TAB", {});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should be selected");
- is(searchPopup.selectedIndex, 0, "first suggestion should still be selected");
-
- // After pressing down, the second suggestion should be selected,
- // and the first one-off still selected.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should still be selected");
- is(searchPopup.selectedIndex, 1, "second suggestion should be selected");
-
- // After pressing up, the first suggestion should be selected again,
- // and the first one-off still selected.
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should still be selected");
- is(searchPopup.selectedIndex, 0, "second suggestion should be selected again");
-
- // After pressing up again, we should have no suggestion selected anymore,
- // the textfield value back to the user-typed value, and still the first one-off
- // selected.
- EventUtils.synthesizeKey("VK_UP", {});
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, kUserValue,
- "the textfield value should be back to user typed value");
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should still be selected");
-
- // Now pressing down should select the second one-off.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton, oneOffs[1],
- "the second one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "there should still be no selected suggestion");
-
- // Finally close the panel.
- let promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-});
-
-add_task(function* test_open_search() {
- let rootDir = getRootDirectory(gTestPath);
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, rootDir + "opensearch.html");
-
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- searchbar.focus();
- yield promise;
-
- let engines = getOpenSearchItems();
- is(engines.length, 2, "the opensearch.html page exposes 2 engines")
-
- // Check that there's initially no selection.
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- ok(!textbox.selectedButton, "no button should be selected");
-
- // Pressing up once selects the setting button...
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // ...and then pressing up selects open search engines.
- for (let i = engines.length; i; --i) {
- EventUtils.synthesizeKey("VK_UP", {});
- let selectedButton = textbox.selectedButton;
- is(selectedButton, engines[i - 1],
- "the engine #" + i + " should be selected");
- ok(selectedButton.classList.contains("addengine-item"),
- "the button is themed as an engine item");
- }
-
- // Pressing up again should select the last one-off button.
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton, getOneOffs().pop(),
- "the last one-off button should be selected");
-
- info("now check that the down key navigates open search items as expected");
- for (let i = 0; i < engines.length; ++i) {
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton, engines[i],
- "the engine #" + (i + 1) + " should be selected");
- }
-
- // Pressing down on the last engine item selects the settings button.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/search/test/browser_searchbar_openpopup.js b/browser/components/search/test/browser_searchbar_openpopup.js
deleted file mode 100644
index befc8f142..000000000
--- a/browser/components/search/test/browser_searchbar_openpopup.js
+++ /dev/null
@@ -1,521 +0,0 @@
-// Tests that the suggestion popup appears at the right times in response to
-// focus and user events (mouse, keyboard, drop).
-
-// Instead of loading EventUtils.js into the test scope in browser-test.js for all tests,
-// we only need EventUtils.js for a few files which is why we are using loadSubScript.
-var EventUtils = {};
-this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
-this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
-
-const searchbar = document.getElementById("searchbar");
-const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid", "searchbar-search-button");
-const goButton = document.getAnonymousElementByAttribute(searchbar, "anonid", "search-go-button");
-const textbox = searchbar._textbox;
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const kValues = ["long text", "long text 2", "long text 3"];
-
-const isWindows = Services.appinfo.OS == "WINNT";
-const mouseDown = isWindows ? 2 : 1;
-const mouseUp = isWindows ? 4 : 2;
-const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-const scale = utils.screenPixelsPerCSSPixel;
-
-function* synthesizeNativeMouseClick(aElement) {
- let rect = aElement.getBoundingClientRect();
- let win = aElement.ownerGlobal;
- let x = win.mozInnerScreenX + (rect.left + rect.right) / 2;
- let y = win.mozInnerScreenY + (rect.top + rect.bottom) / 2;
-
- // Wait for the mouseup event to occur before continuing.
- return new Promise((resolve, reject) => {
- function eventOccurred(e)
- {
- aElement.removeEventListener("mouseup", eventOccurred, true);
- resolve();
- }
-
- aElement.addEventListener("mouseup", eventOccurred, true);
-
- utils.sendNativeMouseEvent(x * scale, y * scale, mouseDown, 0, null);
- utils.sendNativeMouseEvent(x * scale, y * scale, mouseUp, 0, null);
- });
-}
-
-add_task(function* init() {
- yield promiseNewEngine("testEngine.xml");
-
- // First cleanup the form history in case other tests left things there.
- yield new Promise((resolve, reject) => {
- info("cleanup the search history");
- searchbar.FormHistory.update({op: "remove", fieldname: "searchbar-history"},
- {handleCompletion: resolve,
- handleError: reject});
- });
-
- yield new Promise((resolve, reject) => {
- info("adding search history values: " + kValues);
- let ops = kValues.map(value => { return {op: "add",
- fieldname: "searchbar-history",
- value: value}
- });
- searchbar.FormHistory.update(ops, {
- handleCompletion: function() {
- registerCleanupFunction(() => {
- info("removing search history values: " + kValues);
- let ops =
- kValues.map(value => { return {op: "remove",
- fieldname: "searchbar-history",
- value: value}
- });
- searchbar.FormHistory.update(ops);
- });
- resolve();
- },
- handleError: reject
- });
- });
-});
-
-// Adds a task that shouldn't show the search suggestions popup.
-function add_no_popup_task(task) {
- add_task(function*() {
- let sawPopup = false;
- function listener() {
- sawPopup = true;
- }
-
- info("Entering test " + task.name);
- searchPopup.addEventListener("popupshowing", listener, false);
- yield Task.spawn(task);
- searchPopup.removeEventListener("popupshowing", listener, false);
- ok(!sawPopup, "Shouldn't have seen the suggestions popup");
- info("Leaving test " + task.name);
- });
-}
-
-// Simulates the full set of events for a context click
-function context_click(target) {
- for (let event of ["mousedown", "contextmenu", "mouseup"])
- EventUtils.synthesizeMouseAtCenter(target, { type: event, button: 2 });
-}
-
-// Right clicking the icon should not open the popup.
-add_no_popup_task(function* open_icon_context() {
- gURLBar.focus();
- let toolbarPopup = document.getElementById("toolbar-context-menu");
-
- let promise = promiseEvent(toolbarPopup, "popupshown");
- context_click(searchIcon);
- yield promise;
-
- promise = promiseEvent(toolbarPopup, "popuphidden");
- toolbarPopup.hidePopup();
- yield promise;
-});
-
-// With no text in the search box left clicking the icon should open the popup.
-// Clicking the icon again should hide the popup and not show it again.
-add_task(function* open_empty() {
- gURLBar.focus();
-
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Clicking icon");
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- yield promise;
- is(searchPopup.getAttribute("showonlysettings"), "true", "Should only show the settings");
- is(textbox.mController.searchString, "", "Should be an empty search string");
-
- // By giving the textbox some text any next attempt to open the search popup
- // from the click handler will try to search for this text.
- textbox.value = "foo";
-
- promise = promiseEvent(searchPopup, "popuphidden");
-
- info("Hiding popup");
- yield synthesizeNativeMouseClick(searchIcon);
- yield promise;
-
- is(textbox.mController.searchString, "", "Should not have started to search for the new text");
-
- // Cancel the search if it started.
- if (textbox.mController.searchString != "") {
- textbox.mController.stopSearch();
- }
-
- textbox.value = "";
-});
-
-// With no text in the search box left clicking it should not open the popup.
-add_no_popup_task(function* click_doesnt_open_popup() {
- gURLBar.focus();
-
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 0, "Should have selected all of the text");
-});
-
-// Left clicking in a non-empty search box when unfocused should focus it and open the popup.
-add_task(function* click_opens_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-
- textbox.value = "";
-});
-
-// Right clicking in a non-empty search box when unfocused should open the edit context menu.
-add_no_popup_task(function* right_click_doesnt_open_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let contextPopup = document.getAnonymousElementByAttribute(textbox.inputField.parentNode, "anonid", "input-box-contextmenu");
- let promise = promiseEvent(contextPopup, "popupshown");
- context_click(textbox);
- yield promise;
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(contextPopup, "popuphidden");
- contextPopup.hidePopup();
- yield promise;
-
- textbox.value = "";
-});
-
-// Moving focus away from the search box should close the popup
-add_task(function* focus_change_closes_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- let promise2 = promiseEvent(searchbar, "blur");
- EventUtils.synthesizeKey("VK_TAB", { shiftKey: true });
- yield promise;
- yield promise2;
-
- textbox.value = "";
-});
-
-// Moving focus away from the search box should close the small popup
-add_task(function* focus_change_closes_small_popup() {
- gURLBar.focus();
-
- let promise = promiseEvent(searchPopup, "popupshown");
- // For some reason sending the mouse event immediately doesn't open the popup.
- SimpleTest.executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- });
- yield promise;
- is(searchPopup.getAttribute("showonlysettings"), "true", "Should show the small popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- let promise2 = promiseEvent(searchbar, "blur");
- EventUtils.synthesizeKey("VK_TAB", { shiftKey: true });
- yield promise;
- yield promise2;
-});
-
-// Pressing escape should close the popup.
-add_task(function* escape_closes_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-
- textbox.value = "";
-});
-
-// Pressing contextmenu should close the popup.
-add_task(function* contextmenu_closes_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
-
- // synthesizeKey does not work with VK_CONTEXT_MENU (bug 1127368)
- EventUtils.synthesizeMouseAtCenter(textbox, { type: "contextmenu", button: null });
-
- yield promise;
-
- let contextPopup =
- document.getAnonymousElementByAttribute(textbox.inputField.parentNode,
- "anonid", "input-box-contextmenu");
- promise = promiseEvent(contextPopup, "popuphidden");
- contextPopup.hidePopup();
- yield promise;
-
- textbox.value = "";
-});
-
-// Tabbing to the search box should open the popup if it contains text.
-add_task(function* tab_opens_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeKey("VK_TAB", {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-
- textbox.value = "";
-});
-
-// Tabbing to the search box should not open the popup if it doesn't contain text.
-add_no_popup_task(function* tab_doesnt_open_popup() {
- gURLBar.focus();
- textbox.value = "foo";
-
- EventUtils.synthesizeKey("VK_TAB", {});
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- textbox.value = "";
-});
-
-// Switching back to the window when the search box has focus from mouse should not open the popup.
-add_task(function* refocus_window_doesnt_open_popup_mouse() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(searchbar, {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- let newWin = OpenBrowserWindow();
- yield new Promise(resolve => waitForFocus(resolve, newWin));
- yield promise;
-
- function listener() {
- ok(false, "Should not have shown the popup.");
- }
- searchPopup.addEventListener("popupshowing", listener, false);
-
- promise = promiseEvent(searchbar, "focus");
- newWin.close();
- yield promise;
-
- // Wait a few ticks to allow any focus handlers to show the popup if they are going to.
- yield new Promise(resolve => executeSoon(resolve));
- yield new Promise(resolve => executeSoon(resolve));
- yield new Promise(resolve => executeSoon(resolve));
-
- searchPopup.removeEventListener("popupshowing", listener, false);
- textbox.value = "";
-});
-
-// Switching back to the window when the search box has focus from keyboard should not open the popup.
-add_task(function* refocus_window_doesnt_open_popup_keyboard() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeKey("VK_TAB", {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- let newWin = OpenBrowserWindow();
- yield new Promise(resolve => waitForFocus(resolve, newWin));
- yield promise;
-
- function listener() {
- ok(false, "Should not have shown the popup.");
- }
- searchPopup.addEventListener("popupshowing", listener, false);
-
- promise = promiseEvent(searchbar, "focus");
- newWin.close();
- yield promise;
-
- // Wait a few ticks to allow any focus handlers to show the popup if they are going to.
- yield new Promise(resolve => executeSoon(resolve));
- yield new Promise(resolve => executeSoon(resolve));
- yield new Promise(resolve => executeSoon(resolve));
-
- searchPopup.removeEventListener("popupshowing", listener, false);
- textbox.value = "";
-});
-
-// Clicking the search go button shouldn't open the popup
-add_no_popup_task(function* search_go_doesnt_open_popup() {
- gBrowser.selectedTab = gBrowser.addTab();
-
- gURLBar.focus();
- textbox.value = "foo";
- searchbar.updateGoButtonVisibility();
-
- let promise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
- EventUtils.synthesizeMouseAtCenter(goButton, {});
- yield promise;
-
- textbox.value = "";
- gBrowser.removeCurrentTab();
-});
-
-// Clicks outside the search popup should close the popup but not consume the click.
-add_task(function* dont_consume_clicks() {
- gURLBar.focus();
- textbox.value = "foo";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- yield promise;
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
-
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- is(textbox.selectionStart, 0, "Should have selected all of the text");
- is(textbox.selectionEnd, 3, "Should have selected all of the text");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- yield synthesizeNativeMouseClick(gURLBar);
- yield promise;
-
- is(Services.focus.focusedElement, gURLBar.inputField, "Should have focused the URL bar");
-
- textbox.value = "";
-});
-
-// Dropping text to the searchbar should open the popup
-add_task(function* drop_opens_popup() {
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeDrop(searchIcon, textbox.inputField, [[ {type: "text/plain", data: "foo" } ]], "move", window);
- yield promise;
-
- isnot(searchPopup.getAttribute("showonlysettings"), "true", "Should show the full popup");
- is(Services.focus.focusedElement, textbox.inputField, "Should have focused the search bar");
- promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-
- textbox.value = "";
-});
-
-// Moving the caret using the cursor keys should not close the popup.
-add_task(function* dont_rollup_oncaretmove() {
- gURLBar.focus();
- textbox.value = "long text";
-
- let promise = promiseEvent(searchPopup, "popupshown");
- EventUtils.synthesizeMouseAtCenter(textbox, {});
- yield promise;
-
- // Deselect the text
- EventUtils.synthesizeKey("VK_RIGHT", {});
- is(textbox.selectionStart, 9, "Should have moved the caret (selectionStart after deselect right)");
- is(textbox.selectionEnd, 9, "Should have moved the caret (selectionEnd after deselect right)");
- is(searchPopup.state, "open", "Popup should still be open");
-
- EventUtils.synthesizeKey("VK_LEFT", {});
- is(textbox.selectionStart, 8, "Should have moved the caret (selectionStart after left)");
- is(textbox.selectionEnd, 8, "Should have moved the caret (selectionEnd after left)");
- is(searchPopup.state, "open", "Popup should still be open");
-
- EventUtils.synthesizeKey("VK_RIGHT", {});
- is(textbox.selectionStart, 9, "Should have moved the caret (selectionStart after right)");
- is(textbox.selectionEnd, 9, "Should have moved the caret (selectionEnd after right)");
- is(searchPopup.state, "open", "Popup should still be open");
-
- // Ensure caret movement works while a suggestion is selected.
- is(textbox.popup.selectedIndex, -1, "No selected item in list");
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.popup.selectedIndex, 0, "Selected item in list");
- is(textbox.selectionStart, 9, "Should have moved the caret to the end (selectionStart after selection)");
- is(textbox.selectionEnd, 9, "Should have moved the caret to the end (selectionEnd after selection)");
-
- EventUtils.synthesizeKey("VK_LEFT", {});
- is(textbox.selectionStart, 8, "Should have moved the caret again (selectionStart after left)");
- is(textbox.selectionEnd, 8, "Should have moved the caret again (selectionEnd after left)");
- is(searchPopup.state, "open", "Popup should still be open");
-
- EventUtils.synthesizeKey("VK_LEFT", {});
- is(textbox.selectionStart, 7, "Should have moved the caret (selectionStart after left)");
- is(textbox.selectionEnd, 7, "Should have moved the caret (selectionEnd after left)");
- is(searchPopup.state, "open", "Popup should still be open");
-
- EventUtils.synthesizeKey("VK_RIGHT", {});
- is(textbox.selectionStart, 8, "Should have moved the caret (selectionStart after right)");
- is(textbox.selectionEnd, 8, "Should have moved the caret (selectionEnd after right)");
- is(searchPopup.state, "open", "Popup should still be open");
-
- if (navigator.platform.indexOf("Mac") == -1) {
- EventUtils.synthesizeKey("VK_HOME", {});
- is(textbox.selectionStart, 0, "Should have moved the caret (selectionStart after home)");
- is(textbox.selectionEnd, 0, "Should have moved the caret (selectionEnd after home)");
- is(searchPopup.state, "open", "Popup should still be open");
- }
-
- // Close the popup again
- promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_ESCAPE", {});
- yield promise;
-
- textbox.value = "";
-});
diff --git a/browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js b/browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js
deleted file mode 100644
index 37ca32cf2..000000000
--- a/browser/components/search/test/browser_searchbar_smallpanel_keyboard_navigation.js
+++ /dev/null
@@ -1,354 +0,0 @@
-// Tests that keyboard navigation in the search panel works as designed.
-
-const searchbar = document.getElementById("searchbar");
-const textbox = searchbar._textbox;
-const searchPopup = document.getElementById("PopupSearchAutoComplete");
-const oneOffsContainer =
- document.getAnonymousElementByAttribute(searchPopup, "anonid",
- "search-one-off-buttons");
-const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
- "searchbar-search-button");
-
-const kValues = ["foo1", "foo2", "foo3"];
-
-function getOpenSearchItems() {
- let os = [];
-
- let addEngineList =
- document.getAnonymousElementByAttribute(oneOffsContainer, "anonid",
- "add-engines");
- for (let item = addEngineList.firstChild; item; item = item.nextSibling)
- os.push(item);
-
- return os;
-}
-
-add_task(function* init() {
- yield promiseNewEngine("testEngine.xml");
-
- // First cleanup the form history in case other tests left things there.
- yield new Promise((resolve, reject) => {
- info("cleanup the search history");
- searchbar.FormHistory.update({op: "remove", fieldname: "searchbar-history"},
- {handleCompletion: resolve,
- handleError: reject});
- });
-
- yield new Promise((resolve, reject) => {
- info("adding search history values: " + kValues);
- let ops = kValues.map(value => { return {op: "add",
- fieldname: "searchbar-history",
- value: value}
- });
- searchbar.FormHistory.update(ops, {
- handleCompletion: function() {
- registerCleanupFunction(() => {
- info("removing search history values: " + kValues);
- let ops =
- kValues.map(value => { return {op: "remove",
- fieldname: "searchbar-history",
- value: value}
- });
- searchbar.FormHistory.update(ops);
- });
- resolve();
- },
- handleError: reject
- });
- });
-});
-
-
-add_task(function* test_arrows() {
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- yield promise;
-info("textbox.mController.searchString = " + textbox.mController.searchString);
- is(textbox.mController.searchString, "", "The search string should be empty");
-
- // Check the initial state of the panel before sending keyboard events.
- is(searchPopup.getAttribute("showonlysettings"), "true", "Should show the small popup");
- // Having suggestions populated (but hidden) is important, because if there
- // are none we can't ensure the keyboard events don't reach them.
- is(searchPopup.view.rowCount, kValues.length, "There should be 3 suggestions");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
-
- // The tests will be less meaningful if the first, second, last, and
- // before-last one-off buttons aren't different. We should always have more
- // than 4 default engines, but it's safer to check this assumption.
- let oneOffs = getOneOffs();
- ok(oneOffs.length >= 4, "we have at least 4 one-off buttons displayed")
-
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // Pressing should select the first one-off.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-
- // now cycle through the one-off items, the first one is already selected.
- for (let i = 0; i < oneOffs.length; ++i) {
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- EventUtils.synthesizeKey("VK_DOWN", {});
- }
-
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
- EventUtils.synthesizeKey("VK_DOWN", {});
-
- // We should now be back to the initial situation.
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- info("now test the up arrow key");
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // cycle through the one-off items, the first one is already selected.
- for (let i = oneOffs.length; i; --i) {
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton, oneOffs[i - 1],
- "the one-off button #" + i + " should be selected");
- }
-
- // Another press on up should clear the one-off selection.
- EventUtils.synthesizeKey("VK_UP", {});
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-});
-
-add_task(function* test_tab() {
- is(Services.focus.focusedElement, textbox.inputField,
- "the search bar should be focused"); // from the previous test.
-
- let oneOffs = getOneOffs();
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // Pressing tab should select the first one-off without selecting suggestions.
- // now cycle through the one-off items, the first one is already selected.
- for (let i = 0; i < oneOffs.length; ++i) {
- EventUtils.synthesizeKey("VK_TAB", {});
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- }
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-
- // One more <tab> selects the settings button.
- EventUtils.synthesizeKey("VK_TAB", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // Pressing tab again should close the panel...
- let promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_TAB", {});
- yield promise;
-
- // ... and move the focus out of the searchbox.
- isnot(Services.focus.focusedElement, textbox.inputField,
- "the search bar no longer be focused");
-});
-
-add_task(function* test_shift_tab() {
- // First reopen the panel.
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- SimpleTest.executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- });
- yield promise;
-
- let oneOffs = getOneOffs();
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.getAttribute("showonlysettings"), "true", "Should show the small popup");
-
- // Press up once to select the last button.
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // Press up again to select the last one-off button.
- EventUtils.synthesizeKey("VK_UP", {});
-
- // Pressing shift+tab should cycle through the one-off items.
- for (let i = oneOffs.length - 1; i >= 0; --i) {
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- if (i)
- EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
- }
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-
- // Pressing shift+tab again should close the panel...
- promise = promiseEvent(searchPopup, "popuphidden");
- EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
- yield promise;
-
- // ... and move the focus out of the searchbox.
- isnot(Services.focus.focusedElement, textbox.inputField,
- "the search bar no longer be focused");
-});
-
-add_task(function* test_alt_down() {
- // First reopen the panel.
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- SimpleTest.executeSoon(() => {
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- });
- yield promise;
-
- // and check it's in a correct initial state.
- is(searchPopup.getAttribute("showonlysettings"), "true", "Should show the small popup");
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-
- // Pressing alt+down should select the first one-off without selecting suggestions
- // and cycle through the one-off items.
- let oneOffs = getOneOffs();
- for (let i = 0; i < oneOffs.length; ++i) {
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- }
-
- // One more alt+down keypress and nothing should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // another one and the first one-off should be selected.
- EventUtils.synthesizeKey("VK_DOWN", {altKey: true});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should be selected");
-
- // Clear the selection with an alt+up keypress
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- ok(!textbox.selectedButton, "no one-off button should be selected");
-});
-
-add_task(function* test_alt_up() {
- // Check the initial state of the panel
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-
- // Pressing alt+up should select the last one-off without selecting suggestions
- // and cycle up through the one-off items.
- let oneOffs = getOneOffs();
- for (let i = oneOffs.length - 1; i >= 0; --i) {
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- is(textbox.selectedButton, oneOffs[i],
- "the one-off button #" + (i + 1) + " should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- }
-
- // One more alt+down keypress and nothing should be selected.
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- ok(!textbox.selectedButton, "no one-off button should be selected");
-
- // another one and the last one-off should be selected.
- EventUtils.synthesizeKey("VK_UP", {altKey: true});
- is(textbox.selectedButton, oneOffs[oneOffs.length - 1],
- "the last one-off button should be selected");
-
- // Cleanup for the next test.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
- EventUtils.synthesizeKey("VK_DOWN", {});
- ok(!textbox.selectedButton, "no one-off should be selected anymore");
-});
-
-add_task(function* test_tab_and_arrows() {
- // Check the initial state is as expected.
- ok(!textbox.selectedButton, "no one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- is(textbox.value, "", "the textfield value should be unmodified");
-
- // After pressing down, the first one-off should be selected.
- let oneOffs = getOneOffs();
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
-
- // After pressing tab, the second one-off should be selected.
- EventUtils.synthesizeKey("VK_TAB", {});
- is(textbox.selectedButton, oneOffs[1],
- "the second one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
-
- // After pressing up, the first one-off should be selected again.
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton, oneOffs[0],
- "the first one-off button should be selected");
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
-
- // Finally close the panel.
- let promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-});
-
-add_task(function* test_open_search() {
- let rootDir = getRootDirectory(gTestPath);
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, rootDir + "opensearch.html");
-
- let promise = promiseEvent(searchPopup, "popupshown");
- info("Opening search panel");
- EventUtils.synthesizeMouseAtCenter(searchIcon, {});
- yield promise;
- is(searchPopup.getAttribute("showonlysettings"), "true", "Should show the small popup");
-
- let engines = getOpenSearchItems();
- is(engines.length, 2, "the opensearch.html page exposes 2 engines")
-
- // Check that there's initially no selection.
- is(searchPopup.selectedIndex, -1, "no suggestion should be selected");
- ok(!textbox.selectedButton, "no button should be selected");
-
- // Pressing up once selects the setting button...
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- // ...and then pressing up selects open search engines.
- for (let i = engines.length; i; --i) {
- EventUtils.synthesizeKey("VK_UP", {});
- let selectedButton = textbox.selectedButton;
- is(selectedButton, engines[i - 1],
- "the engine #" + i + " should be selected");
- ok(selectedButton.classList.contains("addengine-item"),
- "the button is themed as an engine item");
- }
-
- // Pressing up again should select the last one-off button.
- EventUtils.synthesizeKey("VK_UP", {});
- is(textbox.selectedButton, getOneOffs().pop(),
- "the last one-off button should be selected");
-
- info("now check that the down key navigates open search items as expected");
- for (let i = 0; i < engines.length; ++i) {
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton, engines[i],
- "the engine #" + (i + 1) + " should be selected");
- }
-
- // Pressing down on the last engine item selects the settings button.
- EventUtils.synthesizeKey("VK_DOWN", {});
- is(textbox.selectedButton.getAttribute("anonid"), "search-settings",
- "the settings item should be selected");
-
- promise = promiseEvent(searchPopup, "popuphidden");
- searchPopup.hidePopup();
- yield promise;
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/search/test/browser_webapi.js b/browser/components/search/test/browser_webapi.js
deleted file mode 100644
index d8161ffbe..000000000
--- a/browser/components/search/test/browser_webapi.js
+++ /dev/null
@@ -1,92 +0,0 @@
-var ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
-const searchBundle = Services.strings.createBundle("chrome://global/locale/search/search.properties");
-const brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
-const brandName = brandBundle.GetStringFromName("brandShortName");
-
-function getString(key, ...params) {
- return searchBundle.formatStringFromName(key, params, params.length);
-}
-
-function AddSearchProvider(...args) {
- return gBrowser.addTab(ROOT + "webapi.html?" + encodeURIComponent(JSON.stringify(args)));
-}
-
-function promiseDialogOpened() {
- return new Promise((resolve, reject) => {
- Services.wm.addListener({
- onOpenWindow: function(xulWin) {
- Services.wm.removeListener(this);
-
- let win = xulWin.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- waitForFocus(() => {
- if (win.location == "chrome://global/content/commonDialog.xul")
- resolve(win)
- else
- reject();
- }, win);
- }
- });
- });
-}
-
-add_task(function* test_working() {
- gBrowser.selectedTab = AddSearchProvider(ROOT + "testEngine.xml");
-
- let dialog = yield promiseDialogOpened();
- is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
- is(dialog.args.text, getString("addEngineConfirmation", "Foo", "example.com"),
- "Should have seen the right install message");
- dialog.document.documentElement.cancelDialog();
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* test_HTTP() {
- gBrowser.selectedTab = AddSearchProvider(ROOT.replace("http:", "HTTP:") + "testEngine.xml");
-
- let dialog = yield promiseDialogOpened();
- is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
- is(dialog.args.text, getString("addEngineConfirmation", "Foo", "example.com"),
- "Should have seen the right install message");
- dialog.document.documentElement.cancelDialog();
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* test_relative() {
- gBrowser.selectedTab = AddSearchProvider("testEngine.xml");
-
- let dialog = yield promiseDialogOpened();
- is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
- is(dialog.args.text, getString("addEngineConfirmation", "Foo", "example.com"),
- "Should have seen the right install message");
- dialog.document.documentElement.cancelDialog();
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* test_invalid() {
- gBrowser.selectedTab = AddSearchProvider("z://foobar");
-
- let dialog = yield promiseDialogOpened();
- is(dialog.args.promptType, "alert", "Should see the alert dialog.");
- is(dialog.args.text, getString("error_invalid_engine_msg", brandName),
- "Should have seen the right error message")
- dialog.document.documentElement.acceptDialog();
-
- gBrowser.removeCurrentTab();
-});
-
-add_task(function* test_missing() {
- let url = ROOT + "foobar.xml";
- gBrowser.selectedTab = AddSearchProvider(url);
-
- let dialog = yield promiseDialogOpened();
- is(dialog.args.promptType, "alert", "Should see the alert dialog.");
- is(dialog.args.text, getString("error_loading_engine_msg2", brandName, url),
- "Should have seen the right error message")
- dialog.document.documentElement.acceptDialog();
-
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/search/test/browser_yahoo.js b/browser/components/search/test/browser_yahoo.js
deleted file mode 100644
index f45b47d0c..000000000
--- a/browser/components/search/test/browser_yahoo.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Yahoo search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-function test() {
- let engine = Services.search.getEngineByName("Yahoo");
- ok(engine, "Yahoo");
-
- let base = "https://search.yahoo.com/yhs/search?p=foo&ei=UTF-8&hspart=mozilla";
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base + "&hsimp=yhs-001", "Check search URL for 'foo'");
- url = engine.getSubmission("foo", null, "searchbar").uri.spec;
- is(url, base + "&hsimp=yhs-001", "Check search bar search URL for 'foo'");
- url = engine.getSubmission("foo", null, "keyword").uri.spec;
- is(url, base + "&hsimp=yhs-002", "Check keyword search URL for 'foo'");
- url = engine.getSubmission("foo", null, "homepage").uri.spec;
- is(url, base + "&hsimp=yhs-003", "Check homepage search URL for 'foo'");
- url = engine.getSubmission("foo", null, "newtab").uri.spec;
- is(url, base + "&hsimp=yhs-004", "Check newtab search URL for 'foo'");
- url = engine.getSubmission("foo", null, "contextmenu").uri.spec;
- is(url, base + "&hsimp=yhs-005", "Check context menu search URL for 'foo'");
- url = engine.getSubmission("foo", null, "system").uri.spec;
- is(url, base + "&hsimp=yhs-007", "Check system search URL for 'foo'");
- url = engine.getSubmission("foo", null, "invalid").uri.spec;
- is(url, base + "&hsimp=yhs-001", "Check invalid URL for 'foo'");
-
- // Check search suggestion URL.
- url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
- is(url, "https://search.yahoo.com/sugg/ff?output=fxjson&appid=ffd&command=foo", "Check search suggestion URL for 'foo'");
-
- // Check all other engine properties.
- const EXPECTED_ENGINE = {
- name: "Yahoo",
- alias: null,
- description: "Yahoo Search",
- searchForm: "https://search.yahoo.com/yhs/search?p=&ei=UTF-8&hspart=mozilla&hsimp=yhs-001",
- hidden: false,
- wrappedJSObject: {
- queryCharset: "UTF-8",
- "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC",
- _urls : [
- {
- type: "application/x-suggestions+json",
- method: "GET",
- template: "https://search.yahoo.com/sugg/ff",
- params: [
- {
- name: "output",
- value: "fxjson",
- purpose: undefined,
- },
- {
- name: "appid",
- value: "ffd",
- purpose: undefined,
- },
- {
- name: "command",
- value: "{searchTerms}",
- purpose: undefined,
- },
- ],
- },
- {
- type: "text/html",
- method: "GET",
- template: "https://search.yahoo.com/yhs/search",
- params: [
- {
- name: "p",
- value: "{searchTerms}",
- purpose: undefined,
- },
- {
- name: "ei",
- value: "UTF-8",
- purpose: undefined,
- },
- {
- name: "hspart",
- value: "mozilla",
- purpose: undefined,
- },
- {
- name: "hsimp",
- value: "yhs-001",
- purpose: "searchbar",
- },
- {
- name: "hsimp",
- value: "yhs-002",
- purpose: "keyword",
- },
- {
- name: "hsimp",
- value: "yhs-003",
- purpose: "homepage",
- },
- {
- name: "hsimp",
- value: "yhs-004",
- purpose: "newtab",
- },
- {
- name: "hsimp",
- value: "yhs-005",
- purpose: "contextmenu",
- },
- {
- name: "hsimp",
- value: "yhs-007",
- purpose: "system",
- },
- ],
- mozparams: {},
- },
- ],
- },
- };
-
- isSubObjectOf(EXPECTED_ENGINE, engine, "Yahoo");
-}
diff --git a/browser/components/search/test/browser_yahoo_behavior.js b/browser/components/search/test/browser_yahoo_behavior.js
deleted file mode 100644
index 5b2d61422..000000000
--- a/browser/components/search/test/browser_yahoo_behavior.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Test Yahoo search plugin URLs
- */
-
-"use strict";
-
-const BROWSER_SEARCH_PREF = "browser.search.";
-
-
-function test() {
- let engine = Services.search.getEngineByName("Yahoo");
- ok(engine, "Yahoo is installed");
-
- let previouslySelectedEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
- engine.alias = "y";
-
- let base = "https://search.yahoo.com/yhs/search?p=foo&ei=UTF-8&hspart=mozilla";
- let url;
-
- // Test search URLs (including purposes).
- url = engine.getSubmission("foo").uri.spec;
- is(url, base + "&hsimp=yhs-001", "Check search URL for 'foo'");
-
- waitForExplicitFinish();
-
- var gCurrTest;
- var gTests = [
- {
- name: "context menu search",
- searchURL: base + "&hsimp=yhs-005",
- run: function () {
- // Simulate a contextmenu search
- // FIXME: This is a bit "low-level"...
- BrowserSearch.loadSearch("foo", false, "contextmenu");
- }
- },
- {
- name: "keyword search",
- searchURL: base + "&hsimp=yhs-002",
- run: function () {
- gURLBar.value = "? foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "keyword search with alias",
- searchURL: base + "&hsimp=yhs-002",
- run: function () {
- gURLBar.value = "y foo";
- gURLBar.focus();
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "search bar search",
- searchURL: base + "&hsimp=yhs-001",
- run: function () {
- let sb = BrowserSearch.searchBar;
- sb.focus();
- sb.value = "foo";
- registerCleanupFunction(function () {
- sb.value = "";
- });
- EventUtils.synthesizeKey("VK_RETURN", {});
- }
- },
- {
- name: "new tab search",
- searchURL: base + "&hsimp=yhs-004",
- run: function () {
- function doSearch(doc) {
- // Re-add the listener, and perform a search
- gBrowser.addProgressListener(listener);
- doc.getElementById("newtab-search-text").value = "foo";
- doc.getElementById("newtab-search-submit").click();
- }
-
- // load about:newtab, but remove the listener first so it doesn't
- // get in the way
- gBrowser.removeProgressListener(listener);
- gBrowser.loadURI("about:newtab");
- info("Waiting for about:newtab load");
- tab.linkedBrowser.addEventListener("load", function load(event) {
- if (event.originalTarget != tab.linkedBrowser.contentDocument ||
- event.target.location.href == "about:blank") {
- info("skipping spurious load event");
- return;
- }
- tab.linkedBrowser.removeEventListener("load", load, true);
-
- // Observe page setup
- let win = gBrowser.contentWindow;
- if (win.gSearch.currentEngineName ==
- Services.search.currentEngine.name) {
- doSearch(win.document);
- }
- else {
- info("Waiting for newtab search init");
- win.addEventListener("ContentSearchService", function done(event) {
- info("Got newtab search event " + event.detail.type);
- if (event.detail.type == "State") {
- win.removeEventListener("ContentSearchService", done);
- // Let gSearch respond to the event before continuing.
- executeSoon(() => doSearch(win.document));
- }
- });
- }
- }, true);
- }
- }
- ];
-
- function nextTest() {
- if (gTests.length) {
- gCurrTest = gTests.shift();
- info("Running : " + gCurrTest.name);
- executeSoon(gCurrTest.run);
- } else {
- finish();
- }
- }
-
- let tab = gBrowser.selectedTab = gBrowser.addTab();
-
- let listener = {
- onStateChange: function onStateChange(webProgress, req, flags, status) {
- info("onStateChange");
- // Only care about top-level document starts
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if (!(flags & docStart) || !webProgress.isTopLevel)
- return;
-
- if (req.originalURI.spec == "about:blank")
- return;
-
- info("received document start");
-
- ok(req instanceof Ci.nsIChannel, "req is a channel");
- is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
- info("Actual URI: " + req.URI.spec);
-
- req.cancel(Components.results.NS_ERROR_FAILURE);
-
- executeSoon(nextTest);
- }
- }
-
- 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);
- gBrowser.addProgressListener(listener);
- nextTest();
- }, true);
-}
diff --git a/browser/components/search/test/head.js b/browser/components/search/test/head.js
deleted file mode 100644
index de27b5e1e..000000000
--- a/browser/components/search/test/head.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://gre/modules/Promise.jsm");
-
-/**
- * Recursively compare two objects and check that every property of expectedObj has the same value
- * on actualObj.
- */
-function isSubObjectOf(expectedObj, actualObj, name) {
- for (let prop in expectedObj) {
- if (typeof expectedObj[prop] == 'function')
- continue;
- if (expectedObj[prop] instanceof Object) {
- is(actualObj[prop].length, expectedObj[prop].length, name + "[" + prop + "]");
- isSubObjectOf(expectedObj[prop], actualObj[prop], name + "[" + prop + "]");
- } else {
- is(actualObj[prop], expectedObj[prop], name + "[" + prop + "]");
- }
- }
-}
-
-function getLocale() {
- const localePref = "general.useragent.locale";
- return getLocalizedPref(localePref, Services.prefs.getCharPref(localePref));
-}
-
-/**
- * Wrapper for nsIPrefBranch::getComplexValue.
- * @param aPrefName
- * The name of the pref to get.
- * @returns aDefault if the requested pref doesn't exist.
- */
-function getLocalizedPref(aPrefName, aDefault) {
- try {
- return Services.prefs.getComplexValue(aPrefName, Ci.nsIPrefLocalizedString).data;
- } catch (ex) {
- return aDefault;
- }
-}
-
-function promiseEvent(aTarget, aEventName, aPreventDefault) {
- function cancelEvent(event) {
- if (aPreventDefault) {
- event.preventDefault();
- }
-
- return true;
- }
-
- return BrowserTestUtils.waitForEvent(aTarget, aEventName, false, cancelEvent);
-}
-
-/**
- * Adds a new search engine to the search service and confirms it completes.
- *
- * @param {String} basename The file to load that contains the search engine
- * details.
- * @param {Object} [options] Options for the test:
- * - {String} [iconURL] The icon to use for the search engine.
- * - {Boolean} [setAsCurrent] Whether to set the new engine to be the
- * current engine or not.
- * - {String} [testPath] Used to override the current test path if this
- * file is used from a different directory.
- * @returns {Promise} The promise is resolved once the engine is added, or
- * rejected if the addition failed.
- */
-function promiseNewEngine(basename, options = {}) {
- return new Promise((resolve, reject) => {
- // Default the setAsCurrent option to true.
- let setAsCurrent =
- options.setAsCurrent == undefined ? true : options.setAsCurrent;
- info("Waiting for engine to be added: " + basename);
- Services.search.init({
- onInitComplete: function() {
- let url = getRootDirectory(options.testPath || gTestPath) + basename;
- let current = Services.search.currentEngine;
- Services.search.addEngine(url, null, options.iconURL || "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- if (setAsCurrent) {
- Services.search.currentEngine = engine;
- }
- registerCleanupFunction(() => {
- if (setAsCurrent) {
- Services.search.currentEngine = current;
- }
- Services.search.removeEngine(engine);
- info("Search engine removed: " + basename);
- });
- resolve(engine);
- },
- onError: function (errCode) {
- ok(false, "addEngine failed with error code " + errCode);
- reject();
- }
- });
- }
- });
- });
-}
-
-/**
- * Waits for a load (or custom) event to finish in a given tab. If provided
- * load an uri into the tab.
- *
- * @param tab
- * The tab to load into.
- * @param [optional] url
- * The url to load, or the current url.
- * @return {Promise} resolved when the event is handled.
- * @resolves to the received event
- * @rejects if a valid load event is not received within a meaningful interval
- */
-function promiseTabLoadEvent(tab, url)
-{
- info("Wait tab event: load");
-
- function handle(loadedUrl) {
- if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
- info(`Skipping spurious load event for ${loadedUrl}`);
- return false;
- }
-
- info("Tab event received: load");
- return true;
- }
-
- let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
-
- if (url)
- BrowserTestUtils.loadURI(tab.linkedBrowser, url);
-
- return loaded;
-}
-
-// Get an array of the one-off buttons.
-function getOneOffs() {
- let oneOffs = [];
- let searchPopup = document.getElementById("PopupSearchAutoComplete");
- let oneOffsContainer =
- document.getAnonymousElementByAttribute(searchPopup, "anonid",
- "search-one-off-buttons");
- let oneOff =
- document.getAnonymousElementByAttribute(oneOffsContainer, "anonid",
- "search-panel-one-offs");
- for (oneOff = oneOff.firstChild; oneOff; oneOff = oneOff.nextSibling) {
- if (oneOff.nodeType == Node.ELEMENT_NODE) {
- if (oneOff.classList.contains("dummy") ||
- oneOff.classList.contains("search-setting-button-compact"))
- break;
- oneOffs.push(oneOff);
- }
- }
- return oneOffs;
-}
diff --git a/browser/components/search/test/opensearch.html b/browser/components/search/test/opensearch.html
deleted file mode 100644
index f4c0cc98e..000000000
--- a/browser/components/search/test/opensearch.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="UTF-8">
-<link rel="search" type="application/opensearchdescription+xml" title="engine1" href="http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml">
-<link rel="search" type="application/opensearchdescription+xml" title="engine2" href="http://mochi.test:8888/browser/browser/components/search/test/testEngine_mozsearch.xml">
-</head>
-<body></body>
-</html>
diff --git a/browser/components/search/test/test.html b/browser/components/search/test/test.html
deleted file mode 100644
index a39bece4f..000000000
--- a/browser/components/search/test/test.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8" />
- <title>Bug 426329</title>
-</head>
-<body></body>
-</html>
diff --git a/browser/components/search/test/testEngine.xml b/browser/components/search/test/testEngine.xml
deleted file mode 100644
index 21ddc4b9a..000000000
--- a/browser/components/search/test/testEngine.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
- xmlns:moz="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Foo</ShortName>
- <Description>Foo Search</Description>
- <InputEncoding>utf-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
- <Param name="test" value="{searchTerms}"/>
- </Url>
- <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
- <moz:Alias>fooalias</moz:Alias>
-</OpenSearchDescription>
diff --git a/browser/components/search/test/testEngine_diacritics.xml b/browser/components/search/test/testEngine_diacritics.xml
deleted file mode 100644
index 0744921eb..000000000
--- a/browser/components/search/test/testEngine_diacritics.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
- xmlns:moz="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Foo &#9825;</ShortName>
- <Description>Engine whose ShortName contains non-BMP Unicode characters</Description>
- <InputEncoding>utf-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
- <Param name="test" value="{searchTerms}"/>
- </Url>
- <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
- <moz:Alias>diacriticalias</moz:Alias>
-</OpenSearchDescription>
diff --git a/browser/components/search/test/testEngine_dupe.xml b/browser/components/search/test/testEngine_dupe.xml
deleted file mode 100644
index d2db580c4..000000000
--- a/browser/components/search/test/testEngine_dupe.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
- xmlns:moz="http://www.mozilla.org/2006/browser/search/">
- <ShortName>FooDupe</ShortName>
- <Description>Second Engine Search</Description>
- <InputEncoding>utf-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
- <Param name="test" value="{searchTerms}"/>
- </Url>
- <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
- <moz:Alias>secondalias</moz:Alias>
-</OpenSearchDescription>
diff --git a/browser/components/search/test/testEngine_mozsearch.xml b/browser/components/search/test/testEngine_mozsearch.xml
deleted file mode 100644
index 9b4c02a0c..000000000
--- a/browser/components/search/test/testEngine_mozsearch.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Foo</ShortName>
- <Description>Foo Search</Description>
- <InputEncoding>utf-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
- <Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?suggestions&amp;locale={moz:locale}&amp;test={searchTerms}"/>
- <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/">
- <Param name="test" value="{searchTerms}"/>
- <Param name="ie" value="utf-8"/>
- <MozParam name="channel" condition="purpose" purpose="keyword" value="keywordsearch"/>
- <MozParam name="channel" condition="purpose" purpose="contextmenu" value="contextsearch"/>
- </Url>
- <SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</SearchForm>
-</SearchPlugin>
diff --git a/browser/components/search/test/webapi.html b/browser/components/search/test/webapi.html
deleted file mode 100644
index 1ef38b895..000000000
--- a/browser/components/search/test/webapi.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-<script>
-function installEngine() {
- var query = window.location.search.substring(1);
- var args = JSON.parse(decodeURIComponent(query));
-
- window.external.AddSearchProvider(...args);
-}
-</script>
-</head>
-<body onload="installEngine()">
-</body>
-</html>
diff --git a/browser/components/selfsupport/moz.build b/browser/components/selfsupport/moz.build
index daa59ac97..f8923b081 100644
--- a/browser/components/selfsupport/moz.build
+++ b/browser/components/selfsupport/moz.build
@@ -8,7 +8,3 @@ EXTRA_COMPONENTS += [
'SelfSupportService.js',
'SelfSupportService.manifest',
]
-
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser.ini',
-]
diff --git a/browser/components/selfsupport/test/.eslintrc.js b/browser/components/selfsupport/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/selfsupport/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/selfsupport/test/browser.ini b/browser/components/selfsupport/test/browser.ini
deleted file mode 100644
index ba56857b3..000000000
--- a/browser/components/selfsupport/test/browser.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[DEFAULT]
-
-[browser_selfsupportAPI.js]
diff --git a/browser/components/selfsupport/test/browser_selfsupportAPI.js b/browser/components/selfsupport/test/browser_selfsupportAPI.js
deleted file mode 100644
index 2a54d4ae6..000000000
--- a/browser/components/selfsupport/test/browser_selfsupportAPI.js
+++ /dev/null
@@ -1,88 +0,0 @@
-Cu.import("resource://gre/modules/Preferences.jsm");
-
-function test_resetPref() {
- const prefNewName = "browser.newpref.fake";
- Assert.ok(!Preferences.has(prefNewName), "pref should not exist");
-
- const prefExistingName = "extensions.hotfix.id";
- Assert.ok(Preferences.has(prefExistingName), "pref should exist");
- Assert.ok(!Preferences.isSet(prefExistingName), "pref should not be user-set");
- let prefExistingOriginalValue = Preferences.get(prefExistingName);
-
- registerCleanupFunction(function() {
- Preferences.set(prefExistingName, prefExistingOriginalValue);
- Services.prefs.deleteBranch(prefNewName);
- });
-
- // 1. do nothing on an inexistent pref
- MozSelfSupport.resetPref(prefNewName);
- Assert.ok(!Preferences.has(prefNewName), "pref should still not exist");
-
- // 2. creation of a new pref
- Preferences.set(prefNewName, 10);
- Assert.ok(Preferences.has(prefNewName), "pref should exist");
- Assert.equal(Preferences.get(prefNewName), 10, "pref value should be 10");
-
- MozSelfSupport.resetPref(prefNewName);
- Assert.ok(!Preferences.has(prefNewName), "pref should not exist any more");
-
- // 3. do nothing on an unchanged existing pref
- MozSelfSupport.resetPref(prefExistingName);
- Assert.ok(Preferences.has(prefExistingName), "pref should still exist");
- Assert.equal(Preferences.get(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
-
- // 4. change the value of an existing pref
- Preferences.set(prefExistingName, "anyone@mozilla.org");
- Assert.ok(Preferences.has(prefExistingName), "pref should exist");
- Assert.equal(Preferences.get(prefExistingName), "anyone@mozilla.org", "pref value should have changed");
-
- MozSelfSupport.resetPref(prefExistingName);
- Assert.ok(Preferences.has(prefExistingName), "pref should still exist");
- Assert.equal(Preferences.get(prefExistingName), prefExistingOriginalValue, "pref value should be the same as original");
-
- // 5. delete an existing pref
- // deleteBranch is implemented in such a way that
- // clearUserPref can't undo its action
- // see discussion in bug 1075160
-}
-
-function test_resetSearchEngines()
-{
- const defaultEngineOriginal = Services.search.defaultEngine;
- const visibleEnginesOriginal = Services.search.getVisibleEngines();
-
- // 1. do nothing on unchanged search configuration
- MozSelfSupport.resetSearchEngines();
- Assert.equal(Services.search.defaultEngine, defaultEngineOriginal, "default engine should be reset");
- Assert.deepEqual(Services.search.getVisibleEngines(), visibleEnginesOriginal,
- "default visible engines set should be reset");
-
- // 2. change the default search engine
- const defaultEngineNew = visibleEnginesOriginal[3];
- Assert.notEqual(defaultEngineOriginal, defaultEngineNew, "new default engine should be different from original");
- Services.search.defaultEngine = defaultEngineNew;
- Assert.equal(Services.search.defaultEngine, defaultEngineNew, "default engine should be set to new");
- MozSelfSupport.resetSearchEngines();
- Assert.equal(Services.search.defaultEngine, defaultEngineOriginal, "default engine should be reset");
- Assert.deepEqual(Services.search.getVisibleEngines(), visibleEnginesOriginal,
- "default visible engines set should be reset");
-
- // 3. remove an engine
- const engineRemoved = visibleEnginesOriginal[2];
- Services.search.removeEngine(engineRemoved);
- Assert.ok(Services.search.getVisibleEngines().indexOf(engineRemoved) == -1,
- "removed engine should not be visible any more");
- MozSelfSupport.resetSearchEngines();
- Assert.equal(Services.search.defaultEngine, defaultEngineOriginal, "default engine should be reset");
- Assert.deepEqual(Services.search.getVisibleEngines(), visibleEnginesOriginal,
- "default visible engines set should be reset");
-
- // 4. add an angine
- // we don't remove user-added engines as they are only used if selected
-}
-
-function test()
-{
- test_resetPref();
- test_resetSearchEngines();
-}
diff --git a/browser/components/sessionstore/moz.build b/browser/components/sessionstore/moz.build
index 8a8221c9f..3117f02c7 100644
--- a/browser/components/sessionstore/moz.build
+++ b/browser/components/sessionstore/moz.build
@@ -4,9 +4,6 @@
# 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/.
-XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
XPIDL_SOURCES += [
@@ -47,6 +44,3 @@ EXTRA_JS_MODULES.sessionstore = [
'TabStateCache.jsm',
'TabStateFlusher.jsm',
]
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Session Restore')
diff --git a/browser/components/sessionstore/test/.eslintrc.js b/browser/components/sessionstore/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/sessionstore/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/sessionstore/test/browser.ini b/browser/components/sessionstore/test/browser.ini
deleted file mode 100644
index 37154a0cc..000000000
--- a/browser/components/sessionstore/test/browser.ini
+++ /dev/null
@@ -1,242 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# browser_506482.js is disabled because of frequent failures (bug 538672)
-# browser_526613.js is disabled because of frequent failures (bug 534489)
-# browser_589246.js is disabled for leaking browser windows (bug 752467)
-# browser_580512.js is disabled for leaking browser windows (bug 752467)
-
-[DEFAULT]
-support-files =
- head.js
- content.js
- content-forms.js
- browser_cookies.sjs
- browser_formdata_sample.html
- browser_formdata_xpath_sample.html
- browser_frametree_sample.html
- browser_frametree_sample_frameset.html
- browser_frame_history_index.html
- browser_frame_history_index2.html
- browser_frame_history_index_blank.html
- browser_frame_history_a.html
- browser_frame_history_b.html
- browser_frame_history_c.html
- browser_frame_history_c1.html
- browser_frame_history_c2.html
- browser_form_restore_events_sample.html
- browser_formdata_format_sample.html
- browser_pageStyle_sample.html
- browser_pageStyle_sample_nested.html
- browser_sessionHistory_slow.sjs
- browser_scrollPositions_sample.html
- browser_scrollPositions_sample_frameset.html
- browser_scrollPositions_readerModeArticle.html
- browser_sessionStorage.html
- browser_248970_b_sample.html
- browser_339445_sample.html
- browser_423132_sample.html
- browser_447951_sample.html
- browser_454908_sample.html
- browser_456342_sample.xhtml
- browser_463205_sample.html
- browser_463206_sample.html
- browser_466937_sample.html
- browser_485482_sample.html
- browser_637020_slow.sjs
- browser_662743_sample.html
- browser_739531_sample.html
- browser_911547_sample.html
- browser_911547_sample.html^headers^
- restore_redirect_http.html
- restore_redirect_http.html^headers^
- restore_redirect_js.html
- restore_redirect_target.html
- browser_1234021_page.html
-
-#NB: the following are disabled
-# browser_464620_a.html
-# browser_464620_b.html
-# browser_464620_xd.html
-
-
-#disabled-for-intermittent-failures--bug-766044, browser_459906_empty.html
-#disabled-for-intermittent-failures--bug-766044, browser_459906_sample.html
-#disabled-for-intermittent-failures--bug-765389, browser_461743_sample.html
-
-[browser_aboutPrivateBrowsing.js]
-[browser_aboutSessionRestore.js]
-[browser_async_duplicate_tab.js]
-[browser_async_flushes.js]
-run-if = e10s && crashreporter
-skip-if = debug # bug 1167933
-[browser_async_remove_tab.js]
-run-if = e10s
-skip-if = debug # bug 1211084
-[browser_attributes.js]
-[browser_backup_recovery.js]
-[browser_broadcast.js]
-[browser_capabilities.js]
-[browser_cleaner.js]
-[browser_cookies.js]
-[browser_crashedTabs.js]
-skip-if = !e10s || !crashreporter
-[browser_unrestored_crashedTabs.js]
-skip-if = !e10s || !crashreporter
-[browser_revive_crashed_bg_tabs.js]
-skip-if = !e10s || !crashreporter
-[browser_dying_cache.js]
-[browser_dynamic_frames.js]
-[browser_form_restore_events.js]
-[browser_formdata.js]
-[browser_formdata_cc.js]
-[browser_formdata_format.js]
-[browser_formdata_xpath.js]
-[browser_frametree.js]
-[browser_frame_history.js]
-[browser_global_store.js]
-[browser_history_persist.js]
-[browser_label_and_icon.js]
-[browser_merge_closed_tabs.js]
-[browser_page_title.js]
-[browser_pageStyle.js]
-[browser_pending_tabs.js]
-[browser_privatetabs.js]
-[browser_purge_shistory.js]
-skip-if = e10s # Bug 1271024
-[browser_replace_load.js]
-[browser_restore_redirect.js]
-[browser_restore_cookies_noOriginAttributes.js]
-[browser_scrollPositions.js]
-[browser_scrollPositionsReaderMode.js]
-[browser_sessionHistory.js]
-[browser_sessionStorage.js]
-[browser_sessionStorage_size.js]
-[browser_swapDocShells.js]
-[browser_switch_remoteness.js]
-run-if = e10s
-[browser_upgrade_backup.js]
-[browser_windowRestore_perwindowpb.js]
-[browser_248970_b_perwindowpb.js]
-# Disabled because of leaks.
-# Re-enabling and rewriting this test is tracked in bug 936919.
-skip-if = true
-[browser_339445.js]
-[browser_345898.js]
-[browser_350525.js]
-[browser_354894_perwindowpb.js]
-[browser_367052.js]
-[browser_393716.js]
-[browser_394759_basic.js]
-# Disabled for intermittent failures, bug 944372.
-skip-if = true
-[browser_394759_behavior.js]
-[browser_394759_perwindowpb.js]
-[browser_394759_purge.js]
-[browser_423132.js]
-[browser_447951.js]
-[browser_454908.js]
-[browser_456342.js]
-[browser_461634.js]
-[browser_463205.js]
-[browser_463206.js]
-[browser_464199.js]
-[browser_465215.js]
-[browser_465223.js]
-[browser_466937.js]
-[browser_467409-backslashplosion.js]
-[browser_477657.js]
-[browser_480893.js]
-[browser_485482.js]
-[browser_485563.js]
-[browser_490040.js]
-[browser_491168.js]
-[browser_491577.js]
-[browser_495495.js]
-[browser_500328.js]
-[browser_514751.js]
-[browser_522375.js]
-[browser_522545.js]
-[browser_524745.js]
-[browser_528776.js]
-[browser_579868.js]
-[browser_579879.js]
-skip-if = (os == 'linux' && e10s && (debug||asan)) # Bug 1234404
-[browser_581937.js]
-[browser_586147.js]
-[browser_586068-apptabs.js]
-[browser_586068-apptabs_ondemand.js]
-[browser_586068-browser_state_interrupted.js]
-[browser_586068-cascade.js]
-[browser_586068-multi_window.js]
-[browser_586068-reload.js]
-[browser_586068-select.js]
-[browser_586068-window_state.js]
-[browser_586068-window_state_override.js]
-[browser_588426.js]
-[browser_590268.js]
-[browser_590563.js]
-[browser_595601-restore_hidden.js]
-[browser_597071.js]
-skip-if = true # Needs to be rewritten as Marionette test, bug 995916
-[browser_599909.js]
-[browser_600545.js]
-[browser_601955.js]
-[browser_607016.js]
-[browser_615394-SSWindowState_events.js]
-[browser_618151.js]
-[browser_623779.js]
-[browser_624727.js]
-[browser_628270.js]
-[browser_635418.js]
-[browser_636279.js]
-[browser_637020.js]
-[browser_644409-scratchpads.js]
-[browser_645428.js]
-[browser_659591.js]
-[browser_662743.js]
-[browser_662812.js]
-[browser_665702-state_session.js]
-[browser_682507.js]
-[browser_687710.js]
-[browser_687710_2.js]
-[browser_694378.js]
-[browser_701377.js]
-[browser_705597.js]
-[browser_707862.js]
-[browser_739531.js]
-[browser_739805.js]
-[browser_819510_perwindowpb.js]
-skip-if = (os == 'win' && bits == 64) # Bug 1284312
-
-# Disabled for frequent intermittent failures
-[browser_464620_a.js]
-skip-if = true
-[browser_464620_b.js]
-skip-if = true
-
-# Disabled on OS X:
-[browser_625016.js]
-skip-if = os == "mac"
-
-[browser_911547.js]
-[browser_send_async_message_oom.js]
-[browser_multiple_navigateAndRestore.js]
-run-if = e10s
-[browser_async_window_flushing.js]
-[browser_forget_async_closings.js]
-[browser_newtab_userTypedValue.js]
-[browser_parentProcessRestoreHash.js]
-run-if = e10s
-[browser_sessionStoreContainer.js]
-[browser_windowStateContainer.js]
-[browser_1234021.js]
-[browser_remoteness_flip_on_restore.js]
-run-if = e10s
-[browser_background_tab_crash.js]
-run-if = e10s && crashreporter
-
-# Disabled on debug for frequent intermittent failures:
-[browser_undoCloseById.js]
-skip-if = debug
diff --git a/browser/components/sessionstore/test/browser_1234021.js b/browser/components/sessionstore/test/browser_1234021.js
deleted file mode 100644
index a307d1e01..000000000
--- a/browser/components/sessionstore/test/browser_1234021.js
+++ /dev/null
@@ -1,18 +0,0 @@
-"use strict";
-
-const PREF = 'network.cookie.cookieBehavior';
-const PAGE_URL = 'http://mochi.test:8888/browser/' +
- 'browser/components/sessionstore/test/browser_1234021_page.html';
-const BEHAVIOR_REJECT = 2;
-
-add_task(function* test() {
- yield pushPrefs([PREF, BEHAVIOR_REJECT]);
-
- yield BrowserTestUtils.withNewTab({
- gBrowser: gBrowser,
- url: PAGE_URL
- }, function* handler(aBrowser) {
- yield TabStateFlusher.flush(aBrowser);
- ok(true, "Flush didn't time out");
- });
-});
diff --git a/browser/components/sessionstore/test/browser_1234021_page.html b/browser/components/sessionstore/test/browser_1234021_page.html
deleted file mode 100644
index 4a74fbc02..000000000
--- a/browser/components/sessionstore/test/browser_1234021_page.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!doctype html>
-<html>
- <script>
- sessionStorage
- </script>
-</html>
diff --git a/browser/components/sessionstore/test/browser_248970_b_perwindowpb.js b/browser/components/sessionstore/test/browser_248970_b_perwindowpb.js
deleted file mode 100644
index f5775cd5b..000000000
--- a/browser/components/sessionstore/test/browser_248970_b_perwindowpb.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test (B) for Bug 248970 **/
- waitForExplicitFinish();
-
- let windowsToClose = [];
- let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
- let filePath = file.path;
- let fieldList = {
- "//input[@name='input']": Date.now().toString(),
- "//input[@name='spaced 1']": Math.random().toString(),
- "//input[3]": "three",
- "//input[@type='checkbox']": true,
- "//input[@name='uncheck']": false,
- "//input[@type='radio'][1]": false,
- "//input[@type='radio'][2]": true,
- "//input[@type='radio'][3]": false,
- "//select": 2,
- "//select[@multiple]": [1, 3],
- "//textarea[1]": "",
- "//textarea[2]": "Some text... " + Math.random(),
- "//textarea[3]": "Some more text\n" + new Date(),
- "//input[@type='file']": filePath
- };
-
- registerCleanupFunction(function* () {
- for (let win of windowsToClose) {
- yield BrowserTestUtils.closeWindow(win);
- }
- });
-
- function test(aLambda) {
- try {
- return aLambda() || true;
- } catch(ex) { }
- return false;
- }
-
- function getElementByXPath(aTab, aQuery) {
- let doc = aTab.linkedBrowser.contentDocument;
- let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
- return doc.evaluate(aQuery, doc, null, xptype, null).singleNodeValue;
- }
-
- function setFormValue(aTab, aQuery, aValue) {
- let node = getElementByXPath(aTab, aQuery);
- if (typeof aValue == "string")
- node.value = aValue;
- else if (typeof aValue == "boolean")
- node.checked = aValue;
- else if (typeof aValue == "number")
- node.selectedIndex = aValue;
- else
- Array.forEach(node.options, (aOpt, aIx) =>
- (aOpt.selected = aValue.indexOf(aIx) > -1));
- }
-
- function compareFormValue(aTab, aQuery, aValue) {
- let node = getElementByXPath(aTab, aQuery);
- if (!node)
- return false;
- if (node instanceof Ci.nsIDOMHTMLInputElement)
- return aValue == (node.type == "checkbox" || node.type == "radio" ?
- node.checked : node.value);
- if (node instanceof Ci.nsIDOMHTMLTextAreaElement)
- return aValue == node.value;
- if (!node.multiple)
- return aValue == node.selectedIndex;
- return Array.every(node.options, (aOpt, aIx) =>
- (aValue.indexOf(aIx) > -1) == aOpt.selected);
- }
-
- //////////////////////////////////////////////////////////////////
- // Test (B) : Session data restoration between windows //
- //////////////////////////////////////////////////////////////////
-
- let rootDir = getRootDirectory(gTestPath);
- const testURL = rootDir + "browser_248970_b_sample.html";
- const testURL2 = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_248970_b_sample.html";
-
- whenNewWindowLoaded({ private: false }, function(aWin) {
- windowsToClose.push(aWin);
-
- // get closed tab count
- let count = ss.getClosedTabCount(aWin);
- let max_tabs_undo =
- Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo");
- ok(0 <= count && count <= max_tabs_undo,
- "getClosedTabCount should return zero or at most max_tabs_undo");
-
- // setup a state for tab (A) so we can check later that is restored
- let key = "key";
- let value = "Value " + Math.random();
- let state = { entries: [{ url: testURL }], extData: { key: value } };
-
- // public session, add new tab: (A)
- let tab_A = aWin.gBrowser.addTab(testURL);
- ss.setTabState(tab_A, JSON.stringify(state));
- promiseBrowserLoaded(tab_A.linkedBrowser).then(() => {
- // make sure that the next closed tab will increase getClosedTabCount
- Services.prefs.setIntPref(
- "browser.sessionstore.max_tabs_undo", max_tabs_undo + 1)
-
- // populate tab_A with form data
- for (let i in fieldList)
- setFormValue(tab_A, i, fieldList[i]);
-
- // public session, close tab: (A)
- aWin.gBrowser.removeTab(tab_A);
-
- // verify that closedTabCount increased
- ok(ss.getClosedTabCount(aWin) > count,
- "getClosedTabCount has increased after closing a tab");
-
- // verify tab: (A), in undo list
- let tab_A_restored = test(() => ss.undoCloseTab(aWin, 0));
- ok(tab_A_restored, "a tab is in undo list");
- promiseTabRestored(tab_A_restored).then(() => {
- is(testURL, tab_A_restored.linkedBrowser.currentURI.spec,
- "it's the same tab that we expect");
- aWin.gBrowser.removeTab(tab_A_restored);
-
- whenNewWindowLoaded({ private: true }, function(aWin) {
- windowsToClose.push(aWin);
-
- // setup a state for tab (B) so we can check that its duplicated
- // properly
- let key1 = "key1";
- let value1 = "Value " + Math.random();
- let state1 = {
- entries: [{ url: testURL2 }], extData: { key1: value1 }
- };
-
- let tab_B = aWin.gBrowser.addTab(testURL2);
- promiseTabState(tab_B, state1).then(() => {
- // populate tab: (B) with different form data
- for (let item in fieldList)
- setFormValue(tab_B, item, fieldList[item]);
-
- // duplicate tab: (B)
- let tab_C = aWin.gBrowser.duplicateTab(tab_B);
- promiseTabRestored(tab_C).then(() => {
- // verify the correctness of the duplicated tab
- is(ss.getTabValue(tab_C, key1), value1,
- "tab successfully duplicated - correct state");
-
- for (let item in fieldList)
- ok(compareFormValue(tab_C, item, fieldList[item]),
- "The value for \"" + item + "\" was correctly duplicated");
-
- // private browsing session, close tab: (C) and (B)
- aWin.gBrowser.removeTab(tab_C);
- aWin.gBrowser.removeTab(tab_B);
-
- finish();
- });
- });
- });
- });
- });
- });
-}
diff --git a/browser/components/sessionstore/test/browser_248970_b_sample.html b/browser/components/sessionstore/test/browser_248970_b_sample.html
deleted file mode 100644
index 76c3ae1aa..000000000
--- a/browser/components/sessionstore/test/browser_248970_b_sample.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<meta charset="utf-8">
-<title>Test for bug 248970</title>
-
-<h3>Text Fields</h3>
-<input type="text" name="input">
-<input type="text" name="spaced 1">
-<input>
-
-<h3>Checkboxes and Radio buttons</h3>
-<input type="checkbox" name="check"> Check 1
-<input type="checkbox" name="uncheck" checked> Check 2
-<p>
-<input type="radio" name="group" value="1"> Radio 1
-<input type="radio" name="group" value="some"> Radio 2
-<input type="radio" name="group" checked> Radio 3
-
-<h3>Selects</h3>
-<select name="any">
- <option value="1"> Select 1
- <option value="some"> Select 2
- <option>Select 3
-</select>
-<select multiple="multiple">
- <option value=1> Multi-select 1
- <option value=2> Multi-select 2
- <option value=3> Multi-select 3
- <option value=4> Multi-select 4
-</select>
-
-<h3>Text Areas</h3>
-<textarea name="testarea"></textarea>
-<textarea name="sized one" rows="5" cols="25"></textarea>
-<textarea></textarea>
-
-<h3>File Selector</h3>
-<input type="file">
diff --git a/browser/components/sessionstore/test/browser_339445.js b/browser/components/sessionstore/test/browser_339445.js
deleted file mode 100644
index c38a6cb18..000000000
--- a/browser/components/sessionstore/test/browser_339445.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-add_task(function* test() {
- /** Test for Bug 339445 **/
-
- let testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_339445_sample.html";
-
- let tab = gBrowser.addTab(testURL);
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- yield ContentTask.spawn(tab.linkedBrowser, null, function() {
- let doc = content.document;
- is(doc.getElementById("storageTestItem").textContent, "PENDING",
- "sessionStorage value has been set");
- });
-
- let tab2 = gBrowser.duplicateTab(tab);
- yield promiseTabRestored(tab2);
-
- yield ContentTask.spawn(tab2.linkedBrowser, null, function() {
- let doc2 = content.document;
- is(doc2.getElementById("storageTestItem").textContent, "SUCCESS",
- "sessionStorage value has been duplicated");
- });
-
- // clean up
- yield Promise.all([ BrowserTestUtils.removeTab(tab2),
- BrowserTestUtils.removeTab(tab) ]);
-});
diff --git a/browser/components/sessionstore/test/browser_339445_sample.html b/browser/components/sessionstore/test/browser_339445_sample.html
deleted file mode 100644
index 32656a8d9..000000000
--- a/browser/components/sessionstore/test/browser_339445_sample.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<meta charset="utf-8">
-<title>Test for bug 339445</title>
-
-storageTestItem = <span id="storageTestItem">FAIL</span>
-
-<!--
- storageTestItem's textContent will be one of the following:
- * FAIL : sessionStorage wasn't available
- * PENDING : the test value has been initialized on first load
- * SUCCESS : the test value was correctly retrieved
--->
-
-<script type="application/javascript">
- document.getElementById("storageTestItem").textContent =
- sessionStorage["storageTestItem"] || "PENDING";
- sessionStorage["storageTestItem"] = "SUCCESS";
-</script>
diff --git a/browser/components/sessionstore/test/browser_345898.js b/browser/components/sessionstore/test/browser_345898.js
deleted file mode 100644
index bd4a46e69..000000000
--- a/browser/components/sessionstore/test/browser_345898.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 345898 **/
-
- function test(aLambda) {
- try {
- aLambda();
- return false;
- }
- catch (ex) {
- return ex.name == "NS_ERROR_ILLEGAL_VALUE" ||
- ex.name == "NS_ERROR_FAILURE";
- }
- }
-
- // all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
- ok(test(() => ss.getWindowState({})),
- "Invalid window for getWindowState throws");
- ok(test(() => ss.setWindowState({}, "", false)),
- "Invalid window for setWindowState throws");
- ok(test(() => ss.getTabState({})),
- "Invalid tab for getTabState throws");
- ok(test(() => ss.setTabState({}, "{}")),
- "Invalid tab state for setTabState throws");
- ok(test(() => ss.setTabState({}, JSON.stringify({ entries: [] }))),
- "Invalid tab for setTabState throws");
- ok(test(() => ss.duplicateTab({}, {})),
- "Invalid tab for duplicateTab throws");
- ok(test(() => ss.duplicateTab({}, gBrowser.selectedTab)),
- "Invalid window for duplicateTab throws");
- ok(test(() => ss.getClosedTabData({})),
- "Invalid window for getClosedTabData throws");
- ok(test(() => ss.undoCloseTab({}, 0)),
- "Invalid window for undoCloseTab throws");
- ok(test(() => ss.undoCloseTab(window, -1)),
- "Invalid index for undoCloseTab throws");
- ok(test(() => ss.getWindowValue({}, "")),
- "Invalid window for getWindowValue throws");
- ok(test(() => ss.setWindowValue({}, "", "")),
- "Invalid window for setWindowValue throws");
-}
diff --git a/browser/components/sessionstore/test/browser_350525.js b/browser/components/sessionstore/test/browser_350525.js
deleted file mode 100644
index 1d87b3754..000000000
--- a/browser/components/sessionstore/test/browser_350525.js
+++ /dev/null
@@ -1,102 +0,0 @@
-"use strict";
-
-add_task(function* setup() {
- yield SpecialPowers.pushPrefEnv({
- set: [["dom.ipc.processCount", 1]]
- });
-})
-
-add_task(function* () {
- /** Test for Bug 350525 **/
-
- function test(aLambda) {
- try {
- return aLambda() || true;
- }
- catch (ex) { }
- return false;
- }
-
- ////////////////////////////
- // setWindowValue, et al. //
- ////////////////////////////
- let key = "Unique name: " + Date.now();
- let value = "Unique value: " + Math.random();
-
- // test adding
- ok(test(() => ss.setWindowValue(window, key, value)), "set a window value");
-
- // test retrieving
- is(ss.getWindowValue(window, key), value, "stored window value matches original");
-
- // test deleting
- ok(test(() => ss.deleteWindowValue(window, key)), "delete the window value");
-
- // value should not exist post-delete
- is(ss.getWindowValue(window, key), "", "window value was deleted");
-
- // test deleting a non-existent value
- ok(test(() => ss.deleteWindowValue(window, key)), "delete non-existent window value");
-
- /////////////////////////
- // setTabValue, et al. //
- /////////////////////////
- key = "Unique name: " + Math.random();
- value = "Unique value: " + Date.now();
- let tab = gBrowser.addTab();
- tab.linkedBrowser.stop();
-
- // test adding
- ok(test(() => ss.setTabValue(tab, key, value)), "store a tab value");
-
- // test retrieving
- is(ss.getTabValue(tab, key), value, "stored tab value match original");
-
- // test deleting
- ok(test(() => ss.deleteTabValue(tab, key)), "delete the tab value");
-
- // value should not exist post-delete
- is(ss.getTabValue(tab, key), "", "tab value was deleted");
-
- // test deleting a non-existent value
- ok(test(() => ss.deleteTabValue(tab, key)), "delete non-existent tab value");
-
- // clean up
- yield promiseRemoveTab(tab);
-
- /////////////////////////////////////
- // getClosedTabCount, undoCloseTab //
- /////////////////////////////////////
-
- // get closed tab count
- let count = ss.getClosedTabCount(window);
- let max_tabs_undo = gPrefService.getIntPref("browser.sessionstore.max_tabs_undo");
- ok(0 <= count && count <= max_tabs_undo,
- "getClosedTabCount returns zero or at most max_tabs_undo");
-
- // create a new tab
- let testURL = "about:";
- tab = gBrowser.addTab(testURL);
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- // make sure that the next closed tab will increase getClosedTabCount
- gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo + 1);
- registerCleanupFunction(() => gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo"));
-
- // remove tab
- yield promiseRemoveTab(tab);
-
- // getClosedTabCount
- let newcount = ss.getClosedTabCount(window);
- ok(newcount > count, "after closing a tab, getClosedTabCount has been incremented");
-
- // undoCloseTab
- tab = test(() => ss.undoCloseTab(window, 0));
- ok(tab, "undoCloseTab doesn't throw")
-
- yield promiseTabRestored(tab);
- is(tab.linkedBrowser.currentURI.spec, testURL, "correct tab was reopened");
-
- // clean up
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_354894_perwindowpb.js b/browser/components/sessionstore/test/browser_354894_perwindowpb.js
deleted file mode 100644
index bf80cd710..000000000
--- a/browser/components/sessionstore/test/browser_354894_perwindowpb.js
+++ /dev/null
@@ -1,474 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Checks that restoring the last browser window in session is actually
- * working.
- *
- * @see https://bugzilla.mozilla.org/show_bug.cgi?id=354894
- * @note It is implicitly tested that restoring the last window works when
- * non-browser windows are around. The "Run Tests" window as well as the main
- * browser window (wherein the test code gets executed) won't be considered
- * browser windows. To achiveve this said main browser window has it's windowtype
- * attribute modified so that it's not considered a browser window any longer.
- * This is crucial, because otherwise there would be two browser windows around,
- * said main test window and the one opened by the tests, and hence the new
- * logic wouldn't be executed at all.
- * @note Mac only tests the new notifications, as restoring the last window is
- * not enabled on that platform (platform shim; the application is kept running
- * although there are no windows left)
- * @note There is a difference when closing a browser window with
- * BrowserTryToCloseWindow() as opposed to close(). The former will make
- * nsSessionStore restore a window next time it gets a chance and will post
- * notifications. The latter won't.
- */
-
-// Some urls that might be opened in tabs and/or popups
-// Do not use about:blank:
-// That one is reserved for special purposes in the tests
-const TEST_URLS = ["about:mozilla", "about:buildconfig"];
-
-// Number of -request notifications to except
-// remember to adjust when adding new tests
-const NOTIFICATIONS_EXPECTED = 6;
-
-// Window features of popup windows
-const POPUP_FEATURES = "toolbar=no,resizable=no,status=no";
-
-// Window features of browser windows
-const CHROME_FEATURES = "chrome,all,dialog=no";
-
-const IS_MAC = navigator.platform.match(/Mac/);
-
-/**
- * Returns an Object with two properties:
- * open (int):
- * A count of how many non-closed navigator:browser windows there are.
- * winstates (int):
- * A count of how many windows there are in the SessionStore state.
- */
-function getBrowserWindowsCount() {
- let open = 0;
- let e = Services.wm.getEnumerator("navigator:browser");
- while (e.hasMoreElements()) {
- if (!e.getNext().closed)
- ++open;
- }
-
- let winstates = JSON.parse(ss.getBrowserState()).windows.length;
-
- return { open, winstates };
-}
-
-add_task(function* setup() {
- // Make sure we've only got one browser window to start with
- let { open, winstates } = getBrowserWindowsCount();
- is(open, 1, "Should only be one open window");
- is(winstates, 1, "Should only be one window state in SessionStore");
-
- // This test takes some time to run, and it could timeout randomly.
- // So we require a longer timeout. See bug 528219.
- requestLongerTimeout(3);
-
- // Make the main test window not count as a browser window any longer
- let oldWinType = document.documentElement.getAttribute("windowtype");
- document.documentElement.setAttribute("windowtype", "navigator:testrunner");
-
- registerCleanupFunction(() => {
- document.documentElement.setAttribute("windowtype", "navigator:browser");
- });
-});
-
-/**
- * Sets up one of our tests by setting the right preferences, and
- * then opening up a browser window preloaded with some tabs.
- *
- * @param options (Object)
- * An object that can contain the following properties:
- *
- * private:
- * Whether or not the opened window should be private.
- *
- * denyFirst:
- * Whether or not the first window that attempts to close
- * via closeWindowForRestoration should be denied.
- *
- * @param testFunction (Function*)
- * A generator function that yields Promises to be run
- * once the test has been set up.
- *
- * @returns Promise
- * Resolves once the test has been cleaned up.
- */
-let setupTest = Task.async(function*(options, testFunction) {
- yield pushPrefs(["browser.startup.page", 3],
- ["browser.tabs.warnOnClose", false]);
-
- // Observe these, and also use to count the number of hits
- let observing = {
- "browser-lastwindow-close-requested": 0,
- "browser-lastwindow-close-granted": 0
- };
-
- /**
- * Helper: Will observe and handle the notifications for us
- */
- let hitCount = 0;
- function observer(aCancel, aTopic, aData) {
- // count so that we later may compare
- observing[aTopic]++;
-
- // handle some tests
- if (options.denyFirst && ++hitCount == 1) {
- aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
- }
- }
-
- for (let o in observing) {
- Services.obs.addObserver(observer, o, false);
- }
-
- let private = options.private || false;
- let newWin = yield promiseNewWindowLoaded({ private });
-
- injectTestTabs(newWin);
-
- yield testFunction(newWin, observing);
-
- let count = getBrowserWindowsCount();
- is(count.open, 0, "Got right number of open windows");
- is(count.winstates, 1, "Got right number of stored window states");
-
- for (let o in observing) {
- Services.obs.removeObserver(observer, o);
- }
-
- yield popPrefs();
-});
-
-/**
- * Loads a TEST_URLS into a browser window.
- *
- * @param win (Window)
- * The browser window to load the tabs in
- */
-function injectTestTabs(win) {
- TEST_URLS.forEach(function (url) {
- win.gBrowser.addTab(url);
- });
-}
-
-/**
- * Attempts to close a window via BrowserTryToCloseWindow so that
- * we get the browser-lastwindow-close-requested and
- * browser-lastwindow-close-granted observer notifications.
- *
- * @param win (Window)
- * The window to try to close
- * @returns Promise
- * Resolves to true if the window closed, or false if the window
- * was denied the ability to close.
- */
-function closeWindowForRestoration(win) {
- return new Promise((resolve) => {
- let closePromise = BrowserTestUtils.windowClosed(win);
- win.BrowserTryToCloseWindow();
- if (!win.closed) {
- resolve(false);
- return;
- }
-
- closePromise.then(() => {
- resolve(true);
- });
- });
-}
-
-/**
- * Normal in-session restore
- *
- * @note: Non-Mac only
- *
- * Should do the following:
- * 1. Open a new browser window
- * 2. Add some tabs
- * 3. Close that window
- * 4. Opening another window
- * 5. Checks that state is restored
- */
-add_task(function* test_open_close_normal() {
- if (IS_MAC) {
- return;
- }
-
- yield setupTest({ denyFirst: true }, function*(newWin, obs) {
- let closed = yield closeWindowForRestoration(newWin);
- ok(!closed, "First close request should have been denied");
-
- closed = yield closeWindowForRestoration(newWin);
- ok(closed, "Second close request should be accepted");
-
- newWin = yield promiseNewWindowLoaded();
- is(newWin.gBrowser.browsers.length, TEST_URLS.length + 2,
- "Restored window in-session with otherpopup windows around");
-
- // Note that this will not result in the the browser-lastwindow-close
- // notifications firing for this other newWin.
- yield BrowserTestUtils.closeWindow(newWin);
-
- // setupTest gave us a window which was denied for closing once, and then
- // closed.
- is(obs["browser-lastwindow-close-requested"], 2,
- "Got expected browser-lastwindow-close-requested notifications");
- is(obs["browser-lastwindow-close-granted"], 1,
- "Got expected browser-lastwindow-close-granted notifications");
- });
-});
-
-/**
- * PrivateBrowsing in-session restore
- *
- * @note: Non-Mac only
- *
- * Should do the following:
- * 1. Open a new browser window A
- * 2. Add some tabs
- * 3. Close the window A as the last window
- * 4. Open a private browsing window B
- * 5. Make sure that B didn't restore the tabs from A
- * 6. Close private browsing window B
- * 7. Open a new window C
- * 8. Make sure that new window C has restored tabs from A
- */
-add_task(function* test_open_close_private_browsing() {
- if (IS_MAC) {
- return;
- }
-
- yield setupTest({}, function*(newWin, obs) {
- let closed = yield closeWindowForRestoration(newWin);
- ok(closed, "Should be able to close the window");
-
- newWin = yield promiseNewWindowLoaded({private: true});
- is(newWin.gBrowser.browsers.length, 1,
- "Did not restore in private browing mode");
-
- closed = yield closeWindowForRestoration(newWin);
- ok(closed, "Should be able to close the window");
-
- newWin = yield promiseNewWindowLoaded();
- is(newWin.gBrowser.browsers.length, TEST_URLS.length + 2,
- "Restored tabs in a new non-private window");
-
- // Note that this will not result in the the browser-lastwindow-close
- // notifications firing for this other newWin.
- yield BrowserTestUtils.closeWindow(newWin);
-
- // We closed two windows with closeWindowForRestoration, and both
- // should have been successful.
- is(obs["browser-lastwindow-close-requested"], 2,
- "Got expected browser-lastwindow-close-requested notifications");
- is(obs["browser-lastwindow-close-granted"], 2,
- "Got expected browser-lastwindow-close-granted notifications");
- });
-});
-
-/**
- * Open some popup windows to check those aren't restored, but the browser
- * window is.
- *
- * @note: Non-Mac only
- *
- * Should do the following:
- * 1. Open a new browser window
- * 2. Add some tabs
- * 3. Open some popups
- * 4. Add another tab to one popup (so that it gets stored) and close it again
- * 5. Close the browser window
- * 6. Open another browser window
- * 7. Make sure that the tabs of the closed browser window, but not the popup,
- * are restored
- */
-add_task(function* test_open_close_window_and_popup() {
- if (IS_MAC) {
- return;
- }
-
- yield setupTest({}, function*(newWin, obs) {
- let popupPromise = BrowserTestUtils.waitForNewWindow();
- openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[0]);
- let popup = yield popupPromise;
-
- let popup2Promise = BrowserTestUtils.waitForNewWindow();
- openDialog(location, "popup2", POPUP_FEATURES, TEST_URLS[1]);
- let popup2 = yield popup2Promise;
-
- popup2.gBrowser.addTab(TEST_URLS[0]);
-
- let closed = yield closeWindowForRestoration(newWin);
- ok(closed, "Should be able to close the window");
-
- yield BrowserTestUtils.closeWindow(popup2);
-
- newWin = yield promiseNewWindowLoaded();
-
- is(newWin.gBrowser.browsers.length, TEST_URLS.length + 2,
- "Restored window and associated tabs in session");
-
- yield BrowserTestUtils.closeWindow(popup);
- yield BrowserTestUtils.closeWindow(newWin);
-
- // We closed one window with closeWindowForRestoration, and it should
- // have been successful.
- is(obs["browser-lastwindow-close-requested"], 1,
- "Got expected browser-lastwindow-close-requested notifications");
- is(obs["browser-lastwindow-close-granted"], 1,
- "Got expected browser-lastwindow-close-granted notifications");
- });
-});
-
-/**
- * Open some popup window to check it isn't restored. Instead nothing at all
- * should be restored
- *
- * @note: Non-Mac only
- *
- * Should do the following:
- * 1. Open a popup
- * 2. Add another tab to the popup (so that it gets stored) and close it again
- * 3. Open a window
- * 4. Check that nothing at all is restored
- * 5. Open two browser windows and close them again
- * 6. undoCloseWindow() one
- * 7. Open another browser window
- * 8. Check that nothing at all is restored
- */
-add_task(function* test_open_close_only_popup() {
- if (IS_MAC) {
- return;
- }
-
- yield setupTest({}, function*(newWin, obs) {
- // We actually don't care about the initial window in this test.
- yield BrowserTestUtils.closeWindow(newWin);
-
- // This will cause nsSessionStore to restore a window the next time it
- // gets a chance.
- let popupPromise = BrowserTestUtils.waitForNewWindow();
- openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
- let popup = yield popupPromise;
-
- is(popup.gBrowser.browsers.length, 1,
- "Did not restore the popup window (1)");
-
- let closed = yield closeWindowForRestoration(popup);
- ok(closed, "Should be able to close the window");
-
- popupPromise = BrowserTestUtils.waitForNewWindow();
- openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
- popup = yield popupPromise;
-
- popup.gBrowser.addTab(TEST_URLS[0]);
- is(popup.gBrowser.browsers.length, 2,
- "Did not restore to the popup window (2)");
-
- yield BrowserTestUtils.closeWindow(popup);
-
- newWin = yield promiseNewWindowLoaded();
- isnot(newWin.gBrowser.browsers.length, 2,
- "Did not restore the popup window");
- is(TEST_URLS.indexOf(newWin.gBrowser.browsers[0].currentURI.spec), -1,
- "Did not restore the popup window (2)");
- yield BrowserTestUtils.closeWindow(newWin);
-
- // We closed one popup window with closeWindowForRestoration, and popup
- // windows should never fire the browser-lastwindow notifications.
- is(obs["browser-lastwindow-close-requested"], 0,
- "Got expected browser-lastwindow-close-requested notifications");
- is(obs["browser-lastwindow-close-granted"], 0,
- "Got expected browser-lastwindow-close-granted notifications");
- });
-});
-
-/**
- * Open some windows and do undoCloseWindow. This should prevent any
- * restoring later in the test
- *
- * @note: Non-Mac only
- *
- * Should do the following:
- * 1. Open two browser windows and close them again
- * 2. undoCloseWindow() one
- * 3. Open another browser window
- * 4. Make sure nothing at all is restored
- */
-add_task(function* test_open_close_restore_from_popup() {
- if (IS_MAC) {
- return;
- }
-
- yield setupTest({}, function*(newWin, obs) {
- let newWin2 = yield promiseNewWindowLoaded();
- yield injectTestTabs(newWin2);
-
- let closed = yield closeWindowForRestoration(newWin);
- ok(closed, "Should be able to close the window");
- closed = yield closeWindowForRestoration(newWin2);
- ok(closed, "Should be able to close the window");
-
- let counts = getBrowserWindowsCount();
- is(counts.open, 0, "Got right number of open windows");
- is(counts.winstates, 1, "Got right number of window states");
-
- newWin = undoCloseWindow(0);
- yield BrowserTestUtils.waitForEvent(newWin, "load");
-
- // Make sure we wait until this window is restored.
- yield BrowserTestUtils.waitForEvent(newWin.gBrowser.tabContainer,
- "SSTabRestored");
-
- newWin2 = yield promiseNewWindowLoaded();
-
- is(newWin2.gBrowser.browsers.length, 1,
- "Did not restore, as undoCloseWindow() was last called");
- is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1,
- "Did not restore, as undoCloseWindow() was last called (2)");
-
- counts = getBrowserWindowsCount();
- is(counts.open, 2, "Got right number of open windows");
- is(counts.winstates, 3, "Got right number of window states");
-
- yield BrowserTestUtils.closeWindow(newWin);
- yield BrowserTestUtils.closeWindow(newWin2);
-
- counts = getBrowserWindowsCount();
- is(counts.open, 0, "Got right number of open windows");
- is(counts.winstates, 1, "Got right number of window states");
- });
-});
-
-/**
- * Test if closing can be denied on Mac.
- * @note: Mac only
- */
-add_task(function* test_mac_notifications() {
- if (!IS_MAC) {
- return;
- }
-
- yield setupTest({ denyFirst: true }, function*(newWin, obs) {
- let closed = yield closeWindowForRestoration(newWin);
- ok(!closed, "First close attempt should be denied");
- closed = yield closeWindowForRestoration(newWin);
- ok(closed, "Second close attempt should be granted");
-
- // We tried closing once, and got denied. Then we tried again and
- // succeeded. That means 2 close requests, and 1 close granted.
- is(obs["browser-lastwindow-close-requested"], 2,
- "Got expected browser-lastwindow-close-requested notifications");
- is(obs["browser-lastwindow-close-granted"], 1,
- "Got expected browser-lastwindow-close-granted notifications");
- });
-});
-
diff --git a/browser/components/sessionstore/test/browser_367052.js b/browser/components/sessionstore/test/browser_367052.js
deleted file mode 100644
index 3cc89a66c..000000000
--- a/browser/components/sessionstore/test/browser_367052.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function* () {
- // make sure that the next closed tab will increase getClosedTabCount
- let max_tabs_undo = gPrefService.getIntPref("browser.sessionstore.max_tabs_undo");
- gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo + 1);
- registerCleanupFunction(() => gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo"));
-
- // Empty the list of closed tabs.
- while (ss.getClosedTabCount(window)) {
- ss.forgetClosedTab(window, 0);
- }
-
- // restore a blank tab
- let tab = gBrowser.addTab("about:");
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- let count = yield promiseSHistoryCount(tab.linkedBrowser);
- ok(count >= 1, "the new tab does have at least one history entry");
-
- yield promiseTabState(tab, {entries: []});
-
- // We may have a different sessionHistory object if the tab
- // switched from non-remote to remote.
- count = yield promiseSHistoryCount(tab.linkedBrowser);
- is(count, 0, "the tab was restored without any history whatsoever");
-
- yield promiseRemoveTab(tab);
- is(ss.getClosedTabCount(window), 0,
- "The closed blank tab wasn't added to Recently Closed Tabs");
-});
-
-function promiseSHistoryCount(browser) {
- return ContentTask.spawn(browser, null, function* () {
- return docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory.count;
- });
-}
diff --git a/browser/components/sessionstore/test/browser_393716.js b/browser/components/sessionstore/test/browser_393716.js
deleted file mode 100644
index c59bdcc8b..000000000
--- a/browser/components/sessionstore/test/browser_393716.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = "about:config";
-
-/**
- * Bug 393716 - Basic tests for getTabState(), setTabState(), and duplicateTab().
- */
-add_task(function test_set_tabstate() {
- let key = "Unique key: " + Date.now();
- let value = "Unique value: " + Math.random();
-
- // create a new tab
- let tab = gBrowser.addTab(URL);
- ss.setTabValue(tab, key, value);
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- // get the tab's state
- yield TabStateFlusher.flush(tab.linkedBrowser);
- let state = ss.getTabState(tab);
- ok(state, "get the tab's state");
-
- // verify the tab state's integrity
- state = JSON.parse(state);
- ok(state instanceof Object && state.entries instanceof Array && state.entries.length > 0,
- "state object seems valid");
- ok(state.entries.length == 1 && state.entries[0].url == URL,
- "Got the expected state object (test URL)");
- ok(state.extData && state.extData[key] == value,
- "Got the expected state object (test manually set tab value)");
-
- // clean up
- gBrowser.removeTab(tab);
-});
-
-add_task(function test_set_tabstate_and_duplicate() {
- let key2 = "key2";
- let value2 = "Value " + Math.random();
- let value3 = "Another value: " + Date.now();
- let state = { entries: [{ url: URL }], extData: { key2: value2 } };
-
- // create a new tab
- let tab = gBrowser.addTab();
- // set the tab's state
- ss.setTabState(tab, JSON.stringify(state));
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- // verify the correctness of the restored tab
- ok(ss.getTabValue(tab, key2) == value2 && tab.linkedBrowser.currentURI.spec == URL,
- "the tab's state was correctly restored");
-
- // add text data
- yield setInputValue(tab.linkedBrowser, {id: "textbox", value: value3});
-
- // duplicate the tab
- let tab2 = ss.duplicateTab(window, tab);
- yield promiseTabRestored(tab2);
-
- // verify the correctness of the duplicated tab
- ok(ss.getTabValue(tab2, key2) == value2 &&
- tab2.linkedBrowser.currentURI.spec == URL,
- "correctly duplicated the tab's state");
- let textbox = yield getInputValue(tab2.linkedBrowser, {id: "textbox"});
- is(textbox, value3, "also duplicated text data");
-
- // clean up
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_394759_basic.js b/browser/components/sessionstore/test/browser_394759_basic.js
deleted file mode 100644
index 1b1650e27..000000000
--- a/browser/components/sessionstore/test/browser_394759_basic.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TEST_URL = "data:text/html;charset=utf-8,<input%20id=txt>" +
- "<input%20type=checkbox%20id=chk>";
-
-Cu.import("resource:///modules/sessionstore/SessionStore.jsm");
-
-/**
- * This test ensures that closing a window is a reversible action. We will
- * close the the window, restore it and check that all data has been restored.
- * This includes window-specific data as well as form data for tabs.
- */
-function test() {
- waitForExplicitFinish();
-
- let uniqueKey = "bug 394759";
- let uniqueValue = "unik" + Date.now();
- let uniqueText = "pi != " + Math.random();
-
- // Clear the list of closed windows.
- forgetClosedWindows();
-
- provideWindow(function onTestURLLoaded(newWin) {
- newWin.gBrowser.addTab().linkedBrowser.stop();
-
- // Mark the window with some unique data to be restored later on.
- ss.setWindowValue(newWin, uniqueKey, uniqueValue);
- let [txt, chk] = newWin.content.document.querySelectorAll("#txt, #chk");
- txt.value = uniqueText;
-
- let browser = newWin.gBrowser.selectedBrowser;
- setInputChecked(browser, {id: "chk", checked: true}).then(() => {
- BrowserTestUtils.closeWindow(newWin).then(() => {
- is(ss.getClosedWindowCount(), 1,
- "The closed window was added to Recently Closed Windows");
-
- let data = SessionStore.getClosedWindowData(false);
-
- // Verify that non JSON serialized data is the same as JSON serialized data.
- is(JSON.stringify(data), ss.getClosedWindowData(),
- "Non-serialized data is the same as serialized data")
-
- ok(data[0].title == TEST_URL && JSON.stringify(data[0]).indexOf(uniqueText) > -1,
- "The closed window data was stored correctly");
-
- // Reopen the closed window and ensure its integrity.
- let newWin2 = ss.undoCloseWindow(0);
-
- ok(newWin2 instanceof ChromeWindow,
- "undoCloseWindow actually returned a window");
- is(ss.getClosedWindowCount(), 0,
- "The reopened window was removed from Recently Closed Windows");
-
- // SSTabRestored will fire more than once, so we need to make sure we count them.
- let restoredTabs = 0;
- let expectedTabs = data[0].tabs.length;
- newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
- ++restoredTabs;
- info("Restored tab " + restoredTabs + "/" + expectedTabs);
- if (restoredTabs < expectedTabs) {
- return;
- }
-
- is(restoredTabs, expectedTabs, "Correct number of tabs restored");
- newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
-
- is(newWin2.gBrowser.tabs.length, 2,
- "The window correctly restored 2 tabs");
- is(newWin2.gBrowser.currentURI.spec, TEST_URL,
- "The window correctly restored the URL");
-
- let [txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
- ok(txt.value == uniqueText && chk.checked,
- "The window correctly restored the form");
- is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
- "The window correctly restored the data associated with it");
-
- // Clean up.
- BrowserTestUtils.closeWindow(newWin2).then(finish);
- }, true);
- });
- });
- }, TEST_URL);
-}
-
-function setInputChecked(browser, data) {
- return sendMessage(browser, "ss-test:setInputChecked", data);
-}
diff --git a/browser/components/sessionstore/test/browser_394759_behavior.js b/browser/components/sessionstore/test/browser_394759_behavior.js
deleted file mode 100644
index aa74dc061..000000000
--- a/browser/components/sessionstore/test/browser_394759_behavior.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Test helper function that opens a series of windows, closes them
- * and then checks the closed window data from SessionStore against
- * expected results.
- *
- * @param windowsToOpen (Array)
- * An array of Objects, where each object must define a single
- * property "isPopup" for whether or not the opened window should
- * be a popup.
- * @param expectedResults (Array)
- * An Object with two properies: mac and other, where each points
- * at yet another Object, with the following properties:
- *
- * popup (int):
- * The number of popup windows we expect to be in the closed window
- * data.
- * normal (int):
- * The number of normal windows we expect to be in the closed window
- * data.
- * @returns Promise
- */
-function testWindows(windowsToOpen, expectedResults) {
- return Task.spawn(function*() {
- for (let winData of windowsToOpen) {
- let features = "chrome,dialog=no," +
- (winData.isPopup ? "all=no" : "all");
- let url = "http://example.com/?window=" + windowsToOpen.length;
-
- let openWindowPromise = BrowserTestUtils.waitForNewWindow(true, url);
- openDialog(getBrowserURL(), "", features, url);
- let win = yield openWindowPromise;
- yield BrowserTestUtils.closeWindow(win);
- }
-
- let closedWindowData = JSON.parse(ss.getClosedWindowData());
- let numPopups = closedWindowData.filter(function(el, i, arr) {
- return el.isPopup;
- }).length;
- let numNormal = ss.getClosedWindowCount() - numPopups;
- // #ifdef doesn't work in browser-chrome tests, so do a simple regex on platform
- let oResults = navigator.platform.match(/Mac/) ? expectedResults.mac
- : expectedResults.other;
- is(numPopups, oResults.popup,
- "There were " + oResults.popup + " popup windows to reopen");
- is(numNormal, oResults.normal,
- "There were " + oResults.normal + " normal windows to repoen");
- });
-}
-
-add_task(function* test_closed_window_states() {
- // This test takes quite some time, and timeouts frequently, so we require
- // more time to run.
- // See Bug 518970.
- requestLongerTimeout(2);
-
- let windowsToOpen = [{isPopup: false},
- {isPopup: false},
- {isPopup: true},
- {isPopup: true},
- {isPopup: true}];
- let expectedResults = {mac: {popup: 3, normal: 0},
- other: {popup: 3, normal: 1}};
-
- yield testWindows(windowsToOpen, expectedResults);
-
-
- let windowsToOpen2 = [{isPopup: false},
- {isPopup: false},
- {isPopup: false},
- {isPopup: false},
- {isPopup: false}];
- let expectedResults2 = {mac: {popup: 0, normal: 3},
- other: {popup: 0, normal: 3}};
-
- yield testWindows(windowsToOpen2, expectedResults2);
-}); \ No newline at end of file
diff --git a/browser/components/sessionstore/test/browser_394759_perwindowpb.js b/browser/components/sessionstore/test/browser_394759_perwindowpb.js
deleted file mode 100644
index 83eec3070..000000000
--- a/browser/components/sessionstore/test/browser_394759_perwindowpb.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TESTS = [
- { url: "about:config",
- key: "bug 394759 Non-PB",
- value: "uniq" + r() },
- { url: "about:mozilla",
- key: "bug 394759 PB",
- value: "uniq" + r() },
-];
-
-function promiseTestOpenCloseWindow(aIsPrivate, aTest) {
- return Task.spawn(function*() {
- let win = yield BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
- win.gBrowser.selectedBrowser.loadURI(aTest.url);
- yield promiseBrowserLoaded(win.gBrowser.selectedBrowser);
- yield Promise.resolve();
- // Mark the window with some unique data to be restored later on.
- ss.setWindowValue(win, aTest.key, aTest.value);
- yield TabStateFlusher.flushWindow(win);
- // Close.
- yield BrowserTestUtils.closeWindow(win);
- });
-}
-
-function promiseTestOnWindow(aIsPrivate, aValue) {
- return Task.spawn(function*() {
- let win = yield BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
- yield TabStateFlusher.flushWindow(win);
- let data = JSON.parse(ss.getClosedWindowData())[0];
- is(ss.getClosedWindowCount(), 1, "Check that the closed window count hasn't changed");
- ok(JSON.stringify(data).indexOf(aValue) > -1,
- "Check the closed window data was stored correctly");
- registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
- });
-}
-
-add_task(function* init() {
- forgetClosedWindows();
- while (ss.getClosedTabCount(window) > 0) {
- ss.forgetClosedTab(window, 0);
- }
-});
-
-add_task(function* main() {
- yield promiseTestOpenCloseWindow(false, TESTS[0]);
- yield promiseTestOpenCloseWindow(true, TESTS[1]);
- yield promiseTestOnWindow(false, TESTS[0].value);
- yield promiseTestOnWindow(true, TESTS[0].value);
-});
-
diff --git a/browser/components/sessionstore/test/browser_394759_purge.js b/browser/components/sessionstore/test/browser_394759_purge.js
deleted file mode 100644
index 75144aba1..000000000
--- a/browser/components/sessionstore/test/browser_394759_purge.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/ForgetAboutSite.jsm");
-
-function waitForClearHistory(aCallback) {
- let observer = {
- observe: function(aSubject, aTopic, aData) {
- Services.obs.removeObserver(this, "browser:purge-domain-data");
- setTimeout(aCallback, 0);
- }
- };
- Services.obs.addObserver(observer, "browser:purge-domain-data", false);
-}
-
-function test() {
- waitForExplicitFinish();
- // utility functions
- function countClosedTabsByTitle(aClosedTabList, aTitle) {
- return aClosedTabList.filter(aData => aData.title == aTitle).length;
- }
-
- function countOpenTabsByTitle(aOpenTabList, aTitle) {
- return aOpenTabList.filter(aData => aData.entries.some(aEntry => aEntry.title == aTitle)).length;
- }
-
- // backup old state
- let oldState = ss.getBrowserState();
- let oldState_wins = JSON.parse(oldState).windows.length;
- if (oldState_wins != 1)
- ok(false, "oldState in test_purge has " + oldState_wins + " windows instead of 1");
-
- // create a new state for testing
- const REMEMBER = Date.now(), FORGET = Math.random();
- let testState = {
- windows: [ { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 } ],
- _closedWindows : [
- // _closedWindows[0]
- {
- tabs: [
- { entries: [{ url: "http://example.com/", title: REMEMBER }] },
- { entries: [{ url: "http://mozilla.org/", title: FORGET }] }
- ],
- selected: 2,
- title: "mozilla.org",
- _closedTabs: []
- },
- // _closedWindows[1]
- {
- tabs: [
- { entries: [{ url: "http://mozilla.org/", title: FORGET }] },
- { entries: [{ url: "http://example.com/", title: REMEMBER }] },
- { entries: [{ url: "http://example.com/", title: REMEMBER }] },
- { entries: [{ url: "http://mozilla.org/", title: FORGET }] },
- { entries: [{ url: "http://example.com/", title: REMEMBER }] }
- ],
- selected: 5,
- _closedTabs: []
- },
- // _closedWindows[2]
- {
- tabs: [
- { entries: [{ url: "http://example.com/", title: REMEMBER }] }
- ],
- selected: 1,
- _closedTabs: [
- {
- state: {
- entries: [
- { url: "http://mozilla.org/", title: FORGET },
- { url: "http://mozilla.org/again", title: "doesn't matter" }
- ]
- },
- pos: 1,
- title: FORGET
- },
- {
- state: {
- entries: [
- { url: "http://example.com", title: REMEMBER }
- ]
- },
- title: REMEMBER
- }
- ]
- }
- ]
- };
-
- // set browser to test state
- ss.setBrowserState(JSON.stringify(testState));
-
- // purge domain & check that we purged correctly for closed windows
- ForgetAboutSite.removeDataFromDomain("mozilla.org");
- waitForClearHistory(function() {
- let closedWindowData = JSON.parse(ss.getClosedWindowData());
-
- // First set of tests for _closedWindows[0] - tests basics
- let win = closedWindowData[0];
- is(win.tabs.length, 1, "1 tab was removed");
- is(countOpenTabsByTitle(win.tabs, FORGET), 0,
- "The correct tab was removed");
- is(countOpenTabsByTitle(win.tabs, REMEMBER), 1,
- "The correct tab was remembered");
- is(win.selected, 1, "Selected tab has changed");
- is(win.title, REMEMBER, "The window title was correctly updated");
-
- // Test more complicated case
- win = closedWindowData[1];
- is(win.tabs.length, 3, "2 tabs were removed");
- is(countOpenTabsByTitle(win.tabs, FORGET), 0,
- "The correct tabs were removed");
- is(countOpenTabsByTitle(win.tabs, REMEMBER), 3,
- "The correct tabs were remembered");
- is(win.selected, 3, "Selected tab has changed");
- is(win.title, REMEMBER, "The window title was correctly updated");
-
- // Tests handling of _closedTabs
- win = closedWindowData[2];
- is(countClosedTabsByTitle(win._closedTabs, REMEMBER), 1,
- "The correct number of tabs were removed, and the correct ones");
- is(countClosedTabsByTitle(win._closedTabs, FORGET), 0,
- "All tabs to be forgotten were indeed removed");
-
- // restore pre-test state
- ss.setBrowserState(oldState);
- finish();
- });
-}
diff --git a/browser/components/sessionstore/test/browser_423132.js b/browser/components/sessionstore/test/browser_423132.js
deleted file mode 100644
index 584002cff..000000000
--- a/browser/components/sessionstore/test/browser_423132.js
+++ /dev/null
@@ -1,59 +0,0 @@
-"use strict";
-
-/**
- * Tests that cookies are stored and restored correctly
- * by sessionstore (bug 423132).
- */
-add_task(function*() {
- const testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_423132_sample.html";
-
- Services.cookies.removeAll();
- // make sure that sessionstore.js can be forced to be created by setting
- // the interval pref to 0
- yield SpecialPowers.pushPrefEnv({
- set: [["browser.sessionstore.interval", 0]]
- });
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let browser = win.gBrowser.selectedBrowser;
- browser.loadURI(testURL);
- yield BrowserTestUtils.browserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
-
- // get the sessionstore state for the window
- let state = ss.getWindowState(win);
-
- // verify our cookie got set during pageload
- let enumerator = Services.cookies.enumerator;
- let cookie;
- let i = 0;
- while (enumerator.hasMoreElements()) {
- cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
- i++;
- }
- Assert.equal(i, 1, "expected one cookie");
-
- // remove the cookie
- Services.cookies.removeAll();
-
- // restore the window state
- ss.setWindowState(win, state, true);
-
- // at this point, the cookie should be restored...
- enumerator = Services.cookies.enumerator;
- let cookie2;
- while (enumerator.hasMoreElements()) {
- cookie2 = enumerator.getNext().QueryInterface(Ci.nsICookie);
- if (cookie.name == cookie2.name)
- break;
- }
- is(cookie.name, cookie2.name, "cookie name successfully restored");
- is(cookie.value, cookie2.value, "cookie value successfully restored");
- is(cookie.path, cookie2.path, "cookie path successfully restored");
-
- // clean up
- Services.cookies.removeAll();
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/sessionstore/test/browser_423132_sample.html b/browser/components/sessionstore/test/browser_423132_sample.html
deleted file mode 100644
index 6ff7e7aa3..000000000
--- a/browser/components/sessionstore/test/browser_423132_sample.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <script type="text/javascript">
- // generate an enormous random number...
- var r = Math.floor(Math.random() * Math.pow(2, 62)).toString();
-
- // ... and use it to set a randomly named cookie
- document.cookie = r + "=value; path=/ohai";
- </script>
-<body>
-</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_447951.js b/browser/components/sessionstore/test/browser_447951.js
deleted file mode 100644
index a7b6a5ee8..000000000
--- a/browser/components/sessionstore/test/browser_447951.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 447951 **/
-
- waitForExplicitFinish();
- const baseURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_447951_sample.html#";
-
- // Make sure the functionality added in bug 943339 doesn't affect the results
- gPrefService.setIntPref("browser.sessionstore.max_serialize_back", -1);
- gPrefService.setIntPref("browser.sessionstore.max_serialize_forward", -1);
- registerCleanupFunction(function () {
- gPrefService.clearUserPref("browser.sessionstore.max_serialize_back");
- gPrefService.clearUserPref("browser.sessionstore.max_serialize_forward");
- });
-
- let tab = gBrowser.addTab();
- promiseBrowserLoaded(tab.linkedBrowser).then(() => {
- let tabState = { entries: [] };
- let max_entries = gPrefService.getIntPref("browser.sessionhistory.max_entries");
- for (let i = 0; i < max_entries; i++)
- tabState.entries.push({ url: baseURL + i });
-
- promiseTabState(tab, tabState).then(() => {
- return TabStateFlusher.flush(tab.linkedBrowser);
- }).then(() => {
- tabState = JSON.parse(ss.getTabState(tab));
- is(tabState.entries.length, max_entries, "session history filled to the limit");
- is(tabState.entries[0].url, baseURL + 0, "... but not more");
-
- // visit yet another anchor (appending it to session history)
- ContentTask.spawn(tab.linkedBrowser, null, function() {
- content.window.document.querySelector("a").click();
- }).then(flushAndCheck);
-
- function flushAndCheck() {
- TabStateFlusher.flush(tab.linkedBrowser).then(check);
- }
-
- function check() {
- tabState = JSON.parse(ss.getTabState(tab));
- if (tab.linkedBrowser.currentURI.spec != baseURL + "end") {
- // It may take a few passes through the event loop before we
- // get the right URL.
- executeSoon(flushAndCheck);
- return;
- }
-
- is(tab.linkedBrowser.currentURI.spec, baseURL + "end",
- "the new anchor was loaded");
- is(tabState.entries[tabState.entries.length - 1].url, baseURL + "end",
- "... and ignored");
- is(tabState.entries[0].url, baseURL + 1,
- "... and the first item was removed");
-
- // clean up
- gBrowser.removeTab(tab);
- finish();
- }
- });
- });
-}
diff --git a/browser/components/sessionstore/test/browser_447951_sample.html b/browser/components/sessionstore/test/browser_447951_sample.html
deleted file mode 100644
index 00282f25e..000000000
--- a/browser/components/sessionstore/test/browser_447951_sample.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Testcase for bug 447951</title>
-
-<a href="#end">click me</a>
diff --git a/browser/components/sessionstore/test/browser_454908.js b/browser/components/sessionstore/test/browser_454908.js
deleted file mode 100644
index fb8206e2f..000000000
--- a/browser/components/sessionstore/test/browser_454908.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_454908_sample.html";
-const PASS = "pwd-" + Math.random();
-
-/**
- * Bug 454908 - Don't save/restore values of password fields.
- */
-add_task(function* test_dont_save_passwords() {
- // Make sure we do save form data.
- Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
-
- // Add a tab with a password field.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Fill in some values.
- let usernameValue = "User " + Math.random();
- yield setInputValue(browser, {id: "username", value: usernameValue});
- yield setInputValue(browser, {id: "passwd", value: PASS});
-
- // Close and restore the tab.
- yield promiseRemoveTab(tab);
- tab = ss.undoCloseTab(window, 0);
- browser = tab.linkedBrowser;
- yield promiseTabRestored(tab);
-
- // Check that password fields aren't saved/restored.
- let username = yield getInputValue(browser, {id: "username"});
- is(username, usernameValue, "username was saved/restored");
- let passwd = yield getInputValue(browser, {id: "passwd"});
- is(passwd, "", "password wasn't saved/restored");
-
- // Write to disk and read our file.
- yield forceSaveState();
- yield promiseForEachSessionRestoreFile((state, key) =>
- // Ensure that we have not saved our password.
- ok(!state.includes(PASS), "password has not been written to file " + key)
- );
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_454908_sample.html b/browser/components/sessionstore/test/browser_454908_sample.html
deleted file mode 100644
index 02f40bf20..000000000
--- a/browser/components/sessionstore/test/browser_454908_sample.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<title>Test for bug 454908</title>
-
-<h3>Dummy Login</h3>
-<form>
-<p>Username: <input type="text" id="username">
-<p>Password: <input type="password" id="passwd">
-</form>
diff --git a/browser/components/sessionstore/test/browser_456342.js b/browser/components/sessionstore/test/browser_456342.js
deleted file mode 100644
index d7ed33ee5..000000000
--- a/browser/components/sessionstore/test/browser_456342.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_456342_sample.xhtml";
-
-/**
- * Bug 456342 - Restore values from non-standard input field types.
- */
-add_task(function test_restore_nonstandard_input_values() {
- // Add tab with various non-standard input field types.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Fill in form values.
- let expectedValue = Math.random();
- yield setFormElementValues(browser, {value: expectedValue});
-
- // Remove tab and check collected form data.
- yield promiseRemoveTab(tab);
- let undoItems = JSON.parse(ss.getClosedTabData(window));
- let savedFormData = undoItems[0].state.formdata;
-
- let countGood = 0, countBad = 0;
- for (let id of Object.keys(savedFormData.id)) {
- if (savedFormData.id[id] == expectedValue) {
- countGood++;
- } else {
- countBad++;
- }
- }
-
- for (let exp of Object.keys(savedFormData.xpath)) {
- if (savedFormData.xpath[exp] == expectedValue) {
- countGood++;
- } else {
- countBad++;
- }
- }
-
- is(countGood, 4, "Saved text for non-standard input fields");
- is(countBad, 0, "Didn't save text for ignored field types");
-});
-
-function setFormElementValues(browser, data) {
- return sendMessage(browser, "ss-test:setFormElementValues", data);
-}
diff --git a/browser/components/sessionstore/test/browser_456342_sample.xhtml b/browser/components/sessionstore/test/browser_456342_sample.xhtml
deleted file mode 100644
index a08777a8d..000000000
--- a/browser/components/sessionstore/test/browser_456342_sample.xhtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head><title>Test for bug 456342</title></head>
-
-<body>
-<form>
-<h3>Non-standard &lt;input&gt;s</h3>
-<p>Search <input type="search" id="searchTerm"/></p>
-<p>Image Search: <input type="image search" /></p>
-<p>Autocomplete: <input type="autocomplete" name="fill-in"/></p>
-<p>Mistyped: <input type="txet" name="mistyped"/></p>
-
-<h3>Ignored types</h3>
-<input type="hidden" name="hideme"/>
-<input type="HIDDEN" name="hideme2"/>
-<input type="submit" name="submit"/>
-<input type="reset" name="reset"/>
-<input type="image" name="image"/>
-<input type="button" name="button"/>
-<input type="password" name="password"/>
-<input type="PassWord" name="password2"/>
-<input type="PASSWORD" name="password3"/>
-<input autocomplete="off" name="auto1"/>
-<input type="text" autocomplete="OFF" name="auto2"/>
-<textarea autocomplete="off" name="auto3"/>
-<select autocomplete="off" name="auto4">
- <option value="1" selected="true"/>
- <option value="2"/>
- <option value="3"/>
-</select>
-</form>
-
-</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_459906.js b/browser/components/sessionstore/test/browser_459906.js
deleted file mode 100644
index cadab3e5c..000000000
--- a/browser/components/sessionstore/test/browser_459906.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 459906 **/
-
- waitForExplicitFinish();
-
- let testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_459906_sample.html";
- let uniqueValue = "<b>Unique:</b> " + Date.now();
-
- var frameCount = 0;
- let tab = gBrowser.addTab(testURL);
- tab.linkedBrowser.addEventListener("load", function(aEvent) {
- // wait for all frames to load completely
- if (frameCount++ < 2)
- return;
- tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
- let iframes = tab.linkedBrowser.contentWindow.frames;
- iframes[1].document.body.innerHTML = uniqueValue;
-
- frameCount = 0;
- let tab2 = gBrowser.duplicateTab(tab);
- tab2.linkedBrowser.addEventListener("load", function(aEvent) {
- // wait for all frames to load (and reload!) completely
- if (frameCount++ < 2)
- return;
- tab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
- executeSoon(function() {
- let iframes = tab2.linkedBrowser.contentWindow.frames;
- if (iframes[1].document.body.innerHTML !== uniqueValue) {
- // Poll again the value, since we can't ensure to run
- // after SessionStore has injected innerHTML value.
- // See bug 521802.
- info("Polling for innerHTML value");
- setTimeout(arguments.callee, 100);
- return;
- }
-
- is(iframes[1].document.body.innerHTML, uniqueValue,
- "rich textarea's content correctly duplicated");
-
- let innerDomain = null;
- try {
- innerDomain = iframes[0].document.domain;
- }
- catch (ex) { /* throws for chrome: documents */ }
- is(innerDomain, "mochi.test", "XSS exploit prevented!");
-
- // clean up
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-
- finish();
- });
- }, true);
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_459906_empty.html b/browser/components/sessionstore/test/browser_459906_empty.html
deleted file mode 100644
index e01aaa339..000000000
--- a/browser/components/sessionstore/test/browser_459906_empty.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<title>Cross Domain File for bug 459906</title>
-
-cheers from localhost
diff --git a/browser/components/sessionstore/test/browser_459906_sample.html b/browser/components/sessionstore/test/browser_459906_sample.html
deleted file mode 100644
index 39b789776..000000000
--- a/browser/components/sessionstore/test/browser_459906_sample.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!-- Testcase originally by David Bloom <bloom@google.com> -->
-
-<!DOCTYPE html>
-<title>Test for bug 459906</title>
-
-<body>
-<iframe src="data:text/html;charset=utf-8,not_on_localhost"></iframe>
-<iframe></iframe>
-
-<script type="application/javascript">
- var loadCount = 0;
- frames[0].addEventListener("DOMContentLoaded", handleLoad, false);
- frames[1].addEventListener("DOMContentLoaded", handleLoad, false);
- function handleLoad() {
- if (++loadCount < 2)
- return;
- frames[0].removeEventListener("DOMContentLoaded", handleLoad, false);
- frames[1].removeEventListener("DOMContentLoaded", handleLoad, false);
- frames[0].document.designMode = "on";
- frames[0].document.__defineGetter__("designMode", function() {
- // inject a cross domain file ...
- var documentInjected = false;
- document.getElementsByTagName("iframe")[0].onload =
- function() { documentInjected = true; };
- frames[0].location = "browser_459906_empty.html";
-
- // ... and ensure that it has time to load
- for (var c = 0; !documentInjected && c < 20; c++) {
- var r = new XMLHttpRequest();
- r.open("GET", location.href, false);
- r.overrideMimeType("text/plain");
- r.send(null);
- }
-
- return "on";
- });
-
- frames[1].document.designMode = "on";
- };
-</script>
-</body>
diff --git a/browser/components/sessionstore/test/browser_461634.js b/browser/components/sessionstore/test/browser_461634.js
deleted file mode 100644
index 01d3a4b0d..000000000
--- a/browser/components/sessionstore/test/browser_461634.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Cu.import("resource:///modules/sessionstore/SessionStore.jsm");
-
-function test() {
- /** Test for Bug 461634 **/
-
- waitForExplicitFinish();
-
- const REMEMBER = Date.now(), FORGET = Math.random();
- let test_state = { windows: [{ "tabs": [{ "entries": [] }], _closedTabs: [
- { state: { entries: [{ url: "http://www.example.net/" }] }, title: FORGET },
- { state: { entries: [{ url: "http://www.example.net/" }] }, title: REMEMBER },
- { state: { entries: [{ url: "http://www.example.net/" }] }, title: FORGET },
- { state: { entries: [{ url: "http://www.example.net/" }] }, title: REMEMBER },
- ] }] };
- let remember_count = 2;
-
- function countByTitle(aClosedTabList, aTitle) {
- return aClosedTabList.filter(aData => aData.title == aTitle).length;
- }
-
- function testForError(aFunction) {
- try {
- aFunction();
- return false;
- }
- catch (ex) {
- return ex.name == "NS_ERROR_ILLEGAL_VALUE";
- }
- }
-
- // Open a window and add the above closed tab list.
- let newWin = openDialog(location, "", "chrome,all,dialog=no");
- promiseWindowLoaded(newWin).then(() => {
- gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
- test_state.windows[0]._closedTabs.length);
- ss.setWindowState(newWin, JSON.stringify(test_state), true);
-
- let closedTabs = SessionStore.getClosedTabData(newWin, false);
-
- // Verify that non JSON serialized data is the same as JSON serialized data.
- is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
- "Non-serialized data is the same as serialized data")
-
- is(closedTabs.length, test_state.windows[0]._closedTabs.length,
- "Closed tab list has the expected length");
- is(countByTitle(closedTabs, FORGET),
- test_state.windows[0]._closedTabs.length - remember_count,
- "The correct amout of tabs are to be forgotten");
- is(countByTitle(closedTabs, REMEMBER), remember_count,
- "Everything is set up");
-
- // All of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE.
- ok(testForError(() => ss.forgetClosedTab({}, 0)),
- "Invalid window for forgetClosedTab throws");
- ok(testForError(() => ss.forgetClosedTab(newWin, -1)),
- "Invalid tab for forgetClosedTab throws");
- ok(testForError(() => ss.forgetClosedTab(newWin, test_state.windows[0]._closedTabs.length + 1)),
- "Invalid tab for forgetClosedTab throws");
-
- // Remove third tab, then first tab.
- ss.forgetClosedTab(newWin, 2);
- ss.forgetClosedTab(newWin, null);
-
- closedTabs = SessionStore.getClosedTabData(newWin, false);
-
- // Verify that non JSON serialized data is the same as JSON serialized data.
- is(JSON.stringify(closedTabs), SessionStore.getClosedTabData(newWin),
- "Non-serialized data is the same as serialized data")
-
- is(closedTabs.length, remember_count,
- "The correct amout of tabs was removed");
- is(countByTitle(closedTabs, FORGET), 0,
- "All tabs specifically forgotten were indeed removed");
- is(countByTitle(closedTabs, REMEMBER), remember_count,
- "... and tabs not specifically forgetten weren't");
-
- // Clean up.
- gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
- BrowserTestUtils.closeWindow(newWin).then(finish);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_461743.js b/browser/components/sessionstore/test/browser_461743.js
deleted file mode 100644
index 263fff5f2..000000000
--- a/browser/components/sessionstore/test/browser_461743.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 461743 **/
-
- waitForExplicitFinish();
-
- let testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_461743_sample.html";
-
- let frameCount = 0;
- let tab = gBrowser.addTab(testURL);
- tab.linkedBrowser.addEventListener("load", function(aEvent) {
- // Wait for all frames to load completely.
- if (frameCount++ < 2)
- return;
- tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
- let tab2 = gBrowser.duplicateTab(tab);
- tab2.linkedBrowser.addEventListener("461743", function(aEvent) {
- tab2.linkedBrowser.removeEventListener("461743", arguments.callee, true);
- is(aEvent.data, "done", "XSS injection was attempted");
-
- executeSoon(function() {
- let iframes = tab2.linkedBrowser.contentWindow.frames;
- let innerHTML = iframes[1].document.body.innerHTML;
- isnot(innerHTML, Components.utils.reportError.toString(),
- "chrome access denied!");
-
- // Clean up.
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-
- finish();
- });
- }, true, true);
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_461743_sample.html b/browser/components/sessionstore/test/browser_461743_sample.html
deleted file mode 100644
index 80c9e612a..000000000
--- a/browser/components/sessionstore/test/browser_461743_sample.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
-
-<!DOCTYPE html>
-<title>Test for bug 461743</title>
-
-<body>
-<iframe src="data:text/html;charset=utf-8,empty"></iframe>
-<iframe></iframe>
-
-<script type="application/javascript">
- var chromeUrl = "chrome://global/content/mozilla.xhtml";
- var exploitUrl = "javascript:try { document.body.innerHTML = Components.utils.reportError; } catch (ex) { }";
-
- var loadCount = 0;
- frames[0].addEventListener("DOMContentLoaded", handleLoad, false);
- frames[1].addEventListener("DOMContentLoaded", handleLoad, false);
- function handleLoad() {
- if (++loadCount < 2)
- return;
- frames[0].removeEventListener("DOMContentLoaded", handleLoad, false);
- frames[1].removeEventListener("DOMContentLoaded", handleLoad, false);
-
- var flip = 0;
- MutationEvent.prototype.toString = function() {
- return flip++ == 0 ? chromeUrl : exploitUrl;
- };
-
- var href = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(frames[1].location), "href").get;
- var loadChrome = { handleEvent: href };
- var loadExploit = { handleEvent: href };
-
- function delay() {
- var xhr = new XMLHttpRequest();
- xhr.open("GET", location.href, false);
- xhr.send(null);
- }
- function done() {
- var event = new MessageEvent('461743', { bubbles: true, cancelable: false,
- data: "done", origin: location.href,
- source: window });
- document.dispatchEvent(event);
- frames[0].document.removeEventListener("DOMNodeInserted", loadChrome, true);
- frames[0].document.removeEventListener("DOMNodeInserted", delay, true);
- frames[0].document.removeEventListener("DOMNodeInserted", loadExploit, true);
- frames[0].document.removeEventListener("DOMNodeInserted", done, true);
- }
-
- frames[0].document.addEventListener("DOMNodeInserted", loadChrome, true);
- frames[0].document.addEventListener("DOMNodeInserted", delay, true);
- frames[0].document.addEventListener("DOMNodeInserted", loadExploit, true);
- frames[0].document.addEventListener("DOMNodeInserted", done, true);
-
- frames[0].document.designMode = "on";
- };
-</script>
-</body>
diff --git a/browser/components/sessionstore/test/browser_463205.js b/browser/components/sessionstore/test/browser_463205.js
deleted file mode 100644
index ad3f22794..000000000
--- a/browser/components/sessionstore/test/browser_463205.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_463205_sample.html";
-
-/**
- * Bug 463205 - Check URLs before restoring form data to make sure a malicious
- * website can't modify frame URLs and make us inject form data into the wrong
- * web pages.
- */
-add_task(function test_check_urls_before_restoring() {
- // Add a blank tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Restore form data with a valid URL.
- yield promiseTabState(tab, getState(URL));
-
- let value = yield getInputValue(browser, {id: "text"});
- is(value, "foobar", "value was restored");
-
- // Restore form data with an invalid URL.
- yield promiseTabState(tab, getState("http://example.com/"));
-
- value = yield getInputValue(browser, {id: "text"});
- is(value, "", "value was not restored");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-function getState(url) {
- return JSON.stringify({
- entries: [{url: URL}],
- formdata: {url: url, id: {text: "foobar"}}
- });
-}
diff --git a/browser/components/sessionstore/test/browser_463205_sample.html b/browser/components/sessionstore/test/browser_463205_sample.html
deleted file mode 100644
index 6591401b6..000000000
--- a/browser/components/sessionstore/test/browser_463205_sample.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>bug 463205</title>
-
-<body>
- <input type="text" id="text" />
-</body>
diff --git a/browser/components/sessionstore/test/browser_463206.js b/browser/components/sessionstore/test/browser_463206.js
deleted file mode 100644
index 99ee8373e..000000000
--- a/browser/components/sessionstore/test/browser_463206.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const TEST_URL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_463206_sample.html";
-
-add_task(function* () {
- // Add a new tab.
- let tab = gBrowser.addTab(TEST_URL);
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- // "Type in" some random values.
- yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
- function typeText(aTextField, aValue) {
- aTextField.value = aValue;
-
- let event = aTextField.ownerDocument.createEvent("UIEvents");
- event.initUIEvent("input", true, true, aTextField.ownerGlobal, 0);
- aTextField.dispatchEvent(event);
- }
-
- typeText(content.document.getElementById("out1"), Date.now());
- typeText(content.document.getElementsByName("1|#out2")[0], Math.random());
- typeText(content.frames[0].frames[1].document.getElementById("in1"), new Date());
- });
-
- // Duplicate the tab.
- let tab2 = gBrowser.duplicateTab(tab);
- yield promiseTabRestored(tab2);
-
- // Query a few values from the top and its child frames.
- yield ContentTask.spawn(tab2.linkedBrowser, null, function* () {
- Assert.notEqual(content.document.getElementById("out1").value,
- content.frames[1].document.getElementById("out1").value,
- "text isn't reused for frames");
- Assert.notEqual(content.document.getElementsByName("1|#out2")[0].value,
- "", "text containing | and # is correctly restored");
- Assert.equal(content.frames[1].document.getElementById("out2").value,
- "", "id prefixes can't be faked");
- // Disabled for now, Bug 588077
- //Assert.equal(content.frames[0].frames[1].document.getElementById("in1").value,
- // "", "id prefixes aren't mixed up");
- Assert.equal(content.frames[1].frames[0].document.getElementById("in1").value,
- "", "id prefixes aren't mixed up");
- });
-
- // Cleanup.
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_463206_sample.html b/browser/components/sessionstore/test/browser_463206_sample.html
deleted file mode 100644
index 0d31f2906..000000000
--- a/browser/components/sessionstore/test/browser_463206_sample.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
-
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Test for bug 463206</title>
-
-<iframe src="data:text/html;charset=utf-8,<iframe></iframe><iframe%20src='data:text/html;charset=utf-8,<input%2520id=%2522in1%2522>'></iframe>"></iframe>
-<iframe src="data:text/html;charset=utf-8,<input%20id='out1'><input%20id='out2'><iframe%20src='data:text/html;charset=utf-8,<input%2520id=%2522in1%2522>'>"></iframe>
-
-<input id="out1">
-<input name="1|#out2">
diff --git a/browser/components/sessionstore/test/browser_464199.js b/browser/components/sessionstore/test/browser_464199.js
deleted file mode 100644
index 36f07832c..000000000
--- a/browser/components/sessionstore/test/browser_464199.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/ForgetAboutSite.jsm");
-
-function waitForClearHistory(aCallback) {
- let observer = {
- observe: function(aSubject, aTopic, aData) {
- Services.obs.removeObserver(this, "browser:purge-domain-data");
- setTimeout(aCallback, 0);
- }
- };
- Services.obs.addObserver(observer, "browser:purge-domain-data", false);
-}
-
-function test() {
- /** Test for Bug 464199 **/
-
- waitForExplicitFinish();
-
- const REMEMBER = Date.now(), FORGET = Math.random();
- let test_state = { windows: [{ "tabs": [{ "entries": [] }], _closedTabs: [
- { state: { entries: [{ url: "http://www.example.net/" }] }, title: FORGET },
- { state: { entries: [{ url: "http://www.example.org/" }] }, title: REMEMBER },
- { state: { entries: [{ url: "http://www.example.net/" },
- { url: "http://www.example.org/" }] }, title: FORGET },
- { state: { entries: [{ url: "http://example.net/" }] }, title: FORGET },
- { state: { entries: [{ url: "http://sub.example.net/" }] }, title: FORGET },
- { state: { entries: [{ url: "http://www.example.net:8080/" }] }, title: FORGET },
- { state: { entries: [{ url: "about:license" }] }, title: REMEMBER },
- { state: { entries: [{ url: "http://www.example.org/frameset",
- children: [
- { url: "http://www.example.org/frame" },
- { url: "http://www.example.org:8080/frame2" }
- ] }] }, title: REMEMBER },
- { state: { entries: [{ url: "http://www.example.org/frameset",
- children: [
- { url: "http://www.example.org/frame" },
- { url: "http://www.example.net/frame" }
- ] }] }, title: FORGET },
- { state: { entries: [{ url: "http://www.example.org/form",
- formdata: { id: { "url": "http://www.example.net/" } }
- }] }, title: REMEMBER },
- { state: { entries: [{ url: "http://www.example.org/form" }],
- extData: { "setTabValue": "http://example.net:80" } }, title: REMEMBER }
- ] }] };
- let remember_count = 5;
-
- function countByTitle(aClosedTabList, aTitle) {
- return aClosedTabList.filter(aData => aData.title == aTitle).length;
- }
-
- // open a window and add the above closed tab list
- let newWin = openDialog(location, "", "chrome,all,dialog=no");
- promiseWindowLoaded(newWin).then(() => {
- gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
- test_state.windows[0]._closedTabs.length);
- ss.setWindowState(newWin, JSON.stringify(test_state), true);
-
- let closedTabs = JSON.parse(ss.getClosedTabData(newWin));
- is(closedTabs.length, test_state.windows[0]._closedTabs.length,
- "Closed tab list has the expected length");
- is(countByTitle(closedTabs, FORGET),
- test_state.windows[0]._closedTabs.length - remember_count,
- "The correct amout of tabs are to be forgotten");
- is(countByTitle(closedTabs, REMEMBER), remember_count,
- "Everything is set up.");
-
- ForgetAboutSite.removeDataFromDomain("example.net");
- waitForClearHistory(function() {
- closedTabs = JSON.parse(ss.getClosedTabData(newWin));
- is(closedTabs.length, remember_count,
- "The correct amout of tabs was removed");
- is(countByTitle(closedTabs, FORGET), 0,
- "All tabs to be forgotten were indeed removed");
- is(countByTitle(closedTabs, REMEMBER), remember_count,
- "... and tabs to be remembered weren't.");
-
- // clean up
- gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
- BrowserTestUtils.closeWindow(newWin).then(finish);
- });
- });
-}
diff --git a/browser/components/sessionstore/test/browser_464620_a.html b/browser/components/sessionstore/test/browser_464620_a.html
deleted file mode 100644
index 1f03c92c7..000000000
--- a/browser/components/sessionstore/test/browser_464620_a.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
-
-<title>Test for bug 464620 (injection on input)</title>
-
-<iframe></iframe>
-<iframe onload="setup()"></iframe>
-
-<script>
- var targetUrl = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_464620_xd.html";
- var firstPass;
-
- function setup() {
- if (firstPass !== undefined)
- return;
- firstPass = frames[1].location.href == "about:blank";
- if (firstPass) {
- frames[0].location = 'data:text/html;charset=utf-8,<body onload="if (parent.firstPass) parent.step();"><input id="x" oninput="parent.xss()">XXX</body>';
- }
- frames[1].location = targetUrl;
- }
-
- function step() {
- var x = frames[0].document.getElementById("x");
- if (x.value == "")
- x.value = "ready";
- x.style.display = "none";
- frames[0].document.designMode = "on";
- }
-
- function xss() {
- step();
-
- var documentInjected = false;
- document.getElementsByTagName("iframe")[0].onload =
- function() { documentInjected = true; };
- frames[0].location = targetUrl;
-
- for (var c = 0; !documentInjected && c < 20; c++) {
- var r = new XMLHttpRequest();
- r.open("GET", location.href, false);
- r.overrideMimeType("text/plain");
- r.send(null);
- }
- document.getElementById("state").textContent = "done";
-
- var event = new MessageEvent('464620_a', { bubbles: true, cancelable: false,
- data: "done", origin: location.href,
- source: window });
- document.dispatchEvent(event);
- }
-</script>
-
-<p id="state">pending</p>
diff --git a/browser/components/sessionstore/test/browser_464620_a.js b/browser/components/sessionstore/test/browser_464620_a.js
deleted file mode 100644
index 9756fa703..000000000
--- a/browser/components/sessionstore/test/browser_464620_a.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 464620 (injection on input) **/
-
- waitForExplicitFinish();
-
- let testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_464620_a.html";
-
- var frameCount = 0;
- let tab = gBrowser.addTab(testURL);
- tab.linkedBrowser.addEventListener("load", function(aEvent) {
- // wait for all frames to load completely
- if (frameCount++ < 4)
- return;
- this.removeEventListener("load", arguments.callee, true);
-
- executeSoon(function() {
- frameCount = 0;
- let tab2 = gBrowser.duplicateTab(tab);
- tab2.linkedBrowser.addEventListener("464620_a", function(aEvent) {
- tab2.linkedBrowser.removeEventListener("464620_a", arguments.callee, true);
- is(aEvent.data, "done", "XSS injection was attempted");
-
- // let form restoration complete and take into account the
- // setTimeout(..., 0) in sss_restoreDocument_proxy
- executeSoon(function() {
- setTimeout(function() {
- let win = tab2.linkedBrowser.contentWindow;
- isnot(win.frames[0].document.location, testURL,
- "cross domain document was loaded");
- ok(!/XXX/.test(win.frames[0].document.body.innerHTML),
- "no content was injected");
-
- // clean up
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-
- finish();
- }, 0);
- });
- }, true, true);
- });
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_464620_b.html b/browser/components/sessionstore/test/browser_464620_b.html
deleted file mode 100644
index 8c86d2152..000000000
--- a/browser/components/sessionstore/test/browser_464620_b.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
-
-<title>Test for bug 464620 (injection on DOM node insertion)</title>
-
-<iframe></iframe>
-<iframe></iframe>
-<iframe onload="setup()"></iframe>
-
-<script>
- var targetUrl = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_464620_xd.html";
- var firstPass;
-
- function setup() {
- if (firstPass !== undefined)
- return;
- firstPass = frames[2].location.href == "about:blank";
- if (firstPass) {
- frames[0].location = 'data:text/html;charset=utf-8,<body onload="parent.step()">a</body>';
- frames[1].location = 'data:text/html;charset=utf-8,<body onload="document.designMode=\'on\';">XXX</body>';
- }
- frames[2].location = targetUrl;
- }
-
- 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);
- }
-
- function xss() {
- var documentInjected = false;
- document.getElementsByTagName("iframe")[1].onload =
- function() { documentInjected = true; };
- frames[1].location = targetUrl;
-
- for (var c = 0; !documentInjected && c < 20; c++) {
- var r = new XMLHttpRequest();
- r.open("GET", location.href, false);
- r.overrideMimeType("text/plain");
- r.send(null);
- }
- document.getElementById("state").textContent = "done";
-
- var event = new MessageEvent('464620_b', { bubbles: true, cancelable: false,
- data: "done", origin: location.href,
- source: window });
- document.dispatchEvent(event);
- }
-</script>
-
-<p id="state">pending</p>
diff --git a/browser/components/sessionstore/test/browser_464620_b.js b/browser/components/sessionstore/test/browser_464620_b.js
deleted file mode 100644
index cf23aa460..000000000
--- a/browser/components/sessionstore/test/browser_464620_b.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 464620 (injection on DOM node insertion) **/
-
- waitForExplicitFinish();
-
- let testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_464620_b.html";
-
- var frameCount = 0;
- let tab = gBrowser.addTab(testURL);
- tab.linkedBrowser.addEventListener("load", function(aEvent) {
- // wait for all frames to load completely
- if (frameCount++ < 6)
- return;
- this.removeEventListener("load", arguments.callee, true);
-
- executeSoon(function() {
- frameCount = 0;
- let tab2 = gBrowser.duplicateTab(tab);
- tab2.linkedBrowser.addEventListener("464620_b", function(aEvent) {
- tab2.linkedBrowser.removeEventListener("464620_b", arguments.callee, true);
- is(aEvent.data, "done", "XSS injection was attempted");
-
- // let form restoration complete and take into account the
- // setTimeout(..., 0) in sss_restoreDocument_proxy
- executeSoon(function() {
- setTimeout(function() {
- let win = tab2.linkedBrowser.contentWindow;
- isnot(win.frames[1].document.location, testURL,
- "cross domain document was loaded");
- ok(!/XXX/.test(win.frames[1].document.body.innerHTML),
- "no content was injected");
-
- // clean up
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-
- finish();
- }, 0);
- });
- }, true, true);
- });
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_464620_xd.html b/browser/components/sessionstore/test/browser_464620_xd.html
deleted file mode 100644
index 9ec51c4c7..000000000
--- a/browser/components/sessionstore/test/browser_464620_xd.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<title>Cross Document File for bug 464620</title>
-
-<body onload="document.designMode='on';" bgcolor="red">
- This document is editable.
-</body>
diff --git a/browser/components/sessionstore/test/browser_465215.js b/browser/components/sessionstore/test/browser_465215.js
deleted file mode 100644
index 3a0a7b9c5..000000000
--- a/browser/components/sessionstore/test/browser_465215.js
+++ /dev/null
@@ -1,28 +0,0 @@
-"use strict";
-
-var uniqueName = "bug 465215";
-var uniqueValue1 = "as good as unique: " + Date.now();
-var uniqueValue2 = "as good as unique: " + Math.random();
-
-add_task(function* () {
- // set a unique value on a new, blank tab
- let tab1 = gBrowser.addTab("about:blank");
- yield promiseBrowserLoaded(tab1.linkedBrowser);
- ss.setTabValue(tab1, uniqueName, uniqueValue1);
-
- // duplicate the tab with that value
- let tab2 = ss.duplicateTab(window, tab1);
- yield promiseTabRestored(tab2);
- is(ss.getTabValue(tab2, uniqueName), uniqueValue1, "tab value was duplicated");
-
- ss.setTabValue(tab2, uniqueName, uniqueValue2);
- isnot(ss.getTabValue(tab1, uniqueName), uniqueValue2, "tab values aren't sync'd");
-
- // overwrite the tab with the value which should remove it
- yield promiseTabState(tab1, {entries: []});
- is(ss.getTabValue(tab1, uniqueName), "", "tab value was cleared");
-
- // clean up
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab1);
-});
diff --git a/browser/components/sessionstore/test/browser_465223.js b/browser/components/sessionstore/test/browser_465223.js
deleted file mode 100644
index 04f888b30..000000000
--- a/browser/components/sessionstore/test/browser_465223.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 465223 **/
-
- // test setup
- waitForExplicitFinish();
-
- let uniqueKey1 = "bug 465223.1";
- let uniqueKey2 = "bug 465223.2";
- let uniqueValue1 = "unik" + Date.now();
- let uniqueValue2 = "pi != " + Math.random();
-
- // open a window and set a value on it
- let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
- promiseWindowLoaded(newWin).then(() => {
- ss.setWindowValue(newWin, uniqueKey1, uniqueValue1);
-
- let newState = { windows: [{ tabs:[{ entries: [] }], extData: {} }] };
- newState.windows[0].extData[uniqueKey2] = uniqueValue2;
- ss.setWindowState(newWin, JSON.stringify(newState), false);
-
- is(newWin.gBrowser.tabs.length, 2,
- "original tab wasn't overwritten");
- is(ss.getWindowValue(newWin, uniqueKey1), uniqueValue1,
- "window value wasn't overwritten when the tabs weren't");
- is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue2,
- "new window value was correctly added");
-
- newState.windows[0].extData[uniqueKey2] = uniqueValue1;
- ss.setWindowState(newWin, JSON.stringify(newState), true);
-
- is(newWin.gBrowser.tabs.length, 1,
- "original tabs were overwritten");
- is(ss.getWindowValue(newWin, uniqueKey1), "",
- "window value was cleared");
- is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue1,
- "window value was correctly overwritten");
-
- // clean up
- BrowserTestUtils.closeWindow(newWin).then(finish);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_466937.js b/browser/components/sessionstore/test/browser_466937.js
deleted file mode 100644
index 0a07caa0c..000000000
--- a/browser/components/sessionstore/test/browser_466937.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_466937_sample.html";
-
-/**
- * Bug 466937 - Prevent file stealing with sessionstore.
- */
-add_task(function test_prevent_file_stealing() {
- // Add a tab with some file input fields.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Generate a path to a 'secret' file.
- let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
- file.append("466937_test.file");
- file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
- let testPath = file.path;
-
- // Fill in form values.
- yield setInputValue(browser, {id: "reverse_thief", value: "/home/user/secret2"});
- yield setInputValue(browser, {id: "bystander", value: testPath});
-
- // Duplicate and check form values.
- let tab2 = gBrowser.duplicateTab(tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- let thief = yield getInputValue(browser2, {id: "thief"});
- is(thief, "", "file path wasn't set to text field value");
- let reverse_thief = yield getInputValue(browser2, {id: "reverse_thief"});
- is(reverse_thief, "", "text field value wasn't set to full file path");
- let bystander = yield getInputValue(browser2, {id: "bystander"});
- is(bystander, testPath, "normal case: file path was correctly preserved");
-
- // Cleanup.
- gBrowser.removeTab(tab);
- gBrowser.removeTab(tab2);
-});
diff --git a/browser/components/sessionstore/test/browser_466937_sample.html b/browser/components/sessionstore/test/browser_466937_sample.html
deleted file mode 100644
index 1d46c649a..000000000
--- a/browser/components/sessionstore/test/browser_466937_sample.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
-
-<!DOCTYPE html>
-<meta charset="utf-8">
-<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, false);
- if (!document.location.hash) {
- document.location.hash = "#ready";
- }
- else {
- document.getElementById("thief").type = "file";
- document.getElementById("reverse_thief").type = "text";
- }
- }, false);
-</script>
diff --git a/browser/components/sessionstore/test/browser_467409-backslashplosion.js b/browser/components/sessionstore/test/browser_467409-backslashplosion.js
deleted file mode 100644
index 0e990c614..000000000
--- a/browser/components/sessionstore/test/browser_467409-backslashplosion.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test Summary:
-// 1. Open about:sessionrestore where formdata is a JS object, not a string
-// 1a. Check that #sessionData on the page is readable after JSON.parse (skipped, checking formdata is sufficient)
-// 1b. Check that there are no backslashes in the formdata
-// 1c. Check that formdata doesn't require JSON.parse
-//
-// 2. Use the current state (currently about:sessionrestore with data) and then open that in a new instance of about:sessionrestore
-// 2a. Check that there are no backslashes in the formdata
-// 2b. Check that formdata doesn't require JSON.parse
-//
-// 3. [backwards compat] Use a stringified state as formdata when opening about:sessionrestore
-// 3a. Make sure there are nodes in the tree on about:sessionrestore (skipped, checking formdata is sufficient)
-// 3b. Check that there are no backslashes in the formdata
-// 3c. Check that formdata doesn't require JSON.parse
-
-const CRASH_STATE = {windows: [{tabs: [{entries: [{url: "about:mozilla" }]}]}]};
-const STATE = createEntries(CRASH_STATE);
-const STATE2 = createEntries({windows: [{tabs: [STATE]}]});
-const STATE3 = createEntries(JSON.stringify(CRASH_STATE));
-
-function createEntries(sessionData) {
- return {
- entries: [{url: "about:sessionrestore"}],
- formdata: {id: {sessionData: sessionData}, url: "about:sessionrestore"}
- };
-}
-
-add_task(function test_nested_about_sessionrestore() {
- // Prepare a blank tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // test 1
- yield promiseTabState(tab, STATE);
- yield checkState("test1", tab);
-
- // test 2
- yield promiseTabState(tab, STATE2);
- yield checkState("test2", tab);
-
- // test 3
- yield promiseTabState(tab, STATE3);
- yield checkState("test3", tab);
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-function* checkState(prefix, tab) {
- // Flush and query tab state.
- yield TabStateFlusher.flush(tab.linkedBrowser);
- let {formdata} = JSON.parse(ss.getTabState(tab));
-
- ok(formdata.id["sessionData"], prefix + ": we have form data for about:sessionrestore");
-
- let sessionData_raw = JSON.stringify(formdata.id["sessionData"]);
- ok(!/\\/.test(sessionData_raw), prefix + ": #sessionData contains no backslashes");
- info(sessionData_raw);
-
- let gotError = false;
- try {
- JSON.parse(formdata.id["sessionData"]);
- } catch (e) {
- info(prefix + ": got error: " + e);
- gotError = true;
- }
- ok(gotError, prefix + ": attempting to JSON.parse form data threw error");
-}
diff --git a/browser/components/sessionstore/test/browser_477657.js b/browser/components/sessionstore/test/browser_477657.js
deleted file mode 100644
index 1a8ee3412..000000000
--- a/browser/components/sessionstore/test/browser_477657.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 477657 **/
- waitForExplicitFinish();
-
- let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
- promiseWindowLoaded(newWin).then(() => {
- let newState = { windows: [{
- tabs: [{ entries: [] }],
- _closedTabs: [{
- state: { entries: [{ url: "about:" }]},
- title: "About:"
- }],
- sizemode: "maximized"
- }] };
-
- let uniqueKey = "bug 477657";
- let uniqueValue = "unik" + Date.now();
-
- ss.setWindowValue(newWin, uniqueKey, uniqueValue);
- is(ss.getWindowValue(newWin, uniqueKey), uniqueValue,
- "window value was set before the window was overwritten");
- ss.setWindowState(newWin, JSON.stringify(newState), true);
-
- // use newWin.setTimeout(..., 0) to mirror sss_restoreWindowFeatures
- newWin.setTimeout(function() {
- is(ss.getWindowValue(newWin, uniqueKey), "",
- "window value was implicitly cleared");
-
- is(newWin.windowState, newWin.STATE_MAXIMIZED,
- "the window was maximized");
-
- is(JSON.parse(ss.getClosedTabData(newWin)).length, 1,
- "the closed tab was added before the window was overwritten");
- delete newState.windows[0]._closedTabs;
- delete newState.windows[0].sizemode;
- ss.setWindowState(newWin, JSON.stringify(newState), true);
-
- newWin.setTimeout(function() {
- is(JSON.parse(ss.getClosedTabData(newWin)).length, 0,
- "closed tabs were implicitly cleared");
-
- is(newWin.windowState, newWin.STATE_MAXIMIZED,
- "the window remains maximized");
- newState.windows[0].sizemode = "normal";
- ss.setWindowState(newWin, JSON.stringify(newState), true);
-
- newWin.setTimeout(function() {
- isnot(newWin.windowState, newWin.STATE_MAXIMIZED,
- "the window was explicitly unmaximized");
-
- BrowserTestUtils.closeWindow(newWin).then(finish);
- }, 0);
- }, 0);
- }, 0);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_480893.js b/browser/components/sessionstore/test/browser_480893.js
deleted file mode 100644
index e3ddb39b7..000000000
--- a/browser/components/sessionstore/test/browser_480893.js
+++ /dev/null
@@ -1,47 +0,0 @@
-"use strict";
-
-/**
- * Tests that we get sent to the right page when the user clicks
- * the "Close" button in about:sessionrestore
- */
-add_task(function*() {
- yield SpecialPowers.pushPrefEnv({
- "set": [
- ["browser.startup.page", 0],
- ]
- });
-
- let tab = gBrowser.addTab("about:sessionrestore");
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
- yield BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
-
- let doc = browser.contentDocument;
-
- // Click on the "Close" button after about:sessionrestore is loaded.
- doc.getElementById("errorCancel").click();
-
- yield BrowserTestUtils.browserLoaded(browser, false, "about:blank");
-
- // Test that starting a new session loads the homepage (set to http://mochi.test:8888)
- // if Firefox is configured to display a homepage at startup (browser.startup.page = 1)
- let homepage = "http://mochi.test:8888/";
- yield SpecialPowers.pushPrefEnv({
- "set": [
- ["browser.startup.homepage", homepage],
- ["browser.startup.page", 1],
- ]
- });
-
- browser.loadURI("about:sessionrestore");
- yield BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
- doc = browser.contentDocument;
-
- // Click on the "Close" button after about:sessionrestore is loaded.
- doc.getElementById("errorCancel").click();
- yield BrowserTestUtils.browserLoaded(browser);
-
- is(browser.currentURI.spec, homepage, "loaded page is the homepage");
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_485482.js b/browser/components/sessionstore/test/browser_485482.js
deleted file mode 100644
index 68ec9941b..000000000
--- a/browser/components/sessionstore/test/browser_485482.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_485482_sample.html";
-
-/**
- * Bug 485482 - Make sure that we produce valid XPath expressions even for very
- * weird HTML documents.
- */
-add_task(function test_xpath_exp_for_strange_documents() {
- // Load a page with weird tag names.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Fill in some values.
- let uniqueValue = Math.random();
- yield setInputValue(browser, {selector: "input[type=text]", value: uniqueValue});
- yield setInputChecked(browser, {selector: "input[type=checkbox]", checked: true});
-
- // Duplicate the tab.
- let tab2 = gBrowser.duplicateTab(tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- // Check that we generated valid XPath expressions to restore form values.
- let text = yield getInputValue(browser2, {selector: "input[type=text]"});
- is(text, uniqueValue, "generated XPath expression was valid");
- let checkbox = yield getInputChecked(browser2, {selector: "input[type=checkbox]"});
- ok(checkbox, "generated XPath expression was valid");
-
- // Cleanup.
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_485482_sample.html b/browser/components/sessionstore/test/browser_485482_sample.html
deleted file mode 100644
index c2097b593..000000000
--- a/browser/components/sessionstore/test/browser_485482_sample.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<title>Test for bug 485482</title>
-
-<bad=name>
- <input type="text">
-</bad=name>
-
-<worse=name>
- <l0c@l+na~e"'§>
- <input type="checkbox" name="check"> Check
- </l0c@l+na~e"'§>
-</worse=name>
diff --git a/browser/components/sessionstore/test/browser_485563.js b/browser/components/sessionstore/test/browser_485563.js
deleted file mode 100644
index f4e6b31cc..000000000
--- a/browser/components/sessionstore/test/browser_485563.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 485563 **/
-
- waitForExplicitFinish();
-
- let uniqueValue = Math.random() + "\u2028Second line\u2029Second paragraph\u2027";
-
- let tab = gBrowser.addTab();
- promiseBrowserLoaded(tab.linkedBrowser).then(() => {
- ss.setTabValue(tab, "bug485563", uniqueValue);
- let tabState = JSON.parse(ss.getTabState(tab));
- is(tabState.extData["bug485563"], uniqueValue,
- "unicode line separator wasn't over-encoded");
- ss.deleteTabValue(tab, "bug485563");
- ss.setTabState(tab, JSON.stringify(tabState));
- is(ss.getTabValue(tab, "bug485563"), uniqueValue,
- "unicode line separator was correctly preserved");
-
- gBrowser.removeTab(tab);
- finish();
- });
-}
diff --git a/browser/components/sessionstore/test/browser_490040.js b/browser/components/sessionstore/test/browser_490040.js
deleted file mode 100644
index bc680c32f..000000000
--- a/browser/components/sessionstore/test/browser_490040.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Only windows with open tabs are restorable. Windows where a lone tab is
-// detached may have _closedTabs, but is left with just an empty tab.
-const STATES = [{
- shouldBeAdded: true,
- windowState: {
- windows: [{
- tabs: [{ entries: [{ url: "http://example.com", title: "example.com" }] }],
- selected: 1,
- _closedTabs: []
- }]
- }
- }, {
- shouldBeAdded: false,
- windowState: {
- windows: [{
- tabs: [{ entries: [] }],
- _closedTabs: []
- }]
- }
- }, {
- shouldBeAdded: false,
- windowState: {
- windows: [{
- tabs: [{ entries: [] }],
- _closedTabs: [{ state: { entries: [{ url: "http://example.com", index: 1 }] } }]
- }]
- }
- }, {
- shouldBeAdded: false,
- windowState: {
- windows: [{
- tabs: [{ entries: [] }],
- _closedTabs: [],
- extData: { keyname: "pi != " + Math.random() }
- }]
- }
- }];
-
-add_task(function* test_bug_490040() {
- for (let state of STATES) {
- // Ensure we can store the window if needed.
- let startingClosedWindowCount = ss.getClosedWindowCount();
- yield pushPrefs(["browser.sessionstore.max_windows_undo",
- startingClosedWindowCount + 1]);
-
- let curClosedWindowCount = ss.getClosedWindowCount();
- let win = yield BrowserTestUtils.openNewBrowserWindow();
-
- ss.setWindowState(win, JSON.stringify(state.windowState), true);
- if (state.windowState.windows[0].tabs.length) {
- yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
- }
-
- yield BrowserTestUtils.closeWindow(win);
-
- is(ss.getClosedWindowCount(),
- curClosedWindowCount + (state.shouldBeAdded ? 1 : 0),
- "That window should " + (state.shouldBeAdded ? "" : "not ") +
- "be restorable");
- }
-});
diff --git a/browser/components/sessionstore/test/browser_491168.js b/browser/components/sessionstore/test/browser_491168.js
deleted file mode 100644
index ae66afe77..000000000
--- a/browser/components/sessionstore/test/browser_491168.js
+++ /dev/null
@@ -1,42 +0,0 @@
-"use strict";
-
-const REFERRER1 = "http://example.org/?" + Date.now();
-const REFERRER2 = "http://example.org/?" + Math.random();
-
-add_task(function* () {
- function* checkDocumentReferrer(referrer, msg) {
- yield ContentTask.spawn(gBrowser.selectedBrowser, { referrer, msg }, function* (args) {
- Assert.equal(content.document.referrer, args.referrer, args.msg);
- });
- }
-
- // Add a new tab.
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Load a new URI with a specific referrer.
- let referrerURI = Services.io.newURI(REFERRER1, null, null);
- browser.loadURI("http://example.org", referrerURI, null);
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
- let tabState = JSON.parse(ss.getTabState(tab));
- is(tabState.entries[0].referrer, REFERRER1,
- "Referrer retrieved via getTabState matches referrer set via loadURI.");
-
- tabState.entries[0].referrer = REFERRER2;
- yield promiseTabState(tab, tabState);
-
- yield checkDocumentReferrer(REFERRER2,
- "document.referrer matches referrer set via setTabState.");
- gBrowser.removeCurrentTab();
-
- // Restore the closed tab.
- tab = ss.undoCloseTab(window, 0);
- yield promiseTabRestored(tab);
-
- yield checkDocumentReferrer(REFERRER2,
- "document.referrer is still correct after closing and reopening the tab.");
- gBrowser.removeCurrentTab();
-});
diff --git a/browser/components/sessionstore/test/browser_491577.js b/browser/components/sessionstore/test/browser_491577.js
deleted file mode 100644
index 0e088d702..000000000
--- a/browser/components/sessionstore/test/browser_491577.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 491577 **/
-
- // test setup
- waitForExplicitFinish();
-
- const REMEMBER = Date.now(), FORGET = Math.random();
- let test_state = {
- windows: [ { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 } ],
- _closedWindows : [
- // _closedWindows[0]
- {
- tabs: [
- { entries: [{ url: "http://example.com/", title: "title" }] },
- { entries: [{ url: "http://mozilla.org/", title: "title" }] }
- ],
- selected: 2,
- title: FORGET,
- _closedTabs: []
- },
- // _closedWindows[1]
- {
- tabs: [
- { entries: [{ url: "http://mozilla.org/", title: "title" }] },
- { entries: [{ url: "http://example.com/", title: "title" }] },
- { entries: [{ url: "http://mozilla.org/", title: "title" }] },
- ],
- selected: 3,
- title: REMEMBER,
- _closedTabs: []
- },
- // _closedWindows[2]
- {
- tabs: [
- { entries: [{ url: "http://example.com/", title: "title" }] }
- ],
- selected: 1,
- title: FORGET,
- _closedTabs: [
- {
- state: {
- entries: [
- { url: "http://mozilla.org/", title: "title" },
- { url: "http://mozilla.org/again", title: "title" }
- ]
- },
- pos: 1,
- title: "title"
- },
- {
- state: {
- entries: [
- { url: "http://example.com", title: "title" }
- ]
- },
- title: "title"
- }
- ]
- }
- ]
- };
- let remember_count = 1;
-
- function countByTitle(aClosedWindowList, aTitle) {
- return aClosedWindowList.filter(aData => aData.title == aTitle).length;
- }
-
- function testForError(aFunction) {
- try {
- aFunction();
- return false;
- }
- catch (ex) {
- return ex.name == "NS_ERROR_ILLEGAL_VALUE";
- }
- }
-
- // open a window and add the above closed window list
- let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
- promiseWindowLoaded(newWin).then(() => {
- gPrefService.setIntPref("browser.sessionstore.max_windows_undo",
- test_state._closedWindows.length);
- ss.setWindowState(newWin, JSON.stringify(test_state), true);
-
- let closedWindows = JSON.parse(ss.getClosedWindowData());
- is(closedWindows.length, test_state._closedWindows.length,
- "Closed window list has the expected length");
- is(countByTitle(closedWindows, FORGET),
- test_state._closedWindows.length - remember_count,
- "The correct amount of windows are to be forgotten");
- is(countByTitle(closedWindows, REMEMBER), remember_count,
- "Everything is set up.");
-
- // all of the following calls with illegal arguments should throw NS_ERROR_ILLEGAL_VALUE
- ok(testForError(() => ss.forgetClosedWindow(-1)),
- "Invalid window for forgetClosedWindow throws");
- ok(testForError(() => ss.forgetClosedWindow(test_state._closedWindows.length + 1)),
- "Invalid window for forgetClosedWindow throws");
-
- // Remove third window, then first window
- ss.forgetClosedWindow(2);
- ss.forgetClosedWindow(null);
-
- closedWindows = JSON.parse(ss.getClosedWindowData());
- is(closedWindows.length, remember_count,
- "The correct amount of windows were removed");
- is(countByTitle(closedWindows, FORGET), 0,
- "All windows specifically forgotten were indeed removed");
- is(countByTitle(closedWindows, REMEMBER), remember_count,
- "... and windows not specifically forgetten weren't.");
-
- // clean up
- gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
- BrowserTestUtils.closeWindow(newWin).then(finish);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_495495.js b/browser/components/sessionstore/test/browser_495495.js
deleted file mode 100644
index 658f81c20..000000000
--- a/browser/components/sessionstore/test/browser_495495.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 495495 **/
-
- waitForExplicitFinish();
-
- let newWin = openDialog(location, "_blank", "chrome,all,dialog=no,toolbar=yes");
- promiseWindowLoaded(newWin).then(() => {
- let state1 = ss.getWindowState(newWin);
- BrowserTestUtils.closeWindow(newWin).then(() => {
-
- newWin = openDialog(location, "_blank",
- "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar=no,location,personal,directories,dialog=no");
- promiseWindowLoaded(newWin).then(() => {
- let state2 = ss.getWindowState(newWin);
-
- function testState(state, expected, callback) {
- let win = openDialog(location, "_blank", "chrome,all,dialog=no");
- promiseWindowLoaded(win).then(() => {
-
- is(win.gURLBar.readOnly, false,
- "URL bar should not be read-only before setting the state");
- is(win.gURLBar.getAttribute("enablehistory"), "true",
- "URL bar autocomplete should be enabled before setting the state");
- ss.setWindowState(win, state, true);
- is(win.gURLBar.readOnly, expected.readOnly,
- "URL bar read-only state should be restored correctly");
- is(win.gURLBar.getAttribute("enablehistory"), expected.enablehistory,
- "URL bar autocomplete state should be restored correctly");
-
- BrowserTestUtils.closeWindow(win).then(callback);
- });
- }
-
- BrowserTestUtils.closeWindow(newWin).then(() => {
- testState(state1, {readOnly: false, enablehistory: "true"}, function() {
- testState(state2, {readOnly: true, enablehistory: "false"}, finish);
- });
- });
- });
- });
- });
-}
diff --git a/browser/components/sessionstore/test/browser_500328.js b/browser/components/sessionstore/test/browser_500328.js
deleted file mode 100644
index 44650ef8b..000000000
--- a/browser/components/sessionstore/test/browser_500328.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-let checkState = Task.async(function*(browser) {
- // Go back and then forward, and make sure that the state objects received
- // from the popState event are as we expect them to be.
- //
- // We also add a node to the document's body when after going back and make
- // sure it's still there after we go forward -- this is to test that the two
- // history entries correspond to the same document.
-
- let deferred = {};
- deferred.promise = new Promise(resolve => deferred.resolve = resolve);
-
- let popStateCount = 0;
-
- browser.addEventListener("popstate", function(aEvent) {
- if (popStateCount == 0) {
- popStateCount++;
-
- ok(aEvent.state, "Event should have a state property.");
-
- ContentTask.spawn(browser, null, function() {
- is(content.testState, "foo",
- "testState after going back");
- is(JSON.stringify(content.history.state), JSON.stringify({obj1:1}),
- "first popstate object.");
-
- // Add a node with id "new-elem" to the document.
- let doc = content.document;
- ok(!doc.getElementById("new-elem"),
- "doc shouldn't contain new-elem before we add it.");
- let elem = doc.createElement("div");
- elem.id = "new-elem";
- doc.body.appendChild(elem);
- }).then(() => {
- browser.goForward();
- });
- } else if (popStateCount == 1) {
- popStateCount++;
- // When content fires a PopStateEvent and we observe it from a chrome event
- // listener (as we do here, and, thankfully, nowhere else in the tree), the
- // state object will be a cross-compartment wrapper to an object that was
- // deserialized in the content scope. And in this case, since RegExps are
- // not currently Xrayable (see bug 1014991), trying to pull |obj3| (a RegExp)
- // off of an Xrayed Object won't work. So we need to waive.
- ContentTask.spawn(browser, aEvent.state, function(state) {
- Assert.equal(Cu.waiveXrays(state).obj3.toString(),
- "/^a$/", "second popstate object.");
-
- // Make sure that the new-elem node is present in the document. If it's
- // not, then this history entry has a different doc identifier than the
- // previous entry, which is bad.
- let doc = content.document;
- let newElem = doc.getElementById("new-elem");
- ok(newElem, "doc should contain new-elem.");
- newElem.parentNode.removeChild(newElem);
- ok(!doc.getElementById("new-elem"), "new-elem should be removed.");
- }).then(() => {
- browser.removeEventListener("popstate", arguments.callee, true);
- deferred.resolve();
- });
- }
- });
-
- // Set some state in the page's window. When we go back(), the page should
- // be retrieved from bfcache, and this state should still be there.
- yield ContentTask.spawn(browser, null, function() {
- content.testState = "foo";
- });
-
- // Now go back. This should trigger the popstate event handler above.
- browser.goBack();
-
- yield deferred.promise;
-});
-
-add_task(function* test() {
- // Tests session restore functionality of history.pushState and
- // history.replaceState(). (Bug 500328)
-
- // We open a new blank window, let it load, and then load in
- // http://example.com. We need to load the blank window first, otherwise the
- // docshell gets confused and doesn't have a current history entry.
- let state;
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
- BrowserTestUtils.loadURI(browser, "http://example.com");
- yield BrowserTestUtils.browserLoaded(browser);
-
- // After these push/replaceState calls, the window should have three
- // history entries:
- // testURL (state object: null) <-- oldest
- // testURL (state object: {obj1:1})
- // testURL?page2 (state object: {obj3:/^a$/}) <-- newest
- function contentTest() {
- let history = content.window.history;
- history.pushState({obj1:1}, "title-obj1");
- history.pushState({obj2:2}, "title-obj2", "?page2");
- history.replaceState({obj3:/^a$/}, "title-obj3");
- }
- yield ContentTask.spawn(browser, null, contentTest);
- yield TabStateFlusher.flush(browser);
-
- state = ss.getTabState(gBrowser.getTabForBrowser(browser));
- });
-
- // Restore the state into a new tab. Things don't work well when we
- // restore into the old tab, but that's not a real use case anyway.
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* (browser) {
- let tab2 = gBrowser.getTabForBrowser(browser);
-
- let tabRestoredPromise = promiseTabRestored(tab2);
- ss.setTabState(tab2, state, true);
-
- // Run checkState() once the tab finishes loading its restored state.
- yield tabRestoredPromise;
- yield checkState(browser);
- });
-});
diff --git a/browser/components/sessionstore/test/browser_506482.js b/browser/components/sessionstore/test/browser_506482.js
deleted file mode 100644
index 6e5bd83bd..000000000
--- a/browser/components/sessionstore/test/browser_506482.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 506482 **/
-
- // test setup
- waitForExplicitFinish();
-
- // read the sessionstore.js mtime (picked from browser_248970_a.js)
- let profilePath = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIProperties).
- get("ProfD", Ci.nsIFile);
- function getSessionstoreFile() {
- let sessionStoreJS = profilePath.clone();
- sessionStoreJS.append("sessionstore.js");
- return sessionStoreJS;
- }
- function getSessionstorejsModificationTime() {
- let file = getSessionstoreFile();
- if (file.exists())
- return file.lastModifiedTime;
- else
- return -1;
- }
-
- // delete existing sessionstore.js, to make sure we're not reading
- // the mtime of an old one initially.
- let sessionStoreJS = getSessionstoreFile();
- if (sessionStoreJS.exists())
- sessionStoreJS.remove(false);
-
- // test content URL
- const TEST_URL = "data:text/html;charset=utf-8,"
- + "<body style='width: 100000px; height: 100000px;'><p>top</p></body>"
-
- // preferences that we use
- const PREF_INTERVAL = "browser.sessionstore.interval";
-
- // make sure sessionstore.js is saved ASAP on all events
- gPrefService.setIntPref(PREF_INTERVAL, 0);
-
- // get the initial sessionstore.js mtime (-1 if it doesn't exist yet)
- let mtime0 = getSessionstorejsModificationTime();
-
- // create and select a first tab
- let tab = gBrowser.addTab(TEST_URL);
- promiseBrowserLoaded(tab.linkedBrowser).then(() => {
- // step1: the above has triggered some saveStateDelayed(), sleep until
- // it's done, and get the initial sessionstore.js mtime
- setTimeout(function step1(e) {
- let mtime1 = getSessionstorejsModificationTime();
- isnot(mtime1, mtime0, "initial sessionstore.js update");
-
- // step2: test sessionstore.js is not updated on tab selection
- // or content scrolling
- gBrowser.selectedTab = tab;
- tab.linkedBrowser.contentWindow.scrollTo(1100, 1200);
- setTimeout(function step2(e) {
- let mtime2 = getSessionstorejsModificationTime();
- is(mtime2, mtime1,
- "tab selection and scrolling: sessionstore.js not updated");
-
- // ok, done, cleanup and finish
- if (gPrefService.prefHasUserValue(PREF_INTERVAL))
- gPrefService.clearUserPref(PREF_INTERVAL);
- gBrowser.removeTab(tab);
- finish();
- }, 3500); // end of sleep after tab selection and scrolling
- }, 3500); // end of sleep after initial saveStateDelayed()
- });
-}
diff --git a/browser/components/sessionstore/test/browser_514751.js b/browser/components/sessionstore/test/browser_514751.js
deleted file mode 100644
index ff80245c4..000000000
--- a/browser/components/sessionstore/test/browser_514751.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 514751 (Wallpaper) **/
-
- waitForExplicitFinish();
-
- let state = {
- windows: [{
- tabs: [{
- entries: [
- { url: "about:mozilla", title: "Mozilla" },
- {}
- ]
- }]
- }]
- };
-
- var theWin = openDialog(location, "", "chrome,all,dialog=no");
- theWin.addEventListener("load", function () {
- theWin.removeEventListener("load", arguments.callee, false);
-
- 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);
- });
- }, false);
-}
-
diff --git a/browser/components/sessionstore/test/browser_522375.js b/browser/components/sessionstore/test/browser_522375.js
deleted file mode 100644
index 50b74d6cd..000000000
--- a/browser/components/sessionstore/test/browser_522375.js
+++ /dev/null
@@ -1,21 +0,0 @@
-function test() {
- var startup_info = Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(Components.interfaces.nsIAppStartup).getStartupInfo();
- // No .process info on mac
-
- // Check if we encountered a telemetry error for the the process creation
- // timestamp and turn the first test into a known failure.
- var telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
- var snapshot = telemetry.getHistogramById("STARTUP_MEASUREMENT_ERRORS")
- .snapshot();
-
- if (snapshot.counts[0] == 0)
- ok(startup_info.process <= startup_info.main, "process created before main is run " + uneval(startup_info));
- else
- todo(false, "An error occurred while recording the process creation timestamp, skipping this test");
-
- // on linux firstPaint can happen after everything is loaded (especially with remote X)
- if (startup_info.firstPaint)
- ok(startup_info.main <= startup_info.firstPaint, "main ran before first paint " + uneval(startup_info));
-
- ok(startup_info.main < startup_info.sessionRestored, "Session restored after main " + uneval(startup_info));
-}
diff --git a/browser/components/sessionstore/test/browser_522545.js b/browser/components/sessionstore/test/browser_522545.js
deleted file mode 100644
index f4d373166..000000000
--- a/browser/components/sessionstore/test/browser_522545.js
+++ /dev/null
@@ -1,269 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 522545 **/
-
- waitForExplicitFinish();
- requestLongerTimeout(4);
-
- // This tests the following use case:
- // User opens a new tab which gets focus. The user types something into the
- // address bar, then crashes or quits.
- function test_newTabFocused() {
- let state = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:mozilla" }] },
- { entries: [], userTypedValue: "example.com", userTypedClear: 0 }
- ],
- selected: 2
- }]
- };
-
- waitForBrowserState(state, function() {
- let browser = gBrowser.selectedBrowser;
- is(browser.currentURI.spec, "about:blank",
- "No history entries still sets currentURI to about:blank");
- is(browser.userTypedValue, "example.com",
- "userTypedValue was correctly restored");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "We still know that no load is ongoing");
- is(gURLBar.value, "example.com",
- "Address bar's value correctly restored");
- // Change tabs to make sure address bar value gets updated
- gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(0);
- is(gURLBar.value, "about:mozilla",
- "Address bar's value correctly updated");
- runNextTest();
- });
- }
-
- // This tests the following use case:
- // User opens a new tab which gets focus. The user types something into the
- // address bar, switches back to the first tab, then crashes or quits.
- function test_newTabNotFocused() {
- let state = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:mozilla" }] },
- { entries: [], userTypedValue: "example.org", userTypedClear: 0 }
- ],
- selected: 1
- }]
- };
-
- waitForBrowserState(state, function() {
- let browser = gBrowser.getBrowserAtIndex(1);
- is(browser.currentURI.spec, "about:blank",
- "No history entries still sets currentURI to about:blank");
- is(browser.userTypedValue, "example.org",
- "userTypedValue was correctly restored");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "We still know that no load is ongoing");
- is(gURLBar.value, "about:mozilla",
- "Address bar's value correctly restored");
- // Change tabs to make sure address bar value gets updated
- gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(1);
- is(gURLBar.value, "example.org",
- "Address bar's value correctly updated");
- runNextTest();
- });
- }
-
- // This tests the following use case:
- // User is in a tab with session history, then types something in the
- // address bar, then crashes or quits.
- function test_existingSHEnd_noClear() {
- let state = {
- windows: [{
- tabs: [{
- entries: [{ url: "about:mozilla" }, { url: "about:config" }],
- index: 2,
- userTypedValue: "example.com",
- userTypedClear: 0
- }]
- }]
- };
-
- waitForBrowserState(state, function() {
- let browser = gBrowser.selectedBrowser;
- is(browser.currentURI.spec, "about:config",
- "browser.currentURI set to current entry in SH");
- is(browser.userTypedValue, "example.com",
- "userTypedValue was correctly restored");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "We still know that no load is ongoing");
- is(gURLBar.value, "example.com",
- "Address bar's value correctly restored to userTypedValue");
- runNextTest();
- });
- }
-
- // This tests the following use case:
- // User is in a tab with session history, presses back at some point, then
- // types something in the address bar, then crashes or quits.
- function test_existingSHMiddle_noClear() {
- let state = {
- windows: [{
- tabs: [{
- entries: [{ url: "about:mozilla" }, { url: "about:config" }],
- index: 1,
- userTypedValue: "example.org",
- userTypedClear: 0
- }]
- }]
- };
-
- waitForBrowserState(state, function() {
- let browser = gBrowser.selectedBrowser;
- is(browser.currentURI.spec, "about:mozilla",
- "browser.currentURI set to current entry in SH");
- is(browser.userTypedValue, "example.org",
- "userTypedValue was correctly restored");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "We still know that no load is ongoing");
- is(gURLBar.value, "example.org",
- "Address bar's value correctly restored to userTypedValue");
- runNextTest();
- });
- }
-
- // This test simulates lots of tabs opening at once and then quitting/crashing.
- function test_getBrowserState_lotsOfTabsOpening() {
- gBrowser.stop();
-
- let uris = [];
- for (let i = 0; i < 25; i++)
- uris.push("http://example.com/" + i);
-
- // We're waiting for the first location change, which should indicate
- // one of the tabs has loaded and the others haven't. So one should
- // be in a non-userTypedValue case, while others should still have
- // userTypedValue and userTypedClear set.
- gBrowser.addTabsProgressListener({
- onLocationChange: function (aBrowser) {
- if (uris.indexOf(aBrowser.currentURI.spec) > -1) {
- gBrowser.removeTabsProgressListener(this);
- firstLocationChange();
- }
- }
- });
-
- function firstLocationChange() {
- let state = JSON.parse(ss.getBrowserState());
- let hasUTV = state.windows[0].tabs.some(function(aTab) {
- return aTab.userTypedValue && aTab.userTypedClear && !aTab.entries.length;
- });
-
- ok(hasUTV, "At least one tab has a userTypedValue with userTypedClear with no loaded URL");
-
- BrowserTestUtils.waitForMessage(gBrowser.selectedBrowser.messageManager, "SessionStore:update").then(firstLoad);
- }
-
- function firstLoad() {
- let state = JSON.parse(ss.getTabState(gBrowser.selectedTab));
- let hasSH = !("userTypedValue" in state) && state.entries[0].url;
- ok(hasSH, "The selected tab has its entry in SH");
-
- runNextTest();
- }
-
- gBrowser.loadTabs(uris);
- }
-
- // This simulates setting a userTypedValue and ensures that just typing in the
- // URL bar doesn't set userTypedClear as well.
- function test_getBrowserState_userTypedValue() {
- let state = {
- windows: [{
- tabs: [{ entries: [] }]
- }]
- };
-
- waitForBrowserState(state, function() {
- let browser = gBrowser.selectedBrowser;
- // Make sure this tab isn't loading and state is clear before we test.
- is(browser.userTypedValue, null, "userTypedValue is empty to start");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "Initially, no load should be ongoing");
-
- let inputText = "example.org";
- gURLBar.focus();
- gURLBar.value = inputText.slice(0, -1);
- EventUtils.synthesizeKey(inputText.slice(-1) , {});
-
- executeSoon(function () {
- is(browser.userTypedValue, "example.org",
- "userTypedValue was set when changing URLBar value");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "No load started since changing URLBar value");
-
- // Now make sure ss gets these values too
- let newState = JSON.parse(ss.getBrowserState());
- is(newState.windows[0].tabs[0].userTypedValue, "example.org",
- "sessionstore got correct userTypedValue");
- is(newState.windows[0].tabs[0].userTypedClear, 0,
- "sessionstore got correct userTypedClear");
- runNextTest();
- });
- });
- }
-
- // test_getBrowserState_lotsOfTabsOpening tested userTypedClear in a few cases,
- // but not necessarily any that had legitimate URIs in the state of loading
- // (eg, "http://example.com"), so this test will cover that case.
- function test_userTypedClearLoadURI() {
- let state = {
- windows: [{
- tabs: [
- { entries: [], userTypedValue: "http://example.com", userTypedClear: 2 }
- ]
- }]
- };
-
- waitForBrowserState(state, function() {
- let browser = gBrowser.selectedBrowser;
- is(browser.currentURI.spec, "http://example.com/",
- "userTypedClear=2 caused userTypedValue to be loaded");
- is(browser.userTypedValue, null,
- "userTypedValue was null after loading a URI");
- ok(!browser.didStartLoadSinceLastUserTyping(),
- "We should have reset the load state when the tab loaded");
- is(gURLBar.textValue, gURLBar.trimValue("http://example.com/"),
- "Address bar's value set after loading URI");
- runNextTest();
- });
- }
-
-
- let tests = [test_newTabFocused, test_newTabNotFocused,
- test_existingSHEnd_noClear, test_existingSHMiddle_noClear,
- test_getBrowserState_lotsOfTabsOpening,
- test_getBrowserState_userTypedValue, test_userTypedClearLoadURI];
- let originalState = JSON.parse(ss.getBrowserState());
- let state = {
- windows: [{
- tabs: [{ entries: [{ url: "about:blank" }] }]
- }]
- };
- function runNextTest() {
- if (tests.length) {
- waitForBrowserState(state, function() {
- gBrowser.selectedBrowser.userTypedValue = null;
- URLBarSetURI();
- (tests.shift())();
- });
- } else {
- waitForBrowserState(originalState, function() {
- gBrowser.selectedBrowser.userTypedValue = null;
- URLBarSetURI();
- finish();
- });
- }
- }
-
- // Run the tests!
- runNextTest();
-}
diff --git a/browser/components/sessionstore/test/browser_524745.js b/browser/components/sessionstore/test/browser_524745.js
deleted file mode 100644
index de53f6c92..000000000
--- a/browser/components/sessionstore/test/browser_524745.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 524745 **/
-
- let uniqKey = "bug524745";
- let uniqVal = Date.now().toString();
-
- waitForExplicitFinish();
-
- whenNewWindowLoaded({ private: false }, function (window_B) {
- waitForFocus(function() {
- // Add identifying information to window_B
- ss.setWindowValue(window_B, uniqKey, uniqVal);
- let state = JSON.parse(ss.getBrowserState());
- let selectedWindow = state.windows[state.selectedWindow - 1];
- is(selectedWindow.extData && selectedWindow.extData[uniqKey], uniqVal,
- "selectedWindow is window_B");
-
- // Now minimize window_B. The selected window shouldn't have the secret data
- window_B.minimize();
- waitForFocus(function() {
- state = JSON.parse(ss.getBrowserState());
- selectedWindow = state.windows[state.selectedWindow - 1];
- ok(!selectedWindow.extData || !selectedWindow.extData[uniqKey],
- "selectedWindow is not window_B after minimizing it");
-
- // Now minimize the last open window (assumes no other tests left windows open)
- window.minimize();
- state = JSON.parse(ss.getBrowserState());
- is(state.selectedWindow, 0,
- "selectedWindow should be 0 when all windows are minimized");
-
- // Cleanup
- window.restore();
- BrowserTestUtils.closeWindow(window_B).then(finish);
- });
- }, window_B);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_526613.js b/browser/components/sessionstore/test/browser_526613.js
deleted file mode 100644
index 7e7fe8059..000000000
--- a/browser/components/sessionstore/test/browser_526613.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- /** Test for Bug 526613 **/
-
- // test setup
- waitForExplicitFinish();
-
- function browserWindowsCount(expected) {
- let count = 0;
- let e = Services.wm.getEnumerator("navigator:browser");
- while (e.hasMoreElements()) {
- if (!e.getNext().closed)
- ++count;
- }
- is(count, expected,
- "number of open browser windows according to nsIWindowMediator");
- let state = ss.getBrowserState();
- info(state);
- is(JSON.parse(state).windows.length, expected,
- "number of open browser windows according to getBrowserState");
- }
-
- browserWindowsCount(1);
-
- // backup old state
- let oldState = ss.getBrowserState();
- // create a new state for testing
- let testState = {
- windows: [
- { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 },
- { tabs: [{ entries: [{ url: "about:mozilla" }] }], selected: 1 },
- ],
- // make sure the first window is focused, otherwise when restoring the
- // old state, the first window is closed and the test harness gets unloaded
- selectedWindow: 1
- };
-
- let pass = 1;
- function observer(aSubject, aTopic, aData) {
- is(aTopic, "sessionstore-browser-state-restored",
- "The sessionstore-browser-state-restored notification was observed");
-
- if (pass++ == 1) {
- browserWindowsCount(2);
-
- // let the first window be focused (see above)
- function pollMostRecentWindow() {
- if (Services.wm.getMostRecentWindow("navigator:browser") == window) {
- ss.setBrowserState(oldState);
- } else {
- info("waiting for the current window to become active");
- setTimeout(pollMostRecentWindow, 0);
- window.focus(); //XXX Why is this needed?
- }
- }
- pollMostRecentWindow();
- }
- else {
- browserWindowsCount(1);
- ok(!window.closed, "Restoring the old state should have left this window open");
- Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
- finish();
- }
- }
- Services.obs.addObserver(observer, "sessionstore-browser-state-restored", false);
-
- // set browser to test state
- ss.setBrowserState(JSON.stringify(testState));
-}
diff --git a/browser/components/sessionstore/test/browser_528776.js b/browser/components/sessionstore/test/browser_528776.js
deleted file mode 100644
index d799c9740..000000000
--- a/browser/components/sessionstore/test/browser_528776.js
+++ /dev/null
@@ -1,21 +0,0 @@
-function browserWindowsCount(expected) {
- var count = 0;
- var e = Services.wm.getEnumerator("navigator:browser");
- while (e.hasMoreElements()) {
- if (!e.getNext().closed)
- ++count;
- }
- is(count, expected,
- "number of open browser windows according to nsIWindowMediator");
- is(JSON.parse(ss.getBrowserState()).windows.length, expected,
- "number of open browser windows according to getBrowserState");
-}
-
-add_task(function() {
- browserWindowsCount(1);
-
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- browserWindowsCount(2);
- yield BrowserTestUtils.closeWindow(win);
- browserWindowsCount(1);
-});
diff --git a/browser/components/sessionstore/test/browser_579868.js b/browser/components/sessionstore/test/browser_579868.js
deleted file mode 100644
index d6c6245d0..000000000
--- a/browser/components/sessionstore/test/browser_579868.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
- waitForExplicitFinish();
-
- let tab1 = gBrowser.addTab("about:rights");
- let tab2 = gBrowser.addTab("about:mozilla");
-
- promiseBrowserLoaded(tab1.linkedBrowser).then(() => {
- // Tell the session storer that the tab is pinned
- let newTabState = '{"entries":[{"url":"about:rights"}],"pinned":true,"userTypedValue":"Hello World!"}';
- ss.setTabState(tab1, newTabState);
-
- // Undo pinning
- gBrowser.unpinTab(tab1);
-
- // Close and restore tab
- gBrowser.removeTab(tab1);
- let savedState = JSON.parse(ss.getClosedTabData(window))[0].state;
- isnot(savedState.pinned, true, "Pinned should not be true");
- tab1 = ss.undoCloseTab(window, 0);
-
- isnot(tab1.pinned, true, "Should not be pinned");
- gBrowser.removeTab(tab1);
- gBrowser.removeTab(tab2);
- finish();
- });
-}
diff --git a/browser/components/sessionstore/test/browser_579879.js b/browser/components/sessionstore/test/browser_579879.js
deleted file mode 100644
index 6886be038..000000000
--- a/browser/components/sessionstore/test/browser_579879.js
+++ /dev/null
@@ -1,20 +0,0 @@
-"use strict";
-
-add_task(function* () {
- let tab1 = gBrowser.addTab("data:text/plain;charset=utf-8,foo");
- gBrowser.pinTab(tab1);
-
- yield promiseBrowserLoaded(tab1.linkedBrowser);
- let tab2 = gBrowser.addTab();
- gBrowser.pinTab(tab2);
-
- is(Array.indexOf(gBrowser.tabs, tab1), 0, "pinned tab 1 is at the first position");
- yield promiseRemoveTab(tab1);
-
- tab1 = undoCloseTab();
- ok(tab1.pinned, "pinned tab 1 has been restored as a pinned tab");
- is(Array.indexOf(gBrowser.tabs, tab1), 0, "pinned tab 1 has been restored to the first position");
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-});
diff --git a/browser/components/sessionstore/test/browser_580512.js b/browser/components/sessionstore/test/browser_580512.js
deleted file mode 100644
index ef048cd37..000000000
--- a/browser/components/sessionstore/test/browser_580512.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const URIS_PINNED = ["about:license", "about:about"];
-const URIS_NORMAL_A = ["about:mozilla"];
-const URIS_NORMAL_B = ["about:buildconfig"];
-
-function test() {
- waitForExplicitFinish();
-
- isnot(Services.prefs.getIntPref("browser.startup.page"), 3,
- "pref to save session must not be set for this test");
- ok(!Services.prefs.getBoolPref("browser.sessionstore.resume_session_once"),
- "pref to save session once must not be set for this test");
-
- document.documentElement.setAttribute("windowtype", "navigator:browsertestdummy");
-
- openWinWithCb(closeFirstWin, URIS_PINNED.concat(URIS_NORMAL_A));
-}
-
-function closeFirstWin(win) {
- win.gBrowser.pinTab(win.gBrowser.tabs[0]);
- win.gBrowser.pinTab(win.gBrowser.tabs[1]);
-
- let winClosed = BrowserTestUtils.windowClosed(win);
- // We need to call BrowserTryToCloseWindow in order to trigger
- // the machinery that chooses whether or not to save the session
- // for the last window.
- win.BrowserTryToCloseWindow();
- ok(win.closed, "window closed");
-
- winClosed.then(() => {
- openWinWithCb(checkSecondWin, URIS_NORMAL_B, URIS_PINNED.concat(URIS_NORMAL_B));
- });
-}
-
-function checkSecondWin(win) {
- is(win.gBrowser.browsers[0].currentURI.spec, URIS_PINNED[0], "first pinned tab restored");
- is(win.gBrowser.browsers[1].currentURI.spec, URIS_PINNED[1], "second pinned tab restored");
- ok(win.gBrowser.tabs[0].pinned, "first pinned tab is still pinned");
- ok(win.gBrowser.tabs[1].pinned, "second pinned tab is still pinned");
-
- BrowserTestUtils.closeWindow(win).then(() => {
- // cleanup
- document.documentElement.setAttribute("windowtype", "navigator:browser");
- finish();
- });
-}
-
-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, false);
- 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 &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
- expectedURIs.indexOf(aRequest.QueryInterface(Ci.nsIChannel).originalURI.spec) > -1 &&
- --expectedLoads <= 0) {
- win.gBrowser.removeTabsProgressListener(this);
- info("all tabs loaded");
- is(win.gBrowser.tabs.length, expectedURIs.length, "didn't load any unexpected tabs");
- executeSoon(function () {
- cb(win);
- });
- }
- }
- });
- }, false);
-}
diff --git a/browser/components/sessionstore/test/browser_581937.js b/browser/components/sessionstore/test/browser_581937.js
deleted file mode 100644
index 74ddaa9d2..000000000
--- a/browser/components/sessionstore/test/browser_581937.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Tests that an about:blank tab with no history will not be saved into
-// session store and thus, it will not show up in Recently Closed Tabs.
-
-"use strict";
-
-add_task(function* () {
- let tab = gBrowser.addTab("about:blank");
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- is(tab.linkedBrowser.currentURI.spec, "about:blank",
- "we will be removing an about:blank tab");
-
- let r = `rand-${Math.random()}`;
- ss.setTabValue(tab, "foobar", r);
-
- yield promiseRemoveTab(tab);
- let closedTabData = ss.getClosedTabData(window);
- ok(!closedTabData.includes(r), "tab not stored in _closedTabs");
-});
diff --git a/browser/components/sessionstore/test/browser_586068-apptabs.js b/browser/components/sessionstore/test/browser_586068-apptabs.js
deleted file mode 100644
index f8727c04f..000000000
--- a/browser/components/sessionstore/test/browser_586068-apptabs.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-requestLongerTimeout(2);
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() }, pinned: true },
- { entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() }, pinned: true },
- { entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() }, pinned: true },
- { entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
- ], selected: 5 }] };
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- loadCount++;
-
- // We'll make sure that the loads we get come from pinned tabs or the
- // the selected tab.
-
- // get the tab
- let tab;
- for (let i = 0; i < window.gBrowser.tabs.length; i++) {
- if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
- tab = window.gBrowser.tabs[i];
- }
-
- ok(tab.pinned || tab.selected,
- "load came from pinned or selected tab");
-
- // We should get 4 loads: 3 app tabs + 1 normal selected tab
- if (loadCount < 4)
- return;
-
- gProgressListener.unsetCallback();
- resolve();
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-apptabs_ondemand.js b/browser/components/sessionstore/test/browser_586068-apptabs_ondemand.js
deleted file mode 100644
index b58aa649b..000000000
--- a/browser/components/sessionstore/test/browser_586068-apptabs_ondemand.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-const PREF_RESTORE_PINNED_TABS_ON_DEMAND = "browser.sessionstore.restore_pinned_tabs_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
- Services.prefs.setBoolPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND, true);
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- Services.prefs.clearUserPref(PREF_RESTORE_PINNED_TABS_ON_DEMAND);
- });
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() }, pinned: true },
- { entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() }, pinned: true },
- { entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() }, pinned: true },
- { entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
- ], selected: 5 }] };
-
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- // get the tab
- let tab;
- for (let i = 0; i < window.gBrowser.tabs.length; i++) {
- if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
- tab = window.gBrowser.tabs[i];
- }
-
- // Check that the load only comes from the selected tab.
- ok(tab.selected, "load came from selected tab");
- is(aNeedRestore, 6, "six tabs left to restore");
- is(aRestoring, 1, "one tab is restoring");
- is(aRestored, 0, "no tabs have been restored, yet");
-
- gProgressListener.unsetCallback();
- resolve();
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js b/browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js
deleted file mode 100644
index de8f1aba0..000000000
--- a/browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-requestLongerTimeout(2);
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- // The first state will be loaded using setBrowserState, followed by the 2nd
- // state also being loaded using setBrowserState, interrupting the first restore.
- let state1 = { windows: [
- {
- tabs: [
- { entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }
- ],
- selected: 1
- },
- {
- tabs: [
- { entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
- ],
- selected: 3
- }
- ] };
- let state2 = { windows: [
- {
- tabs: [
- { entries: [{ url: "http://example.org#5" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#6" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#7" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#8" }], extData: { "uniq": r() } }
- ],
- selected: 3
- },
- {
- tabs: [
- { entries: [{ url: "http://example.com#5" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#6" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#7" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#8" }], extData: { "uniq": r() } },
- ],
- selected: 1
- }
- ] };
-
- // interruptedAfter will be set after the selected tab from each window have loaded.
- let interruptedAfter = 0;
- let loadedWindow1 = false;
- let loadedWindow2 = false;
- let numTabs = state2.windows[0].tabs.length + state2.windows[1].tabs.length;
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- loadCount++;
-
- if (aBrowser.currentURI.spec == state1.windows[0].tabs[2].entries[0].url)
- loadedWindow1 = true;
- if (aBrowser.currentURI.spec == state1.windows[1].tabs[0].entries[0].url)
- loadedWindow2 = true;
-
- if (!interruptedAfter && loadedWindow1 && loadedWindow2) {
- interruptedAfter = loadCount;
- ss.setBrowserState(JSON.stringify(state2));
- return;
- }
-
- if (loadCount < numTabs + interruptedAfter)
- return;
-
- // We don't actually care about load order in this test, just that they all
- // do load.
- is(loadCount, numTabs + interruptedAfter, "all tabs were restored");
- is(aNeedRestore, 0, "there are no tabs left needing restore");
-
- // Remove the progress listener.
- gProgressListener.unsetCallback();
- 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);
- Services.ww.unregisterNotification(observer);
- win.gBrowser.addTabsProgressListener(gProgressListener);
- });
- }
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state1));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseAllButPrimaryWindowClosed();
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-cascade.js b/browser/components/sessionstore/test/browser_586068-cascade.js
deleted file mode 100644
index 041aea85c..000000000
--- a/browser/components/sessionstore/test/browser_586068-cascade.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com" }], extData: { "uniq": r() } }
- ] }] };
-
- let expectedCounts = [
- [3, 3, 0],
- [2, 3, 1],
- [1, 3, 2],
- [0, 3, 3],
- [0, 2, 4],
- [0, 1, 5]
- ];
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- loadCount++;
- let expected = expectedCounts[loadCount - 1];
-
- is(aNeedRestore, expected[0], "load " + loadCount + " - # tabs that need to be restored");
- is(aRestoring, expected[1], "load " + loadCount + " - # tabs that are restoring");
- is(aRestored, expected[2], "load " + loadCount + " - # tabs that has been restored");
-
- if (loadCount == state.windows[0].tabs.length) {
- gProgressListener.unsetCallback();
- resolve();
- }
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-multi_window.js b/browser/components/sessionstore/test/browser_586068-multi_window.js
deleted file mode 100644
index 03337568e..000000000
--- a/browser/components/sessionstore/test/browser_586068-multi_window.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- // The first window will be put into the already open window and the second
- // window will be opened with _openWindowWithState, which is the source of the problem.
- let state = { windows: [
- {
- tabs: [
- { entries: [{ url: "http://example.org#0" }], extData: { "uniq": r() } }
- ],
- selected: 1
- },
- {
- tabs: [
- { entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#5" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#6" }], extData: { "uniq": r() } }
- ],
- selected: 4
- }
- ] };
- let numTabs = state.windows[0].tabs.length + state.windows[1].tabs.length;
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- if (++loadCount == numTabs) {
- // We don't actually care about load order in this test, just that they all
- // do load.
- is(loadCount, numTabs, "all tabs were restored");
- is(aNeedRestore, 0, "there are no tabs left needing restore");
-
- gProgressListener.unsetCallback();
- resolve();
- }
- });
- });
-
- // 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);
- Services.ww.unregisterNotification(observer);
- win.gBrowser.addTabsProgressListener(gProgressListener);
- });
- }
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseAllButPrimaryWindowClosed();
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-reload.js b/browser/components/sessionstore/test/browser_586068-reload.js
deleted file mode 100644
index 630c91f2d..000000000
--- a/browser/components/sessionstore/test/browser_586068-reload.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org/#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#2" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#3" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#4" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#5" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#6" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#8" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org/#9" }], extData: { "uniq": r() } },
- ], selected: 1 }] };
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gBrowser.tabContainer.addEventListener("SSTabRestored", function onRestored(event) {
- let tab = event.target;
- let browser = tab.linkedBrowser;
- let tabData = state.windows[0].tabs[loadCount++];
-
- // double check that this tab was the right one
- is(browser.currentURI.spec, tabData.entries[0].url,
- "load " + loadCount + " - browser loaded correct url");
- is(ss.getTabValue(tab, "uniq"), tabData.extData.uniq,
- "load " + loadCount + " - correct tab was restored");
-
- if (loadCount == state.windows[0].tabs.length) {
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onRestored);
- resolve();
- } else {
- // reload the next tab
- gBrowser.browsers[loadCount].reload();
- }
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-select.js b/browser/components/sessionstore/test/browser_586068-select.js
deleted file mode 100644
index 433e1754c..000000000
--- a/browser/components/sessionstore/test/browser_586068-select.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org" }], extData: { "uniq": r() } }
- ], selected: 1 }] };
-
- let expectedCounts = [
- [5, 1, 0],
- [4, 1, 1],
- [3, 1, 2],
- [2, 1, 3],
- [1, 1, 4],
- [0, 1, 5]
- ];
- let tabOrder = [0, 5, 1, 4, 3, 2];
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- loadCount++;
- let expected = expectedCounts[loadCount - 1];
-
- is(aNeedRestore, expected[0], "load " + loadCount + " - # tabs that need to be restored");
- is(aRestoring, expected[1], "load " + loadCount + " - # tabs that are restoring");
- is(aRestored, expected[2], "load " + loadCount + " - # tabs that has been restored");
-
- if (loadCount < state.windows[0].tabs.length) {
- // double check that this tab was the right one
- let expectedData = state.windows[0].tabs[tabOrder[loadCount - 1]].extData.uniq;
- let tab;
- for (let i = 0; i < window.gBrowser.tabs.length; i++) {
- if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
- tab = window.gBrowser.tabs[i];
- }
-
- is(ss.getTabValue(tab, "uniq"), expectedData,
- "load " + loadCount + " - correct tab was restored");
-
- // select the next tab
- window.gBrowser.selectTabAtIndex(tabOrder[loadCount]);
- } else {
- gProgressListener.unsetCallback();
- resolve();
- }
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setBrowserState(JSON.stringify(state));
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-window_state.js b/browser/components/sessionstore/test/browser_586068-window_state.js
deleted file mode 100644
index 6097a70db..000000000
--- a/browser/components/sessionstore/test/browser_586068-window_state.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- // We'll use 2 states so that we can make sure calling setWindowState doesn't
- // wipe out currently restoring data.
- let state1 = { windows: [{ tabs: [
- { entries: [{ url: "http://example.com#1" }] },
- { entries: [{ url: "http://example.com#2" }] },
- { entries: [{ url: "http://example.com#3" }] },
- { entries: [{ url: "http://example.com#4" }] },
- { entries: [{ url: "http://example.com#5" }] },
- ] }] };
- let state2 = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org#1" }] },
- { entries: [{ url: "http://example.org#2" }] },
- { entries: [{ url: "http://example.org#3" }] },
- { entries: [{ url: "http://example.org#4" }] },
- { entries: [{ url: "http://example.org#5" }] }
- ] }] };
- let numTabs = state1.windows[0].tabs.length + state2.windows[0].tabs.length;
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- // When loadCount == 2, we'll also restore state2 into the window
- if (++loadCount == 2) {
- ss.setWindowState(window, JSON.stringify(state2), false);
- }
-
- if (loadCount < numTabs) {
- return;
- }
-
- // We don't actually care about load order in this test, just that they all
- // do load.
- is(loadCount, numTabs, "test_setWindowStateNoOverwrite: all tabs were restored");
- is(aNeedRestore, 0, "there are no tabs left needing restore");
-
- gProgressListener.unsetCallback();
- resolve();
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setWindowState(window, JSON.stringify(state1), true);
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586068-window_state_override.js b/browser/components/sessionstore/test/browser_586068-window_state_override.js
deleted file mode 100644
index 731e03307..000000000
--- a/browser/components/sessionstore/test/browser_586068-window_state_override.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- // We'll use 2 states so that we can make sure calling setWindowState doesn't
- // wipe out currently restoring data.
- let state1 = { windows: [{ tabs: [
- { entries: [{ url: "http://example.com#1" }] },
- { entries: [{ url: "http://example.com#2" }] },
- { entries: [{ url: "http://example.com#3" }] },
- { entries: [{ url: "http://example.com#4" }] },
- { entries: [{ url: "http://example.com#5" }] },
- ] }] };
- let state2 = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org#1" }] },
- { entries: [{ url: "http://example.org#2" }] },
- { entries: [{ url: "http://example.org#3" }] },
- { entries: [{ url: "http://example.org#4" }] },
- { entries: [{ url: "http://example.org#5" }] }
- ] }] };
- let numTabs = 2 + state2.windows[0].tabs.length;
-
- let loadCount = 0;
- let promiseRestoringTabs = new Promise(resolve => {
- gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
- // When loadCount == 2, we'll also restore state2 into the window
- if (++loadCount == 2) {
- executeSoon(() => ss.setWindowState(window, JSON.stringify(state2), true));
- }
-
- if (loadCount < numTabs) {
- return;
- }
-
- // We don't actually care about load order in this test, just that they all
- // do load.
- is(loadCount, numTabs, "all tabs were restored");
- is(aNeedRestore, 0, "there are no tabs left needing restore");
-
- gProgressListener.unsetCallback();
- resolve();
- });
- });
-
- let backupState = ss.getBrowserState();
- ss.setWindowState(window, JSON.stringify(state1), true);
- yield promiseRestoringTabs;
-
- // Cleanup.
- yield promiseBrowserState(backupState);
-});
diff --git a/browser/components/sessionstore/test/browser_586147.js b/browser/components/sessionstore/test/browser_586147.js
deleted file mode 100644
index fbfec53c7..000000000
--- a/browser/components/sessionstore/test/browser_586147.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function observeOneRestore(callback) {
- let topic = "sessionstore-browser-state-restored";
- Services.obs.addObserver(function onRestore() {
- Services.obs.removeObserver(onRestore, topic);
- callback();
- }, topic, false);
-};
-
-function test() {
- waitForExplicitFinish();
-
- // There should be one tab when we start the test
- let [origTab] = gBrowser.visibleTabs;
- let hiddenTab = gBrowser.addTab();
-
- is(gBrowser.visibleTabs.length, 2, "should have 2 tabs before hiding");
- gBrowser.showOnlyTheseTabs([origTab]);
- is(gBrowser.visibleTabs.length, 1, "only 1 after hiding");
- ok(hiddenTab.hidden, "sanity check that it's hidden");
-
- let extraTab = gBrowser.addTab();
- let state = ss.getBrowserState();
- let stateObj = JSON.parse(state);
- let tabs = stateObj.windows[0].tabs;
- is(tabs.length, 3, "just checking that browser state is correct");
- ok(!tabs[0].hidden, "first tab is visible");
- ok(tabs[1].hidden, "second is hidden");
- ok(!tabs[2].hidden, "third is visible");
-
- // Make the third tab hidden and then restore the modified state object
- tabs[2].hidden = true;
-
- observeOneRestore(function() {
- let testWindow = Services.wm.getEnumerator("navigator:browser").getNext();
- is(testWindow.gBrowser.visibleTabs.length, 1, "only restored 1 visible tab");
- let tabs = testWindow.gBrowser.tabs;
- ok(!tabs[0].hidden, "first is still visible");
- ok(tabs[1].hidden, "second tab is still hidden");
- ok(tabs[2].hidden, "third tab is now hidden");
-
- // Restore the original state and clean up now that we're done
- gBrowser.removeTab(hiddenTab);
- gBrowser.removeTab(extraTab);
-
- finish();
- });
- ss.setBrowserState(JSON.stringify(stateObj));
-}
diff --git a/browser/components/sessionstore/test/browser_588426.js b/browser/components/sessionstore/test/browser_588426.js
deleted file mode 100644
index d2462f2bd..000000000
--- a/browser/components/sessionstore/test/browser_588426.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- let state = { windows: [{ tabs: [
- {entries: [{url: "about:mozilla"}], hidden: true},
- {entries: [{url: "about:rights"}], hidden: true}
- ] }] };
-
- waitForExplicitFinish();
-
- newWindowWithState(state, function (win) {
- registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
-
- is(win.gBrowser.tabs.length, 2, "two tabs were restored");
- is(win.gBrowser.visibleTabs.length, 1, "one tab is visible");
-
- let tab = win.gBrowser.visibleTabs[0];
- is(tab.linkedBrowser.currentURI.spec, "about:mozilla", "visible tab is about:mozilla");
-
- 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, false);
-
- executeSoon(function () {
- win.addEventListener("SSWindowStateReady", function onReady() {
- win.removeEventListener("SSWindowStateReady", onReady, false);
- promiseTabRestored(win.gBrowser.tabs[0]).then(() => callback(win));
- }, false);
-
- ss.setWindowState(win, JSON.stringify(state), true);
- });
- }, false);
-}
diff --git a/browser/components/sessionstore/test/browser_589246.js b/browser/components/sessionstore/test/browser_589246.js
deleted file mode 100644
index d1f539073..000000000
--- a/browser/components/sessionstore/test/browser_589246.js
+++ /dev/null
@@ -1,242 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Mirrors WINDOW_ATTRIBUTES IN nsSessionStore.js
-const WINDOW_ATTRIBUTES = ["width", "height", "screenX", "screenY", "sizemode"];
-
-var stateBackup = ss.getBrowserState();
-
-var originalWarnOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
-var originalStartupPage = gPrefService.getIntPref("browser.startup.page");
-var originalWindowType = document.documentElement.getAttribute("windowtype");
-
-var gotLastWindowClosedTopic = false;
-var shouldPinTab = false;
-var shouldOpenTabs = false;
-var shouldCloseTab = false;
-var testNum = 0;
-var afterTestCallback;
-
-// Set state so we know the closed windows content
-var testState = {
- windows: [
- { tabs: [{ entries: [{ url: "http://example.org" }] }] }
- ],
- _closedWindows: []
-};
-
-// We'll push a set of conditions and callbacks into this array
-// Ideally we would also test win/linux under a complete set of conditions, but
-// the tests for osx mirror the other set of conditions possible on win/linux.
-var tests = [];
-
-// the third & fourth test share a condition check, keep it DRY
-function checkOSX34Generator(num) {
- return function(aPreviousState, aCurState) {
- // In here, we should have restored the pinned tab, so only the unpinned tab
- // should be in aCurState. So let's shape our expectations.
- let expectedState = JSON.parse(aPreviousState);
- expectedState[0].tabs.shift();
- // size attributes are stripped out in _prepDataForDeferredRestore in nsSessionStore.
- // This isn't the best approach, but neither is comparing JSON strings
- WINDOW_ATTRIBUTES.forEach(attr => delete expectedState[0][attr]);
-
- is(aCurState, JSON.stringify(expectedState),
- "test #" + num + ": closedWindowState is as expected");
- };
-}
-function checkNoWindowsGenerator(num) {
- return function(aPreviousState, aCurState) {
- is(aCurState, "[]", "test #" + num + ": there should be no closedWindowsLeft");
- };
-}
-
-// The first test has 0 pinned tabs and 1 unpinned tab
-tests.push({
- pinned: false,
- extra: false,
- close: false,
- checkWinLin: checkNoWindowsGenerator(1),
- checkOSX: function(aPreviousState, aCurState) {
- is(aCurState, aPreviousState, "test #1: closed window state is unchanged");
- }
-});
-
-// The second test has 1 pinned tab and 0 unpinned tabs.
-tests.push({
- pinned: true,
- extra: false,
- close: false,
- checkWinLin: checkNoWindowsGenerator(2),
- checkOSX: checkNoWindowsGenerator(2)
-});
-
-// The third test has 1 pinned tab and 2 unpinned tabs.
-tests.push({
- pinned: true,
- extra: true,
- close: false,
- checkWinLin: checkNoWindowsGenerator(3),
- checkOSX: checkOSX34Generator(3)
-});
-
-// The fourth test has 1 pinned tab, 2 unpinned tabs, and closes one unpinned tab.
-tests.push({
- pinned: true,
- extra: true,
- close: "one",
- checkWinLin: checkNoWindowsGenerator(4),
- checkOSX: checkOSX34Generator(4)
-});
-
-// The fifth test has 1 pinned tab, 2 unpinned tabs, and closes both unpinned tabs.
-tests.push({
- pinned: true,
- extra: true,
- close: "both",
- checkWinLin: checkNoWindowsGenerator(5),
- checkOSX: checkNoWindowsGenerator(5)
-});
-
-
-function test() {
- /** Test for Bug 589246 - Closed window state getting corrupted when closing
- and reopening last browser window without exiting browser **/
- waitForExplicitFinish();
- // windows opening & closing, so extending the timeout
- requestLongerTimeout(2);
-
- // We don't want the quit dialog pref
- gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
- // Ensure that we would restore the session (important for Windows)
- gPrefService.setIntPref("browser.startup.page", 3);
-
- runNextTestOrFinish();
-}
-
-function runNextTestOrFinish() {
- if (tests.length) {
- setupForTest(tests.shift())
- }
- else {
- // some state is cleaned up at the end of each test, but not all
- ["browser.tabs.warnOnClose", "browser.startup.page"].forEach(function(p) {
- if (gPrefService.prefHasUserValue(p))
- gPrefService.clearUserPref(p);
- });
-
- ss.setBrowserState(stateBackup);
- executeSoon(finish);
- }
-}
-
-function setupForTest(aConditions) {
- // reset some checks
- gotLastWindowClosedTopic = false;
- shouldPinTab = aConditions.pinned;
- shouldOpenTabs = aConditions.extra;
- shouldCloseTab = aConditions.close;
- testNum++;
-
- // set our test callback
- afterTestCallback = /Mac/.test(navigator.platform) ? aConditions.checkOSX
- : aConditions.checkWinLin;
-
- // Add observers
- Services.obs.addObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
-
- // Set the state
- Services.obs.addObserver(onStateRestored, "sessionstore-browser-state-restored", false);
- ss.setBrowserState(JSON.stringify(testState));
-}
-
-function onStateRestored(aSubject, aTopic, aData) {
- info("test #" + testNum + ": onStateRestored");
- 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, false);
-
- 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, false);
- onWindowUnloaded();
- }, false);
- // 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);
- }
- else {
- newWin.BrowserTryToCloseWindow();
- }
- });
- }, false);
-}
-
-// 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;
-}
-
-// This is the unload event listener on the new window (from onStateRestored).
-// Unload is fired after the window is closed, so sessionstore has already
-// updated _closedWindows (which is important). We'll open a new window here
-// which should actually trigger the bug.
-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, false);
-
- 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);
-
- }, false);
-}
-
-function afterTestCleanup(aNewWin) {
- executeSoon(function() {
- BrowserTestUtils.closeWindow(aNewWin).then(() => {
- document.documentElement.setAttribute("windowtype", originalWindowType);
- runNextTestOrFinish();
- });
- });
-}
diff --git a/browser/components/sessionstore/test/browser_590268.js b/browser/components/sessionstore/test/browser_590268.js
deleted file mode 100644
index 2b0c2f32d..000000000
--- a/browser/components/sessionstore/test/browser_590268.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const NUM_TABS = 12;
-
-var stateBackup = ss.getBrowserState();
-
-function test() {
- /** Test for Bug 590268 - Provide access to sessionstore tab data sooner **/
- waitForExplicitFinish();
- requestLongerTimeout(2);
-
- let startedTest = false;
-
- // wasLoaded will be used to keep track of tabs that have already had SSTabRestoring
- // fired for them.
- let wasLoaded = { };
- let restoringTabsCount = 0;
- let restoredTabsCount = 0;
- let uniq2 = { };
- let uniq2Count = 0;
- let state = { windows: [{ tabs: [] }] };
- // We're going to put a bunch of tabs into this state
- for (let i = 0; i < NUM_TABS; i++) {
- let uniq = r();
- let tabData = {
- entries: [{ url: "http://example.com/#" + i }],
- extData: { "uniq": uniq, "baz": "qux" }
- };
- state.windows[0].tabs.push(tabData);
- wasLoaded[uniq] = false;
- }
-
-
- function onSSTabRestoring(aEvent) {
- restoringTabsCount++;
- let uniq = ss.getTabValue(aEvent.originalTarget, "uniq");
- wasLoaded[uniq] = true;
-
- is(ss.getTabValue(aEvent.originalTarget, "foo"), "",
- "There is no value for 'foo'");
-
- // On the first SSTabRestoring we're going to run the the real test.
- // We'll keep this listener around so we can keep marking tabs as restored.
- if (restoringTabsCount == 1)
- onFirstSSTabRestoring();
- else if (restoringTabsCount == NUM_TABS)
- onLastSSTabRestoring();
- }
-
- function onSSTabRestored(aEvent) {
- if (++restoredTabsCount < NUM_TABS)
- return;
- cleanup();
- }
-
- function onTabOpen(aEvent) {
- // To test bug 614708, we'll just set a value on the tab here. This value
- // would previously cause us to not recognize the values in extData until
- // much later. So testing "uniq" failed.
- ss.setTabValue(aEvent.originalTarget, "foo", "bar");
- }
-
- // This does the actual testing. SSTabRestoring should be firing on tabs from
- // left to right, so we're going to start with the rightmost tab.
- function onFirstSSTabRestoring() {
- info("onFirstSSTabRestoring...");
- for (let i = gBrowser.tabs.length - 1; i >= 0; i--) {
- let tab = gBrowser.tabs[i];
- let actualUniq = ss.getTabValue(tab, "uniq");
- let expectedUniq = state.windows[0].tabs[i].extData["uniq"];
-
- if (wasLoaded[actualUniq]) {
- info("tab " + i + ": already restored");
- continue;
- }
- is(actualUniq, expectedUniq, "tab " + i + ": extData was correct");
-
- // Now we're going to set a piece of data back on the tab so it can be read
- // to test setting a value "early".
- uniq2[actualUniq] = r();
- ss.setTabValue(tab, "uniq2", uniq2[actualUniq]);
-
- // Delete the value we have for "baz". This tests that deleteTabValue
- // will delete "early access" values (c.f. bug 617175). If this doesn't throw
- // then the test is successful.
- try {
- ss.deleteTabValue(tab, "baz");
- }
- catch (e) {
- ok(false, "no error calling deleteTabValue - " + e);
- }
-
- // This will be used in the final comparison to make sure we checked the
- // same number as we set.
- uniq2Count++;
- }
- }
-
- function onLastSSTabRestoring() {
- let checked = 0;
- for (let i = 0; i < gBrowser.tabs.length; i++) {
- let tab = gBrowser.tabs[i];
- let uniq = ss.getTabValue(tab, "uniq");
-
- // Look to see if we set a uniq2 value for this uniq value
- if (uniq in uniq2) {
- is(ss.getTabValue(tab, "uniq2"), uniq2[uniq], "tab " + i + " has correct uniq2 value");
- checked++;
- }
- }
- ok(uniq2Count > 0, "at least 1 tab properly checked 'early access'");
- is(checked, uniq2Count, "checked the same number of uniq2 as we set");
- }
-
- function cleanup() {
- // remove the event listener and clean up before finishing
- gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring, false);
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
- gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, false);
- // Put this in an executeSoon because we still haven't called restoreNextTab
- // in sessionstore for the last tab (we'll call it after this). We end up
- // trying to restore the tab (since we then add a closed tab to the array).
- executeSoon(function() {
- ss.setBrowserState(stateBackup);
- executeSoon(finish);
- });
- }
-
- // Add the event listeners
- gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring, false);
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
- gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, false);
- // Restore state
- ss.setBrowserState(JSON.stringify(state));
-}
diff --git a/browser/components/sessionstore/test/browser_590563.js b/browser/components/sessionstore/test/browser_590563.js
deleted file mode 100644
index 5d1d8f866..000000000
--- a/browser/components/sessionstore/test/browser_590563.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- let sessionData = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:mozilla" }], hidden: true },
- { entries: [{ url: "about:blank" }], hidden: false }
- ]
- }]
- };
- let url = "about:sessionrestore";
- let formdata = {id: {sessionData}, url};
- let state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] };
-
- waitForExplicitFinish();
-
- newWindowWithState(state, function (win) {
- registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
-
- is(gBrowser.tabs.length, 1, "The total number of tabs should be 1");
- is(gBrowser.visibleTabs.length, 1, "The total number of visible tabs should be 1");
-
- executeSoon(function () {
- waitForFocus(function () {
- middleClickTest(win);
- finish();
- }, win);
- });
- });
-}
-
-function middleClickTest(win) {
- let browser = win.gBrowser.selectedBrowser;
- let tree = browser.contentDocument.getElementById("tabList");
- is(tree.view.rowCount, 3, "There should be three items");
-
- // click on the first tab item
- var rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[1], "text");
- EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
- browser.contentWindow);
- // click on the second tab item
- rect = tree.treeBoxObject.getCoordsForCellItem(2, tree.columns[1], "text");
- EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
- browser.contentWindow);
-
- is(win.gBrowser.tabs.length, 3,
- "The total number of tabs should be 3 after restoring 2 tabs by middle click.");
- 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, false);
-
- 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);
- callback(win);
- }, true);
-
- executeSoon(function () {
- ss.setWindowState(win, JSON.stringify(state), true);
- });
- }, false);
-}
diff --git a/browser/components/sessionstore/test/browser_595601-restore_hidden.js b/browser/components/sessionstore/test/browser_595601-restore_hidden.js
deleted file mode 100644
index 4c2b2d24a..000000000
--- a/browser/components/sessionstore/test/browser_595601-restore_hidden.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var state = {windows:[{tabs:[
- {entries:[{url:"http://example.com#1"}]},
- {entries:[{url:"http://example.com#2"}]},
- {entries:[{url:"http://example.com#3"}]},
- {entries:[{url:"http://example.com#4"}]},
- {entries:[{url:"http://example.com#5"}], hidden: true},
- {entries:[{url:"http://example.com#6"}], hidden: true},
- {entries:[{url:"http://example.com#7"}], hidden: true},
- {entries:[{url:"http://example.com#8"}], hidden: true}
-]}]};
-
-function test() {
- waitForExplicitFinish();
- requestLongerTimeout(2);
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
- });
-
- // First stage: restoreHiddenTabs = true
- // Second stage: restoreHiddenTabs = false
- test_loadTabs(true, function () {
- test_loadTabs(false, finish);
- });
-}
-
-function test_loadTabs(restoreHiddenTabs, callback) {
- Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", restoreHiddenTabs);
-
- let expectedTabs = restoreHiddenTabs ? 8 : 4;
- let firstProgress = true;
-
- newWindowWithState(state, function (win, needsRestore, isRestoring) {
- if (firstProgress) {
- firstProgress = false;
- is(isRestoring, 3, "restoring 3 tabs concurrently");
- } else {
- ok(isRestoring < 4, "restoring max. 3 tabs concurrently");
- }
-
- // We're explicity checking for (isRestoring == 1) here because the test
- // progress listener is called before the session store one. So when we're
- // called with one tab left to restore we know that the last tab has
- // finished restoring and will soon be handled by the SS listener.
- let tabsNeedingRestore = win.gBrowser.tabs.length - needsRestore;
- if (isRestoring == 1 && tabsNeedingRestore == expectedTabs) {
- is(win.gBrowser.visibleTabs.length, 4, "only 4 visible tabs");
-
- TabsProgressListener.uninit();
- executeSoon(callback);
- }
- });
-}
-
-var TabsProgressListener = {
- init: function (win) {
- this.window = win;
- Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
- },
-
- uninit: function () {
- Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
-
- delete this.window;
- delete this.callback;
- },
-
- setCallback: function (callback) {
- this.callback = callback;
- },
-
- observe: function (browser) {
- TabsProgressListener.onRestored(browser);
- },
-
- onRestored: function (browser) {
- if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING)
- this.callback.apply(null, [this.window].concat(this.countTabs()));
- },
-
- countTabs: function () {
- let needsRestore = 0, isRestoring = 0;
-
- for (let i = 0; i < this.window.gBrowser.tabs.length; i++) {
- let browser = this.window.gBrowser.tabs[i].linkedBrowser;
- if (browser.__SS_restoreState == TAB_STATE_RESTORING)
- isRestoring++;
- else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
- needsRestore++;
- }
-
- return [needsRestore, isRestoring];
- }
-}
-
-// ----------
-function newWindowWithState(state, callback) {
- let opts = "chrome,all,dialog=no,height=800,width=800";
- let win = window.openDialog(getBrowserURL(), "_blank", opts);
-
- registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
-
- whenWindowLoaded(win, function onWindowLoaded(aWin) {
- TabsProgressListener.init(aWin);
- TabsProgressListener.setCallback(callback);
-
- ss.setWindowState(aWin, JSON.stringify(state), true);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_597071.js b/browser/components/sessionstore/test/browser_597071.js
deleted file mode 100644
index f8ddaaf54..000000000
--- a/browser/components/sessionstore/test/browser_597071.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Bug 597071 - Closed windows should only be resurrected when there is a single
- * popup window
- */
-add_task(function test_close_last_nonpopup_window() {
- // Purge the list of closed windows.
- forgetClosedWindows();
-
- let oldState = ss.getWindowState(window);
-
- let popupState = {windows: [
- {tabs: [{entries: []}], isPopup: true, hidden: "toolbar"}
- ]};
-
- // Set this window to be a popup.
- ss.setWindowState(window, JSON.stringify(popupState), true);
-
- // Open a new window with a tab.
- let win = yield BrowserTestUtils.openNewBrowserWindow({private: false});
- let tab = win.gBrowser.addTab("http://example.com/");
- yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-
- // Make sure sessionstore sees this window.
- let state = JSON.parse(ss.getBrowserState());
- is(state.windows.length, 2, "sessionstore knows about this window");
-
- // Closed the window and check the closed window count.
- yield BrowserTestUtils.closeWindow(win);
- is(ss.getClosedWindowCount(), 1, "correct closed window count");
-
- // Cleanup.
- ss.setWindowState(window, oldState, true);
-});
diff --git a/browser/components/sessionstore/test/browser_599909.js b/browser/components/sessionstore/test/browser_599909.js
deleted file mode 100644
index 1d2c411fe..000000000
--- a/browser/components/sessionstore/test/browser_599909.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var stateBackup = ss.getBrowserState();
-
-function cleanup() {
- // Reset the pref
- try {
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
- } catch (e) {}
- ss.setBrowserState(stateBackup);
- executeSoon(finish);
-}
-
-function test() {
- /** Bug 599909 - to-be-reloaded tabs don't show up in switch-to-tab **/
- waitForExplicitFinish();
-
- // Set the pref to true so we know exactly how many tabs should be restoring at
- // any given time. This guarantees that a finishing load won't start another.
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org/#1" }] },
- { entries: [{ url: "http://example.org/#2" }] },
- { entries: [{ url: "http://example.org/#3" }] },
- { entries: [{ url: "http://example.org/#4" }] }
- ], selected: 1 }] };
-
- let tabsForEnsure = {};
- state.windows[0].tabs.forEach(function(tab) {
- tabsForEnsure[tab.entries[0].url] = 1;
- });
-
- let tabsRestoring = 0;
- let tabsRestored = 0;
-
- function handleEvent(aEvent) {
- if (aEvent.type == "SSTabRestoring")
- tabsRestoring++;
- else
- tabsRestored++;
-
- if (tabsRestoring < state.windows[0].tabs.length ||
- tabsRestored < 1)
- return;
-
- gBrowser.tabContainer.removeEventListener("SSTabRestoring", handleEvent, true);
- gBrowser.tabContainer.removeEventListener("SSTabRestored", handleEvent, true);
- executeSoon(function() {
- checkAutocompleteResults(tabsForEnsure, cleanup);
- });
- }
-
- // currentURI is set before SSTabRestoring is fired, so we can sucessfully check
- // after that has fired for all tabs. Since 1 tab will be restored though, we
- // also need to wait for 1 SSTabRestored since currentURI will be set, unset, then set.
- gBrowser.tabContainer.addEventListener("SSTabRestoring", handleEvent, true);
- gBrowser.tabContainer.addEventListener("SSTabRestored", handleEvent, true);
- ss.setBrowserState(JSON.stringify(state));
-}
-
-// The following was taken from browser/base/content/test/general/browser_tabMatchesInAwesomebar.js
-// so that we could do the same sort of checking.
-var gController = Cc["@mozilla.org/autocomplete/controller;1"].
- getService(Ci.nsIAutoCompleteController);
-
-function checkAutocompleteResults(aExpected, aCallback) {
- gController.input = {
- timeout: 10,
- textValue: "",
- searches: ["unifiedcomplete"],
- searchParam: "enable-actions",
- popupOpen: false,
- minResultsForPopup: 0,
- invalidate: function() {},
- disableAutoComplete: false,
- completeDefaultIndex: false,
- get popup() { return this; },
- onSearchBegin: function() {},
- onSearchComplete: function ()
- {
- info("Found " + gController.matchCount + " matches.");
- // Check to see the expected uris and titles match up (in any order)
- for (let i = 0; i < gController.matchCount; i++) {
- if (gController.getStyleAt(i).includes("heuristic")) {
- info("Skip heuristic match");
- continue;
- }
- let action = gURLBar.popup.input._parseActionUrl(gController.getValueAt(i));
- let uri = action.params.url;
-
- info("Search for '" + uri + "' in open tabs.");
- ok(uri in aExpected, "Registered open page found in autocomplete.");
- // Remove the found entry from expected results.
- delete aExpected[uri];
- }
-
- // Make sure there is no reported open page that is not open.
- for (let entry in aExpected) {
- ok(false, "'" + entry + "' not found in autocomplete.");
- }
-
- executeSoon(aCallback);
- },
- setSelectedIndex: function() {},
- get searchCount() { return this.searches.length; },
- getSearchAt: function(aIndex) {
- return this.searches[aIndex];
- },
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIAutoCompleteInput,
- Ci.nsIAutoCompletePopup,
- ])
- };
-
- info("Searching open pages.");
- gController.startSearch(Services.prefs.getCharPref("browser.urlbar.restrict.openpage"));
-}
diff --git a/browser/components/sessionstore/test/browser_600545.js b/browser/components/sessionstore/test/browser_600545.js
deleted file mode 100644
index 6852357c2..000000000
--- a/browser/components/sessionstore/test/browser_600545.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-requestLongerTimeout(2);
-
-var stateBackup = JSON.parse(ss.getBrowserState());
-
-function test() {
- /** Test for Bug 600545 **/
- waitForExplicitFinish();
- testBug600545();
-}
-
-function testBug600545() {
- // Set the pref to false to cause non-app tabs to be stripped out on a save
- Services.prefs.setBoolPref("browser.sessionstore.resume_from_crash", false);
- Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.resume_from_crash");
- Services.prefs.clearUserPref("browser.sessionstore.interval");
- });
-
- // This tests the following use case: When multiple windows are open
- // and browser.sessionstore.resume_from_crash preference is false,
- // tab session data for non-active window is stripped for non-pinned
- // tabs. This occurs after "sessionstore-state-write-complete"
- // fires which will only fire in this case if there is at least one
- // pinned tab.
- let state = { windows: [
- {
- tabs: [
- { entries: [{ url: "http://example.org#0" }], pinned:true },
- { entries: [{ url: "http://example.com#1" }] },
- { entries: [{ url: "http://example.com#2" }] },
- ],
- selected: 2
- },
- {
- tabs: [
- { entries: [{ url: "http://example.com#3" }] },
- { entries: [{ url: "http://example.com#4" }] },
- { entries: [{ url: "http://example.com#5" }] },
- { entries: [{ url: "http://example.com#6" }] }
- ],
- selected: 3
- }
- ] };
-
- waitForBrowserState(state, function() {
- // Need to wait for SessionStore's saveState function to be called
- // so that non-pinned tabs will be stripped from non-active window
- waitForSaveState(function () {
- let expectedNumberOfTabs = getStateTabCount(state);
- let retrievedState = JSON.parse(ss.getBrowserState());
- let actualNumberOfTabs = getStateTabCount(retrievedState);
-
- is(actualNumberOfTabs, expectedNumberOfTabs,
- "Number of tabs in retreived session data, matches number of tabs set.");
-
- done();
- });
- });
-}
-
-function done() {
- // Enumerate windows and close everything but our primary window. We can't
- // use waitForFocus() because apparently it's buggy. See bug 599253.
- let windowsEnum = Services.wm.getEnumerator("navigator:browser");
- let closeWinPromises = [];
- while (windowsEnum.hasMoreElements()) {
- let currentWindow = windowsEnum.getNext();
- if (currentWindow != window)
- closeWinPromises.push(BrowserTestUtils.closeWindow(currentWindow));
- }
-
- Promise.all(closeWinPromises).then(() => {
- waitForBrowserState(stateBackup, finish);
- });
-}
-
-// Count up the number of tabs in the state data
-function getStateTabCount(aState) {
- let tabCount = 0;
- for (let i in aState.windows)
- tabCount += aState.windows[i].tabs.length;
- return tabCount;
-}
diff --git a/browser/components/sessionstore/test/browser_601955.js b/browser/components/sessionstore/test/browser_601955.js
deleted file mode 100644
index 797d5d7cc..000000000
--- a/browser/components/sessionstore/test/browser_601955.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This tests that pinning/unpinning a tab, on its own, eventually triggers a
-// session store.
-
-function test() {
- waitForExplicitFinish();
- // We speed up the interval between session saves to ensure that the test
- // runs quickly.
- Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
-
- // Loading a tab causes a save state and this is meant to catch that event.
- waitForSaveState(testBug601955_1);
-
- // Assumption: Only one window is open and it has one tab open.
- gBrowser.addTab("about:mozilla");
-}
-
-function testBug601955_1() {
- // Because pinned tabs are at the front of |gBrowser.tabs|, pinning tabs
- // re-arranges the |tabs| array.
- ok(!gBrowser.tabs[0].pinned, "first tab should not be pinned yet");
- ok(!gBrowser.tabs[1].pinned, "second tab should not be pinned yet");
-
- waitForSaveState(testBug601955_2);
- gBrowser.pinTab(gBrowser.tabs[0]);
-}
-
-function testBug601955_2() {
- let state = JSON.parse(ss.getBrowserState());
- ok(state.windows[0].tabs[0].pinned, "first tab should be pinned by now");
- ok(!state.windows[0].tabs[1].pinned, "second tab should still not be pinned");
-
- waitForSaveState(testBug601955_3);
- gBrowser.unpinTab(window.gBrowser.tabs[0]);
-}
-
-function testBug601955_3() {
- let state = JSON.parse(ss.getBrowserState());
- ok(!state.windows[0].tabs[0].pinned, "first tab should not be pinned");
- ok(!state.windows[0].tabs[1].pinned, "second tab should not be pinned");
-
- done();
-}
-
-function done() {
- gBrowser.removeTab(window.gBrowser.tabs[1]);
-
- Services.prefs.clearUserPref("browser.sessionstore.interval");
-
- executeSoon(finish);
-}
diff --git a/browser/components/sessionstore/test/browser_607016.js b/browser/components/sessionstore/test/browser_607016.js
deleted file mode 100644
index ed4b03b9c..000000000
--- a/browser/components/sessionstore/test/browser_607016.js
+++ /dev/null
@@ -1,98 +0,0 @@
-"use strict";
-
-var stateBackup = ss.getBrowserState();
-
-add_task(function* () {
- /** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
- ignoreAllUncaughtExceptions();
-
- // Set the pref to true so we know exactly how many tabs should be restoring at
- // any given time. This guarantees that a finishing load won't start another.
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- let state = { windows: [{ tabs: [
- { entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } }, // overwriting
- { entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } }, // hiding
- { entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }, // adding
- { entries: [{ url: "http://example.org#5" }], extData: { "uniq": r() } }, // deleting
- { entries: [{ url: "http://example.org#6" }] } // creating
- ], selected: 1 }] };
-
- function* progressCallback() {
- let curState = JSON.parse(ss.getBrowserState());
- for (let i = 0; i < curState.windows[0].tabs.length; i++) {
- let tabState = state.windows[0].tabs[i];
- let tabCurState = curState.windows[0].tabs[i];
- if (tabState.extData) {
- is(tabCurState.extData["uniq"], tabState.extData["uniq"],
- "sanity check that tab has correct extData");
- }
- else {
- // We aren't expecting there to be any data on extData, but panorama
- // may be setting something, so we need to make sure that if we do have
- // data, we just don't have anything for "uniq".
- ok(!("extData" in tabCurState) || !("uniq" in tabCurState.extData),
- "sanity check that tab doesn't have extData or extData doesn't have 'uniq'");
- }
- }
-
- // Now we'll set a new unique value on 1 of the tabs
- let newUniq = r();
- ss.setTabValue(gBrowser.tabs[1], "uniq", newUniq);
- let tabState = JSON.parse(ss.getTabState(gBrowser.tabs[1]));
- is(tabState.extData.uniq, newUniq,
- "(overwriting) new data is stored in extData");
-
- // hide the next tab before closing it
- gBrowser.hideTab(gBrowser.tabs[2]);
- tabState = JSON.parse(ss.getTabState(gBrowser.tabs[2]));
- ok(tabState.hidden, "(hiding) tab data has hidden == true");
-
- // set data that's not in a conflicting key
- let stillUniq = r();
- ss.setTabValue(gBrowser.tabs[3], "stillUniq", stillUniq);
- tabState = JSON.parse(ss.getTabState(gBrowser.tabs[3]));
- is(tabState.extData.stillUniq, stillUniq,
- "(adding) new data is stored in extData");
-
- // remove the uniq value and make sure it's not there in the closed data
- ss.deleteTabValue(gBrowser.tabs[4], "uniq");
- tabState = JSON.parse(ss.getTabState(gBrowser.tabs[4]));
- // Since Panorama might have put data in, first check if there is extData.
- // If there is explicitly check that "uniq" isn't in it. Otherwise, we're ok
- if ("extData" in tabState) {
- ok(!("uniq" in tabState.extData),
- "(deleting) uniq not in existing extData");
- }
- else {
- ok(true, "(deleting) no data is stored in extData");
- }
-
- // set unique data on the tab that never had any set, make sure that's saved
- let newUniq2 = r();
- ss.setTabValue(gBrowser.tabs[5], "uniq", newUniq2);
- tabState = JSON.parse(ss.getTabState(gBrowser.tabs[5]));
- is(tabState.extData.uniq, newUniq2,
- "(creating) new data is stored in extData where there was none");
-
- while (gBrowser.tabs.length > 1) {
- yield promiseRemoveTab(gBrowser.tabs[1]);
- }
- }
-
- // Set the test state.
- ss.setBrowserState(JSON.stringify(state));
-
- // Wait until the selected tab is restored and all others are pending.
- yield Promise.all(Array.map(gBrowser.tabs, tab => {
- return (tab == gBrowser.selectedTab) ?
- promiseTabRestored(tab) : promiseTabRestoring(tab)
- }));
-
- // Kick off the actual tests.
- yield progressCallback();
-
- // Cleanup.
- yield promiseBrowserState(stateBackup);
-});
diff --git a/browser/components/sessionstore/test/browser_615394-SSWindowState_events.js b/browser/components/sessionstore/test/browser_615394-SSWindowState_events.js
deleted file mode 100644
index 0b6b8faa6..000000000
--- a/browser/components/sessionstore/test/browser_615394-SSWindowState_events.js
+++ /dev/null
@@ -1,361 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const stateBackup = JSON.parse(ss.getBrowserState());
-const testState = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:blank" }] },
- { entries: [{ url: "about:rights" }] }
- ]
- }]
-};
-const lameMultiWindowState = { windows: [
- {
- tabs: [
- { entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }
- ],
- selected: 1
- },
- {
- tabs: [
- { entries: [{ url: "http://example.com#1" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#2" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#3" }], extData: { "uniq": r() } },
- { entries: [{ url: "http://example.com#4" }], extData: { "uniq": r() } },
- ],
- selected: 3
- }
- ] };
-
-
-function getOuterWindowID(aWindow) {
- return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
-}
-
-function test() {
- /** Test for Bug 615394 - Session Restore should notify when it is beginning and ending a restore **/
- waitForExplicitFinish();
- // Preemptively extend the timeout to prevent [orange]
- requestLongerTimeout(4);
- runNextTest();
-}
-
-
-var tests = [
- test_setTabState,
- test_duplicateTab,
- test_undoCloseTab,
- test_setWindowState,
- test_setBrowserState,
- test_undoCloseWindow
-];
-function runNextTest() {
- // set an empty state & run the next test, or finish
- if (tests.length) {
- // Enumerate windows and close everything but our primary window. We can't
- // use waitForFocus() because apparently it's buggy. See bug 599253.
- var windowsEnum = Services.wm.getEnumerator("navigator:browser");
- let closeWinPromises = [];
- while (windowsEnum.hasMoreElements()) {
- var currentWindow = windowsEnum.getNext();
- if (currentWindow != window) {
- closeWinPromises.push(BrowserTestUtils.closeWindow(currentWindow));
- }
- }
-
- Promise.all(closeWinPromises).then(() => {
- let currentTest = tests.shift();
- info("prepping for " + currentTest.name);
- waitForBrowserState(testState, currentTest);
- });
- }
- else {
- waitForBrowserState(stateBackup, finish);
- }
-}
-
-/** ACTUAL TESTS **/
-
-function test_setTabState() {
- let tab = gBrowser.tabs[1];
- let newTabState = JSON.stringify({ entries: [{ url: "http://example.org" }], extData: { foo: "bar" } });
- let busyEventCount = 0;
- let readyEventCount = 0;
-
- function onSSWindowStateBusy(aEvent) {
- busyEventCount++;
- }
-
- function onSSWindowStateReady(aEvent) {
- readyEventCount++;
- is(ss.getTabValue(tab, "foo"), "bar");
- ss.setTabValue(tab, "baz", "qux");
- }
-
- function onSSTabRestored(aEvent) {
- is(busyEventCount, 1);
- is(readyEventCount, 1);
- is(ss.getTabValue(tab, "baz"), "qux");
- is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
-
- window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
-
- runNextTest();
- }
-
- window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
- ss.setTabState(tab, newTabState);
-}
-
-
-function test_duplicateTab() {
- let tab = gBrowser.tabs[1];
- let busyEventCount = 0;
- let readyEventCount = 0;
- let newTab;
-
- // We'll look to make sure this value is on the duplicated tab
- ss.setTabValue(tab, "foo", "bar");
-
- function onSSWindowStateBusy(aEvent) {
- busyEventCount++;
- }
-
- function onSSWindowStateReady(aEvent) {
- newTab = gBrowser.tabs[2];
- readyEventCount++;
- is(ss.getTabValue(newTab, "foo"), "bar");
- ss.setTabValue(newTab, "baz", "qux");
- }
-
- function onSSTabRestored(aEvent) {
- is(busyEventCount, 1);
- is(readyEventCount, 1);
- is(ss.getTabValue(newTab, "baz"), "qux");
- is(newTab.linkedBrowser.currentURI.spec, "about:rights");
-
- window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
-
- runNextTest();
- }
-
- window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
-
- newTab = ss.duplicateTab(window, tab);
-}
-
-
-function test_undoCloseTab() {
- let tab = gBrowser.tabs[1],
- busyEventCount = 0,
- readyEventCount = 0,
- reopenedTab;
-
- ss.setTabValue(tab, "foo", "bar");
-
- function onSSWindowStateBusy(aEvent) {
- busyEventCount++;
- }
-
- function onSSWindowStateReady(aEvent) {
- reopenedTab = gBrowser.tabs[1];
- readyEventCount++;
- is(ss.getTabValue(reopenedTab, "foo"), "bar");
- ss.setTabValue(reopenedTab, "baz", "qux");
- }
-
- function onSSTabRestored(aEvent) {
- is(busyEventCount, 1);
- is(readyEventCount, 1);
- is(ss.getTabValue(reopenedTab, "baz"), "qux");
- is(reopenedTab.linkedBrowser.currentURI.spec, "about:rights");
-
- window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
-
- runNextTest();
- }
-
- window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
-
- gBrowser.removeTab(tab);
- reopenedTab = ss.undoCloseTab(window, 0);
-}
-
-
-function test_setWindowState() {
- let testState = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:mozilla" }], extData: { "foo": "bar" } },
- { entries: [{ url: "http://example.org" }], extData: { "baz": "qux" } }
- ]
- }]
- };
-
- let busyEventCount = 0,
- readyEventCount = 0,
- tabRestoredCount = 0;
-
- function onSSWindowStateBusy(aEvent) {
- busyEventCount++;
- }
-
- function onSSWindowStateReady(aEvent) {
- readyEventCount++;
- is(ss.getTabValue(gBrowser.tabs[0], "foo"), "bar");
- is(ss.getTabValue(gBrowser.tabs[1], "baz"), "qux");
- }
-
- function onSSTabRestored(aEvent) {
- if (++tabRestoredCount < 2)
- return;
-
- is(busyEventCount, 1);
- is(readyEventCount, 1);
- is(gBrowser.tabs[0].linkedBrowser.currentURI.spec, "about:mozilla");
- is(gBrowser.tabs[1].linkedBrowser.currentURI.spec, "http://example.org/");
-
- window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
-
- runNextTest();
- }
-
- window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
-
- ss.setWindowState(window, JSON.stringify(testState), true);
-}
-
-
-function test_setBrowserState() {
- // We'll track events per window so we are sure that they are each happening once
- // pre window.
- let windowEvents = {};
- windowEvents[getOuterWindowID(window)] = { busyEventCount: 0, readyEventCount: 0 };
-
- // 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, false);
-
- Services.ww.unregisterNotification(windowObserver);
-
- windowEvents[getOuterWindowID(newWindow)] = { busyEventCount: 0, readyEventCount: 0 };
-
- newWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- newWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- }, false);
- }
- }
-
- function onSSWindowStateBusy(aEvent) {
- windowEvents[getOuterWindowID(aEvent.originalTarget)].busyEventCount++;
- }
-
- function onSSWindowStateReady(aEvent) {
- windowEvents[getOuterWindowID(aEvent.originalTarget)].readyEventCount++;
- }
-
- window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- Services.ww.registerNotification(windowObserver);
-
- waitForBrowserState(lameMultiWindowState, function() {
- let checkedWindows = 0;
- for (let id of Object.keys(windowEvents)) {
- let winEvents = windowEvents[id];
- is(winEvents.busyEventCount, 1,
- "[test_setBrowserState] window" + id + " busy event count correct");
- is(winEvents.readyEventCount, 1,
- "[test_setBrowserState] window" + id + " ready event count correct");
- checkedWindows++;
- }
- is(checkedWindows, 2,
- "[test_setBrowserState] checked 2 windows");
- window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- newWindow.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- newWindow.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- runNextTest();
- });
-}
-
-
-function test_undoCloseWindow() {
- let newWindow, reopenedWindow;
-
- function firstWindowObserver(aSubject, aTopic, aData) {
- if (aTopic == "domwindowopened") {
- newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
- Services.ww.unregisterNotification(firstWindowObserver);
- }
- }
- Services.ww.registerNotification(firstWindowObserver);
-
- waitForBrowserState(lameMultiWindowState, function() {
- // 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, false);
- reopenedWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
-
- reopenedWindow.addEventListener("load", function() {
- reopenedWindow.removeEventListener("load", arguments.callee, false);
-
- reopenedWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
- }, false);
- });
- });
-
- let busyEventCount = 0,
- readyEventCount = 0,
- tabRestoredCount = 0;
- // These will listen to the reopened closed window...
- function onSSWindowStateBusy(aEvent) {
- busyEventCount++;
- }
-
- function onSSWindowStateReady(aEvent) {
- readyEventCount++;
- }
-
- function onSSTabRestored(aEvent) {
- if (++tabRestoredCount < 4)
- return;
-
- is(busyEventCount, 1);
- is(readyEventCount, 1);
-
- reopenedWindow.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
- reopenedWindow.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
- reopenedWindow.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
-
- BrowserTestUtils.closeWindow(reopenedWindow).then(runNextTest);
- }
-}
diff --git a/browser/components/sessionstore/test/browser_618151.js b/browser/components/sessionstore/test/browser_618151.js
deleted file mode 100644
index bdc268e6c..000000000
--- a/browser/components/sessionstore/test/browser_618151.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const stateBackup = ss.getBrowserState();
-const testState = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:blank" }] },
- { entries: [{ url: "about:mozilla" }] }
- ]
- }]
-};
-
-
-function test() {
- /** Test for Bug 618151 - Overwriting state can lead to unrestored tabs **/
- waitForExplicitFinish();
- runNextTest();
-}
-
-// Just a subset of tests from bug 615394 that causes a timeout.
-var tests = [test_setup, test_hang];
-function runNextTest() {
- // set an empty state & run the next test, or finish
- if (tests.length) {
- // Enumerate windows and close everything but our primary window. We can't
- // use waitForFocus() because apparently it's buggy. See bug 599253.
- var windowsEnum = Services.wm.getEnumerator("navigator:browser");
- let closeWinPromises = [];
- while (windowsEnum.hasMoreElements()) {
- var currentWindow = windowsEnum.getNext();
- if (currentWindow != window) {
- closeWinPromises.push(BrowserTestUtils.closeWindow(currentWindow));
- }
- }
-
- Promise.all(closeWinPromises).then(() => {
- let currentTest = tests.shift();
- info("running " + currentTest.name);
- waitForBrowserState(testState, currentTest);
- });
- }
- else {
- ss.setBrowserState(stateBackup);
- executeSoon(finish);
- }
-}
-
-function test_setup() {
- function onSSTabRestored(aEvent) {
- gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, false);
- runNextTest();
- }
-
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
- ss.setTabState(gBrowser.tabs[1], JSON.stringify({
- entries: [{ url: "http://example.org" }],
- extData: { foo: "bar" } }));
-}
-
-function test_hang() {
- ok(true, "test didn't time out");
- runNextTest();
-}
diff --git a/browser/components/sessionstore/test/browser_623779.js b/browser/components/sessionstore/test/browser_623779.js
deleted file mode 100644
index 267bccb2d..000000000
--- a/browser/components/sessionstore/test/browser_623779.js
+++ /dev/null
@@ -1,13 +0,0 @@
-"use strict";
-
-add_task(function* () {
- gBrowser.pinTab(gBrowser.selectedTab);
-
- let newTab = gBrowser.duplicateTab(gBrowser.selectedTab);
- yield promiseTabRestored(newTab);
-
- ok(!newTab.pinned, "duplicating a pinned tab creates unpinned tab");
- yield promiseRemoveTab(newTab);
-
- gBrowser.unpinTab(gBrowser.selectedTab);
-});
diff --git a/browser/components/sessionstore/test/browser_624727.js b/browser/components/sessionstore/test/browser_624727.js
deleted file mode 100644
index 85d6ff042..000000000
--- a/browser/components/sessionstore/test/browser_624727.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var TEST_STATE = { windows: [{ tabs: [{ url: "about:blank" }] }] };
-
-add_task(function* () {
- function assertNumberOfTabs(num, msg) {
- is(gBrowser.tabs.length, num, msg);
- }
-
- function assertNumberOfPinnedTabs(num, msg) {
- is(gBrowser._numPinnedTabs, num, msg);
- }
-
- // check prerequisites
- assertNumberOfTabs(1, "we start off with one tab");
- assertNumberOfPinnedTabs(0, "no pinned tabs so far");
-
- // setup
- gBrowser.addTab("about:blank");
- assertNumberOfTabs(2, "there are two tabs, now");
-
- let [tab1, tab2] = gBrowser.tabs;
- let linkedBrowser = tab1.linkedBrowser;
- gBrowser.pinTab(tab1);
- gBrowser.pinTab(tab2);
- assertNumberOfPinnedTabs(2, "both tabs are now pinned");
-
- // run the test
- yield promiseBrowserState(TEST_STATE);
-
- assertNumberOfTabs(1, "one tab left after setBrowserState()");
- assertNumberOfPinnedTabs(0, "there are no pinned tabs");
- is(gBrowser.tabs[0].linkedBrowser, linkedBrowser, "first tab's browser got re-used");
-});
diff --git a/browser/components/sessionstore/test/browser_625016.js b/browser/components/sessionstore/test/browser_625016.js
deleted file mode 100644
index b551fcbb3..000000000
--- a/browser/components/sessionstore/test/browser_625016.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function* setup() {
- /** Test for Bug 625016 - Restore windows closed in succession to quit (non-OSX only) **/
-
- // We'll test this by opening a new window, waiting for the save
- // event, then closing that window. We'll observe the
- // "sessionstore-state-write-complete" notification and check that
- // the state contains no _closedWindows. We'll then add a new tab
- // and make sure that the state following that was reset and the
- // closed window is now in _closedWindows.
-
- requestLongerTimeout(2);
-
- yield forceSaveState();
-
- // We'll clear all closed windows to make sure our state is clean
- // forgetClosedWindow doesn't trigger a delayed save
- forgetClosedWindows();
- is(ss.getClosedWindowCount(), 0, "starting with no closed windows");
-});
-
-add_task(function* new_window() {
- let newWin;
- try {
- newWin = yield promiseNewWindowLoaded();
- let tab = newWin.gBrowser.addTab("http://example.com/browser_625016.js?" + Math.random());
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- // Double check that we have no closed windows
- is(ss.getClosedWindowCount(), 0, "no closed windows on first save");
-
- yield BrowserTestUtils.closeWindow(newWin);
- newWin = null;
-
- let state = JSON.parse((yield promiseRecoveryFileContents()));
- is(state.windows.length, 2,
- "observe1: 2 windows in data written to disk");
- is(state._closedWindows.length, 0,
- "observe1: no closed windows in data written to disk");
-
- // The API still treats the closed window as closed, so ensure that window is there
- is(ss.getClosedWindowCount(), 1,
- "observe1: 1 closed window according to API");
- } finally {
- if (newWin) {
- yield BrowserTestUtils.closeWindow(newWin);
- }
- yield forceSaveState();
- }
-});
-
-// We'll open a tab, which should trigger another state save which would wipe
-// the _shouldRestore attribute from the closed window
-add_task(function* new_tab() {
- let newTab;
- try {
- newTab = gBrowser.addTab("about:mozilla");
-
- let state = JSON.parse((yield promiseRecoveryFileContents()));
- is(state.windows.length, 1,
- "observe2: 1 window in data being written to disk");
- is(state._closedWindows.length, 1,
- "observe2: 1 closed window in data being written to disk");
-
- // The API still treats the closed window as closed, so ensure that window is there
- is(ss.getClosedWindowCount(), 1,
- "observe2: 1 closed window according to API");
- } finally {
- gBrowser.removeTab(newTab);
- }
-});
-
-
-add_task(function* done() {
- // The API still represents the closed window as closed, so we can clear it
- // with the API, but just to make sure...
-// is(ss.getClosedWindowCount(), 1, "1 closed window according to API");
- forgetClosedWindows();
- Services.prefs.clearUserPref("browser.sessionstore.interval");
-});
diff --git a/browser/components/sessionstore/test/browser_628270.js b/browser/components/sessionstore/test/browser_628270.js
deleted file mode 100644
index f552cbfda..000000000
--- a/browser/components/sessionstore/test/browser_628270.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- let assertNumberOfTabs = function (num, msg) {
- is(gBrowser.tabs.length, num, msg);
- }
-
- let assertNumberOfVisibleTabs = function (num, msg) {
- is(gBrowser.visibleTabs.length, num, msg);
- }
-
- let assertNumberOfPinnedTabs = function (num, msg) {
- is(gBrowser._numPinnedTabs, num, msg);
- }
-
- waitForExplicitFinish();
-
- // check prerequisites
- assertNumberOfTabs(1, "we start off with one tab");
-
- // setup
- let tab = gBrowser.addTab("about:mozilla");
-
- whenTabIsLoaded(tab, function () {
- // hide the newly created tab
- assertNumberOfVisibleTabs(2, "there are two visible tabs");
- gBrowser.showOnlyTheseTabs([gBrowser.tabs[0]]);
- assertNumberOfVisibleTabs(1, "there is one visible tab");
- ok(tab.hidden, "newly created tab is now hidden");
-
- // close and restore hidden tab
- promiseRemoveTab(tab).then(() => {
- tab = ss.undoCloseTab(window, 0);
-
- // check that everything was restored correctly, clean up and finish
- whenTabIsLoaded(tab, function () {
- is(tab.linkedBrowser.currentURI.spec, "about:mozilla", "restored tab has correct url");
-
- gBrowser.removeTab(tab);
- finish();
- });
- });
- });
-}
-
-function whenTabIsLoaded(tab, callback) {
- tab.linkedBrowser.addEventListener("load", function onLoad() {
- tab.linkedBrowser.removeEventListener("load", onLoad, true);
- callback();
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_635418.js b/browser/components/sessionstore/test/browser_635418.js
deleted file mode 100644
index 3b21c5b0f..000000000
--- a/browser/components/sessionstore/test/browser_635418.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This tests that hiding/showing a tab, on its own, eventually triggers a
-// session store.
-
-function test() {
- waitForExplicitFinish();
-
- // We speed up the interval between session saves to ensure that the test
- // runs quickly.
- Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
-
- // Loading a tab causes a save state and this is meant to catch that event.
- waitForSaveState(testBug635418_1);
-
- // Assumption: Only one window is open and it has one tab open.
- gBrowser.addTab("about:mozilla");
-}
-
-function testBug635418_1() {
- ok(!gBrowser.tabs[0].hidden, "first tab should not be hidden");
- ok(!gBrowser.tabs[1].hidden, "second tab should not be hidden");
-
- waitForSaveState(testBug635418_2);
-
- // We can't hide the selected tab, so hide the new one
- gBrowser.hideTab(gBrowser.tabs[1]);
-}
-
-function testBug635418_2() {
- let state = JSON.parse(ss.getBrowserState());
- ok(!state.windows[0].tabs[0].hidden, "first tab should still not be hidden");
- ok(state.windows[0].tabs[1].hidden, "second tab should be hidden by now");
-
- waitForSaveState(testBug635418_3);
- gBrowser.showTab(gBrowser.tabs[1]);
-}
-
-function testBug635418_3() {
- let state = JSON.parse(ss.getBrowserState());
- ok(!state.windows[0].tabs[0].hidden, "first tab should still still not be hidden");
- ok(!state.windows[0].tabs[1].hidden, "second tab should not be hidden again");
-
- done();
-}
-
-function done() {
- gBrowser.removeTab(window.gBrowser.tabs[1]);
-
- Services.prefs.clearUserPref("browser.sessionstore.interval");
-
- executeSoon(finish);
-}
diff --git a/browser/components/sessionstore/test/browser_636279.js b/browser/components/sessionstore/test/browser_636279.js
deleted file mode 100644
index 250995606..000000000
--- a/browser/components/sessionstore/test/browser_636279.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var stateBackup = ss.getBrowserState();
-
-var statePinned = {windows:[{tabs:[
- {entries:[{url:"http://example.com#1"}], pinned: true}
-]}]};
-
-var state = {windows:[{tabs:[
- {entries:[{url:"http://example.com#1"}]},
- {entries:[{url:"http://example.com#2"}]},
- {entries:[{url:"http://example.com#3"}]},
- {entries:[{url:"http://example.com#4"}]},
-]}]};
-
-function test() {
- waitForExplicitFinish();
-
- registerCleanupFunction(function () {
- TabsProgressListener.uninit();
- ss.setBrowserState(stateBackup);
- });
-
-
- TabsProgressListener.init();
-
- window.addEventListener("SSWindowStateReady", function onReady() {
- window.removeEventListener("SSWindowStateReady", onReady, false);
-
- 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");
- }
-
- if (0 == needsRestore) {
- TabsProgressListener.unsetCallback();
- waitForFocus(finish);
- }
- });
-
- ss.setBrowserState(JSON.stringify(state));
- }, false);
-
- ss.setBrowserState(JSON.stringify(statePinned));
-}
-
-function countTabs() {
- let needsRestore = 0, isRestoring = 0;
- let windowsEnum = Services.wm.getEnumerator("navigator:browser");
-
- while (windowsEnum.hasMoreElements()) {
- let window = windowsEnum.getNext();
- if (window.closed)
- continue;
-
- for (let i = 0; i < window.gBrowser.tabs.length; i++) {
- let browser = window.gBrowser.tabs[i].linkedBrowser;
- if (browser.__SS_restoreState == TAB_STATE_RESTORING)
- isRestoring++;
- else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
- needsRestore++;
- }
- }
-
- return [needsRestore, isRestoring];
-}
-
-var TabsProgressListener = {
- init: function () {
- Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
- },
-
- uninit: function () {
- Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
- this.unsetCallback();
- },
-
- setCallback: function (callback) {
- this.callback = callback;
- },
-
- unsetCallback: function () {
- delete this.callback;
- },
-
- observe: function (browser, topic, data) {
- TabsProgressListener.onRestored(browser);
- },
-
- onRestored: function (browser) {
- if (this.callback && browser.__SS_restoreState == TAB_STATE_RESTORING) {
- this.callback.apply(null, countTabs());
- }
- }
-}
diff --git a/browser/components/sessionstore/test/browser_637020.js b/browser/components/sessionstore/test/browser_637020.js
deleted file mode 100644
index 1c1f357d7..000000000
--- a/browser/components/sessionstore/test/browser_637020.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
- "sessionstore/test/browser_637020_slow.sjs";
-
-const TEST_STATE = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:mozilla" }] },
- { entries: [{ url: "about:robots" }] }
- ]
- }, {
- tabs: [
- { entries: [{ url: TEST_URL }] },
- { entries: [{ url: TEST_URL }] }
- ]
- }]
-};
-
-/**
- * This test ensures that windows that have just been restored will be marked
- * as dirty, otherwise _getCurrentState() might ignore them when collecting
- * state for the first time and we'd just save them as empty objects.
- *
- * The dirty state acts as a cache to not collect data from all windows all the
- * time, so at the beginning, each window must be dirty so that we collect
- * their state at least once.
- */
-
-add_task(function* test() {
- // Wait until the new window has been opened.
- let promiseWindow = new Promise(resolve => {
- Services.obs.addObserver(function onOpened(subject) {
- Services.obs.removeObserver(onOpened, "domwindowopened");
- resolve(subject);
- }, "domwindowopened", false);
- });
-
- // Set the new browser state that will
- // restore a window with two slowly loading tabs.
- let backupState = SessionStore.getBrowserState();
- SessionStore.setBrowserState(JSON.stringify(TEST_STATE));
- let win = yield promiseWindow;
-
- // The window has now been opened. Check the state that is returned,
- // this should come from the cache while the window isn't restored, yet.
- info("the window has been opened");
- checkWindows();
-
- // The history has now been restored and the tabs are loading. The data must
- // now come from the window, if it's correctly been marked as dirty before.
- yield new Promise(resolve => whenDelayedStartupFinished(win, resolve));
- info("the delayed startup has finished");
- checkWindows();
-
- // Cleanup.
- yield BrowserTestUtils.closeWindow(win);
- yield promiseBrowserState(backupState);
-});
-
-function checkWindows() {
- let state = JSON.parse(SessionStore.getBrowserState());
- is(state.windows[0].tabs.length, 2, "first window has two tabs");
- is(state.windows[1].tabs.length, 2, "second window has two tabs");
-}
diff --git a/browser/components/sessionstore/test/browser_637020_slow.sjs b/browser/components/sessionstore/test/browser_637020_slow.sjs
deleted file mode 100644
index 41da3c2ad..000000000
--- a/browser/components/sessionstore/test/browser_637020_slow.sjs
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const DELAY_MS = "2000";
-
-let timer;
-
-function handleRequest(req, resp) {
- resp.processAsync();
- resp.setHeader("Cache-Control", "no-cache", false);
- resp.setHeader("Content-Type", "text/html;charset=utf-8", false);
-
- timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.init(() => {
- resp.write("hi");
- resp.finish();
- }, DELAY_MS, Ci.nsITimer.TYPE_ONE_SHOT);
-}
diff --git a/browser/components/sessionstore/test/browser_644409-scratchpads.js b/browser/components/sessionstore/test/browser_644409-scratchpads.js
deleted file mode 100644
index 56826801a..000000000
--- a/browser/components/sessionstore/test/browser_644409-scratchpads.js
+++ /dev/null
@@ -1,68 +0,0 @@
- /* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const testState = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:blank" }] },
- ]
- }],
- scratchpads: [
- { text: "text1", executionContext: 1 },
- { text: "", executionContext: 2, filename: "test.js" }
- ]
-};
-
-// only finish() when correct number of windows opened
-var restored = [];
-function addState(state) {
- restored.push(state);
-
- if (restored.length == testState.scratchpads.length) {
- ok(statesMatch(restored, testState.scratchpads),
- "Two scratchpad windows restored");
-
- Services.ww.unregisterNotification(windowObserver);
- finish();
- }
-}
-
-function test() {
- waitForExplicitFinish();
-
- 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, false);
-
- if (win.Scratchpad) {
- win.Scratchpad.addObserver({
- onReady: function() {
- win.Scratchpad.removeObserver(this);
-
- let state = win.Scratchpad.getState();
- BrowserTestUtils.closeWindow(win).then(() => {
- addState(state);
- });
- },
- });
- }
- }, false);
- }
-}
-
-function statesMatch(restored, states) {
- return states.every(function(state) {
- return restored.some(function(restoredState) {
- return state.filename == restoredState.filename &&
- state.text == restoredState.text &&
- state.executionContext == restoredState.executionContext;
- })
- });
-}
diff --git a/browser/components/sessionstore/test/browser_645428.js b/browser/components/sessionstore/test/browser_645428.js
deleted file mode 100644
index 124a7aea9..000000000
--- a/browser/components/sessionstore/test/browser_645428.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const NOTIFICATION = "sessionstore-browser-state-restored";
-
-function test() {
- waitForExplicitFinish();
-
- function observe(subject, topic, data) {
- if (NOTIFICATION == topic) {
- finish();
- ok(true, "TOPIC received");
- }
- }
-
- Services.obs.addObserver(observe, NOTIFICATION, false);
- registerCleanupFunction(function () {
- Services.obs.removeObserver(observe, NOTIFICATION);
- });
-
- ss.setBrowserState(JSON.stringify({ windows: [] }));
-}
diff --git a/browser/components/sessionstore/test/browser_659591.js b/browser/components/sessionstore/test/browser_659591.js
deleted file mode 100644
index 60b1dcd2e..000000000
--- a/browser/components/sessionstore/test/browser_659591.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- waitForExplicitFinish();
-
- let eventReceived = false;
-
- registerCleanupFunction(function () {
- ok(eventReceived, "SSWindowClosing event received");
- });
-
- newWindow(function (win) {
- win.addEventListener("SSWindowClosing", function onWindowClosing() {
- win.removeEventListener("SSWindowClosing", onWindowClosing, false);
- eventReceived = true;
- }, false);
-
- 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, false);
- executeSoon(() => callback(win));
- }, false);
-}
diff --git a/browser/components/sessionstore/test/browser_662743.js b/browser/components/sessionstore/test/browser_662743.js
deleted file mode 100644
index 212180213..000000000
--- a/browser/components/sessionstore/test/browser_662743.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// This tests that session restore component does restore the right <select> option.
-// Session store should not rely only on previous user's selectedIndex, it should
-// check its value as well.
-
-function test() {
- /** Tests selected options **/
- requestLongerTimeout(2);
- waitForExplicitFinish();
-
- let testTabCount = 0;
- let formData = [
- // default case
- { },
-
- // new format
- // index doesn't match value (testing an option in between (two))
- { id:{ "select_id": {"selectedIndex":0,"value":"val2"} } },
- // index doesn't match value (testing an invalid value)
- { id:{ "select_id": {"selectedIndex":4,"value":"val8"} } },
- // index doesn't match value (testing an invalid index)
- { id:{ "select_id": {"selectedIndex":8,"value":"val5"} } },
- // index and value match position zero
- { id:{ "select_id": {"selectedIndex":0,"value":"val0"} }, xpath: {} },
- // index doesn't match value (testing the last option (seven))
- { id:{},"xpath":{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']": {"selectedIndex":1,"value":"val7"} } },
- // index and value match the default option "selectedIndex":3,"value":"val3"
- { xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":3,"value":"val3"} } },
- // index matches default option however it doesn't match value
- { id:{ "select_id": {"selectedIndex":3,"value":"val4"} } },
- ];
-
- let expectedValues = [
- null, // default value
- "val2",
- null, // default value (invalid value)
- "val5", // value is still valid (even it has an invalid index)
- "val0",
- "val7",
- null,
- "val4",
- ];
- let callback = function() {
- testTabCount--;
- if (testTabCount == 0) {
- finish();
- }
- };
-
- for (let i = 0; i < formData.length; i++) {
- testTabCount++;
- testTabRestoreData(formData[i], expectedValues[i], callback);
- }
-}
-
-function testTabRestoreData(aFormData, aExpectedValue, aCallback) {
- let testURL =
- getRootDirectory(gTestPath) + "browser_662743_sample.html";
- let tab = gBrowser.addTab(testURL);
-
- aFormData.url = testURL;
- let tabState = { entries: [{ url: testURL, }], formdata: aFormData };
-
- promiseBrowserLoaded(tab.linkedBrowser).then(() => {
- promiseTabState(tab, tabState).then(() => {
- // Flush to make sure we have the latest form data.
- return TabStateFlusher.flush(tab.linkedBrowser);
- }).then(() => {
- let doc = tab.linkedBrowser.contentDocument;
- let select = doc.getElementById("select_id");
- let value = select.options[select.selectedIndex].value;
- let restoredTabState = JSON.parse(ss.getTabState(tab));
-
- // If aExpectedValue=null we don't expect any form data to be collected.
- if (!aExpectedValue) {
- ok(!restoredTabState.hasOwnProperty("formdata"), "no formdata collected");
- gBrowser.removeTab(tab);
- aCallback();
- return;
- }
-
- // test select options values
- is(value, aExpectedValue,
- "Select Option by selectedIndex &/or value has been restored correctly");
-
- let restoredFormData = restoredTabState.formdata;
- let selectIdFormData = restoredFormData.id.select_id;
- value = restoredFormData.id.select_id.value;
-
- // test format
- ok("id" in restoredFormData || "xpath" in restoredFormData,
- "FormData format is valid");
- // test format
- ok("selectedIndex" in selectIdFormData && "value" in selectIdFormData,
- "select format is valid");
- // test set collection values
- is(value, aExpectedValue,
- "Collection has been saved correctly");
-
- // clean up
- gBrowser.removeTab(tab);
-
- aCallback();
- });
- });
-}
diff --git a/browser/components/sessionstore/test/browser_662743_sample.html b/browser/components/sessionstore/test/browser_662743_sample.html
deleted file mode 100644
index de48fa0c9..000000000
--- a/browser/components/sessionstore/test/browser_662743_sample.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<title>Test 662743</title>
-
-<!-- Select events -->
-<h3>Select options</h3>
-<select id="select_id" name="select_name">
- <option value="val0">Zero</option>
- <option value="val1">One</option>
- <option value="val2">Two</option>
- <option value="val3" selected="selected">Three</option>
- <option value="val4">Four</option>
- <option value="val5">Five</option>
- <option value="val6">Six</option>
- <option value="val7">Seven</option>
-</select> \ No newline at end of file
diff --git a/browser/components/sessionstore/test/browser_662812.js b/browser/components/sessionstore/test/browser_662812.js
deleted file mode 100644
index 1bbaf67dc..000000000
--- a/browser/components/sessionstore/test/browser_662812.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 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, false);
-
- let state = JSON.parse(ss.getWindowState(window));
- ok(state.windows[0].busy, "window is busy");
-
- window.addEventListener("SSWindowStateReady", function onReady() {
- window.removeEventListener("SSWindowStateReady", onReady, false);
-
- let state = JSON.parse(ss.getWindowState(window));
- ok(!state.windows[0].busy, "window is not busy");
-
- executeSoon(() => {
- gBrowser.removeTab(gBrowser.tabs[1]);
- finish();
- });
- }, false);
- }, false);
-
- // 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);
- gBrowser.removeTab(tab);
- ss.undoCloseTab(window, 0);
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_665702-state_session.js b/browser/components/sessionstore/test/browser_665702-state_session.js
deleted file mode 100644
index 524b4969f..000000000
--- a/browser/components/sessionstore/test/browser_665702-state_session.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function compareArray(a, b) {
- if (a.length !== b.length) {
- return false;
- }
- for (let i = 0; i < a.length; i++) {
- if (a[i] !== b[i]) {
- return false;
- }
- }
- return true;
-}
-
-function test() {
- let currentState = JSON.parse(ss.getBrowserState());
- ok(currentState.session, "session data returned by getBrowserState");
-
- let keys = Object.keys(currentState.session);
- let expectedKeys = ["lastUpdate", "startTime", "recentCrashes"];
- ok(compareArray(keys.sort(), expectedKeys.sort()),
- "session object from getBrowserState has correct keys");
-}
diff --git a/browser/components/sessionstore/test/browser_682507.js b/browser/components/sessionstore/test/browser_682507.js
deleted file mode 100644
index 52b95341b..000000000
--- a/browser/components/sessionstore/test/browser_682507.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function test() {
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
- gBrowser.addTab("about:mozilla");
-
- ss.setTabState(gBrowser.tabs[1], ss.getTabState(gBrowser.tabs[1]));
- ok(gBrowser.tabs[1].hasAttribute("pending"), "second tab should have 'pending' attribute");
-
- gBrowser.selectedTab = gBrowser.tabs[1];
- ok(!gBrowser.tabs[1].hasAttribute("pending"), "second tab should have not 'pending' attribute");
-
- gBrowser.removeTab(gBrowser.tabs[1]);
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
-}
diff --git a/browser/components/sessionstore/test/browser_687710.js b/browser/components/sessionstore/test/browser_687710.js
deleted file mode 100644
index 372ecf7ae..000000000
--- a/browser/components/sessionstore/test/browser_687710.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that sessionrestore handles cycles in the shentry graph properly.
-//
-// These cycles shouldn't be there in the first place, but they cause hangs
-// when they mysteriously appear (bug 687710). Docshell code assumes this
-// graph is a tree and tires to walk to the root. But if there's a cycle,
-// there is no root, and we loop forever.
-
-var stateBackup = ss.getBrowserState();
-
-var state = {windows:[{tabs:[{entries:[
- {
- docIdentifier: 1,
- url: "http://example.com",
- children: [
- {
- docIdentifier: 2,
- url: "http://example.com"
- }
- ]
- },
- {
- docIdentifier: 2,
- url: "http://example.com",
- children: [
- {
- docIdentifier: 1,
- url: "http://example.com"
- }
- ]
- }
-]}]}]}
-
-function test() {
- registerCleanupFunction(function () {
- ss.setBrowserState(stateBackup);
- });
-
- /* This test fails by hanging. */
- ss.setBrowserState(JSON.stringify(state));
- ok(true, "Didn't hang!");
-}
diff --git a/browser/components/sessionstore/test/browser_687710_2.js b/browser/components/sessionstore/test/browser_687710_2.js
deleted file mode 100644
index c22e73750..000000000
--- a/browser/components/sessionstore/test/browser_687710_2.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* eslint-env mozilla/frame-script */
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test that the fix for bug 687710 isn't too aggressive -- shentries which are
-// cousins should be able to share bfcache entries.
-
-var stateBackup = ss.getBrowserState();
-
-var state = {entries:[
- {
- docIdentifier: 1,
- url: "http://example.com?1",
- children: [{ docIdentifier: 10,
- url: "http://example.com?10" }]
- },
- {
- docIdentifier: 1,
- url: "http://example.com?1#a",
- children: [{ docIdentifier: 10,
- url: "http://example.com?10#aa" }]
- }
-]};
-
-add_task(function* test() {
- let tab = gBrowser.addTab("about:blank");
- yield promiseTabState(tab, state);
- yield ContentTask.spawn(tab.linkedBrowser, null, function() {
- function compareEntries(i, j, history) {
- let e1 = history.getEntryAtIndex(i, false)
- .QueryInterface(Ci.nsISHEntry)
- .QueryInterface(Ci.nsISHContainer);
-
- let e2 = history.getEntryAtIndex(j, false)
- .QueryInterface(Ci.nsISHEntry)
- .QueryInterface(Ci.nsISHContainer);
-
- ok(e1.sharesDocumentWith(e2),
- `${i} should share doc with ${j}`);
- is(e1.childCount, e2.childCount,
- `Child count mismatch (${i}, ${j})`);
-
- for (let c = 0; c < e1.childCount; c++) {
- let c1 = e1.GetChildAt(c);
- let c2 = e2.GetChildAt(c);
-
- ok(c1.sharesDocumentWith(c2),
- `Cousins should share documents. (${i}, ${j}, ${c})`);
- }
- }
-
- let history = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISHistory);
-
- is(history.count, 2, "history.count");
- for (let i = 0; i < history.count; i++) {
- for (let j = 0; j < history.count; j++) {
- compareEntries(i, j, history);
- }
- }
- });
-
- ss.setBrowserState(stateBackup);
-});
diff --git a/browser/components/sessionstore/test/browser_694378.js b/browser/components/sessionstore/test/browser_694378.js
deleted file mode 100644
index 8578428d8..000000000
--- a/browser/components/sessionstore/test/browser_694378.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test Summary:
-// 1. call ss.setWindowState with a broken state
-// 1a. ensure that it doesn't throw.
-
-function test() {
- waitForExplicitFinish();
-
- let brokenState = {
- windows: [
- { tabs: [{ entries: [{ url: "about:mozilla" }] }] }
- ],
- selectedWindow: 2
- };
- let brokenStateString = JSON.stringify(brokenState);
-
- let gotError = false;
- try {
- ss.setWindowState(window, brokenStateString, true);
- }
- catch (ex) {
- gotError = true;
- info(ex);
- }
-
- ok(!gotError, "ss.setWindowState did not throw an error");
-
- // Make sure that we reset the state. Use a full state just in case things get crazy.
- let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
- waitForBrowserState(blankState, finish);
-}
diff --git a/browser/components/sessionstore/test/browser_701377.js b/browser/components/sessionstore/test/browser_701377.js
deleted file mode 100644
index 1bf2625ef..000000000
--- a/browser/components/sessionstore/test/browser_701377.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var state = {windows:[{tabs:[
- {entries:[{url:"http://example.com#1"}]},
- {entries:[{url:"http://example.com#2"}], hidden: true}
-]}]};
-
-function test() {
- waitForExplicitFinish();
-
- newWindowWithState(state, function (aWindow) {
- let tab = aWindow.gBrowser.tabs[1];
- ok(tab.hidden, "the second tab is hidden");
-
- let tabShown = false;
- let tabShowCallback = () => tabShown = true;
- tab.addEventListener("TabShow", tabShowCallback, false);
-
- let tabState = ss.getTabState(tab);
- ss.setTabState(tab, tabState);
-
- tab.removeEventListener("TabShow", tabShowCallback, false);
- ok(tab.hidden && !tabShown, "tab remains hidden");
-
- finish();
- });
-}
-
-// ----------
-function newWindowWithState(aState, aCallback) {
- let opts = "chrome,all,dialog=no,height=800,width=800";
- let win = window.openDialog(getBrowserURL(), "_blank", opts);
-
- registerCleanupFunction(() => BrowserTestUtils.closeWindow(win));
-
- whenWindowLoaded(win, function onWindowLoaded(aWin) {
- ss.setWindowState(aWin, JSON.stringify(aState), true);
- executeSoon(() => aCallback(aWin));
- });
-}
diff --git a/browser/components/sessionstore/test/browser_705597.js b/browser/components/sessionstore/test/browser_705597.js
deleted file mode 100644
index efadcfe88..000000000
--- a/browser/components/sessionstore/test/browser_705597.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var tabState = {
- entries: [{url: "about:robots", children: [{url: "about:mozilla"}]}]
-};
-
-function test() {
- waitForExplicitFinish();
- requestLongerTimeout(2);
-
- Services.prefs.setIntPref("browser.sessionstore.interval", 4000);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.interval");
- });
-
- let tab = gBrowser.addTab("about:blank");
-
- let browser = tab.linkedBrowser;
-
- promiseTabState(tab, tabState).then(() => {
- let sessionHistory = browser.sessionHistory;
- let entry = sessionHistory.getEntryAtIndex(0, false);
- entry.QueryInterface(Ci.nsISHContainer);
-
- whenChildCount(entry, 1, function () {
- whenChildCount(entry, 2, function () {
- promiseBrowserLoaded(browser).then(() => {
- return TabStateFlusher.flush(browser);
- }).then(() => {
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "tab has one history entry");
- ok(!entries[0].children, "history entry has no subframes");
-
- // Make sure that we reset the state.
- let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
- waitForBrowserState(blankState, finish);
- });
-
- // reload the browser to deprecate the subframes
- browser.reload();
- });
-
- // create a dynamic subframe
- let doc = browser.contentDocument;
- let iframe = doc.createElement("iframe");
- doc.body.appendChild(iframe);
- iframe.setAttribute("src", "about:mozilla");
- });
- });
-}
-
-function whenChildCount(aEntry, aChildCount, aCallback) {
- if (aEntry.childCount == aChildCount)
- aCallback();
- else
- setTimeout(() => whenChildCount(aEntry, aChildCount, aCallback), 100);
-}
diff --git a/browser/components/sessionstore/test/browser_707862.js b/browser/components/sessionstore/test/browser_707862.js
deleted file mode 100644
index e12c44af4..000000000
--- a/browser/components/sessionstore/test/browser_707862.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var tabState = {
- entries: [{url: "about:robots", children: [{url: "about:mozilla"}]}]
-};
-
-function test() {
- waitForExplicitFinish();
- requestLongerTimeout(2);
-
- Services.prefs.setIntPref("browser.sessionstore.interval", 4000);
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.interval");
- });
-
- let tab = gBrowser.addTab("about:blank");
-
- let browser = tab.linkedBrowser;
-
- promiseTabState(tab, tabState).then(() => {
- let sessionHistory = browser.sessionHistory;
- let entry = sessionHistory.getEntryAtIndex(0, false);
- entry.QueryInterface(Ci.nsISHContainer);
-
- whenChildCount(entry, 1, function () {
- whenChildCount(entry, 2, function () {
- promiseBrowserLoaded(browser).then(() => {
- let sessionHistory = browser.sessionHistory;
- let entry = sessionHistory.getEntryAtIndex(0, false);
-
- whenChildCount(entry, 0, function () {
- // Make sure that we reset the state.
- let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
- waitForBrowserState(blankState, finish);
- });
- });
-
- // reload the browser to deprecate the subframes
- browser.reload();
- });
-
- // create a dynamic subframe
- let doc = browser.contentDocument;
- let iframe = doc.createElement("iframe");
- doc.body.appendChild(iframe);
- iframe.setAttribute("src", "about:mozilla");
- });
- });
-
- // This test relies on the test timing out in order to indicate failure so
- // let's add a dummy pass.
- ok(true, "Each test requires at least one pass, fail or todo so here is a pass.");
-}
-
-function whenChildCount(aEntry, aChildCount, aCallback) {
- if (aEntry.childCount == aChildCount)
- aCallback();
- else
- setTimeout(() => whenChildCount(aEntry, aChildCount, aCallback), 100);
-}
diff --git a/browser/components/sessionstore/test/browser_739531.js b/browser/components/sessionstore/test/browser_739531.js
deleted file mode 100644
index e5927caf6..000000000
--- a/browser/components/sessionstore/test/browser_739531.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// This test ensures that attempts made to save/restore ("duplicate") pages
-// using designmode AND make changes to document structure (remove body)
-// don't result in uncaught errors and a broken browser state.
-
-function test() {
- waitForExplicitFinish();
-
- let testURL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_739531_sample.html";
-
- let loadCount = 0;
- let tab = gBrowser.addTab(testURL);
- tab.linkedBrowser.addEventListener("load", function onLoad(aEvent) {
- // make sure both the page and the frame are loaded
- if (++loadCount < 2)
- return;
- tab.linkedBrowser.removeEventListener("load", onLoad, true);
-
- // executeSoon to allow the JS to execute on the page
- executeSoon(function() {
-
- let tab2;
- let caughtError = false;
- try {
- tab2 = ss.duplicateTab(window, tab);
- }
- catch (e) {
- caughtError = true;
- info(e);
- }
-
- is(gBrowser.tabs.length, 3, "there should be 3 tabs")
-
- ok(!caughtError, "duplicateTab didn't throw");
-
- // if the test fails, we don't want to try to close a tab that doesn't exist
- if (tab2)
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-
- finish();
- });
- }, true);
-}
diff --git a/browser/components/sessionstore/test/browser_739531_sample.html b/browser/components/sessionstore/test/browser_739531_sample.html
deleted file mode 100644
index ad317ab0c..000000000
--- a/browser/components/sessionstore/test/browser_739531_sample.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!-- originally a crash test for bug 713417
- https://bug713417.bugzilla.mozilla.org/attachment.cgi?id=584240 -->
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<script>
-
-function boom()
-{
- var w = document.getElementById("f").contentWindow;
- var d = w.document;
- d.designMode = 'on';
- var r = d.documentElement;
- d.removeChild(r);
- document.adoptNode(r);
-}
-
-</script>
-</head>
-<body onload="boom();">
-<iframe src="data:text/html;charset=utf-8,1" id="f"></iframe>
-</body>
-</html>
-
diff --git a/browser/components/sessionstore/test/browser_739805.js b/browser/components/sessionstore/test/browser_739805.js
deleted file mode 100644
index f00871661..000000000
--- a/browser/components/sessionstore/test/browser_739805.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var url = "data:text/html;charset=utf-8,<input%20id='foo'>";
-var tabState = {
- entries: [{ url }], formdata: { id: { "foo": "bar" }, url }
-};
-
-function test() {
- waitForExplicitFinish();
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- registerCleanupFunction(function () {
- if (gBrowser.tabs.length > 1)
- gBrowser.removeTab(gBrowser.tabs[1]);
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
- });
-
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
-
- promiseBrowserLoaded(browser).then(() => {
- isnot(gBrowser.selectedTab, tab, "newly created tab is not selected");
-
- ss.setTabState(tab, JSON.stringify(tabState));
- is(browser.__SS_restoreState, TAB_STATE_NEEDS_RESTORE, "tab needs restoring");
-
- let {formdata} = JSON.parse(ss.getTabState(tab));
- is(formdata && formdata.id["foo"], "bar", "tab state's formdata is valid");
-
- promiseTabRestored(tab).then(() => {
- ContentTask.spawn(browser, null, function() {
- let input = content.document.getElementById("foo");
- is(input.value, "bar", "formdata has been restored correctly");
- }).then(() => { finish(); });
- });
-
- // Restore the tab by selecting it.
- gBrowser.selectedTab = tab;
- });
-}
diff --git a/browser/components/sessionstore/test/browser_819510_perwindowpb.js b/browser/components/sessionstore/test/browser_819510_perwindowpb.js
deleted file mode 100644
index 21f916f0d..000000000
--- a/browser/components/sessionstore/test/browser_819510_perwindowpb.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test opening default mochitest-normal-private-normal-private windows
-// (saving the state with last window being private)
-
-requestLongerTimeout(2);
-
-add_task(function* test_1() {
- let win = yield promiseNewWindowLoaded();
- win.gBrowser.addTab("http://www.example.com/1");
-
- win = yield promiseNewWindowLoaded({private: true});
- win.gBrowser.addTab("http://www.example.com/2");
-
- win = yield promiseNewWindowLoaded();
- win.gBrowser.addTab("http://www.example.com/3");
-
- win = yield promiseNewWindowLoaded({private: true});
- win.gBrowser.addTab("http://www.example.com/4");
-
- let curState = JSON.parse(ss.getBrowserState());
- is(curState.windows.length, 5, "Browser has opened 5 windows");
- is(curState.windows[2].isPrivate, true, "Window is private");
- is(curState.windows[4].isPrivate, true, "Last window is private");
- is(curState.selectedWindow, 5, "Last window opened is the one selected");
-
- let state = JSON.parse(yield promiseRecoveryFileContents());
-
- is(state.windows.length, 3,
- "sessionstore state: 3 windows in data being written to disk");
- is(state.selectedWindow, 3,
- "Selected window is updated to match one of the saved windows");
- ok(state.windows.every(win => !win.isPrivate),
- "Saved windows are not private");
- is(state._closedWindows.length, 0,
- "sessionstore state: no closed windows in data being written to disk");
-
- // Cleanup.
- yield promiseAllButPrimaryWindowClosed();
- forgetClosedWindows();
-});
-
-// Test opening default mochitest window + 2 private windows
-add_task(function* test_2() {
- let win = yield promiseNewWindowLoaded({private: true});
- win.gBrowser.addTab("http://www.example.com/1");
-
- win = yield promiseNewWindowLoaded({private: true});
- win.gBrowser.addTab("http://www.example.com/2");
-
- let curState = JSON.parse(ss.getBrowserState());
- is(curState.windows.length, 3, "Browser has opened 3 windows");
- is(curState.windows[1].isPrivate, true, "Window 1 is private");
- is(curState.windows[2].isPrivate, true, "Window 2 is private");
- is(curState.selectedWindow, 3, "Last window opened is the one selected");
-
- let state = JSON.parse(yield promiseRecoveryFileContents());
-
- is(state.windows.length, 1,
- "sessionstore state: 1 windows in data being written to disk");
- is(state.selectedWindow, 1,
- "Selected window is updated to match one of the saved windows");
- is(state._closedWindows.length, 0,
- "sessionstore state: no closed windows in data being written to disk");
-
- // Cleanup.
- yield promiseAllButPrimaryWindowClosed();
- forgetClosedWindows();
-});
-
-// Test opening default-normal-private-normal windows and closing a normal window
-add_task(function* test_3() {
- let normalWindow = yield promiseNewWindowLoaded();
- yield promiseTabLoad(normalWindow, "http://www.example.com/");
-
- let win = yield promiseNewWindowLoaded({private: true});
- yield promiseTabLoad(win, "http://www.example.com/");
-
- win = yield promiseNewWindowLoaded();
- yield promiseTabLoad(win, "http://www.example.com/");
-
- let curState = JSON.parse(ss.getBrowserState());
- is(curState.windows.length, 4, "Browser has opened 4 windows");
- is(curState.windows[2].isPrivate, true, "Window 2 is private");
- is(curState.selectedWindow, 4, "Last window opened is the one selected");
-
- yield BrowserTestUtils.closeWindow(normalWindow);
-
- // Pin and unpin a tab before checking the written state so that
- // the list of restoring windows gets cleared. Otherwise the
- // window we just closed would be marked as not closed.
- let tab = win.gBrowser.tabs[0];
- win.gBrowser.pinTab(tab);
- win.gBrowser.unpinTab(tab);
-
- let state = JSON.parse(yield promiseRecoveryFileContents());
-
- is(state.windows.length, 2,
- "sessionstore state: 2 windows in data being written to disk");
- is(state.selectedWindow, 2,
- "Selected window is updated to match one of the saved windows");
- ok(state.windows.every(win => !win.isPrivate),
- "Saved windows are not private");
- is(state._closedWindows.length, 1,
- "sessionstore state: 1 closed window in data being written to disk");
- ok(state._closedWindows.every(win => !win.isPrivate),
- "Closed windows are not private");
-
- // Cleanup.
- yield promiseAllButPrimaryWindowClosed();
- forgetClosedWindows();
-});
-
-function* promiseTabLoad(win, url) {
- let browser = win.gBrowser.selectedBrowser;
- browser.loadURI(url);
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-}
diff --git a/browser/components/sessionstore/test/browser_911547.js b/browser/components/sessionstore/test/browser_911547.js
deleted file mode 100644
index 58b2e9ef1..000000000
--- a/browser/components/sessionstore/test/browser_911547.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// This tests that session restore component does restore the right content
-// security policy with the document.
-// The policy being tested disallows inline scripts
-
-add_task(function* test() {
- // create a tab that has a CSP
- let testURL = "http://mochi.test:8888/browser/browser/components/sessionstore/test/browser_911547_sample.html";
- let tab = gBrowser.selectedTab = gBrowser.addTab(testURL);
- gBrowser.selectedTab = tab;
-
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // this is a baseline to ensure CSP is active
- // attempt to inject and run a script via inline (pre-restore, allowed)
- yield injectInlineScript(browser, `document.getElementById("test_id").value = "fail";`);
-
- let loadedPromise = promiseBrowserLoaded(browser);
- yield ContentTask.spawn(browser, null, function() {
- is(content.document.getElementById("test_id").value, "ok",
- "CSP should block the inline script that modifies test_id");
-
- // attempt to click a link to a data: URI (will inherit the CSP of the
- // origin document) and navigate to the data URI in the link.
- content.document.getElementById("test_data_link").click();
- });
-
- yield loadedPromise;
-
- yield ContentTask.spawn(browser, null, function() {
- is(content.document.getElementById("test_id2").value, "ok",
- "CSP should block the script loaded by the clicked data URI");
- });
-
- // close the tab
- yield promiseRemoveTab(tab);
-
- // open new tab and recover the state
- tab = ss.undoCloseTab(window, 0);
- yield promiseTabRestored(tab);
- browser = tab.linkedBrowser;
-
- yield ContentTask.spawn(browser, null, function() {
- is(content.document.getElementById("test_id2").value, "ok",
- "CSP should block the script loaded by the clicked data URI after restore");
- });
-
- // clean up
- gBrowser.removeTab(tab);
-});
-
-// injects an inline script element (with a text body)
-function injectInlineScript(browser, scriptText) {
- return ContentTask.spawn(browser, scriptText, function(text) {
- let scriptElt = content.document.createElement("script");
- scriptElt.type = "text/javascript";
- scriptElt.text = text;
- content.document.body.appendChild(scriptElt);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_911547_sample.html b/browser/components/sessionstore/test/browser_911547_sample.html
deleted file mode 100644
index ccc201159..000000000
--- a/browser/components/sessionstore/test/browser_911547_sample.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>Test 911547</title>
- </head>
-<body>
-
- <!--
- this element gets modified by an injected script;
- that script should be blocked by CSP.
- Inline scripts can modify it, but not data uris.
- -->
- <input type="text" id="test_id" value="ok">
-
- <a id="test_data_link" href="data:text/html;charset=utf-8,<input type='text' id='test_id2' value='ok'/> <script>document.getElementById('test_id2').value = 'fail';</script>">Test Link</a>
-
-</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_911547_sample.html^headers^ b/browser/components/sessionstore/test/browser_911547_sample.html^headers^
deleted file mode 100644
index 4623dec30..000000000
--- a/browser/components/sessionstore/test/browser_911547_sample.html^headers^
+++ /dev/null
@@ -1 +0,0 @@
-Content-Security-Policy: script-src 'self'
diff --git a/browser/components/sessionstore/test/browser_aboutPrivateBrowsing.js b/browser/components/sessionstore/test/browser_aboutPrivateBrowsing.js
deleted file mode 100644
index 3050bd4c1..000000000
--- a/browser/components/sessionstore/test/browser_aboutPrivateBrowsing.js
+++ /dev/null
@@ -1,21 +0,0 @@
-"use strict";
-
-// Tests that an about:privatebrowsing tab with no history will not
-// be saved into session store and thus, it will not show up in
-// Recently Closed Tabs.
-
-add_task(function* () {
- let tab = gBrowser.addTab("about:privatebrowsing");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- is(gBrowser.browsers[1].currentURI.spec, "about:privatebrowsing",
- "we will be removing an about:privatebrowsing tab");
-
- let r = `rand-${Math.random()}`;
- ss.setTabValue(tab, "foobar", r);
-
- yield promiseRemoveTab(tab);
- let closedTabData = ss.getClosedTabData(window);
- ok(!closedTabData.includes(r), "tab not stored in _closedTabs");
-});
diff --git a/browser/components/sessionstore/test/browser_aboutSessionRestore.js b/browser/components/sessionstore/test/browser_aboutSessionRestore.js
deleted file mode 100644
index 8ab91e4df..000000000
--- a/browser/components/sessionstore/test/browser_aboutSessionRestore.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const CRASH_URL = "about:mozilla";
-const CRASH_FAVICON = "chrome://branding/content/icon32.png";
-const CRASH_SHENTRY = {url: CRASH_URL};
-const CRASH_TAB = {entries: [CRASH_SHENTRY], image: CRASH_FAVICON};
-const CRASH_STATE = {windows: [{tabs: [CRASH_TAB]}]};
-
-const TAB_URL = "about:sessionrestore";
-const TAB_FORMDATA = {url: TAB_URL, id: {sessionData: CRASH_STATE}};
-const TAB_SHENTRY = {url: TAB_URL};
-const TAB_STATE = {entries: [TAB_SHENTRY], formdata: TAB_FORMDATA};
-
-const FRAME_SCRIPT = "data:," +
- "content.document.getElementById('errorTryAgain').click()";
-
-add_task(function* () {
- // Prepare a blank tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Fake a post-crash tab.
- ss.setTabState(tab, JSON.stringify(TAB_STATE));
- yield promiseTabRestored(tab);
-
- ok(gBrowser.tabs.length > 1, "we have more than one tab");
-
- let view = browser.contentDocument.getElementById("tabList").view;
- ok(view.isContainer(0), "first entry is the window");
- is(view.getCellProperties(1, { id: "title" }), "icon",
- "second entry is the tab and has a favicon");
-
- browser.messageManager.loadFrameScript(FRAME_SCRIPT, true);
-
- // Wait until the new window was restored.
- let win = yield waitForNewWindow();
- yield BrowserTestUtils.closeWindow(win);
-
- let [{tabs: [{entries: [{url}]}]}] = JSON.parse(ss.getClosedWindowData());
- is(url, CRASH_URL, "session was restored correctly");
- ss.forgetClosedWindow(0);
-});
-
-function waitForNewWindow() {
- return new Promise(resolve => {
- Services.obs.addObserver(function observe(win, topic) {
- Services.obs.removeObserver(observe, topic);
- resolve(win);
- }, "browser-delayed-startup-finished", false);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_async_duplicate_tab.js b/browser/components/sessionstore/test/browser_async_duplicate_tab.js
deleted file mode 100644
index 8696a284f..000000000
--- a/browser/components/sessionstore/test/browser_async_duplicate_tab.js
+++ /dev/null
@@ -1,78 +0,0 @@
-"use strict";
-
-const URL = "data:text/html;charset=utf-8,<a href=%23>clickme</a>";
-
-add_task(function* test_duplicate() {
- // Create new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to empty any queued update messages.
- yield TabStateFlusher.flush(browser);
-
- // Click the link to navigate, this will add second shistory entry.
- yield ContentTask.spawn(browser, null, function* () {
- return new Promise(resolve => {
- addEventListener("hashchange", function onHashChange() {
- removeEventListener("hashchange", onHashChange);
- resolve();
- });
-
- // Click the link.
- content.document.querySelector("a").click();
- });
- });
-
- // Duplicate the tab.
- let tab2 = ss.duplicateTab(window, tab);
-
- // Wait until the tab has fully restored.
- yield promiseTabRestored(tab2);
- yield TabStateFlusher.flush(tab2.linkedBrowser);
-
- // There should be two history entries now.
- let {entries} = JSON.parse(ss.getTabState(tab2));
- is(entries.length, 2, "there are two shistory entries");
-
- // Cleanup.
- yield promiseRemoveTab(tab2);
- yield promiseRemoveTab(tab);
-});
-
-add_task(function* test_duplicate_remove() {
- // Create new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to empty any queued update messages.
- yield TabStateFlusher.flush(browser);
-
- // Click the link to navigate, this will add second shistory entry.
- yield ContentTask.spawn(browser, null, function* () {
- return new Promise(resolve => {
- addEventListener("hashchange", function onHashChange() {
- removeEventListener("hashchange", onHashChange);
- resolve();
- });
-
- // Click the link.
- content.document.querySelector("a").click();
- });
- });
-
- // Duplicate the tab.
- let tab2 = ss.duplicateTab(window, tab);
-
- // Before the duplication finished, remove the tab.
- yield Promise.all([promiseRemoveTab(tab), promiseTabRestored(tab2)]);
- yield TabStateFlusher.flush(tab2.linkedBrowser);
-
- // There should be two history entries now.
- let {entries} = JSON.parse(ss.getTabState(tab2));
- is(entries.length, 2, "there are two shistory entries");
-
- // Cleanup.
- yield promiseRemoveTab(tab2);
-});
diff --git a/browser/components/sessionstore/test/browser_async_flushes.js b/browser/components/sessionstore/test/browser_async_flushes.js
deleted file mode 100644
index a4cbbfbc7..000000000
--- a/browser/components/sessionstore/test/browser_async_flushes.js
+++ /dev/null
@@ -1,113 +0,0 @@
-"use strict";
-
-const URL = "data:text/html;charset=utf-8,<a href=%23>clickme</a>";
-
-add_task(function* test_flush() {
- // Create new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to empty any queued update messages.
- yield TabStateFlusher.flush(browser);
-
- // There should be one history entry.
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is a single history entry");
-
- // Click the link to navigate, this will add second shistory entry.
- yield ContentTask.spawn(browser, null, function* () {
- return new Promise(resolve => {
- addEventListener("hashchange", function onHashChange() {
- removeEventListener("hashchange", onHashChange);
- resolve();
- });
-
- // Click the link.
- content.document.querySelector("a").click();
- });
- });
-
- // Flush to empty any queued update messages.
- yield TabStateFlusher.flush(browser);
-
- // There should be two history entries now.
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 2, "there are two shistory entries");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_crash() {
- // Create new tab.
- let tab = gBrowser.addTab(URL);
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to empty any queued update messages.
- yield TabStateFlusher.flush(browser);
-
- // There should be one history entry.
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is a single history entry");
-
- // Click the link to navigate.
- yield ContentTask.spawn(browser, null, function* () {
- return new Promise(resolve => {
- addEventListener("hashchange", function onHashChange() {
- removeEventListener("hashchange", onHashChange);
- resolve();
- });
-
- // Click the link.
- content.document.querySelector("a").click();
- });
- });
-
- // Crash the browser and flush. Both messages are async and will be sent to
- // the content process. The "crash" message makes it first so that we don't
- // get a chance to process the flush. The TabStateFlusher however should be
- // notified so that the flush still completes.
- let promise1 = BrowserTestUtils.crashBrowser(browser);
- let promise2 = TabStateFlusher.flush(browser);
- yield Promise.all([promise1, promise2]);
-
- // The pending update should be lost.
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 1, "still only one history entry");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_remove() {
- // Create new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to empty any queued update messages.
- yield TabStateFlusher.flush(browser);
-
- // There should be one history entry.
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is a single history entry");
-
- // Click the link to navigate.
- yield ContentTask.spawn(browser, null, function* () {
- return new Promise(resolve => {
- addEventListener("hashchange", function onHashChange() {
- removeEventListener("hashchange", onHashChange);
- resolve();
- });
-
- // Click the link.
- content.document.querySelector("a").click();
- });
- });
-
- // Request a flush and remove the tab. The flush should still complete.
- yield Promise.all([TabStateFlusher.flush(browser), promiseRemoveTab(tab)]);
-})
diff --git a/browser/components/sessionstore/test/browser_async_remove_tab.js b/browser/components/sessionstore/test/browser_async_remove_tab.js
deleted file mode 100644
index 20f3463d0..000000000
--- a/browser/components/sessionstore/test/browser_async_remove_tab.js
+++ /dev/null
@@ -1,242 +0,0 @@
-"use strict";
-
-function* createTabWithRandomValue(url) {
- let tab = gBrowser.addTab(url);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Set a random value.
- let r = `rand-${Math.random()}`;
- ss.setTabValue(tab, "foobar", r);
-
- // Flush to ensure there are no scheduled messages.
- yield TabStateFlusher.flush(browser);
-
- return {tab, r};
-}
-
-function isValueInClosedData(rval) {
- return ss.getClosedTabData(window).includes(rval);
-}
-
-function restoreClosedTabWithValue(rval) {
- let closedTabData = JSON.parse(ss.getClosedTabData(window));
- let index = closedTabData.findIndex(function (data) {
- return (data.state.extData && data.state.extData.foobar) == rval;
- });
-
- if (index == -1) {
- throw new Error("no closed tab found for given rval");
- }
-
- return ss.undoCloseTab(window, index);
-}
-
-function promiseNewLocationAndHistoryEntryReplaced(browser, snippet) {
- return ContentTask.spawn(browser, snippet, function* (snippet) {
- let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
- let shistory = webNavigation.sessionHistory;
-
- // Evaluate the snippet that the changes the location.
- eval(snippet);
-
- return new Promise(resolve => {
- let listener = {
- OnHistoryReplaceEntry() {
- shistory.removeSHistoryListener(this);
- resolve();
- },
-
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsISHistoryListener,
- Ci.nsISupportsWeakReference
- ])
- };
-
- shistory.addSHistoryListener(listener);
-
- /* Keep the weak shistory listener alive. */
- addEventListener("unload", function () {
- try {
- shistory.removeSHistoryListener(listener);
- } catch (e) { /* Will most likely fail. */ }
- });
- });
- });
-}
-
-function promiseHistoryEntryReplacedNonRemote(browser) {
- let {listeners} = promiseHistoryEntryReplacedNonRemote;
-
- return new Promise(resolve => {
- let shistory = browser.webNavigation.sessionHistory;
-
- let listener = {
- OnHistoryReplaceEntry() {
- shistory.removeSHistoryListener(this);
- resolve();
- },
-
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsISHistoryListener,
- Ci.nsISupportsWeakReference
- ])
- };
-
- shistory.addSHistoryListener(listener);
- listeners.set(browser, listener);
- });
-}
-promiseHistoryEntryReplacedNonRemote.listeners = new WeakMap();
-
-add_task(function* dont_save_empty_tabs() {
- let {tab, r} = yield createTabWithRandomValue("about:blank");
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // No tab state worth saving.
- ok(!isValueInClosedData(r), "closed tab not saved");
- yield promise;
-
- // Still no tab state worth saving.
- ok(!isValueInClosedData(r), "closed tab not saved");
-});
-
-add_task(function* save_worthy_tabs_remote() {
- let {tab, r} = yield createTabWithRandomValue("https://example.com/");
- ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote");
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // Tab state deemed worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
- yield promise;
-
- // Tab state still deemed worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
-});
-
-add_task(function* save_worthy_tabs_nonremote() {
- let {tab, r} = yield createTabWithRandomValue("about:robots");
- ok(!tab.linkedBrowser.isRemoteBrowser, "browser is not remote");
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // Tab state deemed worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
- yield promise;
-
- // Tab state still deemed worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
-});
-
-add_task(function* save_worthy_tabs_remote_final() {
- let {tab, r} = yield createTabWithRandomValue("about:blank");
- let browser = tab.linkedBrowser;
- ok(browser.isRemoteBrowser, "browser is remote");
-
- // Replace about:blank with a new remote page.
- let snippet = 'webNavigation.loadURI("https://example.com/", null, null, null, null)';
- yield promiseNewLocationAndHistoryEntryReplaced(browser, snippet);
-
- // Remotness shouldn't have changed.
- ok(browser.isRemoteBrowser, "browser is still remote");
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // No tab state worth saving (that we know about yet).
- ok(!isValueInClosedData(r), "closed tab not saved");
- yield promise;
-
- // Turns out there is a tab state worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
-});
-
-add_task(function* save_worthy_tabs_nonremote_final() {
- let {tab, r} = yield createTabWithRandomValue("about:blank");
- let browser = tab.linkedBrowser;
- ok(browser.isRemoteBrowser, "browser is remote");
-
- // Replace about:blank with a non-remote entry.
- yield BrowserTestUtils.loadURI(browser, "about:robots");
- ok(!browser.isRemoteBrowser, "browser is not remote anymore");
-
- // Wait until the new entry replaces about:blank.
- yield promiseHistoryEntryReplacedNonRemote(browser);
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // No tab state worth saving (that we know about yet).
- ok(!isValueInClosedData(r), "closed tab not saved");
- yield promise;
-
- // Turns out there is a tab state worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
-});
-
-add_task(function* dont_save_empty_tabs_final() {
- let {tab, r} = yield createTabWithRandomValue("https://example.com/");
- let browser = tab.linkedBrowser;
-
- // Replace the current page with an about:blank entry.
- let snippet = 'content.location.replace("about:blank")';
- yield promiseNewLocationAndHistoryEntryReplaced(browser, snippet);
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // Tab state deemed worth saving (yet).
- ok(isValueInClosedData(r), "closed tab saved");
- yield promise;
-
- // Turns out we don't want to save the tab state.
- ok(!isValueInClosedData(r), "closed tab not saved");
-});
-
-add_task(function* undo_worthy_tabs() {
- let {tab, r} = yield createTabWithRandomValue("https://example.com/");
- ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote");
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // Tab state deemed worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
-
- // Restore the closed tab before receiving its final message.
- tab = restoreClosedTabWithValue(r);
-
- // Wait for the final update message.
- yield promise;
-
- // Check we didn't add the tab back to the closed list.
- ok(!isValueInClosedData(r), "tab no longer closed");
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
-
-add_task(function* forget_worthy_tabs_remote() {
- let {tab, r} = yield createTabWithRandomValue("https://example.com/");
- ok(tab.linkedBrowser.isRemoteBrowser, "browser is remote");
-
- // Remove the tab before the update arrives.
- let promise = promiseRemoveTab(tab);
-
- // Tab state deemed worth saving.
- ok(isValueInClosedData(r), "closed tab saved");
-
- // Forget the closed tab.
- ss.forgetClosedTab(window, 0);
-
- // Wait for the final update message.
- yield promise;
-
- // Check we didn't add the tab back to the closed list.
- ok(!isValueInClosedData(r), "we forgot about the tab");
-});
diff --git a/browser/components/sessionstore/test/browser_async_window_flushing.js b/browser/components/sessionstore/test/browser_async_window_flushing.js
deleted file mode 100644
index 418c055c2..000000000
--- a/browser/components/sessionstore/test/browser_async_window_flushing.js
+++ /dev/null
@@ -1,178 +0,0 @@
-"use strict";
-
-const PAGE = "http://example.com/";
-
-/**
- * Tests that if we initially discard a window as not interesting
- * to save in the closed windows array, that we revisit that decision
- * after a window flush has completed.
- */
-add_task(function* test_add_interesting_window() {
- // We want to suppress all non-final updates from the browser tabs
- // so as to eliminate any racy-ness with this test.
- yield pushPrefs(["browser.sessionstore.debug.no_auto_updates", true]);
-
- // Depending on previous tests, we might already have some closed
- // windows stored. We'll use its length to determine whether or not
- // the window was added or not.
- let initialClosedWindows = ss.getClosedWindowCount();
-
- // Make sure we can actually store another closed window
- yield pushPrefs(["browser.sessionstore.max_windows_undo",
- initialClosedWindows + 1]);
-
- // Create a new browser window. Since the default window will start
- // at about:blank, SessionStore should find this tab (and therefore the
- // whole window) uninteresting, and should not initially put it into
- // the closed windows array.
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
-
- let browser = newWin.gBrowser.selectedBrowser;
-
- // Send a message that will cause the content to change its location
- // to someplace more interesting. We've disabled auto updates from
- // the browser, so the parent won't know about this
- yield ContentTask.spawn(browser, PAGE, function*(PAGE) {
- content.location = PAGE;
- });
-
- yield promiseContentMessage(browser, "ss-test:OnHistoryReplaceEntry");
-
- // Clear out the userTypedValue so that the new window looks like
- // it's really not worth restoring.
- browser.userTypedValue = null;
-
- // Once the domWindowClosed Promise resolves, the window should
- // have closed, and SessionStore's onClose handler should have just
- // run.
- let domWindowClosed = BrowserTestUtils.domWindowClosed(newWin);
-
- // Once this windowClosed Promise resolves, we should have finished
- // the flush and revisited our decision to put this window into
- // the closed windows array.
- let windowClosed = BrowserTestUtils.windowClosed(newWin);
-
- // Ok, let's close the window.
- newWin.close();
-
- yield domWindowClosed;
- // OnClose has just finished running.
- let currentClosedWindows = ss.getClosedWindowCount();
- is(currentClosedWindows, initialClosedWindows,
- "We should not have added the window to the closed windows array");
-
- yield windowClosed;
- // The window flush has finished
- currentClosedWindows = ss.getClosedWindowCount();
- is(currentClosedWindows,
- initialClosedWindows + 1,
- "We should have added the window to the closed windows array");
-});
-
-/**
- * Tests that if we initially store a closed window as interesting
- * to save in the closed windows array, that we revisit that decision
- * after a window flush has completed, and stop storing a window that
- * we've deemed no longer interesting.
- */
-add_task(function* test_remove_uninteresting_window() {
- // We want to suppress all non-final updates from the browser tabs
- // so as to eliminate any racy-ness with this test.
- yield pushPrefs(["browser.sessionstore.debug.no_auto_updates", true]);
-
- // Depending on previous tests, we might already have some closed
- // windows stored. We'll use its length to determine whether or not
- // the window was added or not.
- let initialClosedWindows = ss.getClosedWindowCount();
-
- // Make sure we can actually store another closed window
- yield pushPrefs(["browser.sessionstore.max_windows_undo",
- initialClosedWindows + 1]);
-
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
-
- // Now browse the initial tab of that window to an interesting
- // site.
- let tab = newWin.gBrowser.selectedTab;
- let browser = tab.linkedBrowser;
- browser.loadURI(PAGE);
-
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
- yield TabStateFlusher.flush(browser);
-
- // Send a message that will cause the content to purge its
- // history entries and make itself seem uninteresting.
- yield ContentTask.spawn(browser, null, function*() {
- // Epic hackery to make this browser seem suddenly boring.
- Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
- docShell.setCurrentURI(BrowserUtils.makeURI("about:blank"));
-
- let {sessionHistory} = docShell.QueryInterface(Ci.nsIWebNavigation);
- sessionHistory.PurgeHistory(sessionHistory.count);
- });
-
- // Once the domWindowClosed Promise resolves, the window should
- // have closed, and SessionStore's onClose handler should have just
- // run.
- let domWindowClosed = BrowserTestUtils.domWindowClosed(newWin);
-
- // Once this windowClosed Promise resolves, we should have finished
- // the flush and revisited our decision to put this window into
- // the closed windows array.
- let windowClosed = BrowserTestUtils.windowClosed(newWin);
-
- // Ok, let's close the window.
- newWin.close();
-
- yield domWindowClosed;
- // OnClose has just finished running.
- let currentClosedWindows = ss.getClosedWindowCount();
- is(currentClosedWindows, initialClosedWindows + 1,
- "We should have added the window to the closed windows array");
-
- yield windowClosed;
- // The window flush has finished
- currentClosedWindows = ss.getClosedWindowCount();
- is(currentClosedWindows,
- initialClosedWindows,
- "We should have removed the window from the closed windows array");
-});
-
-/**
- * Tests that when we close a window, it is immediately removed from the
- * _windows array.
- */
-add_task(function* test_synchronously_remove_window_state() {
- // Depending on previous tests, we might already have some closed
- // windows stored. We'll use its length to determine whether or not
- // the window was added or not.
- let state = JSON.parse(ss.getBrowserState());
- ok(state, "Make sure we can get the state");
- let initialWindows = state.windows.length;
-
- // Open a new window and send the first tab somewhere
- // interesting.
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
- let browser = newWin.gBrowser.selectedBrowser;
- browser.loadURI(PAGE);
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
- yield TabStateFlusher.flush(browser);
-
- state = JSON.parse(ss.getBrowserState());
- is(state.windows.length, initialWindows + 1,
- "The new window to be in the state");
-
- // Now close the window, and make sure that the window was removed
- // from the windows list from the SessionState. We're specifically
- // testing the case where the window is _not_ removed in between
- // the close-initiated flush request and the flush response.
- let windowClosed = BrowserTestUtils.windowClosed(newWin);
- newWin.close();
-
- state = JSON.parse(ss.getBrowserState());
- is(state.windows.length, initialWindows,
- "The new window should have been removed from the state");
-
- // Wait for our window to go away
- yield windowClosed;
-});
diff --git a/browser/components/sessionstore/test/browser_attributes.js b/browser/components/sessionstore/test/browser_attributes.js
deleted file mode 100644
index 40c7b4e02..000000000
--- a/browser/components/sessionstore/test/browser_attributes.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * This test makes sure that we correctly preserve tab attributes when storing
- * and restoring tabs. It also ensures that we skip special attributes like
- * 'image', 'muted' and 'pending' that need to be handled differently or internally.
- */
-
-const PREF = "browser.sessionstore.restore_on_demand";
-
-add_task(function* test() {
- Services.prefs.setBoolPref(PREF, true)
- registerCleanupFunction(() => Services.prefs.clearUserPref(PREF));
-
- // Add a new tab with a nice icon.
- let tab = gBrowser.addTab("about:robots");
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- // Check that the tab has 'image' and 'iconLoadingPrincipal' attributes.
- ok(tab.hasAttribute("image"), "tab.image exists");
- ok(tab.hasAttribute("iconLoadingPrincipal"), "tab.iconLoadingPrincipal exists");
-
- tab.toggleMuteAudio();
- // Check that the tab has a 'muted' attribute.
- ok(tab.hasAttribute("muted"), "tab.muted exists");
-
- // Make sure we do not persist 'image' or 'muted' attributes.
- ss.persistTabAttribute("image");
- ss.persistTabAttribute("muted");
- ss.persistTabAttribute("iconLoadingPrincipal");
- let {attributes} = JSON.parse(ss.getTabState(tab));
- ok(!("image" in attributes), "'image' attribute not saved");
- ok(!("iconLoadingPrincipal" in attributes), "'iconLoadingPrincipal' attribute not saved");
- ok(!("muted" in attributes), "'muted' attribute not saved");
- ok(!("custom" in attributes), "'custom' attribute not saved");
-
- // Test persisting a custom attribute.
- tab.setAttribute("custom", "foobar");
- ss.persistTabAttribute("custom");
-
- ({attributes} = JSON.parse(ss.getTabState(tab)));
- is(attributes.custom, "foobar", "'custom' attribute is correct");
-
- // Make sure we're backwards compatible and restore old 'image' attributes.
- let state = {
- entries: [{url: "about:mozilla"}],
- attributes: {custom: "foobaz"},
- image: gBrowser.getIcon(tab)
- };
-
- // Prepare a pending tab waiting to be restored.
- let promise = promiseTabRestoring(tab);
- ss.setTabState(tab, JSON.stringify(state));
- yield promise;
-
- ok(tab.hasAttribute("pending"), "tab is pending");
- is(gBrowser.getIcon(tab), state.image, "tab has correct icon");
- ok(!state.attributes.image, "'image' attribute not saved");
-
- // Let the pending tab load.
- gBrowser.selectedTab = tab;
- yield promiseTabRestored(tab);
-
- // Ensure no 'image' or 'pending' attributes are stored.
- ({attributes} = JSON.parse(ss.getTabState(tab)));
- ok(!("image" in attributes), "'image' attribute not saved");
- ok(!("pending" in attributes), "'pending' attribute not saved");
- is(attributes.custom, "foobaz", "'custom' attribute is correct");
-
- // Clean up.
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_background_tab_crash.js b/browser/components/sessionstore/test/browser_background_tab_crash.js
deleted file mode 100644
index e804b177e..000000000
--- a/browser/components/sessionstore/test/browser_background_tab_crash.js
+++ /dev/null
@@ -1,221 +0,0 @@
-"use strict";
-
-/**
- * These tests the behaviour of the browser when background tabs crash,
- * while the foreground tab remains.
- *
- * The current behavioural rule is this: if only background tabs crash,
- * then only the first tab shown of that group should show the tab crash
- * page, and subsequent ones should restore on demand.
- */
-
-/**
- * Makes the current browser tab non-remote, and then sets up two remote
- * background tabs, ensuring that both belong to the same content process.
- * Callers should pass in a testing function that will execute (and possibly
- * yield Promises) taking the created background tabs as arguments. Once
- * the testing function completes, this function will take care of closing
- * the opened tabs.
- *
- * @param testFn (function)
- * A Promise-generating function that will be called once the tabs
- * are opened and ready.
- * @return Promise
- * Resolves once the testing function completes and the opened tabs
- * have been completely closed.
- */
-function* setupBackgroundTabs(testFn) {
- const REMOTE_PAGE = "http://www.example.com";
- const NON_REMOTE_PAGE = "about:robots";
-
- // Browse the initial tab to a non-remote page, which we'll have in the
- // foreground.
- let initialTab = gBrowser.selectedTab;
- let initialBrowser = initialTab.linkedBrowser;
- initialBrowser.loadURI(NON_REMOTE_PAGE);
- yield BrowserTestUtils.browserLoaded(initialBrowser);
-
- // Open some tabs that should be running in the content process.
- let tab1 =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, REMOTE_PAGE);
- let remoteBrowser1 = tab1.linkedBrowser;
- yield TabStateFlusher.flush(remoteBrowser1);
-
- let tab2 =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, REMOTE_PAGE);
- let remoteBrowser2 = tab2.linkedBrowser;
- yield TabStateFlusher.flush(remoteBrowser2);
-
- // Quick sanity check - the two browsers should be remote and share the
- // same childID, or else this test is not going to work.
- Assert.ok(remoteBrowser1.isRemoteBrowser,
- "Browser should be remote in order to crash.");
- Assert.ok(remoteBrowser2.isRemoteBrowser,
- "Browser should be remote in order to crash.");
- Assert.equal(remoteBrowser1.frameLoader.childID,
- remoteBrowser2.frameLoader.childID,
- "Both remote browsers should share the same content process.");
-
- // Now switch back to the non-remote browser...
- yield BrowserTestUtils.switchTab(gBrowser, initialTab);
-
- yield testFn([tab1, tab2]);
-
- yield BrowserTestUtils.removeTab(tab1);
- yield BrowserTestUtils.removeTab(tab2);
-}
-
-/**
- * Takes some set of background tabs that are assumed to all belong to
- * the same content process, and crashes them.
- *
- * @param tabs (Array(<xul:tab>))
- * The tabs to crash.
- * @return Promise
- * Resolves once the tabs have crashed and entered the pending
- * background state.
- */
-function* crashBackgroundTabs(tabs) {
- Assert.ok(tabs.length > 0, "Need to crash at least one tab.");
- for (let tab of tabs) {
- Assert.ok(tab.linkedBrowser.isRemoteBrowser, "tab is remote");
- }
-
- let remotenessChangePromises = tabs.map((t) => {
- return BrowserTestUtils.waitForEvent(t, "TabRemotenessChange");
- });
-
- let tabsRevived = tabs.map((t) => {
- return promiseTabRestoring(t);
- });
-
- yield BrowserTestUtils.crashBrowser(tabs[0].linkedBrowser, false);
- yield Promise.all(remotenessChangePromises);
- yield Promise.all(tabsRevived);
-
- // Both background tabs should now be in the pending restore
- // state.
- for (let tab of tabs) {
- Assert.ok(!tab.linkedBrowser.isRemoteBrowser, "tab is not remote");
- Assert.ok(!tab.linkedBrowser.hasAttribute("crashed"), "tab is not crashed");
- Assert.ok(tab.linkedBrowser.hasAttribute("pending"), "tab is pending");
- }
-}
-
-add_task(function* setup() {
- // We'll simplify by making sure we only ever one content process for this
- // test.
- yield SpecialPowers.pushPrefEnv({ set: [[ "dom.ipc.processCount", 1 ]] });
-
- // On debug builds, crashing tabs results in much thinking, which
- // slows down the test and results in intermittent test timeouts,
- // so we'll pump up the expected timeout for this test.
- requestLongerTimeout(5);
-});
-
-/**
- * Tests that if a content process crashes taking down only
- * background tabs, then the first of those tabs that the user
- * selects will show the tab crash page, but the rest will restore
- * on demand.
- */
-add_task(function* test_background_crash_simple() {
- yield setupBackgroundTabs(function*([tab1, tab2]) {
- // Let's crash one of those background tabs now...
- yield crashBackgroundTabs([tab1, tab2]);
-
- // Selecting the first tab should now send it to the tab crashed page.
- let tabCrashedPagePromise =
- BrowserTestUtils.waitForContentEvent(tab1.linkedBrowser,
- "AboutTabCrashedReady",
- false, null, true);
- yield BrowserTestUtils.switchTab(gBrowser, tab1);
- yield tabCrashedPagePromise;
-
- // Selecting the second tab should restore it.
- let tabRestored = promiseTabRestored(tab2);
- yield BrowserTestUtils.switchTab(gBrowser, tab2);
- yield tabRestored;
- });
-});
-
-/**
- * Tests that if a content process crashes taking down only
- * background tabs, and the user is configured to send backlogged
- * crash reports automatically, that the tab crashed page is not
- * shown.
- */
-add_task(function* test_background_crash_autosubmit_backlogged() {
- yield SpecialPowers.pushPrefEnv({
- set: [["browser.crashReports.unsubmittedCheck.autoSubmit2", true]],
- });
-
- yield setupBackgroundTabs(function*([tab1, tab2]) {
- // Let's crash one of those background tabs now...
- yield crashBackgroundTabs([tab1, tab2]);
-
- // Selecting the first tab should restore it.
- let tabRestored = promiseTabRestored(tab1);
- yield BrowserTestUtils.switchTab(gBrowser, tab1);
- yield tabRestored;
-
- // Selecting the second tab should restore it.
- tabRestored = promiseTabRestored(tab2);
- yield BrowserTestUtils.switchTab(gBrowser, tab2);
- yield tabRestored;
- });
-
- yield SpecialPowers.popPrefEnv();
-});
-
-/**
- * Tests that if there are two background tab crashes in a row, that
- * the two sets of background crashes don't interfere with one another.
- *
- * Specifically, if we start with two background tabs (1, 2) which crash,
- * and we visit 1, 1 should go to the tab crashed page. If we then have
- * two new background tabs (3, 4) crash, visiting 2 should still restore.
- * Visiting 4 should show us the tab crashed page, and then visiting 3
- * should restore.
- */
-add_task(function* test_background_crash_multiple() {
- let initialTab = gBrowser.selectedTab;
-
- yield setupBackgroundTabs(function*([tab1, tab2]) {
- // Let's crash one of those background tabs now...
- yield crashBackgroundTabs([tab1, tab2]);
-
- // Selecting the first tab should now send it to the tab crashed page.
- let tabCrashedPagePromise =
- BrowserTestUtils.waitForContentEvent(tab1.linkedBrowser,
- "AboutTabCrashedReady",
- false, null, true);
- yield BrowserTestUtils.switchTab(gBrowser, tab1);
- yield tabCrashedPagePromise;
-
- // Now switch back to the original non-remote tab...
- yield BrowserTestUtils.switchTab(gBrowser, initialTab);
-
- yield setupBackgroundTabs(function*([tab3, tab4]) {
- yield crashBackgroundTabs([tab3, tab4]);
-
- // Selecting the second tab should restore it.
- let tabRestored = promiseTabRestored(tab2);
- yield BrowserTestUtils.switchTab(gBrowser, tab2);
- yield tabRestored;
-
- // Selecting the fourth tab should now send it to the tab crashed page.
- let tabCrashedPagePromise =
- BrowserTestUtils.waitForContentEvent(tab4.linkedBrowser,
- "AboutTabCrashedReady",
- false, null, true);
- yield BrowserTestUtils.switchTab(gBrowser, tab4);
- yield tabCrashedPagePromise;
-
- // Selecting the third tab should restore it.
- tabRestored = promiseTabRestored(tab3);
- yield BrowserTestUtils.switchTab(gBrowser, tab3);
- yield tabRestored;
- });
- });
-});
diff --git a/browser/components/sessionstore/test/browser_backup_recovery.js b/browser/components/sessionstore/test/browser_backup_recovery.js
deleted file mode 100644
index 81f678856..000000000
--- a/browser/components/sessionstore/test/browser_backup_recovery.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// This tests are for a sessionstore.js atomic backup.
-// Each test will wait for a write to the Session Store
-// before executing.
-
-var OS = Cu.import("resource://gre/modules/osfile.jsm", {}).OS;
-var {File, Constants, Path} = OS;
-
-const PREF_SS_INTERVAL = "browser.sessionstore.interval";
-const Paths = SessionFile.Paths;
-
-// A text decoder.
-var gDecoder = new TextDecoder();
-// Global variables that contain sessionstore.js and sessionstore.bak data for
-// comparison between tests.
-var gSSData;
-var gSSBakData;
-
-function promiseRead(path) {
- return File.read(path, {encoding: "utf-8"});
-}
-
-add_task(function* init() {
- // Make sure that we are not racing with SessionSaver's time based
- // saves.
- Services.prefs.setIntPref(PREF_SS_INTERVAL, 10000000);
- registerCleanupFunction(() => Services.prefs.clearUserPref(PREF_SS_INTERVAL));
-});
-
-add_task(function* test_creation() {
- // Create dummy sessionstore backups
- let OLD_BACKUP = Path.join(Constants.Path.profileDir, "sessionstore.bak");
- let OLD_UPGRADE_BACKUP = Path.join(Constants.Path.profileDir, "sessionstore.bak-0000000");
-
- yield File.writeAtomic(OLD_BACKUP, "sessionstore.bak");
- yield File.writeAtomic(OLD_UPGRADE_BACKUP, "sessionstore upgrade backup");
-
- yield SessionFile.wipe();
- yield SessionFile.read(); // Reinitializes SessionFile
-
- // Ensure none of the sessionstore files and backups exists
- for (let k of Paths.loadOrder) {
- ok(!(yield File.exists(Paths[k])), "After wipe " + k + " sessionstore file doesn't exist");
- }
- ok(!(yield File.exists(OLD_BACKUP)), "After wipe, old backup doesn't exist");
- ok(!(yield File.exists(OLD_UPGRADE_BACKUP)), "After wipe, old upgrade backup doesn't exist");
-
- // Open a new tab, save session, ensure that the correct files exist.
- let URL_BASE = "http://example.com/?atomic_backup_test_creation=" + Math.random();
- let URL = URL_BASE + "?first_write";
- let tab = gBrowser.addTab(URL);
-
- info("Testing situation after a single write");
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- yield SessionSaver.run();
-
- ok((yield File.exists(Paths.recovery)), "After write, recovery sessionstore file exists again");
- ok(!(yield File.exists(Paths.recoveryBackup)), "After write, recoveryBackup sessionstore doesn't exist");
- ok((yield promiseRead(Paths.recovery)).indexOf(URL) != -1, "Recovery sessionstore file contains the required tab");
- ok(!(yield File.exists(Paths.clean)), "After first write, clean shutdown sessionstore doesn't exist, since we haven't shutdown yet");
-
- // Open a second tab, save session, ensure that the correct files exist.
- info("Testing situation after a second write");
- let URL2 = URL_BASE + "?second_write";
- tab.linkedBrowser.loadURI(URL2);
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- yield SessionSaver.run();
-
- ok((yield File.exists(Paths.recovery)), "After second write, recovery sessionstore file still exists");
- ok((yield promiseRead(Paths.recovery)).indexOf(URL2) != -1, "Recovery sessionstore file contains the latest url");
- ok((yield File.exists(Paths.recoveryBackup)), "After write, recoveryBackup sessionstore now exists");
- let backup = yield promiseRead(Paths.recoveryBackup);
- ok(backup.indexOf(URL2) == -1, "Recovery backup doesn't contain the latest url");
- ok(backup.indexOf(URL) != -1, "Recovery backup contains the original url");
- ok(!(yield File.exists(Paths.clean)), "After first write, clean shutdown sessinstore doesn't exist, since we haven't shutdown yet");
-
- info("Reinitialize, ensure that we haven't leaked sensitive files");
- yield SessionFile.read(); // Reinitializes SessionFile
- yield SessionSaver.run();
- ok(!(yield File.exists(Paths.clean)), "After second write, clean shutdown sessonstore doesn't exist, since we haven't shutdown yet");
- ok(!(yield File.exists(Paths.upgradeBackup)), "After second write, clean shutdwn sessionstore doesn't exist, since we haven't shutdown yet");
- ok(!(yield File.exists(Paths.nextUpgradeBackup)), "After second write, clean sutdown sessionstore doesn't exist, since we haven't shutdown yet");
-
- gBrowser.removeTab(tab);
- yield SessionFile.wipe();
-});
-
-var promiseSource = Task.async(function*(name) {
- let URL = "http://example.com/?atomic_backup_test_recovery=" + Math.random() + "&name=" + name;
- let tab = gBrowser.addTab(URL);
-
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- yield SessionSaver.run();
- gBrowser.removeTab(tab);
-
- let SOURCE = yield promiseRead(Paths.recovery);
- yield SessionFile.wipe();
- return SOURCE;
-});
-
-add_task(function* test_recovery() {
- // Remove all files.
- yield SessionFile.wipe();
- info("Attempting to recover from the recovery file");
-
- // Create Paths.recovery, ensure that we can recover from it.
- let SOURCE = yield promiseSource("Paths.recovery");
- yield File.makeDir(Paths.backups);
- yield File.writeAtomic(Paths.recovery, SOURCE);
- is((yield SessionFile.read()).source, SOURCE, "Recovered the correct source from the recovery file");
- yield SessionFile.wipe();
-
- info("Corrupting recovery file, attempting to recover from recovery backup");
- SOURCE = yield promiseSource("Paths.recoveryBackup");
- yield File.makeDir(Paths.backups);
- yield File.writeAtomic(Paths.recoveryBackup, SOURCE);
- yield File.writeAtomic(Paths.recovery, "<Invalid JSON>");
- is((yield SessionFile.read()).source, SOURCE, "Recovered the correct source from the recovery file");
- yield SessionFile.wipe();
-});
-
-add_task(function* test_recovery_inaccessible() {
- // Can't do chmod() on non-UNIX platforms, we need that for this test.
- if (AppConstants.platform != "macosx" && AppConstants.platform != "linux") {
- return;
- }
-
- info("Making recovery file inaccessible, attempting to recover from recovery backup");
- let SOURCE_RECOVERY = yield promiseSource("Paths.recovery");
- let SOURCE = yield promiseSource("Paths.recoveryBackup");
- yield File.makeDir(Paths.backups);
- yield File.writeAtomic(Paths.recoveryBackup, SOURCE);
-
- // Write a valid recovery file but make it inaccessible.
- yield File.writeAtomic(Paths.recovery, SOURCE_RECOVERY);
- yield File.setPermissions(Paths.recovery, { unixMode: 0 });
-
- is((yield SessionFile.read()).source, SOURCE, "Recovered the correct source from the recovery file");
- yield File.setPermissions(Paths.recovery, { unixMode: 0o644 });
-});
-
-add_task(function* test_clean() {
- yield SessionFile.wipe();
- let SOURCE = yield promiseSource("Paths.clean");
- yield File.writeAtomic(Paths.clean, SOURCE);
- yield SessionFile.read();
- yield SessionSaver.run();
- is((yield promiseRead(Paths.cleanBackup)), SOURCE, "After first read/write, clean shutdown file has been moved to cleanBackup");
-});
-
-
-/**
- * Tests loading of sessionstore when format version is known.
- */
-add_task(function* test_version() {
- info("Preparing sessionstore");
- let SOURCE = yield promiseSource("Paths.clean");
-
- // Check there's a format version number
- is(JSON.parse(SOURCE).version[0], "sessionrestore", "Found sessionstore format version");
-
- // Create Paths.clean file
- yield File.makeDir(Paths.backups);
- yield File.writeAtomic(Paths.clean, SOURCE);
-
- info("Attempting to recover from the clean file");
- // Ensure that we can recover from Paths.recovery
- is((yield SessionFile.read()).source, SOURCE, "Recovered the correct source from the clean file");
-});
-
-/**
- * Tests fallback to previous backups if format version is unknown.
- */
-add_task(function* test_version_fallback() {
- info("Preparing data, making sure that it has a version number");
- let SOURCE = yield promiseSource("Paths.clean");
- let BACKUP_SOURCE = yield promiseSource("Paths.cleanBackup");
-
- is(JSON.parse(SOURCE).version[0], "sessionrestore", "Found sessionstore format version");
- is(JSON.parse(BACKUP_SOURCE).version[0], "sessionrestore", "Found backup sessionstore format version");
-
- yield File.makeDir(Paths.backups);
-
- info("Modifying format version number to something incorrect, to make sure that we disregard the file.");
- let parsedSource = JSON.parse(SOURCE);
- parsedSource.version[0] = "bookmarks";
- yield File.writeAtomic(Paths.clean, JSON.stringify(parsedSource));
- yield File.writeAtomic(Paths.cleanBackup, BACKUP_SOURCE);
- is((yield SessionFile.read()).source, BACKUP_SOURCE, "Recovered the correct source from the backup recovery file");
-
- info("Modifying format version number to a future version, to make sure that we disregard the file.");
- parsedSource = JSON.parse(SOURCE);
- parsedSource.version[1] = Number.MAX_SAFE_INTEGER;
- yield File.writeAtomic(Paths.clean, JSON.stringify(parsedSource));
- yield File.writeAtomic(Paths.cleanBackup, BACKUP_SOURCE);
- is((yield SessionFile.read()).source, BACKUP_SOURCE, "Recovered the correct source from the backup recovery file");
-});
-
-add_task(function* cleanup() {
- yield SessionFile.wipe();
-});
diff --git a/browser/components/sessionstore/test/browser_broadcast.js b/browser/components/sessionstore/test/browser_broadcast.js
deleted file mode 100644
index 95984d6d0..000000000
--- a/browser/components/sessionstore/test/browser_broadcast.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const INITIAL_VALUE = "browser_broadcast.js-initial-value-" + Date.now();
-
-/**
- * This test ensures we won't lose tab data queued in the content script when
- * closing a tab.
- */
-add_task(function flush_on_tabclose() {
- let tab = yield createTabWithStorageData(["http://example.com"]);
- let browser = tab.linkedBrowser;
-
- yield modifySessionStorage(browser, {test: "on-tab-close"});
- yield promiseRemoveTab(tab);
-
- let [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- is(storage["http://example.com"].test, "on-tab-close",
- "sessionStorage data has been flushed on TabClose");
-});
-
-/**
- * This test ensures we won't lose tab data queued in the content script when
- * duplicating a tab.
- */
-add_task(function flush_on_duplicate() {
- let tab = yield createTabWithStorageData(["http://example.com"]);
- let browser = tab.linkedBrowser;
-
- yield modifySessionStorage(browser, {test: "on-duplicate"});
- let tab2 = ss.duplicateTab(window, tab);
- yield promiseTabRestored(tab2);
-
- yield promiseRemoveTab(tab2);
- let [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- is(storage["http://example.com"].test, "on-duplicate",
- "sessionStorage data has been flushed when duplicating tabs");
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * This test ensures we won't lose tab data queued in the content script when
- * a window is closed.
- */
-add_task(function flush_on_windowclose() {
- let win = yield promiseNewWindow();
- let tab = yield createTabWithStorageData(["http://example.com"], win);
- let browser = tab.linkedBrowser;
-
- yield modifySessionStorage(browser, {test: "on-window-close"});
- yield BrowserTestUtils.closeWindow(win);
-
- let [{tabs: [_, {storage}]}] = JSON.parse(ss.getClosedWindowData());
- is(storage["http://example.com"].test, "on-window-close",
- "sessionStorage data has been flushed when closing a window");
-});
-
-/**
- * This test ensures that stale tab data is ignored when reusing a tab
- * (via e.g. setTabState) and does not overwrite the new data.
- */
-add_task(function flush_on_settabstate() {
- let tab = yield createTabWithStorageData(["http://example.com"]);
- let browser = tab.linkedBrowser;
-
- // Flush to make sure our tab state is up-to-date.
- yield TabStateFlusher.flush(browser);
-
- let state = ss.getTabState(tab);
- yield modifySessionStorage(browser, {test: "on-set-tab-state"});
-
- // Flush all data contained in the content script but send it using
- // asynchronous messages.
- TabStateFlusher.flush(browser);
-
- yield promiseTabState(tab, state);
-
- let {storage} = JSON.parse(ss.getTabState(tab));
- is(storage["http://example.com"].test, INITIAL_VALUE,
- "sessionStorage data has not been overwritten");
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * This test ensures that we won't lose tab data that has been sent
- * asynchronously just before closing a tab. Flushing must re-send all data
- * that hasn't been received by chrome, yet.
- */
-add_task(function flush_on_tabclose_racy() {
- let tab = yield createTabWithStorageData(["http://example.com"]);
- let browser = tab.linkedBrowser;
-
- // Flush to make sure we start with an empty queue.
- yield TabStateFlusher.flush(browser);
-
- yield modifySessionStorage(browser, {test: "on-tab-close-racy"});
-
- // Flush all data contained in the content script but send it using
- // asynchronous messages.
- TabStateFlusher.flush(browser);
- yield promiseRemoveTab(tab);
-
- let [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- is(storage["http://example.com"].test, "on-tab-close-racy",
- "sessionStorage data has been merged correctly to prevent data loss");
-});
-
-function promiseNewWindow() {
- let deferred = Promise.defer();
- whenNewWindowLoaded({private: false}, deferred.resolve);
- return deferred.promise;
-}
-
-function createTabWithStorageData(urls, win = window) {
- return Task.spawn(function task() {
- let tab = win.gBrowser.addTab();
- let browser = tab.linkedBrowser;
-
- for (let url of urls) {
- browser.loadURI(url);
- yield promiseBrowserLoaded(browser);
- yield modifySessionStorage(browser, {test: INITIAL_VALUE});
- }
-
- throw new Task.Result(tab);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_capabilities.js b/browser/components/sessionstore/test/browser_capabilities.js
deleted file mode 100644
index 456e41882..000000000
--- a/browser/components/sessionstore/test/browser_capabilities.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * These tests ensures that disabling features by flipping nsIDocShell.allow*
- * properties are (re)stored as disabled. Disallowed features must be
- * re-enabled when the tab is re-used by another tab restoration.
- */
-add_task(function docshell_capabilities() {
- let tab = yield createTab();
- let browser = tab.linkedBrowser;
- let docShell = browser.docShell;
-
- // Get the list of capabilities for docShells.
- let flags = Object.keys(docShell).filter(k => k.startsWith("allow"));
-
- // Check that everything is allowed by default for new tabs.
- let state = JSON.parse(ss.getTabState(tab));
- ok(!("disallow" in state), "everything allowed by default");
- ok(flags.every(f => docShell[f]), "all flags set to true");
-
- // Flip a couple of allow* flags.
- docShell.allowImages = false;
- docShell.allowMetaRedirects = false;
-
- // Now reload the document to ensure that these capabilities
- // are taken into account.
- browser.reload();
- yield promiseBrowserLoaded(browser);
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser);
-
- // Check that we correctly save disallowed features.
- let disallowedState = JSON.parse(ss.getTabState(tab));
- let disallow = new Set(disallowedState.disallow.split(","));
- ok(disallow.has("Images"), "images not allowed");
- ok(disallow.has("MetaRedirects"), "meta redirects not allowed");
- is(disallow.size, 2, "two capabilities disallowed");
-
- // Reuse the tab to restore a new, clean state into it.
- yield promiseTabState(tab, {entries: [{url: "about:robots"}]});
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser);
-
- // After restoring disallowed features must be available again.
- state = JSON.parse(ss.getTabState(tab));
- ok(!("disallow" in state), "everything allowed again");
- ok(flags.every(f => docShell[f]), "all flags set to true");
-
- // Restore the state with disallowed features.
- yield promiseTabState(tab, disallowedState);
-
- // Check that docShell flags are set.
- ok(!docShell.allowImages, "images not allowed");
- ok(!docShell.allowMetaRedirects, "meta redirects not allowed");
-
- // Check that we correctly restored features as disabled.
- state = JSON.parse(ss.getTabState(tab));
- disallow = new Set(state.disallow.split(","));
- ok(disallow.has("Images"), "images not allowed anymore");
- ok(disallow.has("MetaRedirects"), "meta redirects not allowed anymore");
- is(disallow.size, 2, "two capabilities disallowed");
-
- // Clean up after ourselves.
- gBrowser.removeTab(tab);
-});
-
-function createTab() {
- let tab = gBrowser.addTab("about:mozilla");
- let browser = tab.linkedBrowser;
- return promiseBrowserLoaded(browser).then(() => tab);
-}
diff --git a/browser/components/sessionstore/test/browser_cleaner.js b/browser/components/sessionstore/test/browser_cleaner.js
deleted file mode 100644
index 921d7d3e4..000000000
--- a/browser/components/sessionstore/test/browser_cleaner.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-/*
- * This test ensures that Session Restore eventually forgets about
- * tabs and windows that have been closed a long time ago.
- */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Services.jsm", this);
-Cu.import("resource://gre/modules/osfile.jsm", this);
-Cu.import("resource://gre/modules/Task.jsm", this);
-
-const LONG_TIME_AGO = 1;
-
-const URL_TAB1 = "http://example.com/browser_cleaner.js?newtab1=" + Math.random();
-const URL_TAB2 = "http://example.com/browser_cleaner.js?newtab2=" + Math.random();
-const URL_NEWWIN = "http://example.com/browser_cleaner.js?newwin=" + Math.random();
-
-function isRecent(stamp) {
- is(typeof stamp, "number", "This is a timestamp");
- return Date.now() - stamp <= 60000;
-}
-
-function promiseCleanup () {
- info("Cleaning up browser");
-
- return promiseBrowserState(getClosedState());
-};
-
-function getClosedState() {
- return Cu.cloneInto(CLOSED_STATE, {});
-}
-
-var CLOSED_STATE;
-
-add_task(function* init() {
- forgetClosedWindows();
- while (ss.getClosedTabCount(window) > 0) {
- ss.forgetClosedTab(window, 0);
- }
-});
-
-add_task(function* test_open_and_close() {
- let newTab1 = gBrowser.addTab(URL_TAB1);
- yield promiseBrowserLoaded(newTab1.linkedBrowser);
-
- let newTab2 = gBrowser.addTab(URL_TAB2);
- yield promiseBrowserLoaded(newTab2.linkedBrowser);
-
- let newWin = yield promiseNewWindowLoaded();
- let tab = newWin.gBrowser.addTab(URL_NEWWIN);
-
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- yield TabStateFlusher.flushWindow(window);
- yield TabStateFlusher.flushWindow(newWin);
-
- info("1. Making sure that before closing, we don't have closedAt");
- // For the moment, no "closedAt"
- let state = JSON.parse(ss.getBrowserState());
- is(state.windows[0].closedAt || false, false, "1. Main window doesn't have closedAt");
- is(state.windows[1].closedAt || false, false, "1. Second window doesn't have closedAt");
- is(state.windows[0].tabs[0].closedAt || false, false, "1. First tab doesn't have closedAt");
- is(state.windows[0].tabs[1].closedAt || false, false, "1. Second tab doesn't have closedAt");
-
- info("2. Making sure that after closing, we have closedAt");
-
- // Now close stuff, this should add closeAt
- yield BrowserTestUtils.closeWindow(newWin);
- yield promiseRemoveTab(newTab1);
- yield promiseRemoveTab(newTab2);
-
- state = CLOSED_STATE = JSON.parse(ss.getBrowserState());
-
- is(state.windows[0].closedAt || false, false, "2. Main window doesn't have closedAt");
- ok(isRecent(state._closedWindows[0].closedAt), "2. Second window was closed recently");
- ok(isRecent(state.windows[0]._closedTabs[0].closedAt), "2. First tab was closed recently");
- ok(isRecent(state.windows[0]._closedTabs[1].closedAt), "2. Second tab was closed recently");
-});
-
-
-add_task(function* test_restore() {
- info("3. Making sure that after restoring, we don't have closedAt");
- yield promiseBrowserState(CLOSED_STATE);
-
- let newWin = ss.undoCloseWindow(0);
- yield promiseDelayedStartupFinished(newWin);
-
- let newTab2 = ss.undoCloseTab(window, 0);
- yield promiseTabRestored(newTab2);
-
- let newTab1 = ss.undoCloseTab(window, 0);
- yield promiseTabRestored(newTab1);
-
- let state = JSON.parse(ss.getBrowserState());
-
- is(state.windows[0].closedAt || false, false, "3. Main window doesn't have closedAt");
- is(state.windows[1].closedAt || false, false, "3. Second window doesn't have closedAt");
- is(state.windows[0].tabs[0].closedAt || false, false, "3. First tab doesn't have closedAt");
- is(state.windows[0].tabs[1].closedAt || false, false, "3. Second tab doesn't have closedAt");
-
- yield BrowserTestUtils.closeWindow(newWin);
- gBrowser.removeTab(newTab1);
- gBrowser.removeTab(newTab2);
-});
-
-
-add_task(function* test_old_data() {
- info("4. Removing closedAt from the sessionstore, making sure that it is added upon idle-daily");
-
- let state = getClosedState();
- delete state._closedWindows[0].closedAt;
- delete state.windows[0]._closedTabs[0].closedAt;
- delete state.windows[0]._closedTabs[1].closedAt;
- yield promiseBrowserState(state);
-
- info("Sending idle-daily");
- Services.obs.notifyObservers(null, "idle-daily", "");
- info("Sent idle-daily");
-
- state = JSON.parse(ss.getBrowserState());
- is(state.windows[0].closedAt || false, false, "4. Main window doesn't have closedAt");
- ok(isRecent(state._closedWindows[0].closedAt), "4. Second window was closed recently");
- ok(isRecent(state.windows[0]._closedTabs[0].closedAt), "4. First tab was closed recently");
- ok(isRecent(state.windows[0]._closedTabs[1].closedAt), "4. Second tab was closed recently");
- yield promiseCleanup();
-});
-
-
-add_task(function* test_cleanup() {
-
- info("5. Altering closedAt to an old date, making sure that stuff gets collected, eventually");
- yield promiseCleanup();
-
- let state = getClosedState();
- state._closedWindows[0].closedAt = LONG_TIME_AGO;
- state.windows[0]._closedTabs[0].closedAt = LONG_TIME_AGO;
- state.windows[0]._closedTabs[1].closedAt = Date.now();
- let url = state.windows[0]._closedTabs[1].state.entries[0].url;
-
- yield promiseBrowserState(state);
-
- info("Sending idle-daily");
- Services.obs.notifyObservers(null, "idle-daily", "");
- info("Sent idle-daily");
-
- state = JSON.parse(ss.getBrowserState());
- is(state._closedWindows[0], undefined, "5. Second window was forgotten");
-
- is(state.windows[0]._closedTabs.length, 1, "5. Only one closed tab left");
- is(state.windows[0]._closedTabs[0].state.entries[0].url, url, "5. The second tab is still here");
- yield promiseCleanup();
-});
-
diff --git a/browser/components/sessionstore/test/browser_cookies.js b/browser/components/sessionstore/test/browser_cookies.js
deleted file mode 100644
index cc5b41e4b..000000000
--- a/browser/components/sessionstore/test/browser_cookies.js
+++ /dev/null
@@ -1,173 +0,0 @@
-"use strict";
-
-const PATH = "/browser/browser/components/sessionstore/test/";
-
-/**
- * Remove all cookies to start off a clean slate.
- */
-add_task(function* test_setup() {
- requestLongerTimeout(2);
- Services.cookies.removeAll();
-});
-
-/**
- * Test multiple scenarios with different Set-Cookie header domain= params.
- */
-add_task(function* test_run() {
- // Set-Cookie: foobar=random()
- // The domain of the cookie should be the request domain (www.example.com).
- // We should collect data only for the request domain, no parent or subdomains.
- yield testCookieCollection({
- host: "http://www.example.com",
- cookieHost: "www.example.com",
- cookieURIs: ["http://www.example.com" + PATH],
- noCookieURIs: ["http://example.com/" + PATH]
- });
-
- // Set-Cookie: foobar=random()
- // The domain of the cookie should be the request domain (example.com).
- // We should collect data only for the request domain, no parent or subdomains.
- yield testCookieCollection({
- host: "http://example.com",
- cookieHost: "example.com",
- cookieURIs: ["http://example.com" + PATH],
- noCookieURIs: ["http://www.example.com/" + PATH]
- });
-
- // Set-Cookie: foobar=random(); Domain=example.com
- // The domain of the cookie should be the given one (.example.com).
- // We should collect data for the given domain and its subdomains.
- yield testCookieCollection({
- host: "http://example.com",
- domain: "example.com",
- cookieHost: ".example.com",
- cookieURIs: ["http://example.com" + PATH, "http://www.example.com/" + PATH],
- noCookieURIs: ["about:robots"]
- });
-
- // Set-Cookie: foobar=random(); Domain=.example.com
- // The domain of the cookie should be the given one (.example.com).
- // We should collect data for the given domain and its subdomains.
- yield testCookieCollection({
- host: "http://example.com",
- domain: ".example.com",
- cookieHost: ".example.com",
- cookieURIs: ["http://example.com" + PATH, "http://www.example.com/" + PATH],
- noCookieURIs: ["about:robots"]
- });
-
- // Set-Cookie: foobar=random(); Domain=www.example.com
- // The domain of the cookie should be the given one (.www.example.com).
- // We should collect data for the given domain and its subdomains.
- yield testCookieCollection({
- host: "http://www.example.com",
- domain: "www.example.com",
- cookieHost: ".www.example.com",
- cookieURIs: ["http://www.example.com/" + PATH],
- noCookieURIs: ["http://example.com"]
- });
-
- // Set-Cookie: foobar=random(); Domain=.www.example.com
- // The domain of the cookie should be the given one (.www.example.com).
- // We should collect data for the given domain and its subdomains.
- yield testCookieCollection({
- host: "http://www.example.com",
- domain: ".www.example.com",
- cookieHost: ".www.example.com",
- cookieURIs: ["http://www.example.com/" + PATH],
- noCookieURIs: ["http://example.com"]
- });
-});
-
-/**
- * Generic test function to check sessionstore's cookie collection module with
- * different cookie domains given in the Set-Cookie header. See above for some
- * usage examples.
- */
-var testCookieCollection = Task.async(function (params) {
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
-
- let urlParams = new URLSearchParams();
- let value = Math.random();
- urlParams.append("value", value);
-
- if (params.domain) {
- urlParams.append("domain", params.domain);
- }
-
- // Construct request URI.
- let uri = `${params.host}${PATH}browser_cookies.sjs?${urlParams}`;
-
- // Wait for the browser to load and the cookie to be set.
- // These two events can probably happen in no particular order,
- // so let's wait for them in parallel.
- yield Promise.all([
- waitForNewCookie(),
- replaceCurrentURI(browser, uri)
- ]);
-
- // Check all URIs for which the cookie should be collected.
- for (let uri of params.cookieURIs || []) {
- yield replaceCurrentURI(browser, uri);
-
- // Check the cookie.
- let cookie = getCookie();
- is(cookie.host, params.cookieHost, "cookie host is correct");
- is(cookie.path, PATH, "cookie path is correct");
- is(cookie.name, "foobar", "cookie name is correct");
- is(cookie.value, value, "cookie value is correct");
- }
-
- // Check all URIs for which the cookie should NOT be collected.
- for (let uri of params.noCookieURIs || []) {
- yield replaceCurrentURI(browser, uri);
-
- // Cookie should be ignored.
- ok(!getCookie(), "no cookie collected");
- }
-
- // Clean up.
- gBrowser.removeTab(tab);
- Services.cookies.removeAll();
-});
-
-/**
- * Replace the current URI of the given browser by loading a new URI. The
- * browser's session history will be completely replaced. This function ensures
- * that the parent process has the lastest shistory data before resolving.
- */
-var replaceCurrentURI = Task.async(function* (browser, uri) {
- // Replace the tab's current URI with the parent domain.
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
- browser.loadURIWithFlags(uri, flags);
- yield promiseBrowserLoaded(browser);
-
- // Ensure the tab's session history is up-to-date.
- yield TabStateFlusher.flush(browser);
-});
-
-/**
- * Waits for a new "*example.com" cookie to be added.
- */
-function waitForNewCookie() {
- return new Promise(resolve => {
- Services.obs.addObserver(function observer(subj, topic, data) {
- let cookie = subj.QueryInterface(Ci.nsICookie2);
- if (data == "added" && cookie.host.endsWith("example.com")) {
- Services.obs.removeObserver(observer, topic);
- resolve();
- }
- }, "cookie-changed", false);
- });
-}
-
-/**
- * Retrieves the first cookie in the first window from the current sessionstore
- * state.
- */
-function getCookie() {
- let state = JSON.parse(ss.getWindowState(window));
- let cookies = state.windows[0].cookies || [];
- return cookies[0] || null;
-}
diff --git a/browser/components/sessionstore/test/browser_cookies.sjs b/browser/components/sessionstore/test/browser_cookies.sjs
deleted file mode 100644
index bffbd66d9..000000000
--- a/browser/components/sessionstore/test/browser_cookies.sjs
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Components.utils.importGlobalProperties(["URLSearchParams"]);
-
-function handleRequest(req, resp) {
- resp.setStatusLine(req.httpVersion, 200);
-
- let params = new URLSearchParams(req.queryString);
- let value = params.get("value");
-
- let domain = "";
- if (params.has("domain")) {
- domain = `; Domain=${params.get("domain")}`;
- }
-
- resp.setHeader("Set-Cookie", `foobar=${value}${domain}`);
- resp.write("<meta charset=utf-8>hi");
-}
diff --git a/browser/components/sessionstore/test/browser_crashedTabs.js b/browser/components/sessionstore/test/browser_crashedTabs.js
deleted file mode 100644
index 5841d536a..000000000
--- a/browser/components/sessionstore/test/browser_crashedTabs.js
+++ /dev/null
@@ -1,462 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(10);
-
-const PAGE_1 = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const PAGE_2 = "data:text/html,<html><body>Another%20regular,%20everyday,%20normal%20page.";
-
-// Turn off tab animations for testing and use a single content process
-// for these tests since we want to test tabs within the crashing process here.
-add_task(function* test_initialize() {
- yield SpecialPowers.pushPrefEnv({
- set: [
- [ "dom.ipc.processCount", 1 ],
- [ "browser.tabs.animate", false]
- ] });
-});
-
-// Allow tabs to restore on demand so we can test pending states
-Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
-
-function clickButton(browser, id) {
- info("Clicking " + id);
-
- let frame_script = (id) => {
- let button = content.document.getElementById(id);
- button.click();
- };
-
- let mm = browser.messageManager;
- mm.loadFrameScript("data:,(" + frame_script.toString() + ")('" + id + "');", false);
-}
-
-/**
- * Checks the documentURI of the root document of a remote browser
- * to see if it equals URI. Returns a Promise that resolves if
- * there is a match, and rejects with an error message if they
- * do not match.
- *
- * @param browser
- * The remote <xul:browser> to check the root document URI in.
- * @param URI
- * A string to match the root document URI against.
- * @return Promise
- */
-function promiseContentDocumentURIEquals(browser, URI) {
- return new Promise((resolve, reject) => {
- let frame_script = () => {
- sendAsyncMessage("test:documenturi", {
- uri: content.document.documentURI,
- });
- };
-
- let mm = browser.messageManager;
- mm.addMessageListener("test:documenturi", function onMessage(message) {
- mm.removeMessageListener("test:documenturi", onMessage);
- let contentURI = message.data.uri;
- if (contentURI == URI) {
- resolve();
- } else {
- reject(`Content has URI ${contentURI} which does not match ${URI}`);
- }
- });
-
- mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false);
- });
-}
-
-/**
- * Checks the window.history.length of the root window of a remote
- * browser to see if it equals length. Returns a Promise that resolves
- * if there is a match, and rejects with an error message if they
- * do not match.
- *
- * @param browser
- * The remote <xul:browser> to check the root window.history.length
- * @param length
- * The expected history length
- * @return Promise
- */
-function promiseHistoryLength(browser, length) {
- return new Promise((resolve, reject) => {
- let frame_script = () => {
- sendAsyncMessage("test:historylength", {
- length: content.history.length,
- });
- };
-
- let mm = browser.messageManager;
- mm.addMessageListener("test:historylength", function onMessage(message) {
- mm.removeMessageListener("test:historylength", onMessage);
- let contentLength = message.data.length;
- if (contentLength == length) {
- resolve();
- } else {
- reject(`Content has window.history.length ${contentLength} which does ` +
- `not equal expected ${length}`);
- }
- });
-
- mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false);
- });
-}
-
-/**
- * Returns a Promise that resolves when a browser has fired the
- * AboutTabCrashedReady event.
- *
- * @param browser
- * The remote <xul:browser> that will fire the event.
- * @return Promise
- */
-function promiseTabCrashedReady(browser) {
- return new Promise((resolve) => {
- browser.addEventListener("AboutTabCrashedReady", function ready(e) {
- browser.removeEventListener("AboutTabCrashedReady", ready, false, true);
- resolve();
- }, false, true);
- });
-}
-
-/**
- * Checks that if a tab crashes, that information about the tab crashed
- * page does not get added to the tab history.
- */
-add_task(function test_crash_page_not_in_history() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
-
- // Check the tab state and make sure the tab crashed page isn't
- // mentioned.
- let {entries} = JSON.parse(ss.getTabState(newTab));
- is(entries.length, 1, "Should have a single history entry");
- is(entries[0].url, PAGE_1,
- "Single entry should be the page we visited before crashing");
-
- gBrowser.removeTab(newTab);
-});
-
-/**
- * Checks that if a tab crashes, that when we browse away from that page
- * to a non-blacklisted site (so the browser becomes remote again), that
- * we record history for that new visit.
- */
-add_task(function test_revived_history_from_remote() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
-
- // Browse to a new site that will cause the browser to
- // become remote again.
- browser.loadURI(PAGE_2);
- yield promiseTabRestored(newTab);
- ok(!newTab.hasAttribute("crashed"), "Tab shouldn't be marked as crashed anymore.");
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield TabStateFlusher.flush(browser);
-
- // Check the tab state and make sure the tab crashed page isn't
- // mentioned.
- let {entries} = JSON.parse(ss.getTabState(newTab));
- is(entries.length, 2, "Should have two history entries");
- is(entries[0].url, PAGE_1,
- "First entry should be the page we visited before crashing");
- is(entries[1].url, PAGE_2,
- "Second entry should be the page we visited after crashing");
-
- gBrowser.removeTab(newTab);
-});
-
-/**
- * Checks that if a tab crashes, that when we browse away from that page
- * to a blacklisted site (so the browser stays non-remote), that
- * we record history for that new visit.
- */
-add_task(function test_revived_history_from_non_remote() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
-
- // Browse to a new site that will not cause the browser to
- // become remote again.
- browser.loadURI("about:mozilla");
- yield promiseBrowserLoaded(browser);
- ok(!newTab.hasAttribute("crashed"), "Tab shouldn't be marked as crashed anymore.");
- ok(!browser.isRemoteBrowser, "Should not be a remote browser");
- yield TabStateFlusher.flush(browser);
-
- // Check the tab state and make sure the tab crashed page isn't
- // mentioned.
- let {entries} = JSON.parse(ss.getTabState(newTab));
- is(entries.length, 2, "Should have two history entries");
- is(entries[0].url, PAGE_1,
- "First entry should be the page we visited before crashing");
- is(entries[1].url, "about:mozilla",
- "Second entry should be the page we visited after crashing");
-
- gBrowser.removeTab(newTab);
-});
-
-/**
- * Checks that we can revive a crashed tab back to the page that
- * it was on when it crashed.
- */
-add_task(function test_revive_tab_from_session_store() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- let newTab2 = gBrowser.addTab();
- let browser2 = newTab2.linkedBrowser;
- ok(browser2.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser2);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_2);
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
- // Background tabs should not be crashed, but should be in the "to be restored"
- // state.
- ok(!newTab2.hasAttribute("crashed"), "Second tab should not be crashed.");
- ok(newTab2.hasAttribute("pending"), "Second tab should be pending.");
-
- // Use SessionStore to revive the first tab
- clickButton(browser, "restoreTab");
- yield promiseTabRestored(newTab);
- ok(!newTab.hasAttribute("crashed"), "Tab shouldn't be marked as crashed anymore.");
- ok(newTab2.hasAttribute("pending"), "Second tab should still be pending.");
-
- // We can't just check browser.currentURI.spec, because from
- // the outside, a crashed tab has the same URI as the page
- // it crashed on (much like an about:neterror page). Instead,
- // we have to use the documentURI on the content.
- yield promiseContentDocumentURIEquals(browser, PAGE_2);
-
- // We should also have two entries in the browser history.
- yield promiseHistoryLength(browser, 2);
-
- gBrowser.removeTab(newTab);
- gBrowser.removeTab(newTab2);
-});
-
-/**
- * Checks that we can revive multiple crashed tabs back to the pages
- * that they were on when they crashed.
- */
-add_task(function test_revive_all_tabs_from_session_store() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- // In order to see a second about:tabcrashed page, we'll need
- // a second window, since only selected tabs will show
- // about:tabcrashed.
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
- let newTab2 = win2.gBrowser.addTab(PAGE_1);
- win2.gBrowser.selectedTab = newTab2;
- let browser2 = newTab2.linkedBrowser;
- ok(browser2.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser2);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_2);
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
- yield TabStateFlusher.flush(browser2);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
- // Both tabs should now be crashed.
- is(newTab.getAttribute("crashed"), "true", "First tab should be crashed");
- is(newTab2.getAttribute("crashed"), "true", "Second window tab should be crashed");
-
- // Use SessionStore to revive all the tabs
- clickButton(browser, "restoreAll");
- yield promiseTabRestored(newTab);
- ok(!newTab.hasAttribute("crashed"), "Tab shouldn't be marked as crashed anymore.");
- ok(!newTab.hasAttribute("pending"), "Tab shouldn't be pending.");
- ok(!newTab2.hasAttribute("crashed"), "Second tab shouldn't be marked as crashed anymore.");
- ok(!newTab2.hasAttribute("pending"), "Second tab shouldn't be pending.");
-
- // We can't just check browser.currentURI.spec, because from
- // the outside, a crashed tab has the same URI as the page
- // it crashed on (much like an about:neterror page). Instead,
- // we have to use the documentURI on the content.
- yield promiseContentDocumentURIEquals(browser, PAGE_2);
- yield promiseContentDocumentURIEquals(browser2, PAGE_1);
-
- // We should also have two entries in the browser history.
- yield promiseHistoryLength(browser, 2);
-
- yield BrowserTestUtils.closeWindow(win2);
- gBrowser.removeTab(newTab);
-});
-
-/**
- * Checks that about:tabcrashed can close the current tab
- */
-add_task(function test_close_tab_after_crash() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
-
- let promise = promiseEvent(gBrowser.tabContainer, "TabClose");
-
- // Click the close tab button
- clickButton(browser, "closeTab");
- yield promise;
-
- is(gBrowser.tabs.length, 1, "Should have closed the tab");
-});
-
-
-/**
- * Checks that "restore all" button is only shown if more than one tab
- * is showing about:tabcrashed
- */
-add_task(function* test_hide_restore_all_button() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
-
- let doc = browser.contentDocument;
- let restoreAllButton = doc.getElementById("restoreAll");
- let restoreOneButton = doc.getElementById("restoreTab");
-
- let restoreAllStyles = window.getComputedStyle(restoreAllButton);
- is(restoreAllStyles.display, "none", "Restore All button should be hidden");
- ok(restoreOneButton.classList.contains("primary"), "Restore Tab button should have the primary class");
-
- let newTab2 = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
-
- browser.loadURI(PAGE_2);
- yield promiseBrowserLoaded(browser);
-
- // Load up a second window so we can get another tab to show
- // about:tabcrashed
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
- let newTab3 = win2.gBrowser.addTab(PAGE_2);
- win2.gBrowser.selectedTab = newTab3;
- let otherWinBrowser = newTab3.linkedBrowser;
- yield promiseBrowserLoaded(otherWinBrowser);
- // We'll need to make sure the second tab's browser has finished
- // sending its AboutTabCrashedReady event before we know for
- // sure whether or not we're showing the right Restore buttons.
- let otherBrowserReady = promiseTabCrashedReady(otherWinBrowser);
-
- // Crash the first tab.
- yield BrowserTestUtils.crashBrowser(browser);
- yield otherBrowserReady;
-
- doc = browser.contentDocument;
- restoreAllButton = doc.getElementById("restoreAll");
- restoreOneButton = doc.getElementById("restoreTab");
-
- restoreAllStyles = window.getComputedStyle(restoreAllButton);
- isnot(restoreAllStyles.display, "none", "Restore All button should not be hidden");
- ok(!(restoreOneButton.classList.contains("primary")), "Restore Tab button should not have the primary class");
-
- yield BrowserTestUtils.closeWindow(win2);
- gBrowser.removeTab(newTab);
- gBrowser.removeTab(newTab2);
-});
-
-add_task(function* test_aboutcrashedtabzoom() {
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
- ok(browser.isRemoteBrowser, "Should be a remote browser");
- yield promiseBrowserLoaded(browser);
-
- browser.loadURI(PAGE_1);
- yield promiseBrowserLoaded(browser);
-
- FullZoom.enlarge();
- let zoomLevel = ZoomManager.getZoomForBrowser(browser);
- ok(zoomLevel !== 1, "should have enlarged");
-
- yield TabStateFlusher.flush(browser);
-
- // Crash the tab
- yield BrowserTestUtils.crashBrowser(browser);
-
- ok(ZoomManager.getZoomForBrowser(browser) === 1, "zoom should have reset on crash");
-
- clickButton(browser, "restoreTab");
- yield promiseTabRestored(newTab);
-
- ok(ZoomManager.getZoomForBrowser(browser) === zoomLevel, "zoom should have gone back to enlarged");
- FullZoom.reset();
-
- gBrowser.removeTab(newTab);
-});
diff --git a/browser/components/sessionstore/test/browser_dying_cache.js b/browser/components/sessionstore/test/browser_dying_cache.js
deleted file mode 100644
index c573aa5d4..000000000
--- a/browser/components/sessionstore/test/browser_dying_cache.js
+++ /dev/null
@@ -1,66 +0,0 @@
-"use strict";
-
-/**
- * This test ensures that after closing a window we keep its state data around
- * as long as something keeps a reference to it. It should only be possible to
- * read data after closing - writing should fail.
- */
-
-add_task(function* test() {
- // Open a new window.
- let win = yield promiseNewWindowLoaded();
-
- // Load some URL in the current tab.
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
- win.gBrowser.selectedBrowser.loadURIWithFlags("about:robots", flags);
- yield promiseBrowserLoaded(win.gBrowser.selectedBrowser);
-
- // Open a second tab and close the first one.
- let tab = win.gBrowser.addTab("about:mozilla");
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- yield promiseRemoveTab(win.gBrowser.tabs[0]);
-
- // Make sure our window is still tracked by sessionstore
- // and the window state is as expected.
- ok("__SSi" in win, "window is being tracked by sessionstore");
- ss.setWindowValue(win, "foo", "bar");
- checkWindowState(win);
-
- let state = ss.getWindowState(win);
- let closedTabData = ss.getClosedTabData(win);
-
- // Close our window.
- yield BrowserTestUtils.closeWindow(win);
-
- // SessionStore should no longer track our window
- // but it should still report the same state.
- ok(!("__SSi" in win), "sessionstore does no longer track our window");
- checkWindowState(win);
-
- // Make sure we're not allowed to modify state data.
- Assert.throws(() => ss.setWindowState(win, {}),
- "we're not allowed to modify state data anymore");
- Assert.throws(() => ss.setWindowValue(win, "foo", "baz"),
- "we're not allowed to modify state data anymore");
-});
-
-function checkWindowState(window) {
- let {windows: [{tabs}]} = JSON.parse(ss.getWindowState(window));
- is(tabs.length, 1, "the window has a single tab");
- is(tabs[0].entries[0].url, "about:mozilla", "the tab is about:mozilla");
-
- is(ss.getClosedTabCount(window), 1, "the window has one closed tab");
- let [{state: {entries: [{url}]}}] = JSON.parse(ss.getClosedTabData(window));
- is(url, "about:robots", "the closed tab is about:robots");
-
- is(ss.getWindowValue(window, "foo"), "bar", "correct extData value");
-}
-
-function shouldThrow(f) {
- try {
- f();
- } catch (e) {
- return true;
- }
-}
diff --git a/browser/components/sessionstore/test/browser_dynamic_frames.js b/browser/components/sessionstore/test/browser_dynamic_frames.js
deleted file mode 100644
index e4355fee3..000000000
--- a/browser/components/sessionstore/test/browser_dynamic_frames.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * Ensure that static frames of framesets are serialized but dynamically
- * inserted iframes are ignored.
- */
-add_task(function () {
- // This URL has the following frames:
- // + data:text/html,A (static)
- // + data:text/html,B (static)
- // + data:text/html,C (dynamic iframe)
- const URL = "data:text/html;charset=utf-8," +
- "<frameset cols=50%25,50%25><frame src='data:text/html,A'>" +
- "<frame src='data:text/html,B'></frameset>" +
- "<script>var i=document.createElement('iframe');" +
- "i.setAttribute('src', 'data:text/html,C');" +
- "document.body.appendChild(i);</script>";
-
- // Add a new tab with two "static" and one "dynamic" frame.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
-
- // Check URLs.
- ok(entries[0].url.startsWith("data:text/html"), "correct root url");
- is(entries[0].children[0].url, "data:text/html,A", "correct url for 1st frame");
- is(entries[0].children[1].url, "data:text/html,B", "correct url for 2nd frame");
-
- // Check the number of children.
- is(entries.length, 1, "there is one root entry ...");
- is(entries[0].children.length, 2, "... with two child entries");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that iframes created by the network parser are serialized but
- * dynamically inserted iframes are ignored. Navigating a subframe should
- * create a second root entry that doesn't contain any dynamic children either.
- */
-add_task(function () {
- // This URL has the following frames:
- // + data:text/html,A (static)
- // + data:text/html,C (dynamic iframe)
- const URL = "data:text/html;charset=utf-8," +
- "<iframe name=t src='data:text/html,A'></iframe>" +
- "<a id=lnk href='data:text/html,B' target=t>clickme</a>" +
- "<script>var i=document.createElement('iframe');" +
- "i.setAttribute('src', 'data:text/html,C');" +
- "document.body.appendChild(i);</script>";
-
- // Add a new tab with one "static" and one "dynamic" frame.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
-
- // Check URLs.
- ok(entries[0].url.startsWith("data:text/html"), "correct root url");
- ok(!entries[0].children, "no children collected");
-
- // Navigate the subframe.
- browser.messageManager.sendAsyncMessage("ss-test:click", {id: "lnk"});
- yield promiseBrowserLoaded(browser, false /* don't ignore subframes */);
-
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
-
- // Check URLs.
- ok(entries[0].url.startsWith("data:text/html"), "correct 1st root url");
- ok(entries[1].url.startsWith("data:text/html"), "correct 2nd root url");
- ok(!entries.children, "no children collected");
- ok(!entries[0].children, "no children collected");
- ok(!entries[1].children, "no children collected");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_forget_async_closings.js b/browser/components/sessionstore/test/browser_forget_async_closings.js
deleted file mode 100644
index c130ec5ad..000000000
--- a/browser/components/sessionstore/test/browser_forget_async_closings.js
+++ /dev/null
@@ -1,144 +0,0 @@
-"use strict";
-
-const PAGE = "http://example.com/";
-
-/**
- * Creates a tab in the current window worth storing in the
- * closedTabs array, and then closes it. Runs a synchronous
- * forgetFn passed in that should cause us to forget the tab,
- * and then ensures that after the tab has sent its final
- * update message that we didn't accidentally store it in
- * the closedTabs array.
- *
- * @param forgetFn (function)
- * A synchronous function that should cause the tab
- * to be forgotten.
- * @returns Promise
- */
-let forgetTabHelper = Task.async(function*(forgetFn) {
- // We want to suppress all non-final updates from the browser tabs
- // so as to eliminate any racy-ness with this test.
- yield pushPrefs(["browser.sessionstore.debug.no_auto_updates", true]);
-
- // Forget any previous closed tabs from other tests that may have
- // run in the same session.
- Services.obs.notifyObservers(null, "browser:purge-session-history", 0);
-
- is(ss.getClosedTabCount(window), 0,
- "We should have 0 closed tabs being stored.");
-
- // Create a tab worth remembering.
- let tab = gBrowser.addTab(PAGE);
- let browser = tab.linkedBrowser;
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
- yield TabStateFlusher.flush(browser);
-
- // Now close the tab, and immediately choose to forget it.
- let promise = BrowserTestUtils.removeTab(tab);
-
- // At this point, the tab will have closed, but the final update
- // to SessionStore hasn't come up yet. Now do the operation that
- // should cause us to forget the tab.
- forgetFn();
-
- is(ss.getClosedTabCount(window), 0, "Should have forgotten the closed tab");
-
- // Now wait for the final update to come up.
- yield promise;
-
- is(ss.getClosedTabCount(window), 0,
- "Should not have stored the forgotten closed tab");
-});
-
-/**
- * Creates a new window worth storing in the closeWIndows array,
- * and then closes it. Runs a synchronous forgetFn passed in that
- * should cause us to forget the window, and then ensures that after
- * the window has sent its final update message that we didn't
- * accidentally store it in the closedWindows array.
- *
- * @param forgetFn (function)
- * A synchronous function that should cause the window
- * to be forgotten.
- * @returns Promise
- */
-let forgetWinHelper = Task.async(function*(forgetFn) {
- // We want to suppress all non-final updates from the browser tabs
- // so as to eliminate any racy-ness with this test.
- yield pushPrefs(["browser.sessionstore.debug.no_auto_updates", true]);
-
- // Forget any previous closed windows from other tests that may have
- // run in the same session.
- Services.obs.notifyObservers(null, "browser:purge-session-history", 0);
-
- is(ss.getClosedWindowCount(), 0, "We should have 0 closed windows being stored.");
-
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
-
- // Create a tab worth remembering.
- let tab = newWin.gBrowser.selectedTab;
- let browser = tab.linkedBrowser;
- browser.loadURI(PAGE);
- yield BrowserTestUtils.browserLoaded(browser, false, PAGE);
- yield TabStateFlusher.flush(browser);
-
- // Now close the window and immediately choose to forget it.
- let windowClosed = BrowserTestUtils.windowClosed(newWin);
- let domWindowClosed = BrowserTestUtils.domWindowClosed(newWin);
-
- newWin.close();
- yield domWindowClosed;
-
- // At this point, the window will have closed and the onClose handler
- // has run, but the final update to SessionStore hasn't come up yet.
- // Now do the oepration that should cause us to forget the window.
- forgetFn();
-
- is(ss.getClosedWindowCount(), 0, "Should have forgotten the closed window");
-
- // Now wait for the final update to come up.
- yield windowClosed;
-
- is(ss.getClosedWindowCount(), 0, "Should not have stored the closed window");
-});
-
-/**
- * Tests that if we choose to forget a tab while waiting for its
- * final flush to complete, we don't accidentally store it.
- */
-add_task(function* test_forget_closed_tab() {
- yield forgetTabHelper(() => {
- ss.forgetClosedTab(window, 0);
- });
-});
-
-/**
- * Tests that if we choose to forget a tab while waiting for its
- * final flush to complete, we don't accidentally store it.
- */
-add_task(function* test_forget_closed_window() {
- yield forgetWinHelper(() => {
- ss.forgetClosedWindow(0);
- });
-});
-
-/**
- * Tests that if we choose to purge history while waiting for a
- * final flush of a tab to complete, we don't accidentally store it.
- */
-add_task(function* test_forget_purged_tab() {
- yield forgetTabHelper(() => {
- Services.obs.notifyObservers(null, "browser:purge-session-history", 0);
- });
-});
-
-/**
- * Tests that if we choose to purge history while waiting for a
- * final flush of a window to complete, we don't accidentally
- * store it.
- */
-add_task(function* test_forget_purged_window() {
- yield forgetWinHelper(() => {
- Services.obs.notifyObservers(null, "browser:purge-session-history", 0);
- });
-});
diff --git a/browser/components/sessionstore/test/browser_form_restore_events.js b/browser/components/sessionstore/test/browser_form_restore_events.js
deleted file mode 100644
index 3fc2e0fd4..000000000
--- a/browser/components/sessionstore/test/browser_form_restore_events.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_form_restore_events_sample.html";
-
-/**
- * Originally a test for Bug 476161, but then expanded to include all input
- * types in bug 640136.
- */
-add_task(function () {
- // Load a page with some form elements.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // text fields
- yield setInputValue(browser, {id: "modify01", value: Math.random()});
- yield setInputValue(browser, {id: "modify02", value: Date.now()});
-
- // textareas
- yield setInputValue(browser, {id: "modify03", value: Math.random()});
- yield setInputValue(browser, {id: "modify04", value: Date.now()});
-
- // file
- let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
- yield setInputValue(browser, {id: "modify05", value: file.path});
-
- // select
- yield setSelectedIndex(browser, {id: "modify06", index: 1});
- yield setMultipleSelected(browser, {id: "modify07", indices: [0,1,2]});
-
- // checkbox
- yield setInputChecked(browser, {id: "modify08", checked: true});
- yield setInputChecked(browser, {id: "modify09", checked: false});
-
- // radio
- yield setInputChecked(browser, {id: "modify10", checked: true});
- yield setInputChecked(browser, {id: "modify11", checked: true});
-
- // Duplicate the tab and check that restoring form data yields the expected
- // input and change events for modified form fields.
- let tab2 = gBrowser.duplicateTab(tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- let inputFired = yield getTextContent(browser2, {id: "inputFired"});
- inputFired = inputFired.trim().split().sort().join(" ");
-
- let changeFired = yield getTextContent(browser2, {id: "changeFired"});
- changeFired = changeFired.trim().split().sort().join(" ");
-
- is(inputFired, "modify01 modify02 modify03 modify04 modify05",
- "input events were only dispatched for modified input, textarea fields");
-
- is(changeFired, "modify06 modify07 modify08 modify09 modify11",
- "change events were only dispatched for modified select, checkbox, radio fields");
-
- // Cleanup.
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_form_restore_events_sample.html b/browser/components/sessionstore/test/browser_form_restore_events_sample.html
deleted file mode 100644
index 1d46d4040..000000000
--- a/browser/components/sessionstore/test/browser_form_restore_events_sample.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Test for form restore events (originally bug 476161)</title>
-
-<script>
-
-document.addEventListener("input", function(aEvent) {
- var inputEl = aEvent.originalTarget;
- var changedEl = document.getElementById("inputFired");
- changedEl.textContent += " " + inputEl.id;
-}, false);
-
-document.addEventListener("change", function(aEvent) {
- var inputEl = aEvent.originalTarget;
- var changedEl = document.getElementById("changeFired");
- changedEl.textContent += " " + inputEl.id;
-}, false);
-
-</script>
-
-<!-- input events -->
-<h3>Text fields with changed text</h3>
-<input type="text" id="modify1">
-<input type="text" id="modify2" value="preset value">
-<input type="text" id="modify01">
-<input type="text" id="modify02" value="preset value">
-
-<h3>Text fields with unchanged text</h3>
-<input type="text" id="unchanged1">
-<input type="text" id="unchanged2" value="preset value">
-<input type="text" id="unchanged01">
-<input type="text" id="unchanged02" value="preset value">
-
-<h3>Textarea with changed text</h3>
-<textarea id="modify03"></textarea>
-<textarea id="modify04">preset value</textarea>
-
-<h3>Textarea with unchanged text</h3>
-<textarea id="unchanged03"></textarea>
-<textarea id="unchanged04">preset value</textarea>
-
-<h3>file field with changed value</h3>
-<input type="file" id="modify05">
-
-<h3>file field with unchanged value</h3>
-<input type="file" id="unchanged05">
-
-<!-- change events -->
-
-<h3>Select menu with changed selection</h3>
-<select id="modify06">
- <option value="one">one</option>
- <option value="two">two</option>
- <option value="three">three</option>
-</select>
-
-<h3>Select menu with unchanged selection (change event still fires)</h3>
-<select id="unchanged06">
- <option value="one">one</option>
- <option value="two" selected>two</option>
- <option value="three">three</option>
-</select>
-
-<h3>Multiple Select menu with changed selection</h3>
-<select id="modify07" multiple>
- <option value="one">one</option>
- <option value="two" selected>two</option>
- <option value="three">three</option>
-</select>
-
-<h3>Select menu with unchanged selection</h3>
-<select id="unchanged07" multiple>
- <option value="one">one</option>
- <option value="two" selected>two</option>
- <option value="three" selected>three</option>
-</select>
-
-<h3>checkbox with changed value</h3>
-<input type="checkbox" id="modify08">
-<input type="checkbox" id="modify09" checked>
-
-<h3>checkbox with unchanged value</h3>
-<input type="checkbox" id="unchanged08">
-<input type="checkbox" id="unchanged09" checked>
-
-<h3>radio with changed value</h3>
-<input type="radio" id="modify10" name="group">Radio 1</input>
-<input type="radio" id="modify11" name="group">Radio 2</input>
-<input type="radio" id="modify12" name="group" checked>Radio 3</input>
-
-<h3>radio with unchanged value</h3>
-<input type="radio" id="unchanged10" name="group2">Radio 4</input>
-<input type="radio" id="unchanged11" name="group2">Radio 5</input>
-<input type="radio" id="unchanged12" name="group2" checked>Radio 6</input>
-
-<h3>Changed field IDs</h3>
-<div id="changed"></div>
-<div id="inputFired"></div>
-<div id="changeFired"></div>
diff --git a/browser/components/sessionstore/test/browser_formdata.js b/browser/components/sessionstore/test/browser_formdata.js
deleted file mode 100644
index ce1272888..000000000
--- a/browser/components/sessionstore/test/browser_formdata.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-/**
- * This test ensures that form data collection respects the privacy level as
- * set by the user.
- */
-add_task(function test_formdata() {
- const URL = "http://mochi.test:8888/browser/browser/components/" +
- "sessionstore/test/browser_formdata_sample.html";
-
- const OUTER_VALUE = "browser_formdata_" + Math.random();
- const INNER_VALUE = "browser_formdata_" + Math.random();
-
- // Creates a tab, loads a page with some form fields,
- // modifies their values and closes the tab.
- function createAndRemoveTab() {
- return Task.spawn(function () {
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Modify form data.
- yield setInputValue(browser, {id: "txt", value: OUTER_VALUE});
- yield setInputValue(browser, {id: "txt", value: INNER_VALUE, frame: 0});
-
- // Remove the tab.
- yield promiseRemoveTab(tab);
- });
- }
-
- yield createAndRemoveTab();
- let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
- is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
- is(formdata.children[0].id.txt, INNER_VALUE, "inner value is correct");
-
- // Disable saving data for encrypted sites.
- Services.prefs.setIntPref("browser.sessionstore.privacy_level", 1);
-
- yield createAndRemoveTab();
- [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
- is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
- ok(!formdata.children, "inner value was *not* stored");
-
- // Disable saving data for any site.
- Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2);
-
- yield createAndRemoveTab();
- [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
- ok(!formdata, "form data has *not* been stored");
-
- // Restore the default privacy level.
- Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
-});
-
-/**
- * This test ensures that a malicious website can't trick us into restoring
- * form data into a wrong website and that we always check the stored URL
- * before doing so.
- */
-add_task(function test_url_check() {
- const URL = "data:text/html;charset=utf-8,<input%20id=input>";
- const VALUE = "value-" + Math.random();
-
- // Create a tab with an iframe containing an input field.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Restore a tab state with a given form data url.
- function restoreStateWithURL(url) {
- let state = {entries: [{url: URL}], formdata: {id: {input: VALUE}}};
-
- if (url) {
- state.formdata.url = url;
- }
-
- return promiseTabState(tab, state).then(() => getInputValue(browser, "input"));
- }
-
- // Check that the form value is restored with the correct URL.
- is((yield restoreStateWithURL(URL)), VALUE, "form data restored");
-
- // Check that the form value is *not* restored with the wrong URL.
- is((yield restoreStateWithURL(URL + "?")), "", "form data not restored");
- is((yield restoreStateWithURL()), "", "form data not restored");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * This test ensures that collecting form data works as expected when having
- * nested frame sets.
- */
-add_task(function test_nested() {
- const URL = "data:text/html;charset=utf-8," +
- "<iframe src='data:text/html;charset=utf-8," +
- "<input autofocus=true>'/>";
-
- const FORM_DATA = {
- children: [{
- xpath: {"/xhtml:html/xhtml:body/xhtml:input": "M"},
- url: "data:text/html;charset=utf-8,<input%20autofocus=true>"
- }]
- };
-
- // Create a tab with an iframe containing an input field.
- let tab = gBrowser.selectedTab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Modify the input field's value.
- yield sendMessage(browser, "ss-test:sendKeyEvent", {key: "m", frame: 0});
-
- // Remove the tab and check that we stored form data correctly.
- yield promiseRemoveTab(tab);
- let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
- is(JSON.stringify(formdata), JSON.stringify(FORM_DATA),
- "formdata for iframe stored correctly");
-
- // Restore the closed tab.
- tab = ss.undoCloseTab(window, 0);
- browser = tab.linkedBrowser;
- yield promiseTabRestored(tab);
-
- // Check that the input field has the right value.
- yield TabStateFlusher.flush(browser);
- ({formdata} = JSON.parse(ss.getTabState(tab)));
- is(JSON.stringify(formdata), JSON.stringify(FORM_DATA),
- "formdata for iframe restored correctly");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * This test ensures that collecting form data for documents with
- * designMode=on works as expected.
- */
-add_task(function test_design_mode() {
- const URL = "data:text/html;charset=utf-8,<h1>mozilla</h1>" +
- "<script>document.designMode='on'</script>";
-
- // Load a tab with an editable document.
- let tab = gBrowser.selectedTab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Modify the document content.
- yield sendMessage(browser, "ss-test:sendKeyEvent", {key: "m"});
-
- // Close and restore the tab.
- yield promiseRemoveTab(tab);
- tab = ss.undoCloseTab(window, 0);
- browser = tab.linkedBrowser;
- yield promiseTabRestored(tab);
-
- // Check that the innerHTML value was restored.
- let html = yield getInnerHTML(browser);
- let expected = "<h1>Mmozilla</h1><script>document.designMode='on'</script>";
- is(html, expected, "editable document has been restored correctly");
-
- // Close and restore the tab.
- yield promiseRemoveTab(tab);
- tab = ss.undoCloseTab(window, 0);
- browser = tab.linkedBrowser;
- yield promiseTabRestored(tab);
-
- // Check that the innerHTML value was restored.
- html = yield getInnerHTML(browser);
- expected = "<h1>Mmozilla</h1><script>document.designMode='on'</script>";
- is(html, expected, "editable document has been restored correctly");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-function getInputValue(browser, id) {
- return sendMessage(browser, "ss-test:getInputValue", {id: id});
-}
-
-function setInputValue(browser, data) {
- return sendMessage(browser, "ss-test:setInputValue", data);
-}
-
-function getInnerHTML(browser) {
- return sendMessage(browser, "ss-test:getInnerHTML", {selector: "body"});
-}
diff --git a/browser/components/sessionstore/test/browser_formdata_cc.js b/browser/components/sessionstore/test/browser_formdata_cc.js
deleted file mode 100644
index 6e27ca970..000000000
--- a/browser/components/sessionstore/test/browser_formdata_cc.js
+++ /dev/null
@@ -1,79 +0,0 @@
-"use strict";
-
-const URL = "http://mochi.test:8888/browser/browser/components/" +
- "sessionstore/test/browser_formdata_sample.html";
-
-requestLongerTimeout(3);
-
-/**
- * This test ensures that credit card numbers in form data will not be
- * collected, while numbers that don't look like credit card numbers will
- * still be collected.
- */
-add_task(function* () {
- const validCCNumbers = [
- // 15 digits
- "930771457288760", "474915027480942",
- "924894781317325", "714816113937185",
- "790466087343106", "474320195408363",
- "219211148122351", "633038472250799",
- "354236732906484", "095347810189325",
- // 16 digits
- "3091269135815020", "5471839082338112",
- "0580828863575793", "5015290610002932",
- "9465714503078607", "4302068493801686",
- "2721398408985465", "6160334316984331",
- "8643619970075142", "0218246069710785"
- ];
-
- const invalidCCNumbers = [
- // 15 digits
- "526931005800649", "724952425140686",
- "379761391174135", "030551436468583",
- "947377014076746", "254848023655752",
- "226871580283345", "708025346034339",
- "917585839076788", "918632588027666",
- // 16 digits
- "9946177098017064", "4081194386488872",
- "3095975979578034", "3662215692222536",
- "6723210018630429", "4411962856225025",
- "8276996369036686", "4449796938248871",
- "3350852696538147", "5011802870046957"
- ];
-
- // Creates a tab, loads a page with a form field, sets the value of the
- // field, and then removes the tab to trigger data collection.
- function* createAndRemoveTab(formValue) {
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Set form value.
- yield setInputValue(browser, formValue);
-
- // Remove the tab.
- yield promiseRemoveTab(tab);
- }
-
- // Test that valid CC numbers are not collected.
- for (let number of validCCNumbers) {
- yield createAndRemoveTab(number);
- let [{state}] = JSON.parse(ss.getClosedTabData(window));
- ok(!("formdata" in state), "valid CC numbers are not collected");
- }
-
- // Test that non-CC numbers are still collected.
- for (let number of invalidCCNumbers) {
- yield createAndRemoveTab(number);
- let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
- is(formdata.id.txt, number,
- "numbers that are not valid CC numbers are still collected");
- }
-});
-
-function setInputValue(browser, formValue) {
- return ContentTask.spawn(browser, formValue, function* (formValue) {
- content.document.getElementById("txt").setUserInput(formValue);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_formdata_format.js b/browser/components/sessionstore/test/browser_formdata_format.js
deleted file mode 100644
index 6a1b5975d..000000000
--- a/browser/components/sessionstore/test/browser_formdata_format.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-function test() {
- /** Tests formdata format **/
- waitForExplicitFinish();
-
- let formData = [
- { },
- // old format
- { "#input1" : "value0" },
- { "#input1" : "value1", "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value2" },
- { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value3" },
- // new format
- { id: { "input1" : "value4" } },
- { id: { "input1" : "value5" }, xpath: {} },
- { id: { "input1" : "value6" }, xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value7" } },
- { id: {}, xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value8" } },
- { xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value9" } },
- // combinations
- { "#input1" : "value10", id: { "input1" : "value11" } },
- { "#input1" : "value12", id: { "input1" : "value13" }, xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value14" } },
- { "#input1" : "value15", xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value16" } },
- { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value17", id: { "input1" : "value18" } },
- { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value19", id: { "input1" : "value20" }, xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value21" } },
- { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value22", xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value23" } },
- { "#input1" : "value24", "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value25", id: { "input1" : "value26" } },
- { "#input1" : "value27", "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value28", id: { "input1" : "value29" }, xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value30" } },
- { "#input1" : "value31", "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value32", xpath: { "/xhtml:html/xhtml:body/xhtml:input[@name='input2']" : "value33" } }
- ]
- let expectedValues = [
- [ "" , "" ],
- // old format
- [ "value0", "" ],
- [ "value1", "value2" ],
- [ "", "value3" ],
- // new format
- [ "value4", "" ],
- [ "value5", "" ],
- [ "value6", "value7" ],
- [ "", "value8" ],
- [ "", "value9" ],
- // combinations
- [ "value11", "" ],
- [ "value13", "value14" ],
- [ "", "value16" ],
- [ "value18", "" ],
- [ "value20", "value21" ],
- [ "", "value23" ],
- [ "value26", "" ],
- [ "value29", "value30" ],
- [ "", "value33" ]
- ];
- let testTabCount = 0;
- let callback = function() {
- testTabCount--;
- if (testTabCount == 0) {
- finish();
- }
- };
-
- for (let i = 0; i < formData.length; i++) {
- testTabCount++;
- testTabRestoreData(formData[i], expectedValues[i], callback);
- }
-}
-
-function testTabRestoreData(aFormData, aExpectedValue, aCallback) {
- let URL = ROOT + "browser_formdata_format_sample.html";
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
-
- aFormData.url = URL;
- let tabState = { entries: [{ url: URL }], formdata: aFormData };
-
- Task.spawn(function () {
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield promiseTabState(tab, tabState);
-
- yield TabStateFlusher.flush(tab.linkedBrowser);
- let restoredTabState = JSON.parse(ss.getTabState(tab));
- let restoredFormData = restoredTabState.formdata;
-
- if (restoredFormData) {
- let doc = tab.linkedBrowser.contentDocument;
- let input1 = doc.getElementById("input1");
- let input2 = doc.querySelector("input[name=input2]");
-
- // test format
- ok("id" in restoredFormData || "xpath" in restoredFormData,
- "FormData format is valid: " + restoredFormData);
- // validate that there are no old keys
- for (let key of Object.keys(restoredFormData)) {
- if (["id", "xpath", "url"].indexOf(key) === -1) {
- ok(false, "FormData format is invalid.");
- }
- }
- // test id
- is(input1.value, aExpectedValue[0],
- "FormData by 'id' has been restored correctly");
- // test xpath
- is(input2.value, aExpectedValue[1],
- "FormData by 'xpath' has been restored correctly");
- }
-
- // clean up
- gBrowser.removeTab(tab);
-
- // This test might time out if the task fails.
- }).then(aCallback);
-}
diff --git a/browser/components/sessionstore/test/browser_formdata_format_sample.html b/browser/components/sessionstore/test/browser_formdata_format_sample.html
deleted file mode 100644
index f991e3657..000000000
--- a/browser/components/sessionstore/test/browser_formdata_format_sample.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<title>Test formdata format</title>
-
-<!-- input events -->
-<h3>Input fields</h3>
-<input type="text" id="input1">
-<input type="text" name="input2"> \ No newline at end of file
diff --git a/browser/components/sessionstore/test/browser_formdata_sample.html b/browser/components/sessionstore/test/browser_formdata_sample.html
deleted file mode 100644
index 6cbb54fb5..000000000
--- a/browser/components/sessionstore/test/browser_formdata_sample.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>browser_formdata_sample.html</title>
- </head>
- <body>
- <input id="txt" />
-
- <script type="text/javascript;version=1.8">
- let isOuter = window == window.top;
-
- if (isOuter) {
- let iframe = document.createElement("iframe");
- iframe.setAttribute("src", "https://example.com" + location.pathname);
- document.body.appendChild(iframe);
- }
- </script>
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_formdata_xpath.js b/browser/components/sessionstore/test/browser_formdata_xpath.js
deleted file mode 100644
index d69feb546..000000000
--- a/browser/components/sessionstore/test/browser_formdata_xpath.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = ROOT + "browser_formdata_xpath_sample.html";
-
-/**
- * Bug 346337 - Generic form data restoration tests.
- */
-add_task(function setup() {
- // make sure we don't save form data at all (except for tab duplication)
- Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2);
-
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
- });
-});
-
-const FILE1 = createFilePath("346337_test1.file");
-const FILE2 = createFilePath("346337_test2.file");
-
-const FIELDS = {
- "//input[@name='input']": Date.now().toString(),
- "//input[@name='spaced 1']": Math.random().toString(),
- "//input[3]": "three",
- "//input[@type='checkbox']": true,
- "//input[@name='uncheck']": false,
- "//input[@type='radio'][1]": false,
- "//input[@type='radio'][2]": true,
- "//input[@type='radio'][3]": false,
- "//select": 2,
- "//select[@multiple]": [1, 3],
- "//textarea[1]": "",
- "//textarea[2]": "Some text... " + Math.random(),
- "//textarea[3]": "Some more text\n" + new Date(),
- "//input[@type='file'][1]": [FILE1],
- "//input[@type='file'][2]": [FILE1, FILE2]
-};
-
-add_task(function test_form_data_restoration() {
- // Load page with some input fields.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Fill in some values.
- for (let xpath of Object.keys(FIELDS)) {
- yield setFormValue(browser, xpath);
- }
-
- // Duplicate the tab.
- let tab2 = gBrowser.duplicateTab(tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- // Check that all form values have been duplicated.
- for (let xpath of Object.keys(FIELDS)) {
- let expected = JSON.stringify(FIELDS[xpath]);
- let actual = JSON.stringify(yield getFormValue(browser2, xpath));
- is(actual, expected, "The value for \"" + xpath + "\" was correctly restored");
- }
-
- // Remove all tabs.
- yield promiseRemoveTab(tab2);
- yield promiseRemoveTab(tab);
-
- // Restore one of the tabs again.
- tab = ss.undoCloseTab(window, 0);
- browser = tab.linkedBrowser;
- yield promiseTabRestored(tab);
-
- // Check that none of the form values have been restored due to the privacy
- // level settings.
- for (let xpath of Object.keys(FIELDS)) {
- let expected = FIELDS[xpath];
- if (expected) {
- let actual = yield getFormValue(browser, xpath, expected);
- isnot(actual, expected, "The value for \"" + xpath + "\" was correctly discarded");
- }
- }
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
-
-function createFilePath(leaf) {
- let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
- file.append(leaf);
- return file.path;
-}
-
-function isArrayOfNumbers(value) {
- return Array.isArray(value) && value.every(n => typeof(n) === "number");
-}
-
-function isArrayOfStrings(value) {
- return Array.isArray(value) && value.every(n => typeof(n) === "string");
-}
-
-function getFormValue(browser, xpath) {
- let value = FIELDS[xpath];
-
- if (typeof value == "string") {
- return getInputValue(browser, {xpath: xpath});
- }
-
- if (typeof value == "boolean") {
- return getInputChecked(browser, {xpath: xpath});
- }
-
- if (typeof value == "number") {
- return getSelectedIndex(browser, {xpath: xpath});
- }
-
- if (isArrayOfNumbers(value)) {
- return getMultipleSelected(browser, {xpath: xpath});
- }
-
- if (isArrayOfStrings(value)) {
- return getFileNameArray(browser, {xpath: xpath});
- }
-
- throw new Error("unknown input type");
-}
-
-function setFormValue(browser, xpath) {
- let value = FIELDS[xpath];
-
- if (typeof value == "string") {
- return setInputValue(browser, {xpath: xpath, value: value});
- }
-
- if (typeof value == "boolean") {
- return setInputChecked(browser, {xpath: xpath, checked: value});
- }
-
- if (typeof value == "number") {
- return setSelectedIndex(browser, {xpath: xpath, index: value});
- }
-
- if (isArrayOfNumbers(value)) {
- return setMultipleSelected(browser, {xpath: xpath, indices: value});
- }
-
- if (isArrayOfStrings(value)) {
- return setFileNameArray(browser, {xpath: xpath, names: value});
- }
-
- throw new Error("unknown input type");
-}
diff --git a/browser/components/sessionstore/test/browser_formdata_xpath_sample.html b/browser/components/sessionstore/test/browser_formdata_xpath_sample.html
deleted file mode 100644
index 682162d6a..000000000
--- a/browser/components/sessionstore/test/browser_formdata_xpath_sample.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<title>Test for bug 346337</title>
-
-<h3>Text Fields</h3>
-<input type="text" name="input">
-<input type="text" name="spaced 1">
-<input>
-
-<h3>Checkboxes and Radio buttons</h3>
-<input type="checkbox" name="check"> Check 1
-<input type="checkbox" name="uncheck" checked> Check 2
-<p>
-<input type="radio" name="group" value="1"> Radio 1
-<input type="radio" name="group" value="some"> Radio 2
-<input type="radio" name="group" checked> Radio 3
-
-<h3>Selects</h3>
-<select name="any">
- <option value="1"> Select 1
- <option value="some"> Select 2
- <option>Select 3
-</select>
-<select multiple="multiple">
- <option value=1> Multi-select 1
- <option value=2> Multi-select 2
- <option value=3> Multi-select 3
- <option value=4> Multi-select 4
-</select>
-
-<h3>Text Areas</h3>
-<textarea name="testarea"></textarea>
-<textarea name="sized one" rows="5" cols="25"></textarea>
-<textarea></textarea>
-
-<h3>File Selector</h3>
-<input type="file">
-<input type="file" multiple>
diff --git a/browser/components/sessionstore/test/browser_frame_history.js b/browser/components/sessionstore/test/browser_frame_history.js
deleted file mode 100644
index e0d152f77..000000000
--- a/browser/components/sessionstore/test/browser_frame_history.js
+++ /dev/null
@@ -1,170 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- Ensure that frameset history works properly when restoring a tab,
- provided that the frameset is static.
- */
-
-// Loading a toplevel frameset
-add_task(function() {
- let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index.html";
- let tab = gBrowser.addTab(testURL);
- gBrowser.selectedTab = tab;
-
- info("Opening a page with three frames, 4 loads should take place");
- yield waitForLoadsInBrowser(tab.linkedBrowser, 4);
-
- let browser_b = tab.linkedBrowser.contentDocument.getElementsByTagName("frame")[1];
- let document_b = browser_b.contentDocument;
- let links = document_b.getElementsByTagName("a");
-
- // We're going to click on the first link, so listen for another load event
- info("Clicking on link 1, 1 load should take place");
- let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
- EventUtils.sendMouseEvent({type:"click"}, links[0], browser_b.contentWindow);
- yield promise;
-
- info("Clicking on link 2, 1 load should take place");
- promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
- EventUtils.sendMouseEvent({type:"click"}, links[1], browser_b.contentWindow);
- yield promise;
-
- info("Close then un-close page, 4 loads should take place");
- yield promiseRemoveTab(tab);
- let newTab = ss.undoCloseTab(window, 0);
- yield waitForLoadsInBrowser(newTab.linkedBrowser, 4);
-
- info("Go back in time, 1 load should take place");
- gBrowser.goBack();
- yield waitForLoadsInBrowser(newTab.linkedBrowser, 1);
-
- let expectedURLEnds = ["a.html", "b.html", "c1.html"];
- let frames = newTab.linkedBrowser.contentDocument.getElementsByTagName("frame");
- for (let i = 0; i < frames.length; i++) {
- is(frames[i].contentDocument.location,
- getRootDirectory(gTestPath) + "browser_frame_history_" + expectedURLEnds[i],
- "frame " + i + " has the right url");
- }
- gBrowser.removeTab(newTab);
-});
-
-// Loading the frameset inside an iframe
-add_task(function() {
- let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index2.html";
- let tab = gBrowser.addTab(testURL);
- gBrowser.selectedTab = tab;
-
- info("iframe: Opening a page with an iframe containing three frames, 5 loads should take place");
- yield waitForLoadsInBrowser(tab.linkedBrowser, 5);
-
- let browser_b = tab.linkedBrowser.contentDocument.
- getElementById("iframe").contentDocument.
- getElementsByTagName("frame")[1];
- let document_b = browser_b.contentDocument;
- let links = document_b.getElementsByTagName("a");
-
- // We're going to click on the first link, so listen for another load event
- info("iframe: Clicking on link 1, 1 load should take place");
- let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
- EventUtils.sendMouseEvent({type:"click"}, links[0], browser_b.contentWindow);
- yield promise;
-
- info("iframe: Clicking on link 2, 1 load should take place");
- promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
- EventUtils.sendMouseEvent({type:"click"}, links[1], browser_b.contentWindow);
- yield promise;
-
- info("iframe: Close then un-close page, 5 loads should take place");
- yield promiseRemoveTab(tab);
- let newTab = ss.undoCloseTab(window, 0);
- yield waitForLoadsInBrowser(newTab.linkedBrowser, 5);
-
- info("iframe: Go back in time, 1 load should take place");
- gBrowser.goBack();
- yield waitForLoadsInBrowser(newTab.linkedBrowser, 1);
-
- let expectedURLEnds = ["a.html", "b.html", "c1.html"];
- let frames = newTab.linkedBrowser.contentDocument.
- getElementById("iframe").contentDocument.
- getElementsByTagName("frame");
- for (let i = 0; i < frames.length; i++) {
- is(frames[i].contentDocument.location,
- getRootDirectory(gTestPath) + "browser_frame_history_" + expectedURLEnds[i],
- "frame " + i + " has the right url");
- }
- gBrowser.removeTab(newTab);
-});
-
-// Now, test that we don't record history if the iframe is added dynamically
-add_task(function() {
- // Start with an empty history
- let blankState = JSON.stringify({
- windows: [{
- tabs: [{ entries: [{ url: "about:blank" }] }],
- _closedTabs: []
- }],
- _closedWindows: []
- });
- ss.setBrowserState(blankState);
-
- let testURL = getRootDirectory(gTestPath) + "browser_frame_history_index_blank.html";
- let tab = gBrowser.addTab(testURL);
- gBrowser.selectedTab = tab;
- yield waitForLoadsInBrowser(tab.linkedBrowser, 1);
-
- info("dynamic: Opening a page with an iframe containing three frames, 4 dynamic loads should take place");
- let doc = tab.linkedBrowser.contentDocument;
- let iframe = doc.createElement("iframe");
- iframe.id = "iframe";
- iframe.src="browser_frame_history_index.html";
- doc.body.appendChild(iframe);
- yield waitForLoadsInBrowser(tab.linkedBrowser, 4);
-
- let browser_b = tab.linkedBrowser.contentDocument.
- getElementById("iframe").contentDocument.
- getElementsByTagName("frame")[1];
- let document_b = browser_b.contentDocument;
- let links = document_b.getElementsByTagName("a");
-
- // We're going to click on the first link, so listen for another load event
- info("dynamic: Clicking on link 1, 1 load should take place");
- let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
- EventUtils.sendMouseEvent({type:"click"}, links[0], browser_b.contentWindow);
- yield promise;
-
- info("dynamic: Clicking on link 2, 1 load should take place");
- promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
- EventUtils.sendMouseEvent({type:"click"}, links[1], browser_b.contentWindow);
- yield promise;
-
- info("Check in the state that we have not stored this history");
- let state = ss.getBrowserState();
- info(JSON.stringify(JSON.parse(state), null, "\t"));
- is(state.indexOf("c1.html"), -1, "History entry was not stored in the session state");;
- gBrowser.removeTab(tab);
-});
-
-// helper functions
-function waitForLoadsInBrowser(aBrowser, aLoadCount) {
- let deferred = Promise.defer();
- let loadCount = 0;
- aBrowser.addEventListener("load", function(aEvent) {
- if (++loadCount < aLoadCount) {
- info("Got " + loadCount + " loads, waiting until we have " + aLoadCount);
- return;
- }
-
- aBrowser.removeEventListener("load", arguments.callee, true);
- deferred.resolve();
- }, true);
- return deferred.promise;
-}
-
-function timeout(delay, task) {
- let deferred = Promise.defer();
- setTimeout(() => deferred.resolve(true), delay);
- task.then(() => deferred.resolve(false), deferred.reject);
- return deferred.promise;
-}
diff --git a/browser/components/sessionstore/test/browser_frame_history_a.html b/browser/components/sessionstore/test/browser_frame_history_a.html
deleted file mode 100755
index 8e7b35d7a..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_a.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
- <body>
- I'm A!
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_frame_history_b.html b/browser/components/sessionstore/test/browser_frame_history_b.html
deleted file mode 100755
index 38b43da21..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_b.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
- <body>
- I'm B!<br/>
- <a target="c" href="browser_frame_history_c1.html">click me first</a><br/>
- <a target="c" href="browser_frame_history_c2.html">then click me</a><br/>
- Close this tab.<br/>
- Restore this tab.<br/>
- Click back.<br/>
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_frame_history_c.html b/browser/components/sessionstore/test/browser_frame_history_c.html
deleted file mode 100755
index 0efd7d902..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_c.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
- <body>
- I'm C!
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_frame_history_c1.html b/browser/components/sessionstore/test/browser_frame_history_c1.html
deleted file mode 100755
index b55c1d45a..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_c1.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
- <body>
- I'm C1!
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_frame_history_c2.html b/browser/components/sessionstore/test/browser_frame_history_c2.html
deleted file mode 100755
index aec504141..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_c2.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
- <body>
- I'm C2!
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_frame_history_index.html b/browser/components/sessionstore/test/browser_frame_history_index.html
deleted file mode 100644
index 76eeb4c4d..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_index.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
- <frameset cols="20%,80%">
- <frameset rows="30%,70%">
- <frame src="browser_frame_history_a.html"/>
- <frame src="browser_frame_history_b.html"/>
- </frameset>
- <frame src="browser_frame_history_c.html" name="c"/>
- </frameset>
-</html>
-
diff --git a/browser/components/sessionstore/test/browser_frame_history_index2.html b/browser/components/sessionstore/test/browser_frame_history_index2.html
deleted file mode 100644
index e4dfb4083..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_index2.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<html>
- <iframe src="browser_frame_history_index.html" id="iframe" />
-</html>
-
diff --git a/browser/components/sessionstore/test/browser_frame_history_index_blank.html b/browser/components/sessionstore/test/browser_frame_history_index_blank.html
deleted file mode 100644
index 30fd1f58c..000000000
--- a/browser/components/sessionstore/test/browser_frame_history_index_blank.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
- <body>
- </body>
-</html>
-
diff --git a/browser/components/sessionstore/test/browser_frametree.js b/browser/components/sessionstore/test/browser_frametree.js
deleted file mode 100644
index a342f8c66..000000000
--- a/browser/components/sessionstore/test/browser_frametree.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = HTTPROOT + "browser_frametree_sample.html";
-const URL_FRAMESET = HTTPROOT + "browser_frametree_sample_frameset.html";
-
-/**
- * This ensures that loading a page normally, aborting a page load, reloading
- * a page, navigating using the bfcache, and ignoring frames that were
- * created dynamically work as expect. We expect the frame tree to be reset
- * when a page starts loading and we also expect a valid frame tree to exist
- * when it has stopped loading.
- */
-add_task(function test_frametree() {
- const FRAME_TREE_SINGLE = { href: URL };
- const FRAME_TREE_FRAMESET = {
- href: URL_FRAMESET,
- children: [{href: URL}, {href: URL}, {href: URL}]
- };
-
- // Create a tab with a single frame.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseNewFrameTree(browser);
- yield checkFrameTree(browser, FRAME_TREE_SINGLE,
- "loading a page resets and creates the frame tree correctly");
-
- // Load the frameset and create two frames dynamically, the first on
- // DOMContentLoaded and the second on load.
- yield sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
- browser.loadURI(URL_FRAMESET);
- yield promiseNewFrameTree(browser);
- yield checkFrameTree(browser, FRAME_TREE_FRAMESET,
- "dynamic frames created on or after the load event are ignored");
-
- // Go back to the previous single-frame page. There will be no load event as
- // the page is still in the bfcache. We thus make sure this type of navigation
- // resets the frame tree.
- browser.goBack();
- yield promiseNewFrameTree(browser);
- yield checkFrameTree(browser, FRAME_TREE_SINGLE,
- "loading from bfache resets and creates the frame tree correctly");
-
- // Load the frameset again but abort the load early.
- // The frame tree should still be reset and created.
- browser.loadURI(URL_FRAMESET);
- executeSoon(() => browser.stop());
- yield promiseNewFrameTree(browser);
-
- // Load the frameset and check the tree again.
- yield sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
- browser.loadURI(URL_FRAMESET);
- yield promiseNewFrameTree(browser);
- yield checkFrameTree(browser, FRAME_TREE_FRAMESET,
- "reloading a page resets and creates the frame tree correctly");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * This test ensures that we ignore frames that were created dynamically at or
- * after the load event. SessionStore can't handle these and will not restore
- * or collect any data for them.
- */
-add_task(function test_frametree_dynamic() {
- // The frame tree as expected. The first two frames are static
- // and the third one was created on DOMContentLoaded.
- const FRAME_TREE = {
- href: URL_FRAMESET,
- children: [{href: URL}, {href: URL}, {href: URL}]
- };
- const FRAME_TREE_REMOVED = {
- href: URL_FRAMESET,
- children: [{href: URL}, {href: URL}]
- };
-
- // Add an empty tab for a start.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Create dynamic frames on "DOMContentLoaded" and on "load".
- yield sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
- browser.loadURI(URL_FRAMESET);
- yield promiseNewFrameTree(browser);
-
- // Check that the frame tree does not contain the frame created on "load".
- // The two static frames and the one created on DOMContentLoaded must be in
- // the tree.
- yield checkFrameTree(browser, FRAME_TREE,
- "frame tree contains first four frames");
-
- // Remove the last frame in the frameset.
- yield sendMessage(browser, "ss-test:removeLastFrame", {id: "frames"});
- // Check that the frame tree didn't change.
- yield checkFrameTree(browser, FRAME_TREE,
- "frame tree contains first four frames");
-
- // Remove the last frame in the frameset.
- yield sendMessage(browser, "ss-test:removeLastFrame", {id: "frames"});
- // Check that the frame tree excludes the removed frame.
- yield checkFrameTree(browser, FRAME_TREE_REMOVED,
- "frame tree contains first three frames");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Checks whether the current frame hierarchy of a given |browser| matches the
- * |expected| frame hierarchy.
- */
-function checkFrameTree(browser, expected, msg) {
- return sendMessage(browser, "ss-test:mapFrameTree").then(tree => {
- is(JSON.stringify(tree), JSON.stringify(expected), msg);
- });
-}
-
-/**
- * Returns a promise that will be resolved when the given |browser| has loaded
- * and we received messages saying that its frame tree has been reset and
- * recollected.
- */
-function promiseNewFrameTree(browser) {
- let reset = promiseContentMessage(browser, "ss-test:onFrameTreeCollected");
- let collect = promiseContentMessage(browser, "ss-test:onFrameTreeCollected");
- return Promise.all([reset, collect]);
-}
diff --git a/browser/components/sessionstore/test/browser_frametree_sample.html b/browser/components/sessionstore/test/browser_frametree_sample.html
deleted file mode 100644
index dda129448..000000000
--- a/browser/components/sessionstore/test/browser_frametree_sample.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>browser_frametree_sample.html</title>
- </head>
- <body style='width: 100000px; height: 100000px;'>top</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_frametree_sample_frameset.html b/browser/components/sessionstore/test/browser_frametree_sample_frameset.html
deleted file mode 100644
index e1cd08735..000000000
--- a/browser/components/sessionstore/test/browser_frametree_sample_frameset.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>browser_frametree_sample_frameset.html</title>
- </head>
- <frameset id="frames" rows="50%, 50%">
- <frame src="browser_frametree_sample.html">
- <frame src="browser_frametree_sample.html">
- </frameset>
-</html>
diff --git a/browser/components/sessionstore/test/browser_global_store.js b/browser/components/sessionstore/test/browser_global_store.js
deleted file mode 100644
index 792154830..000000000
--- a/browser/components/sessionstore/test/browser_global_store.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Tests the API for saving global session data.
-add_task(function* () {
- const key1 = "Unique name 1: " + Date.now();
- const key2 = "Unique name 2: " + Date.now();
- const value1 = "Unique value 1: " + Math.random();
- const value2 = "Unique value 2: " + Math.random();
-
- let global = {};
- global[key1] = value1;
-
- const testState = {
- windows: [
- {
- tabs: [
- { entries: [{ url: "about:blank" }] },
- ]
- }
- ],
- global: global
- };
-
- function testRestoredState() {
- is(ss.getGlobalValue(key1), value1, "restored state has global value");
- }
-
- function testGlobalStore() {
- is(ss.getGlobalValue(key2), "", "global value initially not set");
-
- ss.setGlobalValue(key2, value1);
- is(ss.getGlobalValue(key2), value1, "retreived value matches stored");
-
- ss.setGlobalValue(key2, value2);
- is(ss.getGlobalValue(key2), value2, "previously stored value was overwritten");
-
- ss.deleteGlobalValue(key2);
- is(ss.getGlobalValue(key2), "", "global value was deleted");
- }
-
- yield promiseBrowserState(testState);
- testRestoredState();
- testGlobalStore();
-});
diff --git a/browser/components/sessionstore/test/browser_history_persist.js b/browser/components/sessionstore/test/browser_history_persist.js
deleted file mode 100644
index 6b9e62abc..000000000
--- a/browser/components/sessionstore/test/browser_history_persist.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* eslint-env mozilla/frame-script */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * Ensure that history entries that should not be persisted are restored in the
- * same state.
- */
-add_task(function check_history_not_persisted() {
- // Create an about:blank tab
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Retrieve the tab state.
- yield TabStateFlusher.flush(browser);
- let state = JSON.parse(ss.getTabState(tab));
- ok(!state.entries[0].persist, "Should have collected the persistence state");
- yield promiseRemoveTab(tab);
- browser = null;
-
- // Open a new tab to restore into.
- tab = gBrowser.addTab("about:blank");
- browser = tab.linkedBrowser;
- yield promiseTabState(tab, state);
-
- yield ContentTask.spawn(browser, null, function() {
- let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISHistory);
-
- is(sessionHistory.count, 1, "Should be a single history entry");
- is(sessionHistory.getEntryAtIndex(0, false).URI.spec, "about:blank", "Should be the right URL");
- });
-
- // Load a new URL into the tab, it should replace the about:blank history entry
- browser.loadURI("about:robots");
- yield promiseBrowserLoaded(browser);
- yield ContentTask.spawn(browser, null, function() {
- let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISHistory);
- is(sessionHistory.count, 1, "Should be a single history entry");
- is(sessionHistory.getEntryAtIndex(0, false).URI.spec, "about:robots", "Should be the right URL");
- });
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
-
-/**
- * Check that entries default to being persisted when the attribute doesn't
- * exist
- */
-add_task(function check_history_default_persisted() {
- // Create an about:blank tab
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Retrieve the tab state.
- yield TabStateFlusher.flush(browser);
- let state = JSON.parse(ss.getTabState(tab));
- delete state.entries[0].persist;
- yield promiseRemoveTab(tab);
- browser = null;
-
- // Open a new tab to restore into.
- tab = gBrowser.addTab("about:blank");
- browser = tab.linkedBrowser;
- yield promiseTabState(tab, state);
- yield ContentTask.spawn(browser, null, function() {
- let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISHistory);
-
- is(sessionHistory.count, 1, "Should be a single history entry");
- is(sessionHistory.getEntryAtIndex(0, false).URI.spec, "about:blank", "Should be the right URL");
- });
-
- // Load a new URL into the tab, it should replace the about:blank history entry
- browser.loadURI("about:robots");
- yield promiseBrowserLoaded(browser);
- yield ContentTask.spawn(browser, null, function() {
- let sessionHistory = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISHistory);
- is(sessionHistory.count, 2, "Should be two history entries");
- is(sessionHistory.getEntryAtIndex(0, false).URI.spec, "about:blank", "Should be the right URL");
- is(sessionHistory.getEntryAtIndex(1, false).URI.spec, "about:robots", "Should be the right URL");
- });
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_label_and_icon.js b/browser/components/sessionstore/test/browser_label_and_icon.js
deleted file mode 100644
index db68eb042..000000000
--- a/browser/components/sessionstore/test/browser_label_and_icon.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci} = Components;
-
-/**
- * Make sure that tabs are restored on demand as otherwise the tab will start
- * loading immediately and we can't check its icon and label.
- */
-add_task(function setup() {
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
- });
-});
-
-/**
- * Ensure that a pending tab has label and icon correctly set.
- */
-add_task(function test_label_and_icon() {
- // Create a new tab.
- let tab = gBrowser.addTab("about:robots");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Retrieve the tab state.
- yield TabStateFlusher.flush(browser);
- let state = ss.getTabState(tab);
- yield promiseRemoveTab(tab);
- browser = null;
-
- // Open a new tab to restore into.
- tab = gBrowser.addTab("about:blank");
- ss.setTabState(tab, state);
- yield promiseTabRestoring(tab);
-
- // Check that label and icon are set for the restoring tab.
- ok(gBrowser.getIcon(tab).startsWith("data:image/png;"), "icon is set");
- is(tab.label, "Gort! Klaatu barada nikto!", "label is set");
-
- let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
- .getService(Ci.nsISerializationHelper);
- let serializedPrincipal = tab.getAttribute("iconLoadingPrincipal");
- let iconLoadingPrincipal = serhelper.deserializeObject(serializedPrincipal)
- .QueryInterface(Ci.nsIPrincipal);
- is(iconLoadingPrincipal.origin, "about:robots", "correct loadingPrincipal used");
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_merge_closed_tabs.js b/browser/components/sessionstore/test/browser_merge_closed_tabs.js
deleted file mode 100644
index b26e86f22..000000000
--- a/browser/components/sessionstore/test/browser_merge_closed_tabs.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * This test ensures that closed tabs are merged when restoring
- * a window state without overwriting tabs.
- */
-add_task(function () {
- const initialState = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:blank" }] }
- ],
- _closedTabs: [
- { state: { entries: [{ ID: 1000, url: "about:blank" }]} },
- { state: { entries: [{ ID: 1001, url: "about:blank" }]} }
- ]
- }]
- }
-
- const restoreState = {
- windows: [{
- tabs: [
- { entries: [{ url: "about:robots" }] }
- ],
- _closedTabs: [
- { state: { entries: [{ ID: 1002, url: "about:robots" }]} },
- { state: { entries: [{ ID: 1003, url: "about:robots" }]} },
- { state: { entries: [{ ID: 1004, url: "about:robots" }]} }
- ]
- }]
- }
-
- const maxTabsUndo = 4;
- gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", maxTabsUndo);
-
- // Open a new window and restore it to an initial state.
- let win = yield promiseNewWindowLoaded({private: false});
- SessionStore.setWindowState(win, JSON.stringify(initialState), true);
- is(SessionStore.getClosedTabCount(win), 2, "2 closed tabs after restoring initial state");
-
- // Restore the new state but do not overwrite existing tabs (this should
- // cause the closed tabs to be merged).
- SessionStore.setWindowState(win, JSON.stringify(restoreState), false);
-
- // Verify the windows closed tab data is correct.
- let iClosed = initialState.windows[0]._closedTabs;
- let rClosed = restoreState.windows[0]._closedTabs;
- let cData = JSON.parse(SessionStore.getClosedTabData(win));
-
- is(cData.length, Math.min(iClosed.length + rClosed.length, maxTabsUndo),
- "Number of closed tabs is correct");
-
- // When the closed tabs are merged the restored tabs are considered to be
- // closed more recently.
- for (let i = 0; i < cData.length; i++) {
- if (i < rClosed.length) {
- is(cData[i].state.entries[0].ID, rClosed[i].state.entries[0].ID,
- "Closed tab entry matches");
- } else {
- is(cData[i].state.entries[0].ID, iClosed[i - rClosed.length].state.entries[0].ID,
- "Closed tab entry matches");
- }
- }
-
- // Clean up.
- gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
- yield BrowserTestUtils.closeWindow(win);
-});
-
-
diff --git a/browser/components/sessionstore/test/browser_multiple_navigateAndRestore.js b/browser/components/sessionstore/test/browser_multiple_navigateAndRestore.js
deleted file mode 100644
index fc958b293..000000000
--- a/browser/components/sessionstore/test/browser_multiple_navigateAndRestore.js
+++ /dev/null
@@ -1,36 +0,0 @@
-"use strict";
-
-const PAGE_1 = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const PAGE_2 = "data:text/html,<html><body>Another%20regular,%20everyday,%20normal%20page.";
-
-add_task(function*() {
- // Load an empty, non-remote tab at about:blank...
- let tab = gBrowser.addTab("about:blank", {
- forceNotRemote: true,
- });
- gBrowser.selectedTab = tab;
- let browser = gBrowser.selectedBrowser;
- ok(!browser.isRemoteBrowser, "Ensure browser is not remote");
- // Load a remote page, and then another remote page immediately
- // after.
- browser.loadURI(PAGE_1);
- browser.stop();
- browser.loadURI(PAGE_2);
- yield BrowserTestUtils.browserLoaded(browser);
-
- ok(browser.isRemoteBrowser, "Should have switched remoteness");
- yield TabStateFlusher.flush(browser);
- let state = JSON.parse(ss.getTabState(tab));
- let entries = state.entries;
- is(entries.length, 1, "There should only be one entry");
- is(entries[0].url, PAGE_2, "Should have PAGE_2 as the sole history entry");
- is(browser.currentURI.spec, PAGE_2, "Should have PAGE_2 as the browser currentURI");
-
- yield ContentTask.spawn(browser, PAGE_2, function*(PAGE_2) {
- docShell.QueryInterface(Ci.nsIWebNavigation);
- Assert.equal(docShell.currentURI.spec, PAGE_2,
- "Content should have PAGE_2 as the browser currentURI");
- });
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_newtab_userTypedValue.js b/browser/components/sessionstore/test/browser_newtab_userTypedValue.js
deleted file mode 100644
index 66dc93380..000000000
--- a/browser/components/sessionstore/test/browser_newtab_userTypedValue.js
+++ /dev/null
@@ -1,72 +0,0 @@
-"use strict";
-
-requestLongerTimeout(4);
-
-/**
- * Test that when restoring an 'initial page' with session restore, it
- * produces an empty URL bar, rather than leaving its URL explicitly
- * there as a 'user typed value'.
- */
-add_task(function* () {
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:logo");
- let tabOpenedAndSwitchedTo = BrowserTestUtils.switchTab(win.gBrowser, () => {});
-
- // This opens about:newtab:
- win.BrowserOpenTab();
- let tab = yield tabOpenedAndSwitchedTo;
- is(win.gURLBar.value, "", "URL bar should be empty");
- is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
- let state = JSON.parse(SessionStore.getTabState(tab));
- ok(!state.userTypedValue, "userTypedValue should be undefined on the tab's state");
- tab = null;
-
- yield BrowserTestUtils.closeWindow(win);
-
- ok(SessionStore.getClosedWindowCount(), "Should have a closed window");
-
- win = SessionStore.undoCloseWindow(0);
- yield TestUtils.topicObserved("sessionstore-single-window-restored",
- subject => subject == win);
- // Don't wait for load here because it's about:newtab and we may have swapped in
- // a preloaded browser.
- yield TabStateFlusher.flush(win.gBrowser.selectedBrowser);
-
- is(win.gURLBar.value, "", "URL bar should be empty");
- tab = win.gBrowser.selectedTab;
- is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
- state = JSON.parse(SessionStore.getTabState(tab));
- ok(!state.userTypedValue, "userTypedValue should be undefined on the tab's state");
-
- yield BrowserTestUtils.removeTab(tab);
-
- for (let url of gInitialPages) {
- if (url == BROWSER_NEW_TAB_URL) {
- continue; // We tested about:newtab using BrowserOpenTab() above.
- }
- info("Testing " + url + " - " + new Date());
- yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, url);
- yield BrowserTestUtils.closeWindow(win);
-
- ok(SessionStore.getClosedWindowCount(), "Should have a closed window");
-
- win = SessionStore.undoCloseWindow(0);
- yield TestUtils.topicObserved("sessionstore-single-window-restored",
- subject => subject == win);
- yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
- yield TabStateFlusher.flush(win.gBrowser.selectedBrowser);
-
- is(win.gURLBar.value, "", "URL bar should be empty");
- tab = win.gBrowser.selectedTab;
- is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
- state = JSON.parse(SessionStore.getTabState(tab));
- ok(!state.userTypedValue, "userTypedValue should be undefined on the tab's state");
-
- info("Removing tab - " + new Date());
- yield BrowserTestUtils.removeTab(tab);
- info("Finished removing tab - " + new Date());
- }
- info("Removing window - " + new Date());
- yield BrowserTestUtils.closeWindow(win);
- info("Finished removing window - " + new Date());
-});
diff --git a/browser/components/sessionstore/test/browser_pageStyle.js b/browser/components/sessionstore/test/browser_pageStyle.js
deleted file mode 100644
index 7abee5d9d..000000000
--- a/browser/components/sessionstore/test/browser_pageStyle.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const URL = getRootDirectory(gTestPath) + "browser_pageStyle_sample.html";
-const URL_NESTED = getRootDirectory(gTestPath) + "browser_pageStyle_sample_nested.html";
-
-/**
- * This test ensures that page style information is correctly persisted.
- */
-add_task(function page_style() {
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
- let sheets = yield getStyleSheets(browser);
-
- // Enable all style sheets one by one.
- for (let [title, disabled] of sheets) {
- yield enableStyleSheetsForSet(browser, title);
-
- let tab2 = gBrowser.duplicateTab(tab);
- yield promiseTabRestored(tab2);
-
- let sheets = yield getStyleSheets(tab2.linkedBrowser);
- let enabled = sheets.filter(([title, disabled]) => !disabled);
-
- if (title.startsWith("fail_")) {
- ok(!enabled.length, "didn't restore " + title);
- } else {
- is(enabled.length, 1, "restored one style sheet");
- is(enabled[0][0], title, "restored correct sheet");
- }
-
- gBrowser.removeTab(tab2);
- }
-
- // Disable all styles and verify that this is correctly persisted.
- yield setAuthorStyleDisabled(browser, true);
-
- let tab2 = gBrowser.duplicateTab(tab);
- yield promiseTabRestored(tab2);
-
- let authorStyleDisabled = yield getAuthorStyleDisabled(tab2.linkedBrowser);
- ok(authorStyleDisabled, "disabled all stylesheets");
-
- // Clean up.
- gBrowser.removeTab(tab);
- gBrowser.removeTab(tab2);
-});
-
-/**
- * This test ensures that page style notification from nested documents are
- * received and the page style is persisted correctly.
- */
-add_task(function nested_page_style() {
- let tab = gBrowser.addTab(URL_NESTED);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- yield enableSubDocumentStyleSheetsForSet(browser, "alternate");
- yield promiseRemoveTab(tab);
-
- let [{state: {pageStyle}}] = JSON.parse(ss.getClosedTabData(window));
- let expected = JSON.stringify({children: [{pageStyle: "alternate"}]});
- is(JSON.stringify(pageStyle), expected, "correct pageStyle persisted");
-});
-
-function getStyleSheets(browser) {
- return sendMessage(browser, "ss-test:getStyleSheets");
-}
-
-function enableStyleSheetsForSet(browser, name) {
- return sendMessage(browser, "ss-test:enableStyleSheetsForSet", name);
-}
-
-function enableSubDocumentStyleSheetsForSet(browser, name) {
- return sendMessage(browser, "ss-test:enableSubDocumentStyleSheetsForSet", {
- id: "iframe", set: name
- });
-}
-
-function getAuthorStyleDisabled(browser) {
- return sendMessage(browser, "ss-test:getAuthorStyleDisabled");
-}
-
-function setAuthorStyleDisabled(browser, val) {
- return sendMessage(browser, "ss-test:setAuthorStyleDisabled", val)
-}
diff --git a/browser/components/sessionstore/test/browser_pageStyle_sample.html b/browser/components/sessionstore/test/browser_pageStyle_sample.html
deleted file mode 100644
index 810054049..000000000
--- a/browser/components/sessionstore/test/browser_pageStyle_sample.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<html>
-<head>
- <meta charset="utf-8">
- <title>pageStyle sample</title>
-
- <link href="404.css" title="default" rel="stylesheet">
- <link href="404.css" title="alternate" rel="alternate stylesheet">
- <link href="404.css" title="altERnate" rel=" styLEsheet altERnate ">
- <link href="404.css" title="media_empty" rel="alternate stylesheet" media="">
- <link href="404.css" title="media_all" rel="alternate stylesheet" media="all">
- <link href="404.css" title="media_ALL" rel="alternate stylesheet" media=" ALL ">
- <link href="404.css" title="media_screen" rel="alternate stylesheet" media="screen">
- <link href="404.css" title="media_print_screen" rel="alternate stylesheet" media="print,screen">
-</head>
-<body></body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_pageStyle_sample_nested.html b/browser/components/sessionstore/test/browser_pageStyle_sample_nested.html
deleted file mode 100644
index 157609fa6..000000000
--- a/browser/components/sessionstore/test/browser_pageStyle_sample_nested.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
- <meta charset="utf-8">
- <title>pageStyle sample (nested)</title>
-</head>
-<body>
- <iframe id="iframe" src="browser_pageStyle_sample.html"/>
-</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_page_title.js b/browser/components/sessionstore/test/browser_page_title.js
deleted file mode 100644
index 9bbb1ca76..000000000
--- a/browser/components/sessionstore/test/browser_page_title.js
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-const URL = "data:text/html,<title>initial title</title>";
-
-add_task(function* () {
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- yield promiseBrowserLoaded(tab.linkedBrowser);
-
- // Remove the tab.
- yield promiseRemoveTab(tab);
-
- // Check the title.
- let [{state: {entries}}] = JSON.parse(ss.getClosedTabData(window));
- is(entries[0].title, "initial title", "correct title");
-});
-
-add_task(function* () {
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to ensure we collected the initial title.
- yield TabStateFlusher.flush(browser);
-
- // Set a new title.
- yield ContentTask.spawn(browser, null, function* () {
- return new Promise(resolve => {
- addEventListener("DOMTitleChanged", function onTitleChanged() {
- removeEventListener("DOMTitleChanged", onTitleChanged);
- resolve();
- });
-
- content.document.title = "new title";
- });
- });
-
- // Remove the tab.
- yield promiseRemoveTab(tab);
-
- // Check the title.
- let [{state: {entries}}] = JSON.parse(ss.getClosedTabData(window));
- is(entries[0].title, "new title", "correct title");
-});
diff --git a/browser/components/sessionstore/test/browser_parentProcessRestoreHash.js b/browser/components/sessionstore/test/browser_parentProcessRestoreHash.js
deleted file mode 100644
index 1deb461c8..000000000
--- a/browser/components/sessionstore/test/browser_parentProcessRestoreHash.js
+++ /dev/null
@@ -1,95 +0,0 @@
-"use strict";
-
-const SELFCHROMEURL =
- "chrome://mochitests/content/browser/browser/" +
- "components/sessionstore/test/browser_parentProcessRestoreHash.js";
-
-const Cm = Components.manager;
-
-const TESTCLASSID = "78742c04-3630-448c-9be3-6c5070f062de";
-
-const TESTURL = "about:testpageforsessionrestore#foo";
-
-
-let TestAboutPage = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
- getURIFlags: function(aURI) {
- // No CAN_ or MUST_LOAD_IN_CHILD means this loads in the parent:
- return Ci.nsIAboutModule.ALLOW_SCRIPT |
- Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT |
- Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
- },
-
- newChannel: function(aURI, aLoadInfo) {
- // about: page inception!
- let newURI = Services.io.newURI(SELFCHROMEURL, null, null);
- let channel = Services.io.newChannelFromURIWithLoadInfo(newURI,
- aLoadInfo);
- channel.originalURI = aURI;
- return channel;
- },
-
- createInstance: function(outer, iid) {
- if (outer != null) {
- throw Cr.NS_ERROR_NO_AGGREGATION;
- }
- return this.QueryInterface(iid);
- },
-
- register: function() {
- Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(
- Components.ID(TESTCLASSID), "Only here for a test",
- "@mozilla.org/network/protocol/about;1?what=testpageforsessionrestore", this);
- },
-
- unregister: function() {
- Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(
- Components.ID(TESTCLASSID), this);
- }
-};
-
-
-/**
- * Test that switching from a remote to a parent process browser
- * correctly clears the userTypedValue
- */
-add_task(function* () {
- TestAboutPage.register();
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/", true, true);
- ok(tab.linkedBrowser.isRemoteBrowser, "Browser should be remote");
-
- let resolveLocationChangePromise;
- let locationChangePromise = new Promise(r => resolveLocationChangePromise = r);
- let wpl = {
- onStateChange(wpl, request, state, status) {
- let location = request.QueryInterface(Ci.nsIChannel).originalURI;
- // Ignore about:blank loads.
- let docStop = Ci.nsIWebProgressListener.STATE_STOP |
- Ci.nsIWebProgressListener.STATE_IS_NETWORK;
- if (location.spec == "about:blank" || (state & docStop == docStop)) {
- return;
- }
- is(location.spec, TESTURL, "Got the expected URL");
- resolveLocationChangePromise();
- },
- };
- gBrowser.addProgressListener(wpl);
-
- gURLBar.value = TESTURL;
- gURLBar.select();
- EventUtils.sendKey("return");
-
- yield locationChangePromise;
-
- ok(!tab.linkedBrowser.isRemoteBrowser, "Browser should no longer be remote");
-
- is(gURLBar.textValue, TESTURL, "URL bar visible value should be correct.");
- is(gURLBar.value, TESTURL, "URL bar value should be correct.");
- is(gURLBar.getAttribute("pageproxystate"), "valid", "URL bar is in valid page proxy state");
-
- ok(!tab.linkedBrowser.userTypedValue, "No userTypedValue should be on the browser.");
-
- yield BrowserTestUtils.removeTab(tab);
- gBrowser.removeProgressListener(wpl);
- TestAboutPage.unregister();
-});
diff --git a/browser/components/sessionstore/test/browser_pending_tabs.js b/browser/components/sessionstore/test/browser_pending_tabs.js
deleted file mode 100644
index e734e55c9..000000000
--- a/browser/components/sessionstore/test/browser_pending_tabs.js
+++ /dev/null
@@ -1,35 +0,0 @@
-"use strict";
-
-const TAB_STATE = {
- entries: [{ url: "about:mozilla" }, { url: "about:robots" }],
- index: 1,
-};
-
-add_task(function* () {
- // Create a background tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // The tab shouldn't be restored right away.
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- // Prepare the tab state.
- let promise = promiseTabRestoring(tab);
- ss.setTabState(tab, JSON.stringify(TAB_STATE));
- ok(tab.hasAttribute("pending"), "tab is pending");
- yield promise;
-
- // Flush to ensure the parent has all data.
- yield TabStateFlusher.flush(browser);
-
- // Check that the shistory index is the one we restored.
- let tabState = TabState.collect(tab);
- is(tabState.index, TAB_STATE.index, "correct shistory index");
-
- // Check we don't collect userTypedValue when we shouldn't.
- ok(!tabState.userTypedValue, "tab didn't have a userTypedValue");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_privatetabs.js b/browser/components/sessionstore/test/browser_privatetabs.js
deleted file mode 100644
index cc02e56cf..000000000
--- a/browser/components/sessionstore/test/browser_privatetabs.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-add_task(function cleanup() {
- info("Forgetting closed tabs");
- while (ss.getClosedTabCount(window)) {
- ss.forgetClosedTab(window, 0);
- }
-});
-
-add_task(function() {
- let URL_PUBLIC = "http://example.com/public/" + Math.random();
- let URL_PRIVATE = "http://example.com/private/" + Math.random();
- let tab1, tab2;
- try {
- // Setup a public tab and a private tab
- info("Setting up public tab");
- tab1 = gBrowser.addTab(URL_PUBLIC);
- yield promiseBrowserLoaded(tab1.linkedBrowser);
-
- info("Setting up private tab");
- tab2 = gBrowser.addTab();
- yield promiseBrowserLoaded(tab2.linkedBrowser);
- yield setUsePrivateBrowsing(tab2.linkedBrowser, true);
- tab2.linkedBrowser.loadURI(URL_PRIVATE);
- yield promiseBrowserLoaded(tab2.linkedBrowser);
-
- info("Flush to make sure chrome received all data.");
- yield TabStateFlusher.flush(tab1.linkedBrowser);
- yield TabStateFlusher.flush(tab2.linkedBrowser);
-
- info("Checking out state");
- let state = yield promiseRecoveryFileContents();
-
- info("State: " + state);
- // Ensure that sessionstore.js only knows about the public tab
- ok(state.indexOf(URL_PUBLIC) != -1, "State contains public tab");
- ok(state.indexOf(URL_PRIVATE) == -1, "State does not contain private tab");
-
- // Ensure that we can close and undo close the public tab but not the private tab
- gBrowser.removeTab(tab2);
- tab2 = null;
-
- gBrowser.removeTab(tab1);
- tab1 = null;
-
- tab1 = ss.undoCloseTab(window, 0);
- ok(true, "Public tab supports undo close");
-
- is(ss.getClosedTabCount(window), 0, "Private tab does not support undo close");
-
- } finally {
- if (tab1) {
- gBrowser.removeTab(tab1);
- }
- if (tab2) {
- gBrowser.removeTab(tab2);
- }
- }
-});
-
-add_task(function () {
- const FRAME_SCRIPT = "data:," +
- "docShell.QueryInterface%28Components.interfaces.nsILoadContext%29.usePrivateBrowsing%3Dtrue";
-
- // Clear the list of closed windows.
- forgetClosedWindows();
-
- // Create a new window to attach our frame script to.
- let win = yield promiseNewWindowLoaded();
- let mm = win.getGroupMessageManager("browsers");
- mm.loadFrameScript(FRAME_SCRIPT, true);
-
- // Create a new tab in the new window that will load the frame script.
- let tab = win.gBrowser.addTab("about:mozilla");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-
- // Check that we consider the tab as private.
- let state = JSON.parse(ss.getTabState(tab));
- ok(state.isPrivate, "tab considered private");
-
- // Ensure we don't allow restoring closed private tabs in non-private windows.
- win.gBrowser.removeTab(tab);
- is(ss.getClosedTabCount(win), 0, "no tabs to restore");
-
- // Create a new tab in the new window that will load the frame script.
- tab = win.gBrowser.addTab("about:mozilla");
- browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-
- // Check that we consider the tab as private.
- state = JSON.parse(ss.getTabState(tab));
- ok(state.isPrivate, "tab considered private");
-
- // Check that all private tabs are removed when the non-private
- // window is closed and we don't save windows without any tabs.
- yield BrowserTestUtils.closeWindow(win);
- is(ss.getClosedWindowCount(), 0, "no windows to restore");
-});
-
-add_task(function () {
- // Clear the list of closed windows.
- forgetClosedWindows();
-
- // Create a new window to attach our frame script to.
- let win = yield promiseNewWindowLoaded({private: true});
-
- // Create a new tab in the new window that will load the frame script.
- let tab = win.gBrowser.addTab("about:mozilla");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
- yield TabStateFlusher.flush(browser);
-
- // Check that we consider the tab as private.
- let state = JSON.parse(ss.getTabState(tab));
- ok(state.isPrivate, "tab considered private");
-
- // Ensure that closed tabs in a private windows can be restored.
- win.gBrowser.removeTab(tab);
- is(ss.getClosedTabCount(win), 1, "there is a single tab to restore");
-
- // Ensure that closed private windows can never be restored.
- yield BrowserTestUtils.closeWindow(win);
- is(ss.getClosedWindowCount(), 0, "no windows to restore");
-});
-
-function setUsePrivateBrowsing(browser, val) {
- return sendMessage(browser, "ss-test:setUsePrivateBrowsing", val);
-}
-
diff --git a/browser/components/sessionstore/test/browser_purge_shistory.js b/browser/components/sessionstore/test/browser_purge_shistory.js
deleted file mode 100644
index 28c6f6f24..000000000
--- a/browser/components/sessionstore/test/browser_purge_shistory.js
+++ /dev/null
@@ -1,59 +0,0 @@
-"use strict";
-
-/**
- * This test checks that pending tabs are treated like fully loaded tabs when
- * purging session history. Just like for fully loaded tabs we want to remove
- * every but the current shistory entry.
- */
-
-const TAB_STATE = {
- entries: [{url: "about:mozilla"}, {url: "about:robots"}],
- index: 1,
-};
-
-function checkTabContents(browser) {
- return ContentTask.spawn(browser, null, function* () {
- let Ci = Components.interfaces;
- let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
- let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal);
- Assert.ok(history && history.count == 1 && content.document.documentURI == "about:mozilla",
- "expected tab contents found");
- });
-}
-
-add_task(function* () {
- // Create a new tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
- yield promiseTabState(tab, TAB_STATE);
-
- // Create another new tab.
- let tab2 = gBrowser.addTab("about:blank");
- let browser2 = tab2.linkedBrowser;
- yield promiseBrowserLoaded(browser2);
-
- // The tab shouldn't be restored right away.
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- // Prepare the tab state.
- let promise = promiseTabRestoring(tab2);
- ss.setTabState(tab2, JSON.stringify(TAB_STATE));
- ok(tab2.hasAttribute("pending"), "tab is pending");
- yield promise;
-
- // Purge session history.
- Services.obs.notifyObservers(null, "browser:purge-session-history", "");
- yield checkTabContents(browser);
- ok(tab2.hasAttribute("pending"), "tab is still pending");
-
- // Kick off tab restoration.
- gBrowser.selectedTab = tab2;
- yield promiseTabRestored(tab2);
- yield checkTabContents(browser2);
- ok(!tab2.hasAttribute("pending"), "tab is not pending anymore");
-
- // Cleanup.
- gBrowser.removeTab(tab2);
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js b/browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js
deleted file mode 100644
index 7dbee03fd..000000000
--- a/browser/components/sessionstore/test/browser_remoteness_flip_on_restore.js
+++ /dev/null
@@ -1,342 +0,0 @@
-"use strict";
-
-/**
- * This set of tests checks that the remoteness is properly
- * set for each browser in a window when that window has
- * session state loaded into it.
- */
-
-/**
- * Takes a SessionStore window state object for a single
- * window, sets the selected tab for it, and then returns
- * the object to be passed to SessionStore.setWindowState.
- *
- * @param state (object)
- * The state to prepare to be sent to a window. This is
- * state should just be for a single window.
- * @param selected (int)
- * The 1-based index of the selected tab. Note that
- * If this is 0, then the selected tab will not change
- * from what's already selected in the window that we're
- * sending state to.
- * @returns (object)
- * The JSON encoded string to call
- * SessionStore.setWindowState with.
- */
-function prepareState(state, selected) {
- // We'll create a copy so that we don't accidentally
- // modify the caller's selected property.
- let copy = {};
- Object.assign(copy, state);
- copy.selected = selected;
-
- return {
- windows: [ copy ],
- };
-}
-
-const SIMPLE_STATE = {
- tabs: [
- { entries: [{ url: "http://example.com/", title: "title" }] },
- { entries: [{ url: "http://example.com/", title: "title" }] },
- { entries: [{ url: "http://example.com/", title: "title" }] },
- ],
- title: "",
- _closedTabs: [],
-};
-
-const PINNED_STATE = {
- tabs: [
- { entries: [{ url: "http://example.com/", title: "title" }], pinned: true },
- { entries: [{ url: "http://example.com/", title: "title" }], pinned: true },
- { entries: [{ url: "http://example.com/", title: "title" }] },
- ],
- title: "",
- _closedTabs: [],
-};
-
-/**
- * This is where most of the action is happening. This function takes
- * an Array of "test scenario" Objects and runs them. For each scenario, a
- * window is opened, put into some state, and then a new state is
- * loaded into that window. We then check to make sure that the
- * right things have happened in that window wrt remoteness flips.
- *
- * The schema for a testing scenario Object is as follows:
- *
- * initialRemoteness:
- * an Array that represents the starting window. Each bool
- * in the Array represents the window tabs in order. A "true"
- * indicates that that tab should be remote. "false" if the tab
- * should be non-remote.
- *
- * initialSelectedTab:
- * The 1-based index of the tab that we want to select for the
- * restored window. This is 1-based to avoid confusion with the
- * selectedTab property described down below, though you probably
- * want to set this to be greater than 0, since the initial window
- * needs to have a defined initial selected tab. Because of this,
- * the test will throw if initialSelectedTab is 0.
- *
- * stateToRestore:
- * A JS Object for the state to send down to the window.
- *
- * selectedTab:
- * The 1-based index of the tab that we want to select for the
- * restored window. Leave this at 0 if you don't want to change
- * the selection from the initial window state.
- *
- * expectedFlips:
- * an Array that represents the window that we end up with after
- * restoring state. Each bool in the Array represents the window tabs,
- * in order. A "true" indicates that the tab should have flipped
- * its remoteness once. "false" indicates that the tab should never
- * have flipped remoteness. Note that any tab that flips its remoteness
- * more than once will cause a test failure.
- *
- * expectedRemoteness:
- * an Array that represents the window that we end up with after
- * restoring state. Each bool in the Array represents the window
- * tabs in order. A "true" indicates that the tab be remote, and
- * a "false" indicates that the tab should be "non-remote". We
- * need this Array in order to test pinned tabs which will also
- * be loaded by default, and therefore should end up remote.
- *
- */
-function* runScenarios(scenarios) {
- for (let scenario of scenarios) {
- // Let's make sure our scenario is sane first.
- Assert.equal(scenario.expectedFlips.length,
- scenario.expectedRemoteness.length,
- "All expected flips and remoteness needs to be supplied");
- Assert.ok(scenario.initialSelectedTab > 0,
- "You must define an initially selected tab");
-
- // First, we need to create the initial conditions, so we
- // open a new window to put into our starting state...
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let tabbrowser = win.gBrowser;
- Assert.ok(tabbrowser.selectedBrowser.isRemoteBrowser,
- "The initial browser should be remote.");
- // Now put the window into the expected initial state.
- for (let i = 0; i < scenario.initialRemoteness.length; ++i) {
- let tab;
- if (i > 0) {
- // The window starts with one tab, so we need to create
- // any of the additional ones required by this test.
- info("Opening a new tab");
- tab = yield BrowserTestUtils.openNewForegroundTab(tabbrowser)
- } else {
- info("Using the selected tab");
- tab = tabbrowser.selectedTab;
- }
- let browser = tab.linkedBrowser;
- let remotenessState = scenario.initialRemoteness[i];
- tabbrowser.updateBrowserRemoteness(browser, remotenessState);
- }
-
- // And select the requested tab.
- let tabToSelect = tabbrowser.tabs[scenario.initialSelectedTab - 1];
- if (tabbrowser.selectedTab != tabToSelect) {
- yield BrowserTestUtils.switchTab(tabbrowser, tabToSelect);
- }
-
- // Hook up an event listener to make sure that the right
- // tabs flip remoteness, and only once.
- let flipListener = {
- seenBeforeTabs: new Set(),
- seenAfterTabs: new Set(),
- handleEvent(e) {
- let index = Array.from(tabbrowser.tabs).indexOf(e.target);
- switch (e.type) {
- case "BeforeTabRemotenessChange":
- info(`Saw tab at index ${index} before remoteness flip`);
- if (this.seenBeforeTabs.has(e.target)) {
- Assert.ok(false, "Saw tab before remoteness flip more than once");
- }
- this.seenBeforeTabs.add(e.target);
- break;
- case "TabRemotenessChange":
- info(`Saw tab at index ${index} after remoteness flip`);
- if (this.seenAfterTabs.has(e.target)) {
- Assert.ok(false, "Saw tab after remoteness flip more than once");
- }
- this.seenAfterTabs.add(e.target);
- break;
- }
- },
- };
-
- win.addEventListener("BeforeTabRemotenessChange", flipListener);
- win.addEventListener("TabRemotenessChange", flipListener);
-
- // Okay, time to test!
- let state = prepareState(scenario.stateToRestore,
- scenario.selectedTab);
-
- SessionStore.setWindowState(win, state, true);
-
- win.removeEventListener("BeforeTabRemotenessChange", flipListener);
- win.removeEventListener("TabRemotenessChange", flipListener);
-
- // Because we know that scenario.expectedFlips and
- // scenario.expectedRemoteness have the same length, we
- // can check that we satisfied both with the same loop.
- for (let i = 0; i < scenario.expectedFlips.length; ++i) {
- let expectedToFlip = scenario.expectedFlips[i];
- let expectedRemoteness = scenario.expectedRemoteness[i];
- let tab = tabbrowser.tabs[i];
- if (expectedToFlip) {
- Assert.ok(flipListener.seenBeforeTabs.has(tab),
- `We should have seen tab at index ${i} before remoteness flip`);
- Assert.ok(flipListener.seenAfterTabs.has(tab),
- `We should have seen tab at index ${i} after remoteness flip`);
- } else {
- Assert.ok(!flipListener.seenBeforeTabs.has(tab),
- `We should not have seen tab at index ${i} before remoteness flip`);
- Assert.ok(!flipListener.seenAfterTabs.has(tab),
- `We should not have seen tab at index ${i} after remoteness flip`);
- }
-
- Assert.equal(tab.linkedBrowser.isRemoteBrowser, expectedRemoteness,
- "Should have gotten the expected remoteness " +
- `for the tab at index ${i}`);
- }
-
- yield BrowserTestUtils.closeWindow(win);
- }
-}
-
-/**
- * Tests that if we restore state to browser windows with
- * a variety of initial remoteness states, that we only flip
- * the remoteness on the necessary tabs. For this particular
- * set of tests, we assume that tabs are restoring on demand.
- */
-add_task(function*() {
- // This test opens and closes windows, which might bog down
- // a debug build long enough to time out the test, so we
- // extend the tolerance on timeouts.
- requestLongerTimeout(5);
-
- yield SpecialPowers.pushPrefEnv({
- "set": [["browser.sessionstore.restore_on_demand", true]],
- });
-
- const TEST_SCENARIOS = [
- // Only one tab in the new window, and it's remote. This
- // is the common case, since this is how restoration occurs
- // when the restored window is being opened.
- {
- initialRemoteness: [true],
- initialSelectedTab: 1,
- stateToRestore: SIMPLE_STATE,
- selectedTab: 3,
- // The initial tab is remote and should go into
- // the background state. The second and third tabs
- // are new and should be initialized non-remote.
- expectedFlips: [true, false, true],
- // Only the selected tab should be remote.
- expectedRemoteness: [false, false, true],
- },
-
- // A single remote tab, and this is the one that's going
- // to be selected once state is restored.
- {
- initialRemoteness: [true],
- initialSelectedTab: 1,
- stateToRestore: SIMPLE_STATE,
- selectedTab: 1,
- // The initial tab is remote and selected, so it should
- // not flip remoteness. The other two new tabs should
- // be non-remote by default.
- expectedFlips: [false, false, false],
- // Only the selected tab should be remote.
- expectedRemoteness: [true, false, false],
- },
-
- // A single remote tab which starts selected. We set the
- // selectedTab to 0 which is equivalent to "don't change
- // the tab selection in the window".
- {
- initialRemoteness: [true],
- initialSelectedTab: 1,
- stateToRestore: SIMPLE_STATE,
- selectedTab: 0,
- // The initial tab is remote and selected, so it should
- // not flip remoteness. The other two new tabs should
- // be non-remote by default.
- expectedFlips: [false, false, false],
- // Only the selected tab should be remote.
- expectedRemoteness: [true, false, false],
- },
-
- // An initially remote tab, but we're going to load
- // some pinned tabs now, and the pinned tabs should load
- // right away.
- {
- initialRemoteness: [true],
- initialSelectedTab: 1,
- stateToRestore: PINNED_STATE,
- selectedTab: 3,
- // The initial tab is pinned and will load right away,
- // so it should stay remote. The second tab is new
- // and pinned, so it should start remote and not flip.
- // The third tab is not pinned, but it is selected,
- // so it will start non-remote, and then flip remoteness.
- expectedFlips: [false, false, true],
- // Both pinned tabs and the selected tabs should all
- // end up being remote.
- expectedRemoteness: [true, true, true],
- },
-
- // A single non-remote tab.
- {
- initialRemoteness: [false],
- initialSelectedTab: 1,
- stateToRestore: SIMPLE_STATE,
- selectedTab: 2,
- // The initial tab is non-remote and should stay
- // that way. The second and third tabs are new and
- // should be initialized non-remote.
- expectedFlips: [false, true, false],
- // Only the selected tab should be remote.
- expectedRemoteness: [false, true, false],
- },
-
- // A mixture of remote and non-remote tabs.
- {
- initialRemoteness: [true, false, true],
- initialSelectedTab: 1,
- stateToRestore: SIMPLE_STATE,
- selectedTab: 3,
- // The initial tab is remote and should flip to non-remote
- // as it is put into the background. The second tab should
- // stay non-remote, and the third one should stay remote.
- expectedFlips: [true, false, false],
- // Only the selected tab should be remote.
- expectedRemoteness: [false, false, true],
- },
-
- // An initially non-remote tab, but we're going to load
- // some pinned tabs now, and the pinned tabs should load
- // right away.
- {
- initialRemoteness: [false],
- initialSelectedTab: 1,
- stateToRestore: PINNED_STATE,
- selectedTab: 3,
- // The initial tab is pinned and will load right away,
- // so it should flip remoteness. The second tab is new
- // and pinned, so it should start remote and not flip.
- // The third tab is not pinned, but it is selected,
- // so it will start non-remote, and then flip remoteness.
- expectedFlips: [true, false, true],
- // Both pinned tabs and the selected tabs should all
- // end up being remote.
- expectedRemoteness: [true, true, true],
- },
- ];
-
- yield* runScenarios(TEST_SCENARIOS);
-});
diff --git a/browser/components/sessionstore/test/browser_replace_load.js b/browser/components/sessionstore/test/browser_replace_load.js
deleted file mode 100644
index 5464a0874..000000000
--- a/browser/components/sessionstore/test/browser_replace_load.js
+++ /dev/null
@@ -1,52 +0,0 @@
-"use strict";
-
-const STATE = {
- entries: [{url: "about:robots"}, {url: "about:mozilla"}],
- selected: 2
-};
-
-/**
- * Bug 1100223. Calling browser.loadURI() while a tab is loading causes
- * sessionstore to override the desired target URL. This test ensures that
- * calling loadURI() on a pending tab causes the tab to no longer be marked
- * as pending and correctly finish the instructed load while keeping the
- * restored history around.
- */
-add_task(function* () {
- yield testSwitchToTab("about:mozilla#fooobar", {ignoreFragment: "whenComparingAndReplace"});
- yield testSwitchToTab("about:mozilla?foo=bar", {replaceQueryString: true});
-});
-
-var testSwitchToTab = Task.async(function* (url, options) {
- // Create a background tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // The tab shouldn't be restored right away.
- Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
-
- // Prepare the tab state.
- let promise = promiseTabRestoring(tab);
- ss.setTabState(tab, JSON.stringify(STATE));
- ok(tab.hasAttribute("pending"), "tab is pending");
- yield promise;
-
- // Switch-to-tab with a similar URI.
- switchToTabHavingURI(url, false, options);
-
- // Tab should now restore
- yield promiseTabRestored(tab);
- is(browser.currentURI.spec, url, "correct URL loaded");
-
- // Check that we didn't lose any history entries.
- yield ContentTask.spawn(browser, null, function* () {
- let Ci = Components.interfaces;
- let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
- let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal);
- Assert.equal(history && history.count, 3, "three history entries");
- });
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js b/browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js
deleted file mode 100644
index 5767c6c0f..000000000
--- a/browser/components/sessionstore/test/browser_restore_cookies_noOriginAttributes.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Bug 1267910 - The regression test case for session cookies.
- */
-
-"use strict";
-
-const TEST_HOST = "www.example.com";
-const COOKIE =
-{
- name: "test1",
- value: "yes1",
- path: "/browser/browser/components/sessionstore/test/"
-};
-const SESSION_DATA = `
-{
- "version": ["sessionrestore", 1],
- "windows": [{
- "tabs": [{
- "entries": [],
- "lastAccessed": 1463893009797,
- "hidden": false,
- "attributes": {},
- "image": null
- }, {
- "entries": [{
- "url": "http://www.example.com/browser/browser/components/sessionstore/test/browser_1267910_page.html",
- \"charset": "UTF-8",
- "ID": 0,
- "docshellID": 2,
- "originalURI": "http://www.example.com/browser/browser/components/sessionstore/test/browser_1267910_page.html",
- \"docIdentifier": 0,
- "persist": true
- }],
- "lastAccessed": 1463893009321,
- "hidden": false,
- "attributes": {},
- "userContextId": 0,
- "index": 1,
- "image": "http://www.example.com/favicon.ico"
- }],
- "selected": 1,
- "_closedTabs": [],
- "busy": false,
- "width": 1024,
- "height": 768,
- "screenX": 4,
- "screenY": 23,
- "sizemode": "normal",
- "cookies": [{
- "host": "www.example.com",
- "value": "yes1",
- "path": "/browser/browser/components/sessionstore/test/",
- "name": "test1"
- }]
- }],
- "selectedWindow": 1,
- "_closedWindows": [],
- "session": {
- "lastUpdate": 1463893009801,
- "startTime": 1463893007134,
- "recentCrashes": 0
- },
- "global": {}
-}`;
-const SESSION_DATA_OA = `
-{
- "version": ["sessionrestore", 1],
- "windows": [{
- "tabs": [{
- "entries": [],
- "lastAccessed": 1463893009797,
- "hidden": false,
- "attributes": {},
- "image": null
- }, {
- "entries": [{
- "url": "http://www.example.com/browser/browser/components/sessionstore/test/browser_1267910_page.html",
- \"charset": "UTF-8",
- "ID": 0,
- "docshellID": 2,
- "originalURI": "http://www.example.com/browser/browser/components/sessionstore/test/browser_1267910_page.html",
- \"docIdentifier": 0,
- "persist": true
- }],
- "lastAccessed": 1463893009321,
- "hidden": false,
- "attributes": {},
- "userContextId": 0,
- "index": 1,
- "image": "http://www.example.com/favicon.ico"
- }],
- "selected": 1,
- "_closedTabs": [],
- "busy": false,
- "width": 1024,
- "height": 768,
- "screenX": 4,
- "screenY": 23,
- "sizemode": "normal",
- "cookies": [{
- "host": "www.example.com",
- "value": "yes1",
- "path": "/browser/browser/components/sessionstore/test/",
- "name": "test1",
- "originAttributes": {
- "addonId": "",
- "appId": 0,
- "inIsolatedMozBrowser": false,
- "userContextId": 0
- }
- }]
- }],
- "selectedWindow": 1,
- "_closedWindows": [],
- "session": {
- "lastUpdate": 1463893009801,
- "startTime": 1463893007134,
- "recentCrashes": 0
- },
- "global": {}
-}`;
-
-add_task(function* run_test() {
- // Wait until initialization is complete.
- yield SessionStore.promiseInitialized;
-
- // Clear cookies.
- Services.cookies.removeAll();
-
- // Open a new window.
- let win = yield promiseNewWindowLoaded();
-
- // Restore window with session cookies that have no originAttributes.
- ss.setWindowState(win, SESSION_DATA, true);
-
- let enumerator = Services.cookies.getCookiesFromHost(TEST_HOST, {});
- let cookie;
- let cookieCount = 0;
- while (enumerator.hasMoreElements()) {
- cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
- cookieCount++;
- }
-
- // Check that the cookie is restored successfully.
- is(cookieCount, 1, "expected one cookie");
- is(cookie.name, COOKIE.name, "cookie name successfully restored");
- is(cookie.value, COOKIE.value, "cookie value successfully restored");
- is(cookie.path, COOKIE.path, "cookie path successfully restored");
-
- // Clear cookies.
- Services.cookies.removeAll();
-
- // Restore window with session cookies that have originAttributes within.
- ss.setWindowState(win, SESSION_DATA_OA, true);
-
- enumerator = Services.cookies.getCookiesFromHost(TEST_HOST, {});
- cookieCount = 0;
- while (enumerator.hasMoreElements()) {
- cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
- cookieCount++;
- }
-
- // Check that the cookie is restored successfully.
- is(cookieCount, 1, "expected one cookie");
- is(cookie.name, COOKIE.name, "cookie name successfully restored");
- is(cookie.value, COOKIE.value, "cookie value successfully restored");
- is(cookie.path, COOKIE.path, "cookie path successfully restored");
-
- // Close our window.
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/sessionstore/test/browser_restore_redirect.js b/browser/components/sessionstore/test/browser_restore_redirect.js
deleted file mode 100644
index bea6e9f47..000000000
--- a/browser/components/sessionstore/test/browser_restore_redirect.js
+++ /dev/null
@@ -1,69 +0,0 @@
-"use strict";
-
-const BASE = "http://example.com/browser/browser/components/sessionstore/test/";
-const TARGET = BASE + "restore_redirect_target.html";
-
-/**
- * Ensure that a http redirect leaves a working tab.
- */
-add_task(function check_http_redirect() {
- let state = {
- entries: [{ url: BASE + "restore_redirect_http.html" }]
- };
-
- // Open a new tab to restore into.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseTabState(tab, state);
-
- info("Restored tab");
-
- yield TabStateFlusher.flush(browser);
- let data = TabState.collect(tab);
- is(data.entries.length, 1, "Should be one entry in session history");
- is(data.entries[0].url, TARGET, "Should be the right session history entry");
-
- ok(!("__SS_data" in browser), "Temporary restore data should have been cleared");
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
-
-/**
- * Ensure that a js redirect leaves a working tab.
- */
-add_task(function check_js_redirect() {
- let state = {
- entries: [{ url: BASE + "restore_redirect_js.html" }]
- };
-
- let loadPromise = new Promise(resolve => {
- function listener(msg) {
- if (msg.data.url.endsWith("restore_redirect_target.html")) {
- window.messageManager.removeMessageListener("ss-test:loadEvent", listener);
- resolve();
- }
- }
-
- window.messageManager.addMessageListener("ss-test:loadEvent", listener);
- });
-
- // Open a new tab to restore into.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseTabState(tab, state);
-
- info("Restored tab");
-
- yield loadPromise;
-
- yield TabStateFlusher.flush(browser);
- let data = TabState.collect(tab);
- is(data.entries.length, 1, "Should be one entry in session history");
- is(data.entries[0].url, TARGET, "Should be the right session history entry");
-
- ok(!("__SS_data" in browser), "Temporary restore data should have been cleared");
-
- // Cleanup.
- yield promiseRemoveTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js b/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
deleted file mode 100644
index e29cd5e49..000000000
--- a/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that even if the user has set their tabs to restore
- * immediately on session start, that background tabs after a
- * content process crash restore on demand.
- */
-
-"use strict";
-
-const PAGE_1 = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const PAGE_2 = "data:text/html,<html><body>Another%20regular,%20everyday,%20normal%20page.";
-
-add_task(function* setup() {
- yield pushPrefs(["dom.ipc.processCount", 1],
- ["browser.tabs.animate", false],
- ["browser.sessionstore.restore_on_demand", false]);
-});
-
-add_task(function* test_revive_bg_tabs_on_demand() {
- let newTab1 = gBrowser.addTab(PAGE_1);
- let browser1 = newTab1.linkedBrowser;
- gBrowser.selectedTab = newTab1;
-
- let newTab2 = gBrowser.addTab(PAGE_2);
- let browser2 = newTab2.linkedBrowser;
-
- yield BrowserTestUtils.browserLoaded(browser1);
- yield BrowserTestUtils.browserLoaded(browser2);
-
- yield TabStateFlusher.flush(browser2);
-
- // Now crash the selected tab
- let windowReady = BrowserTestUtils.waitForEvent(window, "SSWindowStateReady");
- yield BrowserTestUtils.crashBrowser(browser1);
-
- ok(newTab1.hasAttribute("crashed"), "Selected tab should be crashed");
- ok(!newTab2.hasAttribute("crashed"), "Background tab should not be crashed");
-
- // Wait until we've had a chance to restore all tabs immediately
- yield windowReady;
-
- // But we should not have restored the background tab
- ok(newTab2.hasAttribute("pending"), "Background tab should be pending");
-
- // Now select newTab2 to make sure it restores.
- let newTab2Restored = promiseTabRestored(newTab2);
- gBrowser.selectedTab = newTab2;
- yield newTab2Restored;
-
- ok(browser2.isRemoteBrowser, "Restored browser should be remote");
-
- yield BrowserTestUtils.removeTab(newTab1);
- yield BrowserTestUtils.removeTab(newTab2);
-});
diff --git a/browser/components/sessionstore/test/browser_scrollPositions.js b/browser/components/sessionstore/test/browser_scrollPositions.js
deleted file mode 100644
index 865520772..000000000
--- a/browser/components/sessionstore/test/browser_scrollPositions.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const BASE = "http://example.com/browser/browser/components/sessionstore/test/"
-const URL = BASE + "browser_scrollPositions_sample.html";
-const URL_FRAMESET = BASE + "browser_scrollPositions_sample_frameset.html";
-
-// Randomized set of scroll positions we will use in this test.
-const SCROLL_X = Math.round(100 * (1 + Math.random()));
-const SCROLL_Y = Math.round(200 * (1 + Math.random()));
-const SCROLL_STR = SCROLL_X + "," + SCROLL_Y;
-
-const SCROLL2_X = Math.round(300 * (1 + Math.random()));
-const SCROLL2_Y = Math.round(400 * (1 + Math.random()));
-const SCROLL2_STR = SCROLL2_X + "," + SCROLL2_Y;
-
-requestLongerTimeout(2);
-
-/**
- * This test ensures that we properly serialize and restore scroll positions
- * for an average page without any frames.
- */
-add_task(function test_scroll() {
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Scroll down a little.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y});
- yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll is fine");
-
- // Duplicate and check that the scroll position is restored.
- let tab2 = ss.duplicateTab(window, tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- let scroll = yield sendMessage(browser2, "ss-test:getScrollPosition");
- is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}),
- "scroll position has been duplicated correctly");
-
- // Check that reloading retains the scroll positions.
- browser2.reload();
- yield promiseBrowserLoaded(browser2);
- yield checkScroll(tab2, {scroll: SCROLL_STR}, "reloading retains scroll positions");
-
- // Check that a force-reload resets scroll positions.
- browser2.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
- yield promiseBrowserLoaded(browser2);
- yield checkScroll(tab2, null, "force-reload resets scroll positions");
-
- // Scroll back to the top and check that the position has been reset. We
- // expect the scroll position to be "null" here because there is no data to
- // be stored if the frame is in its default scroll position.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0});
- yield checkScroll(tab, null, "no scroll stored");
-
- // Cleanup.
- yield promiseRemoveTab(tab);
- yield promiseRemoveTab(tab2);
-});
-
-/**
- * This tests ensures that we properly serialize and restore scroll positions
- * for multiple frames of pages with framesets.
- */
-add_task(function test_scroll_nested() {
- let tab = gBrowser.addTab(URL_FRAMESET);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Scroll the first child frame down a little.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y, frame: 0});
- yield checkScroll(tab, {children: [{scroll: SCROLL_STR}]}, "scroll is fine");
-
- // Scroll the second child frame down a little.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL2_X, y: SCROLL2_Y, frame: 1});
- yield checkScroll(tab, {children: [{scroll: SCROLL_STR}, {scroll: SCROLL2_STR}]}, "scroll is fine");
-
- // Duplicate and check that the scroll position is restored.
- let tab2 = ss.duplicateTab(window, tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- let scroll = yield sendMessage(browser2, "ss-test:getScrollPosition", {frame: 0});
- is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}),
- "scroll position #1 has been duplicated correctly");
-
- scroll = yield sendMessage(browser2, "ss-test:getScrollPosition", {frame: 1});
- is(JSON.stringify(scroll), JSON.stringify({x: SCROLL2_X, y: SCROLL2_Y}),
- "scroll position #2 has been duplicated correctly");
-
- // Check that resetting one frame's scroll position removes it from the
- // serialized value.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0, frame: 0});
- yield checkScroll(tab, {children: [null, {scroll: SCROLL2_STR}]}, "scroll is fine");
-
- // Check the resetting all frames' scroll positions nulls the stored value.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: 0, frame: 1});
- yield checkScroll(tab, null, "no scroll stored");
-
- // Cleanup.
- yield promiseRemoveTab(tab);
- yield promiseRemoveTab(tab2);
-});
-
-/**
- * Test that scroll positions persist after restoring background tabs in
- * a restored window (bug 1228518).
- */
-add_task(function test_scroll_background_tabs() {
- pushPrefs(["browser.sessionstore.restore_on_demand", true]);
-
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
- let tab = newWin.gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield BrowserTestUtils.browserLoaded(browser);
-
- // Scroll down a little.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y});
- yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll is fine");
-
- // Close the window
- yield BrowserTestUtils.closeWindow(newWin);
-
- // Now restore the window
- newWin = ss.undoCloseWindow(0);
-
- // Make sure to wait for the window to be restored.
- yield BrowserTestUtils.waitForEvent(newWin, "SSWindowStateReady");
-
- is(newWin.gBrowser.tabs.length, 2, "There should be two tabs");
-
- // The second tab should be the one we loaded URL at still
- tab = newWin.gBrowser.tabs[1];
- yield promiseTabRestoring(tab);
-
- ok(tab.hasAttribute("pending"), "Tab should be pending");
- browser = tab.linkedBrowser;
-
- // Ensure there are no pending queued messages in the child.
- yield TabStateFlusher.flush(browser);
-
- // Now check to see if the background tab remembers where it
- // should be scrolled to.
- newWin.gBrowser.selectedTab = tab;
- yield promiseTabRestored(tab);
-
- yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll is still fine");
-
- yield BrowserTestUtils.closeWindow(newWin);
-});
diff --git a/browser/components/sessionstore/test/browser_scrollPositionsReaderMode.js b/browser/components/sessionstore/test/browser_scrollPositionsReaderMode.js
deleted file mode 100644
index 735a87634..000000000
--- a/browser/components/sessionstore/test/browser_scrollPositionsReaderMode.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const BASE = "http://example.com/browser/browser/components/sessionstore/test/"
-const READER_MODE_URL = "about:reader?url=" +
- encodeURIComponent(BASE + "browser_scrollPositions_readerModeArticle.html");
-
-// Randomized set of scroll positions we will use in this test.
-const SCROLL_READER_MODE_Y = Math.round(400 * (1 + Math.random()));
-const SCROLL_READER_MODE_STR = "0," + SCROLL_READER_MODE_Y;
-
-requestLongerTimeout(2);
-
-/**
- * Test that scroll positions of about reader page after restoring background
- * tabs in a restored window (bug 1153393).
- */
-add_task(function test_scroll_background_about_reader_tabs() {
- pushPrefs(["browser.sessionstore.restore_on_demand", true]);
-
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
- let tab = newWin.gBrowser.addTab(READER_MODE_URL);
- let browser = tab.linkedBrowser;
- yield Promise.all([
- BrowserTestUtils.browserLoaded(browser),
- BrowserTestUtils.waitForContentEvent(browser, "AboutReaderContentReady")
- ]);
-
- // Scroll down a little.
- yield sendMessage(browser, "ss-test:setScrollPosition", {x: 0, y: SCROLL_READER_MODE_Y});
- yield checkScroll(tab, {scroll: SCROLL_READER_MODE_STR}, "scroll is fine");
-
- // Close the window
- yield BrowserTestUtils.closeWindow(newWin);
-
- // Now restore the window
- newWin = ss.undoCloseWindow(0);
-
- // Make sure to wait for the window to be restored.
- yield BrowserTestUtils.waitForEvent(newWin, "SSWindowStateReady");
-
- is(newWin.gBrowser.tabs.length, 2, "There should be two tabs");
-
- // The second tab should be the one we loaded URL at still
- tab = newWin.gBrowser.tabs[1];
- yield promiseTabRestoring(tab);
-
- ok(tab.hasAttribute("pending"), "Tab should be pending");
- browser = tab.linkedBrowser;
-
- // Ensure there are no pending queued messages in the child.
- yield TabStateFlusher.flush(browser);
-
- // Now check to see if the background tab remembers where it
- // should be scrolled to.
- newWin.gBrowser.selectedTab = tab;
- yield Promise.all([
- promiseTabRestored(tab),
- BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "AboutReaderContentReady")
- ]);
-
- yield checkScroll(tab, {scroll: SCROLL_READER_MODE_STR}, "scroll is still fine");
-
- yield BrowserTestUtils.closeWindow(newWin);
-});
diff --git a/browser/components/sessionstore/test/browser_scrollPositions_readerModeArticle.html b/browser/components/sessionstore/test/browser_scrollPositions_readerModeArticle.html
deleted file mode 100644
index 55452e043..000000000
--- a/browser/components/sessionstore/test/browser_scrollPositions_readerModeArticle.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Article title</title>
-<meta name="description" content="This is the article description." />
-</head>
-<body>
-<header>Site header</header>
-<div>
-<h1>Article title</h1>
-<h2 class="author">by Jane Doe</h2>
-<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
-</div>
-</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_scrollPositions_sample.html b/browser/components/sessionstore/test/browser_scrollPositions_sample.html
deleted file mode 100644
index 0182783db..000000000
--- a/browser/components/sessionstore/test/browser_scrollPositions_sample.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>browser_scrollPositions_sample.html</title>
- </head>
- <body style='width: 100000px; height: 100000px;'>top</body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_scrollPositions_sample_frameset.html b/browser/components/sessionstore/test/browser_scrollPositions_sample_frameset.html
deleted file mode 100644
index c7e363fa1..000000000
--- a/browser/components/sessionstore/test/browser_scrollPositions_sample_frameset.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>browser_scrollPositions_sample_frameset.html</title>
- </head>
- <frameset id="frames" rows="50%, 50%">
- <frame src="browser_scrollPositions_sample.html">
- <frame src="browser_scrollPositions_sample.html">
- </frameset>
-</html>
diff --git a/browser/components/sessionstore/test/browser_send_async_message_oom.js b/browser/components/sessionstore/test/browser_send_async_message_oom.js
deleted file mode 100644
index 6afd771db..000000000
--- a/browser/components/sessionstore/test/browser_send_async_message_oom.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-const HISTOGRAM_NAME = "FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM";
-
-/**
- * Test that an OOM in sendAsyncMessage in a framescript will be reported
- * to Telemetry.
- */
-
-add_task(function* init() {
- Services.telemetry.canRecordExtended = true;
-});
-
-function frameScript() {
- // Make send[A]syncMessage("SessionStore:update", ...) simulate OOM.
- // Other operations are unaffected.
- let mm = docShell.sameTypeRootTreeItem.
- QueryInterface(Ci.nsIDocShell).
- QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIContentFrameMessageManager);
-
- let wrap = function(original) {
- return function(name, ...args) {
- if (name != "SessionStore:update") {
- return original(name, ...args);
- }
- throw new Components.Exception("Simulated OOM", Cr.NS_ERROR_OUT_OF_MEMORY);
- }
- }
-
- mm.sendAsyncMessage = wrap(mm.sendAsyncMessage);
- mm.sendSyncMessage = wrap(mm.sendSyncMessage);
-}
-
-add_task(function*() {
- // Capture original state.
- let snapshot = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
-
- // Open a browser, configure it to cause OOM.
- let newTab = gBrowser.addTab("about:robots");
- let browser = newTab.linkedBrowser;
- yield ContentTask.spawn(browser, null, frameScript);
-
-
- let promiseReported = new Promise(resolve => {
- browser.messageManager.addMessageListener("SessionStore:error", resolve);
- });
-
- // Attempt to flush. This should fail.
- let promiseFlushed = TabStateFlusher.flush(browser);
- promiseFlushed.then((success) => {
- if (success) {
- throw new Error("Flush should have failed")
- }
- });
-
- // The frame script should report an error.
- yield promiseReported;
-
- // Give us some time to handle that error.
- yield new Promise(resolve => setTimeout(resolve, 10));
-
- // By now, Telemetry should have been updated.
- let snapshot2 = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
- gBrowser.removeTab(newTab);
-
- Assert.ok(snapshot2.sum > snapshot.sum);
-});
-
-add_task(function* cleanup() {
- Services.telemetry.canRecordExtended = false;
-});
diff --git a/browser/components/sessionstore/test/browser_sessionHistory.js b/browser/components/sessionstore/test/browser_sessionHistory.js
deleted file mode 100644
index f4523e06a..000000000
--- a/browser/components/sessionstore/test/browser_sessionHistory.js
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-requestLongerTimeout(2);
-
-/**
- * Ensure that starting a load invalidates shistory.
- */
-add_task(function test_load_start() {
- // Create a new tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Load a new URI.
- yield BrowserTestUtils.loadURI(browser, "about:mozilla");
-
- // Remove the tab before it has finished loading.
- yield promiseContentMessage(browser, "ss-test:OnHistoryReplaceEntry");
- yield promiseRemoveTab(tab);
-
- // Undo close the tab.
- tab = ss.undoCloseTab(window, 0);
- browser = tab.linkedBrowser;
- yield promiseTabRestored(tab);
-
- // Check that the correct URL was restored.
- is(browser.currentURI.spec, "about:mozilla", "url is correct");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that anchor navigation invalidates shistory.
- */
-add_task(function test_hashchange() {
- const URL = "data:text/html;charset=utf-8,<a id=a href=%23>clickme</a>";
-
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Check that we start with a single shistory entry.
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is one shistory entry");
-
- // Click the link and wait for a hashchange event.
- browser.messageManager.sendAsyncMessage("ss-test:click", {id: "a"});
- yield promiseContentMessage(browser, "ss-test:hashchange");
-
- // Check that we now have two shistory entries.
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 2, "there are two shistory entries");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that loading pages from the bfcache invalidates shistory.
- */
-add_task(function test_pageshow() {
- const URL = "data:text/html;charset=utf-8,<h1>first</h1>";
- const URL2 = "data:text/html;charset=utf-8,<h1>second</h1>";
-
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Create a second shistory entry.
- browser.loadURI(URL2);
- yield promiseBrowserLoaded(browser);
-
- // Go back to the previous url which is loaded from the bfcache.
- browser.goBack();
- yield promiseContentMessage(browser, "ss-test:onFrameTreeCollected");
- is(browser.currentURI.spec, URL, "correct url after going back");
-
- // Check that loading from bfcache did invalidate shistory.
- yield TabStateFlusher.flush(browser);
- let {index} = JSON.parse(ss.getTabState(tab));
- is(index, 1, "first history entry is selected");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that subframe navigation invalidates shistory.
- */
-add_task(function test_subframes() {
- const URL = "data:text/html;charset=utf-8," +
- "<iframe src=http%3A//example.com/ name=t></iframe>" +
- "<a id=a1 href=http%3A//example.com/1 target=t>clickme</a>" +
- "<a id=a2 href=http%3A//example.com/%23 target=t>clickme</a>";
-
- // Create a new tab.
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Check that we have a single shistory entry.
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is one shistory entry");
- is(entries[0].children.length, 1, "the entry has one child");
-
- // Navigate the subframe.
- browser.messageManager.sendAsyncMessage("ss-test:click", {id: "a1"});
- yield promiseBrowserLoaded(browser, false /* don't ignore subframes */);
-
- // Check shistory.
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 2, "there now are two shistory entries");
- is(entries[1].children.length, 1, "the second entry has one child");
-
- // Go back in history.
- browser.goBack();
- yield promiseBrowserLoaded(browser, false /* don't ignore subframes */);
-
- // Navigate the subframe again.
- browser.messageManager.sendAsyncMessage("ss-test:click", {id: "a2"});
- yield promiseContentMessage(browser, "ss-test:hashchange");
-
- // Check shistory.
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 2, "there now are two shistory entries");
- is(entries[1].children.length, 1, "the second entry has one child");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that navigating from an about page invalidates shistory.
- */
-add_task(function test_about_page_navigate() {
- // Create a new tab.
- let tab = gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Check that we have a single shistory entry.
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is one shistory entry");
- is(entries[0].url, "about:blank", "url is correct");
-
- browser.loadURI("about:robots");
- yield promiseBrowserLoaded(browser);
-
- // Check that we have changed the history entry.
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 1, "there is one shistory entry");
- is(entries[0].url, "about:robots", "url is correct");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that history.pushState and history.replaceState invalidate shistory.
- */
-add_task(function test_pushstate_replacestate() {
- // Create a new tab.
- let tab = gBrowser.addTab("http://example.com/1");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Check that we have a single shistory entry.
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
- is(entries.length, 1, "there is one shistory entry");
- is(entries[0].url, "http://example.com/1", "url is correct");
-
- yield ContentTask.spawn(browser, {}, function* () {
- content.window.history.pushState({}, "", 'test-entry/');
- });
-
- // Check that we have added the history entry.
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 2, "there is another shistory entry");
- is(entries[1].url, "http://example.com/test-entry/", "url is correct");
-
- yield ContentTask.spawn(browser, {}, function* () {
- content.window.history.replaceState({}, "", "test-entry2/");
- });
-
- // Check that we have modified the history entry.
- yield TabStateFlusher.flush(browser);
- ({entries} = JSON.parse(ss.getTabState(tab)));
- is(entries.length, 2, "there is still two shistory entries");
- is(entries[1].url, "http://example.com/test-entry/test-entry2/", "url is correct");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that slow loading subframes will invalidate shistory.
- */
-add_task(function test_slow_subframe_load() {
- const SLOW_URL = "http://mochi.test:8888/browser/browser/components/" +
- "sessionstore/test/browser_sessionHistory_slow.sjs";
-
- const URL = "data:text/html;charset=utf-8," +
- "<frameset cols=50%25,50%25>" +
- "<frame src='" + SLOW_URL + "'>" +
- "</frameset>";
-
- // Add a new tab with a slow loading subframe
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- yield TabStateFlusher.flush(browser);
- let {entries} = JSON.parse(ss.getTabState(tab));
-
- // Check the number of children.
- is(entries.length, 1, "there is one root entry ...");
- is(entries[0].children.length, 1, "... with one child entries");
-
- // Check URLs.
- ok(entries[0].url.startsWith("data:text/html"), "correct root url");
- is(entries[0].children[0].url, SLOW_URL, "correct url for subframe");
-
- // Cleanup.
- gBrowser.removeTab(tab);
-});
diff --git a/browser/components/sessionstore/test/browser_sessionHistory_slow.sjs b/browser/components/sessionstore/test/browser_sessionHistory_slow.sjs
deleted file mode 100644
index 41da3c2ad..000000000
--- a/browser/components/sessionstore/test/browser_sessionHistory_slow.sjs
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const DELAY_MS = "2000";
-
-let timer;
-
-function handleRequest(req, resp) {
- resp.processAsync();
- resp.setHeader("Cache-Control", "no-cache", false);
- resp.setHeader("Content-Type", "text/html;charset=utf-8", false);
-
- timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.init(() => {
- resp.write("hi");
- resp.finish();
- }, DELAY_MS, Ci.nsITimer.TYPE_ONE_SHOT);
-}
diff --git a/browser/components/sessionstore/test/browser_sessionStorage.html b/browser/components/sessionstore/test/browser_sessionStorage.html
deleted file mode 100644
index 7e2dccf4a..000000000
--- a/browser/components/sessionstore/test/browser_sessionStorage.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <title>browser_sessionStorage.html</title>
- </head>
- <body>
- <script type="text/javascript;version=1.8">
- let isOuter = window == window.top;
- let args = window.location.search.slice(1).split("&");
- let rand = args[0];
-
- if (isOuter) {
- let iframe = document.createElement("iframe");
- let isSecure = args.indexOf("secure") > -1;
- let scheme = isSecure ? "https" : "http";
- iframe.setAttribute("src", scheme + "://example.com" + location.pathname + "?" + rand);
- document.body.appendChild(iframe);
- }
-
- if (sessionStorage.length === 0) {
- sessionStorage.test = (isOuter ? "outer" : "inner") + "-value-" + rand;
- document.title = sessionStorage.test;
- }
- </script>
- </body>
-</html>
diff --git a/browser/components/sessionstore/test/browser_sessionStorage.js b/browser/components/sessionstore/test/browser_sessionStorage.js
deleted file mode 100644
index b580c5cc2..000000000
--- a/browser/components/sessionstore/test/browser_sessionStorage.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const RAND = Math.random();
-const URL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_sessionStorage.html" +
- "?" + RAND;
-
-const OUTER_VALUE = "outer-value-" + RAND;
-const INNER_VALUE = "inner-value-" + RAND;
-
-/**
- * This test ensures that setting, modifying and restoring sessionStorage data
- * works as expected.
- */
-add_task(function session_storage() {
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser);
-
- let {storage} = JSON.parse(ss.getTabState(tab));
- is(storage["http://example.com"].test, INNER_VALUE,
- "sessionStorage data for example.com has been serialized correctly");
- is(storage["http://mochi.test:8888"].test, OUTER_VALUE,
- "sessionStorage data for mochi.test has been serialized correctly");
-
- // Ensure that modifying sessionStore values works for the inner frame only.
- yield modifySessionStorage(browser, {test: "modified1"}, {frameIndex: 0});
- yield TabStateFlusher.flush(browser);
-
- ({storage} = JSON.parse(ss.getTabState(tab)));
- is(storage["http://example.com"].test, "modified1",
- "sessionStorage data for example.com has been serialized correctly");
- is(storage["http://mochi.test:8888"].test, OUTER_VALUE,
- "sessionStorage data for mochi.test has been serialized correctly");
-
- // Ensure that modifying sessionStore values works for both frames.
- yield modifySessionStorage(browser, {test: "modified"});
- yield modifySessionStorage(browser, {test: "modified2"}, {frameIndex: 0});
- yield TabStateFlusher.flush(browser);
-
- ({storage} = JSON.parse(ss.getTabState(tab)));
- is(storage["http://example.com"].test, "modified2",
- "sessionStorage data for example.com has been serialized correctly");
- is(storage["http://mochi.test:8888"].test, "modified",
- "sessionStorage data for mochi.test has been serialized correctly");
-
- // Test that duplicating a tab works.
- let tab2 = gBrowser.duplicateTab(tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2);
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser2);
-
- ({storage} = JSON.parse(ss.getTabState(tab2)));
- is(storage["http://example.com"].test, "modified2",
- "sessionStorage data for example.com has been duplicated correctly");
- is(storage["http://mochi.test:8888"].test, "modified",
- "sessionStorage data for mochi.test has been duplicated correctly");
-
- // Ensure that the content script retains restored data
- // (by e.g. duplicateTab) and sends it along with new data.
- yield modifySessionStorage(browser2, {test: "modified3"});
- yield TabStateFlusher.flush(browser2);
-
- ({storage} = JSON.parse(ss.getTabState(tab2)));
- is(storage["http://example.com"].test, "modified2",
- "sessionStorage data for example.com has been duplicated correctly");
- is(storage["http://mochi.test:8888"].test, "modified3",
- "sessionStorage data for mochi.test has been duplicated correctly");
-
- // Check that loading a new URL discards data.
- browser2.loadURI("http://mochi.test:8888/");
- yield promiseBrowserLoaded(browser2);
- yield TabStateFlusher.flush(browser2);
-
- ({storage} = JSON.parse(ss.getTabState(tab2)));
- is(storage["http://mochi.test:8888"].test, "modified3",
- "navigating retains correct storage data");
- ok(!storage["http://example.com"], "storage data was discarded");
-
- // Check that loading a new URL discards data.
- browser2.loadURI("about:mozilla");
- yield promiseBrowserLoaded(browser2);
- yield TabStateFlusher.flush(browser2);
-
- let state = JSON.parse(ss.getTabState(tab2));
- ok(!state.hasOwnProperty("storage"), "storage data was discarded");
-
- // Clean up.
- yield promiseRemoveTab(tab);
- yield promiseRemoveTab(tab2);
-});
-
-/**
- * This test ensures that purging domain data also purges data from the
- * sessionStorage data collected for tabs.
- */
-add_task(function purge_domain() {
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Purge data for "mochi.test".
- yield purgeDomainData(browser, "mochi.test");
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser);
-
- let {storage} = JSON.parse(ss.getTabState(tab));
- ok(!storage["http://mochi.test:8888"],
- "sessionStorage data for mochi.test has been purged");
- is(storage["http://example.com"].test, INNER_VALUE,
- "sessionStorage data for example.com has been preserved");
-
- yield promiseRemoveTab(tab);
-});
-
-/**
- * This test ensures that collecting sessionStorage data respects the privacy
- * levels as set by the user.
- */
-add_task(function respect_privacy_level() {
- let tab = gBrowser.addTab(URL + "&secure");
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield promiseRemoveTab(tab);
-
- let [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- is(storage["http://mochi.test:8888"].test, OUTER_VALUE,
- "http sessionStorage data has been saved");
- is(storage["https://example.com"].test, INNER_VALUE,
- "https sessionStorage data has been saved");
-
- // Disable saving data for encrypted sites.
- Services.prefs.setIntPref("browser.sessionstore.privacy_level", 1);
-
- tab = gBrowser.addTab(URL + "&secure");
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield promiseRemoveTab(tab);
-
- [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- is(storage["http://mochi.test:8888"].test, OUTER_VALUE,
- "http sessionStorage data has been saved");
- ok(!storage["https://example.com"],
- "https sessionStorage data has *not* been saved");
-
- // Disable saving data for any site.
- Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2);
-
- // Check that duplicating a tab copies all private data.
- tab = gBrowser.addTab(URL + "&secure");
- yield promiseBrowserLoaded(tab.linkedBrowser);
- let tab2 = gBrowser.duplicateTab(tab);
- yield promiseTabRestored(tab2);
- yield promiseRemoveTab(tab);
-
- // With privacy_level=2 the |tab| shouldn't have any sessionStorage data.
- [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- ok(!storage, "sessionStorage data has *not* been saved");
-
- // Remove all closed tabs before continuing with the next test.
- // As Date.now() isn't monotonic we might sometimes check
- // the wrong closedTabData entry.
- while (ss.getClosedTabCount(window) > 0) {
- ss.forgetClosedTab(window, 0);
- }
-
- // Restore the default privacy level and close the duplicated tab.
- Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
- yield promiseRemoveTab(tab2);
-
- // With privacy_level=0 the duplicated |tab2| should persist all data.
- [{state: {storage}}] = JSON.parse(ss.getClosedTabData(window));
- is(storage["http://mochi.test:8888"].test, OUTER_VALUE,
- "http sessionStorage data has been saved");
- is(storage["https://example.com"].test, INNER_VALUE,
- "https sessionStorage data has been saved");
-});
-
-function purgeDomainData(browser, domain) {
- return sendMessage(browser, "ss-test:purgeDomainData", domain);
-}
diff --git a/browser/components/sessionstore/test/browser_sessionStorage_size.js b/browser/components/sessionstore/test/browser_sessionStorage_size.js
deleted file mode 100644
index d1d894611..000000000
--- a/browser/components/sessionstore/test/browser_sessionStorage_size.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const RAND = Math.random();
-const URL = "http://mochi.test:8888/browser/" +
- "browser/components/sessionstore/test/browser_sessionStorage.html" +
- "?" + RAND;
-
-const OUTER_VALUE = "outer-value-" + RAND;
-
-// Test that we record the size of messages.
-add_task(function* test_telemetry() {
- Services.telemetry.canRecordExtended = true;
- let histogram = Services.telemetry.getHistogramById("FX_SESSION_RESTORE_DOM_STORAGE_SIZE_ESTIMATE_CHARS");
- let snap1 = histogram.snapshot();
-
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser);
- let snap2 = histogram.snapshot();
-
- Assert.ok(snap2.counts[5] > snap1.counts[5]);
- yield promiseRemoveTab(tab);
- Services.telemetry.canRecordExtended = false;
-});
-
-// Lower the size limit for DOM Storage content. Check that DOM Storage
-// is not updated, but that other things remain updated.
-add_task(function* test_large_content() {
- Services.prefs.setIntPref("browser.sessionstore.dom_storage_limit", 5);
-
- let tab = gBrowser.addTab(URL);
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
-
- // Flush to make sure chrome received all data.
- yield TabStateFlusher.flush(browser);
-
- let state = JSON.parse(ss.getTabState(tab));
- info(JSON.stringify(state, null, "\t"));
- Assert.equal(state.storage, null, "We have no storage for the tab");
- Assert.equal(state.entries[0].title, OUTER_VALUE);
- yield promiseRemoveTab(tab);
-
- Services.prefs.clearUserPref("browser.sessionstore.dom_storage_limit");
-});
diff --git a/browser/components/sessionstore/test/browser_sessionStoreContainer.js b/browser/components/sessionstore/test/browser_sessionStoreContainer.js
deleted file mode 100644
index 1bc9537e2..000000000
--- a/browser/components/sessionstore/test/browser_sessionStoreContainer.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-add_task(function* () {
- for (let i = 0; i < 3; ++i) {
- let tab = gBrowser.addTab("http://example.com/", { userContextId: i });
- let browser = tab.linkedBrowser;
-
- yield promiseBrowserLoaded(browser);
-
- let tab2 = gBrowser.duplicateTab(tab);
- Assert.equal(tab2.getAttribute("usercontextid"), i);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2)
-
- yield ContentTask.spawn(browser2, { expectedId: i }, function* (args) {
- let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
- Assert.equal(loadContext.originAttributes.userContextId,
- args.expectedId, "The docShell has the correct userContextId");
- });
-
- yield promiseRemoveTab(tab);
- yield promiseRemoveTab(tab2);
- }
-});
-
-add_task(function* () {
- let tab = gBrowser.addTab("http://example.com/", { userContextId: 1 });
- let browser = tab.linkedBrowser;
-
- yield promiseBrowserLoaded(browser);
-
- gBrowser.selectedTab = tab;
-
- let tab2 = gBrowser.duplicateTab(tab);
- let browser2 = tab2.linkedBrowser;
- yield promiseTabRestored(tab2)
-
- yield ContentTask.spawn(browser2, { expectedId: 1 }, function* (args) {
- Assert.equal(docShell.getOriginAttributes().userContextId,
- args.expectedId,
- "The docShell has the correct userContextId");
- });
-
- yield promiseRemoveTab(tab);
- yield promiseRemoveTab(tab2);
-});
-
-add_task(function* () {
- let tab = gBrowser.addTab("http://example.com/", { userContextId: 1 });
- let browser = tab.linkedBrowser;
-
- yield promiseBrowserLoaded(browser);
-
- gBrowser.removeTab(tab);
-
- let tab2 = ss.undoCloseTab(window, 0);
- Assert.equal(tab2.getAttribute("usercontextid"), 1);
- yield promiseTabRestored(tab2);
- yield ContentTask.spawn(tab2.linkedBrowser, { expectedId: 1 }, function* (args) {
- Assert.equal(docShell.getOriginAttributes().userContextId,
- args.expectedId,
- "The docShell has the correct userContextId");
- });
-
- yield promiseRemoveTab(tab2);
-});
-
-// Opens "uri" in a new tab with the provided userContextId and focuses it.
-// Returns the newly opened tab.
-function* openTabInUserContext(userContextId) {
- // Open the tab in the correct userContextId.
- let tab = gBrowser.addTab("http://example.com", { userContextId });
-
- // Select tab and make sure its browser is focused.
- gBrowser.selectedTab = tab;
- tab.ownerGlobal.focus();
-
- let browser = gBrowser.getBrowserForTab(tab);
- yield BrowserTestUtils.browserLoaded(browser);
- return { tab, browser };
-}
-
-function waitForNewCookie() {
- return new Promise(resolve => {
- Services.obs.addObserver(function observer(subj, topic, data) {
- let cookie = subj.QueryInterface(Ci.nsICookie2);
- if (data == "added") {
- Services.obs.removeObserver(observer, topic);
- resolve();
- }
- }, "cookie-changed", false);
- });
-}
-
-add_task(function* test() {
- const USER_CONTEXTS = [
- "default",
- "personal",
- "work",
- ];
-
- const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
- const { TabStateFlusher } = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
- // Make sure userContext is enabled.
- yield SpecialPowers.pushPrefEnv({
- "set": [ [ "privacy.userContext.enabled", true ] ]
- });
-
- let lastSessionRestore;
- for (let userContextId of Object.keys(USER_CONTEXTS)) {
- // Load the page in 3 different contexts and set a cookie
- // which should only be visible in that context.
- let cookie = USER_CONTEXTS[userContextId];
-
- // Open our tab in the given user context.
- let { tab, browser } = yield* openTabInUserContext(userContextId);
-
- yield Promise.all([
- waitForNewCookie(),
- ContentTask.spawn(browser, cookie, cookie => content.document.cookie = cookie)
- ]);
-
- // Ensure the tab's session history is up-to-date.
- yield TabStateFlusher.flush(browser);
-
- lastSessionRestore = ss.getWindowState(window);
-
- // Remove the tab.
- gBrowser.removeTab(tab);
- }
-
- let state = JSON.parse(lastSessionRestore);
- is(state.windows[0].cookies.length, USER_CONTEXTS.length,
- "session restore should have each container's cookie");
-});
-
diff --git a/browser/components/sessionstore/test/browser_swapDocShells.js b/browser/components/sessionstore/test/browser_swapDocShells.js
deleted file mode 100644
index 839f060e7..000000000
--- a/browser/components/sessionstore/test/browser_swapDocShells.js
+++ /dev/null
@@ -1,35 +0,0 @@
-"use strict";
-
-add_task(function* () {
- let tab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla");
- yield promiseBrowserLoaded(gBrowser.selectedBrowser);
-
- let win = gBrowser.replaceTabWithWindow(tab);
- yield promiseDelayedStartupFinished(win);
- yield promiseBrowserHasURL(win.gBrowser.browsers[0], "about:mozilla");
-
- win.duplicateTabIn(win.gBrowser.selectedTab, "tab");
- yield promiseTabRestored(win.gBrowser.tabs[1]);
-
- let browser = win.gBrowser.browsers[1];
- is(browser.currentURI.spec, "about:mozilla", "tab was duplicated");
-
- yield BrowserTestUtils.closeWindow(win);
-});
-
-function promiseDelayedStartupFinished(win) {
- let deferred = Promise.defer();
- whenDelayedStartupFinished(win, deferred.resolve);
- return deferred.promise;
-}
-
-function promiseBrowserHasURL(browser, url) {
- let promise = Promise.resolve();
-
- if (browser.contentDocument.readyState === "complete" &&
- browser.currentURI.spec === url) {
- return promise;
- }
-
- return promise.then(() => promiseBrowserHasURL(browser, url));
-}
diff --git a/browser/components/sessionstore/test/browser_switch_remoteness.js b/browser/components/sessionstore/test/browser_switch_remoteness.js
deleted file mode 100644
index 9eb8c260a..000000000
--- a/browser/components/sessionstore/test/browser_switch_remoteness.js
+++ /dev/null
@@ -1,49 +0,0 @@
-"use strict";
-
-const URL = "http://example.com/browser_switch_remoteness_";
-
-function countHistoryEntries(browser, expected) {
- return ContentTask.spawn(browser, { expected }, function* (args) {
- let Ci = Components.interfaces;
- let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
- let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal);
- Assert.equal(history && history.count, args.expected,
- "correct number of shistory entries");
- });
-}
-
-add_task(function* () {
- // Open a new window.
- let win = yield promiseNewWindowLoaded();
-
- // Add a new tab.
- let tab = win.gBrowser.addTab("about:blank");
- let browser = tab.linkedBrowser;
- yield promiseBrowserLoaded(browser);
- ok(browser.isRemoteBrowser, "browser is remote");
-
- // Get the maximum number of preceding entries to save.
- const MAX_BACK = Services.prefs.getIntPref("browser.sessionstore.max_serialize_back");
- ok(MAX_BACK > -1, "check that the default has a value that caps data");
-
- // Load more pages than we would save to disk on a clean shutdown.
- for (let i = 0; i < MAX_BACK + 2; i++) {
- browser.loadURI(URL + i);
- yield promiseBrowserLoaded(browser);
- ok(browser.isRemoteBrowser, "browser is still remote");
- }
-
- // Check we have the right number of shistory entries.
- yield countHistoryEntries(browser, MAX_BACK + 2);
-
- // Load a non-remote page.
- browser.loadURI("about:robots");
- yield promiseTabRestored(tab);
- ok(!browser.isRemoteBrowser, "browser is not remote anymore");
-
- // Check that we didn't lose any shistory entries.
- yield countHistoryEntries(browser, MAX_BACK + 3);
-
- // Cleanup.
- yield BrowserTestUtils.closeWindow(win);
-});
diff --git a/browser/components/sessionstore/test/browser_undoCloseById.js b/browser/components/sessionstore/test/browser_undoCloseById.js
deleted file mode 100644
index f2f0f919c..000000000
--- a/browser/components/sessionstore/test/browser_undoCloseById.js
+++ /dev/null
@@ -1,118 +0,0 @@
-"use strict";
-
-/**
- * This test is for the undoCloseById function.
- */
-
-Cu.import("resource:///modules/sessionstore/SessionStore.jsm");
-
-function openAndCloseTab(window, url) {
- let tab = window.gBrowser.addTab(url);
- yield promiseBrowserLoaded(tab.linkedBrowser, true, url);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- yield promiseRemoveTab(tab);
-}
-
-function* openWindow(url) {
- let win = yield promiseNewWindowLoaded();
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
- win.gBrowser.selectedBrowser.loadURIWithFlags(url, flags);
- yield promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, url);
- return win;
-}
-
-function closeWindow(win) {
- yield BrowserTestUtils.closeWindow(win);
- // Wait 20 ms to allow SessionStorage a chance to register the closed window.
- yield new Promise(resolve => setTimeout(resolve, 20));
-}
-
-add_task(function* test_undoCloseById() {
- // Clear the lists of closed windows and tabs.
- forgetClosedWindows();
- while (SessionStore.getClosedTabCount(window)) {
- SessionStore.forgetClosedTab(window, 0);
- }
-
- // Open a new window.
- let win = yield openWindow("about:robots");
-
- // Open and close a tab.
- yield openAndCloseTab(win, "about:mozilla");
- is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab");
-
- // Record the first closedId created.
- let initialClosedId = SessionStore.getClosedTabData(win, false)[0].closedId;
-
- // Open and close another window.
- let win2 = yield openWindow("about:mozilla");
- yield closeWindow(win2); // closedId == initialClosedId + 1
- is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window");
-
- // Open and close another tab in the first window.
- yield openAndCloseTab(win, "about:robots"); // closedId == initialClosedId + 2
- is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab");
-
- // Undo closing the second tab.
- let tab = SessionStore.undoCloseById(initialClosedId + 2);
- yield promiseBrowserLoaded(tab.linkedBrowser);
- is(tab.linkedBrowser.currentURI.spec, "about:robots", "The expected tab was re-opened");
-
- let notTab = SessionStore.undoCloseById(initialClosedId + 2);
- is(notTab, undefined, "Re-opened tab cannot be unClosed again by closedId");
-
- // Now the last closed object should be a window again.
- is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window");
-
- // Undo closing the first tab.
- let tab2 = SessionStore.undoCloseById(initialClosedId);
- yield promiseBrowserLoaded(tab2.linkedBrowser);
- is(tab2.linkedBrowser.currentURI.spec, "about:mozilla", "The expected tab was re-opened");
-
- // Close the two tabs we re-opened.
- yield promiseRemoveTab(tab); // closedId == initialClosedId + 3
- is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab");
- yield promiseRemoveTab(tab2); // closedId == initialClosedId + 4
- is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab");
-
- // Open another new window.
- let win3 = yield openWindow("about:mozilla");
-
- // Close both windows.
- yield closeWindow(win); // closedId == initialClosedId + 5
- is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window");
- yield closeWindow(win3); // closedId == initialClosedId + 6
- is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window");
-
- // Undo closing the second window.
- win = SessionStore.undoCloseById(initialClosedId + 6);
- yield BrowserTestUtils.waitForEvent(win, "load");
-
- // Make sure we wait until this window is restored.
- yield BrowserTestUtils.waitForEvent(win.gBrowser.tabContainer,
- "SSTabRestored");
-
- is(win.gBrowser.selectedBrowser.currentURI.spec, "about:mozilla", "The expected window was re-opened");
-
- let notWin = SessionStore.undoCloseById(initialClosedId + 6);
- is(notWin, undefined, "Re-opened window cannot be unClosed again by closedId");
-
- // Close the window again.
- yield closeWindow(win);
- is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window");
-
- // Undo closing the first window.
- win = SessionStore.undoCloseById(initialClosedId + 5);
-
- yield BrowserTestUtils.waitForEvent(win, "load");
-
- // Make sure we wait until this window is restored.
- yield BrowserTestUtils.waitForEvent(win.gBrowser.tabContainer,
- "SSTabRestored");
-
- is(win.gBrowser.selectedBrowser.currentURI.spec, "about:robots", "The expected window was re-opened");
-
- // Close the window again.
- yield closeWindow(win);
- is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window");
-});
diff --git a/browser/components/sessionstore/test/browser_unrestored_crashedTabs.js b/browser/components/sessionstore/test/browser_unrestored_crashedTabs.js
deleted file mode 100644
index e46348e59..000000000
--- a/browser/components/sessionstore/test/browser_unrestored_crashedTabs.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * Tests that if we have tabs that are still in the "click to
- * restore" state, that if their browsers crash, that we don't
- * show the crashed state for those tabs (since selecting them
- * should restore them anyway).
- */
-
-const PREF = "browser.sessionstore.restore_on_demand";
-const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-
-add_task(function* test() {
- yield pushPrefs([PREF, true]);
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: PAGE,
- }, function*(browser) {
- yield TabStateFlusher.flush(browser);
-
- // We'll create a second "pending" tab. This is the one we'll
- // ensure doesn't go to about:tabcrashed. We start it non-remote
- // since this is how SessionStore creates all browsers before
- // they are restored.
- let unrestoredTab = gBrowser.addTab("about:blank", {
- skipAnimation: true,
- forceNotRemote: true,
- });
-
- let state = {
- entries: [{url: PAGE}],
- };
-
- ss.setTabState(unrestoredTab, JSON.stringify(state));
-
- ok(!unrestoredTab.hasAttribute("crashed"), "tab is not crashed");
- ok(unrestoredTab.hasAttribute("pending"), "tab is pending");
-
- // Now crash the selected browser.
- yield BrowserTestUtils.crashBrowser(browser);
-
- ok(!unrestoredTab.hasAttribute("crashed"), "tab is still not crashed");
- ok(unrestoredTab.hasAttribute("pending"), "tab is still pending");
-
- // Selecting the tab should now restore it.
- gBrowser.selectedTab = unrestoredTab;
- yield promiseTabRestored(unrestoredTab);
-
- ok(!unrestoredTab.hasAttribute("crashed"), "tab is still not crashed");
- ok(!unrestoredTab.hasAttribute("pending"), "tab is no longer pending");
-
- // The original tab should still be crashed
- let originalTab = gBrowser.getTabForBrowser(browser);
- ok(originalTab.hasAttribute("crashed"), "original tab is crashed");
- ok(!originalTab.isRemoteBrowser, "Should not be remote");
-
- // We'd better be able to restore it still.
- gBrowser.selectedTab = originalTab;
- SessionStore.reviveCrashedTab(originalTab);
- yield promiseTabRestored(originalTab);
-
- // Clean up.
- yield BrowserTestUtils.removeTab(unrestoredTab);
- });
-});
diff --git a/browser/components/sessionstore/test/browser_upgrade_backup.js b/browser/components/sessionstore/test/browser_upgrade_backup.js
deleted file mode 100644
index 768671051..000000000
--- a/browser/components/sessionstore/test/browser_upgrade_backup.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://gre/modules/Services.jsm", this);
-Cu.import("resource://gre/modules/osfile.jsm", this);
-Cu.import("resource://gre/modules/Task.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm", this);
-
-const Paths = SessionFile.Paths;
-const PREF_UPGRADE = "browser.sessionstore.upgradeBackup.latestBuildID";
-const PREF_MAX_UPGRADE_BACKUPS = "browser.sessionstore.upgradeBackup.maxUpgradeBackups";
-
-/**
- * Prepares tests by retrieving the current platform's build ID, clearing the
- * build where the last backup was created and creating arbitrary JSON data
- * for a new backup.
- */
-var prepareTest = Task.async(function* () {
- let result = {};
-
- result.buildID = Services.appinfo.platformBuildID;
- Services.prefs.setCharPref(PREF_UPGRADE, "");
- result.contents = JSON.stringify({"browser_upgrade_backup.js": Math.random()});
-
- return result;
-});
-
-/**
- * Retrieves all upgrade backups and returns them in an array.
- */
-var getUpgradeBackups = Task.async(function* () {
- let iterator;
- let backups = [];
- let upgradeBackupPrefix = Paths.upgradeBackupPrefix;
-
- try {
- iterator = new OS.File.DirectoryIterator(Paths.backups);
-
- // iterate over all files in the backup directory
- yield iterator.forEach(function (file) {
- // check the upgradeBackupPrefix
- if (file.path.startsWith(Paths.upgradeBackupPrefix)) {
- // the file is a backup
- backups.push(file.path);
- }
- }, this);
- } finally {
- if (iterator) {
- iterator.close();
- }
- }
-
- // return results
- return backups;
-});
-
-add_task(function* init() {
- // Wait until initialization is complete
- yield SessionStore.promiseInitialized;
- yield SessionFile.wipe();
-});
-
-add_task(function* test_upgrade_backup() {
- let test = yield prepareTest();
- info("Let's check if we create an upgrade backup");
- yield OS.File.writeAtomic(Paths.clean, test.contents);
- yield SessionFile.read(); // First call to read() initializes the SessionWorker
- yield SessionFile.write(""); // First call to write() triggers the backup
-
- is(Services.prefs.getCharPref(PREF_UPGRADE), test.buildID, "upgrade backup should be set");
-
- is((yield OS.File.exists(Paths.upgradeBackup)), true, "upgrade backup file has been created");
-
- let data = yield OS.File.read(Paths.upgradeBackup);
- is(test.contents, (new TextDecoder()).decode(data), "upgrade backup contains the expected contents");
-
- info("Let's check that we don't overwrite this upgrade backup");
- let newContents = JSON.stringify({"something else entirely": Math.random()});
- yield OS.File.writeAtomic(Paths.clean, newContents);
- yield SessionFile.read(); // Reinitialize the SessionWorker
- yield SessionFile.write(""); // Next call to write() shouldn't trigger the backup
- data = yield OS.File.read(Paths.upgradeBackup);
- is(test.contents, (new TextDecoder()).decode(data), "upgrade backup hasn't changed");
-});
-
-add_task(function* test_upgrade_backup_removal() {
- let test = yield prepareTest();
- let maxUpgradeBackups = Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3);
- info("Let's see if we remove backups if there are too many");
- yield OS.File.writeAtomic(Paths.clean, test.contents);
-
- // if the nextUpgradeBackup already exists (from another test), remove it
- if (OS.File.exists(Paths.nextUpgradeBackup)) {
- yield OS.File.remove(Paths.nextUpgradeBackup);
- }
-
- // create dummy backups
- yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20080101010101", "");
- yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20090101010101", "");
- yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20100101010101", "");
- yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20110101010101", "");
- yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20120101010101", "");
- yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20130101010101", "");
-
- // get currently existing backups
- let backups = yield getUpgradeBackups();
-
- // trigger new backup
- yield SessionFile.read(); // First call to read() initializes the SessionWorker
- yield SessionFile.write(""); // First call to write() triggers the backup and the cleanup
-
- // a new backup should have been created (and still exist)
- is(Services.prefs.getCharPref(PREF_UPGRADE), test.buildID, "upgrade backup should be set");
- is((yield OS.File.exists(Paths.upgradeBackup)), true, "upgrade backup file has been created");
-
- // get currently existing backups and check their count
- let newBackups = yield getUpgradeBackups();
- is(newBackups.length, maxUpgradeBackups, "expected number of backups are present after removing old backups");
-
- // find all backups that were created during the last call to `SessionFile.write("");`
- // ie, filter out all the backups that have already been present before the call
- newBackups = newBackups.filter(function (backup) {
- return backups.indexOf(backup) < 0;
- });
-
- // check that exactly one new backup was created
- is(newBackups.length, 1, "one new backup was created that was not removed");
-
- yield SessionFile.write(""); // Second call to write() should not trigger anything
-
- backups = yield getUpgradeBackups();
- is(backups.length, maxUpgradeBackups, "second call to SessionFile.write() didn't create or remove more backups");
-});
-
diff --git a/browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js b/browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js
deleted file mode 100644
index 781692909..000000000
--- a/browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This test checks that closed private windows can't be restored
-
-function test() {
- waitForExplicitFinish();
-
- // 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, false);
- executeSoon(function () {
- is(ss.getClosedWindowCount(), 0,
- "The private window should not have been stored");
- });
- }, false);
- BrowserTestUtils.closeWindow(win).then(finish);
- });
-}
diff --git a/browser/components/sessionstore/test/browser_windowStateContainer.js b/browser/components/sessionstore/test/browser_windowStateContainer.js
deleted file mode 100644
index beb838088..000000000
--- a/browser/components/sessionstore/test/browser_windowStateContainer.js
+++ /dev/null
@@ -1,122 +0,0 @@
-"use strict";
-
-requestLongerTimeout(2);
-
-add_task(function* setup() {
- yield SpecialPowers.pushPrefEnv({
- set: [["dom.ipc.processCount", 1]]
- });
-});
-
-add_task(function* () {
- let win = yield BrowserTestUtils.openNewBrowserWindow();
-
- // Create 4 tabs with different userContextId.
- for (let userContextId = 1; userContextId < 5; userContextId++) {
- let tab = win.gBrowser.addTab("http://example.com/", {userContextId});
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- }
-
- // Move the default tab of window to the end.
- // We want the 1st tab to have non-default userContextId, so later when we
- // restore into win2 we can test restore into an existing tab with different
- // userContextId.
- win.gBrowser.moveTabTo(win.gBrowser.tabs[0], win.gBrowser.tabs.length - 1);
-
- let winState = JSON.parse(ss.getWindowState(win));
-
- for (let i = 0; i < 4; i++) {
- Assert.equal(winState.windows[0].tabs[i].userContextId, i + 1,
- "1st Window: tabs[" + i + "].userContextId should exist.");
- }
-
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- // Create tabs with different userContextId, but this time we create them with
- // fewer tabs and with different order with win.
- for (let userContextId = 3; userContextId > 0; userContextId--) {
- let tab = win2.gBrowser.addTab("http://example.com/", {userContextId});
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
- }
-
- ss.setWindowState(win2, JSON.stringify(winState), true);
-
- for (let i = 0; i < 4; i++) {
- let browser = win2.gBrowser.tabs[i].linkedBrowser;
- yield ContentTask.spawn(browser, { expectedId: i + 1 }, function* (args) {
- Assert.equal(docShell.getOriginAttributes().userContextId,
- args.expectedId,
- "The docShell has the correct userContextId");
-
- Assert.equal(content.document.nodePrincipal.originAttributes.userContextId,
- args.expectedId,
- "The document has the correct userContextId");
- });
- }
-
- // Test the last tab, which doesn't have userContextId.
- let browser = win2.gBrowser.tabs[4].linkedBrowser;
- yield ContentTask.spawn(browser, { expectedId: 0 }, function* (args) {
- Assert.equal(docShell.getOriginAttributes().userContextId,
- args.expectedId,
- "The docShell has the correct userContextId");
-
- Assert.equal(content.document.nodePrincipal.originAttributes.userContextId,
- args.expectedId,
- "The document has the correct userContextId");
- });
-
- yield BrowserTestUtils.closeWindow(win);
- yield BrowserTestUtils.closeWindow(win2);
-});
-
-add_task(function* () {
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- yield TabStateFlusher.flush(win.gBrowser.selectedBrowser);
-
- let tab = win.gBrowser.addTab("http://example.com/", { userContextId: 1 });
- yield promiseBrowserLoaded(tab.linkedBrowser);
- yield TabStateFlusher.flush(tab.linkedBrowser);
-
- // win should have 1 default tab, and 1 container tab.
- Assert.equal(win.gBrowser.tabs.length, 2, "win should have 2 tabs");
-
- let winState = JSON.parse(ss.getWindowState(win));
-
- for (let i = 0; i < 2; i++) {
- Assert.equal(winState.windows[0].tabs[i].userContextId, i,
- "1st Window: tabs[" + i + "].userContextId should be " + i);
- }
-
- let win2 = yield BrowserTestUtils.openNewBrowserWindow();
-
- let tab2 = win2.gBrowser.addTab("http://example.com/", { userContextId : 1 });
- yield promiseBrowserLoaded(tab2.linkedBrowser);
- yield TabStateFlusher.flush(tab2.linkedBrowser);
-
- // Move the first normal tab to end, so the first tab of win2 will be a
- // container tab.
- win2.gBrowser.moveTabTo(win2.gBrowser.tabs[0], win2.gBrowser.tabs.length - 1);
- yield TabStateFlusher.flush(win2.gBrowser.tabs[0].linkedBrowser);
-
- ss.setWindowState(win2, JSON.stringify(winState), true);
-
- for (let i = 0; i < 2; i++) {
- let browser = win2.gBrowser.tabs[i].linkedBrowser;
- yield ContentTask.spawn(browser, { expectedId: i }, function* (args) {
- Assert.equal(docShell.getOriginAttributes().userContextId,
- args.expectedId,
- "The docShell has the correct userContextId");
-
- Assert.equal(content.document.nodePrincipal.originAttributes.userContextId,
- args.expectedId,
- "The document has the correct userContextId");
- });
- }
-
- yield BrowserTestUtils.closeWindow(win);
- yield BrowserTestUtils.closeWindow(win2);
-});
-
diff --git a/browser/components/sessionstore/test/content-forms.js b/browser/components/sessionstore/test/content-forms.js
deleted file mode 100644
index da7bc9c08..000000000
--- a/browser/components/sessionstore/test/content-forms.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-/**
- * This frame script is only loaded for sessionstore mochitests. It contains
- * a bunch of utility functions used to test form data collection and
- * restoration in remote browsers.
- */
-
-function queryElement(data) {
- let frame = content;
- if (data.hasOwnProperty("frame")) {
- frame = content.frames[data.frame];
- }
-
- let doc = frame.document;
-
- if (data.hasOwnProperty("id")) {
- return doc.getElementById(data.id);
- }
-
- if (data.hasOwnProperty("selector")) {
- return doc.querySelector(data.selector);
- }
-
- if (data.hasOwnProperty("xpath")) {
- let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
- return doc.evaluate(data.xpath, doc, null, xptype, null).singleNodeValue;
- }
-
- throw new Error("couldn't query element");
-}
-
-function dispatchUIEvent(input, type) {
- let event = input.ownerDocument.createEvent("UIEvents");
- event.initUIEvent(type, true, true, input.ownerGlobal, 0);
- input.dispatchEvent(event);
-}
-
-function defineListener(type, cb) {
- addMessageListener("ss-test:" + type, function ({data}) {
- sendAsyncMessage("ss-test:" + type, cb(data));
- });
-}
-
-defineListener("sendKeyEvent", function (data) {
- let frame = content;
- if (data.hasOwnProperty("frame")) {
- frame = content.frames[data.frame];
- }
-
- let ifreq = frame.QueryInterface(Ci.nsIInterfaceRequestor);
- let utils = ifreq.getInterface(Ci.nsIDOMWindowUtils);
-
- let keyCode = data.key.charCodeAt(0);
- let charCode = Ci.nsIDOMKeyEvent.DOM_VK_A + keyCode - "a".charCodeAt(0);
-
- utils.sendKeyEvent("keydown", keyCode, charCode, null);
- utils.sendKeyEvent("keypress", keyCode, charCode, null);
- utils.sendKeyEvent("keyup", keyCode, charCode, null);
-});
-
-defineListener("getInnerHTML", function (data) {
- return queryElement(data).innerHTML;
-});
-
-defineListener("getTextContent", function (data) {
- return queryElement(data).textContent;
-});
-
-defineListener("getInputValue", function (data) {
- return queryElement(data).value;
-});
-
-defineListener("setInputValue", function (data) {
- let input = queryElement(data);
- input.value = data.value;
- dispatchUIEvent(input, "input");
-});
-
-defineListener("getInputChecked", function (data) {
- return queryElement(data).checked;
-});
-
-defineListener("setInputChecked", function (data) {
- let input = queryElement(data);
- input.checked = data.checked;
- dispatchUIEvent(input, "change");
-});
-
-defineListener("getSelectedIndex", function (data) {
- return queryElement(data).selectedIndex;
-});
-
-defineListener("setSelectedIndex", function (data) {
- let input = queryElement(data);
- input.selectedIndex = data.index;
- dispatchUIEvent(input, "change");
-});
-
-defineListener("getMultipleSelected", function (data) {
- let input = queryElement(data);
- return Array.map(input.options, (opt, idx) => idx)
- .filter(idx => input.options[idx].selected);
-});
-
-defineListener("setMultipleSelected", function (data) {
- let input = queryElement(data);
- Array.forEach(input.options, (opt, idx) => opt.selected = data.indices.indexOf(idx) > -1);
- dispatchUIEvent(input, "change");
-});
-
-defineListener("getFileNameArray", function (data) {
- return queryElement(data).mozGetFileNameArray();
-});
-
-defineListener("setFileNameArray", function (data) {
- let input = queryElement(data);
- input.mozSetFileNameArray(data.names, data.names.length);
- dispatchUIEvent(input, "input");
-});
-
-defineListener("setFormElementValues", function (data) {
- for (let elem of content.document.forms[0].elements) {
- elem.value = data.value;
- dispatchUIEvent(elem, "input");
- }
-});
diff --git a/browser/components/sessionstore/test/content.js b/browser/components/sessionstore/test/content.js
deleted file mode 100644
index e815a6783..000000000
--- a/browser/components/sessionstore/test/content.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var Cu = Components.utils;
-var Ci = Components.interfaces;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
-var gFrameTree = new FrameTree(this);
-
-function executeSoon(callback) {
- Services.tm.mainThread.dispatch(callback, Components.interfaces.nsIThread.DISPATCH_NORMAL);
-}
-
-gFrameTree.addObserver({
- onFrameTreeReset: function () {
- sendAsyncMessage("ss-test:onFrameTreeReset");
- },
-
- onFrameTreeCollected: function () {
- sendAsyncMessage("ss-test:onFrameTreeCollected");
- }
-});
-
-var historyListener = {
- OnHistoryNewEntry: function () {
- sendAsyncMessage("ss-test:OnHistoryNewEntry");
- },
-
- OnHistoryGoBack: function () {
- sendAsyncMessage("ss-test:OnHistoryGoBack");
- return true;
- },
-
- OnHistoryGoForward: function () {
- sendAsyncMessage("ss-test:OnHistoryGoForward");
- return true;
- },
-
- OnHistoryGotoIndex: function () {
- sendAsyncMessage("ss-test:OnHistoryGotoIndex");
- return true;
- },
-
- OnHistoryPurge: function () {
- sendAsyncMessage("ss-test:OnHistoryPurge");
- return true;
- },
-
- OnHistoryReload: function () {
- sendAsyncMessage("ss-test:OnHistoryReload");
- return true;
- },
-
- OnHistoryReplaceEntry: function () {
- sendAsyncMessage("ss-test:OnHistoryReplaceEntry");
- },
-
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsISHistoryListener,
- Ci.nsISupportsWeakReference
- ])
-};
-
-var {sessionHistory} = docShell.QueryInterface(Ci.nsIWebNavigation);
-if (sessionHistory) {
- sessionHistory.addSHistoryListener(historyListener);
-}
-
-/**
- * This frame script is only loaded for sessionstore mochitests. It enables us
- * to modify and query docShell data when running with multiple processes.
- */
-
-addEventListener("hashchange", function () {
- sendAsyncMessage("ss-test:hashchange");
-});
-
-addMessageListener("ss-test:purgeDomainData", function ({data: domain}) {
- Services.obs.notifyObservers(null, "browser:purge-domain-data", domain);
- content.setTimeout(() => sendAsyncMessage("ss-test:purgeDomainData"));
-});
-
-addMessageListener("ss-test:getStyleSheets", function (msg) {
- let sheets = content.document.styleSheets;
- let titles = Array.map(sheets, ss => [ss.title, ss.disabled]);
- sendSyncMessage("ss-test:getStyleSheets", titles);
-});
-
-addMessageListener("ss-test:enableStyleSheetsForSet", function (msg) {
- let sheets = content.document.styleSheets;
- let change = false;
- for (let i = 0; i < sheets.length; i++) {
- if (sheets[i].disabled != (msg.data.indexOf(sheets[i].title) == -1)) {
- change = true;
- break;
- }
- }
- function observer() {
- Services.obs.removeObserver(observer, "style-sheet-applicable-state-changed");
-
- // It's possible our observer will run before the one in
- // content-sessionStore.js. Therefore, we run ours a little
- // later.
- executeSoon(() => sendAsyncMessage("ss-test:enableStyleSheetsForSet"));
- }
- if (change) {
- // We don't want to reply until content-sessionStore.js has seen
- // the change.
- Services.obs.addObserver(observer, "style-sheet-applicable-state-changed", false);
-
- content.document.enableStyleSheetsForSet(msg.data);
- } else {
- sendAsyncMessage("ss-test:enableStyleSheetsForSet");
- }
-});
-
-addMessageListener("ss-test:enableSubDocumentStyleSheetsForSet", function (msg) {
- let iframe = content.document.getElementById(msg.data.id);
- iframe.contentDocument.enableStyleSheetsForSet(msg.data.set);
- sendAsyncMessage("ss-test:enableSubDocumentStyleSheetsForSet");
-});
-
-addMessageListener("ss-test:getAuthorStyleDisabled", function (msg) {
- let {authorStyleDisabled} =
- docShell.contentViewer;
- sendSyncMessage("ss-test:getAuthorStyleDisabled", authorStyleDisabled);
-});
-
-addMessageListener("ss-test:setAuthorStyleDisabled", function (msg) {
- let markupDocumentViewer =
- docShell.contentViewer;
- markupDocumentViewer.authorStyleDisabled = msg.data;
- sendSyncMessage("ss-test:setAuthorStyleDisabled");
-});
-
-addMessageListener("ss-test:setUsePrivateBrowsing", function (msg) {
- let loadContext =
- docShell.QueryInterface(Ci.nsILoadContext);
- loadContext.usePrivateBrowsing = msg.data;
- sendAsyncMessage("ss-test:setUsePrivateBrowsing");
-});
-
-addMessageListener("ss-test:getScrollPosition", function (msg) {
- let frame = content;
- if (msg.data.hasOwnProperty("frame")) {
- frame = content.frames[msg.data.frame];
- }
- let {scrollX: x, scrollY: y} = frame;
- sendAsyncMessage("ss-test:getScrollPosition", {x: x, y: y});
-});
-
-addMessageListener("ss-test:setScrollPosition", function (msg) {
- let frame = content;
- let {x, y} = msg.data;
- if (msg.data.hasOwnProperty("frame")) {
- frame = content.frames[msg.data.frame];
- }
- frame.scrollTo(x, y);
-
- frame.addEventListener("scroll", function onScroll(event) {
- if (frame.document == event.target) {
- frame.removeEventListener("scroll", onScroll);
- sendAsyncMessage("ss-test:setScrollPosition");
- }
- });
-});
-
-addMessageListener("ss-test:createDynamicFrames", function ({data}) {
- function createIFrame(rows) {
- let frames = content.document.getElementById(data.id);
- frames.setAttribute("rows", rows);
-
- let frame = content.document.createElement("frame");
- frame.setAttribute("src", data.url);
- frames.appendChild(frame);
- }
-
- addEventListener("DOMContentLoaded", function onContentLoaded(event) {
- if (content.document == event.target) {
- removeEventListener("DOMContentLoaded", onContentLoaded, true);
- // DOMContentLoaded is fired right after we finished parsing the document.
- createIFrame("33%, 33%, 33%");
- }
- }, true);
-
- addEventListener("load", function onLoad(event) {
- if (content.document == event.target) {
- removeEventListener("load", onLoad, true);
-
- // Creating this frame on the same tick as the load event
- // means that it must not be included in the frame tree.
- createIFrame("25%, 25%, 25%, 25%");
- }
- }, true);
-
- sendAsyncMessage("ss-test:createDynamicFrames");
-});
-
-addMessageListener("ss-test:removeLastFrame", function ({data}) {
- let frames = content.document.getElementById(data.id);
- frames.lastElementChild.remove();
- sendAsyncMessage("ss-test:removeLastFrame");
-});
-
-addMessageListener("ss-test:mapFrameTree", function (msg) {
- let result = gFrameTree.map(frame => ({href: frame.location.href}));
- sendAsyncMessage("ss-test:mapFrameTree", result);
-});
-
-addMessageListener("ss-test:click", function ({data}) {
- content.document.getElementById(data.id).click();
- sendAsyncMessage("ss-test:click");
-});
-
-addEventListener("load", function(event) {
- let subframe = event.target != content.document;
- sendAsyncMessage("ss-test:loadEvent", {subframe: subframe, url: event.target.documentURI});
-}, true);
diff --git a/browser/components/sessionstore/test/head.js b/browser/components/sessionstore/test/head.js
deleted file mode 100644
index 5a8c5dbfc..000000000
--- a/browser/components/sessionstore/test/head.js
+++ /dev/null
@@ -1,564 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const TAB_STATE_NEEDS_RESTORE = 1;
-const TAB_STATE_RESTORING = 2;
-
-const ROOT = getRootDirectory(gTestPath);
-const HTTPROOT = ROOT.replace("chrome://mochitests/content/", "http://example.com/");
-const FRAME_SCRIPTS = [
- ROOT + "content.js",
- ROOT + "content-forms.js"
-];
-
-var mm = Cc["@mozilla.org/globalmessagemanager;1"]
- .getService(Ci.nsIMessageListenerManager);
-
-for (let script of FRAME_SCRIPTS) {
- mm.loadFrameScript(script, true);
-}
-
-registerCleanupFunction(() => {
- for (let script of FRAME_SCRIPTS) {
- mm.removeDelayedFrameScript(script, true);
- }
-});
-
-const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
-const {SessionStore} = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {});
-const {SessionSaver} = Cu.import("resource:///modules/sessionstore/SessionSaver.jsm", {});
-const {SessionFile} = Cu.import("resource:///modules/sessionstore/SessionFile.jsm", {});
-const {TabState} = Cu.import("resource:///modules/sessionstore/TabState.jsm", {});
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-
-// Some tests here assume that all restored tabs are loaded without waiting for
-// the user to bring them to the foreground. We ensure this by resetting the
-// related preference (see the "firefox.js" defaults file for details).
-Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", false);
-registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
-});
-
-// Obtain access to internals
-Services.prefs.setBoolPref("browser.sessionstore.debug", true);
-registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.debug");
-});
-
-
-// This kicks off the search service used on about:home and allows the
-// session restore tests to be run standalone without triggering errors.
-Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
-
-function provideWindow(aCallback, aURL, aFeatures) {
- function callbackSoon(aWindow) {
- executeSoon(function executeCallbackSoon() {
- aCallback(aWindow);
- });
- }
-
- 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);
- callbackSoon(aWin);
- }, true);
- });
-}
-
-// This assumes that tests will at least have some state/entries
-function waitForBrowserState(aState, aSetStateCallback) {
- if (typeof aState == "string") {
- aState = JSON.parse(aState);
- }
- if (typeof aState != "object") {
- throw new TypeError("Argument must be an object or a JSON representation of an object");
- }
- let windows = [window];
- let tabsRestored = 0;
- let expectedTabsRestored = 0;
- let expectedWindows = aState.windows.length;
- let windowsOpen = 1;
- let listening = false;
- let windowObserving = false;
- let restoreHiddenTabs = Services.prefs.getBoolPref(
- "browser.sessionstore.restore_hidden_tabs");
-
- aState.windows.forEach(function (winState) {
- winState.tabs.forEach(function (tabState) {
- if (restoreHiddenTabs || !tabState.hidden)
- expectedTabsRestored++;
- });
- });
-
- // There must be only hidden tabs and restoreHiddenTabs = false. We still
- // expect one of them to be restored because it gets shown automatically.
- if (!expectedTabsRestored)
- expectedTabsRestored = 1;
-
- function onSSTabRestored(aEvent) {
- if (++tabsRestored == expectedTabsRestored) {
- // Remove the event listener from each window
- windows.forEach(function(win) {
- win.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
- });
- listening = false;
- info("running " + aSetStateCallback.name);
- executeSoon(aSetStateCallback);
- }
- }
-
- // 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, false);
-
- 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);
- }, false);
- }
- }
-
- // 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);
- }
- });
- windowObserving = true;
- Services.ww.registerNotification(windowObserver);
- }
-
- registerCleanupFunction(function() {
- if (listening) {
- windows.forEach(function(win) {
- win.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
- });
- }
- });
- // Add the event listener for this window as well.
- listening = true;
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
-
- // Ensure setBrowserState() doesn't remove the initial tab.
- gBrowser.selectedTab = gBrowser.tabs[0];
-
- // Finally, call setBrowserState
- ss.setBrowserState(JSON.stringify(aState));
-}
-
-function promiseBrowserState(aState) {
- return new Promise(resolve => waitForBrowserState(aState, resolve));
-}
-
-function promiseTabState(tab, state) {
- if (typeof(state) != "string") {
- state = JSON.stringify(state);
- }
-
- let promise = promiseTabRestored(tab);
- ss.setTabState(tab, state);
- return promise;
-}
-
-/**
- * Wait for a content -> chrome message.
- */
-function promiseContentMessage(browser, name) {
- let mm = browser.messageManager;
-
- return new Promise(resolve => {
- function removeListener() {
- mm.removeMessageListener(name, listener);
- }
-
- function listener(msg) {
- removeListener();
- resolve(msg.data);
- }
-
- mm.addMessageListener(name, listener);
- registerCleanupFunction(removeListener);
- });
-}
-
-function waitForTopic(aTopic, aTimeout, aCallback) {
- let observing = false;
- function removeObserver() {
- if (!observing)
- return;
- Services.obs.removeObserver(observer, aTopic);
- observing = false;
- }
-
- let timeout = setTimeout(function () {
- removeObserver();
- aCallback(false);
- }, aTimeout);
-
- function observer(aSubject, aTopic, aData) {
- removeObserver();
- timeout = clearTimeout(timeout);
- executeSoon(() => aCallback(true));
- }
-
- registerCleanupFunction(function() {
- removeObserver();
- if (timeout) {
- clearTimeout(timeout);
- }
- });
-
- observing = true;
- Services.obs.addObserver(observer, aTopic, false);
-}
-
-/**
- * Wait until session restore has finished collecting its data and is
- * has written that data ("sessionstore-state-write-complete").
- *
- * @param {function} aCallback If sessionstore-state-write-complete is sent
- * within buffering interval + 100 ms, the callback is passed |true|,
- * otherwise, it is passed |false|.
- */
-function waitForSaveState(aCallback) {
- let timeout = 100 +
- Services.prefs.getIntPref("browser.sessionstore.interval");
- return waitForTopic("sessionstore-state-write-complete", timeout, aCallback);
-}
-function promiseSaveState() {
- return new Promise(resolve => {
- waitForSaveState(isSuccessful => {
- if (!isSuccessful) {
- throw new Error("timeout");
- }
-
- resolve();
- });
- });
-}
-function forceSaveState() {
- return SessionSaver.run();
-}
-
-function promiseRecoveryFileContents() {
- let promise = forceSaveState();
- return promise.then(function() {
- return OS.File.read(SessionFile.Paths.recovery, { encoding: "utf-8" });
- });
-}
-
-var promiseForEachSessionRestoreFile = Task.async(function*(cb) {
- for (let key of SessionFile.Paths.loadOrder) {
- let data = "";
- try {
- data = yield OS.File.read(SessionFile.Paths[key], { encoding: "utf-8" });
- } catch (ex) {
- // Ignore missing files
- if (!(ex instanceof OS.File.Error && ex.becauseNoSuchFile)) {
- throw ex;
- }
- }
- cb(data, key);
- }
-});
-
-function promiseBrowserLoaded(aBrowser, ignoreSubFrames = true, wantLoad = null) {
- return BrowserTestUtils.browserLoaded(aBrowser, !ignoreSubFrames, wantLoad);
-}
-
-function whenWindowLoaded(aWindow, aCallback = next) {
- aWindow.addEventListener("load", function windowLoadListener() {
- aWindow.removeEventListener("load", windowLoadListener, false);
- executeSoon(function executeWhenWindowLoaded() {
- aCallback(aWindow);
- });
- }, false);
-}
-function promiseWindowLoaded(aWindow) {
- return new Promise(resolve => whenWindowLoaded(aWindow, resolve));
-}
-
-var gUniqueCounter = 0;
-function r() {
- return Date.now() + "-" + (++gUniqueCounter);
-}
-
-function* BrowserWindowIterator() {
- let windowsEnum = Services.wm.getEnumerator("navigator:browser");
- while (windowsEnum.hasMoreElements()) {
- let currentWindow = windowsEnum.getNext();
- if (!currentWindow.closed) {
- yield currentWindow;
- }
- }
-}
-
-var gWebProgressListener = {
- _callback: null,
-
- setCallback: function (aCallback) {
- if (!this._callback) {
- window.gBrowser.addTabsProgressListener(this);
- }
- this._callback = aCallback;
- },
-
- unsetCallback: function () {
- if (this._callback) {
- this._callback = null;
- window.gBrowser.removeTabsProgressListener(this);
- }
- },
-
- onStateChange: function (aBrowser, aWebProgress, aRequest,
- aStateFlags, aStatus) {
- if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
- this._callback(aBrowser);
- }
- }
-};
-
-registerCleanupFunction(function () {
- gWebProgressListener.unsetCallback();
-});
-
-var gProgressListener = {
- _callback: null,
-
- setCallback: function (callback) {
- Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
- this._callback = callback;
- },
-
- unsetCallback: function () {
- if (this._callback) {
- this._callback = null;
- Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
- }
- },
-
- observe: function (browser, topic, data) {
- gProgressListener.onRestored(browser);
- },
-
- onRestored: function (browser) {
- if (browser.__SS_restoreState == TAB_STATE_RESTORING) {
- let args = [browser].concat(gProgressListener._countTabs());
- gProgressListener._callback.apply(gProgressListener, args);
- }
- },
-
- _countTabs: function () {
- let needsRestore = 0, isRestoring = 0, wasRestored = 0;
-
- for (let win of BrowserWindowIterator()) {
- for (let i = 0; i < win.gBrowser.tabs.length; i++) {
- let browser = win.gBrowser.tabs[i].linkedBrowser;
- if (!browser.__SS_restoreState)
- wasRestored++;
- else if (browser.__SS_restoreState == TAB_STATE_RESTORING)
- isRestoring++;
- else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
- needsRestore++;
- }
- }
- return [needsRestore, isRestoring, wasRestored];
- }
-};
-
-registerCleanupFunction(function () {
- gProgressListener.unsetCallback();
-});
-
-// Close all but our primary window.
-function promiseAllButPrimaryWindowClosed() {
- let windows = [];
- for (let win of BrowserWindowIterator()) {
- if (win != window) {
- windows.push(win);
- }
- }
-
- return Promise.all(windows.map(BrowserTestUtils.closeWindow));
-}
-
-// Forget all closed windows.
-function forgetClosedWindows() {
- while (ss.getClosedWindowCount() > 0) {
- ss.forgetClosedWindow(0);
- }
-}
-
-/**
- * When opening a new window it is not sufficient to wait for its load event.
- * We need to use whenDelayedStartupFinshed() here as the browser window's
- * delayedStartup() routine is executed one tick after the window's load event
- * has been dispatched. browser-delayed-startup-finished might be deferred even
- * further if parts of the window's initialization process take more time than
- * expected (e.g. reading a big session state from disk).
- */
-function whenNewWindowLoaded(aOptions, aCallback) {
- let features = "";
- let url = "about:blank";
-
- if (aOptions && aOptions.private || false) {
- features = ",private";
- url = "about:privatebrowsing";
- }
-
- let win = openDialog(getBrowserURL(), "", "chrome,all,dialog=no" + features, url);
- let delayedStartup = promiseDelayedStartupFinished(win);
-
- let browserLoaded = new Promise(resolve => {
- if (url == "about:blank") {
- resolve();
- return;
- }
-
- win.addEventListener("load", function onLoad() {
- win.removeEventListener("load", onLoad);
- let browser = win.gBrowser.selectedBrowser;
- promiseBrowserLoaded(browser).then(resolve);
- });
- });
-
- Promise.all([delayedStartup, browserLoaded]).then(() => aCallback(win));
-}
-function promiseNewWindowLoaded(aOptions) {
- return new Promise(resolve => whenNewWindowLoaded(aOptions, resolve));
-}
-
-/**
- * This waits for the browser-delayed-startup-finished notification of a given
- * window. It indicates that the windows has loaded completely and is ready to
- * be used for testing.
- */
-function whenDelayedStartupFinished(aWindow, aCallback) {
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- executeSoon(aCallback);
- }
- }, "browser-delayed-startup-finished", false);
-}
-function promiseDelayedStartupFinished(aWindow) {
- return new Promise(resolve => whenDelayedStartupFinished(aWindow, resolve));
-}
-
-function promiseEvent(element, eventType, isCapturing = false) {
- return new Promise(resolve => {
- element.addEventListener(eventType, function listener(event) {
- element.removeEventListener(eventType, listener, isCapturing);
- resolve(event);
- }, isCapturing);
- });
-}
-
-function promiseTabRestored(tab) {
- return promiseEvent(tab, "SSTabRestored");
-}
-
-function promiseTabRestoring(tab) {
- return promiseEvent(tab, "SSTabRestoring");
-}
-
-function sendMessage(browser, name, data = {}) {
- browser.messageManager.sendAsyncMessage(name, data);
- return promiseContentMessage(browser, name);
-}
-
-// This creates list of functions that we will map to their corresponding
-// ss-test:* messages names. Those will be sent to the frame script and
-// be used to read and modify form data.
-const FORM_HELPERS = [
- "getTextContent",
- "getInputValue", "setInputValue",
- "getInputChecked", "setInputChecked",
- "getSelectedIndex", "setSelectedIndex",
- "getMultipleSelected", "setMultipleSelected",
- "getFileNameArray", "setFileNameArray",
-];
-
-for (let name of FORM_HELPERS) {
- let msg = "ss-test:" + name;
- this[name] = (browser, data) => sendMessage(browser, msg, data);
-}
-
-// Removes the given tab immediately and returns a promise that resolves when
-// all pending status updates (messages) of the closing tab have been received.
-function promiseRemoveTab(tab) {
- return BrowserTestUtils.removeTab(tab);
-}
-
-// Write DOMSessionStorage data to the given browser.
-function modifySessionStorage(browser, data, options = {}) {
- return ContentTask.spawn(browser, [data, options], function* ([data, options]) {
- let frame = content;
- if (options && "frameIndex" in options) {
- frame = content.frames[options.frameIndex];
- }
-
- let keys = new Set(Object.keys(data));
- let storage = frame.sessionStorage;
-
- return new Promise(resolve => {
- addEventListener("MozSessionStorageChanged", function onStorageChanged(event) {
- if (event.storageArea == storage) {
- keys.delete(event.key);
- }
-
- if (keys.size == 0) {
- removeEventListener("MozSessionStorageChanged", onStorageChanged, true);
- resolve();
- }
- }, true);
-
- for (let key of keys) {
- frame.sessionStorage[key] = data[key];
- }
- });
- });
-}
-
-function pushPrefs(...aPrefs) {
- return new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
- });
-}
-
-function popPrefs() {
- return new Promise(resolve => {
- SpecialPowers.popPrefEnv(resolve);
- });
-}
-
-function* checkScroll(tab, expected, msg) {
- let browser = tab.linkedBrowser;
- yield TabStateFlusher.flush(browser);
-
- let scroll = JSON.parse(ss.getTabState(tab)).scroll || null;
- is(JSON.stringify(scroll), JSON.stringify(expected), msg);
-}
diff --git a/browser/components/sessionstore/test/restore_redirect_http.html b/browser/components/sessionstore/test/restore_redirect_http.html
deleted file mode 100644
index e69de29bb..000000000
--- a/browser/components/sessionstore/test/restore_redirect_http.html
+++ /dev/null
diff --git a/browser/components/sessionstore/test/restore_redirect_http.html^headers^ b/browser/components/sessionstore/test/restore_redirect_http.html^headers^
deleted file mode 100644
index 533bda36f..000000000
--- a/browser/components/sessionstore/test/restore_redirect_http.html^headers^
+++ /dev/null
@@ -1,2 +0,0 @@
-HTTP 302 Moved Temporarily
-Location: restore_redirect_target.html
diff --git a/browser/components/sessionstore/test/restore_redirect_js.html b/browser/components/sessionstore/test/restore_redirect_js.html
deleted file mode 100644
index 1f5f0e54c..000000000
--- a/browser/components/sessionstore/test/restore_redirect_js.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-<script>
-var newLocation = window.location.toString().replace("restore_redirect_js.html", "restore_redirect_target.html");
-window.location.replace(newLocation);
-</script>
-</head>
-</html> \ No newline at end of file
diff --git a/browser/components/sessionstore/test/restore_redirect_target.html b/browser/components/sessionstore/test/restore_redirect_target.html
deleted file mode 100644
index 6c8b3aae5..000000000
--- a/browser/components/sessionstore/test/restore_redirect_target.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-<title>Test page</title>
-</head>
-<body>Test page</body>
-</html>
diff --git a/browser/components/sessionstore/test/unit/.eslintrc.js b/browser/components/sessionstore/test/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/sessionstore/test/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/sessionstore/test/unit/data/sessionCheckpoints_all.json b/browser/components/sessionstore/test/unit/data/sessionCheckpoints_all.json
deleted file mode 100644
index 928de6a39..000000000
--- a/browser/components/sessionstore/test/unit/data/sessionCheckpoints_all.json
+++ /dev/null
@@ -1 +0,0 @@
-{"profile-after-change":true,"final-ui-startup":true,"sessionstore-windows-restored":true,"quit-application-granted":true,"quit-application":true,"sessionstore-final-state-write-complete":true,"profile-change-net-teardown":true,"profile-change-teardown":true,"profile-before-change":true} \ No newline at end of file
diff --git a/browser/components/sessionstore/test/unit/data/sessionstore_invalid.js b/browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
deleted file mode 100644
index a8c3ff2ff..000000000
--- a/browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "windows": // invalid json
-}
diff --git a/browser/components/sessionstore/test/unit/data/sessionstore_valid.js b/browser/components/sessionstore/test/unit/data/sessionstore_valid.js
deleted file mode 100644
index f9511f29f..000000000
--- a/browser/components/sessionstore/test/unit/data/sessionstore_valid.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "windows": []
-} \ No newline at end of file
diff --git a/browser/components/sessionstore/test/unit/head.js b/browser/components/sessionstore/test/unit/head.js
deleted file mode 100644
index b62856012..000000000
--- a/browser/components/sessionstore/test/unit/head.js
+++ /dev/null
@@ -1,32 +0,0 @@
-var Cu = Components.utils;
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-// Call a function once initialization of SessionStartup is complete
-function afterSessionStartupInitialization(cb) {
- do_print("Waiting for session startup initialization");
- let observer = function() {
- try {
- do_print("Session startup initialization observed");
- Services.obs.removeObserver(observer, "sessionstore-state-finalized");
- cb();
- } catch (ex) {
- do_throw(ex);
- }
- };
-
- // We need the Crash Monitor initialized for sessionstartup to run
- // successfully.
- Components.utils.import("resource://gre/modules/CrashMonitor.jsm");
- CrashMonitor.init();
-
- // Start sessionstartup initialization.
- let startup = Cc["@mozilla.org/browser/sessionstartup;1"].
- getService(Ci.nsIObserver);
- Services.obs.addObserver(startup, "final-ui-startup", false);
- Services.obs.addObserver(startup, "quit-application", false);
- Services.obs.notifyObservers(null, "final-ui-startup", "");
- Services.obs.addObserver(observer, "sessionstore-state-finalized", false);
-};
diff --git a/browser/components/sessionstore/test/unit/test_backup_once.js b/browser/components/sessionstore/test/unit/test_backup_once.js
deleted file mode 100644
index fff34ad58..000000000
--- a/browser/components/sessionstore/test/unit/test_backup_once.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
-var {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-var {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
-var {SessionWorker} = Cu.import("resource:///modules/sessionstore/SessionWorker.jsm", {});
-
-var File = OS.File;
-var Paths;
-var SessionFile;
-
-// We need a XULAppInfo to initialize SessionFile
-Cu.import("resource://testing-common/AppInfo.jsm", this);
-updateAppInfo({
- name: "SessionRestoreTest",
- ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
- version: "1",
- platformVersion: "",
-});
-
-function run_test() {
- run_next_test();
-}
-
-add_task(function* init() {
- // Make sure that we have a profile before initializing SessionFile
- let profd = do_get_profile();
- SessionFile = Cu.import("resource:///modules/sessionstore/SessionFile.jsm", {}).SessionFile;
- Paths = SessionFile.Paths;
-
-
- let source = do_get_file("data/sessionstore_valid.js");
- source.copyTo(profd, "sessionstore.js");
-
- // Finish initialization of SessionFile
- yield SessionFile.read();
-});
-
-var pathStore;
-var pathBackup;
-var decoder;
-
-function promise_check_exist(path, shouldExist) {
- return Task.spawn(function*() {
- do_print("Ensuring that " + path + (shouldExist?" exists":" does not exist"));
- if ((yield OS.File.exists(path)) != shouldExist) {
- throw new Error("File " + path + " should " + (shouldExist?"exist":"not exist"));
- }
- });
-}
-
-function promise_check_contents(path, expect) {
- return Task.spawn(function*() {
- do_print("Checking whether " + path + " has the right contents");
- let actual = yield OS.File.read(path, { encoding: "utf-8"});
- Assert.deepEqual(JSON.parse(actual), expect, `File ${path} contains the expected data.`);
- });
-}
-
-function generateFileContents(id) {
- let url = `http://example.com/test_backup_once#${id}_${Math.random()}`;
- return {windows: [{tabs: [{entries: [{url}], index: 1}]}]}
-}
-
-// Write to the store, and check that it creates:
-// - $Path.recovery with the new data
-// - $Path.nextUpgradeBackup with the old data
-add_task(function* test_first_write_backup() {
- let initial_content = generateFileContents("initial");
- let new_content = generateFileContents("test_1");
-
- do_print("Before the first write, none of the files should exist");
- yield promise_check_exist(Paths.backups, false);
-
- yield File.makeDir(Paths.backups);
- yield File.writeAtomic(Paths.clean, JSON.stringify(initial_content), { encoding: "utf-8" });
- yield SessionFile.write(new_content);
-
- do_print("After first write, a few files should have been created");
- yield promise_check_exist(Paths.backups, true);
- yield promise_check_exist(Paths.clean, false);
- yield promise_check_exist(Paths.cleanBackup, true);
- yield promise_check_exist(Paths.recovery, true);
- yield promise_check_exist(Paths.recoveryBackup, false);
- yield promise_check_exist(Paths.nextUpgradeBackup, true);
-
- yield promise_check_contents(Paths.recovery, new_content);
- yield promise_check_contents(Paths.nextUpgradeBackup, initial_content);
-});
-
-// Write to the store again, and check that
-// - $Path.clean is not written
-// - $Path.recovery contains the new data
-// - $Path.recoveryBackup contains the previous data
-add_task(function* test_second_write_no_backup() {
- let new_content = generateFileContents("test_2");
- let previous_backup_content = yield File.read(Paths.recovery, { encoding: "utf-8" });
- previous_backup_content = JSON.parse(previous_backup_content);
-
- yield OS.File.remove(Paths.cleanBackup);
-
- yield SessionFile.write(new_content);
-
- yield promise_check_exist(Paths.backups, true);
- yield promise_check_exist(Paths.clean, false);
- yield promise_check_exist(Paths.cleanBackup, false);
- yield promise_check_exist(Paths.recovery, true);
- yield promise_check_exist(Paths.nextUpgradeBackup, true);
-
- yield promise_check_contents(Paths.recovery, new_content);
- yield promise_check_contents(Paths.recoveryBackup, previous_backup_content);
-});
-
-// Make sure that we create $Paths.clean and remove $Paths.recovery*
-// upon shutdown
-add_task(function* test_shutdown() {
- let output = generateFileContents("test_3");
-
- yield File.writeAtomic(Paths.recovery, "I should disappear");
- yield File.writeAtomic(Paths.recoveryBackup, "I should also disappear");
-
- yield SessionWorker.post("write", [output, { isFinalWrite: true, performShutdownCleanup: true}]);
-
- do_check_false((yield File.exists(Paths.recovery)));
- do_check_false((yield File.exists(Paths.recoveryBackup)));
- yield promise_check_contents(Paths.clean, output);
-});
diff --git a/browser/components/sessionstore/test/unit/test_histogram_corrupt_files.js b/browser/components/sessionstore/test/unit/test_histogram_corrupt_files.js
deleted file mode 100644
index c7d8b03ed..000000000
--- a/browser/components/sessionstore/test/unit/test_histogram_corrupt_files.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * The primary purpose of this test is to ensure that
- * the sessionstore component records information about
- * corrupted backup files into a histogram.
- */
-
-"use strict";
-Cu.import("resource://gre/modules/osfile.jsm", this);
-
-const Telemetry = Services.telemetry;
-const Path = OS.Path;
-const HistogramId = "FX_SESSION_RESTORE_ALL_FILES_CORRUPT";
-
-// Prepare the session file.
-var profd = do_get_profile();
-Cu.import("resource:///modules/sessionstore/SessionFile.jsm", this);
-
-/**
- * A utility function for resetting the histogram and the contents
- * of the backup directory.
- */
-function reset_session(backups = {}) {
-
- // Reset the histogram.
- Telemetry.getHistogramById(HistogramId).clear();
-
- // Reset the contents of the backups directory
- OS.File.makeDir(SessionFile.Paths.backups);
- for (let key of SessionFile.Paths.loadOrder) {
- if (backups.hasOwnProperty(key)) {
- OS.File.copy(backups[key], SessionFile.Paths[key]);
- } else {
- OS.File.remove(SessionFile.Paths[key]);
- }
- }
-}
-
-/**
- * In order to use FX_SESSION_RESTORE_ALL_FILES_CORRUPT histogram
- * it has to be registered in "toolkit/components/telemetry/Histograms.json".
- * This test ensures that the histogram is registered and empty.
- */
-add_task(function* test_ensure_histogram_exists_and_empty() {
- let s = Telemetry.getHistogramById(HistogramId).snapshot();
- Assert.equal(s.sum, 0, "Initially, the sum of probes is 0");
-});
-
-/**
- * Makes sure that the histogram is negatively updated when no
- * backup files are present.
- */
-add_task(function* test_no_files_exist() {
- // No session files are available to SessionFile.
- reset_session();
-
- yield SessionFile.read();
- // Checking if the histogram is updated negatively
- let h = Telemetry.getHistogramById(HistogramId);
- let s = h.snapshot();
- Assert.equal(s.counts[0], 1, "One probe for the 'false' bucket.");
- Assert.equal(s.counts[1], 0, "No probes in the 'true' bucket.");
-});
-
-/**
- * Makes sure that the histogram is negatively updated when at least one
- * backup file is not corrupted.
- */
-add_task(function* test_one_file_valid() {
- // Corrupting some backup files.
- let invalidSession = "data/sessionstore_invalid.js";
- let validSession = "data/sessionstore_valid.js";
- reset_session({
- clean : invalidSession,
- cleanBackup: validSession,
- recovery: invalidSession,
- recoveryBackup: invalidSession
- });
-
- yield SessionFile.read();
- // Checking if the histogram is updated negatively.
- let h = Telemetry.getHistogramById(HistogramId);
- let s = h.snapshot();
- Assert.equal(s.counts[0], 1, "One probe for the 'false' bucket.");
- Assert.equal(s.counts[1], 0, "No probes in the 'true' bucket.");
-});
-
-/**
- * Makes sure that the histogram is positively updated when all
- * backup files are corrupted.
- */
-add_task(function* test_all_files_corrupt() {
- // Corrupting all backup files.
- let invalidSession = "data/sessionstore_invalid.js";
- reset_session({
- clean : invalidSession,
- cleanBackup: invalidSession,
- recovery: invalidSession,
- recoveryBackup: invalidSession
- });
-
- yield SessionFile.read();
- // Checking if the histogram is positively updated.
- let h = Telemetry.getHistogramById(HistogramId);
- let s = h.snapshot();
- Assert.equal(s.counts[1], 1, "One probe for the 'true' bucket.");
- Assert.equal(s.counts[0], 0, "No probes in the 'false' bucket.");
-});
-
-function run_test() {
- run_next_test();
-}
diff --git a/browser/components/sessionstore/test/unit/test_shutdown_cleanup.js b/browser/components/sessionstore/test/unit/test_shutdown_cleanup.js
deleted file mode 100644
index b99e566e9..000000000
--- a/browser/components/sessionstore/test/unit/test_shutdown_cleanup.js
+++ /dev/null
@@ -1,127 +0,0 @@
-"use strict";
-
-/**
- * This test ensures that we correctly clean up the session state before
- * writing to disk a last time on shutdown. For now it only tests that each
- * tab's shistory is capped to a maximum number of preceding and succeeding
- * entries.
- */
-
-const {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
-const {SessionWorker} = Cu.import("resource:///modules/sessionstore/SessionWorker.jsm", {});
-
-const profd = do_get_profile();
-const {SessionFile} = Cu.import("resource:///modules/sessionstore/SessionFile.jsm", {});
-const {Paths} = SessionFile;
-
-const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
-const {File} = OS;
-
-const MAX_ENTRIES = 9;
-const URL = "http://example.com/#";
-
-// We need a XULAppInfo to initialize SessionFile
-Cu.import("resource://testing-common/AppInfo.jsm", this);
-updateAppInfo({
- name: "SessionRestoreTest",
- ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
- version: "1",
- platformVersion: "",
-});
-
-add_task(function* setup() {
- let source = do_get_file("data/sessionstore_valid.js");
- source.copyTo(profd, "sessionstore.js");
-
- // Finish SessionFile initialization.
- yield SessionFile.read();
-
- // Reset prefs on cleanup.
- do_register_cleanup(() => {
- Services.prefs.clearUserPref("browser.sessionstore.max_serialize_back");
- Services.prefs.clearUserPref("browser.sessionstore.max_serialize_forward");
- });
-});
-
-function createSessionState(index) {
- // Generate the tab state entries and set the one-based
- // tab-state index to the middle session history entry.
- let tabState = {entries: [], index};
- for (let i = 0; i < MAX_ENTRIES; i++) {
- tabState.entries.push({url: URL + i});
- }
-
- return {windows: [{tabs: [tabState]}]};
-}
-
-function* setMaxBackForward(back, fwd) {
- Services.prefs.setIntPref("browser.sessionstore.max_serialize_back", back);
- Services.prefs.setIntPref("browser.sessionstore.max_serialize_forward", fwd);
- yield SessionFile.read();
-}
-
-function* writeAndParse(state, path, options = {}) {
- yield SessionWorker.post("write", [state, options]);
- return JSON.parse(yield File.read(path, {encoding: "utf-8"}));
-}
-
-add_task(function* test_shistory_cap_none() {
- let state = createSessionState(5);
-
- // Don't limit the number of shistory entries.
- yield setMaxBackForward(-1, -1);
-
- // Check that no caps are applied.
- let diskState = yield writeAndParse(state, Paths.clean, {isFinalWrite: true});
- Assert.deepEqual(state, diskState, "no cap applied");
-});
-
-add_task(function* test_shistory_cap_middle() {
- let state = createSessionState(5);
- yield setMaxBackForward(2, 3);
-
- // Cap is only applied on clean shutdown.
- let diskState = yield writeAndParse(state, Paths.recovery);
- Assert.deepEqual(state, diskState, "no cap applied");
-
- // Check that the right number of shistory entries was discarded
- // and the shistory index updated accordingly.
- diskState = yield writeAndParse(state, Paths.clean, {isFinalWrite: true});
- let tabState = state.windows[0].tabs[0];
- tabState.entries = tabState.entries.slice(2, 8);
- tabState.index = 3;
- Assert.deepEqual(state, diskState, "cap applied");
-});
-
-add_task(function* test_shistory_cap_lower_bound() {
- let state = createSessionState(1);
- yield setMaxBackForward(5, 5);
-
- // Cap is only applied on clean shutdown.
- let diskState = yield writeAndParse(state, Paths.recovery);
- Assert.deepEqual(state, diskState, "no cap applied");
-
- // Check that the right number of shistory entries was discarded.
- diskState = yield writeAndParse(state, Paths.clean, {isFinalWrite: true});
- let tabState = state.windows[0].tabs[0];
- tabState.entries = tabState.entries.slice(0, 6);
- Assert.deepEqual(state, diskState, "cap applied");
-});
-
-add_task(function* test_shistory_cap_upper_bound() {
- let state = createSessionState(MAX_ENTRIES);
- yield setMaxBackForward(5, 5);
-
- // Cap is only applied on clean shutdown.
- let diskState = yield writeAndParse(state, Paths.recovery);
- Assert.deepEqual(state, diskState, "no cap applied");
-
- // Check that the right number of shistory entries was discarded
- // and the shistory index updated accordingly.
- diskState = yield writeAndParse(state, Paths.clean, {isFinalWrite: true});
- let tabState = state.windows[0].tabs[0];
- tabState.entries = tabState.entries.slice(3);
- tabState.index = 6;
- Assert.deepEqual(state, diskState, "cap applied");
-});
diff --git a/browser/components/sessionstore/test/unit/test_startup_invalid_session.js b/browser/components/sessionstore/test/unit/test_startup_invalid_session.js
deleted file mode 100644
index 9f6df8585..000000000
--- a/browser/components/sessionstore/test/unit/test_startup_invalid_session.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function run_test() {
- let profd = do_get_profile();
-
- let sourceSession = do_get_file("data/sessionstore_invalid.js");
- sourceSession.copyTo(profd, "sessionstore.js");
-
- let sourceCheckpoints = do_get_file("data/sessionCheckpoints_all.json");
- sourceCheckpoints.copyTo(profd, "sessionCheckpoints.json");
-
- do_test_pending();
- let startup = Cc["@mozilla.org/browser/sessionstartup;1"].
- getService(Ci.nsISessionStartup);
-
- afterSessionStartupInitialization(function cb() {
- do_check_eq(startup.sessionType, Ci.nsISessionStartup.NO_SESSION);
- do_test_finished();
- });
-}
diff --git a/browser/components/sessionstore/test/unit/test_startup_nosession_async.js b/browser/components/sessionstore/test/unit/test_startup_nosession_async.js
deleted file mode 100644
index 5185b02d6..000000000
--- a/browser/components/sessionstore/test/unit/test_startup_nosession_async.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-// Test nsISessionStartup.sessionType in the following scenario:
-// - no sessionstore.js;
-// - the session store has been loaded, so no need to go
-// through the synchronous fallback
-
-function run_test() {
- do_get_profile();
- // Initialize the profile (the session startup uses it)
-
- do_test_pending();
- let startup = Cc["@mozilla.org/browser/sessionstartup;1"].
- getService(Ci.nsISessionStartup);
-
- afterSessionStartupInitialization(function cb() {
- do_check_eq(startup.sessionType, Ci.nsISessionStartup.NO_SESSION);
- do_test_finished();
- });
-} \ No newline at end of file
diff --git a/browser/components/sessionstore/test/unit/test_startup_session_async.js b/browser/components/sessionstore/test/unit/test_startup_session_async.js
deleted file mode 100644
index 459acf885..000000000
--- a/browser/components/sessionstore/test/unit/test_startup_session_async.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-
-// Test nsISessionStartup.sessionType in the following scenario:
-// - valid sessionstore.js;
-// - valid sessionCheckpoints.json with all checkpoints;
-// - the session store has been loaded
-
-function run_test() {
- let profd = do_get_profile();
-
- let sourceSession = do_get_file("data/sessionstore_valid.js");
- sourceSession.copyTo(profd, "sessionstore.js");
-
- let sourceCheckpoints = do_get_file("data/sessionCheckpoints_all.json");
- sourceCheckpoints.copyTo(profd, "sessionCheckpoints.json");
-
- do_test_pending();
- let startup = Cc["@mozilla.org/browser/sessionstartup;1"].
- getService(Ci.nsISessionStartup);
-
- afterSessionStartupInitialization(function cb() {
- do_check_eq(startup.sessionType, Ci.nsISessionStartup.DEFER_SESSION);
- do_test_finished();
- });
-}
diff --git a/browser/components/sessionstore/test/unit/xpcshell.ini b/browser/components/sessionstore/test/unit/xpcshell.ini
deleted file mode 100644
index 09980f877..000000000
--- a/browser/components/sessionstore/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-support-files =
- data/sessionCheckpoints_all.json
- data/sessionstore_invalid.js
- data/sessionstore_valid.js
-
-[test_backup_once.js]
-[test_histogram_corrupt_files.js]
-[test_shutdown_cleanup.js]
-[test_startup_nosession_async.js]
-[test_startup_session_async.js]
-[test_startup_invalid_session.js]
diff --git a/browser/components/shell/moz.build b/browser/components/shell/moz.build
index 7a605de5f..94ec88571 100644
--- a/browser/components/shell/moz.build
+++ b/browser/components/shell/moz.build
@@ -4,9 +4,6 @@
# 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/.
-XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
XPIDL_SOURCES += [
@@ -57,6 +54,3 @@ for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION'):
DEFINES[var] = '"%s"' % CONFIG[var]
CXXFLAGS += CONFIG['TK_CFLAGS']
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Shell Integration')
diff --git a/browser/components/shell/test/.eslintrc.js b/browser/components/shell/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/shell/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/shell/test/browser.ini b/browser/components/shell/test/browser.ini
deleted file mode 100644
index 8f18415c0..000000000
--- a/browser/components/shell/test/browser.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[DEFAULT]
-skip-if = os != "linux"
-
-[browser_420786.js]
-[browser_633221.js]
-
diff --git a/browser/components/shell/test/browser_420786.js b/browser/components/shell/test/browser_420786.js
deleted file mode 100644
index ae4521890..000000000
--- a/browser/components/shell/test/browser_420786.js
+++ /dev/null
@@ -1,88 +0,0 @@
-const DG_BACKGROUND = "/desktop/gnome/background"
-const DG_IMAGE_KEY = DG_BACKGROUND + "/picture_filename";
-const DG_OPTION_KEY = DG_BACKGROUND + "/picture_options";
-const DG_DRAW_BG_KEY = DG_BACKGROUND + "/draw_background";
-
-function onPageLoad() {
- gBrowser.selectedBrowser.removeEventListener("load", onPageLoad, true);
-
- var bs = Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService);
- var brandName = bs.createBundle("chrome://branding/locale/brand.properties").
- GetStringFromName("brandShortName");
-
- var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIDirectoryServiceProvider);
- var homeDir = dirSvc.getFile("Home", {});
-
- var wpFile = homeDir.clone();
- wpFile.append(brandName + "_wallpaper.png");
-
- // Backup the existing wallpaper so that this test doesn't change the user's
- // settings.
- var wpFileBackup = homeDir.clone()
- wpFileBackup.append(brandName + "_wallpaper.png.backup");
-
- if (wpFileBackup.exists())
- wpFileBackup.remove(false);
-
- if (wpFile.exists())
- wpFile.copyTo(null, wpFileBackup.leafName);
-
- var shell = Cc["@mozilla.org/browser/shell-service;1"].
- getService(Ci.nsIShellService);
- var gconf = Cc["@mozilla.org/gnome-gconf-service;1"].
- getService(Ci.nsIGConfService);
-
- var prevImageKey = gconf.getString(DG_IMAGE_KEY);
- var prevOptionKey = gconf.getString(DG_OPTION_KEY);
- var prevDrawBgKey = gconf.getBool(DG_DRAW_BG_KEY);
-
- var image = content.document.images[0];
-
- function checkWallpaper(position, expectedGConfPosition) {
- shell.setDesktopBackground(image, position);
- ok(wpFile.exists(), "Wallpaper was written to disk");
- is(gconf.getString(DG_IMAGE_KEY), wpFile.path,
- "Wallpaper file GConf key is correct");
- is(gconf.getString(DG_OPTION_KEY), expectedGConfPosition,
- "Wallpaper position GConf key is correct");
- }
-
- checkWallpaper(Ci.nsIShellService.BACKGROUND_TILE, "wallpaper");
- checkWallpaper(Ci.nsIShellService.BACKGROUND_STRETCH, "stretched");
- checkWallpaper(Ci.nsIShellService.BACKGROUND_CENTER, "centered");
- checkWallpaper(Ci.nsIShellService.BACKGROUND_FILL, "zoom");
- checkWallpaper(Ci.nsIShellService.BACKGROUND_FIT, "scaled");
-
- // Restore GConf and wallpaper
-
- gconf.setString(DG_IMAGE_KEY, prevImageKey);
- gconf.setString(DG_OPTION_KEY, prevOptionKey);
- gconf.setBool(DG_DRAW_BG_KEY, prevDrawBgKey);
-
- wpFile.remove(false);
- if (wpFileBackup.exists())
- wpFileBackup.moveTo(null, wpFile.leafName);
-
- gBrowser.removeCurrentTab();
- finish();
-}
-
-function test() {
- try {
- // If GSettings is available, then the GConf tests
- // will fail
- Cc["@mozilla.org/gsettings-service;1"].
- getService(Ci.nsIGSettingsService).
- getCollectionForSchema("org.gnome.desktop.background");
- todo(false, "This test doesn't work when GSettings is available");
- return;
- } catch (e) { }
-
- gBrowser.selectedTab = gBrowser.addTab();
- gBrowser.selectedBrowser.addEventListener("load", onPageLoad, true);
- content.location = "about:logo";
-
- waitForExplicitFinish();
-}
diff --git a/browser/components/shell/test/browser_633221.js b/browser/components/shell/test/browser_633221.js
deleted file mode 100644
index 7929e8098..000000000
--- a/browser/components/shell/test/browser_633221.js
+++ /dev/null
@@ -1,7 +0,0 @@
-Components.utils.import("resource:///modules/ShellService.jsm");
-
-function test() {
- ShellService.setDefaultBrowser(true, false);
- ok(ShellService.isDefaultBrowser(true, false), "we got here and are the default browser");
- ok(ShellService.isDefaultBrowser(true, true), "we got here and are the default browser");
-}
diff --git a/browser/components/shell/test/unit/.eslintrc.js b/browser/components/shell/test/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/shell/test/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/shell/test/unit/test_421977.js b/browser/components/shell/test/unit/test_421977.js
deleted file mode 100644
index 637db4b91..000000000
--- a/browser/components/shell/test/unit/test_421977.js
+++ /dev/null
@@ -1,123 +0,0 @@
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cr = Components.results;
-
-const GCONF_BG_COLOR_KEY = "/desktop/gnome/background/primary_color";
-
-var gShell;
-var gGConf;
-
-/**
- * Converts from a rgb numerical color valule (r << 16 | g << 8 | b)
- * into a hex string in #RRGGBB format.
- */
-function colorToHex(aColor) {
- const rMask = 4294901760;
- const gMask = 65280;
- const bMask = 255;
-
- var r = (aColor & rMask) >> 16;
- var g = (aColor & gMask) >> 8;
- var b = (aColor & bMask);
-
- return "#" + [r, g, b].map(aInt =>
- aInt.toString(16).replace(/^(.)$/, "0$1"))
- .join("").toUpperCase();
-}
-
-/**
- * Converts a color string in #RRGGBB format to a rgb numerical color value
- * (r << 16 | g << 8 | b).
- */
-function hexToColor(aString) {
- return parseInt(aString.substring(1, 3), 16) << 16 |
- parseInt(aString.substring(3, 5), 16) << 8 |
- parseInt(aString.substring(5, 7), 16);
-}
-
-/**
- * Checks that setting the GConf background key to aGConfColor will
- * result in the Shell component returning a background color equals
- * to aExpectedShellColor in #RRGGBB format.
- */
-function checkGConfToShellColor(aGConfColor, aExpectedShellColor) {
-
- gGConf.setString(GCONF_BG_COLOR_KEY, aGConfColor);
- var shellColor = colorToHex(gShell.desktopBackgroundColor);
-
- do_check_eq(shellColor, aExpectedShellColor);
-}
-
-/**
- * Checks that setting the background color (in #RRGGBB format) using the Shell
- * component will result in having a GConf key for the background color set to
- * aExpectedGConfColor.
- */
-function checkShellToGConfColor(aShellColor, aExpectedGConfColor) {
-
- gShell.desktopBackgroundColor = hexToColor(aShellColor);
- var gconfColor = gGConf.getString(GCONF_BG_COLOR_KEY);
-
- do_check_eq(gconfColor, aExpectedGConfColor);
-}
-
-function run_test() {
-
- // This test is Linux specific for now
- if (!("@mozilla.org/gnome-gconf-service;1" in Cc))
- return;
-
- try {
- // If GSettings is available, then the GConf tests
- // will fail
- Cc["@mozilla.org/gsettings-service;1"].
- getService(Ci.nsIGSettingsService).
- getCollectionForSchema("org.gnome.desktop.background");
- return;
- } catch (e) { }
-
- gGConf = Cc["@mozilla.org/gnome-gconf-service;1"].
- getService(Ci.nsIGConfService);
-
- gShell = Cc["@mozilla.org/browser/shell-service;1"].
- getService(Ci.nsIShellService);
-
- // Save the original background color so that we can restore it
- // after the test.
- var origGConfColor = gGConf.getString(GCONF_BG_COLOR_KEY);
-
- try {
-
- checkGConfToShellColor("#000", "#000000");
- checkGConfToShellColor("#00f", "#0000FF");
- checkGConfToShellColor("#b2f", "#BB22FF");
- checkGConfToShellColor("#fff", "#FFFFFF");
-
- checkGConfToShellColor("#000000", "#000000");
- checkGConfToShellColor("#0000ff", "#0000FF");
- checkGConfToShellColor("#b002f0", "#B002F0");
- checkGConfToShellColor("#ffffff", "#FFFFFF");
-
- checkGConfToShellColor("#000000000", "#000000");
- checkGConfToShellColor("#00f00f00f", "#000000");
- checkGConfToShellColor("#aaabbbccc", "#AABBCC");
- checkGConfToShellColor("#fffffffff", "#FFFFFF");
-
- checkGConfToShellColor("#000000000000", "#000000");
- checkGConfToShellColor("#000f000f000f", "#000000");
- checkGConfToShellColor("#00ff00ff00ff", "#000000");
- checkGConfToShellColor("#aaaabbbbcccc", "#AABBCC");
- checkGConfToShellColor("#111122223333", "#112233");
- checkGConfToShellColor("#ffffffffffff", "#FFFFFF");
-
- checkShellToGConfColor("#000000", "#000000000000");
- checkShellToGConfColor("#0000FF", "#00000000ffff");
- checkShellToGConfColor("#FFFFFF", "#ffffffffffff");
- checkShellToGConfColor("#0A0B0C", "#0a0a0b0b0c0c");
- checkShellToGConfColor("#A0B0C0", "#a0a0b0b0c0c0");
- checkShellToGConfColor("#AABBCC", "#aaaabbbbcccc");
-
- } finally {
- gGConf.setString(GCONF_BG_COLOR_KEY, origGConfColor);
- }
-}
diff --git a/browser/components/shell/test/unit/xpcshell.ini b/browser/components/shell/test/unit/xpcshell.ini
deleted file mode 100644
index be00037e0..000000000
--- a/browser/components/shell/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-head =
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-[test_421977.js]
diff --git a/browser/components/syncedtabs/moz.build b/browser/components/syncedtabs/moz.build
index 93c98e65d..a6515d6a1 100644
--- a/browser/components/syncedtabs/moz.build
+++ b/browser/components/syncedtabs/moz.build
@@ -4,10 +4,6 @@
JAR_MANIFESTS += ['jar.mn']
-BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
-
-XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
-
EXTRA_JS_MODULES.syncedtabs += [
'EventEmitter.jsm',
'SyncedTabsDeckComponent.js',
@@ -19,6 +15,3 @@ EXTRA_JS_MODULES.syncedtabs += [
'util.js',
]
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Synced tabs')
-
diff --git a/browser/components/syncedtabs/test/browser/.eslintrc.js b/browser/components/syncedtabs/test/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/components/syncedtabs/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/syncedtabs/test/browser/browser.ini b/browser/components/syncedtabs/test/browser/browser.ini
deleted file mode 100644
index 02fa364f1..000000000
--- a/browser/components/syncedtabs/test/browser/browser.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[DEFAULT]
-support-files = head.js
-
-[browser_sidebar_syncedtabslist.js]
diff --git a/browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js b/browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js
deleted file mode 100644
index afbc00282..000000000
--- a/browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js
+++ /dev/null
@@ -1,410 +0,0 @@
-"use strict";
-
-const FIXTURE = [
- {
- "id": "7cqCr77ptzX3",
- "type": "client",
- "name": "zcarter's Nightly on MacBook-Pro-25",
- "isMobile": false,
- "tabs": [
- {
- "type": "tab",
- "title": "Firefox for Android — Mobile Web browser — More ways to customize and protect your privacy — Mozilla",
- "url": "https://www.mozilla.org/en-US/firefox/android/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
- "icon": "chrome://mozapps/skin/places/defaultFavicon.png",
- "client": "7cqCr77ptzX3",
- "lastUsed": 1452124677
- }
- ]
- },
- {
- "id": "2xU5h-4bkWqA",
- "type": "client",
- "name": "laptop",
- "isMobile": false,
- "tabs": [
- {
- "type": "tab",
- "title": "Firefox for iOS — Mobile Web browser for your iPhone, iPad and iPod touch — Mozilla",
- "url": "https://www.mozilla.org/en-US/firefox/ios/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
- "icon": "moz-anno:favicon:https://www.mozilla.org/media/img/firefox/favicon.dc6635050bf5.ico",
- "client": "2xU5h-4bkWqA",
- "lastUsed": 1451519425
- },
- {
- "type": "tab",
- "title": "Firefox Nightly First Run Page",
- "url": "https://www.mozilla.org/en-US/firefox/nightly/firstrun/?oldversion=45.0a1",
- "icon": "moz-anno:favicon:https://www.mozilla.org/media/img/firefox/favicon-nightly.560395bbb2e1.png",
- "client": "2xU5h-4bkWqA",
- "lastUsed": 1451519420
- },
- {
- // Should appear first for this client.
- "type": "tab",
- "title": "Mozilla Developer Network",
- "url": "https://developer.mozilla.org/en-US/",
- "icon": "moz-anno:favicon:https://developer.cdn.mozilla.net/static/img/favicon32.e02854fdcf73.png",
- "client": "2xU5h-4bkWqA",
- "lastUsed": 1451519725
- }
- ]
- },
- {
- "id": "OL3EJCsdb2JD",
- "type": "client",
- "name": "desktop",
- "isMobile": false,
- "tabs": []
- }
-];
-
-let originalSyncedTabsInternal = null;
-
-function* testClean() {
- let syncedTabsDeckComponent = window.SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
- let SyncedTabs = window.SidebarUI.browser.contentWindow.SyncedTabs;
- syncedTabsDeckComponent._accountStatus.restore();
- SyncedTabs._internal.getTabClients.restore();
- SyncedTabs._internal = originalSyncedTabsInternal;
-
- yield new Promise(resolve => {
- window.SidebarUI.browser.contentWindow.addEventListener("unload", function listener() {
- window.SidebarUI.browser.contentWindow.removeEventListener("unload", listener);
- resolve();
- });
- SidebarUI.hide();
- });
-}
-
-add_task(function* testSyncedTabsSidebarList() {
- yield SidebarUI.show('viewTabsSidebar');
-
- Assert.equal(SidebarUI.currentID, "viewTabsSidebar", "Sidebar should have SyncedTabs loaded");
-
- let syncedTabsDeckComponent = SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
- let SyncedTabs = SidebarUI.browser.contentWindow.SyncedTabs;
-
- Assert.ok(syncedTabsDeckComponent, "component exists");
-
- originalSyncedTabsInternal = SyncedTabs._internal;
- SyncedTabs._internal = {
- isConfiguredToSyncTabs: true,
- hasSyncedThisSession: true,
- getTabClients() { return Promise.resolve([]) },
- syncTabs() { return Promise.resolve(); },
- };
-
- sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(true));
- sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve(Cu.cloneInto(FIXTURE, {})));
-
- yield syncedTabsDeckComponent.updatePanel();
- // This is a hacky way of waiting for the view to render. The view renders
- // after the following promise (a different instance of which is triggered
- // in updatePanel) resolves, so we wait for it here as well
- yield syncedTabsDeckComponent.tabListComponent._store.getData();
-
- Assert.ok(SyncedTabs._internal.getTabClients.called, "get clients called");
-
- let selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
-
-
- Assert.ok(selectedPanel.classList.contains("tabs-container"),
- "tabs panel is selected");
-
- Assert.equal(selectedPanel.querySelectorAll(".tab").length, 4,
- "four tabs listed");
- Assert.equal(selectedPanel.querySelectorAll(".client").length, 3,
- "three clients listed");
- Assert.equal(selectedPanel.querySelectorAll(".client")[2].querySelectorAll(".empty").length, 1,
- "third client is empty");
-
- // Verify that the tabs are sorted by last used time.
- var expectedTabIndices = [[0], [2, 0, 1]];
- Array.prototype.forEach.call(selectedPanel.querySelectorAll(".client"), (clientNode, i) => {
- checkItem(clientNode, FIXTURE[i]);
- Array.prototype.forEach.call(clientNode.querySelectorAll(".tab"), (tabNode, j) => {
- let tabIndex = expectedTabIndices[i][j];
- checkItem(tabNode, FIXTURE[i].tabs[tabIndex]);
- });
- });
-
-});
-
-add_task(testClean);
-
-add_task(function* testSyncedTabsSidebarFilteredList() {
- yield SidebarUI.show('viewTabsSidebar');
- let syncedTabsDeckComponent = window.SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
- let SyncedTabs = window.SidebarUI.browser.contentWindow.SyncedTabs;
-
- Assert.ok(syncedTabsDeckComponent, "component exists");
-
- originalSyncedTabsInternal = SyncedTabs._internal;
- SyncedTabs._internal = {
- isConfiguredToSyncTabs: true,
- hasSyncedThisSession: true,
- getTabClients() { return Promise.resolve([]) },
- syncTabs() { return Promise.resolve(); },
- };
-
- sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(true));
- sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve(Cu.cloneInto(FIXTURE, {})));
-
- yield syncedTabsDeckComponent.updatePanel();
- // This is a hacky way of waiting for the view to render. The view renders
- // after the following promise (a different instance of which is triggered
- // in updatePanel) resolves, so we wait for it here as well
- yield syncedTabsDeckComponent.tabListComponent._store.getData();
-
- let filterInput = syncedTabsDeckComponent._window.document.querySelector(".tabsFilter");
- filterInput.value = "filter text";
- filterInput.blur();
-
- yield syncedTabsDeckComponent.tabListComponent._store.getData("filter text");
-
- let selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("tabs-container"),
- "tabs panel is selected");
-
- Assert.equal(selectedPanel.querySelectorAll(".tab").length, 4,
- "four tabs listed");
- Assert.equal(selectedPanel.querySelectorAll(".client").length, 0,
- "no clients are listed");
-
- Assert.equal(filterInput.value, "filter text",
- "filter text box has correct value");
-
- // Tabs should not be sorted when filter is active.
- let FIXTURE_TABS = FIXTURE.reduce((prev, client) => prev.concat(client.tabs), []);
-
- Array.prototype.forEach.call(selectedPanel.querySelectorAll(".tab"), (tabNode, i) => {
- checkItem(tabNode, FIXTURE_TABS[i]);
- });
-
- // Removing the filter should resort tabs.
- FIXTURE_TABS.sort((a, b) => b.lastUsed - a.lastUsed);
- yield syncedTabsDeckComponent.tabListComponent._store.getData();
- Array.prototype.forEach.call(selectedPanel.querySelectorAll(".tab"), (tabNode, i) => {
- checkItem(tabNode, FIXTURE_TABS[i]);
- });
-});
-
-add_task(testClean);
-
-add_task(function* testSyncedTabsSidebarStatus() {
- let accountExists = false;
-
- yield SidebarUI.show('viewTabsSidebar');
- let syncedTabsDeckComponent = window.SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
- let SyncedTabs = window.SidebarUI.browser.contentWindow.SyncedTabs;
-
- originalSyncedTabsInternal = SyncedTabs._internal;
- SyncedTabs._internal = {
- isConfiguredToSyncTabs: false,
- hasSyncedThisSession: false,
- getTabClients() {},
- syncTabs() { return Promise.resolve(); },
- };
-
- Assert.ok(syncedTabsDeckComponent, "component exists");
-
- sinon.spy(syncedTabsDeckComponent, "updatePanel");
- sinon.spy(syncedTabsDeckComponent, "observe");
-
- sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.reject("Test error"));
- yield syncedTabsDeckComponent.updatePanel();
-
- let selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("notAuthedInfo"),
- "not-authed panel is selected on auth error");
-
- syncedTabsDeckComponent._accountStatus.restore();
- sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(accountExists));
- yield syncedTabsDeckComponent.updatePanel();
- selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("notAuthedInfo"),
- "not-authed panel is selected");
-
- accountExists = true;
- yield syncedTabsDeckComponent.updatePanel();
- selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("tabs-disabled"),
- "tabs disabled panel is selected");
-
- SyncedTabs._internal.isConfiguredToSyncTabs = true;
- yield syncedTabsDeckComponent.updatePanel();
- selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("tabs-fetching"),
- "tabs fetch panel is selected");
-
- SyncedTabs._internal.hasSyncedThisSession = true;
- sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve([]));
- yield syncedTabsDeckComponent.updatePanel();
- selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("singleDeviceInfo"),
- "tabs fetch panel is selected");
-
- SyncedTabs._internal.getTabClients.restore();
- sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve([{id: "mock"}]));
- yield syncedTabsDeckComponent.updatePanel();
- selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- Assert.ok(selectedPanel.classList.contains("tabs-container"),
- "tabs panel is selected");
-});
-
-add_task(testClean);
-
-add_task(function* testSyncedTabsSidebarContextMenu() {
- yield SidebarUI.show('viewTabsSidebar');
- let syncedTabsDeckComponent = window.SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
- let SyncedTabs = window.SidebarUI.browser.contentWindow.SyncedTabs;
-
- Assert.ok(syncedTabsDeckComponent, "component exists");
-
- originalSyncedTabsInternal = SyncedTabs._internal;
- SyncedTabs._internal = {
- isConfiguredToSyncTabs: true,
- hasSyncedThisSession: true,
- getTabClients() { return Promise.resolve([]) },
- syncTabs() { return Promise.resolve(); },
- };
-
- sinon.stub(syncedTabsDeckComponent, "_accountStatus", () => Promise.resolve(true));
- sinon.stub(SyncedTabs._internal, "getTabClients", () => Promise.resolve(Cu.cloneInto(FIXTURE, {})));
-
- yield syncedTabsDeckComponent.updatePanel();
- // This is a hacky way of waiting for the view to render. The view renders
- // after the following promise (a different instance of which is triggered
- // in updatePanel) resolves, so we wait for it here as well
- yield syncedTabsDeckComponent.tabListComponent._store.getData();
-
- info("Right-clicking the search box should show text-related actions");
- let filterMenuItems = [
- "menuitem[cmd=cmd_undo]",
- "menuseparator",
- // We don't check whether the commands are enabled due to platform
- // differences. On OS X and Windows, "cut" and "copy" are always enabled
- // for HTML inputs; on Linux, they're only enabled if text is selected.
- "menuitem[cmd=cmd_cut]",
- "menuitem[cmd=cmd_copy]",
- "menuitem[cmd=cmd_paste]",
- "menuitem[cmd=cmd_delete]",
- "menuseparator",
- "menuitem[cmd=cmd_selectAll]",
- "menuseparator",
- "menuitem#syncedTabsRefreshFilter",
- ];
- yield* testContextMenu(syncedTabsDeckComponent,
- "#SyncedTabsSidebarTabsFilterContext",
- ".tabsFilter",
- filterMenuItems);
-
- info("Right-clicking a tab should show additional actions");
- let tabMenuItems = [
- ["menuitem#syncedTabsOpenSelected", { hidden: false }],
- ["menuitem#syncedTabsOpenSelectedInTab", { hidden: false }],
- ["menuitem#syncedTabsOpenSelectedInWindow", { hidden: false }],
- ["menuitem#syncedTabsOpenSelectedInPrivateWindow", { hidden: false }],
- ["menuseparator", { hidden: false }],
- ["menuitem#syncedTabsBookmarkSelected", { hidden: false }],
- ["menuitem#syncedTabsCopySelected", { hidden: false }],
- ["menuseparator", { hidden: false }],
- ["menuitem#syncedTabsRefresh", { hidden: false }],
- ];
- yield* testContextMenu(syncedTabsDeckComponent,
- "#SyncedTabsSidebarContext",
- "#tab-7cqCr77ptzX3-0",
- tabMenuItems);
-
- info("Right-clicking a client shouldn't show any actions");
- let sidebarMenuItems = [
- ["menuitem#syncedTabsOpenSelected", { hidden: true }],
- ["menuitem#syncedTabsOpenSelectedInTab", { hidden: true }],
- ["menuitem#syncedTabsOpenSelectedInWindow", { hidden: true }],
- ["menuitem#syncedTabsOpenSelectedInPrivateWindow", { hidden: true }],
- ["menuseparator", { hidden: true }],
- ["menuitem#syncedTabsBookmarkSelected", { hidden: true }],
- ["menuitem#syncedTabsCopySelected", { hidden: true }],
- ["menuseparator", { hidden: true }],
- ["menuitem#syncedTabsRefresh", { hidden: false }],
- ];
- yield* testContextMenu(syncedTabsDeckComponent,
- "#SyncedTabsSidebarContext",
- "#item-OL3EJCsdb2JD",
- sidebarMenuItems);
-});
-
-add_task(testClean);
-
-function checkItem(node, item) {
- Assert.ok(node.classList.contains("item"),
- "Node should have .item class");
- if (item.client) {
- // tab items
- Assert.equal(node.querySelector(".item-title").textContent, item.title,
- "Node's title element's text should match item title");
- Assert.ok(node.classList.contains("tab"),
- "Node should have .tab class");
- Assert.equal(node.dataset.url, item.url,
- "Node's URL should match item URL");
- Assert.equal(node.getAttribute("title"), item.title + "\n" + item.url,
- "Tab node should have correct title attribute");
- } else {
- // client items
- Assert.equal(node.querySelector(".item-title").textContent, item.name,
- "Node's title element's text should match client name");
- Assert.ok(node.classList.contains("client"),
- "Node should have .client class");
- Assert.equal(node.dataset.id, item.id,
- "Node's ID should match item ID");
- }
-}
-
-function* testContextMenu(syncedTabsDeckComponent, contextSelector, triggerSelector, menuSelectors) {
- let contextMenu = document.querySelector(contextSelector);
- let triggerElement = syncedTabsDeckComponent._window.document.querySelector(triggerSelector);
- let isClosed = triggerElement.classList.contains("closed");
-
- let promisePopupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
-
- let chromeWindow = triggerElement.ownerGlobal.top;
- let rect = triggerElement.getBoundingClientRect();
- let contentRect = chromeWindow.SidebarUI.browser.getBoundingClientRect();
- // The offsets in `rect` are relative to the content window, but
- // `synthesizeMouseAtPoint` calls `nsIDOMWindowUtils.sendMouseEvent`,
- // which interprets the offsets relative to the containing *chrome* window.
- // This means we need to account for the width and height of any elements
- // outside the `browser` element, like `sidebarheader`.
- let offsetX = contentRect.x + rect.x + (rect.width / 2);
- let offsetY = contentRect.y + rect.y + (rect.height / 4);
-
- yield EventUtils.synthesizeMouseAtPoint(offsetX, offsetY, {
- type: "contextmenu",
- button: 2,
- }, chromeWindow);
- yield promisePopupShown;
- is(triggerElement.classList.contains("closed"), isClosed,
- "Showing the context menu shouldn't toggle the tab list");
- checkChildren(contextMenu, menuSelectors);
-
- let promisePopupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- contextMenu.hidePopup();
- yield promisePopupHidden;
-}
-
-function checkChildren(node, selectors) {
- is(node.children.length, selectors.length, "Menu item count doesn't match");
- for (let index = 0; index < node.children.length; index++) {
- let child = node.children[index];
- let [selector, props] = [].concat(selectors[index]);
- ok(selector, `Node at ${index} should have selector`);
- ok(child.matches(selector), `Node ${
- index} should match ${selector}`);
- if (props) {
- Object.keys(props).forEach(prop => {
- is(child[prop], props[prop], `${prop} value at ${index} should match`);
- });
- }
- }
-}
diff --git a/browser/components/syncedtabs/test/browser/head.js b/browser/components/syncedtabs/test/browser/head.js
deleted file mode 100644
index 40e36123e..000000000
--- a/browser/components/syncedtabs/test/browser/head.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-
-// Load mocking/stubbing library, sinon
-// docs: http://sinonjs.org/docs/
-/* global sinon */
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
-loader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
-
-registerCleanupFunction(function*() {
- // Cleanup window or the test runner will throw an error
- delete window.sinon;
- delete window.setImmediate;
- delete window.clearImmediate;
-});
diff --git a/browser/components/syncedtabs/test/xpcshell/.eslintrc.js b/browser/components/syncedtabs/test/xpcshell/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/syncedtabs/test/xpcshell/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/syncedtabs/test/xpcshell/head.js b/browser/components/syncedtabs/test/xpcshell/head.js
deleted file mode 100644
index 00055231c..000000000
--- a/browser/components/syncedtabs/test/xpcshell/head.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
- return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {});
-});
-
-Cu.import("resource://gre/modules/Timer.jsm");
-
-do_get_profile(); // fxa needs a profile directory for storage.
-
-// Create a window polyfill so sinon can load
-let window = {
- document: {},
- location: {},
- setTimeout: setTimeout,
- setInterval: setInterval,
- clearTimeout: clearTimeout,
- clearinterval: clearInterval
-};
-let self = window;
-
-// Load mocking/stubbing library, sinon
-// docs: http://sinonjs.org/docs/
-/* global sinon */
-let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
-loader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
diff --git a/browser/components/syncedtabs/test/xpcshell/test_EventEmitter.js b/browser/components/syncedtabs/test/xpcshell/test_EventEmitter.js
deleted file mode 100644
index bc73ac621..000000000
--- a/browser/components/syncedtabs/test/xpcshell/test_EventEmitter.js
+++ /dev/null
@@ -1,35 +0,0 @@
-"use strict";
-
-let { EventEmitter } = Cu.import("resource:///modules/syncedtabs/EventEmitter.jsm", {});
-
-add_task(function* testSingleListener() {
- let eventEmitter = new EventEmitter();
- let spy = sinon.spy();
-
- eventEmitter.on("click", spy);
- eventEmitter.emit("click", "foo", "bar");
- Assert.ok(spy.calledOnce);
- Assert.ok(spy.calledWith("foo", "bar"));
-
- eventEmitter.off("click", spy);
- eventEmitter.emit("click");
- Assert.ok(spy.calledOnce);
-});
-
-add_task(function* testMultipleListeners() {
- let eventEmitter = new EventEmitter();
- let spy1 = sinon.spy();
- let spy2 = sinon.spy();
-
- eventEmitter.on("some_event", spy1);
- eventEmitter.on("some_event", spy2);
- eventEmitter.emit("some_event");
- Assert.ok(spy1.calledOnce);
- Assert.ok(spy2.calledOnce);
-
- eventEmitter.off("some_event", spy1);
- eventEmitter.emit("some_event");
- Assert.ok(spy1.calledOnce);
- Assert.ok(spy2.calledTwice);
-});
-
diff --git a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js b/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js
deleted file mode 100644
index 3d748b33c..000000000
--- a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckComponent.js
+++ /dev/null
@@ -1,218 +0,0 @@
-"use strict";
-
-let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
-let { SyncedTabsDeckComponent } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckComponent.js", {});
-let { TabListComponent } = Cu.import("resource:///modules/syncedtabs/TabListComponent.js", {});
-let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
-let { SyncedTabsDeckStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckStore.js", {});
-let { TabListView } = Cu.import("resource:///modules/syncedtabs/TabListView.js", {});
-let { DeckView } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckView.js", {});
-
-
-add_task(function* testInitUninit() {
- let deckStore = new SyncedTabsDeckStore();
- let listComponent = {};
-
- let ViewMock = sinon.stub();
- let view = {render: sinon.spy(), destroy: sinon.spy(), container: {}};
- ViewMock.returns(view);
-
- sinon.stub(SyncedTabs, "syncTabs", () => Promise.resolve());
-
- sinon.spy(deckStore, "on");
- sinon.stub(deckStore, "setPanels");
-
- let component = new SyncedTabsDeckComponent({
- window,
- deckStore,
- listComponent,
- SyncedTabs,
- DeckView: ViewMock,
- });
-
- sinon.stub(component, "updatePanel");
-
- component.init();
-
- Assert.ok(SyncedTabs.syncTabs.called);
- SyncedTabs.syncTabs.restore();
-
- Assert.ok(ViewMock.calledWithNew(), "view is instantiated");
- Assert.equal(ViewMock.args[0][0], window);
- Assert.equal(ViewMock.args[0][1], listComponent);
- Assert.ok(ViewMock.args[0][2].onAndroidClick,
- "view is passed onAndroidClick prop");
- Assert.ok(ViewMock.args[0][2].oniOSClick,
- "view is passed oniOSClick prop");
- Assert.ok(ViewMock.args[0][2].onSyncPrefClick,
- "view is passed onSyncPrefClick prop");
-
- Assert.equal(component.container, view.container,
- "component returns view's container");
-
- Assert.ok(deckStore.on.calledOnce, "listener is added to store");
- Assert.equal(deckStore.on.args[0][0], "change");
- // Object.values only in nightly
- let values = Object.keys(component.PANELS).map(k => component.PANELS[k]);
- Assert.ok(deckStore.setPanels.calledWith(values),
- "panels are set on deck store");
-
- Assert.ok(component.updatePanel.called);
-
- deckStore.emit("change", "mock state");
- Assert.ok(view.render.calledWith("mock state"),
- "view.render is called on state change");
-
- component.uninit();
-
- Assert.ok(view.destroy.calledOnce, "view is destroyed on uninit");
-});
-
-
-function waitForObserver() {
- return new Promise((resolve, reject) => {
- Services.obs.addObserver((subject, topic) => {
- resolve();
- }, SyncedTabs.TOPIC_TABS_CHANGED, false);
- });
-}
-
-add_task(function* testObserver() {
- let deckStore = new SyncedTabsDeckStore();
- let listStore = new SyncedTabsListStore(SyncedTabs);
- let listComponent = {};
-
- let ViewMock = sinon.stub();
- let view = {render: sinon.spy(), destroy: sinon.spy(), container: {}};
- ViewMock.returns(view);
-
- sinon.stub(SyncedTabs, "syncTabs", () => Promise.resolve());
-
- sinon.spy(deckStore, "on");
- sinon.stub(deckStore, "setPanels");
-
- sinon.stub(listStore, "getData");
-
- let component = new SyncedTabsDeckComponent({
- window,
- deckStore,
- listStore,
- listComponent,
- SyncedTabs,
- DeckView: ViewMock,
- });
-
- sinon.spy(component, "observe");
- sinon.stub(component, "updatePanel");
-
- component.init();
- SyncedTabs.syncTabs.restore();
- Assert.ok(component.updatePanel.called, "triggers panel update during init");
-
- Services.obs.notifyObservers(null, SyncedTabs.TOPIC_TABS_CHANGED, "");
-
- Assert.ok(component.observe.calledWith(null, SyncedTabs.TOPIC_TABS_CHANGED, ""),
- "component is notified");
-
- Assert.ok(listStore.getData.called, "gets list data");
- Assert.ok(component.updatePanel.calledTwice, "triggers panel update");
-
- Services.obs.notifyObservers(null, FxAccountsCommon.ONLOGIN_NOTIFICATION, "");
-
- Assert.ok(component.observe.calledWith(null, FxAccountsCommon.ONLOGIN_NOTIFICATION, ""),
- "component is notified of login");
- Assert.equal(component.updatePanel.callCount, 3, "triggers panel update again");
-});
-
-add_task(function* testPanelStatus() {
- let deckStore = new SyncedTabsDeckStore();
- let listStore = new SyncedTabsListStore();
- let listComponent = {};
- let fxAccounts = {
- accountStatus() {}
- };
- let SyncedTabsMock = {
- getTabClients() {}
- };
-
- sinon.stub(listStore, "getData");
-
-
- let component = new SyncedTabsDeckComponent({
- fxAccounts,
- deckStore,
- listComponent,
- SyncedTabs: SyncedTabsMock,
- });
-
- let isAuthed = false;
- sinon.stub(fxAccounts, "accountStatus", () => Promise.resolve(isAuthed));
- let result = yield component.getPanelStatus();
- Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
-
- isAuthed = true;
-
- SyncedTabsMock.isConfiguredToSyncTabs = false;
- result = yield component.getPanelStatus();
- Assert.equal(result, component.PANELS.TABS_DISABLED);
-
- SyncedTabsMock.isConfiguredToSyncTabs = true;
-
- SyncedTabsMock.hasSyncedThisSession = false;
- result = yield component.getPanelStatus();
- Assert.equal(result, component.PANELS.TABS_FETCHING);
-
- SyncedTabsMock.hasSyncedThisSession = true;
-
- let clients = [];
- sinon.stub(SyncedTabsMock, "getTabClients", () => Promise.resolve(clients));
- result = yield component.getPanelStatus();
- Assert.equal(result, component.PANELS.SINGLE_DEVICE_INFO);
-
- clients = ["mock-client"];
- result = yield component.getPanelStatus();
- Assert.equal(result, component.PANELS.TABS_CONTAINER);
-
- fxAccounts.accountStatus.restore();
- sinon.stub(fxAccounts, "accountStatus", () => Promise.reject("err"));
- result = yield component.getPanelStatus();
- Assert.equal(result, component.PANELS.NOT_AUTHED_INFO);
-
- sinon.stub(component, "getPanelStatus", () => Promise.resolve("mock-panelId"));
- sinon.spy(deckStore, "selectPanel");
- yield component.updatePanel();
- Assert.ok(deckStore.selectPanel.calledWith("mock-panelId"));
-});
-
-add_task(function* testActions() {
- let windowMock = {
- openUILink() {},
- };
- let chromeWindowMock = {
- gSyncUI: {
- openSetup() {}
- }
- };
- sinon.spy(windowMock, "openUILink");
- sinon.spy(chromeWindowMock.gSyncUI, "openSetup");
-
- let getChromeWindowMock = sinon.stub();
- getChromeWindowMock.returns(chromeWindowMock);
-
- let component = new SyncedTabsDeckComponent({
- window: windowMock,
- getChromeWindowMock
- });
-
- let href = Services.prefs.getCharPref("identity.mobilepromo.android") + "synced-tabs-sidebar";
- component.openAndroidLink("mock-event");
- Assert.ok(windowMock.openUILink.calledWith(href, "mock-event"));
-
- href = Services.prefs.getCharPref("identity.mobilepromo.ios") + "synced-tabs-sidebar";
- component.openiOSLink("mock-event");
- Assert.ok(windowMock.openUILink.calledWith(href, "mock-event"));
-
- component.openSyncPrefs();
- Assert.ok(getChromeWindowMock.calledWith(windowMock));
- Assert.ok(chromeWindowMock.gSyncUI.openSetup.called);
-});
diff --git a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckStore.js b/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckStore.js
deleted file mode 100644
index 69abb4024..000000000
--- a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsDeckStore.js
+++ /dev/null
@@ -1,64 +0,0 @@
-"use strict";
-
-let { SyncedTabsDeckStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckStore.js", {});
-
-add_task(function* testSelectUnkownPanel() {
- let deckStore = new SyncedTabsDeckStore();
- let spy = sinon.spy();
-
- deckStore.on("change", spy);
- deckStore.selectPanel("foo");
-
- Assert.ok(!spy.called);
-});
-
-add_task(function* testSetPanels() {
- let deckStore = new SyncedTabsDeckStore();
- let spy = sinon.spy();
-
- deckStore.on("change", spy);
- deckStore.setPanels(["panel1", "panel2"]);
-
- Assert.ok(spy.calledWith({
- panels: [
- { id: "panel1", selected: false },
- { id: "panel2", selected: false },
- ],
- isUpdatable: false
- }));
-});
-
-add_task(function* testSelectPanel() {
- let deckStore = new SyncedTabsDeckStore();
- let spy = sinon.spy();
-
- deckStore.setPanels(["panel1", "panel2"]);
-
- deckStore.on("change", spy);
- deckStore.selectPanel("panel2");
-
- Assert.ok(spy.calledWith({
- panels: [
- { id: "panel1", selected: false },
- { id: "panel2", selected: true },
- ],
- isUpdatable: true
- }));
-
- deckStore.selectPanel("panel2");
- Assert.ok(spy.calledOnce, "doesn't trigger unless panel changes");
-});
-
-add_task(function* testSetPanelsSameArray() {
- let deckStore = new SyncedTabsDeckStore();
- let spy = sinon.spy();
- deckStore.on("change", spy);
-
- let panels = ["panel1", "panel2"];
-
- deckStore.setPanels(panels);
- deckStore.setPanels(panels);
-
- Assert.ok(spy.calledOnce, "doesn't trigger unless set of panels changes");
-});
-
diff --git a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js b/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js
deleted file mode 100644
index 51580235f..000000000
--- a/browser/components/syncedtabs/test/xpcshell/test_SyncedTabsListStore.js
+++ /dev/null
@@ -1,266 +0,0 @@
-"use strict";
-
-let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
-let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
-
-const FIXTURE = [
- {
- "id": "2xU5h-4bkWqA",
- "type": "client",
- "name": "laptop",
- "isMobile": false,
- "tabs": [
- {
- "type": "tab",
- "title": "Firefox for iOS — Mobile Web browser for your iPhone, iPad and iPod touch — Mozilla",
- "url": "https://www.mozilla.org/en-US/firefox/ios/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=synced-tabs-sidebar",
- "icon": "moz-anno:favicon:https://www.mozilla.org/media/img/firefox/favicon.dc6635050bf5.ico",
- "client": "2xU5h-4bkWqA",
- "lastUsed": 1451519425
- },
- {
- "type": "tab",
- "title": "Firefox Nightly First Run Page",
- "url": "https://www.mozilla.org/en-US/firefox/nightly/firstrun/?oldversion=45.0a1",
- "icon": "moz-anno:favicon:https://www.mozilla.org/media/img/firefox/favicon-nightly.560395bbb2e1.png",
- "client": "2xU5h-4bkWqA",
- "lastUsed": 1451519420
- }
- ]
- },
- {
- "id": "OL3EJCsdb2JD",
- "type": "client",
- "name": "desktop",
- "isMobile": false,
- "tabs": []
- }
-];
-
-add_task(function* testGetDataEmpty() {
- let store = new SyncedTabsListStore(SyncedTabs);
- let spy = sinon.spy();
-
- sinon.stub(SyncedTabs, "getTabClients", () => {
- return Promise.resolve([]);
- });
- store.on("change", spy);
-
- yield store.getData();
-
- Assert.ok(SyncedTabs.getTabClients.calledWith(""));
- Assert.ok(spy.calledWith({
- clients: [],
- canUpdateAll: false,
- canUpdateInput: false,
- filter: "",
- inputFocused: false
- }));
-
- yield store.getData("filter");
-
- Assert.ok(SyncedTabs.getTabClients.calledWith("filter"));
- Assert.ok(spy.calledWith({
- clients: [],
- canUpdateAll: false,
- canUpdateInput: true,
- filter: "filter",
- inputFocused: false
- }));
-
- SyncedTabs.getTabClients.restore();
-});
-
-add_task(function* testRowSelectionWithoutFilter() {
- let store = new SyncedTabsListStore(SyncedTabs);
- let spy = sinon.spy();
-
- sinon.stub(SyncedTabs, "getTabClients", () => {
- return Promise.resolve(FIXTURE);
- });
-
- yield store.getData();
- SyncedTabs.getTabClients.restore();
-
- store.on("change", spy);
-
- store.selectRow(0, -1);
- Assert.ok(spy.args[0][0].canUpdateAll, "can update the whole view");
- Assert.ok(spy.args[0][0].clients[0].selected, "first client is selected");
-
- store.moveSelectionUp();
- Assert.ok(spy.calledOnce,
- "can't move up past first client, no change triggered");
-
- store.selectRow(0, 0);
- Assert.ok(spy.args[1][0].clients[0].tabs[0].selected,
- "first tab of first client is selected");
-
- store.selectRow(0, 0);
- Assert.ok(spy.calledTwice, "selecting same row doesn't trigger change");
-
- store.selectRow(0, 1);
- Assert.ok(spy.args[2][0].clients[0].tabs[1].selected,
- "second tab of first client is selected");
-
- store.selectRow(1);
- Assert.ok(spy.args[3][0].clients[1].selected, "second client is selected");
-
- store.moveSelectionDown();
- Assert.equal(spy.callCount, 4,
- "can't move selection down past last client, no change triggered");
-
- store.moveSelectionUp();
- Assert.equal(spy.callCount, 5,
- "changed");
- Assert.ok(spy.args[4][0].clients[0].tabs[FIXTURE[0].tabs.length - 1].selected,
- "move selection up from client selects last tab of previous client");
-
- store.moveSelectionUp();
- Assert.ok(spy.args[5][0].clients[0].tabs[FIXTURE[0].tabs.length - 2].selected,
- "move selection up from tab selects previous tab of client");
-});
-
-
-add_task(function* testToggleBranches() {
- let store = new SyncedTabsListStore(SyncedTabs);
- let spy = sinon.spy();
-
- sinon.stub(SyncedTabs, "getTabClients", () => {
- return Promise.resolve(FIXTURE);
- });
-
- yield store.getData();
- SyncedTabs.getTabClients.restore();
-
- store.selectRow(0);
- store.on("change", spy);
-
- let clientId = FIXTURE[0].id;
- store.closeBranch(clientId);
- Assert.ok(spy.args[0][0].clients[0].closed, "first client is closed");
-
- store.openBranch(clientId);
- Assert.ok(!spy.args[1][0].clients[0].closed, "first client is open");
-
- store.toggleBranch(clientId);
- Assert.ok(spy.args[2][0].clients[0].closed, "first client is toggled closed");
-
- store.moveSelectionDown();
- Assert.ok(spy.args[3][0].clients[1].selected,
- "selection skips tabs if client is closed");
-
- store.moveSelectionUp();
- Assert.ok(spy.args[4][0].clients[0].selected,
- "selection skips tabs if client is closed");
-});
-
-
-add_task(function* testRowSelectionWithFilter() {
- let store = new SyncedTabsListStore(SyncedTabs);
- let spy = sinon.spy();
-
- sinon.stub(SyncedTabs, "getTabClients", () => {
- return Promise.resolve(FIXTURE);
- });
-
- yield store.getData("filter");
- SyncedTabs.getTabClients.restore();
-
- store.on("change", spy);
-
- store.selectRow(0);
- Assert.ok(spy.args[0][0].clients[0].tabs[0].selected, "first tab is selected");
-
- store.moveSelectionUp();
- Assert.ok(spy.calledOnce,
- "can't move up past first tab, no change triggered");
-
- store.moveSelectionDown();
- Assert.ok(spy.args[1][0].clients[0].tabs[1].selected,
- "selection skips tabs if client is closed");
-
- store.moveSelectionDown();
- Assert.equal(spy.callCount, 2,
- "can't move selection down past last tab, no change triggered");
-
- store.selectRow(1);
- Assert.equal(spy.callCount, 2,
- "doesn't trigger change if same row selected");
-
-});
-
-
-add_task(function* testFilterAndClearFilter() {
- let store = new SyncedTabsListStore(SyncedTabs);
- let spy = sinon.spy();
-
- sinon.stub(SyncedTabs, "getTabClients", () => {
- return Promise.resolve(FIXTURE);
- });
- store.on("change", spy);
-
- yield store.getData("filter");
-
- Assert.ok(SyncedTabs.getTabClients.calledWith("filter"));
- Assert.ok(!spy.args[0][0].canUpdateAll, "can't update all");
- Assert.ok(spy.args[0][0].canUpdateInput, "can update just input");
-
- store.selectRow(0);
-
- Assert.equal(spy.args[1][0].filter, "filter");
- Assert.ok(spy.args[1][0].clients[0].tabs[0].selected,
- "tab is selected");
-
- yield store.clearFilter();
-
- Assert.ok(SyncedTabs.getTabClients.calledWith(""));
- Assert.ok(!spy.args[2][0].canUpdateAll, "can't update all");
- Assert.ok(!spy.args[2][0].canUpdateInput, "can't just update input");
-
- Assert.equal(spy.args[2][0].filter, "");
- Assert.ok(!spy.args[2][0].clients[0].tabs[0].selected,
- "tab is no longer selected");
-
- SyncedTabs.getTabClients.restore();
-});
-
-add_task(function* testFocusBlurInput() {
- let store = new SyncedTabsListStore(SyncedTabs);
- let spy = sinon.spy();
-
- sinon.stub(SyncedTabs, "getTabClients", () => {
- return Promise.resolve(FIXTURE);
- });
- store.on("change", spy);
-
- yield store.getData();
- SyncedTabs.getTabClients.restore();
-
- Assert.ok(!spy.args[0][0].canUpdateAll, "must rerender all");
-
- store.selectRow(0);
- Assert.ok(!spy.args[1][0].inputFocused,
- "input is not focused");
- Assert.ok(spy.args[1][0].clients[0].selected,
- "client is selected");
- Assert.ok(spy.args[1][0].clients[0].focused,
- "client is focused");
-
- store.focusInput();
- Assert.ok(spy.args[2][0].inputFocused,
- "input is focused");
- Assert.ok(spy.args[2][0].clients[0].selected,
- "client is still selected");
- Assert.ok(!spy.args[2][0].clients[0].focused,
- "client is no longer focused");
-
- store.blurInput();
- Assert.ok(!spy.args[3][0].inputFocused,
- "input is not focused");
- Assert.ok(spy.args[3][0].clients[0].selected,
- "client is selected");
- Assert.ok(spy.args[3][0].clients[0].focused,
- "client is focused");
-});
-
diff --git a/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js b/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js
deleted file mode 100644
index 0b0665a1b..000000000
--- a/browser/components/syncedtabs/test/xpcshell/test_TabListComponent.js
+++ /dev/null
@@ -1,155 +0,0 @@
-"use strict";
-
-let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
-let { TabListComponent } = Cu.import("resource:///modules/syncedtabs/TabListComponent.js", {});
-let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
-let { View } = Cu.import("resource:///modules/syncedtabs/TabListView.js", {});
-
-const ACTION_METHODS = [
- "onSelectRow",
- "onOpenTab",
- "onOpenTabs",
- "onMoveSelectionDown",
- "onMoveSelectionUp",
- "onToggleBranch",
- "onBookmarkTab",
- "onSyncRefresh",
- "onFilter",
- "onClearFilter",
- "onFilterFocus",
- "onFilterBlur",
-];
-
-add_task(function* testInitUninit() {
- let store = new SyncedTabsListStore();
- let ViewMock = sinon.stub();
- let view = {render() {}, destroy() {}};
-
- ViewMock.returns(view);
-
- sinon.spy(view, 'render');
- sinon.spy(view, 'destroy');
-
- sinon.spy(store, "on");
- sinon.stub(store, "getData");
- sinon.stub(store, "focusInput");
-
- let component = new TabListComponent({window, store, View: ViewMock, SyncedTabs});
-
- for (let action of ACTION_METHODS) {
- sinon.stub(component, action);
- }
-
- component.init();
-
- Assert.ok(ViewMock.calledWithNew(), "view is instantiated");
- Assert.ok(store.on.calledOnce, "listener is added to store");
- Assert.equal(store.on.args[0][0], "change");
- Assert.ok(view.render.calledWith({clients: []}),
- "render is called on view instance");
- Assert.ok(store.getData.calledOnce, "store gets initial data");
- Assert.ok(store.focusInput.calledOnce, "input field is focused");
-
- for (let method of ACTION_METHODS) {
- let action = ViewMock.args[0][1][method];
- Assert.ok(action, method + " action is passed to View");
- action("foo", "bar");
- Assert.ok(component[method].calledWith("foo", "bar"),
- method + " action passed to View triggers the component method with args");
- }
-
- store.emit("change", "mock state");
- Assert.ok(view.render.secondCall.calledWith("mock state"),
- "view.render is called on state change");
-
- component.uninit();
- Assert.ok(view.destroy.calledOnce, "view is destroyed on uninit");
-});
-
-add_task(function* testActions() {
- let store = new SyncedTabsListStore();
- let chromeWindowMock = {
- gBrowser: {
- loadTabs() {},
- },
- };
- let getChromeWindowMock = sinon.stub();
- getChromeWindowMock.returns(chromeWindowMock);
- let clipboardHelperMock = {
- copyString() {},
- };
- let windowMock = {
- top: {
- PlacesCommandHook: {
- bookmarkLink() { return Promise.resolve(); }
- },
- PlacesUtils: { bookmarksMenuFolderId: "id" }
- },
- getBrowserURL() {},
- openDialog() {},
- openUILinkIn() {}
- };
- let component = new TabListComponent({
- window: windowMock, store, View: null, SyncedTabs,
- clipboardHelper: clipboardHelperMock,
- getChromeWindow: getChromeWindowMock });
-
- sinon.stub(store, "getData");
- component.onFilter("query");
- Assert.ok(store.getData.calledWith("query"));
-
- sinon.stub(store, "clearFilter");
- component.onClearFilter();
- Assert.ok(store.clearFilter.called);
-
- sinon.stub(store, "focusInput");
- component.onFilterFocus();
- Assert.ok(store.focusInput.called);
-
- sinon.stub(store, "blurInput");
- component.onFilterBlur();
- Assert.ok(store.blurInput.called);
-
- sinon.stub(store, "selectRow");
- component.onSelectRow([-1, -1]);
- Assert.ok(store.selectRow.calledWith(-1, -1));
-
- sinon.stub(store, "moveSelectionDown");
- component.onMoveSelectionDown();
- Assert.ok(store.moveSelectionDown.called);
-
- sinon.stub(store, "moveSelectionUp");
- component.onMoveSelectionUp();
- Assert.ok(store.moveSelectionUp.called);
-
- sinon.stub(store, "toggleBranch");
- component.onToggleBranch("foo-id");
- Assert.ok(store.toggleBranch.calledWith("foo-id"));
-
- sinon.spy(windowMock.top.PlacesCommandHook, "bookmarkLink");
- component.onBookmarkTab("uri", "title");
- Assert.equal(windowMock.top.PlacesCommandHook.bookmarkLink.args[0][1], "uri");
- Assert.equal(windowMock.top.PlacesCommandHook.bookmarkLink.args[0][2], "title");
-
- sinon.spy(windowMock, "openUILinkIn");
- component.onOpenTab("uri", "where", "params");
- Assert.ok(windowMock.openUILinkIn.calledWith("uri", "where", "params"));
-
- sinon.spy(chromeWindowMock.gBrowser, "loadTabs");
- let tabsToOpen = ["uri1", "uri2"];
- component.onOpenTabs(tabsToOpen, "where");
- Assert.ok(getChromeWindowMock.calledWith(windowMock));
- Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, false, false));
- component.onOpenTabs(tabsToOpen, "tabshifted");
- Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, true, false));
-
- sinon.spy(clipboardHelperMock, "copyString");
- component.onCopyTabLocation("uri");
- Assert.ok(clipboardHelperMock.copyString.calledWith("uri"));
-
- sinon.stub(SyncedTabs, "syncTabs");
- component.onSyncRefresh();
- Assert.ok(SyncedTabs.syncTabs.calledWith(true));
- SyncedTabs.syncTabs.restore();
-});
-
diff --git a/browser/components/syncedtabs/test/xpcshell/xpcshell.ini b/browser/components/syncedtabs/test/xpcshell/xpcshell.ini
deleted file mode 100644
index 1cb8dcb7a..000000000
--- a/browser/components/syncedtabs/test/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-firefox-appdir = browser
-
-[test_EventEmitter.js]
-[test_SyncedTabsDeckStore.js]
-[test_SyncedTabsListStore.js]
-[test_SyncedTabsDeckComponent.js]
-[test_TabListComponent.js]
diff --git a/browser/components/tests/browser/.eslintrc.js b/browser/components/tests/browser/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/tests/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/tests/browser/browser.ini b/browser/components/tests/browser/browser.ini
deleted file mode 100644
index 6d00b69fa..000000000
--- a/browser/components/tests/browser/browser.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[DEFAULT]
-
-[browser_bug538331.js]
-[browser_contentpermissionprompt.js]
diff --git a/browser/components/tests/browser/browser_bug538331.js b/browser/components/tests/browser/browser_bug538331.js
deleted file mode 100644
index fce3790a0..000000000
--- a/browser/components/tests/browser/browser_bug538331.js
+++ /dev/null
@@ -1,426 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const PREF_POSTUPDATE = "app.update.postupdate";
-const PREF_MSTONE = "browser.startup.homepage_override.mstone";
-const PREF_OVERRIDE_URL = "startup.homepage_override_url";
-
-const DEFAULT_PREF_URL = "http://pref.example.com/";
-const DEFAULT_UPDATE_URL = "http://example.com/";
-
-const XML_EMPTY = "<?xml version=\"1.0\"?><updates xmlns=" +
- "\"http://www.mozilla.org/2005/app-update\"></updates>";
-
-const XML_PREFIX = "<updates xmlns=\"http://www.mozilla.org/2005/app-update\"" +
- "><update appVersion=\"1.0\" buildID=\"20080811053724\" " +
- "channel=\"nightly\" displayVersion=\"Version 1.0\" " +
- "extensionVersion=\"1.0\" installDate=\"1238441400314\" " +
- "isCompleteUpdate=\"true\" name=\"Update Test 1.0\" " +
- "serviceURL=\"https://example.com/\" showNeverForVersion=" +
- "\"false\" showPrompt=\"false\" type=" +
- "\"minor\" version=\"version 1.0\" detailsURL=" +
- "\"http://example.com/\" previousAppVersion=\"1.0\" " +
- "statusText=\"The Update was successfully installed\" " +
- "foregroundDownload=\"true\"";
-
-const XML_SUFFIX = "><patch type=\"complete\" URL=\"http://example.com/\" " +
- "hashFunction=\"MD5\" hashValue=" +
- "\"6232cd43a1c77e30191c53a329a3f99d\" size=\"775\" " +
- "selected=\"true\" state=\"succeeded\"/></update></updates>";
-
-// nsBrowserContentHandler.js defaultArgs tests
-const BCH_TESTS = [
- {
- description: "no mstone change and no update",
- noPostUpdatePref: true,
- noMstoneChange: true
- }, {
- description: "mstone changed and no update",
- noPostUpdatePref: true,
- prefURL: DEFAULT_PREF_URL
- }, {
- description: "no mstone change and update with 'showURL' for actions",
- actions: "showURL",
- noMstoneChange: true
- }, {
- description: "update without actions",
- prefURL: DEFAULT_PREF_URL
- }, {
- description: "update with 'showURL' for actions",
- actions: "showURL",
- prefURL: DEFAULT_PREF_URL
- }, {
- description: "update with 'showURL' for actions and openURL",
- actions: "showURL",
- openURL: DEFAULT_UPDATE_URL
- }, {
- description: "update with 'showURL showAlert' for actions",
- actions: "showAlert showURL",
- prefURL: DEFAULT_PREF_URL
- }, {
- description: "update with 'showAlert showURL' for actions and openURL",
- actions: "showAlert showURL",
- openURL: DEFAULT_UPDATE_URL
- }, {
- description: "update with 'showURL showNotification' for actions",
- actions: "showURL showNotification",
- prefURL: DEFAULT_PREF_URL
- }, {
- description: "update with 'showNotification showURL' for actions and " +
- "openURL",
- actions: "showNotification showURL",
- openURL: DEFAULT_UPDATE_URL
- }, {
- description: "update with 'showAlert showURL showNotification' for actions",
- actions: "showAlert showURL showNotification",
- prefURL: DEFAULT_PREF_URL
- }, {
- description: "update with 'showNotification showURL showAlert' for " +
- "actions and openURL",
- actions: "showNotification showURL showAlert",
- openURL: DEFAULT_UPDATE_URL
- }, {
- description: "update with 'showAlert' for actions",
- actions: "showAlert"
- }, {
- description: "update with 'showAlert showNotification' for actions",
- actions: "showAlert showNotification"
- }, {
- description: "update with 'showNotification' for actions",
- actions: "showNotification"
- }, {
- description: "update with 'showNotification showAlert' for actions",
- actions: "showNotification showAlert"
- }, {
- description: "update with 'silent' for actions",
- actions: "silent"
- }, {
- description: "update with 'silent showURL showAlert showNotification' " +
- "for actions and openURL",
- actions: "silent showURL showAlert showNotification"
- }
-];
-
-var gOriginalMStone;
-var gOriginalOverrideURL;
-
-this.__defineGetter__("gBG", function() {
- delete this.gBG;
- return this.gBG = Cc["@mozilla.org/browser/browserglue;1"].
- getService(Ci.nsIObserver);
-});
-
-function test()
-{
- waitForExplicitFinish();
-
- // Reset the startup page pref since it may have been set by other tests
- // and we will assume it is default.
- Services.prefs.clearUserPref('browser.startup.page');
-
- if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
- gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE);
- }
-
- if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
- gOriginalOverrideURL = gPrefService.getCharPref(PREF_OVERRIDE_URL);
- }
-
- testDefaultArgs();
-}
-
-var gWindowCatcher = {
- windowsOpen: 0,
- finishCalled: false,
- start: function() {
- Services.ww.registerNotification(this);
- },
-
- finish: function(aFunc) {
- Services.ww.unregisterNotification(this);
- this.finishFunc = aFunc;
- if (this.windowsOpen > 0)
- return;
-
- this.finishFunc();
- },
-
- closeWindow: function (win) {
- info("window catcher closing window: " + win.document.documentURI);
- win.close();
- this.windowsOpen--;
- if (this.finishFunc) {
- this.finish(this.finishFunc);
- }
- },
-
- windowLoad: function (win) {
- executeSoon(this.closeWindow.bind(this, win));
- },
-
- observe: function(subject, topic, data) {
- if (topic != "domwindowopened")
- return;
-
- this.windowsOpen++;
- let win = subject.QueryInterface(Ci.nsIDOMWindow);
- info("window catcher caught window opening: " + win.document.documentURI);
- win.addEventListener("load", function () {
- win.removeEventListener("load", arguments.callee, false);
- gWindowCatcher.windowLoad(win);
- }, false);
- }
-};
-
-function finish_test()
-{
- // Reset browser.startup.homepage_override.mstone to the original value or
- // clear it if it didn't exist.
- if (gOriginalMStone) {
- gPrefService.setCharPref(PREF_MSTONE, gOriginalMStone);
- } else if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
- gPrefService.clearUserPref(PREF_MSTONE);
- }
-
- // Reset startup.homepage_override_url to the original value or clear it if
- // it didn't exist.
- if (gOriginalOverrideURL) {
- gPrefService.setCharPref(PREF_OVERRIDE_URL, gOriginalOverrideURL);
- } else if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
- gPrefService.clearUserPref(PREF_OVERRIDE_URL);
- }
-
- writeUpdatesToXMLFile(XML_EMPTY);
- reloadUpdateManagerData();
-
- finish();
-}
-
-// Test the defaultArgs returned by nsBrowserContentHandler after an update
-function testDefaultArgs()
-{
- // Clear any pre-existing override in defaultArgs that are hanging around.
- // This will also set the browser.startup.homepage_override.mstone preference
- // if it isn't already set.
- Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
-
- let originalMstone = gPrefService.getCharPref(PREF_MSTONE);
-
- gPrefService.setCharPref(PREF_OVERRIDE_URL, DEFAULT_PREF_URL);
-
- writeUpdatesToXMLFile(XML_EMPTY);
- reloadUpdateManagerData();
-
- for (let i = 0; i < BCH_TESTS.length; i++) {
- let test = BCH_TESTS[i];
- ok(true, "Test nsBrowserContentHandler " + (i + 1) + ": " + test.description);
-
- if (test.actions) {
- let actionsXML = " actions=\"" + test.actions + "\"";
- if (test.openURL) {
- actionsXML += " openURL=\"" + test.openURL + "\"";
- }
- writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
- } else {
- writeUpdatesToXMLFile(XML_EMPTY);
- }
-
- reloadUpdateManagerData();
-
- let noOverrideArgs = Cc["@mozilla.org/browser/clh;1"].
- getService(Ci.nsIBrowserHandler).defaultArgs;
-
- let overrideArgs = "";
- if (test.prefURL) {
- overrideArgs = test.prefURL;
- } else if (test.openURL) {
- overrideArgs = test.openURL;
- }
-
- if (overrideArgs == "" && noOverrideArgs) {
- overrideArgs = noOverrideArgs;
- } else if (noOverrideArgs) {
- overrideArgs += "|" + noOverrideArgs;
- }
-
- if (test.noMstoneChange === undefined) {
- gPrefService.setCharPref(PREF_MSTONE, "PreviousMilestone");
- }
-
- if (test.noPostUpdatePref == undefined) {
- gPrefService.setBoolPref(PREF_POSTUPDATE, true);
- }
-
- let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
- getService(Ci.nsIBrowserHandler).defaultArgs;
- is(defaultArgs, overrideArgs, "correct value returned by defaultArgs");
-
- if (test.noMstoneChange === undefined || test.noMstoneChange != true) {
- let newMstone = gPrefService.getCharPref(PREF_MSTONE);
- is(originalMstone, newMstone, "preference " + PREF_MSTONE +
- " should have been updated");
- }
-
- if (gPrefService.prefHasUserValue(PREF_POSTUPDATE)) {
- gPrefService.clearUserPref(PREF_POSTUPDATE);
- }
- }
-
- testShowNotification();
-}
-
-// nsBrowserGlue.js _showUpdateNotification notification tests
-const BG_NOTIFY_TESTS = [
- {
- description: "'silent showNotification' actions should not display a notification",
- actions: "silent showNotification"
- }, {
- description: "'showNotification' for actions should display a notification",
- actions: "showNotification"
- }, {
- description: "no actions and empty updates.xml",
- }, {
- description: "'showAlert' for actions should not display a notification",
- actions: "showAlert"
- }, {
- // This test MUST be the last test in the array to test opening the url
- // provided by the updates.xml.
- description: "'showNotification' for actions with custom notification " +
- "attributes should display a notification",
- actions: "showNotification",
- notificationText: "notification text",
- notificationURL: DEFAULT_UPDATE_URL,
- notificationButtonLabel: "button label",
- notificationButtonAccessKey: "b"
- }
-];
-
-// Test showing a notification after an update
-// _showUpdateNotification in nsBrowserGlue.js
-function testShowNotification()
-{
- let notifyBox = document.getElementById("high-priority-global-notificationbox");
-
- // Catches any windows opened by these tests (e.g. alert windows) and closes
- // them
- gWindowCatcher.start();
-
- for (let i = 0; i < BG_NOTIFY_TESTS.length; i++) {
- let test = BG_NOTIFY_TESTS[i];
- ok(true, "Test showNotification " + (i + 1) + ": " + test.description);
-
- if (test.actions) {
- let actionsXML = " actions=\"" + test.actions + "\"";
- if (test.notificationText) {
- actionsXML += " notificationText=\"" + test.notificationText + "\"";
- }
- if (test.notificationURL) {
- actionsXML += " notificationURL=\"" + test.notificationURL + "\"";
- }
- if (test.notificationButtonLabel) {
- actionsXML += " notificationButtonLabel=\"" + test.notificationButtonLabel + "\"";
- }
- if (test.notificationButtonAccessKey) {
- actionsXML += " notificationButtonAccessKey=\"" + test.notificationButtonAccessKey + "\"";
- }
- writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
- } else {
- writeUpdatesToXMLFile(XML_EMPTY);
- }
-
- reloadUpdateManagerData();
- gPrefService.setBoolPref(PREF_POSTUPDATE, true);
-
- gBG.observe(null, "browser-glue-test", "post-update-notification");
-
- let updateBox = notifyBox.getNotificationWithValue("post-update-notification");
- if (test.actions && test.actions.indexOf("showNotification") != -1 &&
- test.actions.indexOf("silent") == -1) {
- ok(updateBox, "Update notification box should have been displayed");
- if (updateBox) {
- if (test.notificationText) {
- is(updateBox.label, test.notificationText, "Update notification box " +
- "should have the label provided by the update");
- }
- if (test.notificationButtonLabel) {
- var button = updateBox.getElementsByTagName("button").item(0);
- is(button.label, test.notificationButtonLabel, "Update notification " +
- "box button should have the label provided by the update");
- if (test.notificationButtonAccessKey) {
- let accessKey = button.getAttribute("accesskey");
- is(accessKey, test.notificationButtonAccessKey, "Update " +
- "notification box button should have the accesskey " +
- "provided by the update");
- }
- }
- // The last test opens an url and verifies the url from the updates.xml
- // is correct.
- if (i == (BG_NOTIFY_TESTS.length - 1)) {
- // Wait for any windows caught by the windowcatcher to close
- gWindowCatcher.finish(function () {
- BrowserTestUtils.waitForNewTab(gBrowser).then(testNotificationURL);
- button.click();
- });
- } else {
- notifyBox.removeAllNotifications(true);
- }
- } else if (i == (BG_NOTIFY_TESTS.length - 1)) {
- // If updateBox is null the test has already reported errors so bail
- finish_test();
- }
- } else {
- ok(!updateBox, "Update notification box should not have been displayed");
- }
-
- let prefHasUserValue = gPrefService.prefHasUserValue(PREF_POSTUPDATE);
- is(prefHasUserValue, false, "preference " + PREF_POSTUPDATE +
- " shouldn't have a user value");
- }
-}
-
-// Test opening the url provided by the updates.xml in the last test
-function testNotificationURL()
-{
- ok(true, "Test testNotificationURL: clicking the notification button " +
- "opened the url specified by the update");
- let href = gBrowser.currentURI.spec;
- let expectedURL = BG_NOTIFY_TESTS[BG_NOTIFY_TESTS.length - 1].notificationURL;
- is(href, expectedURL, "The url opened from the notification should be the " +
- "url provided by the update");
- gBrowser.removeCurrentTab();
- window.focus();
- finish_test();
-}
-
-/* Reloads the update metadata from disk */
-function reloadUpdateManagerData()
-{
- Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
- QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
-}
-
-
-function writeUpdatesToXMLFile(aText)
-{
- const PERMS_FILE = 0o644;
-
- const MODE_WRONLY = 0x02;
- const MODE_CREATE = 0x08;
- const MODE_TRUNCATE = 0x20;
-
- let file = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIProperties).
- get("UpdRootD", Ci.nsIFile);
- file.append("updates.xml");
- let fos = Cc["@mozilla.org/network/file-output-stream;1"].
- createInstance(Ci.nsIFileOutputStream);
- if (!file.exists()) {
- file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
- }
- fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
- fos.write(aText, aText.length);
- fos.close();
-}
diff --git a/browser/components/tests/browser/browser_contentpermissionprompt.js b/browser/components/tests/browser/browser_contentpermissionprompt.js
deleted file mode 100644
index 054aa22e8..000000000
--- a/browser/components/tests/browser/browser_contentpermissionprompt.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * These tests test nsBrowserGlue's nsIContentPermissionPrompt
- * implementation behaviour with various types of
- * nsIContentPermissionRequests.
- */
-
-"use strict";
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Integration.jsm", this);
-
-XPCOMUtils.defineLazyServiceGetter(this, "ContentPermissionPrompt",
- "@mozilla.org/content-permission/prompt;1",
- "nsIContentPermissionPrompt");
-
-/**
- * This is a partial implementation of nsIContentPermissionType.
- *
- * @param {string} type
- * The string defining what type of permission is being requested.
- * Example: "geo", "desktop-notification".
- * @return nsIContentPermissionType implementation.
- */
-function MockContentPermissionType(type) {
- this.type = type;
-}
-
-MockContentPermissionType.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType]),
- // We expose the wrappedJSObject so that we can be sure
- // in some of our tests that we're passing the right
- // nsIContentPermissionType around.
- wrappedJSObject: this,
-};
-
-/**
- * This is a partial implementation of nsIContentPermissionRequest.
- *
- * @param {Array<nsIContentPermissionType>} typesArray
- * The types to assign to this nsIContentPermissionRequest,
- * in order. You probably want to use MockContentPermissionType.
- * @return nsIContentPermissionRequest implementation.
- */
-function MockContentPermissionRequest(typesArray) {
- this.types = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
- for (let type of typesArray) {
- this.types.appendElement(type, false);
- }
-}
-
-MockContentPermissionRequest.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
- // We expose the wrappedJSObject so that we can be sure
- // in some of our tests that we're passing the right
- // nsIContentPermissionRequest around.
- wrappedJSObject: this,
- // For some of our tests, we want to make sure that the
- // request is cancelled, so we add some instrumentation here
- // to check that cancel() is called.
- cancel() {
- this.cancelled = true;
- },
- cancelled: false,
-};
-
-/**
- * Tests that if the nsIContentPermissionRequest has an empty
- * types array, that NS_ERROR_UNEXPECTED is thrown, and the
- * request is cancelled.
- */
-add_task(function* test_empty_types() {
- let mockRequest = new MockContentPermissionRequest([]);
- Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); },
- /NS_ERROR_UNEXPECTED/,
- "Should have thrown NS_ERROR_UNEXPECTED.");
- Assert.ok(mockRequest.cancelled, "Should have cancelled the request.");
-});
-
-/**
- * Tests that if the nsIContentPermissionRequest has more than
- * one type, that NS_ERROR_UNEXPECTED is thrown, and the request
- * is cancelled.
- */
-add_task(function* test_multiple_types() {
- let mockRequest = new MockContentPermissionRequest([
- new MockContentPermissionType("test1"),
- new MockContentPermissionType("test2"),
- ]);
-
- Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); },
- /NS_ERROR_UNEXPECTED/);
- Assert.ok(mockRequest.cancelled, "Should have cancelled the request.");
-});
-
-/**
- * Tests that if the nsIContentPermissionRequest has a type that
- * does not implement nsIContentPermissionType that NS_NOINTERFACE
- * is thrown, and the request is cancelled.
- */
-add_task(function* test_not_permission_type() {
- let mockRequest = new MockContentPermissionRequest([
- { QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) },
- ]);
-
- Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); },
- /NS_NOINTERFACE/);
- Assert.ok(mockRequest.cancelled, "Should have cancelled the request.");
-});
-
-/**
- * Tests that if the nsIContentPermissionRequest is for a type
- * that is not recognized, that NS_ERROR_FAILURE is thrown and
- * the request is cancelled.
- */
-add_task(function* test_unrecognized_type() {
- let mockRequest = new MockContentPermissionRequest([
- new MockContentPermissionType("test1"),
- ]);
-
- Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); },
- /NS_ERROR_FAILURE/);
- Assert.ok(mockRequest.cancelled, "Should have cancelled the request.");
-});
-
-/**
- * Tests that if we meet the minimal requirements for a
- * nsIContentPermissionRequest, that it will be passed to
- * ContentPermissionIntegration's createPermissionPrompt
- * method.
- */
-add_task(function* test_working_request() {
- let mockType = new MockContentPermissionType("test-permission-type");
- let mockRequest = new MockContentPermissionRequest([mockType]);
-
- // mockPermissionPrompt is what createPermissionPrompt
- // will return. Returning some kind of object should be
- // enough to convince nsBrowserGlue that everything went
- // okay.
- let didPrompt = false;
- let mockPermissionPrompt = {
- prompt() {
- didPrompt = true;
- }
- };
-
- let integration = (base) => ({
- createPermissionPrompt(type, request) {
- Assert.equal(type, "test-permission-type");
- Assert.ok(Object.is(request.wrappedJSObject, mockRequest.wrappedJSObject));
- return mockPermissionPrompt;
- },
- });
-
- // Register an integration so that we can capture the
- // calls into ContentPermissionIntegration.
- try {
- Integration.contentPermission.register(integration);
-
- ContentPermissionPrompt.prompt(mockRequest);
- Assert.ok(!mockRequest.cancelled,
- "Should not have cancelled the request.");
- Assert.ok(didPrompt, "Should have tried to show the prompt");
- } finally {
- Integration.contentPermission.unregister(integration);
- }
-});
diff --git a/browser/components/tests/unit/.eslintrc.js b/browser/components/tests/unit/.eslintrc.js
deleted file mode 100644
index fee088c17..000000000
--- a/browser/components/tests/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/tests/unit/data/engine-de-DE.xml b/browser/components/tests/unit/data/engine-de-DE.xml
deleted file mode 100644
index b9fa0a464..000000000
--- a/browser/components/tests/unit/data/engine-de-DE.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Google</ShortName>
-<Description>override-de-DE</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Url type="text/html" method="GET" template="http://searchtest.local">
- <Param name="search" value="{searchTerms}"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/components/tests/unit/distribution.ini b/browser/components/tests/unit/distribution.ini
deleted file mode 100644
index d7d298808..000000000
--- a/browser/components/tests/unit/distribution.ini
+++ /dev/null
@@ -1,58 +0,0 @@
-# Distribution Configuration File
-# Test of distribution preferences
-
-[Global]
-id=disttest
-version=1.0
-about=Test distribution file
-about.en-US=Tèƨƭ δïƨƭřïβúƭïôñ ƒïℓè
-
-[Preferences]
-distribution.test.string="Test String"
-distribution.test.string.noquotes=Test String
-distribution.test.int=777
-distribution.test.bool.true=true
-distribution.test.bool.false=false
-distribution.test.empty=
-
-distribution.test.pref.locale="%LOCALE%"
-distribution.test.pref.language.reset="Preference Set"
-distribution.test.pref.locale.reset="Preference Set"
-distribution.test.pref.locale.set="Preference Set"
-distribution.test.pref.language.set="Preference Set"
-
-[Preferences-en]
-distribution.test.pref.language.en="en"
-distribution.test.pref.language.reset=
-distribution.test.pref.language.set="Language Set"
-distribution.test.pref.locale.set="Language Set"
-
-[Preferences-en-US]
-distribution.test.pref.locale.en-US="en-US"
-distribution.test.pref.locale.reset=
-distribution.test.pref.locale.set="Locale Set"
-
-
-[Preferences-de]
-distribution.test.pref.language.de="de"
-
-[LocalizablePreferences]
-distribution.test.locale="%LOCALE%"
-distribution.test.language.reset="Preference Set"
-distribution.test.locale.reset="Preference Set"
-distribution.test.locale.set="Preference Set"
-distribution.test.language.set="Preference Set"
-
-[LocalizablePreferences-en]
-distribution.test.language.en="en"
-distribution.test.language.reset=
-distribution.test.language.set="Language Set"
-distribution.test.locale.set="Language Set"
-
-[LocalizablePreferences-en-US]
-distribution.test.locale.en-US="en-US"
-distribution.test.locale.reset=
-distribution.test.locale.set="Locale Set"
-
-[LocalizablePreferences-de]
-distribution.test.language.de="de"
diff --git a/browser/components/tests/unit/head.js b/browser/components/tests/unit/head.js
deleted file mode 100644
index 3d4e23452..000000000
--- a/browser/components/tests/unit/head.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-var gProfD = do_get_profile().QueryInterface(Ci.nsILocalFile);
diff --git a/browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js b/browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js
deleted file mode 100644
index a68503db3..000000000
--- a/browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const UI_VERSION = 41;
-const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
-const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
-
-var gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"]
- .getService(Ci.nsIObserver);
-
-Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
-
-add_task(function* test_check_cleanup_loop_prefs() {
- Services.prefs.setBoolPref("loop.createdRoom", true);
- Services.prefs.setBoolPref("loop1.createdRoom", true);
- Services.prefs.setBoolPref("loo.createdRoom", true);
-
- // Simulate a migration.
- gBrowserGlue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_BROWSERGLUE_TEST);
-
- Assert.throws(() => Services.prefs.getBoolPref("loop.createdRoom"),
- /NS_ERROR_UNEXPECTED/,
- "should have cleared old loop preference 'loop.createdRoom'");
- Assert.ok(Services.prefs.getBoolPref("loop1.createdRoom"),
- "should have left non-loop pref 'loop1.createdRoom' untouched");
- Assert.ok(Services.prefs.getBoolPref("loo.createdRoom"),
- "should have left non-loop pref 'loo.createdRoom' untouched");
-});
-
-do_register_cleanup(() => {
- Services.prefs.clearUserPref("browser.migration.version");
- Services.prefs.clearUserPref("loop.createdRoom");
- Services.prefs.clearUserPref("loop1.createdRoom");
- Services.prefs.clearUserPref("loo.createdRoom");
-});
diff --git a/browser/components/tests/unit/test_distribution.js b/browser/components/tests/unit/test_distribution.js
deleted file mode 100644
index 183ab85d6..000000000
--- a/browser/components/tests/unit/test_distribution.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that preferences are properly set by distribution.ini
- */
-
-Cu.import("resource://gre/modules/LoadContextInfo.jsm");
-
-// Import common head.
-var commonFile = do_get_file("../../../../toolkit/components/places/tests/head_common.js", false);
-/* import-globals-from ../../../../toolkit/components/places/tests/head_common.js */
-if (commonFile) {
- let uri = Services.io.newFileURI(commonFile);
- Services.scriptloader.loadSubScript(uri.spec, this);
-}
-
-const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization";
-const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
-
-/**
- * Copy the engine-distribution.xml engine to a fake distribution
- * created in the profile, and registered with the directory service.
- * Create an empty en-US directory to make sure it isn't used.
- */
-function installDistributionEngine() {
- const XRE_APP_DISTRIBUTION_DIR = "XREAppDist";
-
- let dir = gProfD.clone();
- dir.append("distribution");
- let distDir = dir.clone();
-
- dir.append("searchplugins");
- dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-
- dir.append("locale");
- dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
- let localeDir = dir.clone();
-
- dir.append("en-US");
- dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-
- localeDir.append("de-DE");
- localeDir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-
- do_get_file("data/engine-de-DE.xml").copyTo(localeDir, "engine-de-DE.xml");
-
- Services.dirsvc.registerProvider({
- getFile: function(aProp, aPersistent) {
- aPersistent.value = true;
- if (aProp == XRE_APP_DISTRIBUTION_DIR)
- return distDir.clone();
- return null;
- }
- });
-}
-
-function run_test() {
- // Set special pref to load distribution.ini from the profile folder.
- Services.prefs.setBoolPref("distribution.testing.loadFromProfile", true);
-
- // Copy distribution.ini file to the profile dir.
- let distroDir = gProfD.clone();
- distroDir.leafName = "distribution";
- let iniFile = distroDir.clone();
- iniFile.append("distribution.ini");
- if (iniFile.exists()) {
- iniFile.remove(false);
- print("distribution.ini already exists, did some test forget to cleanup?");
- }
-
- let testDistributionFile = gTestDir.clone();
- testDistributionFile.append("distribution.ini");
- testDistributionFile.copyTo(distroDir, "distribution.ini");
- Assert.ok(testDistributionFile.exists());
-
- installDistributionEngine();
-
- run_next_test();
-}
-
-do_register_cleanup(function () {
- // Remove the distribution dir, even if the test failed, otherwise all
- // next tests will use it.
- let distDir = gProfD.clone();
- distDir.append("distribution");
- distDir.remove(true);
- Assert.ok(!distDir.exists());
-});
-
-add_task(function* () {
- // Force distribution.
- let glue = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver)
- glue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_DISTRIBUTION_CUSTOMIZATION);
-
- var defaultBranch = Services.prefs.getDefaultBranch(null);
-
- Assert.equal(defaultBranch.getCharPref("distribution.id"), "disttest");
- Assert.equal(defaultBranch.getCharPref("distribution.version"), "1.0");
- Assert.equal(defaultBranch.getComplexValue("distribution.about", Ci.nsISupportsString).data, "Tèƨƭ δïƨƭřïβúƭïôñ ƒïℓè");
-
- Assert.equal(defaultBranch.getCharPref("distribution.test.string"), "Test String");
- Assert.equal(defaultBranch.getCharPref("distribution.test.string.noquotes"), "Test String");
- Assert.equal(defaultBranch.getIntPref("distribution.test.int"), 777);
- Assert.equal(defaultBranch.getBoolPref("distribution.test.bool.true"), true);
- Assert.equal(defaultBranch.getBoolPref("distribution.test.bool.false"), false);
-
- Assert.throws(() => defaultBranch.getCharPref("distribution.test.empty"));
- Assert.throws(() => defaultBranch.getIntPref("distribution.test.empty"));
- Assert.throws(() => defaultBranch.getBoolPref("distribution.test.empty"));
-
- Assert.equal(defaultBranch.getCharPref("distribution.test.pref.locale"), "en-US");
- Assert.equal(defaultBranch.getCharPref("distribution.test.pref.language.en"), "en");
- Assert.equal(defaultBranch.getCharPref("distribution.test.pref.locale.en-US"), "en-US");
- Assert.throws(() => defaultBranch.getCharPref("distribution.test.pref.language.de"));
- // This value was never set because of the empty language specific pref
- Assert.throws(() => defaultBranch.getCharPref("distribution.test.pref.language.reset"));
- // This value was never set because of the empty locale specific pref
- Assert.throws(() => defaultBranch.getCharPref("distribution.test.pref.locale.reset"));
- // This value was overridden by a locale specific setting
- Assert.equal(defaultBranch.getCharPref("distribution.test.pref.locale.set"), "Locale Set");
- // This value was overridden by a language specific setting
- Assert.equal(defaultBranch.getCharPref("distribution.test.pref.language.set"), "Language Set");
- // Language should not override locale
- Assert.notEqual(defaultBranch.getCharPref("distribution.test.pref.locale.set"), "Language Set");
-
- Assert.equal(defaultBranch.getComplexValue("distribution.test.locale", Ci.nsIPrefLocalizedString).data, "en-US");
- Assert.equal(defaultBranch.getComplexValue("distribution.test.language.en", Ci.nsIPrefLocalizedString).data, "en");
- Assert.equal(defaultBranch.getComplexValue("distribution.test.locale.en-US", Ci.nsIPrefLocalizedString).data, "en-US");
- Assert.throws(() => defaultBranch.getComplexValue("distribution.test.language.de", Ci.nsIPrefLocalizedString));
- // This value was never set because of the empty language specific pref
- Assert.throws(() => defaultBranch.getComplexValue("distribution.test.language.reset", Ci.nsIPrefLocalizedString));
- // This value was never set because of the empty locale specific pref
- Assert.throws(() => defaultBranch.getComplexValue("distribution.test.locale.reset", Ci.nsIPrefLocalizedString));
- // This value was overridden by a locale specific setting
- Assert.equal(defaultBranch.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Locale Set");
- // This value was overridden by a language specific setting
- Assert.equal(defaultBranch.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Language Set");
- // Language should not override locale
- Assert.notEqual(defaultBranch.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Language Set");
-
- do_test_pending();
-
- Services.prefs.setCharPref("distribution.searchplugins.defaultLocale", "de-DE");
-
- Services.search.init(function() {
- Assert.equal(Services.search.isInitialized, true);
- var engine = Services.search.getEngineByName("Google");
- Assert.equal(engine.description, "override-de-DE");
- do_test_finished();
- });
-});
diff --git a/browser/components/tests/unit/xpcshell.ini b/browser/components/tests/unit/xpcshell.ini
deleted file mode 100644
index c2f461966..000000000
--- a/browser/components/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[DEFAULT]
-head = head.js
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-support-files =
- distribution.ini
- data/engine-de-DE.xml
-
-[test_distribution.js]
-[test_browserGlue_migration_loop_cleanup.js]
diff --git a/browser/components/translation/moz.build b/browser/components/translation/moz.build
index 468f2af20..ac0165230 100644
--- a/browser/components/translation/moz.build
+++ b/browser/components/translation/moz.build
@@ -14,11 +14,3 @@ EXTRA_JS_MODULES.translation = [
]
JAR_MANIFESTS += ['jar.mn']
-
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser.ini'
-]
-
-XPCSHELL_TESTS_MANIFESTS += [
- 'test/unit/xpcshell.ini'
-]
diff --git a/browser/components/translation/test/.eslintrc.js b/browser/components/translation/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/translation/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/translation/test/bing.sjs b/browser/components/translation/test/bing.sjs
deleted file mode 100644
index ce3b96855..000000000
--- a/browser/components/translation/test/bing.sjs
+++ /dev/null
@@ -1,234 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, Constructor: CC} = Components;
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-
-function handleRequest(req, res) {
- try {
- reallyHandleRequest(req, res);
- } catch (ex) {
- res.setStatusLine("1.0", 200, "AlmostOK");
- let msg = "Error handling request: " + ex + "\n" + ex.stack;
- log(msg);
- res.write(msg);
- }
-}
-
-function log(msg) {
- // dump("BING-SERVER-MOCK: " + msg + "\n");
-}
-
-const statusCodes = {
- 400: "Bad Request",
- 401: "Unauthorized",
- 403: "Forbidden",
- 404: "Not Found",
- 405: "Method Not Allowed",
- 500: "Internal Server Error",
- 501: "Not Implemented",
- 503: "Service Unavailable"
-};
-
-function HTTPError(code = 500, message) {
- this.code = code;
- this.name = statusCodes[code] || "HTTPError";
- this.message = message || this.name;
-}
-HTTPError.prototype = new Error();
-HTTPError.prototype.constructor = HTTPError;
-
-function sendError(res, err) {
- if (!(err instanceof HTTPError)) {
- err = new HTTPError(typeof err == "number" ? err : 500,
- err.message || typeof err == "string" ? err : "");
- }
- res.setStatusLine("1.1", err.code, err.name);
- res.write(err.message);
-}
-
-function parseQuery(query) {
- let ret = {};
- for (let param of query.replace(/^[?&]/, "").split("&")) {
- param = param.split("=");
- if (!param[0])
- continue;
- ret[unescape(param[0])] = unescape(param[1]);
- }
- return ret;
-}
-
-function getRequestBody(req) {
- let avail;
- let bytes = [];
- let body = new BinaryInputStream(req.bodyInputStream);
-
- while ((avail = body.available()) > 0)
- Array.prototype.push.apply(bytes, body.readByteArray(avail));
-
- return String.fromCharCode.apply(null, bytes);
-}
-
-function sha1(str) {
- let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Ci.nsIScriptableUnicodeConverter);
- converter.charset = "UTF-8";
- // `result` is an out parameter, `result.value` will contain the array length.
- let result = {};
- // `data` is an array of bytes.
- let data = converter.convertToByteArray(str, result);
- let ch = Cc["@mozilla.org/security/hash;1"]
- .createInstance(Ci.nsICryptoHash);
- ch.init(ch.SHA1);
- ch.update(data, data.length);
- let hash = ch.finish(false);
-
- // Return the two-digit hexadecimal code for a byte.
- function toHexString(charCode) {
- return ("0" + charCode.toString(16)).slice(-2);
- }
-
- // Convert the binary hash data to a hex string.
- return Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
-}
-
-function parseXml(body) {
- let DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"]
- .createInstance(Ci.nsIDOMParser);
- let xml = DOMParser.parseFromString(body, "text/xml");
- if (xml.documentElement.localName == "parsererror")
- throw new Error("Invalid XML");
- return xml;
-}
-
-function getInputStream(path) {
- let file = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("CurWorkD", Ci.nsILocalFile);
- for (let part of path.split("/"))
- file.append(part);
- let fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- fileStream.init(file, 1, 0, false);
- return fileStream;
-}
-
-function checkAuth(req) {
- let err = new Error("Authorization failed");
- err.code = 401;
-
- if (!req.hasHeader("Authorization"))
- throw new HTTPError(401, "No Authorization header provided.");
-
- let auth = req.getHeader("Authorization");
- if (!auth.startsWith("Bearer "))
- throw new HTTPError(401, "Invalid Authorization header content: '" + auth + "'");
-
- // Rejecting inactive subscriptions.
- if (auth.includes("inactive")) {
- const INACTIVE_STATE_RESPONSE = "<html><body><h1>TranslateApiException</h1><p>Method: TranslateArray()</p><p>Message: The Azure Market Place Translator Subscription associated with the request credentials is not in an active state.</p><code></code><p>message id=5641.V2_Rest.TranslateArray.48CC6470</p></body></html>";
- throw new HTTPError(401, INACTIVE_STATE_RESPONSE);
- }
-
-}
-
-function reallyHandleRequest(req, res) {
- log("method: " + req.method);
- if (req.method != "POST") {
- sendError(res, "Bing only deals with POST requests, not '" + req.method + "'.");
- return;
- }
-
- let body = getRequestBody(req);
- log("body: " + body);
-
- // First, we'll see if we're dealing with an XML body:
- let contentType = req.hasHeader("Content-Type") ? req.getHeader("Content-Type") : null;
- log("contentType: " + contentType);
-
- if (contentType.startsWith("text/xml")) {
- try {
- // For all these requests the client needs to supply the correct
- // authentication headers.
- checkAuth(req);
-
- let xml = parseXml(body);
- let method = xml.documentElement.localName;
- log("invoking method: " + method);
- // If the requested method is supported, delegate it to its handler.
- if (methodHandlers[method])
- methodHandlers[method](res, xml);
- else
- throw new HTTPError(501);
- } catch (ex) {
- sendError(res, ex, ex.code);
- }
- } else {
- // Not XML, so it must be a query-string.
- let params = parseQuery(body);
-
- // Delegate an authentication request to the correct handler.
- if ("grant_type" in params && params.grant_type == "client_credentials")
- methodHandlers.authenticate(res, params);
- else
- sendError(res, 501);
- }
-}
-
-const methodHandlers = {
- authenticate: function(res, params) {
- // Validate a few required parameters.
- if (params.scope != "http://api.microsofttranslator.com") {
- sendError(res, "Invalid scope.");
- return;
- }
- if (!params.client_id) {
- sendError(res, "Missing client_id param.");
- return;
- }
- if (!params.client_secret) {
- sendError(res, "Missing client_secret param.");
- return;
- }
-
- // Defines the tokens for certain client ids.
- const TOKEN_MAP = {
- 'testInactive' : 'inactive',
- 'testClient' : 'test'
- };
- let token = 'test'; // Default token.
- if((params.client_id in TOKEN_MAP)){
- token = TOKEN_MAP[params.client_id];
- }
- let content = JSON.stringify({
- access_token: token,
- expires_in: 600
- });
-
- res.setStatusLine("1.1", 200, "OK");
- res.setHeader("Content-Length", String(content.length));
- res.setHeader("Content-Type", "application/json");
- res.write(content);
- },
-
- TranslateArrayRequest: function(res, xml, body) {
- let from = xml.querySelector("From").firstChild.nodeValue;
- let to = xml.querySelector("To").firstChild.nodeValue
- log("translating from '" + from + "' to '" + to + "'");
-
- res.setStatusLine("1.1", 200, "OK");
- res.setHeader("Content-Type", "text/xml");
-
- let hash = sha1(body).substr(0, 10);
- log("SHA1 hash of content: " + hash);
- let inputStream = getInputStream(
- "browser/browser/components/translation/test/fixtures/result-" + hash + ".txt");
- res.bodyOutputStream.writeFrom(inputStream, inputStream.available());
- inputStream.close();
- }
-};
diff --git a/browser/components/translation/test/browser.ini b/browser/components/translation/test/browser.ini
deleted file mode 100644
index 59e481855..000000000
--- a/browser/components/translation/test/browser.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[DEFAULT]
-support-files =
- bing.sjs
- yandex.sjs
- fixtures/bug1022725-fr.html
- fixtures/result-da39a3ee5e.txt
- fixtures/result-yandex-d448894848.json
-
-[browser_translation_bing.js]
-[browser_translation_yandex.js]
-[browser_translation_telemetry.js]
-[browser_translation_infobar.js]
-[browser_translation_exceptions.js]
diff --git a/browser/components/translation/test/browser_translation_bing.js b/browser/components/translation/test/browser_translation_bing.js
deleted file mode 100644
index 399a67022..000000000
--- a/browser/components/translation/test/browser_translation_bing.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test the Bing Translator client against a mock Bing service, bing.sjs.
-
-"use strict";
-
-const kClientIdPref = "browser.translation.bing.clientIdOverride";
-const kClientSecretPref = "browser.translation.bing.apiKeyOverride";
-
-const {BingTranslator} = Cu.import("resource:///modules/translation/BingTranslator.jsm", {});
-const {TranslationDocument} = Cu.import("resource:///modules/translation/TranslationDocument.jsm", {});
-const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
-
-add_task(function* setup() {
- Services.prefs.setCharPref(kClientIdPref, "testClient");
- Services.prefs.setCharPref(kClientSecretPref, "testSecret");
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(kClientIdPref);
- Services.prefs.clearUserPref(kClientSecretPref);
- });
-});
-
-/**
- * Checks if the translation is happening.
- */
-add_task(function* test_bing_translation() {
-
- // Ensure the correct client id is used for authentication.
- Services.prefs.setCharPref(kClientIdPref, "testClient");
-
- // Loading the fixture page.
- let url = constructFixtureURL("bug1022725-fr.html");
- let tab = yield promiseTestPageLoad(url);
-
- // Translating the contents of the loaded tab.
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
-
- yield ContentTask.spawn(browser, null, function*() {
- Cu.import("resource:///modules/translation/BingTranslator.jsm");
- Cu.import("resource:///modules/translation/TranslationDocument.jsm");
-
- let client = new BingTranslator(
- new TranslationDocument(content.document), "fr", "en");
- let result = yield client.translate();
-
- // XXXmikedeboer; here you would continue the test/ content inspection.
- Assert.ok(result, "There should be a result");
- });
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensures that the BingTranslator handles out-of-valid-key response
- * correctly. Sometimes Bing Translate replies with
- * "request credentials is not in an active state" error. BingTranslator
- * should catch this error and classify it as Service Unavailable.
- *
- */
-add_task(function* test_handling_out_of_valid_key_error() {
-
- // Simulating request from inactive subscription.
- Services.prefs.setCharPref(kClientIdPref, "testInactive");
-
- // Loading the fixture page.
- let url = constructFixtureURL("bug1022725-fr.html");
- let tab = yield promiseTestPageLoad(url);
-
- // Translating the contents of the loaded tab.
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
-
- yield ContentTask.spawn(browser, null, function*() {
- Cu.import("resource:///modules/translation/BingTranslator.jsm");
- Cu.import("resource:///modules/translation/TranslationDocument.jsm");
-
- let client = new BingTranslator(
- new TranslationDocument(content.document), "fr", "en");
- client._resetToken();
- try {
- yield client.translate();
- } catch (ex) {
- // It is alright that the translation fails.
- }
- client._resetToken();
-
- // Checking if the client detected service and unavailable.
- Assert.ok(client._serviceUnavailable, "Service should be detected unavailable.");
- });
-
- // Cleaning up.
- Services.prefs.setCharPref(kClientIdPref, "testClient");
- gBrowser.removeTab(tab);
-});
-
-/**
- * A helper function for constructing a URL to a page stored in the
- * local fixture folder.
- *
- * @param filename Name of a fixture file.
- */
-function constructFixtureURL(filename) {
- // Deduce the Mochitest server address in use from a pref that was pre-processed.
- let server = Services.prefs.getCharPref("browser.translation.bing.authURL")
- .replace("http://", "");
- server = server.substr(0, server.indexOf("/"));
- let url = "http://" + server +
- "/browser/browser/components/translation/test/fixtures/" + filename;
- return url;
-}
-
-/**
- * A helper function to open a new tab and wait for its content to load.
- *
- * @param String url A URL to be loaded in the new tab.
- */
-function promiseTestPageLoad(url) {
- let deferred = Promise.defer();
- let tab = gBrowser.selectedTab = gBrowser.addTab(url);
- let browser = gBrowser.selectedBrowser;
- browser.addEventListener("load", function listener() {
- if (browser.currentURI.spec == "about:blank")
- return;
- info("Page loaded: " + browser.currentURI.spec);
- browser.removeEventListener("load", listener, true);
- deferred.resolve(tab);
- }, true);
- return deferred.promise;
-}
diff --git a/browser/components/translation/test/browser_translation_exceptions.js b/browser/components/translation/test/browser_translation_exceptions.js
deleted file mode 100644
index bf6875768..000000000
--- a/browser/components/translation/test/browser_translation_exceptions.js
+++ /dev/null
@@ -1,327 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// tests the translation infobar, using a fake 'Translation' implementation.
-
-var tmp = {};
-Cu.import("resource:///modules/translation/Translation.jsm", tmp);
-Cu.import("resource://gre/modules/Promise.jsm", tmp);
-var {Translation, Promise} = tmp;
-
-const kLanguagesPref = "browser.translation.neverForLanguages";
-const kShowUIPref = "browser.translation.ui.show";
-
-function test() {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref(kShowUIPref, true);
- let tab = gBrowser.addTab();
- gBrowser.selectedTab = tab;
- registerCleanupFunction(function () {
- gBrowser.removeTab(tab);
- Services.prefs.clearUserPref(kShowUIPref);
- });
- tab.linkedBrowser.addEventListener("load", function onload() {
- tab.linkedBrowser.removeEventListener("load", onload, true);
- Task.spawn(function* () {
- for (let test of gTests) {
- info(test.desc);
- yield test.run();
- }
- }).then(finish, ex => {
- ok(false, "Unexpected Exception: " + ex);
- finish();
- });
- }, true);
-
- content.location = "http://example.com/";
-}
-
-function getLanguageExceptions() {
- let langs = Services.prefs.getCharPref(kLanguagesPref);
- return langs ? langs.split(",") : [];
-}
-
-function getDomainExceptions() {
- let results = [];
- let enumerator = Services.perms.enumerator;
- while (enumerator.hasMoreElements()) {
- let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
-
- if (perm.type == "translate" &&
- perm.capability == Services.perms.DENY_ACTION)
- results.push(perm.principal);
- }
-
- return results;
-}
-
-function getInfoBar() {
- let deferred = Promise.defer();
- let infobar =
- gBrowser.getNotificationBox().getNotificationWithValue("translation");
-
- if (!infobar) {
- deferred.resolve();
- } else {
- // Wait for all animations to finish
- Promise.all(infobar.getAnimations().map(animation => animation.finished))
- .then(() => deferred.resolve(infobar));
- }
-
- return deferred.promise;
-}
-
-function openPopup(aPopup) {
- let deferred = Promise.defer();
-
- aPopup.addEventListener("popupshown", function popupShown() {
- aPopup.removeEventListener("popupshown", popupShown);
- deferred.resolve();
- });
-
- aPopup.focus();
- // One down event to open the popup.
- EventUtils.synthesizeKey("VK_DOWN",
- { altKey: !navigator.platform.includes("Mac") });
-
- return deferred.promise;
-}
-
-function waitForWindowLoad(aWin) {
- let deferred = Promise.defer();
-
- aWin.addEventListener("load", function onload() {
- aWin.removeEventListener("load", onload, true);
- deferred.resolve();
- }, true);
-
- return deferred.promise;
-}
-
-
-var gTests = [
-
-{
- desc: "clean exception lists at startup",
- run: function checkNeverForLanguage() {
- is(getLanguageExceptions().length, 0,
- "we start with an empty list of languages to never translate");
- is(getDomainExceptions().length, 0,
- "we start with an empty list of sites to never translate");
- }
-},
-
-{
- desc: "never for language",
- run: function* checkNeverForLanguage() {
- // Show the infobar for example.com and fr.
- Translation.documentStateReceived(gBrowser.selectedBrowser,
- {state: Translation.STATE_OFFER,
- originalShown: true,
- detectedLanguage: "fr"});
- let notif = yield getInfoBar();
- ok(notif, "the infobar is visible");
- let ui = gBrowser.selectedBrowser.translationUI;
- let uri = gBrowser.selectedBrowser.currentURI;
- ok(ui.shouldShowInfoBar(uri, "fr"),
- "check shouldShowInfoBar initially returns true");
-
- // Open the "options" drop down.
- yield openPopup(notif._getAnonElt("options"));
- ok(notif._getAnonElt("options").getAttribute("open"),
- "the options menu is open");
-
- // Check that the item is not disabled.
- ok(!notif._getAnonElt("neverForLanguage").disabled,
- "The 'Never translate <language>' item isn't disabled");
-
- // Click the 'Never for French' item.
- notif._getAnonElt("neverForLanguage").click();
- notif = yield getInfoBar();
- ok(!notif, "infobar hidden");
-
- // Check this has been saved to the exceptions list.
- let langs = getLanguageExceptions();
- is(langs.length, 1, "one language in the exception list");
- is(langs[0], "fr", "correct language in the exception list");
- ok(!ui.shouldShowInfoBar(uri, "fr"),
- "the infobar wouldn't be shown anymore");
-
- // Reopen the infobar.
- PopupNotifications.getNotification("translate").anchorElement.click();
- notif = yield getInfoBar();
- // Open the "options" drop down.
- yield openPopup(notif._getAnonElt("options"));
- ok(notif._getAnonElt("neverForLanguage").disabled,
- "The 'Never translate French' item is disabled");
-
- // Cleanup.
- Services.prefs.setCharPref(kLanguagesPref, "");
- notif.close();
- }
-},
-
-{
- desc: "never for site",
- run: function* checkNeverForSite() {
- // Show the infobar for example.com and fr.
- Translation.documentStateReceived(gBrowser.selectedBrowser,
- {state: Translation.STATE_OFFER,
- originalShown: true,
- detectedLanguage: "fr"});
- let notif = yield getInfoBar();
- ok(notif, "the infobar is visible");
- let ui = gBrowser.selectedBrowser.translationUI;
- let uri = gBrowser.selectedBrowser.currentURI;
- ok(ui.shouldShowInfoBar(uri, "fr"),
- "check shouldShowInfoBar initially returns true");
-
- // Open the "options" drop down.
- yield openPopup(notif._getAnonElt("options"));
- ok(notif._getAnonElt("options").getAttribute("open"),
- "the options menu is open");
-
- // Check that the item is not disabled.
- ok(!notif._getAnonElt("neverForSite").disabled,
- "The 'Never translate site' item isn't disabled");
-
- // Click the 'Never for French' item.
- notif._getAnonElt("neverForSite").click();
- notif = yield getInfoBar();
- ok(!notif, "infobar hidden");
-
- // Check this has been saved to the exceptions list.
- let sites = getDomainExceptions();
- is(sites.length, 1, "one site in the exception list");
- is(sites[0].origin, "http://example.com", "correct site in the exception list");
- ok(!ui.shouldShowInfoBar(uri, "fr"),
- "the infobar wouldn't be shown anymore");
-
- // Reopen the infobar.
- PopupNotifications.getNotification("translate").anchorElement.click();
- notif = yield getInfoBar();
- // Open the "options" drop down.
- yield openPopup(notif._getAnonElt("options"));
- ok(notif._getAnonElt("neverForSite").disabled,
- "The 'Never translate French' item is disabled");
-
- // Cleanup.
- Services.perms.remove(makeURI("http://example.com"), "translate");
- notif.close();
- }
-},
-
-{
- desc: "language exception list",
- run: function* checkLanguageExceptions() {
- // Put 2 languages in the pref before opening the window to check
- // the list is displayed on load.
- Services.prefs.setCharPref(kLanguagesPref, "fr,de");
-
- // Open the translation exceptions dialog.
- let win = openDialog("chrome://browser/content/preferences/translation.xul",
- "Browser:TranslationExceptions",
- "", null);
- yield waitForWindowLoad(win);
-
- // Check that the list of language exceptions is loaded.
- let getById = win.document.getElementById.bind(win.document);
- let tree = getById("languagesTree");
- let remove = getById("removeLanguage");
- let removeAll = getById("removeAllLanguages");
- is(tree.view.rowCount, 2, "The language exceptions list has 2 items");
- ok(remove.disabled, "The 'Remove Language' button is disabled");
- ok(!removeAll.disabled, "The 'Remove All Languages' button is enabled");
-
- // Select the first item.
- tree.view.selection.select(0);
- ok(!remove.disabled, "The 'Remove Language' button is enabled");
-
- // Click the 'Remove' button.
- remove.click();
- is(tree.view.rowCount, 1, "The language exceptions now contains 1 item");
- is(getLanguageExceptions().length, 1, "One exception in the pref");
-
- // Clear the pref, and check the last item is removed from the display.
- Services.prefs.setCharPref(kLanguagesPref, "");
- is(tree.view.rowCount, 0, "The language exceptions list is empty");
- ok(remove.disabled, "The 'Remove Language' button is disabled");
- ok(removeAll.disabled, "The 'Remove All Languages' button is disabled");
-
- // Add an item and check it appears.
- Services.prefs.setCharPref(kLanguagesPref, "fr");
- is(tree.view.rowCount, 1, "The language exceptions list has 1 item");
- ok(remove.disabled, "The 'Remove Language' button is disabled");
- ok(!removeAll.disabled, "The 'Remove All Languages' button is enabled");
-
- // Click the 'Remove All' button.
- removeAll.click();
- is(tree.view.rowCount, 0, "The language exceptions list is empty");
- ok(remove.disabled, "The 'Remove Language' button is disabled");
- ok(removeAll.disabled, "The 'Remove All Languages' button is disabled");
- is(Services.prefs.getCharPref(kLanguagesPref), "", "The pref is empty");
-
- win.close();
- }
-},
-
-{
- desc: "domains exception list",
- run: function* checkDomainExceptions() {
- // Put 2 exceptions before opening the window to check the list is
- // displayed on load.
- let perms = Services.perms;
- perms.add(makeURI("http://example.org"), "translate", perms.DENY_ACTION);
- perms.add(makeURI("http://example.com"), "translate", perms.DENY_ACTION);
-
- // Open the translation exceptions dialog.
- let win = openDialog("chrome://browser/content/preferences/translation.xul",
- "Browser:TranslationExceptions",
- "", null);
- yield waitForWindowLoad(win);
-
- // Check that the list of language exceptions is loaded.
- let getById = win.document.getElementById.bind(win.document);
- let tree = getById("sitesTree");
- let remove = getById("removeSite");
- let removeAll = getById("removeAllSites");
- is(tree.view.rowCount, 2, "The sites exceptions list has 2 items");
- ok(remove.disabled, "The 'Remove Site' button is disabled");
- ok(!removeAll.disabled, "The 'Remove All Sites' button is enabled");
-
- // Select the first item.
- tree.view.selection.select(0);
- ok(!remove.disabled, "The 'Remove Site' button is enabled");
-
- // Click the 'Remove' button.
- remove.click();
- is(tree.view.rowCount, 1, "The site exceptions now contains 1 item");
- is(getDomainExceptions().length, 1, "One exception in the permissions");
-
- // Clear the permissions, and check the last item is removed from the display.
- perms.remove(makeURI("http://example.org"), "translate");
- perms.remove(makeURI("http://example.com"), "translate");
- is(tree.view.rowCount, 0, "The site exceptions list is empty");
- ok(remove.disabled, "The 'Remove Site' button is disabled");
- ok(removeAll.disabled, "The 'Remove All Site' button is disabled");
-
- // Add an item and check it appears.
- perms.add(makeURI("http://example.com"), "translate", perms.DENY_ACTION);
- is(tree.view.rowCount, 1, "The site exceptions list has 1 item");
- ok(remove.disabled, "The 'Remove Site' button is disabled");
- ok(!removeAll.disabled, "The 'Remove All Sites' button is enabled");
-
- // Click the 'Remove All' button.
- removeAll.click();
- is(tree.view.rowCount, 0, "The site exceptions list is empty");
- ok(remove.disabled, "The 'Remove Site' button is disabled");
- ok(removeAll.disabled, "The 'Remove All Sites' button is disabled");
- is(getDomainExceptions().length, 0, "No exceptions in the permissions");
-
- win.close();
- }
-}
-
-];
diff --git a/browser/components/translation/test/browser_translation_infobar.js b/browser/components/translation/test/browser_translation_infobar.js
deleted file mode 100644
index c16b3939c..000000000
--- a/browser/components/translation/test/browser_translation_infobar.js
+++ /dev/null
@@ -1,216 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// tests the translation infobar, using a fake 'Translation' implementation.
-
-var tmp = {};
-Cu.import("resource:///modules/translation/Translation.jsm", tmp);
-var {Translation} = tmp;
-
-const kShowUIPref = "browser.translation.ui.show";
-
-function waitForCondition(condition, nextTest, errorMsg) {
- var tries = 0;
- var interval = setInterval(function() {
- if (tries >= 30) {
- ok(false, errorMsg);
- moveOn();
- }
- var conditionPassed;
- try {
- conditionPassed = condition();
- } catch (e) {
- ok(false, e + "\n" + e.stack);
- conditionPassed = false;
- }
- if (conditionPassed) {
- moveOn();
- }
- tries++;
- }, 100);
- var moveOn = function() { clearInterval(interval); nextTest(); };
-}
-
-var TranslationStub = {
- translate: function(aFrom, aTo) {
- this.state = Translation.STATE_TRANSLATING;
- this.translatedFrom = aFrom;
- this.translatedTo = aTo;
- },
-
- _reset: function() {
- this.translatedFrom = "";
- this.translatedTo = "";
- },
-
- failTranslation: function() {
- this.state = Translation.STATE_ERROR;
- this._reset();
- },
-
- finishTranslation: function() {
- this.showTranslatedContent();
- this.state = Translation.STATE_TRANSLATED;
- this._reset();
- }
-};
-
-function showTranslationUI(aDetectedLanguage) {
- let browser = gBrowser.selectedBrowser;
- Translation.documentStateReceived(browser, {state: Translation.STATE_OFFER,
- originalShown: true,
- detectedLanguage: aDetectedLanguage});
- let ui = browser.translationUI;
- for (let name of ["translate", "_reset", "failTranslation", "finishTranslation"])
- ui[name] = TranslationStub[name];
- return ui.notificationBox.getNotificationWithValue("translation");
-}
-
-function hasTranslationInfoBar() {
- return !!gBrowser.getNotificationBox().getNotificationWithValue("translation");
-}
-
-function test() {
- waitForExplicitFinish();
-
- Services.prefs.setBoolPref(kShowUIPref, true);
- let tab = gBrowser.addTab();
- gBrowser.selectedTab = tab;
- tab.linkedBrowser.addEventListener("load", function onload() {
- tab.linkedBrowser.removeEventListener("load", onload, true);
- TranslationStub.browser = gBrowser.selectedBrowser;
- registerCleanupFunction(function () {
- gBrowser.removeTab(tab);
- Services.prefs.clearUserPref(kShowUIPref);
- });
- run_tests(() => {
- finish();
- });
- }, true);
-
- content.location = "data:text/plain,test page";
-}
-
-function checkURLBarIcon(aExpectTranslated = false) {
- is(!PopupNotifications.getNotification("translate"), aExpectTranslated,
- "translate icon " + (aExpectTranslated ? "not " : "") + "shown");
- is(!!PopupNotifications.getNotification("translated"), aExpectTranslated,
- "translated icon " + (aExpectTranslated ? "" : "not ") + "shown");
-}
-
-function run_tests(aFinishCallback) {
- info("Show an info bar saying the current page is in French");
- let notif = showTranslationUI("fr");
- is(notif.state, Translation.STATE_OFFER, "the infobar is offering translation");
- is(notif._getAnonElt("detectedLanguage").value, "fr", "The detected language is displayed");
- checkURLBarIcon();
-
- info("Click the 'Translate' button");
- notif._getAnonElt("translate").click();
- is(notif.state, Translation.STATE_TRANSLATING, "the infobar is in the translating state");
- ok(!!notif.translation.translatedFrom, "Translation.translate has been called");
- is(notif.translation.translatedFrom, "fr", "from language correct");
- is(notif.translation.translatedTo, Translation.defaultTargetLanguage, "from language correct");
- checkURLBarIcon();
-
- info("Make the translation fail and check we are in the error state.");
- notif.translation.failTranslation();
- is(notif.state, Translation.STATE_ERROR, "infobar in the error state");
- checkURLBarIcon();
-
- info("Click the try again button");
- notif._getAnonElt("tryAgain").click();
- is(notif.state, Translation.STATE_TRANSLATING, "infobar in the translating state");
- ok(!!notif.translation.translatedFrom, "Translation.translate has been called");
- is(notif.translation.translatedFrom, "fr", "from language correct");
- is(notif.translation.translatedTo, Translation.defaultTargetLanguage, "from language correct");
- checkURLBarIcon();
-
- info("Make the translation succeed and check we are in the 'translated' state.");
- notif.translation.finishTranslation();
- is(notif.state, Translation.STATE_TRANSLATED, "infobar in the translated state");
- checkURLBarIcon(true);
-
- info("Test 'Show original' / 'Show Translation' buttons.");
- // First check 'Show Original' is visible and 'Show Translation' is hidden.
- ok(!notif._getAnonElt("showOriginal").hidden, "'Show Original' button visible");
- ok(notif._getAnonElt("showTranslation").hidden, "'Show Translation' button hidden");
- // Click the button.
- notif._getAnonElt("showOriginal").click();
- // Check that the url bar icon shows the original content is displayed.
- checkURLBarIcon();
- // And the 'Show Translation' button is now visible.
- ok(notif._getAnonElt("showOriginal").hidden, "'Show Original' button hidden");
- ok(!notif._getAnonElt("showTranslation").hidden, "'Show Translation' button visible");
- // Click the 'Show Translation' button
- notif._getAnonElt("showTranslation").click();
- // Check that the url bar icon shows the page is translated.
- checkURLBarIcon(true);
- // Check that the 'Show Original' button is visible again.
- ok(!notif._getAnonElt("showOriginal").hidden, "'Show Original' button visible");
- ok(notif._getAnonElt("showTranslation").hidden, "'Show Translation' button hidden");
-
- info("Check that changing the source language causes a re-translation");
- let from = notif._getAnonElt("fromLanguage");
- from.value = "es";
- from.doCommand();
- is(notif.state, Translation.STATE_TRANSLATING, "infobar in the translating state");
- ok(!!notif.translation.translatedFrom, "Translation.translate has been called");
- is(notif.translation.translatedFrom, "es", "from language correct");
- is(notif.translation.translatedTo, Translation.defaultTargetLanguage, "to language correct");
- // We want to show the 'translated' icon while re-translating,
- // because we are still displaying the previous translation.
- checkURLBarIcon(true);
- notif.translation.finishTranslation();
- checkURLBarIcon(true);
-
- info("Check that changing the target language causes a re-translation");
- let to = notif._getAnonElt("toLanguage");
- to.value = "pl";
- to.doCommand();
- is(notif.state, Translation.STATE_TRANSLATING, "infobar in the translating state");
- ok(!!notif.translation.translatedFrom, "Translation.translate has been called");
- is(notif.translation.translatedFrom, "es", "from language correct");
- is(notif.translation.translatedTo, "pl", "to language correct");
- checkURLBarIcon(true);
- notif.translation.finishTranslation();
- checkURLBarIcon(true);
-
- // Cleanup.
- notif.close();
-
- info("Reopen the info bar to check that it's possible to override the detected language.");
- notif = showTranslationUI("fr");
- is(notif.state, Translation.STATE_OFFER, "the infobar is offering translation");
- is(notif._getAnonElt("detectedLanguage").value, "fr", "The detected language is displayed");
- // Change the language and click 'Translate'
- notif._getAnonElt("detectedLanguage").value = "ja";
- notif._getAnonElt("translate").click();
- is(notif.state, Translation.STATE_TRANSLATING, "the infobar is in the translating state");
- ok(!!notif.translation.translatedFrom, "Translation.translate has been called");
- is(notif.translation.translatedFrom, "ja", "from language correct");
- notif.close();
-
- info("Reopen to check the 'Not Now' button closes the notification.");
- notif = showTranslationUI("fr");
- is(hasTranslationInfoBar(), true, "there's a 'translate' notification");
- notif._getAnonElt("notNow").click();
- is(hasTranslationInfoBar(), false, "no 'translate' notification after clicking 'not now'");
-
- info("Reopen to check the url bar icon closes the notification.");
- notif = showTranslationUI("fr");
- is(hasTranslationInfoBar(), true, "there's a 'translate' notification");
- PopupNotifications.getNotification("translate").anchorElement.click();
- is(hasTranslationInfoBar(), false, "no 'translate' notification after clicking the url bar icon");
-
- info("Check that clicking the url bar icon reopens the info bar");
- checkURLBarIcon();
- // Clicking the anchor element causes a 'showing' event to be sent
- // asynchronously to our callback that will then show the infobar.
- PopupNotifications.getNotification("translate").anchorElement.click();
- waitForCondition(hasTranslationInfoBar, () => {
- ok(hasTranslationInfoBar(), "there's a 'translate' notification");
- aFinishCallback();
- }, "timeout waiting for the info bar to reappear");
-}
diff --git a/browser/components/translation/test/browser_translation_telemetry.js b/browser/components/translation/test/browser_translation_telemetry.js
deleted file mode 100644
index e60bc17ef..000000000
--- a/browser/components/translation/test/browser_translation_telemetry.js
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var tmp = {};
-Cu.import("resource:///modules/translation/Translation.jsm", tmp);
-var {Translation, TranslationTelemetry} = tmp;
-const Telemetry = Services.telemetry;
-
-var MetricsChecker = {
- HISTOGRAMS: {
- OPPORTUNITIES : Services.telemetry.getHistogramById("TRANSLATION_OPPORTUNITIES"),
- OPPORTUNITIES_BY_LANG : Services.telemetry.getKeyedHistogramById("TRANSLATION_OPPORTUNITIES_BY_LANGUAGE"),
- PAGES : Services.telemetry.getHistogramById("TRANSLATED_PAGES"),
- PAGES_BY_LANG : Services.telemetry.getKeyedHistogramById("TRANSLATED_PAGES_BY_LANGUAGE"),
- CHARACTERS : Services.telemetry.getHistogramById("TRANSLATED_CHARACTERS"),
- DENIED : Services.telemetry.getHistogramById("DENIED_TRANSLATION_OFFERS"),
- AUTO_REJECTED : Services.telemetry.getHistogramById("AUTO_REJECTED_TRANSLATION_OFFERS"),
- SHOW_ORIGINAL : Services.telemetry.getHistogramById("REQUESTS_OF_ORIGINAL_CONTENT"),
- TARGET_CHANGES : Services.telemetry.getHistogramById("CHANGES_OF_TARGET_LANGUAGE"),
- DETECTION_CHANGES : Services.telemetry.getHistogramById("CHANGES_OF_DETECTED_LANGUAGE"),
- SHOW_UI : Services.telemetry.getHistogramById("SHOULD_TRANSLATION_UI_APPEAR"),
- DETECT_LANG : Services.telemetry.getHistogramById("SHOULD_AUTO_DETECT_LANGUAGE"),
- },
-
- reset: function() {
- for (let i of Object.keys(this.HISTOGRAMS)) {
- this.HISTOGRAMS[i].clear();
- }
- this.updateMetrics();
- },
-
- updateMetrics: function () {
- this._metrics = {
- opportunitiesCount: this.HISTOGRAMS.OPPORTUNITIES.snapshot().sum || 0,
- pageCount: this.HISTOGRAMS.PAGES.snapshot().sum || 0,
- charCount: this.HISTOGRAMS.CHARACTERS.snapshot().sum || 0,
- deniedOffers: this.HISTOGRAMS.DENIED.snapshot().sum || 0,
- autoRejectedOffers: this.HISTOGRAMS.AUTO_REJECTED.snapshot().sum || 0,
- showOriginal: this.HISTOGRAMS.SHOW_ORIGINAL.snapshot().sum || 0,
- detectedLanguageChangedBefore: this.HISTOGRAMS.DETECTION_CHANGES.snapshot().counts[1] || 0,
- detectedLanguageChangeAfter: this.HISTOGRAMS.DETECTION_CHANGES.snapshot().counts[0] || 0,
- targetLanguageChanged: this.HISTOGRAMS.TARGET_CHANGES.snapshot().sum || 0,
- showUI: this.HISTOGRAMS.SHOW_UI.snapshot().sum || 0,
- detectLang: this.HISTOGRAMS.DETECT_LANG.snapshot().sum || 0,
- // Metrics for Keyed histograms are estimated below.
- opportunitiesCountByLang: {},
- pageCountByLang: {}
- };
-
- let opportunities = this.HISTOGRAMS.OPPORTUNITIES_BY_LANG.snapshot();
- let pages = this.HISTOGRAMS.PAGES_BY_LANG.snapshot();
- for (let source of Translation.supportedSourceLanguages) {
- this._metrics.opportunitiesCountByLang[source] = opportunities[source] ?
- opportunities[source].sum : 0;
- for (let target of Translation.supportedTargetLanguages) {
- if (source === target) continue;
- let key = source + " -> " + target;
- this._metrics.pageCountByLang[key] = pages[key] ? pages[key].sum : 0;
- }
- }
- },
-
- /**
- * A recurrent loop for making assertions about collected metrics.
- */
- _assertionLoop: function (prevMetrics, metrics, additions) {
- for (let metric of Object.keys(additions)) {
- let addition = additions[metric];
- // Allows nesting metrics. Useful for keyed histograms.
- if (typeof addition === 'object') {
- this._assertionLoop(prevMetrics[metric], metrics[metric], addition);
- continue;
- }
- Assert.equal(prevMetrics[metric] + addition, metrics[metric]);
- }
- },
-
- checkAdditions: function (additions) {
- let prevMetrics = this._metrics;
- this.updateMetrics();
- this._assertionLoop(prevMetrics, this._metrics, additions);
- }
-
-};
-
-function getInfobarElement(browser, anonid) {
- let notif = browser.translationUI
- .notificationBox.getNotificationWithValue("translation");
- return notif._getAnonElt(anonid);
-}
-
-var offerTranslationFor = Task.async(function*(text, from) {
- // Create some content to translate.
- const dataUrl = "data:text/html;charset=utf-8," + text;
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, dataUrl);
-
- let browser = gBrowser.getBrowserForTab(tab);
-
- // Send a translation offer.
- Translation.documentStateReceived(browser, {state: Translation.STATE_OFFER,
- originalShown: true,
- detectedLanguage: from});
-
- return tab;
-});
-
-var acceptTranslationOffer = Task.async(function*(tab) {
- let browser = tab.linkedBrowser;
- getInfobarElement(browser, "translate").doCommand();
- yield waitForMessage(browser, "Translation:Finished");
-});
-
-var translate = Task.async(function*(text, from, closeTab = true) {
- let tab = yield offerTranslationFor(text, from);
- yield acceptTranslationOffer(tab);
- if (closeTab) {
- gBrowser.removeTab(tab);
- return null;
- }
- return tab;
-});
-
-function waitForMessage({messageManager}, name) {
- return new Promise(resolve => {
- messageManager.addMessageListener(name, function onMessage() {
- messageManager.removeMessageListener(name, onMessage);
- resolve();
- });
- });
-}
-
-function simulateUserSelectInMenulist(menulist, value) {
- menulist.value = value;
- menulist.doCommand();
-}
-
-add_task(function* setup() {
- const setupPrefs = prefs => {
- let prefsBackup = {};
- for (let p of prefs) {
- prefsBackup[p] = Services.prefs.setBoolPref;
- Services.prefs.setBoolPref(p, true);
- }
- return prefsBackup;
- };
-
- const restorePrefs = (prefs, backup) => {
- for (let p of prefs) {
- Services.prefs.setBoolPref(p, backup[p]);
- }
- };
-
- const prefs = [
- "toolkit.telemetry.enabled",
- "browser.translation.detectLanguage",
- "browser.translation.ui.show"
- ];
-
- let prefsBackup = setupPrefs(prefs);
-
- let oldCanRecord = Telemetry.canRecordExtended;
- Telemetry.canRecordExtended = true;
-
- registerCleanupFunction(() => {
- restorePrefs(prefs, prefsBackup);
- Telemetry.canRecordExtended = oldCanRecord;
- });
-
- // Reset histogram metrics.
- MetricsChecker.reset();
-});
-
-add_task(function* test_telemetry() {
- // Translate a page.
- yield translate("<h1>Привет, мир!</h1>", "ru");
-
- // Translate another page.
- yield translate("<h1>Hallo Welt!</h1><h1>Bratwurst!</h1>", "de");
- yield MetricsChecker.checkAdditions({
- opportunitiesCount: 2,
- opportunitiesCountByLang: { "ru" : 1, "de" : 1 },
- pageCount: 1,
- pageCountByLang: { "de -> en" : 1 },
- charCount: 21,
- deniedOffers: 0
- });
-});
-
-add_task(function* test_deny_translation_metric() {
- function* offerAndDeny(elementAnonid) {
- let tab = yield offerTranslationFor("<h1>Hallo Welt!</h1>", "de", "en");
- getInfobarElement(tab.linkedBrowser, elementAnonid).doCommand();
- yield MetricsChecker.checkAdditions({ deniedOffers: 1 });
- gBrowser.removeTab(tab);
- }
-
- yield offerAndDeny("notNow");
- yield offerAndDeny("neverForSite");
- yield offerAndDeny("neverForLanguage");
- yield offerAndDeny("closeButton");
-
- // Test that the close button doesn't record a denied translation if
- // the infobar is not in its "offer" state.
- let tab = yield translate("<h1>Hallo Welt!</h1>", "de", false);
- yield MetricsChecker.checkAdditions({ deniedOffers: 0 });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_show_original() {
- let tab =
- yield translate("<h1>Hallo Welt!</h1><h1>Bratwurst!</h1>", "de", false);
- yield MetricsChecker.checkAdditions({ pageCount: 1, showOriginal: 0 });
- getInfobarElement(tab.linkedBrowser, "showOriginal").doCommand();
- yield MetricsChecker.checkAdditions({ pageCount: 0, showOriginal: 1 });
- gBrowser.removeTab(tab);
-});
-
-add_task(function* test_language_change() {
- // This is run 4 times, the total additions are checked afterwards.
- for (let i of Array(4)) { // eslint-disable-line no-unused-vars
- let tab = yield offerTranslationFor("<h1>Hallo Welt!</h1>", "fr");
- let browser = tab.linkedBrowser;
- // In the offer state, translation is executed by the Translate button,
- // so we expect just a single recoding.
- let detectedLangMenulist = getInfobarElement(browser, "detectedLanguage");
- simulateUserSelectInMenulist(detectedLangMenulist, "de");
- simulateUserSelectInMenulist(detectedLangMenulist, "it");
- simulateUserSelectInMenulist(detectedLangMenulist, "de");
- yield acceptTranslationOffer(tab);
-
- // In the translated state, a change in the form or to menulists
- // triggers re-translation right away.
- let fromLangMenulist = getInfobarElement(browser, "fromLanguage");
- simulateUserSelectInMenulist(fromLangMenulist, "it");
- simulateUserSelectInMenulist(fromLangMenulist, "de");
-
- // Selecting the same item shouldn't count.
- simulateUserSelectInMenulist(fromLangMenulist, "de");
-
- let toLangMenulist = getInfobarElement(browser, "toLanguage");
- simulateUserSelectInMenulist(toLangMenulist, "fr");
- simulateUserSelectInMenulist(toLangMenulist, "en");
- simulateUserSelectInMenulist(toLangMenulist, "it");
-
- // Selecting the same item shouldn't count.
- simulateUserSelectInMenulist(toLangMenulist, "it");
-
- // Setting the target language to the source language is a no-op,
- // so it shouldn't count.
- simulateUserSelectInMenulist(toLangMenulist, "de");
-
- gBrowser.removeTab(tab);
- }
- yield MetricsChecker.checkAdditions({
- detectedLanguageChangedBefore: 4,
- detectedLanguageChangeAfter: 8,
- targetLanguageChanged: 12
- });
-});
-
-add_task(function* test_never_offer_translation() {
- Services.prefs.setCharPref("browser.translation.neverForLanguages", "fr");
-
- let tab = yield offerTranslationFor("<h1>Hallo Welt!</h1>", "fr");
-
- yield MetricsChecker.checkAdditions({
- autoRejectedOffers: 1,
- });
-
- gBrowser.removeTab(tab);
- Services.prefs.clearUserPref("browser.translation.neverForLanguages");
-});
-
-add_task(function* test_translation_preferences() {
-
- let preferenceChecks = {
- "browser.translation.ui.show" : [
- {value: false, expected: {showUI: 0}},
- {value: true, expected: {showUI: 1}}
- ],
- "browser.translation.detectLanguage" : [
- {value: false, expected: {detectLang: 0}},
- {value: true, expected: {detectLang: 1}}
- ],
- };
-
- for (let preference of Object.keys(preferenceChecks)) {
- for (let check of preferenceChecks[preference]) {
- MetricsChecker.reset();
- Services.prefs.setBoolPref(preference, check.value);
- // Preference metrics are collected once when the provider is initialized.
- TranslationTelemetry.init();
- yield MetricsChecker.checkAdditions(check.expected);
- }
- Services.prefs.clearUserPref(preference);
- }
-
-});
diff --git a/browser/components/translation/test/browser_translation_yandex.js b/browser/components/translation/test/browser_translation_yandex.js
deleted file mode 100644
index 6e0af18e6..000000000
--- a/browser/components/translation/test/browser_translation_yandex.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test the Yandex Translator client against a mock Yandex service, yandex.sjs.
-
-"use strict";
-
-const kEnginePref = "browser.translation.engine";
-const kApiKeyPref = "browser.translation.yandex.apiKeyOverride";
-const kShowUIPref = "browser.translation.ui.show";
-
-const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
-const {Translation} = Cu.import("resource:///modules/translation/Translation.jsm", {});
-
-add_task(function* setup() {
- Services.prefs.setCharPref(kEnginePref, "yandex");
- Services.prefs.setCharPref(kApiKeyPref, "yandexValidKey");
- Services.prefs.setBoolPref(kShowUIPref, true);
-
- registerCleanupFunction(function () {
- Services.prefs.clearUserPref(kEnginePref);
- Services.prefs.clearUserPref(kApiKeyPref);
- Services.prefs.clearUserPref(kShowUIPref);
- });
-});
-
-/**
- * Ensure that the translation engine behaives as expected when translating
- * a sample page.
- */
-add_task(function* test_yandex_translation() {
-
- // Loading the fixture page.
- let url = constructFixtureURL("bug1022725-fr.html");
- let tab = yield promiseTestPageLoad(url);
-
- // Translating the contents of the loaded tab.
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
-
- yield ContentTask.spawn(browser, null, function*() {
- Cu.import("resource:///modules/translation/TranslationDocument.jsm");
- Cu.import("resource:///modules/translation/YandexTranslator.jsm");
-
- let client = new YandexTranslator(
- new TranslationDocument(content.document), "fr", "en");
- let result = yield client.translate();
-
- Assert.ok(result, "There should be a result.");
- });
-
- gBrowser.removeTab(tab);
-});
-
-/**
- * Ensure that Yandex.Translate is propertly attributed.
- */
-add_task(function* test_yandex_attribution() {
- // Loading the fixture page.
- let url = constructFixtureURL("bug1022725-fr.html");
- let tab = yield promiseTestPageLoad(url);
-
- info("Show an info bar saying the current page is in French");
- let notif = showTranslationUI(tab, "fr");
- let attribution = notif._getAnonElt("translationEngine").selectedIndex;
- Assert.equal(attribution, 1, "Yandex attribution should be shown.");
-
- gBrowser.removeTab(tab);
-});
-
-
-add_task(function* test_preference_attribution() {
-
- let prefUrl = "about:preferences#content";
- let tab = yield promiseTestPageLoad(prefUrl);
-
- let browser = gBrowser.getBrowserForTab(tab);
- let win = browser.contentWindow;
- let bingAttribution = win.document.getElementById("bingAttribution");
- ok(bingAttribution, "Bing attribution should exist.");
- ok(bingAttribution.hidden, "Bing attribution should be hidden.");
-
- gBrowser.removeTab(tab);
-
-});
-
-/**
- * A helper function for constructing a URL to a page stored in the
- * local fixture folder.
- *
- * @param filename Name of a fixture file.
- */
-function constructFixtureURL(filename) {
- // Deduce the Mochitest server address in use from a pref that was pre-processed.
- let server = Services.prefs.getCharPref("browser.translation.yandex.translateURLOverride")
- .replace("http://", "");
- server = server.substr(0, server.indexOf("/"));
- let url = "http://" + server +
- "/browser/browser/components/translation/test/fixtures/" + filename;
- return url;
-}
-
-/**
- * A helper function to open a new tab and wait for its content to load.
- *
- * @param String url A URL to be loaded in the new tab.
- */
-function promiseTestPageLoad(url) {
- let deferred = Promise.defer();
- let tab = gBrowser.selectedTab = gBrowser.addTab(url);
- let browser = gBrowser.selectedBrowser;
- browser.addEventListener("load", function listener() {
- if (browser.currentURI.spec == "about:blank")
- return;
- info("Page loaded: " + browser.currentURI.spec);
- browser.removeEventListener("load", listener, true);
- deferred.resolve(tab);
- }, true);
- return deferred.promise;
-}
-
-function showTranslationUI(tab, aDetectedLanguage) {
- let browser = gBrowser.selectedBrowser;
- Translation.documentStateReceived(browser, {state: Translation.STATE_OFFER,
- originalShown: true,
- detectedLanguage: aDetectedLanguage});
- let ui = browser.translationUI;
- return ui.notificationBox.getNotificationWithValue("translation");
-}
diff --git a/browser/components/translation/test/fixtures/bug1022725-fr.html b/browser/components/translation/test/fixtures/bug1022725-fr.html
deleted file mode 100644
index f30edf52e..000000000
--- a/browser/components/translation/test/fixtures/bug1022725-fr.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!doctype html>
-<html lang="fr">
- <head>
- <!--
- - Text retrieved from http://fr.wikipedia.org/wiki/Coupe_du_monde_de_football_de_2014
- - at 06/13/2014, Creative Commons Attribution-ShareAlike License.
- -->
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>test</title>
- </head>
- <body>
- <h1>Coupe du monde de football de 2014</h1>
- <div>La Coupe du monde de football de 2014 est la 20e édition de la Coupe du monde de football, compétition organisée par la FIFA et qui réunit les trente-deux meilleures sélections nationales. Sa phase finale a lieu à l'été 2014 au Brésil. Avec le pays organisateur, toutes les équipes championnes du monde depuis 1930 (Uruguay, Italie, Allemagne, Angleterre, Argentine, France et Espagne) se sont qualifiées pour cette compétition. Elle est aussi la première compétition internationale de la Bosnie-Herzégovine.</div>
- </body>
-</html>
diff --git a/browser/components/translation/test/fixtures/result-da39a3ee5e.txt b/browser/components/translation/test/fixtures/result-da39a3ee5e.txt
deleted file mode 100644
index d2d14c788..000000000
--- a/browser/components/translation/test/fixtures/result-da39a3ee5e.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-<ArrayOfTranslateArrayResponse xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
- <TranslateArrayResponse>
- <From>fr</From>
- <OriginalTextSentenceLengths xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
- <a:int>34</a:int>
- </OriginalTextSentenceLengths>
- <TranslatedText>Football's 2014 World Cup</TranslatedText>
- <TranslatedTextSentenceLengths xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
- <a:int>25</a:int>
- </TranslatedTextSentenceLengths>
- </TranslateArrayResponse>
- <TranslateArrayResponse>
- <From>fr</From>
- <OriginalTextSentenceLengths xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
- <a:int>508</a:int>
- </OriginalTextSentenceLengths>
- <TranslatedText>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus diam sem, porttitor eget neque sit amet, ultricies posuere metus. Cras placerat rutrum risus, nec dignissim magna dictum vitae. Fusce eleifend fermentum lacinia. Nulla sagittis cursus nibh. Praesent adipiscing, elit at pulvinar dapibus, neque massa tincidunt sapien, eu consectetur lectus metus sit amet odio. Proin blandit consequat porttitor. Pellentesque vehicula justo sed luctus vestibulum. Donec metus.</TranslatedText>
- <TranslatedTextSentenceLengths xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
- <a:int>475</a:int>
- </TranslatedTextSentenceLengths>
- </TranslateArrayResponse>
-</ArrayOfTranslateArrayResponse>
diff --git a/browser/components/translation/test/fixtures/result-yandex-d448894848.json b/browser/components/translation/test/fixtures/result-yandex-d448894848.json
deleted file mode 100644
index de2f5650e..000000000
--- a/browser/components/translation/test/fixtures/result-yandex-d448894848.json
+++ /dev/null
@@ -1 +0,0 @@
-{"code":200,"lang":"fr-en","text":["Football's 2014 World Cup","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus diam sem, porttitor eget neque sit amet, ultricies posuere metus. Cras placerat rutrum risus, nec dignissim magna dictum vitae. Fusce eleifend fermentum lacinia. Nulla sagittis cursus nibh. Praesent adipiscing, elit at pulvinar dapibus, neque massa tincidunt sapien, eu consectetur lectus metus sit amet odio. Proin blandit consequat porttitor. Pellentesque vehicula justo sed luctus vestibulum. Donec metus."]}
diff --git a/browser/components/translation/test/unit/.eslintrc.js b/browser/components/translation/test/unit/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/components/translation/test/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/components/translation/test/unit/test_cld2.js b/browser/components/translation/test/unit/test_cld2.js
deleted file mode 100644
index 9ebc4d766..000000000
--- a/browser/components/translation/test/unit/test_cld2.js
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//
-// Author: dsites@google.com (Dick Sites)
-//
-// Unit test compact language detector, CLD2
-//
-
-// Test strings.
-const kTeststr_en =
- "confiscation of goods is assigned as the penalty part most of the courts " +
- "consist of members and when it is necessary to bring public cases before a " +
- "jury of members two courts combine for the purpose the most important cases " +
- "of all are brought jurors or";
-
-const kTeststr_aa_Latn = " nagay tanito nagay tanto nagayna naharsi nahrur nake nala nammay nammay haytu nanu narig ne ni num numu o obare obe obe obisse oggole ogli olloyta ongorowe orbise othoga r rabe rade ra e rage rakub rasitte rasu reyta rog ruddi ruga s sa al bada sa ala";
-const kTeststr_ab_Cyrl = " а зуа абзиара дақәшәоит ан лыбзиабара ахә амаӡам ауаҩы игәы иҭоу ихы иҿы ианубаалоит Ð°Ò§Ò³Ó™Ñ‹Ñ Ò§ÑˆÓ¡Ð° ахацәа лышьҭоуп аҿааÑҭа лара дрышьҭоуп";
-const kTeststr_af_Latn = " aam skukuza die naam beteken hy wat skoonvee of hy wat alles onderstebo keer wysig bosveldkampe boskampe is kleiner afgeleë ruskampe wat oor min fasiliteite beskik daar is geen restaurante of winkels nie en slegs oornagbesoekers word toegelaat bateleur";
-const kTeststr_ak_Latn = "Wɔwoo Hilla Limann Mumu-Ɔpɛnimba 12 afe 1934. Wɔwoo no wɔ Gwollu wɔ Sisala Mantaw mu Nna ne maame yɛ Mma Hayawah. Ne papa so nna ɔyɛ Babini Yomu. Ɔwarr Fulera Limann ? Ne mba yɛ esuon-- Lariba Montia [wɔwoo no Limann]; Baba Limann; Sibi Andan [wɔwoo no Limann]; Lida Limann; Danni Limann; Zilla Limann na Salma Limann. Ɔtenaa ase kɔpemm Sanda-Kwakwa da ɛtɔ so 23 wɔ afe 1998 wɔ ?.";
-const kTeststr_am_Ethi = " ለመጠይቅ ወደ እስክንድርያ ላኩዋቸá‹áŠ“ የእስክንድርያ ጳጳስ አቴናስዮስ áሬáˆáŠ•áŒ¦áˆµáŠ• እራሳቸá‹áŠ• ሾመዠáˆáŠ¨á‹‹áˆ ከዚያ እስከ á‹“ ሠድረስ የኢትዮጵያ አቡáŠ";
-const kTeststr_ar_Arab = "احتيالية بيع أي حساب";
-const kTeststr_as_Beng = "অঞà§à¦šà¦² নতà§à¦¨ সদসà§à¦¯à¦¬à§ƒà¦¨à§à¦¦ সকলোৱে ভৰà§à¦¤à¦¿ হব পাৰে মà§à¦² পৃষà§à¦ à¦¾ জন লেখক গà§à¦— ল দল সাৰাংশ ই পতà§à§° টা বাৰà§à¦¤à¦¾ à¦à¦œà¦¨";
-const kTeststr_ay_Latn = " aru wijar aru ispañula ukaran aru witanam aru kurti aru kalis aru warani aru malta aru yatiyawi niya jakitanaka isluwiñ aru lmir phuran aru masirunan aru purtukal aru kruwat aru jakira urtu aru inklisa pirsan aru suyku aru malay aru jisk aptayma thaya";
-const kTeststr_az_Arab = " آذربایجان دا انسان حاقلاری ائوی آچیلاجاق ب Ù… ت ائلچيسي برمه موخاليÙتي نين ليدئري ايله گؤروشه بيليب ترس شوونيسم Ùارس از آزادي ملتهاي تورکمن";
-const kTeststr_az_Latn = " a az qalıb breyn rinq intellektual oyunu üzrə yarışın zona mərhələləri keçirilib miq un qalıqlarının dənizdən çıxarılması davam edir məhəmməd peyğəmbərin karikaturalarını çap edən qəzetin baş redaktoru iş otağında ölüb";
-const kTeststr_ba_Cyrl = " арналђан бындай ђилми Ñш тіркињлњ тњјге тапєыр нњшер ителњ ғинуар бєхет именлектє етешлектє ауыл ўќмерџєре хеџмєт юлын ћайлаѓанда";
-const kTeststr_be_Cyrl = " а друкаваць Ñ–Ñ… не было Ñ‚Ñхнічна магчыма бліжÑй за вільню тым Ñамым чаÑам нÑмецкае кіраўніцтва прапаноўвала апроч ўвÑÐ´Ð·ÐµÐ½Ð½Ñ Ð»Ð°Ñ†Ñ–Ð½ÐºÑ– Ñе";
-const kTeststr_bg_Cyrl = " а дума попада в ÑÑŠÑтоÑние на изпитание ключовите думи Ñ Ð¿Ñ€ÐµÐ´Ñказана малко под то изиÑкване на Ñтраниците за Ñ‚ÑŠÑ€Ñене в";
-// From 10% testing part of new lang=bh scrape
-const kTeststr_bh_Deva = "काल में उनका हमला से बचे खाती à¤à¤¹à¤¿à¤œà¤¾ भाग के अइले आ भोजपà¥à¤° नाम से नगर बसवले. à¤à¤•à¤°à¤¾ बारे में विसà¥à¤¤à¤¾à¤° से जानकारी नीचे दीहल गइल बा. बाकिर आशà¥à¤šà¤°à¥à¤¯à¤œà¤¨à¤• रूप से मालवा के राजा भोज के बिहार आवे आ भोजपà¥à¤° नगर बसावे आ चाहे भोजपà¥à¤°à¥€ के साथे उनकर कवनो संबंध होखे के कवनो जानकारी भोपाल के भोज संसà¥à¤¥à¤¾à¤¨ आ चाहे मधà¥à¤¯ पà¥à¤°à¤¦à¥‡à¤¶ के इतिहासकार लोगन के तनिको नइखे. हालांकि ऊ सब लोग à¤à¤¹ बात के मानत बा कि à¤à¤•à¤°à¤¾ बारे में अबहीं तकले मूरà¥à¤¤à¤¿ बनवइलें. राजा भोज के जवना जगहा पऽ वागà¥à¤¦à¥‡à¤µà¥€ के दरà¥à¤¶à¤¨ भइल रहे, ओही सà¥à¤¥à¤¾à¤¨ पऽ à¤à¤¹ मूरà¥à¤¤à¤¿ के सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ कइल गइल. अब अगर à¤à¤¹ मंदिर के à¤à¤¹ शिलालेख के तसà¥à¤µà¥€à¤° (पृषà¥à¤  संखà¥à¤¯à¤¾ 33 पऽ पà¥à¤°à¤•à¤¾à¤¶à¤¿à¤¤) रउआ धेयान से देखीं तऽ à¤à¤•à¤°à¤¾ पऽ कैथी लिपि में -सीताराम- लिखल साफ लउकत बा. कैथी भोजपà¥à¤°à¥€ के बहà¥à¤¤ पà¥à¤°à¤šà¤²à¤¿à¤¤ लिपि रहल बिया. à¤à¤•à¤°à¤¾ बारे में कवनो शंका संदेह बिहार-यूपी के जानकार लोगन में नइखे. à¤à¤². à¤à¤¸. à¤à¤¸. वो माले के लिखल पढ़ीं ";
-
-const kTeststr_bi_Latn = " king wantaem nomo hem i sakem setan mo ol rabis enjel blong hem oli aot long heven oli kamdaon long wol taswe ol samting oli kam nogud olgeta long wol ya stat long revelesen ol faet kakae i sot ol sik mo fasin blong brekem loa oli kam antap olgeta samting";
-const kTeststr_blu_Latn = " Kuv hlub koj txawm lub ntuj yuav si ntshi nphaus los kuv tsis ua siab nkaug txawm ntiab teb yuav si ntshi nphaus los kuv tseem ua lon tsaug vim kuv hlub koj tag lub siab";
-const kTeststr_blu_Latn2 = "Kuv hnov Txhiaj Xeeb Vaj, co-owner of Hmong Village Shopping Center, hais ua hnub ua hmo tias kom Hmoob yuav tsum txhawb Hmoob thiab listed cov mini-shops uas nyob rau hauv nws lub MALL txhua txhua kom sawv daws mus txhawb, tiam sis uas cas zaum twg twb pom nws mus kav kiav hauv taj laj qhabmeem (Sun Foods) xwb tiag. Nag hmo kuv pom nws mus shopping nrog nws poj niam hauv Sun Foods. Thaum tawm mus txog nraum parking lot kuv thiaj txhob txwm mus ze ze seb ua li nws mus yuav dab tsi tiag, thiab seb tej uas nws yuav ntawd puas muaj nyob ntawm tej kiab khw Hmoob. Surprised!!! Vuag.... txhua yam nws yuav hauv Sun Foods peb Hmoob cov khw yeej muaj tag nrho. Peb niaj hnub nqua hu kom Hmoob yuav tsum pab Hmoob yog pab li no lod?";
-// From 10% testing part of new lang=bn scrape
-const kTeststr_bn_Beng = "গà§à¦¯à¦¾à¦²à¦¾à¦°à¦¿à¦° ৩৮ বছর পূরà§à¦¤à¦¿à¦¤à§‡ মূলà§à¦¯à¦›à¦¾à§œ অরà§à¦¥à¦¨à§€à¦¤à¦¿ বিà¦à¦¨à¦ªà¦¿à¦° ওয়াক আউট তপন চৌধà§à¦°à§€ হারবাল অà§à¦¯à¦¾à¦¸à§‹à¦¸à¦¿à§Ÿà§‡à¦¶à¦¨à§‡à¦° সভাপতি আনà§à¦¤à¦°à§à¦œà¦¾à¦¤à¦¿à¦• পরামরà§à¦¶à¦• বোরà§à¦¡ দিয়ে শরিয়াহৠইননà§à¦¡à§‡à¦•à§à¦¸ করবে সিà¦à¦¸à¦‡ মালিকপকà§à¦·à§‡à¦° কানà§à¦¨à¦¾, শà§à¦°à¦®à¦¿à¦•à§‡à¦° অনিশà§à¦šà§Ÿà¦¤à¦¾ মতিà¦à¦¿à¦²à§‡ সমাবেশ নিষিদà§à¦§: à¦à¦«à¦¬à¦¿à¦¸à¦¿à¦¸à¦¿à¦†à¦‡à§Ÿà§‡à¦° ধনà§à¦¯à¦¬à¦¾à¦¦ বিনোদন বিশেষ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ বাংলালিংকের গà§à¦°à§à¦¯à¦¾à¦¨à§à¦¡à¦®à¦¾à¦¸à§à¦Ÿà¦¾à¦° সিজন-৩ বà§à¦°à¦¾à¦œà¦¿à¦²à§‡ বিশà§à¦¬à¦•à¦¾à¦ª ফà§à¦Ÿà¦¬à¦² আয়োজনবিরোধী বিকà§à¦·à§‹à¦­ দেশের নিরাপতà§à¦¤à¦¾à¦° চেয়ে অনেক বেশি সচেতন । পà§à¦°à¦¾à¦°à§à¦¥à§€à¦¦à§‡à¦° দকà§à¦·à¦¤à¦¾ ও যোগà§à¦¯à¦¤à¦¾à¦° পাশাপাশি তারা জাতীয় ইসà§à¦¯à§à¦—à§à¦²à§‹à¦¤à§‡ পà§à¦°à¦¾à¦§à¦¾à¦¨à§à¦¯ দিয়েছেন । †পাà¦à¦šà¦Ÿà¦¿ সিটিতে ২০ লাখ ভোটারদের দিয়ে জাতীয় নিরà§à¦¬à¦¾à¦šà¦¨à§‡ ৮ কোটি ভোটারদের সঙà§à¦—ে তà§à¦²à¦¨à¦¾ করা যাবে কি à¦à¦•à¦œà¦¨ দরà§à¦¶à¦•à§‡à¦° à¦à¦®à¦¨ পà§à¦°à¦¶à§à¦¨à§‡ জবাবে আবà§à¦¦à§à¦²à§à¦²à¦¾à¦¹ আল নোমান বলেন , “ à¦à¦‡ পাà¦à¦šà¦Ÿà¦¿ সিটি করà§à¦ªà§‹à¦°à§‡à¦¶à¦¨ নিরà§à¦¬à¦¾à¦šà¦¨ দেশের পাà¦à¦šà¦Ÿà¦¿ বড় বিভাগের পà§à¦°à¦¤à¦¿à¦¨à¦¿à¦§à¦¿à¦¤à§à¦¬ করছে । à¦à¦›à¦¾à§œà¦¾ à¦à¦–ানকার ভোটার রা সবাই সচেতন । তারা";
-
-// From 10% testing part of new lang=bo scrape
-const kTeststr_bo_Tibt = " ་གྱིས་à½à¼‹à½†à½ºà½ à½²à¼‹à½•à¾±à½‚་འཚལ་à½à½„་ཞིག་བཤིག་སྲིད་པ༠ཡར་ཀླུང་གཙང་པོར་ཆ ུ་མཛོང་བརྒྱག་རྒྱུའི་ལས་འཆར་ལ་རྒྱ་གར་གྱི་སེམས་ཚབས༠རྒྱ་གརགྱི་མཚོ་འོག་དམག་གྲུར་སྦར་གས་བྱུང་བ༠པ་ཀི་སི་à½à½“་གྱིས་རྒྱ་གར་ལ་མི་སེར་བསད་པའི་སà¾à¾±à½¼à½“་འཛུགས་བྱས་པ༠རྩོམ་ཡིག་མང་བ༠འབྲེལ་མà½à½´à½‘་བརྒྱུད་ལམ༠à½à½¼à½“་སà¾à¾±à½ºà½‘་དང་སྲི་ཞུ༠་à½à½¼à½‚་དེབ་བཞི་ དཔར་འགྲེམས་གནང་ཡོད་པ་དང་བོད་ཡིག་དྲ་ཚིགས་à½à½‚་ནང་ལ་ཡང་རྩོམ་ཡང་ཡང་བྲིས་གནང་མà½à½“་རེད༠ལེ་ཚན་à½à½‚ ལེ་ཚན་à½à½‚ འབྲེལ་ཡོད༠འགྲེམ་སྟོན༠རྒྱུད་ལམ་སྣ་མང་ཡིག་མཛོད༠བཀོལ་སྤྱོད་པའི་འཇོག་ཡུལ་དྲ་ངོས༠སྔོན་མ༠རྗེས་མ༠བསྟན་འཛིན་བདེ་སà¾à¾±à½²à½‘༠ཚེ་རིང་རྣམ་རྒྱལ༠བསྟན་འཛིན་ངག་དབང་༠ཡོལ་གདོང་ཚེ་རིང་ལྷག་པ༠་དབང་ ཕྱུག་གཉིས་ཀྱིས་བརྗོད་གཞི་བྱེ་བྲག་པ་ཞིག་ལ་བགྲོ་གླེང་གà½à½²à½„་ཟབ་བྱེད་པའི་གཟའ་ འà½à½¼à½¢à¼‹à½‚ཉིས་རེའི་མཚམས་ཀྱི་ལེ་ཚན་ཞིག་ཡིན༠དཔྱད་ཞིབ་ཀྱིས་རྒྱ་ནག་ནང་à½à½´à½£à¼‹à½‚ྱི་འགྱུར་ལྡོག་དང༌༠རྒྱ་ནག་དང་རྒྱལ་སྤྱིའི་འབྲེལ་བར་དམིགས་སུ་བཀར་ནས་བགྲོ་གླེང་བྱེད་ཀྱི་ཡོདà¼à¼ རྒྱང་སྲིང་དུས་ཚོདà¼";
-
-const kTeststr_br_Latn = " a chom met leuskel a ra e blas da jack irons dilabour hag aet kuit eus what is this dibab a reont da c houde michael beinhorn evit produiñ an trede pladenn kavet e vez ar ganaouennoù buhan ha buhan ganto setu stummet ar bladenn adkavet e vez enni funk";
-const kTeststr_bs_Cyrl = "иÑторија боÑне књ иÑторија боÑне књ иÑторија боÑне књ иÑторија боÑне књ ";
-// From 10% testing part of new lang=bs scrape
-const kTeststr_bs_Latn = "Novi predsjednik MeÅ¡ihata Islamske zajednice u Srbiji (IZuS) i muftija dr. Mevlud ef. Dudić izjavio je u intervjuu za Anadolu Agency (AA) kako je uvjeren da će doći do vraćanja jedinstva meÄ‘u muslimanima i unutar Islamske zajednice na prostoru Sandžaka, te da je njegova ruka pružena za povratak svih u okrilje Islamske zajednice u Srbiji nakon skoro sedam godina podjela u tom dijelu Srbije. Dudić je za predsjednika MeÅ¡ihata IZ u Srbiji izabran 4. januara, a zvaniÄna inauguracija će biti obavljena u prvoj polovini februara. Kako se oÄekuje, prisustvovat će joj i reisu-l-ulema Islamske zajednice u Srbiji Husein ef. Kavazović koji će i zvaniÄno promovirati Dudića u novog prvog Äovjeka IZ u Srbiji. Dudić će danas boraviti u prvoj zvaniÄnoj posjeti reisu Kavazoviću, Å¡to je njegov privi simboliÄni potez nakon imenovanja. ";
-
-const kTeststr_ca_Latn = "al final en un únic lloc nhorabona l correu electrònic està concebut com a eina de productivitat aleshores per què perdre el temps arxivant missatges per després intentar recordar on els veu desar i per què heu d eliminar missatges importants per l";
-const kTeststr_ceb_Latn = "Ang Sugbo usa sa mga labing ugmad nga lalawigan sa nasod. Kini ang sentro sa komersyo, edukasyon ug industriya sa sentral ug habagatang dapit sa kapupod-an. Ang mipadayag sa Sugbo isip ikapito nga labing nindot nga pulo sa , ang nag-inusarang pulo sa Pilipinas nga napasidunggan sa maong magasin sukad pa sa tuig";
-const kTeststr_ceb_Latn2 = "Ang mga komyun sa Pransiya duol-duol sa inkorporadong mga lungsod ug mga dakbayan sa Estados Unidos. Wala kini susamang istruktura sa Hiniusang Gingharian (UK) tungod kay ang estado niini taliwala sa di-metropolitan nga distrito ug sa sibil nga parokya. Wala usab kini susamang istruktura sa Pilipinas.";
-const kTeststr_chr_Cher = "ᎠᎢáᎩ ᎠáŸáŽ¶áá— á¥á„áá›áŽ© ᎦᎫáá›á…Ꭿ ᎾᎥᎢ";
-const kTeststr_co_Latn = " a prupusitu di risultati for utilizà a scatula per ricercà ind issi risultati servore errore u servore ha incuntratu una errore pruvisoria é ùn ha pussutu compie a vostra dumanda per piacè acimenta dinò ind una minuta tuttu listessu ligami truvà i";
-const kTeststr_crs_Latn = "Sesel ou menm nou sel patri. Kot nou viv dan larmoni. Lazwa, lanmour ek lape. Nou remersye Bondye. Preserv labote nou pei. Larises nou losean. En leritaz byen presye. Pour boner nou zanfan. Reste touzour dan linite. Fer monte nou paviyon. Ansanm pou tou leternite. Koste Seselwa!";
-const kTeststr_cs_Latn = " a akci opakujte film uložen vykreslit gmail tokio smazat obsah adresáře nelze naÄíst systémový profil jednotky smoot okud používáte pro urÄení polokoule znaÄky z západ nebo v východ používejte nezáporné hodnoty zemÄ›pisné délky nelze";
-const kTeststr_cy_Latn = " a chofrestru eich cyfrif ymwelwch a unwaith i chi greu eich cyfrif mi fydd yn cael ei hysbysu o ch cyfeiriad ebost newydd fel eich bod yn gallu cadw mewn cysylltiad drwy gmail os nad ydych chi wedi clywed yn barod am gmail mae n gwasanaeth gwebost";
-const kTeststr_da_Latn = " a z tallene og punktummer der er tilladte log ud angiv den ønskede adgangskode igen november gem personlige oplysninger kontrolspørgsmål det sidste tegn i dit brugernavn skal være et bogstav a z eller tal skriv de tegn du kan se i billedet nedenfor";
-const kTeststr_de_Latn = " abschnitt ordner aktivieren werden die ordnereinstellungen im farbabschnitt deaktiviert öchten sie wirklich fortfahren eldtypen angeben optional n diesem schritt geben sie für jedesfeld aus dem datenset den typ an ieser schritt ist optional eldtypen";
-const kTeststr_dv_Thaa = " Þ€Þ¨Þ‚Þ°Þ‹Þ© Þ„Þ¦Þ€ÞªÞ‚Þ° ÞˆÞ§Þ€Þ¦Þ†Þ¦ Þ‹Þ¦Þ‡Þ°Þ†Þ§Þ‡Þ¨ÞƒÞª Þ‹Þ¬ÞˆÞ¦Þ‚Þ¦ Þ„Þ¦Þ€Þ¬Þ‡Þ°ÞŽÞ¬ ގޮތުގައާއި Þ‡Þ¬Þ‚Þ«Þ‚Þ° ގޮތްގޮތުން Þ€Þ¨Þ‚Þ°Þ‹Þ© Þ„Þ¦Þ€ÞªÞ‚Þ° ÞˆÞ§Þ€Þ¦Þ†Þ¦ Þ‹Þ¦Þ‡Þ°Þ†Þ§ Þ‰Þ©Þ€ÞªÞ‚Þ°ÞŽÞ¬ Þ‡Þ¦Þ‹Þ¦Þ‹Þª Þ‰Þ¨ÞÞ¨Þ‡Þ¦Þ‚Þ¦ÞÞ°";
-const kTeststr_dz_Tibt = " རྩིས བརà¾à¾±à½– ཚུལ ལྡན དང ངེས བདེན སྦ སྟོན ནིའི དོན ལུ à½à¾±à½¼à½‘ གུག ཤད ལག ལེན འà½à½– དགོ ག དང ཨིན པུཊི གྲལ à½à½²à½‚ གུ";
-const kTeststr_ee_Latn = "Yi (Di tanya sia) tatia akɔ wò ayi axa yeye dzi kple tanya si sɔ kple esi wòŋlɔ ɖe goa me, negbe axaa ɖe li kpakple tanya mawo xoxo ko. Teƒe le axa yeye sia dzi si wòateŋu atia na kpekpeɖeŋu kple nuwoŋlɔŋlɔ ne anɔ hahiãm na wò. Mehiã be na gbugbɔ ava afii na axa yeye gɔmedzedze o. Woateŋu adze wo gɔme kple nuŋɔŋlɔ dzẽwo tatia. Megavɔ̃ na nuyeyewo gɔmedzedze kroa o.";
-const kTeststr_el_Grek = " ή αÏνητική αναζήτηση λέξης ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎºÎ±Ï„Î±ÏƒÏ„Î®ÏƒÏ„Îµ τις μεμονωμένες λέξεις κλειδιά πεÏισσότεÏο στοχοθετημένες με τη μετατÏοπή τους σε";
-const kTeststr_en_Latn = " a backup credit card by visiting your billing preferences page or visit the adwords help centre for more details https adwords google com support bin answer py answer hl en we were unable to process the payment of for your outstanding google adwords";
-const kTeststr_eo_Latn = " a jarcento refoje per enmetado de koncerna pastro tiam de reformita konfesio ekde refoje ekzistis luteranaj komunumanoj tamen tiuj fondis propran komunumon nur en ambaÅ­ apartenis ekde al la evangela eklezio en prusio resp ties rejnlanda provinceklezio en";
-const kTeststr_es_Latn = " a continuación haz clic en el botón obtener ruta también puedes desplazarte hasta el final de la página para cambiar tus opciones de búsqueda gráfico y detalles ésta es una lista de los vídeos que te recomendamos nuestras recomendaciones se basan";
-const kTeststr_et_Latn = " a niipea kui sinu maksimaalne igakuine krediidi limiit on meie poolt heaks kiidetud on sinu kohustuseks see krediidilimiit";
-const kTeststr_eu_Latn = " a den eraso bat honen kontra hortaz eragiketa bakarrik behar dituen eraso batek aes apurtuko luke nahiz eta oraingoz eraso bideraezina izan gaur egungo teknologiaren mugak direla eta oraingoz kezka hauek alde batera utzi daitezke orain arteko indar";
-const kTeststr_fa_Arab = " آب خوردن عجله Ù…ÛŒ کردند به جای باز ÛŒ کتک کاری Ù…ÛŒ کردند Ùˆ همه چيز مثل قبل بود Ùقط من ماندم Ùˆ ÙŠÚ© دنيا حر٠و انتظار تا عاقبت رسيد احضاريه ÛŒ ای با";
-const kTeststr_fi_Latn = " a joilla olet käynyt tämä kerro meille kuka ä olet ei tunnistettavia käyttötietoja kuten virheraportteja käytetään google desktopin parantamiseen etsi näyttää mukautettuja uutisia google desktop keskivaihto leikkaa voit kaksoisnapsauttaa";
-const kTeststr_fj_Latn = " i kina na i iri ka duatani na matana main a meke wesi se meke mada na meke ni yaqona oqo na meke ka dau vakayagataki ena yaqona vakaturaga e dau caka toka ga kina na vucu ka dau lagati tiko kina na ka e yaco tiko na talo ni wai ni yaqona na lewai ni wai";
-const kTeststr_fo_Latn = " at verða átaluverdar óhóskandi ella áloypandi vit kunnu ikki garanterða at google leitanin ikki finnur naka sum er áloypandi óhóskandi ella átaluvert og google tekur onga ábyrgd yvir tær síður sum koma við í okkara leitiskipan fá tær ein";
-const kTeststr_fr_Latn = " a accès aux collections et aux frontaux qui lui ont été attribués il peut consulter et modifier ses collections et exporter des configurations de collection toutefois il ne peut pas créer ni supprimer des collections enfin il a accès aux fonctions";
-const kTeststr_fy_Latn = " adfertinsjes gewoan lytse adfertinsjes mei besibbe siden dy t fan belang binne foar de ynhâld fan jo berjochten wolle jo mear witte fan gmail foardat jo jo oanmelde gean dan nei wy wurkje eltse dei om gmail te ferbetterjen dêrta sille wy jo sa út en";
-const kTeststr_ga_Latn = " a bhfuil na focail go léir i do cheist le fáil orthu ní gá ach focail breise a chur leis na cinn a cuardaíodh cheana chun an cuardach a bheachtú nó a chúngú má chuirtear focal breise isteach aimseofar fo aicme ar leith de na torthaí a fuarthas";
-const kTeststr_gaa_Latn = "Akε mlawookpeehe kε Maŋhiεnyiεlכ oshikifככ lε eba naagbee ni maŋ lε nitsumכ ni kwεכ oshikifככ nכ lε etsככ mכ ni ye kunim ni akε lε eta esεŋ nכ. Dani nomεi baaba nכ lε, maŋ nכkwεmכ kui wuji enyכ ni yככ wכ maŋ lε mli, NPP kε NDC mli bii fכfכi wiemכi kεmaje majee amεhe. Ekomεi kwraa po yafee hiεkwεmכi ni ha ni gidigidi, pilamכ kε la shishwiemכ aaba yε heikomεi. ";
-const kTeststr_gd_Latn = " air son is gum bi casg air a h uile briosgaid no gum faigh thu brath nuair a tha briosgaid a tighinn gad rannsachadh ghoogle gu ceart mura bheil briosgaidean ceadaichte cuiridh google briosgaid dha do neach cleachdaidh fa leth tha google a cleachdadh";
-const kTeststr_gl_Latn = " debe ser como mínimo taranto tendas de venda polo miúdo cociñas servizos bordado canadá viaxes parques de vehículos de recreo hotel oriental habitación recibir unha postal no enderezo indicado anteriormente";
-const kTeststr_gn_Latn = " aháta añe ë ne mbo ehára ndive ajeruréta chupe oporandujey haÄua peëme mba épa pekaru ha áÄa oporandúvo nde eréta avei re paraguaýpe kachíke he i leúpe ndépa re úma kure tatakuápe ha leu ombohovái héë ha ujepéma kachíke he ijey";
-const kTeststr_gu_Gujr = " આના પરિણામ પà«àª°àª®àª¾àª£àª¸àª° ફોનà«àªŸ અવતરણ ચિનà«àª¹àªµàª¾àª³àª¾ પાઠને છà«àªªàª¾àªµà«‹ બધા સમૂહો શોધાયા હાલનો જ સંદેશ વિષયની";
-const kTeststr_gv_Latn = " and not ripe as i thought yn assyl yn shynnagh as yn lion the ass the fox and the lion va assyl as shynnagh ayns commee son nyn vendeilys as sauchys hie ad magh ayns y cheyll dy shelg cha row ad er gholl feer foddey tra veeit ad rish lion yn shynnagh";
-const kTeststr_ha_Latn = " a cikin a kan sakamako daga sakwannin a kan sakamako daga sakwannin daga ranar zuwa a kan sakamako daga guda daga ranar zuwa a kan sakamako daga shafukan daga ranar zuwa a kan sakamako daga guda a cikin last hour a kan sakamako daga guda daga kafar";
-const kTeststr_haw_Latn = "He puke noiÊ»i kÅ«Ê»ikena kÅ«noa Ê»o Wikipikia. E Ê»oluÊ»olu nÅ, e hÄÊ»awi mai i kÄu Ê»ike, kÄu manaÊ»o, a me kou leo no ke kÅ«kulu Ê»ana a me ke kÄkoÊ»o Ê»ana mai i ka Wikipikia HawaiÊ»i. He kahua pÅ«naewele HawaiÊ»i kÄ“ia no ka hoÊ»oulu Ê»ana i ka Ê»ike HawaiÊ»i. InÄ hiki iÄ Ê»oe ke Ê»Ålelo HawaiÊ»i, e Ê»oluÊ»olu nÅ, e kÅkua mai a e hoÊ»ololi i nÄ Ê»atikala ma Ê»aneÊ»i, a pono e haÊ»i aku i kou mau hoa aloha e pili ana i ka Wikipikia HawaiÊ»i. E ola mau nÅ ka Ê»Ålelo HawaiÊ»i a mau loa aku.";
-const kTeststr_hi_Deva = " ं à¤à¤¡à¤µà¤°à¥à¤¡à¥à¤¸ विजà¥à¤žà¤¾à¤ªà¤¨à¥‹à¤‚ के अनà¥à¤­à¤µ पर आधारित हैं और इनकी मदद से आपको अपने विजà¥à¤žà¤¾à¤ªà¤¨à¥‹à¤‚ का अधिकतम लाभ";
-const kTeststr_hr_Latn = "Posljednja dva vladara su Kijaksar (ΚυαξαÏης; 625-585 prije Krista), fraortov sin koji će proÅ¡iriti teritorij Medije i Astijag. Kijaksar je imao kćer ili unuku koja se zvala Amitis a postala je ženom Nabukodonosora II. kojoj je ovaj izgradio Viseće vrtove Babilona. Kijaksar je modernizirao svoju vojsku i uniÅ¡tio Ninivu 612. prije Krista. Naslijedio ga je njegov sin, posljednji medijski kralj, Astijag, kojega je detronizirao (sruÅ¡io sa vlasti) njegov unuk Kir Veliki. Zemljom su zavladali Perzijanci.";
-const kTeststr_ht_Latn = " ak pitit tout sosyete a chita se pou sa leta dwe pwoteje yo nimewo leta fèt pou li pwoteje tout paran ak pitit nan peyi a menm jan kit paran yo marye kit yo pa marye tout manman ki fè pitit leta fèt pou ba yo konkoul menm jan tou pou timoun piti ak pou";
-const kTeststr_hu_Latn = " a felhasználóim a google azonosító szöveget ikor látják a felhasználóim a google azonosító szöveget felhasználók a google azonosító szöveget fogják látni minden tranzakció után ha a vásárlását regisztrációját oldalunk";
-const kTeststr_hy_Armn = " Õ¡ Õµ Õ¥Õ¾ Õ¶Õ¡ Õ°Õ«Õ¡ÖÕ¡Õ® Õ¡Õ¹Ö„Õ¥Ö€Õ¸Õ¾ Õ¶Õ¡ÕµÕ¸Ö‚Õ´ Õ§ Õ°Õ«Õ¶Õ£Õ°Õ¡Ö€Õ¯Õ¡Õ¶Õ« Õ·Õ¥Õ¶Ö„Õ« Õ¿Õ¡Ö€Ö…Ö€Õ«Õ¶Õ¡Õ¯ ÖƒÕ¸Ö„Ö€Õ«Õ¯ Ö„Õ¡Õ¼Õ¡Õ¯Õ¸Ö‚Õ½Õ« ÕºÕ¡Õ¿Õ¸Ö‚Õ°Õ¡Õ¶Õ¶Õ¥Ö€Õ«Õ¶ Õ¤Õ¥Õ¼ Õ´Õ¥Õ¶Ö„ Õ·Õ¡Õ¿ Õ¥Õ¶Ö„ Õ°Õ¥Õ¿Õ¡Õ´Õ¶Õ¡Ö Õ¡Õ½Õ¸Ö‚Õ´ Õ§ Õ¶Õ¡ Õ¡ÕµÕ½ÕºÕ¥Õ½ Õ§";
-const kTeststr_ia_Latn = " super le sitos que tu visita isto es necessari pro render disponibile alcun functionalitates del barra de utensiles a fin que nos pote monstrar informationes ulterior super un sito le barra de utensiles debe dicer a nos le";
-// From 10% testing part of new lang=id scrape
-const kTeststr_id_Latn = "berdiri setelah pengurusnya yang berusia 83 tahun, Fayzrahman Satarov, mendeklarasikan diri sebagai nabi dan rumahnya sebagai negara Islam Satarov digambarkan sebagai mantan ulama Islam tahun 1970-an. Pengikutnya didorong membaca manuskripnya dan kebanyakan dilarang meninggalkan tempat persembunyian bawah tanah di dasar gedung delapan lantai mereka. Jaksa membuka penyelidikan kasus kriminal pada kelompok itu dan menyatakan akan membubarkan kelompok kalau tetap melakukan kegiatan ilegal seperti mencegah anggotanya mencari bantuan medis atau pendidikan. Sampai sekarang pihak berwajib belum melakukan penangkapan meskipun polisi mencurigai adanya tindak kekerasan pada anak. Pengadilan selanjutnya akan memutuskan apakah anak-anak diizinkan tetap tinggal dengan orang tua mereka. Kazan yang berada sekitar 800 kilometer di timur Moskow merupakan wilayah Tatarstan yang";
-
-const kTeststr_ie_Latn = " abhorre exceptiones in li derivation plu cardinal por un l i es li regularità del flexion conjugation ples comparar latino sine flexione e li antiqui projectes naturalistic queles have quasi null regules de derivation ma si on nu examina li enunciationes";
-const kTeststr_ig_Latn = "Chineke bụ aha á»zá» ndï omenala Igbo kpá»ro Chukwu. Mgbe ndị bekee bịara, ha mee ya nke ndi Christian. N'echiche ndi ekpere chi Omenala Ndi Igbo, Christianity, Judaism, ma Islam, Chineke nwere á»tụtụ utu aha, ma nwee nanị otu aha. Ụzá» abụỠe si akpá» aha ahụ bụ Jehovah ma Ọ bụ Yahweh. Na á»tụtụ Akwụkwá» Nsá», e wepụla aha Chineke ma jiri utu aha bụ Onyenwe Anyị ma á» bụ Chineke dochie ya. Ma mgbe e dere akwụkwá» nsá», aha ahụ bụ Jehova pụtara n’ime ya, ihe dị ka ugboro pụkụ asaa(7,000).";
-// From 10% testing part of new lang=ik scrape
-const kTeststr_ik_Latn = "sabvaqjuktuq sabvaba atiqaqpa atiqaqpa ibiq iebiq ixafich niuqtulgiññatif uvani natural gas tatpikka ufasiksigiruaq maaffa savaannafarufa mi tatkivani navy qanuqjugugguuq taaptuma inna uqsrunik ivaqjiqhutik taktuk allualiuqtuq sigukun nanuq puuvraatuq taktuum amugaa kalumnitigun nanuq agliruq allualiuqtuq";
-
-const kTeststr_is_Latn = " a afköst leitarorða þinna leitarorð neikvæð leitarorð auglýsingahópa byggja upp aðallista yfir ný leitarorð fyrir auglýsingahópana og skoða ítarleg gögn um árangur leitarorða eins og samkeppni auglýsenda og leitarmagn er krafist notkun";
-const kTeststr_it_Latn = " a causa di un intervento di manutenzione del sistema fino alle ore circa ora legale costa del pacifico del novembre le campagne esistenti continueranno a essere pubblicate come di consueto anche durante questo breve periodo di inattività ci scusiamo per";
-const kTeststr_iu_Cans = "áƒá‘¯á’ªá’»á’ªá‘¦ ᕿᓈá–á“ᓇᓲᖑᒻᒪᑦ ᑎᑎᖅᑕᓕᒫᖅᓃᕕᑦ ᑎᑦᕆáŠá‘á“á–ᑦᑕᑎᑦ ᑎᑎᖅᑕᑉá±á‘¦ ᓯᕗᓂᖓᓂ ᑎᑎᖅᖃᖅ ᑎᑎᕆáŠá‘á“á–á‘•áƒá‘¦ ᕿᓂᓲᖑᔪá’ᑦ ᑎᑎᖅᑕᓕᒫᖅᓃᕕᑦ";
-const kTeststr_he_Hebr = " ×ו לערוך ×ת העדפות ההפצה ×× × ×¢×§×•×‘ ×חרי ×”×©×œ×‘×™× ×”×‘××™× ×›× ×¡ לחשבון ×”×ישי שלך ב";
-const kTeststr_ja_Hani = " ã“ã®ãƒš ジã§ã¯ アカウントã«æŒ‡å®šã•ã‚ŒãŸäºˆç®—ã®å±¥æ­´ã‚’一覧ã«ã—ã¦ã„ã¾ã™ ãã‚Œãžã‚Œã®é …ç›®ã«ã¯ 予算é¡ã¨ç‰¹å®šæœŸé–“ã®ã‚¹ãƒ† タスãŒè¡¨ç¤ºã•ã‚Œã¾ã™ ç¾åœ¨ã¾ãŸã¯ä»Šå¾Œã®äºˆç®—を設定ã™ã‚‹ã«ã¯";
-const kTeststr_jw_Latn = " account ten server niki kalian username meniko tanpo judul cacahe account nggonanmu wes pol pesen mu wes diguwak pesenan mu wes di simpen sante wae pesenan mu wes ke kirim mbuh tekan ora pesenan e ke kethok pesenan mu wes ke kirim mbuh tekan ora pesenan";
-const kTeststr_ka_Geor = " რბირთვიდáƒáƒœ მიღებული ელემენტი მენდელეევის პერიáƒáƒ“ულ სიტემáƒáƒ¨áƒ˜ გáƒáƒ“áƒáƒ˜áƒœáƒáƒªáƒ•áƒšáƒ”ბს áƒáƒ áƒ˜ უჯრით";
-const kTeststr_kha_Latn = " kaba jem jai sa sngap thuh ia ki bynta ba sharum naka sohbuin jong phi nangta sa pynhiar ia ka kti kadiang jong phi sha ka krung jong phi bad da kaba pyndonkam kumjuh ia ki shympriahti jong phi sa sngap thuh shapoh ka tohtit jong phi pyndonkam ia kajuh ka";
-const kTeststr_kk_Arab = " ﺎ ﻗﻴﺎﻧﺎﺕ ﺑﻮﻟﻤﺎﻳﺪﻯ ïº‘ï¯˜ï» ï­˜ïº®ï»­ïº—ïº´ï»ªïº³ï¯©ï»¦ ﻳﺎﻋﻨﻲ ﻗﺎﻻ ﻭﻣﯩﺮﯨﻨﺪﻩ ﻗﺎﺯïºï»• Ø¡ ﺗﯩﻠﯩﻨﯩﯔ ﻗﻮﻟﺪïºï»§ï¯©ï» ï»¤ïºŽï¯žï»¯ ﻗﺎﺯïºï»• ﺟﻪﺭﯨﻨﺪﻩ";
-const kTeststr_kk_Cyrl = " а билердің өзіне Ñ€Ò±Ò›Ñат берілмеген егер халық талап етÑе ғана хан келіÑім берген өздеріңіз білеÑіздер қр қыл Ð¼Ñ‹Ñ Ñ‚Ñ‹Ò› кодекÑінде жазаның";
-const kTeststr_kk_Latn = " bolsa da otanyna qaityp keledi al oralmandar basqa elderde diasporasy ote az bolghandyqtan bir birine komektesip bauyrmal bolady birde men poezben oralmandardyng qazaqstangha keluin kordim monghol qazaqtary poezdan tuse sala jerdi suip jylap keletin biraq";
-const kTeststr_kl_Latn = " at nittartakkalli uani toqqarsimasatta akornanni nittartakkanut allanut ingerlaqqittoqarsinnaavoq kanukoka tassaavoq kommuneqarfiit kattuffiat nuna tamakkerlugu kommunit nittartagaannut ingerlaqqiffiusinnaasoq kisitsiserpassuit nunatsinnut tunngasut";
-const kTeststr_km_Khmr = " ក ហគ ឃ ង ច ឆ ជ ឈ ញ ដ ឋ ឌ ហណ ហហទ ធ ន ប ផ ព ភ ម យ រ ល វ ស ហ ឡ អ ឥ ឦ ឧ ឪ ឫ ឬ ឯ ឱ ទាំងអស់";
-const kTeststr_kn_Knda = " ಂಠಯà³à²¯à²¨à²µà²°à³ ತà³à²®à²•à³‚ರೠಜಿಲà³à²²à³†à²¯ ಚಿಕà³à²•à²¨à²¾à²¯à²•à²¨à²¹à²³à³à²³à²¿ ತಾಲà³à²²à³‚ಕಿನ ತೀರà³à²¥à²ªà³à²° ವೆಂಬ ಸಾಧಾರಣ ಹಳà³à²³à²¿à²¯ ಶà³à²¯à²¾à²¨à³à²­à³‹à²—ರ";
-const kTeststr_ko_Hani = " 개별ì ìœ¼ë¡œ 리í¬íŠ¸ 액세스 ê¶Œí•œì„ ë¶€ì—¬í•  수 있습니다 액세스 권한 부여사용ìžì—게 프로필 리í¬íŠ¸ì— 액세스할 수 있는 ê¶Œí•œì„ ë¶€ì—¬í•˜ì‹œë ¤ë©´ 가용 프로필 ìƒìžì—ì„œ 프로필 ì´ë¦„ì„ ì„ íƒí•œ 다ìŒ";
-// From 10% testing part of new lang=ks scrape
-const kTeststr_ks_Arab = " ژماں سرابن منز گرٲن Ú†Ú¾ÙÛ Ø®Ø§Ø¨Ù•Ú© کھلونÛÙ• ؤڈراواں تÙلتÙÚ¾ Ù†Ùیَس تÛÙ• گوشÛ٠گوشÛ٠مندچھاوى۪س دÙلس Ú†Ú¾ÙÛ ÙˆÙˆÙ†Ù˜Øª ÙˆÙچھان از ستم قلم صبوÙرٕ وول مسٲÙر لیۆکھÙÙ† بێتابن منز ورل سوال Ú†Ú¾ÙÛ ØªØ±Ø§ÙˆØ§Úº جوابن منز کالÛÙ• پھۯستÛÙ• پھن٘ب Ù¾Ú¯ÙŽÛÛ Ù¾Û Ù¾Û†Øª نظر دÙÚ˜ Ù†ÛÙ• ژھالÛÙ• مٔت آرن مٲنز مسول متھان Ú†Ú¾Û’Ùš مس والن ÙˆÛ…Ù† Ú†Ú¾Û’Ùš غارن تÛ٠نارٕ Ú˜Ú¾Ù¹Ú¾ ژاپان رێش تۅرگ تراوٕÛÙ† تÛÙ• ون رٹÛÙ• ÛÙ† ÛوشÛÙ ÛÛŽÛ†Ú†Ú¾ Ù†ÛÙ• پوشنوÙلس Ù†ÙØ´ Ù…Û…Ûرٕ دی دی زٕلاں چھ٠زى۪و حرÙÙ† لۆدرٕ Ù¾Ú¾Ù”Ù„ Ûى۪تھ ملر عازمؔ سۆدرٕ Ú©Ú¾Û…Ù†Û٠منز منگاں Ú†Ú¾ÙÛ Ù†Ø¯Ø±Ù‰ÛªÙ† پن Ú˜Û’ تھى۪کی ÛŒÛ٠مسٲÙر پنن ÙˆÙÚˆÙˆ تÛÙ• پڑاو گٕتَو گٕتَو Ú†Ú¾Û’Ùš ÛŒÛÙ Ú©Û…Ù„ بÙتھ تÛÙ• بانÛÙ• سٕÛÛ Ú¯Û…Ø±Ø¯Ù• Ú†Ú¾Û٠سپداں دمÛÙ• Ù¾ÙÚ¾Ù¹ Ú†Ú¾ÙÙ¹Û Ù¾ÙˆÙ†Ù¾Ø± Ù¾Ú©Ú¾ÛÙ• داران سÙÛ ÛŒØªÙ‰ÛªÙ† تۯاو٠کم نظر دۯاکھ تÛÙ• باسیوے سÙÛ Ù…Û†Û Ûیو یێران Ù…Û’Ùš ژى۪تÙرمÙت Ú†Ú¾ÙÛ Ø³ÙÙ„ÛŒ تس Ú†Ú¾Û’Ùš کتى۪ن تھپھ شاد مس کراں ÙˆÙÚ†Ú¾ Ù…Û’Ùš خون Ú˜Ù• خبر کیاز٠کراں دۯاکھ تمÙس پى۪ٹھ ماتم أز Ú©Û٠شبÛÙ• آو Ù…Û’Ùš بێیÛ٠پیش سÙر زانÛ٠خدا دار٠پى۪ٹھ ژٲنگ Ûنا تھو ز٠ژے Ú†Ú¾Û’Ùš مێون أنÛÙ• کپٹاں Ú†Ú¾ÙÛ Ø²Ù•Ú˜Ù† سون مظÙّر عازمؔ Ù¾ÙˆØ´Û Ø¨Ø±Ú¯Ù† Ú†Ú¾ÙÛ Ø³Ùواں چاکھ سÙÛ Ø§Ù„Ù…Ø§Ø³ قلم لو٠کٔ Úˆ نو٠سرٕ سونتس Ú©Ù„ پرو٠بۆر Ø¨ÛŽÛŒÛ Ø§Ø² بانبر٠Ûۆت یمبرزلÛ٠ٹارى۪ن منز نار وزملÛ٠کۅسÛÙ• کتھ کٔر اظÛار Ú©Ú†Ú¾Û٠منزٕ ÙˆÙ”Ù† رووÙÙ… اچھÛ٠چشمو ژوپÙÙ… Ú©Ù”Ù†Úˆ انبار تماشÛÙ Ú†Ú¾Û٠تگاں";
-
-const kTeststr_ks_Deva = "नमसà¥à¤¤à¥‡ शारदे देवि काशà¥à¤®à¤¿à¤°à¤ªà¥à¤°à¥à¤µà¤¾à¤¸à¤¿à¤¨à¤¿ तà¥à¤µà¤¾à¤®à¤¹à¤® पà¥à¤°à¤¾à¤°à¥à¤¥à¤¯à¥‡ देवि विदà¥à¤¯ दानम च देहि मे कॉशà¥à¤° लेख॒नà¥à¤• सारिव॒य खॊत॒ आसान तरीक॒ छॠयि देवनागरी टाइपराइटर इसà¥à¤¤à¤¿à¤®à¤¾à¤² करà¥à¤¨. अथ मंज़ छि कॉशà¥à¤° लेख॒न॒चि सारॆय मातà¥à¤°à¤¾à¤¯à¤¿. अमि अलाव॒ हॆकिव तॊहà¥à¤¯à¥ यिम॒ यूनिकोड à¤à¤¡à¤¿à¤Ÿà¤° ति वरतॉविथ मगर कॉशिरि मातà¥à¤°à¤¾à¤¯à¤¿ लेख॒नस गछ़ि हना दिकथ: अकà¥à¤·à¤°à¤®à¤¾à¤²à¤¾à¤›à¥ अख मà¥à¤«à¤¼à¥à¤¤ त॒ सॅहॅल सोफà¥à¤Ÿà¤µà¥‡à¤° यॆमि स॒तà¥à¤¯à¥ यà¥à¤¨à¤¿à¤•à¥‹à¤¡ देवनागरी मंज़ ITRANS scheme स॒तà¥à¤¯à¥ छॠयिवान लेख॒न॒. वà¥à¤›à¤¿à¤µ: सहायता. अथ स॒तà¥à¤¯à¥ जà¥à¤¡à¤¿à¤¥ जालपृषà¥à¤  (वेबपेज) (सॉरी अà¤à¤—à¥à¤°à¥€à¤œà¤¼à¥€ पॉठà¥à¤¯)";
-const kTeststr_ku_Arab = " بۆ به ڕێوه بردنی نامه ی که دێتن ڕاسته وخۆ ڕه وان بکه نامه کانی گ مایل بۆ حسابی پۆستێکی تر هێنانی په یوه ندکاره کان له";
-const kTeststr_ku_Latn = " be zmaneki ter le inglis werdegeretewe em srvise heshta le cor beta daye wate hest a taqi dekrete u bashtr dekret tewawwzmanekan wernegrawnetewe u ne hemu laperakn ke eme pshtiwan dekayn be teaweti wergerawete nermwalley wergeran teksti new wene nasnatewe";
-const kTeststr_ky_Arab = " جانا انى تانۇۇ ۇلۇتۇن تانۇۇ قىرعىزدى بئلۉۉ دەگەندىك اچىق ايتساق ماناستى تاانىعاندىق ۅزۉڭدۉ تاانىعاندىق بۉگۉن تەما جۉكتۅمۅ ق ى رع ى ز ت ى ل ى";
-const kTeststr_ky_Cyrl = " агай Ñле оболу мен ÑÐ°Ð´Ñ‹Ð±Ð°ÐºÐ°Ñ Ð°Ð³Ð°Ð½Ñ‹Ð½ өзү менен ÑÐ¼ÐµÑ Ñмгектери менен тааныштым жылдары ташкенде өзбекÑтан илимдер академиÑÑынын баÑны";
-const kTeststr_la_Latn = " a deo qui enim nocendi causa mentiri solet si iam consulendi causa mentiatur multum profecit sed aliud est quod per se ipsum laudabile proponitur aliud quod in deterioris comparatione praeponitur aliter enim gratulamur cum sanus est homo aliter cum melius";
-const kTeststr_lb_Latn = " a gewerkschaften och hei gefuerdert dir dammen an dir häre vun de gewerkschaften denkt un déi aarm wann der äer fuerderunge formuléiert d sechst congés woch an aarbechtszäitverkierzung hëllefen hinnen net d unhiewe vun de steigerungssäz bei de";
-const kTeststr_lg_Latn = " abaana ba bani lukaaga mu ana mu babiri abaana ba bebayi lukaaga mu abiri mu basatu abaana ba azugaadi lukumi mu ebikumi bibiri mu abiri mu babiri abaana ba adonikamu lukaaga mu nltaaga mu mukaaga abaana ba biguvaayi enkumi bbiri mu ataano mu mukaaga";
-const kTeststr_lif_Limb = "á¤á¤¡á¤–ᤠᤳ ᤕᤠᤰᤌᤢᤱ ᤆᤢᤶᤗᤢᤱᤖᤧ ᤛᤥᤎᤢᤱᤃᤧᤴ ᤀᤡᤔᤠᤴᤛᤡᤱ ᤆᤧᤶᤈᤱᤗᤧ á¤á¤¢á¤”ᤡᤱᤅᤥ á¤á¤ á¤ˆá¤¡á¤–ᤡ ᤋᤱᤒᤣ ᥈᥆᥆᥉ ᤒᤠ ᤈá¤á¤˜á¤–ᤡ ᤗᤠá¤á¤¢á¤€á¤ á¤± á¤á¤¹á¤á¤  ᤋᤱᤒᤣ á¤á¤ á¤° á¤á¤ á¤ºá¤³á¤‹á¤¢ ᤕᤢᤖᤢᤒᤠ ᤀᤡᤔᤠᤴᤛᤡᤱ ᤋᤱᤃᤡᤵᤛᤡᤱ ᤌᤡᤶᤒᤣᤴ ᤂᤠᤃᤴ ᤛᤡᤛᤣ᤺ᤰᤗᤠ ᥇ᥠᤂᤧᤴ ᤀᤡᤛᤡᤰ ᥇ ᤈá¤á¤˜á¤–ᤡ ᥈᥆᥆᥊ ᤀᤥ á¤á¤ á¤›á¤¢á¤µ ᤆᤥ᤺ᤰᤔᤠ ᤌᤡᤶᤒᤣ ᤋᤱᤃᤠᤶᤛᤡᤱᤗ á¤á¤³á¤á¤  ᤀᤡᤱᤄᤱ ᤘᤠ᤹";
-const kTeststr_ln_Latn = " abakisamaki ndenge esengeli moyebami abongisamaki solo mpenza kombo ya moyebami elonguamaki kombo ya bayebami elonguamaki kombo eleki molayi po na esika epesameli limbisa esika ya kotia ba kombo esuki boye esengeli olimbola ndako na yo ya mikanda kombo";
-const kTeststr_lo_Laoo = " àºàº«àº²àº—ົ່ວທັງເວັບ à»àº¥àº°à»ƒàº™à»€àº§àº±àºšà»„ຮ້ສາຠທຳອິດໃຫ້ທຳàºàº²àº™àºŠàº­àºàº«àº²àºà»ˆàº­àº™ ຈາàºàº™àº±à»‰àº™ ໃຫ້àºàº»àº”ປຸ່ມເມນູ ໃນໜ້າຜົນໄດ້";
-const kTeststr_lt_Latn = " a išsijungia mano idėja dėl geriausio laiko po pastarųjų savo santykių pasimokiau penki dalykai be kurių negaliu gyventi mano miegamajame tu surasi ideali pora išsilavinimas aukštoji mokykla koledžas universitetas pagrindinis laipsnis metai";
-const kTeststr_lv_Latn = " a gadskÄrtÄ“jÄ izpÄrdoÅ¡ana slÄ“poÅ¡ana jÄņi atlaide izmaiņas trafikÄ kas saistÄ«tas ar sezonas izpÄrdoÅ¡anu speciÄlajÄm atlaidÄ“m u c ir parastas un atslÄ“gvÄrdi kas ir populÄri noteiktos laika posmos Å¡ajÄ laikÄ saņems lielÄku klikÅ¡Ä·u";
-const kTeststr_mfe_Latn = "Anz dir mwa, Sa bann delo ki to trouve la, kot fam prostitie asize, samem bann pep, bann lafoul dimoun, bann nasion ek bann langaz. Sa dis korn ki to finn trouve, ansam avek bebet la, zot pou ena laenn pou prostitie la; zot pou pran tou seki li ena e met li touni, zot pou manz so laser e bril seki reste dan dife. Parski Bondie finn met dan zot leker proze pou realiz so plan. Zot pou met zot dakor pou sed zot pouvwar bebet la ziska ki parol Bondie fini realize.";
-const kTeststr_mg_Latn = " amporisihin i ianao mba hijery ny dika teksta ranofotsiny an ity lahatsoratra ity tsy ilaina ny opérateur efa karohina daholo ny teny rehetra nosoratanao ampiasao anaovana dokambarotra i google telugu datin ny takelaka fikarohana sary renitakelak i";
-const kTeststr_mi_Latn = " haere ki te kainga o o haere ki te kainga o o haere ki te kainga o te rapunga ahua o haere ki te kainga o ka tangohia he ki to rapunga kaore au mohio te tikanga whakatiki o te ra he whakaharuru te pai rapunga a te rapunga ahua a e kainga o nga awhina o te";
-const kTeststr_mk_Cyrl = " глаÑовите коалицијата на вмро дпмне како партија Ñо најмногу оÑвоени глаÑови ќе добие евра а на Ñметката на коализијата за македонија";
-const kTeststr_ml_Mlym = " à´‚ à´…à´™àµà´™à´¨àµ† à´žà´™àµà´™à´³àµ അവരàµà´Ÿàµ† à´®àµà´®àµà´ªà´¿à´²àµ നിനàµà´¨àµ ഔടàµà´‚ ഉടനെ നിങàµà´™à´³àµ പതിയിരിപàµà´ªà´¿à´²àµ നിനàµà´¨àµ à´Žà´´àµà´¨àµà´¨àµ‡à´±àµà´±àµ";
-const kTeststr_mn_Cyrl = " а боловÑронгуй болгох орон нутгийн ажил үйлÑийг уÑлдуулж зохицуулах дүрÑм журам боловÑруулах орон нутгийн өмч хөрөнгө Ñанхүүгийн";
-const kTeststr_mn_Mong = "ᠦᠭᠡ ᠵᠢᠨ ᠴᠢᠨᠭ᠎ᠠ ᠬᠦᠨᠳᠡᠢ ᠵᠢ ᠢᠯᠭᠠᠬᠣ";
-const kTeststr_mr_Deva = "हैदराबाद उचà¥à¤šà¤¾à¤° à¤à¤•à¤¾ (सहायà¥à¤¯Â·à¤®à¤¾à¤¹à¤¿à¤¤à¥€)तेलà¥à¤—ू: హైదరాబాదౠ, उरà¥à¤¦à¥‚: حیدر آباد हे भारतातील आंधà¥à¤° पà¥à¤°à¤¦à¥‡à¤¶ राजà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ राजधानीचे शहर आहे. हैदराबादची लोकसंखà¥à¤¯à¤¾ ७७ लाख ४० हजार ३३४ आहे. मोतà¥à¤¯à¤¾à¤‚चे शहर अशी à¤à¤•à¥‡à¤•à¤¾à¤³à¥€ ओळख असलेलà¥à¤¯à¤¾ या शहराला à¤à¤¤à¤¿à¤¹à¤¾à¤¸à¤¿à¤•, सांसà¥à¤•à¥ƒà¤¤à¤¿à¤• आणि सà¥à¤¥à¤¾à¤ªà¤¤à¥à¤¯à¤¶à¤¾à¤¸à¥à¤¤à¥à¤°à¥€à¤¯ वारसा लाभला आहे. १९९० नंतर शिकà¥à¤·à¤£ आणि माहिती तंतà¥à¤°à¤œà¥à¤žà¤¾à¤¨ तà¥à¤¯à¤¾à¤šà¤ªà¥à¤°à¤®à¤¾à¤£à¥‡ औषधनिरà¥à¤®à¤¿à¤¤à¥€ आणि जैवतंतà¥à¤°à¤œà¥à¤žà¤¾à¤¨ कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤¤à¥€à¤² उदà¥à¤¯à¥‹à¤—धंदà¥à¤¯à¤¾à¤‚ची वाढ शहरात à¤à¤¾à¤²à¥€. दकà¥à¤·à¤¿à¤£ मधà¥à¤¯ भारतातील परà¥à¤¯à¤Ÿà¤¨ आणि तेलà¥à¤—ू चितà¥à¤°à¤ªà¤Ÿà¤¨à¤¿à¤°à¥à¤®à¤¿à¤¤à¥€à¤šà¥‡ हैदराबाद हे केंदà¥à¤° आहे";
-// From 10% testing part of new lang=ms scrape
-const kTeststr_ms_Latn = "pengampunan beramai-ramai supaya mereka pulang ke rumah masing-masing. Orang-orang besarnya enggan mengiktiraf sultan yang dilantik oleh Belanda sebagai Yang DiPertuan Selangor. Orang ramai pula tidak mahu menjalankan perniagaan bijih timah dengan Belanda, selagi raja yang berhak tidak ditabalkan. Perdagang yang lain dibekukan terus kerana untuk membalas jasa beliau yang membantu Belanda menentang Riau, Johor dan Selangor. Di antara tiga orang Sultan juga dipandang oleh rakyat sebagai seorang sultan yang paling gigih. 1 | 2 SULTAN Sebagai ganti Sultan Ibrahim ditabalkan Raja Muhammad iaitu Raja Muda. Walaupun baginda bukan anak isteri pertama bergelar Sultan Muhammad bersemayam di Kuala Selangor juga. Pentadbiran baginda yang lemah itu menyebabkan Kuala Selangor menjadi sarang ioleh Cina di Lukut tidak diambil tindakan, sedangkan baginda sendiri banyak berhutang kepada 1";
-
-const kTeststr_ms_Latn2 = "bilik sebelah berkata julai pada pm ladymariah hmm sume ni terpulang kepada individu mungkin anda bernasib baik selama ini dalam membeli hp yang bagus deli berkata julai pada pm walaupun bukan bahsa baku tp tetap bahasa melayu kan perubahan boleh dibuat";
-const kTeststr_mt_Latn = " ata ikteb messaġġ lil indirizzi differenti billi tagħżilhom u tagħfas il buttuna ikteb żid numri tfittxijja tal kotba mur print home kotba minn pagni ghal pagna minn ghall ktieb ta aċċessa stieden habib iehor grazzi it tim tal gruppi google";
-const kTeststr_my_Latn = " jyk ef oif gawgodcsifayvdrfhrnf bmawgrsm topf dsvj g mail tamumif avhvm atmif txjwgif yxrqhk avhvm efae m pwifavhvm ef ufkyfwdky help center odkyvmyg drsm ar avh dswjhar cgef rsm udkawdkifygw f tajzawgudk smedkifygw f jyd awmh g mail cool features rsm";
-const kTeststr_my_Mymr = " á€á€€á€¹á€€á€žá€¯á€­á€œá€¹ မ္ဟ ပ္ရန္ လာ္ရပီးေနာက္ န္ဟစ္ အရ္á€á€šá€¹ ဦးသန္ ့သည္ ပန္ းá€á€”ော္ အမ္ယုိးသား ေက္ယာင္ း";
-const kTeststr_na_Latn = " arcol obabakaen riringa itorere ibibokiei ababaro min kuduwa airumena baoin tokin rowiowet itiket keram damadamit eigirow etoreiy row keitsito boney ibingo itsiw dorerin naoerodelaporte s nauruan dictionary a c a c d g h o p s t y aiquen ion eins aiquen";
-const kTeststr_ne_Deva = "अरू ठाऊà¤à¤¬à¤¾à¤Ÿà¤ªà¤¨à¤¿ खà¥à¤²à¥‡à¤•à¥‹ छ यो खाता अर अरू ठाऊà¤à¤¬à¤¾à¤Ÿà¤ªà¤¨à¤¿ खà¥à¤²à¥‡à¤•à¥‹ छ यो खाता अर ू";
-const kTeststr_nl_Latn = " a als volgt te werk om een configuratiebestand te maken sitemap gen py ebruik filters om de s op te geven die moeten worden toegevoegd of uitgesloten op basis van de opmaaktaal elke sitemap mag alleen de s bevatten voor een bepaalde opmaaktaal dit";
-const kTeststr_nn_Latn = " a for verktylina til å hjelpa deg å nå oss merk at pagerank syninga ikkje automatisk kjem til å henta inn informasjon frå sider med argument dvs frå sider med eit i en dersom datamaskina di er plassert bak ein mellomtenar for vevsider kan det verka";
-const kTeststr_no_Latn = " a er obligatorisk tidsforskyvning plassering av katalogsøk planinformasjon loggfilbane gruppenavn kontoinformasjon passord domene gruppeinformasjon alle kampanjesporing alternativ bruker grupper oppgaveplanlegger oppgavehistorikk kontosammendrag antall";
-const kTeststr_nr_Latn = "ikomiti elawulako yegatja emhlanganweni walo ]imithetho mgomo ye anc ibekwa malunga wayo begodu ubudosiphambili kugandelela lokho okutjhiwo yi lokha nayithi abantu ngibo ";
-
-const kTeststr_nso_Latn = "Bophara bja Asia ekaba 8.6% bja lefase goba 29.4% bja naga ya lefase (ntle le mawatle). Asia enale badudu bao bakabago dimillione millione tše nne (4 billion) yeo e bago 60% ya badudi ba lefase ka bophara. A bapolelwa rena sefapanong mehleng ya Pontius Pilatus. A hlokofatšwa, A bolokwa, A tsoga ka letšatši la boraro, ka mo mangwalo a bolelago ka gona, a rotogela magodimong, ";
-const kTeststr_ny_Latn = "Boma ndi gawo la dziko lomwe linapangidwa ndi cholinga chothandiza ntchito yolamulira. Kuŵalako kulikuunikabe mandita, Edipo nyima unalephera kugonjetsa kuŵalako.";
-const kTeststr_oc_Latn = " Pasmens, la classificacion pus admesa uei (segon Juli Ronjat e Pèire Bèc) agropa lei parlars deis Aups dins l'occitan vivaroaupenc e non dins lo dialècte provençau.";
-const kTeststr_om_Latn = " afaan katalaa bork bork bork hiikaa jira hin argamne gareen barbaadame hin argamne gargarsa qube en gar bayee jira garee walitti firooman gareewwan walitti firooman fuula web akka tartiiba qubeetiin agarsiisi akka tartiiba qubeetiin agarsiisaa jira akka";
-const kTeststr_or_Orya = "ଅକà­à¬Ÿà­‹à¬¬à¬° ଡିସେମà­à¬¬à¬°";
-const kTeststr_pa_Guru = " ਂ ਦਿਨਾਂ ਵਿਚ ਭਾਈ ਸਾਹਿਬ ਦੀ ਬà©à©±à¨šà©œ ਗੋਬਿੰਦ ਰਾਮ ਨਾਲ ਅੜਫਸ ਚੱਲ ਰਹੀ ਸੀ ਗੋਬਿੰਦ ਰਾਮ ਨੇ ਭਾਈ ਸਾਹਿਬ ਦੀਆਂ ਭੈਣਾ";
-const kTeststr_pl_Latn = " a australii będzie widział inne reklamy niż użytkownik z kanady kierowanie geograficzne sprawia że reklamy są lepiej dopasowane do użytkownika twojej strony oznacza to także że możesz nie zobaczyć wszystkich reklam które są wyświetlane na";
-const kTeststr_ps_Arab = " اتو مستقل رياست جوړ شو او د پخواني ادبي انجمن Ú…Ø§Ù†Ú«Û Ø¯Ø¯Û Ø±ÙŠØ§Ø³Øª جز شوی او Ø¯Ø¯Û Ø§Ù†Ø¬Ù…Ù† د Ú˜Ø¨Û Ù…Ø¯ÙŠØ±ÙŠØª د پښتو Ù¼ÙˆÙ„Ù†Û Ù¾Ù‡ لوی مديريت واوښت لوی مدير ÙŠÛ Ø¯";
-const kTeststr_pt_Latn = " a abit prevê que a entrada desses produtos estrangeiros no mercado têxtil e vestuário do brasil possa reduzir os preços em cerca de a partir de má notícia para os empresários que terão que lutar para garantir suas margens de lucro mas boa notícia";
-const kTeststr_qu_Latn = " is t ipanakunatapis rikuchinankupaq qanpa simiykipi noqaykoqpa uya jllanakunamanta kunan jamoq simikunaman qelqan tiyan watukuy qpa uyata qanpa llaqtaykipi llank anakuna simimanta yanapakuna simimanta mayqen llaqtallapis kay simimanta t ijray qpa qelqa";
-const kTeststr_rm_Latn = " Cur ch’il chantun Turitg ha dà il dretg da votar a las dunnas (1970) è ella vegnida elegida en il cussegl da vischnanca da Zumikon per la Partida liberaldemocratica svizra (PLD). Da 1974 enfin 1982 è ella stada presidenta da vischnanca da Zumikon. L’onn 1979 è Elisabeth Kopp vegnida elegida en il Cussegl naziunal e reelegida quatter onns pli tard cun in resultat da sur 100 000 vuschs. L’onn 1984 è ella daventada vicepresidenta da la PLD.";
-const kTeststr_rn_Latn = " ishaka mu ndero y abana bawe ganira n abigisha nimba hari ingorane izo ari zo zose ushobora gusaba kubonana n umwigisha canke kuvugana nawe kuri terefone inyuma y uko babarungikira urutonde rw amanota i muhira mu bisanzwe amashure aratumira abavyeyi";
-const kTeststr_ro_Latn = " a anunţurilor reţineţi nu plătiţi pentru clicuri sau impresii ci numai atunci când pe site ul dvs survine o acţiune dorită site urile negative nu pot avea uri de destinaţie daţi instrucţiuni societăţii dvs bancare sau constructoare să";
-const kTeststr_ro_Cyrl = "Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ñ Ð° органелор ши инÑтитуциилор екзекутиве ши а органелор жудичиаре але путерий де Ñтат фиекÑруй орган ал путерий де Ñтат и Ñе";
-const kTeststr_ru_Cyrl = " а неправильный формат идентификатора дн назад";
-const kTeststr_rw_Latn = " dore ibyo ukeneye kumenya ukwo watubona ibibazo byinshi abandi babaza ububonero byibibina google onjela ho izina dyikyibina kyawe onjela ho yawe mulugo kulaho ibyandiko byawe shyilaho tegula yawe tulubaka tukongeraho iyanya mishya buliko tulambula";
-const kTeststr_sa_Deva = " ं क रà¥à¤®à¤£à¤¸à¥ त सà¥à¤¯ य तà¥à¤•à¤¿ ङà¥à¤šà¥‡à¤¹ करो तà¥à¤¯à¤¯ ं त सà¥à¤®à¤¾à¤²à¥ लोका तà¥à¤ªà¥ नरै ति असà¥à¤®à¥ˆ लोका य क रà¥à¤®à¤£ इ ति नॠकाम";
-const kTeststr_sa_Latn = " brahmÄ tatraivÄntaradhÄ«yata tataḥ saÅ›iá¹£yo vÄlmÄ«kir munir vismayam Äyayau tasya Å›iá¹£yÄs tataḥ sarve jaguḥ Å›lokam imaṃ punaḥ muhur muhuḥ prÄ«yamÄṇÄḥ prÄhuÅ› ca bhṛśavismitÄḥ samÄká¹£araiÅ› caturbhir yaḥ pÄdair gÄ«to";
-const kTeststr_sco_Latn = " a gless an geordie runciman ower a gless an tamson their man preached a hale hoor aboot the glorious memories o forty three an backsliders an profane persons like esau an aboot jeroboam the son o nebat that gaed stravagin to anither kirk an made aa israel";
-const kTeststr_sd_Arab = " اضاÙÙˆ ٿي ٿيو پر اها خبر عثمان Ú©ÙŠ بعد پيئي ته سگريٽ ڇڪيندڙ مسلمان نه هو بلڪ هندو هو دڪان تي پهچي عثمان ڪسبت کولي گراهڪن جي سيرب لاهڻ شروع ڪئي پر";
-const kTeststr_sg_Latn = " atâa na âkotta zo me lâkwê angbâ gï tarrango nî âkotta zo tî koddoro nî âde agbû tenne nî na kate töngana mbênî kotta kpalle tî nzönî dutï tî halëzo pëpe atâa sô âla lü gbâ tî ândya tî mâi na sahngo asâra gbâ tî";
-const kTeststr_si_Sinh = " අනුරà·à¶° මිහිඳුකුල නමින් සකුර෠ට ලිපියක් තà·à¶´à·‘ලෙන් එව෠තිබුණ෠කි à·Š රස්ටි ෂෙල්ටන් ප à·Š රනà·à¶±à·Šà¶¯à·” ද";
-const kTeststr_sit_NP = " dialekten in de roerstreek pierre bakkes oet roerstreek blz bewirk waordebook zónjig oktoeaber is t ieëste mofers waordebook oetgekaome dit waordebook is samegestèldj";
-const kTeststr_sk_Latn = " a aktivovaÅ¥ reklamnú kampaň ak chcete kampaň pred spustením eÅ¡te prispôsobiÅ¥ uložte ju ako Å¡ablónu a pokraÄujte v úprave vyberte si jednu z možností nižšie a kliknite na tlaÄidlo uložiÅ¥ kampaň nastavenia kampane môžete ľubovoľne";
-const kTeststr_sl_Latn = " adsense stanje prijave za google adsense google adsense raÄun je bil zaÄasno zamrznjen pozdravljeni hvala za vaÅ¡e zanimanje v google adsense po pregledu vaÅ¡e prijavnice so naÅ¡i strokovnjaki ugotovili da spletna stran ki je trenutno povezana z vaÅ¡im";
-const kTeststr_sm_Latn = " autu mea o lo totonu le e le minaomia matou te tuu i totonu i le faamatalaina o le suesuega i taimi uma mea o lo totonu fuafua i mea e tatau fa afoi tala mai le newsgroup mataupu fa afoi mai tala e ai le mataupu e ai totonu tusitala o le itu o faamatalaga";
-const kTeststr_sn_Latn = " chete vanyori vanotevera vakabatsira kunyora zvikamu zvino kumba home tinyorere tsamba chikamu chakumbirwa hachina kuwanikwa chikamu ichi cheninge chakayiswa kuimwe nzvimbo mudhairekitori rino chimwe chikamu chopadhuze pane chinhu chatadza kushanda bad";
-const kTeststr_so_Latn = " a oo maanta bogga koobaad ugu qoran yahey beesha caalamka laakiin si kata oo beesha caalamku ula guntato soomaaliya waxa aan shaki ku jirin in aakhirataanka dadka soomaalida oo kaliya ay yihiin ku soomaaliya ka saari kara dhibka ay ku jirto";
-const kTeststr_sq_Latn = " a do të kërkoni nga beogradi që të njohë pavarësinë e kosovës zoti thaçi prishtina është gati ta njoh pavarësinë e serbisë ndërsa natyrisht se do të kërkohet një gjë e tillë që edhe beogradi ta njoh shtetin e pavarur dhe sovran të";
-const kTeststr_sr_Cyrl = "балчак балчак на мапи Ñрбије уреди демографија у наÑељу балчак живи пунолетна Ñтановника а проÑечна ÑтароÑÑ‚ Ñтановништва изноÑи година";
-const kTeststr_sr_Latn = "DruÅ¡tvo | Äetvrtak 1.08.2013 | 13:43 Krade se i izvorska voda Izvor: Gornji Milanovac -- U gružanskom selu Belo Polje proÅ¡le noći ukradeno je viÅ¡e od 10.000 litara kojima je obijen bazen. Bazen je bio zakljuÄan i propisno obezbeÄ‘en.";
-
-const kTeststr_sr_ME_Latn = "savjet pobjeda a radi bržeg rada poÅ¡to rom radi sporije nego ram izvorni rom se iskljuÄuje a dio ram a se rezerviÅ¡e te se u njega ne ploÄa procesor ram memorija grafiÄka kartica zvuÄna kartica modem mrežna kartica napojna jedinica ureÄ‘aji za pohranjivanje";
-const kTeststr_ss_Latn = " bakhokhintsela yesikhashana bafake imininingwane ye akhawunti leliciniso kulelifomu nangabe akukafakwa imininingwane leliciniso imali lekhokhiwe angeke ifakwe kumkhokhintsela lofanele imininingwane ye akhawunti ime ngalendlela lelandzelako inombolo";
-const kTeststr_st_Latn = " bang ba nang le thahasello matshwao a sehlooho thuto e thehilweng hodima diphetho ke tsela ya ho ruta le ho ithuta e totobatsang hantle seo baithuti ba lokelang ho se fihlella ntlhatheo eo e sebetsang ka yona ke ya hore titjhere o hlakisa pele seo";
-const kTeststr_su_Latn = "Nu ngatur kahirupan warga, keur kapentingan pamarentahan diatur ku RT, RW jeung Kepala Dusun, sedengkeun urusan adat dipupuhuan ku Kuncen jeung kepala adat. Sanajan Kampung Kuta teu pati anggang jeung lembur sejenna nu aya di wewengkon Desa Pasir Angin, tapi boh wangunan imah atawa tradisi kahirupan masarakatna nenggang ti nu lian.";
-const kTeststr_sv_Latn = " a bort objekt från google desktop post äldst meny öretag dress etaljer alternativ för vad är inne yaste google skrivbord plugin program för nyheter google visa nyheter som är anpassade efter de artiklar som du läser om du till exempel läser";
-const kTeststr_sw_Latn = " a ujumbe mpya jumla unda tafuta na angalia vikundi vya kujadiliana na kushiriki mawazo iliyopangwa kwa tarehe watumiaji wapya futa orodha hizi lugha hoja vishikanisho vilivyo dhaminiwa ujumbe sanaa na tamasha toka udhibitisho wa neno kwa haraka fikia";
-const kTeststr_syr_Syrc = "ÜܕܪÜÜ£ ܓܛܘ ܫܘܪÜÜ Ü¡Ü¢ Ü¦ÜªÜ¢Ü£Ü Ü¡Ü¢ ÜܣܦܢÜÜ ÜšÜÜªÜ˜Ü¬Ü Ü’Üܕܪ Ü’Ü¢Üܣܢ Ü«Ü›ÜÜšÜ˜Ü¬Ü ÜŸÜ Ü¢ÜÜ Ü¡ÜÌˆÜ Ü’Ü¥Ü Ü¡Ü";
-const kTeststr_ta_Taml = " à®…à®™à¯à®•à¯ ராஜேநà¯à®¤à®¿à®° சோழனால௠கடà¯à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ பிரமà¯à®®à®¾à®£à¯à®Ÿà®®à®¾à®© சிவன௠கோவில௠ஒனà¯à®±à¯à®®à¯ உளà¯à®³à®¤à¯ தொகà¯";
-const kTeststr_te_Telu = " ఠదనర జయించిన తతà±à°µ మరసి చూడఠదాన యగà±à°¨à± రాజయోగి యిటà±à°²à± తేజరిలà±à°²à±à°šà± à°¨à±à°‚డౠవిశà±à°µà°¦à°¾à°­à°¿à°°à°¾à°® వినర వేమ";
-const kTeststr_tg_Arab = "رادیو Ùردا راديوى آزادى";
-const kTeststr_tg_Cyrl = " адолат ва инÑондӯÑтиро бар фашизм нажодпараÑÑ‚Ó£ ва адоват тарҷеҳ додааÑÑ‚ чоп кунед ба дигарон фириÑтед чоп кунед ба дигарон фириÑтед";
-const kTeststr_th_Thai = " à¸à¸à¹ƒà¸™à¸à¸²à¸£à¸„้นหา หรือหน้าเนื้อหา หาà¸à¸—่านเลือà¸à¸¥à¸‡à¹‚ฆษณา ท่านอาจจะปรับต้องเพิ่มงบประมาณรายวันตา";
-const kTeststr_ti_Ethi = " ሃገር ተረáŽáˆ ዘለዉ ኢትዮጵያá‹á‹«áŠ• ኣብቲ áˆáˆµ ኢትዮጵያ á‹á‹³á‹á‰¥ ኣá‹áˆ«áŒƒ ደቡብ ንኽáŠá‰¥áˆ© ኣይáቀደሎáˆáŠ• እዩ ካብ ሃገር ንኽትወጽእ ዜጋ ኹን ወጻእተኛ ናይ";
-const kTeststr_tk_Cyrl = " айдÑнларына ынанÑрмыка Ñхли боз мейданлары Ñурулип гутарылан тебигы ота гарып гумлукларда миллиондан да артыкмач ири шахлы малы миллиона";
-const kTeststr_tk_Latn = " akyllylyk çyn söýgi üçin böwet däl de tebigylykdyr duýgularyň gödeňsiligi aç açanlygy bahyllygy söýgini betnyşanlyk derejesine düşürýändir söýeni söý söýmedige süýkenme özüni söýmeýändigini görmek ýigit üçin uly";
-const kTeststr_tl_Latn = " a na ugma sa google ay nakaka bantog sa gitna nang kliks na nangyayari sa pamamagitan nang ordinaryong paggagamit at sa kliks na likha nang pandaraya o hindi tunay na paggamit bunga nito nasasala namin ang mga kliks na hindi kailangan o hindi gusto nang";
-const kTeststr_tl_Tglg = " ᜋᜇ᜔ áœáœ“ᜎᜆ᜔ ᜃ ᜈᜅ᜔ ᜊᜌ᜔ᜊᜌᜒᜈ᜔ ᜂᜉᜅ᜔᜔ ᜋáœáœˆáœŒáœ” ᜎᜅ᜔ áœáœ ᜉᜅ᜔ ᜀᜃ᜔ᜎᜆ᜔ ᜆᜓᜅ᜔ᜃᜓᜎ᜔ ᜠᜊᜌ᜔ᜊᜌᜒᜈ᜔ ᜠᜆᜒᜅᜒᜈ᜔ ᜃᜓ";
-const kTeststr_tlh_Latn = " a ghuv bid soh naq jih lodni yisov chich wo vamvo qeylis lunge pu chah povpu vodleh a dah ghah cho ej dah wo che pujwi bommu tlhegh darinmohlahchu pu majqa horey so lom qa ip quv law may vad suvtahbogh wa sanid utlh quv pus datu pu a vitu chu pu johwi tar";
-const kTeststr_tn_Latn = " go etela batla ditsebe tsa web tse di nang le le batla ditsebe tse di golaganya le tswang mo leka go batla web yotlhe batla mo web yotlhe go bona home page ya google batla mo a o ne o batla gore a o ne o batla ditsebe tsa bihari batla mo re maswabi ga go";
-const kTeststr_to_Latn = " a ke kumi oku ikai ke ma u vakai ki hono hokohoko faka alafapeti api pe ko e uluaki peesi a ho o fekumi faka malatihi fekumi ki he lea oku fakaha atu pe ko ha fonua fekumi ki he fekumi ki he peesi oku ngaahi me a oku sai imisi alu ki he ki he ulu aki";
-const kTeststr_tr_Latn = " a ayarlarınızı görmeniz ve yönetmeniz içindir eğer kampanyanız için günlük bütçenizi gözden geçirebileceğiniz yeri arıyorsanız kampanya yönetimi ne gidin kampanyanızı seçin ve kampanya ayarlarını düzenle yi tıklayın sunumu";
-const kTeststr_ts_Latn = " a ku na timhaka leti nga ta vulavuriwa na google google yi hlonipha yi tlhela yi sirheleta vanhu hinkwavo lava tirhisaka google toolbar ku dyondza hi vusireleli eka system ya hina hi kombela u hlaya vusireleli bya hina eka toolbar mbulavulo wu tshikiwile";
-const kTeststr_tt_Cyrl = "ачарга да бирмәде чәт чәт килеп тора безнең абыйнымы олы абыйнымы Ñштән";
-const kTeststr_tt_Latn = " alarnı eşkärtü proğramnarın eşläwen däwam itü tatar söylämen buldıru wä sizep alu sistemnarın eşläwen däwat itü häm başqalar yılnıñ mayında tatar internetı ictimağıy oyışması milli ts isemle berençe däräcäle häm tat";
-const kTeststr_tw_Latn = " amammui tumidifo no bɛtow ahyɛ atoro som so mpofirim na wɔasɛe no pasaa ma ayɛ nwonwa dɛn na ɛbɛka wɔn ma wɔayɛ saa bible no ma ho mmuae wɔ adiyisɛm nhoma no mu sɛ onyankopɔn na ɔde hyɛɛ wɔn komam sɛ wɔmma ne nsusuwii mmra mu";
-const kTeststr_ug_Arab = " ئالەملەرنىڭ پەرۋەردىگارىدىن تىلەيمەن سىلەر بۇ يەرلەردە باغچىلاردىن بۇلاقلاردىن زىرائەتلەردىن يۇمشاق پىشقان خورمىلاردىن بەھرىمەن بولۇپ";
-const kTeststr_ug_Cyrl = " а башлиди әмма бу қетимқи канада мәтбуатлириниң хәвәрлиридә илгирикидәк хитай һөкүмәт мәтбуатлиридин нәқил алидиған вә уни көчүрүп";
-const kTeststr_ug_Latn = " adawet bolghachqa hazir musherrepmu bu ikki partiyining birleshme hökümet qurushta pikir birliki hasil qilalmasliqini kütüwatqan iken wehalenki pakistan xelq partiyisining rehbiri asif eli zerdari pakistandiki bashqa ushshaq partiyilerning rehberliri";
-const kTeststr_uk_Cyrl = " а більший бюджет щоб забезпечити Ñобі макÑимум прибутків від переходів відÑтежуйте Ñвої об Ñви за датою географічним розташуваннÑм";
-const kTeststr_ur_Arab = " آپ Ú©Ùˆ Ú©Ù… سے Ú©Ù… Ù…Ù…Ú©Ù†Û Ø±Ù‚Ù… چارج کرتا ÛÛ’ اس Ú©ÛŒ مثال Ú©Û’ طور پر Ùرض کریں اگر آپ Ú©ÛŒ Ø²ÛŒØ§Ø¯Û Ø³Û’ Ø²ÛŒØ§Ø¯Û Ù‚ÛŒÙ…Øª ÙÛŒ Ú©Ù„ÙÚ© امریکی ڈالر اور Ú©Ù„ÙÚ© کرنے Ú©ÛŒ شرح ÛÙˆ تو";
-const kTeststr_uz_Arab = " آرقلی بوتون سیاسی حزب Ùˆ گروه لرÙعالیتیگه رخصت بیرگن اخبارات واسطه لری شو ییل مدتیده مثال سیز ترقی تاپکن Ùˆ اهالی نینگ اقتصادی وضعیتی اوتمیش";
-const kTeststr_uz_Cyrl = " а гапирадиган бўлÑак бунинг иккита йўли бор биринчиÑи мана шу қуриган Ñатҳини қумликларни тўхтатиш учун Ñкотизимни муÑтаҳкамлаш қумга";
-const kTeststr_uz_Latn = " abadiylashtirildi aqsh ayol prezidentga tayyormi markaziy osiyo afg onistonga qanday yordam berishi mumkin ukrainada o zbekistonlik muhojirlar tazyiqdan shikoyat qilmoqda gruziya va ukraina hozircha natoga qabul qilinmaydi afg oniston o zbekistonni g";
-const kTeststr_ve_Latn = "Vho ṱanganedzwa kha Wikipedia nga tshiVenḓa. Vhadivhi vha manwalo a TshiVenda vha talusa divhazwakale na vhubvo ha Vhavenda ngau fhambana. Vha tikedza mbuno dzavho uya nga mawanwa a thoduluso dze vha ita. Vhanwe vha vhatodulusi vhari Vhavenda vho tumbuka Afrika vhukati vha tshimbila vha tshiya Tshipembe ha Afrika, Rhodesia hune ha vho vhidzwa Zimbagwe namusi.";
-const kTeststr_vi_Latn = " adsense cho nội dung nhaÌ€ cung câÌp diÌ£ch vuÌ£ di động xaÌc minh tiÌn duÌ£ng thay đổi nhãn kg caÌc ô xem chi phiÌ cho tÆ°Ì€ chôÌi caÌc Ä‘Æ¡n đặt haÌ€ng daÌ£ng câÌp dữ liệu aÌc minh trang web của baÌ£n để xem";
-const kTeststr_vo_Latn = " brefik se volapükavol nüm balid äpubon ün dü lif lölik okas redakans älaipübons gasedi at nomöfiko äd ai mu kuratiko pläo timü koup nedäna fa ns deutän kü päproibon fa koupanef me gased at ästeifülom ad propagidön volapüki as sam ün";
-const kTeststr_war_Latn = "Amo ini an balay han Winaray o Binisaya nga Lineyte-Samarnon nga Wikipedia, an libre ngan gawasnon nga ensayklopedya nga bisan hin-o puyde magliwat o mag-edit. An Wikipedia syahan gintikang ha Iningles nga yinaknan han tuig 2001. Ini nga bersyon Winaray gintikang han ika-25 han Septyembre 2005 ngan ha yana mayda 514,613 nga artikulo. Kon karuyag niyo magsari o magprobar, pakadto ha . An Gastrotheca pulchra[2] in uska species han Anura nga ginhulagway ni Ulisses Caramaschi ngan Rodrigues hadton 2007. An Gastrotheca pulchra in nahilalakip ha genus nga Gastrotheca, ngan familia nga Hemiphractidae.[3][4] Ginklasipika han IUCN an species komo kulang hin datos.[1] Waray hini subspecies nga nakalista.[3]";
-const kTeststr_wo_Latn = " am ak dëgg dëggam ak gëm aji bind ji te gëstu ko te jëfandikoo tegtalu xel ci saxal ko sokraat nag jëfandikoo woon na xeltu ngir tas jikko yu rafet ci biir nit ñi ak dëggu ak soppante sokraat nag ñëw na mook aflaton platon sukkandiku ci ñaari";
-const kTeststr_xh_Latn = " a naynga zonke futhi libhengezwa kwiwebsite yebond yasemzantsi afrika izinga elisebenzayo xa usenza olu tyalo mali liya kusebenza de liphele ixesha lotyalo mali lwakho inzala ihlawulwa rhoqo emva kweenyanga ezintandathu ngomhla wamashumi amathathu ananye";
-const kTeststr_xx_Bugi = "ᨄᨛᨑᨊᨒ ᨑᨗ ᨔᨒᨗᨓᨛ ᨕᨗᨋᨗᨔᨗ ᨒᨛᨄ ᨑᨛᨔᨛᨆᨗᨊ";
-const kTeststr_xx_Goth = "ðŒ° ðŒ°ðŒ±ð‚ðŒ°ðŒ·ðŒ°ðŒ¼ ðŒ°ðŒ²ðŒ²ðŒ¹ðŒ»ðŒ¹ðƒðŒºðƒ ðŒ¸ðŒ¹ðŒ¿ðŒ³ðŒ¹ðƒðŒºðƒ ð†ð‚ðŒ°ðŒ²ðŒºðŒ¹ðƒðŒºðƒ";
-const kTeststr_yi_Hebr = "×ון פ×נט××–×™×¢ ער ××™×– ב×ק×נט ×¦×™× ×ž×¢×¨×¡×˜×Ÿ פ×ר ×–×™×™× ×¢ ב×ַל×ַדעס ער ×”×ָט געוווינט ×ין וו×רשע יעס פ×ריס ליווערפול ×ון ל×נד×ן סוף כל סוף ××™×– ער";
-const kTeststr_yo_Latn = " abinibi han ikawe alantakun le ni opolopo ede abinibi ti a to lesese bi eniyan to fe lo se fe lati se atunse jowo mo pe awon oju iwe itakunagbaye miran ti ako ni oniruru ede abinibi le faragba nipa atunse ninu se iwadi blogs ni ori itakun agbaye ti e ba";
-const kTeststr_za_Hani = " 两个宾语的字数较少时 åªå¸¦ä¸€ä¸ªåŠ¨è¯ å¦åˆ™å°±å¸¦ä¸¤ä¸ªåŠ¨è¯ 三å¥å­ç±» 从å¥å­æ–¹é¢åŽ»è°ˆæ±‰ 壮语结构格å¼ç›¸å¼‚的类型的 å«å¥å­ç±» 汉 壮语中 å¥å­ç±»ç»“æž„æ ¼å¼æœ‰å·®åˆ«çš„自然ä¸å°‘";
-const kTeststr_za_Latn = " dih yinzminz ndaej daengz bujbienq youjyau dih cingzyin caeuq cinhingz diuz daihit boux boux ma daengz lajmbwn couh miz cwyouz cinhyenz caeuq genzli bouxboux bingzdaengj gyoengq vunz miz lijsing caeuq liengzsim wngdang daih gyoengq de lumj beixnuengx";
-const kTeststr_zh_Hans = "产å“的简报和公告 æ交该申请åŽæ— æ³•è¿›è¡Œæ›´æ”¹ 请确认您的选择是正确的 对于è¦æ交的图书 我确认 我是版æƒæ‰€æœ‰è€…或已得到版æƒæ‰€æœ‰è€…çš„æŽˆæƒ è¦æ›´æ”¹æ‚¨çš„国家 地区 请在此表的最上端更改您的";
-const kTeststr_zh_Hant = " 之å‰ç‚º å¸³å–®äº¤æ˜“ä½œæ¥­å€ å·²è®Šæ›´ 廣告內容 之å‰ç‚º 銷售代表 之å‰ç‚º 張貼日期為 百分比之å‰ç‚º åˆç´„ 為 目標å°è±¡æ¢ä»¶å·²åˆªé™¤ çµæŸæ—¥æœŸä¹‹å‰ç‚º";
-const kTeststr_zu_Latn = " ana engu uma inkinga iqhubeka siza ubike kwi isexwayiso ngenxa yephutha lomlekeleli sikwazi ukubuyisela emuva kuphela imiphumela engaqediwe ukuthola imiphumela eqediwe zama ukulayisha kabusha leli khasi emizuzwini engu uma inkinga iqhubeka siza uthumele";
-const kTeststr_zzb_Latn = "becoose a ve a leemit qooereees tu vurds um gesh dee bork bork nu peges vere a fuoond cunteeening is a fery cummun vurd und ves nut inclooded in yuoor seerch zee ooperetur is unnecessery ve a incloode a ell seerch terms by deffoolt um de hur de hur de hur";
-const kTeststr_zze_Latn = " a diffewent type of seawch send feedback about google wiwewess seawch to wap google com wesuwts found on de entiwe web fow wesuwts found on de mobiwe web fow de functionawity of de toolbar up button has been expanded swightwy it now considews fow exampwe";
-const kTeststr_zzh_Latn = " b x z un b e t und rs n a dr ss p as ry an th r a dr ss ry us n a l ss mb gu us c ti n l ke a z p c d n a dr ss nt r d pl as en r n a dr ss y ur s ar h f r n ar d d n t m tch ny l c ti n w th n m l s nd m r r at d p g s th l c ti ns b l w w r ut m t ca y";
-const kTeststr_zzp_Latn = " away ackupbay editcray ardcay ybay isitingvay ouryay illingbay eferencespray agepay orway isitvay ethay adwordsway elphay entrecay orfay oremay etailsday adwordsway ooglegay omcay upportsay";
-
-// Two very close Wikipedia page beginnings
-const kTeststr_ms_close = "sukiyaki wikipedia bahasa melayu ensiklopedia bebas sukiyaki dari wikipedia bahasa melayu ensiklopedia bebas lompat ke navigasi gelintar sukiyaki sukiyaki hirisan tipis daging lembu sayur sayuran dan tauhu di dalam periuk besi yang dimasak di atas meja makan dengan cara rebusan sukiyaki dimakan dengan mence";
-const kTeststr_id_close = "sukiyaki wikipedia indonesia ensiklopedia bebas berbahasa bebas berbahasa indonesia langsung ke navigasi cari untuk pengertian lain dari sukiyaki lihat sukiyaki irisan tipis daging sapi sayur sayuran dan tahu di dalam panci besi yang dimasak di atas meja makan dengan cara direbus sukiyaki dimakan dengan mence";
-
-// Simple intermixed French/English text
-const kTeststr_fr_en_Latn = "France is the largest country in Western Europe and the third-largest in Europe as a whole. " +
- "A accès aux chiens et aux frontaux qui lui ont été il peut consulter et modifier ses collections et exporter " +
- "Cet article concerne le pays européen aujourd’hui appelé République française. Pour d’autres usages du nom France, " +
- "Pour une aide rapide et effective, veuiller trouver votre aide dans le menu ci-dessus." +
- "Motoring events began soon after the construction of the first successful gasoline-fueled automobiles. The quick brown fox jumped over the lazy dog";
-
-// This can be used to cross-check the build date of the main quadgram table
-const kTeststr_version = "qpdbmrmxyzptlkuuddlrlrbas las les qpdbmrmxyzptlkuuddlrlrbas el la qpdbmrmxyzptlkuuddlrlrbas";
-
-const kTestPairs = [
-// A simple case to begin
- ["en", "ENGLISH", kTeststr_en],
-
-// 20 languages recognized via Unicode script
- ["hy", "ARMENIAN", kTeststr_hy_Armn],
- ["chr", "CHEROKEE", kTeststr_chr_Cher],
- ["dv", "DHIVEHI", kTeststr_dv_Thaa],
- ["ka", "GEORGIAN", kTeststr_ka_Geor],
- ["el", "GREEK", kTeststr_el_Grek],
- ["gu", "GUJARATI", kTeststr_gu_Gujr],
- ["iu", "INUKTITUT", kTeststr_iu_Cans],
- ["kn", "KANNADA", kTeststr_kn_Knda],
- ["km", "KHMER", kTeststr_km_Khmr],
- ["lo", "LAOTHIAN", kTeststr_lo_Laoo],
- ["lif", "LIMBU", kTeststr_lif_Limb],
- ["ml", "MALAYALAM", kTeststr_ml_Mlym],
- ["or", "ORIYA", kTeststr_or_Orya],
- ["pa", "PUNJABI", kTeststr_pa_Guru],
- ["si", "SINHALESE", kTeststr_si_Sinh],
- ["syr", "SYRIAC", kTeststr_syr_Syrc],
- ["tl", "TAGALOG", kTeststr_tl_Tglg], // Also in quadgram list below
- ["ta", "TAMIL", kTeststr_ta_Taml],
- ["te", "TELUGU", kTeststr_te_Telu],
- ["th", "THAI", kTeststr_th_Thai],
-
-// 4 languages regognized via single letters
- ["zh", "CHINESE", kTeststr_zh_Hans],
- ["zh-Hant", "CHINESET", kTeststr_zh_Hant],
- ["ja", "JAPANESE", kTeststr_ja_Hani],
- ["ko", "KOREAN", kTeststr_ko_Hani],
-
-// 60 languages recognized via combinations of four letters
- ["af", "AFRIKAANS", kTeststr_af_Latn],
- ["sq", "ALBANIAN", kTeststr_sq_Latn],
- ["ar", "ARABIC", kTeststr_ar_Arab],
- ["az", "AZERBAIJANI", kTeststr_az_Latn],
- ["eu", "BASQUE", kTeststr_eu_Latn],
- ["be", "BELARUSIAN", kTeststr_be_Cyrl],
- ["bn", "BENGALI", kTeststr_bn_Beng], // No Assamese in subset
- ["bh", "BIHARI", kTeststr_bh_Deva],
- ["bg", "BULGARIAN", kTeststr_bg_Cyrl],
- ["ca", "CATALAN", kTeststr_ca_Latn],
- ["ceb", "CEBUANO", kTeststr_ceb_Latn],
- ["hr", "CROATIAN", kTeststr_hr_Latn, [false, 0, "el", 4]],
- ["cs", "CZECH", kTeststr_cs_Latn],
- ["da", "DANISH", kTeststr_da_Latn],
- ["nl", "DUTCH", kTeststr_nl_Latn],
- ["en", "ENGLISH", kTeststr_en_Latn],
- ["et", "ESTONIAN", kTeststr_et_Latn],
- ["fi", "FINNISH", kTeststr_fi_Latn],
- ["fr", "FRENCH", kTeststr_fr_Latn],
- ["gl", "GALICIAN", kTeststr_gl_Latn],
- ["lg", "GANDA", kTeststr_lg_Latn],
- ["de", "GERMAN", kTeststr_de_Latn],
- ["ht", "HAITIAN_CREOLE", kTeststr_ht_Latn],
- ["he", "HEBREW", kTeststr_he_Hebr],
- ["hi", "HINDI", kTeststr_hi_Deva],
- ["hmn", "HMONG", kTeststr_blu_Latn],
- ["hu", "HUNGARIAN", kTeststr_hu_Latn],
- ["is", "ICELANDIC", kTeststr_is_Latn],
- ["id", "INDONESIAN", kTeststr_id_Latn],
- ["ga", "IRISH", kTeststr_ga_Latn],
- ["it", "ITALIAN", kTeststr_it_Latn],
- ["jw", "JAVANESE", kTeststr_jw_Latn],
- ["rw", "KINYARWANDA", kTeststr_rw_Latn],
- ["lv", "LATVIAN", kTeststr_lv_Latn],
- ["lt", "LITHUANIAN", kTeststr_lt_Latn],
- ["mk", "MACEDONIAN", kTeststr_mk_Cyrl],
- ["ms", "MALAY", kTeststr_ms_Latn],
- ["mt", "MALTESE", kTeststr_mt_Latn],
- ["mr", "MARATHI", kTeststr_mr_Deva, [false, 0, "te", 3]],
- ["ne", "NEPALI", kTeststr_ne_Deva],
- ["no", "NORWEGIAN", kTeststr_no_Latn],
- ["fa", "PERSIAN", kTeststr_fa_Arab],
- ["pl", "POLISH", kTeststr_pl_Latn],
- ["pt", "PORTUGUESE", kTeststr_pt_Latn],
- ["ro", "ROMANIAN", kTeststr_ro_Latn],
- ["ro", "ROMANIAN", kTeststr_ro_Cyrl],
- ["ru", "RUSSIAN", kTeststr_ru_Cyrl],
- ["gd", "SCOTS_GAELIC", kTeststr_gd_Latn],
- ["sr", "SERBIAN", kTeststr_sr_Cyrl],
- ["sr", "SERBIAN", kTeststr_sr_Latn],
- ["sk", "SLOVAK", kTeststr_sk_Latn],
- ["sl", "SLOVENIAN", kTeststr_sl_Latn],
- ["es", "SPANISH", kTeststr_es_Latn],
- ["sw", "SWAHILI", kTeststr_sw_Latn],
- ["sv", "SWEDISH", kTeststr_sv_Latn],
- ["tl", "TAGALOG", kTeststr_tl_Latn],
- ["tr", "TURKISH", kTeststr_tr_Latn],
- ["uk", "UKRAINIAN", kTeststr_uk_Cyrl],
- ["ur", "URDU", kTeststr_ur_Arab],
- ["vi", "VIETNAMESE", kTeststr_vi_Latn],
- ["cy", "WELSH", kTeststr_cy_Latn],
- ["yi", "YIDDISH", kTeststr_yi_Hebr],
-
- // Added 2013.08.31 so-Latn ig-Latn ha-Latn yo-Latn zu-Latn
- ["so", "SOMALI", kTeststr_so_Latn],
- ["ig", "IGBO", kTeststr_ig_Latn],
- ["ha", "HAUSA", kTeststr_ha_Latn],
- ["yo", "YORUBA", kTeststr_yo_Latn],
- ["zu", "ZULU", kTeststr_zu_Latn],
- // Added 2014.01.22 bs-Latn
- ["bs", "BOSNIAN", kTeststr_bs_Latn],
-
-// 2 statistically-close languages
- ["id", "INDONESIAN", kTeststr_id_close, [true, 80], []],
- ["ms", "MALAY", kTeststr_ms_close],
-
-// Simple intermixed French/English text
- ["fr", "FRENCH", kTeststr_fr_en_Latn, [false, 80, "en", 32]],
-
-// Cross-check the main quadgram table build date
-// Change the expected language each time it is rebuilt
- ["az", "AZERBAIJANI", kTeststr_version] // 2014.01.31
-];
-
-Components.utils.import("resource://gre/modules/Timer.jsm");
-let detectorModule = Components.utils.import("resource:///modules/translation/LanguageDetector.jsm");
-
-function check_result(result, langCode, expected) {
- equal(result.language, langCode, "Expected language code");
-
- // Round percentage up to the nearest 5%, since most strings are
- // detected at slightly less than 100%, and we don't want to
- // encode each exact value.
- let percent = result.languages[0].percent;
- percent = Math.ceil(percent / 20) * 20;
-
- equal(result.languages[0].languageCode, langCode, "Expected first guess language code");
- equal(percent, expected[1] || 100, "Expected first guess language percent");
-
- if (expected.length < 3) {
- // We're not expecting a second language.
- equal(result.languages.length, 1, "Expected only one language result");
- } else {
- equal(result.languages.length, 2, "Expected two language results");
-
- equal(result.languages[1].languageCode, expected[2], "Expected second guess language code");
- equal(result.languages[1].percent, expected[3], "Expected second guess language percent");
- }
-
- equal(result.confident, !expected[0], "Expected confidence");
-}
-
-add_task(function* test_pairs() {
- for (let item of kTestPairs) {
- let params = [item[2],
- { text: item[2], tld: "com", language: item[0], encoding: "utf-8" }]
-
- for (let [i, param] of params.entries()) {
- // For test items with different expected results when using the
- // language hint, use those for the hinted version of the API.
- // Otherwise, fall back to the first set of expected values.
- let expected = item[3 + i] || item[3] || [];
-
- let result = yield LanguageDetector.detectLanguage(param);
- check_result(result, item[0], expected);
- }
- }
-});
-
-// Test that the worker is flushed shortly after processing a large
-// string.
-add_task(function* test_worker_flush() {
- let test_string = kTeststr_fr_en_Latn;
- let test_item = kTestPairs.find(item => item[2] == test_string);
-
- // Set shorter timeouts and lower string lengths to make things easier
- // on the test infrastructure.
- detectorModule.LARGE_STRING = test_string.length - 1;
- detectorModule.IDLE_TIMEOUT = 1000;
-
- equal(detectorModule.workerManager._idleTimeout, null,
- "Should have no idle timeout to start with");
-
- let result = yield LanguageDetector.detectLanguage(test_string);
-
- // Make sure the results are still correct.
- check_result(result, test_item[0], test_item[3]);
-
- // We should have an idle timeout after processing the string.
- ok(detectorModule.workerManager._idleTimeout != null,
- "Should have an idle timeout");
- ok(detectorModule.workerManager._worker != null,
- "Should have a worker instance");
- ok(detectorModule.workerManager._workerReadyPromise != null,
- "Should have a worker promise");
-
- // Wait for the idle timeout to elapse.
- yield new Promise(resolve => setTimeout(resolve, detectorModule.IDLE_TIMEOUT));
-
- equal(detectorModule.workerManager._idleTimeout, null,
- "Should have no idle timeout after it has elapsed");
- equal(detectorModule.workerManager._worker, null,
- "Should have no worker instance after idle timeout");
- equal(detectorModule.workerManager._workerReadyPromise, null,
- "Should have no worker promise after idle timeout");
-
- // We should still be able to use the language detector after its
- // worker has been flushed.
- result = yield LanguageDetector.detectLanguage(test_string);
-
- // Make sure the results are still correct.
- check_result(result, test_item[0], test_item[3]);
-});
diff --git a/browser/components/translation/test/unit/xpcshell.ini b/browser/components/translation/test/unit/xpcshell.ini
deleted file mode 100644
index 8431a8c4e..000000000
--- a/browser/components/translation/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-head =
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-[test_cld2.js]
diff --git a/browser/components/translation/test/yandex.sjs b/browser/components/translation/test/yandex.sjs
deleted file mode 100644
index ed515beab..000000000
--- a/browser/components/translation/test/yandex.sjs
+++ /dev/null
@@ -1,199 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, Constructor: CC} = Components;
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-
-function handleRequest(req, res) {
- try {
- reallyHandleRequest(req, res);
- } catch (ex) {
- res.setStatusLine("1.0", 200, "AlmostOK");
- let msg = "Error handling request: " + ex + "\n" + ex.stack;
- log(msg);
- res.write(msg);
- }
-}
-
-function log(msg) {
- dump("YANDEX-SERVER-MOCK: " + msg + "\n");
-}
-
-const statusCodes = {
- 400: "Bad Request",
- 401: "Invalid API key",
- 402: "This API key has been blocked",
- 403: "Daily limit for requests reached",
- 404: "Daily limit for chars reached",
- 413: "The text size exceeds the maximum",
- 422: "The text could not be translated",
- 500: "Internal Server Error",
- 501: "The specified translation direction is not supported",
- 503: "Service Unavailable"
-};
-
-function HTTPError(code = 500, message) {
- this.code = code;
- this.name = statusCodes[code] || "HTTPError";
- this.message = message || this.name;
-}
-HTTPError.prototype = new Error();
-HTTPError.prototype.constructor = HTTPError;
-
-function sendError(res, err) {
- if (!(err instanceof HTTPError)) {
- err = new HTTPError(typeof err == "number" ? err : 500,
- err.message || typeof err == "string" ? err : "");
- }
- res.setStatusLine("1.1", err.code, err.name);
- res.write(err.message);
-}
-
-// Based on the code borrowed from:
-// http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
-function parseQuery(query) {
- let match,
- params = {},
- pl = /\+/g,
- search = /([^&=]+)=?([^&]*)/g,
- decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
-
- while (match = search.exec(query)) {
- let k = decode(match[1]),
- v = decode(match[2]);
- if (k in params) {
- if(params[k] instanceof Array)
- params[k].push(v);
- else
- params[k] = [params[k], v];
- } else {
- params[k] = v;
- }
- }
-
- return params;
-}
-
-function sha1(str) {
- let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Ci.nsIScriptableUnicodeConverter);
- converter.charset = "UTF-8";
- // `result` is an out parameter, `result.value` will contain the array length.
- let result = {};
- // `data` is an array of bytes.
- let data = converter.convertToByteArray(str, result);
- let ch = Cc["@mozilla.org/security/hash;1"]
- .createInstance(Ci.nsICryptoHash);
- ch.init(ch.SHA1);
- ch.update(data, data.length);
- let hash = ch.finish(false);
-
- // Return the two-digit hexadecimal code for a byte.
- function toHexString(charCode) {
- return ("0" + charCode.toString(16)).slice(-2);
- }
-
- // Convert the binary hash data to a hex string.
- return Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
-}
-
-function getRequestBody(req) {
- let avail;
- let bytes = [];
- let body = new BinaryInputStream(req.bodyInputStream);
-
- while ((avail = body.available()) > 0)
- Array.prototype.push.apply(bytes, body.readByteArray(avail));
-
- return String.fromCharCode.apply(null, bytes);
-}
-
-function getInputStream(path) {
- let file = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
- .get("CurWorkD", Ci.nsILocalFile);
- for (let part of path.split("/"))
- file.append(part);
- let fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- fileStream.init(file, 1, 0, false);
- return fileStream;
-}
-
-/**
- * Yandex Requests have to be signed with an API Key. This mock server
- * supports the following keys:
- *
- * yandexValidKey Always passes the authentication,
- * yandexInvalidKey Never passes authentication and fails with 401 code,
- * yandexBlockedKey Never passes authentication and fails with 402 code,
- * yandexOutOfRequestsKey Never passes authentication and fails with 403 code,
- * yandexOutOfCharsKey Never passes authentication and fails with 404 code.
- *
- * If any other key is used the server reponds with 401 error code.
- */
-function checkAuth(params) {
- if(!("key" in params))
- throw new HTTPError(400);
-
- let key = params.key;
- if(key === "yandexValidKey")
- return true;
-
- let invalidKeys = {
- "yandexInvalidKey" : 401,
- "yandexBlockedKey" : 402,
- "yandexOutOfRequestsKey" : 403,
- "yandexOutOfCharsKey" : 404,
- };
-
- if(key in invalidKeys)
- throw new HTTPError(invalidKeys[key]);
-
- throw new HTTPError(401);
-}
-
-function reallyHandleRequest(req, res) {
-
- try {
-
- // Preparing the query parameters.
- let params = {};
- if(req.method == 'POST') {
- params = parseQuery(getRequestBody(req));
- }
-
- // Extracting the API key and attempting to authenticate the request.
- log(JSON.stringify(params));
-
- checkAuth(params);
- methodHandlers['translate'](res, params);
-
- } catch (ex) {
- sendError(res, ex, ex.code);
- }
-
-}
-
-const methodHandlers = {
- translate: function(res, params) {
- res.setStatusLine("1.1", 200, "OK");
- res.setHeader("Content-Type", "application/json");
-
- let hash = sha1(JSON.stringify(params)).substr(0, 10);
- log("SHA1 hash of content: " + hash);
-
- let fixture = "browser/browser/components/translation/test/fixtures/result-yandex-" + hash + ".json";
- log("PATH: " + fixture);
-
- let inputStream = getInputStream(fixture);
- res.bodyOutputStream.writeFrom(inputStream, inputStream.available());
- inputStream.close();
- }
-
-};
diff --git a/browser/components/uitour/moz.build b/browser/components/uitour/moz.build
index 51e6037cc..c8b1450b9 100644
--- a/browser/components/uitour/moz.build
+++ b/browser/components/uitour/moz.build
@@ -7,10 +7,3 @@ EXTRA_JS_MODULES += [
]
JAR_MANIFESTS += ['jar.mn']
-
-BROWSER_CHROME_MANIFESTS += [
- 'test/browser.ini',
-]
-
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Tours')
diff --git a/browser/components/uitour/test/.eslintrc.js b/browser/components/uitour/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/components/uitour/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/components/uitour/test/browser.ini b/browser/components/uitour/test/browser.ini
deleted file mode 100644
index ae027a738..000000000
--- a/browser/components/uitour/test/browser.ini
+++ /dev/null
@@ -1,49 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
- image.png
- uitour.html
- ../UITour-lib.js
-
-[browser_backgroundTab.js]
-[browser_closeTab.js]
-[browser_fxa.js]
-skip-if = debug || asan # updateAppMenuItem leaks
-[browser_no_tabs.js]
-[browser_openPreferences.js]
-[browser_openSearchPanel.js]
-skip-if = true # Bug 1113038 - Intermittent "Popup was opened"
-[browser_trackingProtection.js]
-skip-if = os == "linux" # Intermittent NS_ERROR_NOT_AVAILABLE [nsIUrlClassifierDBService.beginUpdate]
-tag = trackingprotection
-support-files =
- !/browser/base/content/test/general/benignPage.html
- !/browser/base/content/test/general/trackingPage.html
-[browser_trackingProtection_tour.js]
-tag = trackingprotection
-[browser_showMenu_controlCenter.js]
-tag = trackingprotection
-[browser_UITour.js]
-skip-if = os == "linux" # Intermittent failures, bug 951965
-[browser_UITour2.js]
-[browser_UITour3.js]
-skip-if = os == "linux" # Linux: Bug 986760, Bug 989101.
-[browser_UITour_availableTargets.js]
-[browser_UITour_annotation_size_attributes.js]
-[browser_UITour_defaultBrowser.js]
-[browser_UITour_detach_tab.js]
-[browser_UITour_forceReaderMode.js]
-[browser_UITour_heartbeat.js]
-skip-if = os == "win" # Bug 1277107
-[browser_UITour_modalDialog.js]
-skip-if = os != "mac" # modal dialog disabling only working on OS X.
-[browser_UITour_observe.js]
-[browser_UITour_panel_close_annotation.js]
-skip-if = true # Disabled due to frequent failures, bugs 1026310 and 1032137
-[browser_UITour_pocket.js]
-skip-if = true # Disabled pending removal of pocket UI Tour
-[browser_UITour_registerPageID.js]
-[browser_UITour_resetProfile.js]
-[browser_UITour_showNewTab.js]
-[browser_UITour_sync.js]
-[browser_UITour_toggleReaderMode.js]
diff --git a/browser/components/uitour/test/browser_UITour.js b/browser/components/uitour/test/browser_UITour.js
deleted file mode 100644
index 964be0215..000000000
--- a/browser/components/uitour/test/browser_UITour.js
+++ /dev/null
@@ -1,408 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-Components.utils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this);
-
-function test() {
- UITourTest();
-}
-
-var tests = [
- function test_untrusted_host(done) {
- loadUITourTestPage(function() {
- let bookmarksMenu = document.getElementById("bookmarks-menu-button");
- is(bookmarksMenu.open, false, "Bookmark menu should initially be closed");
-
- gContentAPI.showMenu("bookmarks");
- is(bookmarksMenu.open, false, "Bookmark menu should not open on a untrusted host");
-
- done();
- }, "http://mochi.test:8888/");
- },
- function test_testing_host(done) {
- // Add two testing origins intentionally surrounded by whitespace to be ignored.
- Services.prefs.setCharPref("browser.uitour.testingOrigins",
- "https://test1.example.org, https://test2.example.org:443 ");
-
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.uitour.testingOrigins");
- });
- function callback(result) {
- ok(result, "Callback should be called on a testing origin");
- done();
- }
-
- loadUITourTestPage(function() {
- gContentAPI.getConfiguration("appinfo", callback);
- }, "https://test2.example.org/");
- },
- function test_unsecure_host(done) {
- loadUITourTestPage(function() {
- let bookmarksMenu = document.getElementById("bookmarks-menu-button");
- is(bookmarksMenu.open, false, "Bookmark menu should initially be closed");
-
- gContentAPI.showMenu("bookmarks");
- is(bookmarksMenu.open, false, "Bookmark menu should not open on a unsecure host");
-
- done();
- }, "http://example.org/");
- },
- function test_unsecure_host_override(done) {
- Services.prefs.setBoolPref("browser.uitour.requireSecure", false);
- loadUITourTestPage(function() {
- let highlight = document.getElementById("UITourHighlight");
- is_element_hidden(highlight, "Highlight should initially be hidden");
-
- gContentAPI.showHighlight("urlbar");
- waitForElementToBeVisible(highlight, done, "Highlight should be shown on a unsecure host when override pref is set");
-
- Services.prefs.setBoolPref("browser.uitour.requireSecure", true);
- }, "http://example.org/");
- },
- function test_disabled(done) {
- Services.prefs.setBoolPref("browser.uitour.enabled", false);
-
- let bookmarksMenu = document.getElementById("bookmarks-menu-button");
- is(bookmarksMenu.open, false, "Bookmark menu should initially be closed");
-
- gContentAPI.showMenu("bookmarks");
- is(bookmarksMenu.open, false, "Bookmark menu should not open when feature is disabled");
-
- Services.prefs.setBoolPref("browser.uitour.enabled", true);
- done();
- },
- function test_highlight(done) {
- function test_highlight_2() {
- let highlight = document.getElementById("UITourHighlight");
- gContentAPI.hideHighlight();
-
- waitForElementToBeHidden(highlight, test_highlight_3, "Highlight should be hidden after hideHighlight()");
- }
- function test_highlight_3() {
- is_element_hidden(highlight, "Highlight should be hidden after hideHighlight()");
-
- gContentAPI.showHighlight("urlbar");
- waitForElementToBeVisible(highlight, test_highlight_4, "Highlight should be shown after showHighlight()");
- }
- function test_highlight_4() {
- let highlight = document.getElementById("UITourHighlight");
- gContentAPI.showHighlight("backForward");
- waitForElementToBeVisible(highlight, done, "Highlight should be shown after showHighlight()");
- }
-
- let highlight = document.getElementById("UITourHighlight");
- is_element_hidden(highlight, "Highlight should initially be hidden");
-
- gContentAPI.showHighlight("urlbar");
- waitForElementToBeVisible(highlight, test_highlight_2, "Highlight should be shown after showHighlight()");
- },
- function test_highlight_circle(done) {
- function check_highlight_size() {
- let panel = highlight.parentElement;
- let anchor = panel.anchorNode;
- let anchorRect = anchor.getBoundingClientRect();
- info("addons target: width: " + anchorRect.width + " height: " + anchorRect.height);
- let maxDimension = Math.round(Math.max(anchorRect.width, anchorRect.height));
- let highlightRect = highlight.getBoundingClientRect();
- info("highlight: width: " + highlightRect.width + " height: " + highlightRect.height);
- is(Math.round(highlightRect.width), maxDimension, "The width of the highlight should be equal to the largest dimension of the target");
- is(Math.round(highlightRect.height), maxDimension, "The height of the highlight should be equal to the largest dimension of the target");
- is(Math.round(highlightRect.height), Math.round(highlightRect.width), "The height and width of the highlight should be the same to create a circle");
- is(highlight.style.borderRadius, "100%", "The border-radius should be 100% to create a circle");
- done();
- }
- let highlight = document.getElementById("UITourHighlight");
- is_element_hidden(highlight, "Highlight should initially be hidden");
-
- gContentAPI.showHighlight("addons");
- waitForElementToBeVisible(highlight, check_highlight_size, "Highlight should be shown after showHighlight()");
- },
- function test_highlight_customize_auto_open_close(done) {
- let highlight = document.getElementById("UITourHighlight");
- gContentAPI.showHighlight("customize");
- waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Move the highlight outside which should close the app menu.
- gContentAPI.showHighlight("appMenu");
- waitForElementToBeVisible(highlight, function checkPanelIsClosed() {
- isnot(PanelUI.panel.state, "open",
- "Panel should have closed after the highlight moved elsewhere.");
- done();
- }, "Highlight should move to the appMenu button");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
- function test_highlight_customize_manual_open_close(done) {
- let highlight = document.getElementById("UITourHighlight");
- // Manually open the app menu then show a highlight there. The menu should remain open.
- let shownPromise = promisePanelShown(window);
- gContentAPI.showMenu("appMenu");
- shownPromise.then(() => {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
- gContentAPI.showHighlight("customize");
-
- waitForElementToBeVisible(highlight, function checkPanelIsStillOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should still be open");
-
- // Move the highlight outside which shouldn't close the app menu since it was manually opened.
- gContentAPI.showHighlight("appMenu");
- waitForElementToBeVisible(highlight, function () {
- isnot(PanelUI.panel.state, "closed",
- "Panel should remain open since UITour didn't open it in the first place");
- gContentAPI.hideMenu("appMenu");
- done();
- }, "Highlight should move to the appMenu button");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- }).then(null, Components.utils.reportError);
- },
- function test_highlight_effect(done) {
- function waitForHighlightWithEffect(highlightEl, effect, next, error) {
- return waitForCondition(() => highlightEl.getAttribute("active") == effect,
- next,
- error);
- }
- function checkDefaultEffect() {
- is(highlight.getAttribute("active"), "none", "The default should be no effect");
-
- gContentAPI.showHighlight("urlbar", "none");
- waitForHighlightWithEffect(highlight, "none", checkZoomEffect, "There should be no effect");
- }
- function checkZoomEffect() {
- gContentAPI.showHighlight("urlbar", "zoom");
- waitForHighlightWithEffect(highlight, "zoom", () => {
- let style = window.getComputedStyle(highlight);
- is(style.animationName, "uitour-zoom", "The animation-name should be uitour-zoom");
- checkSameEffectOnDifferentTarget();
- }, "There should be a zoom effect");
- }
- function checkSameEffectOnDifferentTarget() {
- gContentAPI.showHighlight("appMenu", "wobble");
- waitForHighlightWithEffect(highlight, "wobble", () => {
- highlight.addEventListener("animationstart", function onAnimationStart(aEvent) {
- highlight.removeEventListener("animationstart", onAnimationStart);
- ok(true, "Animation occurred again even though the effect was the same");
- checkRandomEffect();
- });
- gContentAPI.showHighlight("backForward", "wobble");
- }, "There should be a wobble effect");
- }
- function checkRandomEffect() {
- function waitForActiveHighlight(highlightEl, next, error) {
- return waitForCondition(() => highlightEl.hasAttribute("active"),
- next,
- error);
- }
-
- gContentAPI.hideHighlight();
- gContentAPI.showHighlight("urlbar", "random");
- waitForActiveHighlight(highlight, () => {
- ok(highlight.hasAttribute("active"), "The highlight should be active");
- isnot(highlight.getAttribute("active"), "none", "A random effect other than none should have been chosen");
- isnot(highlight.getAttribute("active"), "random", "The random effect shouldn't be 'random'");
- isnot(UITour.highlightEffects.indexOf(highlight.getAttribute("active")), -1, "Check that a supported effect was randomly chosen");
- done();
- }, "There should be an active highlight with a random effect");
- }
-
- let highlight = document.getElementById("UITourHighlight");
- is_element_hidden(highlight, "Highlight should initially be hidden");
-
- gContentAPI.showHighlight("urlbar");
- waitForElementToBeVisible(highlight, checkDefaultEffect, "Highlight should be shown after showHighlight()");
- },
- function test_highlight_effect_unsupported(done) {
- function checkUnsupportedEffect() {
- is(highlight.getAttribute("active"), "none", "No effect should be used when an unsupported effect is requested");
- done();
- }
-
- let highlight = document.getElementById("UITourHighlight");
- is_element_hidden(highlight, "Highlight should initially be hidden");
-
- gContentAPI.showHighlight("urlbar", "__UNSUPPORTED__");
- waitForElementToBeVisible(highlight, checkUnsupportedEffect, "Highlight should be shown after showHighlight()");
- },
- function test_info_1(done) {
- let popup = document.getElementById("UITourTooltip");
- let title = document.getElementById("UITourTooltipTitle");
- let desc = document.getElementById("UITourTooltipDescription");
- let icon = document.getElementById("UITourTooltipIcon");
- let buttons = document.getElementById("UITourTooltipButtons");
-
- popup.addEventListener("popupshown", function onPopupShown() {
- popup.removeEventListener("popupshown", onPopupShown);
- is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar");
- is(title.textContent, "test title", "Popup should have correct title");
- is(desc.textContent, "test text", "Popup should have correct description text");
- is(icon.src, "", "Popup should have no icon");
- is(buttons.hasChildNodes(), false, "Popup should have no buttons");
-
- popup.addEventListener("popuphidden", function onPopupHidden() {
- popup.removeEventListener("popuphidden", onPopupHidden);
-
- popup.addEventListener("popupshown", function onPopupShown() {
- popup.removeEventListener("popupshown", onPopupShown);
- done();
- });
-
- gContentAPI.showInfo("urlbar", "test title", "test text");
-
- });
- gContentAPI.hideInfo();
- });
-
- gContentAPI.showInfo("urlbar", "test title", "test text");
- },
- taskify(function* test_info_2() {
- let popup = document.getElementById("UITourTooltip");
- let title = document.getElementById("UITourTooltipTitle");
- let desc = document.getElementById("UITourTooltipDescription");
- let icon = document.getElementById("UITourTooltipIcon");
- let buttons = document.getElementById("UITourTooltipButtons");
-
- yield showInfoPromise("urlbar", "urlbar title", "urlbar text");
-
- is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar");
- is(title.textContent, "urlbar title", "Popup should have correct title");
- is(desc.textContent, "urlbar text", "Popup should have correct description text");
- is(icon.src, "", "Popup should have no icon");
- is(buttons.hasChildNodes(), false, "Popup should have no buttons");
-
- yield showInfoPromise("search", "search title", "search text");
-
- is(popup.popupBoxObject.anchorNode, document.getElementById("searchbar"), "Popup should be anchored to the searchbar");
- is(title.textContent, "search title", "Popup should have correct title");
- is(desc.textContent, "search text", "Popup should have correct description text");
- }),
- function test_getConfigurationVersion(done) {
- function callback(result) {
- let props = ["defaultUpdateChannel", "version"];
- for (let property of props) {
- ok(typeof(result[property]) !== "undefined", "Check " + property + " isn't undefined.");
- is(result[property], Services.appinfo[property], "Should have the same " + property + " property.");
- }
- done();
- }
-
- gContentAPI.getConfiguration("appinfo", callback);
- },
- function test_getConfigurationDistribution(done) {
- gContentAPI.getConfiguration("appinfo", (result) => {
- ok(typeof(result.distribution) !== "undefined", "Check distribution isn't undefined.");
- is(result.distribution, "default", "Should be \"default\" without preference set.");
-
- let defaults = Services.prefs.getDefaultBranch("distribution.");
- let testDistributionID = "TestDistribution";
- defaults.setCharPref("id", testDistributionID);
- gContentAPI.getConfiguration("appinfo", (result) => {
- ok(typeof(result.distribution) !== "undefined", "Check distribution isn't undefined.");
- is(result.distribution, testDistributionID, "Should have the distribution as set in preference.");
-
- done();
- });
- });
- },
- function test_addToolbarButton(done) {
- let placement = CustomizableUI.getPlacementOfWidget("panic-button");
- is(placement, null, "default UI has panic button in the palette");
-
- gContentAPI.getConfiguration("availableTargets", (data) => {
- let available = (data.targets.indexOf("forget") != -1);
- ok(!available, "Forget button should not be available by default");
-
- gContentAPI.addNavBarWidget("forget", () => {
- info("addNavBarWidget callback successfully called");
-
- let placement = CustomizableUI.getPlacementOfWidget("panic-button");
- is(placement.area, CustomizableUI.AREA_NAVBAR);
-
- gContentAPI.getConfiguration("availableTargets", (data) => {
- let available = (data.targets.indexOf("forget") != -1);
- ok(available, "Forget button should now be available");
-
- // Cleanup
- CustomizableUI.removeWidgetFromArea("panic-button");
- done();
- });
- });
- });
- },
- function test_search(done) {
- Services.search.init(rv => {
- if (!Components.isSuccessCode(rv)) {
- ok(false, "search service init failed: " + rv);
- done();
- return;
- }
- let defaultEngine = Services.search.defaultEngine;
- gContentAPI.getConfiguration("search", data => {
- let visibleEngines = Services.search.getVisibleEngines();
- let expectedEngines = visibleEngines.filter((engine) => engine.identifier)
- .map((engine) => "searchEngine-" + engine.identifier);
-
- let engines = data.engines;
- ok(Array.isArray(engines), "data.engines should be an array");
- is(engines.sort().toString(), expectedEngines.sort().toString(),
- "Engines should be as expected");
-
- is(data.searchEngineIdentifier, defaultEngine.identifier,
- "the searchEngineIdentifier property should contain the defaultEngine's identifier");
-
- let someOtherEngineID = data.engines.filter(t => t != "searchEngine-" + defaultEngine.identifier)[0];
- someOtherEngineID = someOtherEngineID.replace(/^searchEngine-/, "");
-
- let observe = function (subject, topic, verb) {
- info("browser-search-engine-modified: " + verb);
- if (verb == "engine-current") {
- is(Services.search.defaultEngine.identifier, someOtherEngineID, "correct engine was switched to");
- done();
- }
- };
- Services.obs.addObserver(observe, "browser-search-engine-modified", false);
- registerCleanupFunction(() => {
- // Clean up
- Services.obs.removeObserver(observe, "browser-search-engine-modified");
- Services.search.defaultEngine = defaultEngine;
- });
-
- gContentAPI.setDefaultSearchEngine(someOtherEngineID);
- });
- });
- },
- taskify(function* test_treatment_tag() {
- let ac = new TelemetryArchiveTesting.Checker();
- yield ac.promiseInit();
- yield gContentAPI.setTreatmentTag("foobar", "baz");
- // Wait until the treatment telemetry is sent before looking in the archive.
- yield BrowserTestUtils.waitForContentEvent(gTestTab.linkedBrowser, "mozUITourNotification", false,
- event => event.detail.event === "TreatmentTag:TelemetrySent");
- yield new Promise((resolve) => {
- gContentAPI.getTreatmentTag("foobar", (data) => {
- is(data.value, "baz", "set and retrieved treatmentTag");
- ac.promiseFindPing("uitour-tag", [
- [["payload", "tagName"], "foobar"],
- [["payload", "tagValue"], "baz"],
- ]).then((found) => {
- ok(found, "Telemetry ping submitted for setTreatmentTag");
- resolve();
- }, (err) => {
- ok(false, "Exception finding uitour telemetry ping: " + err);
- resolve();
- });
- });
- });
- }),
-
- // Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down.
- taskify(function* cleanupMenus() {
- let shownPromise = promisePanelShown(window);
- gContentAPI.showMenu("appMenu");
- yield shownPromise;
- }),
-];
diff --git a/browser/components/uitour/test/browser_UITour2.js b/browser/components/uitour/test/browser_UITour2.js
deleted file mode 100644
index e74a71afa..000000000
--- a/browser/components/uitour/test/browser_UITour2.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-function test() {
- UITourTest();
-}
-
-var tests = [
- function test_info_customize_auto_open_close(done) {
- let popup = document.getElementById("UITourTooltip");
- gContentAPI.showInfo("customize", "Customization", "Customize me please!");
- UITour.getTarget(window, "customize").then((customizeTarget) => {
- waitForPopupAtAnchor(popup, customizeTarget.node, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened before the popup anchored");
- ok(PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been set");
-
- // Move the info outside which should close the app menu.
- gContentAPI.showInfo("appMenu", "Open Me", "You know you want to");
- UITour.getTarget(window, "appMenu").then((target) => {
- waitForPopupAtAnchor(popup, target.node, function checkPanelIsClosed() {
- isnot(PanelUI.panel.state, "open",
- "Panel should have closed after the info moved elsewhere.");
- ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up on close");
- done();
- }, "Info should move to the appMenu button");
- });
- }, "Info panel should be anchored to the customize button");
- });
- },
- function test_info_customize_manual_open_close(done) {
- let popup = document.getElementById("UITourTooltip");
- // Manually open the app menu then show an info panel there. The menu should remain open.
- let shownPromise = promisePanelShown(window);
- gContentAPI.showMenu("appMenu");
- shownPromise.then(() => {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
- ok(PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been set");
- gContentAPI.showInfo("customize", "Customization", "Customize me please!");
-
- UITour.getTarget(window, "customize").then((customizeTarget) => {
- waitForPopupAtAnchor(popup, customizeTarget.node, function checkMenuIsStillOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should still be open");
- ok(PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should still be set");
-
- // Move the info outside which shouldn't close the app menu since it was manually opened.
- gContentAPI.showInfo("appMenu", "Open Me", "You know you want to");
- UITour.getTarget(window, "appMenu").then((target) => {
- waitForPopupAtAnchor(popup, target.node, function checkMenuIsStillOpen() {
- isnot(PanelUI.panel.state, "closed",
- "Menu should remain open since UITour didn't open it in the first place");
- waitForElementToBeHidden(window.PanelUI.panel, () => {
- ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up on close");
- done();
- });
- gContentAPI.hideMenu("appMenu");
- }, "Info should move to the appMenu button");
- });
- }, "Info should be shown after showInfo() for fixed menu panel items");
- });
- }).then(null, Components.utils.reportError);
- },
- taskify(function* test_bookmarks_menu() {
- let bookmarksMenuButton = document.getElementById("bookmarks-menu-button");
-
- is(bookmarksMenuButton.open, false, "Menu should initially be closed");
- gContentAPI.showMenu("bookmarks");
-
- yield waitForConditionPromise(() => {
- return bookmarksMenuButton.open;
- }, "Menu should be visible after showMenu()");
-
- gContentAPI.hideMenu("bookmarks");
- yield waitForConditionPromise(() => {
- return !bookmarksMenuButton.open;
- }, "Menu should be hidden after hideMenu()");
- }),
-];
diff --git a/browser/components/uitour/test/browser_UITour3.js b/browser/components/uitour/test/browser_UITour3.js
deleted file mode 100644
index b852339f1..000000000
--- a/browser/components/uitour/test/browser_UITour3.js
+++ /dev/null
@@ -1,181 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-requestLongerTimeout(2);
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_info_icon() {
- let popup = document.getElementById("UITourTooltip");
- let title = document.getElementById("UITourTooltipTitle");
- let desc = document.getElementById("UITourTooltipDescription");
- let icon = document.getElementById("UITourTooltipIcon");
- let buttons = document.getElementById("UITourTooltipButtons");
-
- // Disable the animation to prevent the mouse clicks from hitting the main
- // window during the transition instead of the buttons in the popup.
- popup.setAttribute("animate", "false");
-
- yield showInfoPromise("urlbar", "a title", "some text", "image.png");
-
- is(title.textContent, "a title", "Popup should have correct title");
- is(desc.textContent, "some text", "Popup should have correct description text");
-
- let imageURL = getRootDirectory(gTestPath) + "image.png";
- imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.org/");
- is(icon.src, imageURL, "Popup should have correct icon shown");
-
- is(buttons.hasChildNodes(), false, "Popup should have no buttons");
-}),
-
-add_UITour_task(function* test_info_buttons_1() {
- let popup = document.getElementById("UITourTooltip");
- let title = document.getElementById("UITourTooltipTitle");
- let desc = document.getElementById("UITourTooltipDescription");
- let icon = document.getElementById("UITourTooltipIcon");
-
- yield showInfoPromise("urlbar", "another title", "moar text", "./image.png", "makeButtons");
-
- is(title.textContent, "another title", "Popup should have correct title");
- is(desc.textContent, "moar text", "Popup should have correct description text");
-
- let imageURL = getRootDirectory(gTestPath) + "image.png";
- imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.org/");
- is(icon.src, imageURL, "Popup should have correct icon shown");
-
- let buttons = document.getElementById("UITourTooltipButtons");
- is(buttons.childElementCount, 4, "Popup should have four buttons");
-
- is(buttons.childNodes[0].nodeName, "label", "Text label should be a <label>");
- is(buttons.childNodes[0].getAttribute("value"), "Regular text", "Text label should have correct value");
- is(buttons.childNodes[0].getAttribute("image"), "", "Text should have no image");
- is(buttons.childNodes[0].className, "", "Text should have no class");
-
- is(buttons.childNodes[1].nodeName, "button", "Link should be a <button>");
- is(buttons.childNodes[1].getAttribute("label"), "Link", "Link should have correct label");
- is(buttons.childNodes[1].getAttribute("image"), "", "Link should have no image");
- is(buttons.childNodes[1].className, "button-link", "Check link class");
-
- is(buttons.childNodes[2].nodeName, "button", "Button 1 should be a <button>");
- is(buttons.childNodes[2].getAttribute("label"), "Button 1", "First button should have correct label");
- is(buttons.childNodes[2].getAttribute("image"), "", "First button should have no image");
- is(buttons.childNodes[2].className, "", "Button 1 should have no class");
-
- is(buttons.childNodes[3].nodeName, "button", "Button 2 should be a <button>");
- is(buttons.childNodes[3].getAttribute("label"), "Button 2", "Second button should have correct label");
- is(buttons.childNodes[3].getAttribute("image"), imageURL, "Second button should have correct image");
- is(buttons.childNodes[3].className, "button-primary", "Check button 2 class");
-
- let promiseHidden = promisePanelElementHidden(window, popup);
- EventUtils.synthesizeMouseAtCenter(buttons.childNodes[2], {}, window);
- yield promiseHidden;
-
- ok(true, "Popup should close automatically");
-
- let returnValue = yield waitForCallbackResultPromise();
- is(returnValue.result, "button1", "Correct callback should have been called");
-});
-
-add_UITour_task(function* test_info_buttons_2() {
- let popup = document.getElementById("UITourTooltip");
- let title = document.getElementById("UITourTooltipTitle");
- let desc = document.getElementById("UITourTooltipDescription");
- let icon = document.getElementById("UITourTooltipIcon");
-
- yield showInfoPromise("urlbar", "another title", "moar text", "./image.png", "makeButtons");
-
- is(title.textContent, "another title", "Popup should have correct title");
- is(desc.textContent, "moar text", "Popup should have correct description text");
-
- let imageURL = getRootDirectory(gTestPath) + "image.png";
- imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.org/");
- is(icon.src, imageURL, "Popup should have correct icon shown");
-
- let buttons = document.getElementById("UITourTooltipButtons");
- is(buttons.childElementCount, 4, "Popup should have four buttons");
-
- is(buttons.childNodes[1].getAttribute("label"), "Link", "Link should have correct label");
- is(buttons.childNodes[1].getAttribute("image"), "", "Link should have no image");
- ok(buttons.childNodes[1].classList.contains("button-link"), "Link should have button-link class");
-
- is(buttons.childNodes[2].getAttribute("label"), "Button 1", "First button should have correct label");
- is(buttons.childNodes[2].getAttribute("image"), "", "First button should have no image");
-
- is(buttons.childNodes[3].getAttribute("label"), "Button 2", "Second button should have correct label");
- is(buttons.childNodes[3].getAttribute("image"), imageURL, "Second button should have correct image");
-
- let promiseHidden = promisePanelElementHidden(window, popup);
- EventUtils.synthesizeMouseAtCenter(buttons.childNodes[3], {}, window);
- yield promiseHidden;
-
- ok(true, "Popup should close automatically");
-
- let returnValue = yield waitForCallbackResultPromise();
-
- is(returnValue.result, "button2", "Correct callback should have been called");
-}),
-
-add_UITour_task(function* test_info_close_button() {
- let closeButton = document.getElementById("UITourTooltipClose");
-
- yield showInfoPromise("urlbar", "Close me", "X marks the spot", null, null, "makeInfoOptions");
-
- EventUtils.synthesizeMouseAtCenter(closeButton, {}, window);
-
- let returnValue = yield waitForCallbackResultPromise();
-
- is(returnValue.result, "closeButton", "Close button callback called");
-}),
-
-add_UITour_task(function* test_info_target_callback() {
- let popup = document.getElementById("UITourTooltip");
-
- yield showInfoPromise("appMenu", "I want to know when the target is clicked", "*click*", null, null, "makeInfoOptions");
-
- yield PanelUI.show();
-
- let returnValue = yield waitForCallbackResultPromise();
-
- is(returnValue.result, "target", "target callback called");
- is(returnValue.data.target, "appMenu", "target callback was from the appMenu");
- is(returnValue.data.type, "popupshown", "target callback was from the mousedown");
-
- // Cleanup.
- yield hideInfoPromise();
-
- popup.removeAttribute("animate");
-}),
-
-add_UITour_task(function* test_getConfiguration_selectedSearchEngine() {
- yield new Promise((resolve) => {
- Services.search.init(Task.async(function*(rv) {
- ok(Components.isSuccessCode(rv), "Search service initialized");
- let engine = Services.search.defaultEngine;
- let data = yield getConfigurationPromise("selectedSearchEngine");
- is(data.searchEngineIdentifier, engine.identifier, "Correct engine identifier");
- resolve();
- }));
- });
-});
-
-add_UITour_task(function* test_setSearchTerm() {
- const TERM = "UITour Search Term";
- yield gContentAPI.setSearchTerm(TERM);
-
- let searchbar = document.getElementById("searchbar");
- // The UITour gets to the searchbar element through a promise, so the value setting
- // only happens after a tick.
- yield waitForConditionPromise(() => searchbar.value == TERM, "Correct term set");
-});
-
-add_UITour_task(function* test_clearSearchTerm() {
- yield gContentAPI.setSearchTerm("");
-
- let searchbar = document.getElementById("searchbar");
- // The UITour gets to the searchbar element through a promise, so the value setting
- // only happens after a tick.
- yield waitForConditionPromise(() => searchbar.value == "", "Search term cleared");
-});
diff --git a/browser/components/uitour/test/browser_UITour_annotation_size_attributes.js b/browser/components/uitour/test/browser_UITour_annotation_size_attributes.js
deleted file mode 100644
index dbdeb9589..000000000
--- a/browser/components/uitour/test/browser_UITour_annotation_size_attributes.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Test that width and height attributes don't get set by widget code on the highlight panel.
- */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-var highlight = document.getElementById("UITourHighlightContainer");
-var tooltip = document.getElementById("UITourTooltip");
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_highlight_size_attributes() {
- yield gContentAPI.showHighlight("appMenu");
- yield elementVisiblePromise(highlight,
- "Highlight should be shown after showHighlight() for the appMenu");
- yield gContentAPI.showHighlight("urlbar");
- yield elementVisiblePromise(highlight, "Highlight should be moved to the urlbar");
- yield new Promise((resolve) => {
- SimpleTest.executeSoon(() => {
- is(highlight.height, "", "Highlight panel should have no explicit height set");
- is(highlight.width, "", "Highlight panel should have no explicit width set");
- resolve();
- });
- });
-});
-
-add_UITour_task(function* test_info_size_attributes() {
- yield gContentAPI.showInfo("appMenu", "test title", "test text");
- yield elementVisiblePromise(tooltip, "Tooltip should be shown after showInfo() for the appMenu");
- yield gContentAPI.showInfo("urlbar", "new title", "new text");
- yield elementVisiblePromise(tooltip, "Tooltip should be moved to the urlbar");
- yield new Promise((resolve) => {
- SimpleTest.executeSoon(() => {
- is(tooltip.height, "", "Info panel should have no explicit height set");
- is(tooltip.width, "", "Info panel should have no explicit width set");
- resolve();
- });
- });
-});
diff --git a/browser/components/uitour/test/browser_UITour_availableTargets.js b/browser/components/uitour/test/browser_UITour_availableTargets.js
deleted file mode 100644
index a6e96e31f..000000000
--- a/browser/components/uitour/test/browser_UITour_availableTargets.js
+++ /dev/null
@@ -1,114 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-var hasWebIDE = Services.prefs.getBoolPref("devtools.webide.widget.enabled");
-var hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
-
-requestLongerTimeout(2);
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_availableTargets() {
- let data = yield getConfigurationPromise("availableTargets");
- ok_targets(data, [
- "accountStatus",
- "addons",
- "appMenu",
- "backForward",
- "bookmarks",
- "customize",
- "help",
- "home",
- "devtools",
- ...(hasPocket ? ["pocket"] : []),
- "privateWindow",
- "quit",
- "readerMode-urlBar",
- "search",
- "searchIcon",
- "trackingProtection",
- "urlbar",
- ...(hasWebIDE ? ["webide"] : [])
- ]);
-
- ok(UITour.availableTargetsCache.has(window),
- "Targets should now be cached");
-});
-
-add_UITour_task(function* test_availableTargets_changeWidgets() {
- CustomizableUI.removeWidgetFromArea("bookmarks-menu-button");
- ok(!UITour.availableTargetsCache.has(window),
- "Targets should be evicted from cache after widget change");
- let data = yield getConfigurationPromise("availableTargets");
- ok_targets(data, [
- "accountStatus",
- "addons",
- "appMenu",
- "backForward",
- "customize",
- "help",
- "devtools",
- "home",
- ...(hasPocket ? ["pocket"] : []),
- "privateWindow",
- "quit",
- "readerMode-urlBar",
- "search",
- "searchIcon",
- "trackingProtection",
- "urlbar",
- ...(hasWebIDE ? ["webide"] : [])
- ]);
-
- ok(UITour.availableTargetsCache.has(window),
- "Targets should now be cached again");
- CustomizableUI.reset();
- ok(!UITour.availableTargetsCache.has(window),
- "Targets should not be cached after reset");
-});
-
-add_UITour_task(function* test_availableTargets_exceptionFromGetTarget() {
- // The query function for the "search" target will throw if it's not found.
- // Make sure the callback still fires with the other available targets.
- CustomizableUI.removeWidgetFromArea("search-container");
- let data = yield getConfigurationPromise("availableTargets");
- // Default minus "search" and "searchIcon"
- ok_targets(data, [
- "accountStatus",
- "addons",
- "appMenu",
- "backForward",
- "bookmarks",
- "customize",
- "help",
- "home",
- "devtools",
- ...(hasPocket ? ["pocket"] : []),
- "privateWindow",
- "quit",
- "readerMode-urlBar",
- "trackingProtection",
- "urlbar",
- ...(hasWebIDE ? ["webide"] : [])
- ]);
-
- CustomizableUI.reset();
-});
-
-function ok_targets(actualData, expectedTargets) {
- // Depending on how soon after page load this is called, the selected tab icon
- // may or may not be showing the loading throbber. Check for its presence and
- // insert it into expectedTargets if it's visible.
- let selectedTabIcon =
- document.getAnonymousElementByAttribute(gBrowser.selectedTab,
- "anonid",
- "tab-icon-image");
- if (selectedTabIcon && UITour.isElementVisible(selectedTabIcon))
- expectedTargets.push("selectedTabIcon");
-
- ok(Array.isArray(actualData.targets), "data.targets should be an array");
- is(actualData.targets.sort().toString(), expectedTargets.sort().toString(),
- "Targets should be as expected");
-}
diff --git a/browser/components/uitour/test/browser_UITour_defaultBrowser.js b/browser/components/uitour/test/browser_UITour_defaultBrowser.js
deleted file mode 100644
index 5ebf553b0..000000000
--- a/browser/components/uitour/test/browser_UITour_defaultBrowser.js
+++ /dev/null
@@ -1,61 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-var setDefaultBrowserCalled = false;
-
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochikit/content/tests/SimpleTest/MockObjects.js", this);
-
-function MockShellService() {}
-MockShellService.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIShellService]),
- isDefaultBrowser: function(aStartupCheck, aForAllTypes) { return false; },
- setDefaultBrowser: function(aClaimAllTypes, aForAllUsers) {
- setDefaultBrowserCalled = true;
- },
- shouldCheckDefaultBrowser: false,
- canSetDesktopBackground: false,
- BACKGROUND_TILE : 1,
- BACKGROUND_STRETCH : 2,
- BACKGROUND_CENTER : 3,
- BACKGROUND_FILL : 4,
- BACKGROUND_FIT : 5,
- setDesktopBackground: function(aElement, aPosition) {},
- APPLICATION_MAIL : 0,
- APPLICATION_NEWS : 1,
- openApplication: function(aApplication) {},
- desktopBackgroundColor: 0,
- openApplicationWithURI: function(aApplication, aURI) {},
- defaultFeedReader: 0,
-};
-
-var mockShellService = new MockObjectRegisterer("@mozilla.org/browser/shell-service;1",
- MockShellService);
-
-// Temporarily disabled, see note at test_setDefaultBrowser.
-// mockShellService.register();
-
-add_task(setup_UITourTest);
-
-/* This test is disabled (bug 1180714) since the MockObjectRegisterer
- is not actually replacing the original ShellService.
-add_UITour_task(function* test_setDefaultBrowser() {
- try {
- yield gContentAPI.setConfiguration("defaultBrowser");
- ok(setDefaultBrowserCalled, "setDefaultBrowser called");
- } finally {
- mockShellService.unregister();
- }
-});
-*/
-
-add_UITour_task(function* test_isDefaultBrowser() {
- let shell = Components.classes["@mozilla.org/browser/shell-service;1"]
- .getService(Components.interfaces.nsIShellService);
- let isDefault = shell.isDefaultBrowser(false);
- let data = yield getConfigurationPromise("appinfo");
- is(isDefault, data.defaultBrowser, "gContentAPI result should match shellService.isDefaultBrowser");
-});
diff --git a/browser/components/uitour/test/browser_UITour_detach_tab.js b/browser/components/uitour/test/browser_UITour_detach_tab.js
deleted file mode 100644
index b8edf6dc4..000000000
--- a/browser/components/uitour/test/browser_UITour_detach_tab.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Detaching a tab to a new window shouldn't break the menu panel.
- */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-var gContentDoc;
-
-function test() {
- registerCleanupFunction(function() {
- gContentDoc = null;
- });
- UITourTest();
-}
-
-/**
- * When tab is changed we're tearing the tour down. So the UITour client has to always be aware of this
- * fact and therefore listens to visibilitychange events.
- * In particular this scenario happens for detaching the tab (ie. moving it to a new window).
- */
-var tests = [
- taskify(function* test_move_tab_to_new_window() {
- const myDocIdentifier = "Hello, I'm a unique expando to identify this document.";
-
- let highlight = document.getElementById("UITourHighlight");
- let windowDestroyedDeferred = Promise.defer();
- let onDOMWindowDestroyed = (aWindow) => {
- if (gContentWindow && aWindow == gContentWindow) {
- Services.obs.removeObserver(onDOMWindowDestroyed, "dom-window-destroyed", false);
- windowDestroyedDeferred.resolve();
- }
- };
-
- let browserStartupDeferred = Promise.defer();
- Services.obs.addObserver(function onBrowserDelayedStartup(aWindow) {
- Services.obs.removeObserver(onBrowserDelayedStartup, "browser-delayed-startup-finished");
- browserStartupDeferred.resolve(aWindow);
- }, "browser-delayed-startup-finished", false);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, myDocIdentifier, myDocIdentifier => {
- let onVisibilityChange = () => {
- if (!content.document.hidden) {
- let win = Cu.waiveXrays(content);
- win.Mozilla.UITour.showHighlight("appMenu");
- }
- };
- content.document.addEventListener("visibilitychange", onVisibilityChange);
- content.document.myExpando = myDocIdentifier;
- });
- gContentAPI.showHighlight("appMenu");
-
- yield elementVisiblePromise(highlight);
-
- gContentWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
- yield browserStartupDeferred.promise;
-
- // This highlight should be shown thanks to the visibilitychange listener.
- let newWindowHighlight = gContentWindow.document.getElementById("UITourHighlight");
- yield elementVisiblePromise(newWindowHighlight);
-
- let selectedTab = gContentWindow.gBrowser.selectedTab;
- yield ContentTask.spawn(selectedTab.linkedBrowser, myDocIdentifier, myDocIdentifier => {
- is(content.document.myExpando, myDocIdentifier, "Document should be selected in new window");
- });
- ok(UITour.tourBrowsersByWindow && UITour.tourBrowsersByWindow.has(gContentWindow), "Window should be known");
- ok(UITour.tourBrowsersByWindow.get(gContentWindow).has(selectedTab.linkedBrowser), "Selected browser should be known");
-
- // Need this because gContentAPI in e10s land will try to use gTestTab to
- // spawn a content task, which doesn't work if the tab is dead, for obvious
- // reasons.
- gTestTab = gContentWindow.gBrowser.selectedTab;
-
- let shownPromise = promisePanelShown(gContentWindow);
- gContentAPI.showMenu("appMenu");
- yield shownPromise;
-
- isnot(gContentWindow.PanelUI.panel.state, "closed", "Panel should be open");
- ok(gContentWindow.PanelUI.contents.children.length > 0, "Panel contents should have children");
- gContentAPI.hideHighlight();
- gContentAPI.hideMenu("appMenu");
- gTestTab = null;
-
- Services.obs.addObserver(onDOMWindowDestroyed, "dom-window-destroyed", false);
- gContentWindow.close();
-
- yield windowDestroyedDeferred.promise;
- }),
-];
diff --git a/browser/components/uitour/test/browser_UITour_forceReaderMode.js b/browser/components/uitour/test/browser_UITour_forceReaderMode.js
deleted file mode 100644
index 5b5e883c3..000000000
--- a/browser/components/uitour/test/browser_UITour_forceReaderMode.js
+++ /dev/null
@@ -1,17 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function*() {
- ok(!gBrowser.selectedBrowser.isArticle, "Should not be an article when we start");
- ok(document.getElementById("reader-mode-button").hidden, "Button should be hidden.");
- yield gContentAPI.forceShowReaderIcon();
- yield waitForConditionPromise(() => gBrowser.selectedBrowser.isArticle);
- ok(gBrowser.selectedBrowser.isArticle, "Should suddenly be an article.");
- ok(!document.getElementById("reader-mode-button").hidden, "Button should now be visible.");
-});
-
diff --git a/browser/components/uitour/test/browser_UITour_heartbeat.js b/browser/components/uitour/test/browser_UITour_heartbeat.js
deleted file mode 100644
index 61be1d44b..000000000
--- a/browser/components/uitour/test/browser_UITour_heartbeat.js
+++ /dev/null
@@ -1,755 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-function getHeartbeatNotification(aId, aChromeWindow = window) {
- let notificationBox = aChromeWindow.document.getElementById("high-priority-global-notificationbox");
- // UITour.jsm prefixes the notification box ID with "heartbeat-" to prevent collisions.
- return notificationBox.getNotificationWithValue("heartbeat-" + aId);
-}
-
-/**
- * Simulate a click on a rating element in the Heartbeat notification.
- *
- * @param aId
- * The id of the notification box.
- * @param aScore
- * The score related to the rating element we want to click on.
- */
-function simulateVote(aId, aScore) {
- let notification = getHeartbeatNotification(aId);
-
- let ratingContainer = notification.childNodes[0];
- ok(ratingContainer, "The notification has a valid rating container.");
-
- let ratingElement = ratingContainer.getElementsByAttribute("data-score", aScore);
- ok(ratingElement[0], "The rating container contains the requested rating element.");
-
- ratingElement[0].click();
-}
-
-/**
- * Simulate a click on the learn-more link.
- *
- * @param aId
- * The id of the notification box.
- */
-function clickLearnMore(aId) {
- let notification = getHeartbeatNotification(aId);
-
- let learnMoreLabel = notification.childNodes[2];
- ok(learnMoreLabel, "The notification has a valid learn more label.");
-
- learnMoreLabel.click();
-}
-
-/**
- * Remove the notification box.
- *
- * @param aId
- * The id of the notification box to remove.
- * @param [aChromeWindow=window]
- * The chrome window the notification box is in.
- */
-function cleanUpNotification(aId, aChromeWindow = window) {
- let notification = getHeartbeatNotification(aId, aChromeWindow);
- notification.close();
-}
-
-/**
- * Check telemetry payload for proper format and expected content.
- *
- * @param aPayload
- * The Telemetry payload to verify
- * @param aFlowId
- * Expected value of the flowId field.
- * @param aExpectedFields
- * Array of expected fields. No other fields are allowed.
- */
-function checkTelemetry(aPayload, aFlowId, aExpectedFields) {
- // Basic payload format
- is(aPayload.version, 1, "Telemetry ping must have heartbeat version=1");
- is(aPayload.flowId, aFlowId, "Flow ID in the Telemetry ping must match");
-
- // Check for superfluous fields
- let extraKeys = new Set(Object.keys(aPayload));
- extraKeys.delete("version");
- extraKeys.delete("flowId");
-
- // Check for expected fields
- for (let field of aExpectedFields) {
- ok(field in aPayload, "The payload should have the field '" + field + "'");
- if (field.endsWith("TS")) {
- let ts = aPayload[field];
- ok(Number.isInteger(ts) && ts > 0, "Timestamp '" + field + "' must be a natural number");
- }
- extraKeys.delete(field);
- }
-
- is(extraKeys.size, 0, "No unexpected fields in the Telemetry payload");
-}
-
-/**
- * Waits for an UITour notification dispatched through |UITour.notify|. This should be
- * done with |gContentAPI.observe|. Unfortunately, in e10s, |gContentAPI.observe| doesn't
- * allow for multiple calls to the same callback, allowing to catch just the first
- * notification.
- *
- * @param aEventName
- * The notification name to wait for.
- * @return {Promise} Resolved with the data that comes with the event.
- */
-function promiseWaitHeartbeatNotification(aEventName) {
- return ContentTask.spawn(gTestTab.linkedBrowser, { aEventName },
- function({ aEventName }) {
- return new Promise(resolve => {
- addEventListener("mozUITourNotification", function listener(event) {
- if (event.detail.event !== aEventName) {
- return;
- }
- removeEventListener("mozUITourNotification", listener, false);
- resolve(event.detail.params);
- }, false);
- });
- });
-}
-
-/**
- * Waits for UITour notifications dispatched through |UITour.notify|. This works like
- * |promiseWaitHeartbeatNotification|, but waits for all the passed notifications to
- * be received before resolving. If it receives an unaccounted notification, it rejects.
- *
- * @param events
- * An array of expected notification names to wait for.
- * @return {Promise} Resolved with the data that comes with the event. Rejects with the
- * name of an undesired notification if received.
- */
-function promiseWaitExpectedNotifications(events) {
- return ContentTask.spawn(gTestTab.linkedBrowser, { events },
- function({ events }) {
- let stillToReceive = events;
- return new Promise((res, rej) => {
- addEventListener("mozUITourNotification", function listener(event) {
- if (stillToReceive.includes(event.detail.event)) {
- // Filter out the received event.
- stillToReceive = stillToReceive.filter(x => x !== event.detail.event);
- } else {
- removeEventListener("mozUITourNotification", listener, false);
- rej(event.detail.event);
- }
- // We still need to catch some notifications. Don't do anything.
- if (stillToReceive.length > 0) {
- return;
- }
- // We don't need to listen for other notifications. Resolve the promise.
- removeEventListener("mozUITourNotification", listener, false);
- res();
- }, false);
- });
- });
-}
-
-function validateTimestamp(eventName, timestamp) {
- info("'" + eventName + "' notification received (timestamp " + timestamp.toString() + ").");
- ok(Number.isFinite(timestamp), "Timestamp must be a number.");
-}
-
-add_task(function* test_setup() {
- yield setup_UITourTest();
- requestLongerTimeout(2);
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.uitour.surveyDuration");
- });
-});
-
-/**
- * Check that the "stars" heartbeat UI correctly shows and closes.
- */
-add_UITour_task(function* test_heartbeat_stars_show() {
- let flowId = "ui-ratefirefox-" + Math.random();
- let engagementURL = "http://example.com";
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(
- ["Heartbeat:NotificationOffered", "Heartbeat:NotificationClosed", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL);
-
- // Validate the returned timestamp.
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Close the heartbeat notification.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
- cleanUpNotification(flowId);
-
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
-
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received");
- checkTelemetry(data, flowId, ["offeredTS", "closedTS"]);
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Check that the heartbeat UI correctly takes optional icon URL.
- */
-add_UITour_task(function* test_heartbeat_take_optional_icon_URL() {
- let flowId = "ui-ratefirefox-" + Math.random();
- let engagementURL = "http://example.com";
- let iconURL = "chrome://branding/content/icon48.png";
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(
- ["Heartbeat:NotificationOffered", "Heartbeat:NotificationClosed", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL, null, null, {
- iconURL: iconURL
- });
-
- // Validate the returned timestamp.
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Check the icon URL
- let notification = getHeartbeatNotification(flowId);
- is(notification.image, iconURL, "The optional icon URL is not taken correctly");
-
- // Close the heartbeat notification.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
- cleanUpNotification(flowId);
-
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
-
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received");
- checkTelemetry(data, flowId, ["offeredTS", "closedTS"]);
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Test that the heartbeat UI correctly works with null engagement URL.
- */
-add_UITour_task(function* test_heartbeat_null_engagementURL() {
- let flowId = "ui-ratefirefox-" + Math.random();
- let originalTabCount = gBrowser.tabs.length;
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, null);
-
- // Validate the returned timestamp.
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so
- // wait for them here.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- // The UI was just shown. We can simulate a click on a rating element (i.e., "star").
- simulateVote(flowId, 2);
- data = yield votedPromise;
- validateTimestamp('Heartbeat:Voted', data.timestamp);
-
- // Validate the closing timestamp.
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
- is(gBrowser.tabs.length, originalTabCount, "No engagement tab should be opened.");
-
- // Validate the data we send out.
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]);
- is(data.score, 2, "Checking Telemetry payload.score");
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Test that the heartbeat UI correctly works with an invalid, but non null, engagement URL.
- */
-add_UITour_task(function* test_heartbeat_invalid_engagement_URL() {
- let flowId = "ui-ratefirefox-" + Math.random();
- let originalTabCount = gBrowser.tabs.length;
- let invalidEngagementURL = "invalidEngagement";
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, invalidEngagementURL);
-
- // Validate the returned timestamp.
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so
- // wait for them here.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- // The UI was just shown. We can simulate a click on a rating element (i.e., "star").
- simulateVote(flowId, 2);
- data = yield votedPromise;
- validateTimestamp('Heartbeat:Voted', data.timestamp);
-
- // Validate the closing timestamp.
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
- is(gBrowser.tabs.length, originalTabCount, "No engagement tab should be opened.");
-
- // Validate the data we send out.
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]);
- is(data.score, 2, "Checking Telemetry payload.score");
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Test that the score is correctly reported.
- */
-add_UITour_task(function* test_heartbeat_stars_vote() {
- const expectedScore = 4;
- let originalTabCount = gBrowser.tabs.length;
- let flowId = "ui-ratefirefox-" + Math.random();
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, null);
-
- // Validate the returned timestamp.
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so
- // wait for them here.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- // The UI was just shown. We can simulate a click on a rating element (i.e., "star").
- simulateVote(flowId, expectedScore);
- data = yield votedPromise;
- validateTimestamp('Heartbeat:Voted', data.timestamp);
- is(data.score, expectedScore, "Should report a score of " + expectedScore);
-
- // Validate the closing timestamp and vote.
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
- is(gBrowser.tabs.length, originalTabCount, "No engagement tab should be opened.");
-
- // Validate the data we send out.
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]);
- is(data.score, expectedScore, "Checking Telemetry payload.score");
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Test that the engagement page is correctly opened when voting.
- */
-add_UITour_task(function* test_heartbeat_engagement_tab() {
- let engagementURL = "http://example.com";
- let flowId = "ui-ratefirefox-" + Math.random();
- let originalTabCount = gBrowser.tabs.length;
- const expectedTabCount = originalTabCount + 1;
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL);
-
- // Validate the returned timestamp.
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so
- // wait for them here.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- // The UI was just shown. We can simulate a click on a rating element (i.e., "star").
- simulateVote(flowId, 1);
- data = yield votedPromise;
- validateTimestamp('Heartbeat:Voted', data.timestamp);
-
- // Validate the closing timestamp, vote and make sure the engagement page was opened.
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
- is(gBrowser.tabs.length, expectedTabCount, "Engagement URL should open in a new tab.");
- gBrowser.removeCurrentTab();
-
- // Validate the data we send out.
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]);
- is(data.score, 1, "Checking Telemetry payload.score");
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Test that the engagement button opens the engagement URL.
- */
-add_UITour_task(function* test_heartbeat_engagement_button() {
- let engagementURL = "http://example.com";
- let flowId = "ui-engagewithfirefox-" + Math.random();
- let originalTabCount = gBrowser.tabs.length;
- const expectedTabCount = originalTabCount + 1;
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:Engaged", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, null, null, {
- engagementButtonLabel: "Engage Me",
- });
-
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Wait an the Engaged, Closed and Telemetry Sent events. They are fired together, so
- // wait for them here.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let engagedPromise = promiseWaitHeartbeatNotification("Heartbeat:Engaged");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- // Simulate user engagement.
- let notification = getHeartbeatNotification(flowId);
- is(notification.querySelectorAll(".star-x").length, 0, "No stars should be present");
- // The UI was just shown. We can simulate a click on the engagement button.
- let engagementButton = notification.querySelector(".notification-button");
- is(engagementButton.label, "Engage Me", "Check engagement button text");
- engagementButton.doCommand();
-
- data = yield engagedPromise;
- validateTimestamp('Heartbeat:Engaged', data.timestamp);
-
- // Validate the closing timestamp, vote and make sure the engagement page was opened.
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
- is(gBrowser.tabs.length, expectedTabCount, "Engagement URL should open in a new tab.");
- gBrowser.removeCurrentTab();
-
- // Validate the data we send out.
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "engagedTS", "closedTS"]);
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Test that the learn more link is displayed and that the page is correctly opened when
- * clicking on it.
- */
-add_UITour_task(function* test_heartbeat_learnmore() {
- let dummyURL = "http://example.com";
- let flowId = "ui-ratefirefox-" + Math.random();
- let originalTabCount = gBrowser.tabs.length;
- const expectedTabCount = originalTabCount + 1;
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:LearnMore", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, dummyURL,
- "What is this?", dummyURL);
-
- let data = yield shownPromise;
- validateTimestamp('Heartbeat:Offered', data.timestamp);
-
- // Wait an the LearnMore, Closed and Telemetry Sent events. They are fired together, so
- // wait for them here.
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let learnMorePromise = promiseWaitHeartbeatNotification("Heartbeat:LearnMore");
- let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- // The UI was just shown. Simulate a click on the learn more link.
- clickLearnMore(flowId);
-
- data = yield learnMorePromise;
- validateTimestamp('Heartbeat:LearnMore', data.timestamp);
- cleanUpNotification(flowId);
-
- // The notification was closed.
- data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
- is(gBrowser.tabs.length, expectedTabCount, "Learn more URL should open in a new tab.");
- gBrowser.removeCurrentTab();
-
- // Validate the data we send out.
- data = yield pingSentPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "learnMoreTS", "closedTS"]);
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-add_UITour_task(function* test_invalidEngagementButtonLabel() {
- let engagementURL = "http://example.com";
- let flowId = "invalidEngagementButtonLabel-" + Math.random();
-
- let eventPromise = promisePageEvent();
-
- gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
- null, null, {
- engagementButtonLabel: 42,
- });
-
- yield eventPromise;
- ok(!isTourBrowser(gBrowser.selectedBrowser),
- "Invalid engagementButtonLabel should prevent init");
-
-})
-
-add_UITour_task(function* test_privateWindowsOnly_noneOpen() {
- let engagementURL = "http://example.com";
- let flowId = "privateWindowsOnly_noneOpen-" + Math.random();
-
- let eventPromise = promisePageEvent();
-
- gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
- null, null, {
- engagementButtonLabel: "Yes!",
- privateWindowsOnly: true,
- });
-
- yield eventPromise;
- ok(!isTourBrowser(gBrowser.selectedBrowser),
- "If there are no private windows opened, tour init should be prevented");
-})
-
-add_UITour_task(function* test_privateWindowsOnly_notMostRecent() {
- let engagementURL = "http://example.com";
- let flowId = "notMostRecent-" + Math.random();
-
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
- let mostRecentWin = yield BrowserTestUtils.openNewBrowserWindow();
-
- let eventPromise = promisePageEvent();
-
- gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
- null, null, {
- engagementButtonLabel: "Yes!",
- privateWindowsOnly: true,
- });
-
- yield eventPromise;
- is(getHeartbeatNotification(flowId, window), null,
- "Heartbeat shouldn't appear in the default window");
- is(!!getHeartbeatNotification(flowId, privateWin), true,
- "Heartbeat should appear in the most recent private window");
- is(getHeartbeatNotification(flowId, mostRecentWin), null,
- "Heartbeat shouldn't appear in the most recent non-private window");
-
- yield BrowserTestUtils.closeWindow(mostRecentWin);
- yield BrowserTestUtils.closeWindow(privateWin);
-})
-
-add_UITour_task(function* test_privateWindowsOnly() {
- let engagementURL = "http://example.com";
- let learnMoreURL = "http://example.org/learnmore/";
- let flowId = "ui-privateWindowsOnly-" + Math.random();
-
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
-
- yield new Promise((resolve) => {
- gContentAPI.observe(function(aEventName, aData) {
- info(aEventName + " notification received: " + JSON.stringify(aData, null, 2));
- ok(false, "No heartbeat notifications should arrive for privateWindowsOnly");
- }, resolve);
- });
-
- gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL,
- "Learn More", learnMoreURL, {
- engagementButtonLabel: "Yes!",
- privateWindowsOnly: true,
- });
-
- yield promisePageEvent();
-
- ok(isTourBrowser(gBrowser.selectedBrowser), "UITour should have been init for the browser");
-
- let notification = getHeartbeatNotification(flowId, privateWin);
-
- is(notification.querySelectorAll(".star-x").length, 0, "No stars should be present");
-
- info("Test the learn more link.");
- let learnMoreLink = notification.querySelector(".text-link");
- is(learnMoreLink.value, "Learn More", "Check learn more label");
- let learnMoreTabPromise = BrowserTestUtils.waitForNewTab(privateWin.gBrowser, null);
- learnMoreLink.click();
- let learnMoreTab = yield learnMoreTabPromise;
- is(learnMoreTab.linkedBrowser.currentURI.host, "example.org", "Check learn more site opened");
- ok(PrivateBrowsingUtils.isBrowserPrivate(learnMoreTab.linkedBrowser), "Ensure the learn more tab is private");
- yield BrowserTestUtils.removeTab(learnMoreTab);
-
- info("Test the engagement button's new tab.");
- let engagementButton = notification.querySelector(".notification-button");
- is(engagementButton.label, "Yes!", "Check engagement button text");
- let engagementTabPromise = BrowserTestUtils.waitForNewTab(privateWin.gBrowser, null);
- engagementButton.doCommand();
- let engagementTab = yield engagementTabPromise;
- is(engagementTab.linkedBrowser.currentURI.host, "example.com", "Check enagement site opened");
- ok(PrivateBrowsingUtils.isBrowserPrivate(engagementTab.linkedBrowser), "Ensure the engagement tab is private");
- yield BrowserTestUtils.removeTab(engagementTab);
-
- yield BrowserTestUtils.closeWindow(privateWin);
-})
-
-/**
- * Test that the survey closes itself after a while and submits Telemetry
- */
-add_UITour_task(function* test_telemetry_surveyExpired() {
- let flowId = "survey-expired-" + Math.random();
- let engagementURL = "http://example.com";
- let surveyDuration = 1; // 1 second (pref is in seconds)
- Services.prefs.setIntPref("browser.uitour.surveyDuration", surveyDuration);
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered",
- "Heartbeat:NotificationClosed", "Heartbeat:SurveyExpired", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL);
-
- let expiredPromise = promiseWaitHeartbeatNotification("Heartbeat:SurveyExpired");
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let pingPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
-
- yield Promise.all([shownPromise, expiredPromise, closedPromise]);
- // Validate the ping data.
- let data = yield pingPromise;
- checkTelemetry(data, flowId, ["offeredTS", "expiredTS", "closedTS"]);
-
- Services.prefs.clearUserPref("browser.uitour.surveyDuration");
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
-
-/**
- * Check that certain whitelisted experiment parameters get reflected in the
- * Telemetry ping
- */
-add_UITour_task(function* test_telemetry_params() {
- let flowId = "telemetry-params-" + Math.random();
- let engagementURL = "http://example.com";
- let extraParams = {
- "surveyId": "foo",
- "surveyVersion": 1.5,
- "testing": true,
- "notWhitelisted": 123,
- };
- let expectedFields = ["surveyId", "surveyVersion", "testing"];
-
- // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener|
- // in UITour-lib.js, otherwise no message will get propagated.
- gContentAPI.observe(() => {});
-
- let receivedExpectedPromise = promiseWaitExpectedNotifications(
- ["Heartbeat:NotificationOffered", "Heartbeat:NotificationClosed", "Heartbeat:TelemetrySent"]);
-
- // Show the Heartbeat notification and wait for it to be displayed.
- let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered");
- gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!",
- flowId, engagementURL, null, null, extraParams);
- yield shownPromise;
-
- let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed");
- let pingPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent");
- cleanUpNotification(flowId);
-
- // The notification was closed.
- let data = yield closedPromise;
- validateTimestamp('Heartbeat:NotificationClosed', data.timestamp);
-
- // Validate the data we send out.
- data = yield pingPromise;
- info("'Heartbeat:TelemetrySent' notification received.");
- checkTelemetry(data, flowId, ["offeredTS", "closedTS"].concat(expectedFields));
- for (let param of expectedFields) {
- is(data[param], extraParams[param],
- "Whitelisted experiment configs should be copied into Telemetry pings");
- }
-
- // This rejects whenever an unexpected notification is received.
- yield receivedExpectedPromise;
-})
diff --git a/browser/components/uitour/test/browser_UITour_modalDialog.js b/browser/components/uitour/test/browser_UITour_modalDialog.js
deleted file mode 100644
index 1890739c4..000000000
--- a/browser/components/uitour/test/browser_UITour_modalDialog.js
+++ /dev/null
@@ -1,104 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-var handleDialog;
-
-// Modified from toolkit/components/passwordmgr/test/prompt_common.js
-var didDialog;
-
-var timer; // keep in outer scope so it's not GC'd before firing
-function startCallbackTimer() {
- didDialog = false;
-
- // Delay before the callback twiddles the prompt.
- const dialogDelay = 10;
-
- // Use a timer to invoke a callback to twiddle the authentication dialog
- timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
-}
-
-
-var observer = SpecialPowers.wrapCallbackObject({
- QueryInterface : function (iid) {
- const interfaces = [Ci.nsIObserver,
- Ci.nsISupports, Ci.nsISupportsWeakReference];
-
- if (!interfaces.some( function(v) { return iid.equals(v) } ))
- throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- },
-
- observe : function (subject, topic, data) {
- var doc = getDialogDoc();
- if (doc)
- handleDialog(doc);
- else
- startCallbackTimer(); // try again in a bit
- }
-});
-
-function getDialogDoc() {
- // Find the <browser> which contains notifyWindow, by looking
- // through all the open windows and all the <browsers> in each.
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator);
- // var enumerator = wm.getEnumerator("navigator:browser");
- var enumerator = wm.getXULWindowEnumerator(null);
-
- while (enumerator.hasMoreElements()) {
- var win = enumerator.getNext();
- var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
-
- var containedDocShells = windowDocShell.getDocShellEnumerator(
- Ci.nsIDocShellTreeItem.typeChrome,
- Ci.nsIDocShell.ENUMERATE_FORWARDS);
- while (containedDocShells.hasMoreElements()) {
- // Get the corresponding document for this docshell
- var childDocShell = containedDocShells.getNext();
- // We don't want it if it's not done loading.
- if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
- continue;
- var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
- .contentViewer
- .DOMDocument;
-
- // ok(true, "Got window: " + childDoc.location.href);
- if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
- return childDoc;
- }
- }
-
- return null;
-}
-
-function test() {
- UITourTest();
-}
-
-
-var tests = [
- taskify(function* test_modal_dialog_while_opening_tooltip() {
- let panelShown;
- let popup;
-
- handleDialog = (doc) => {
- popup = document.getElementById("UITourTooltip");
- gContentAPI.showInfo("appMenu", "test title", "test text");
- doc.defaultView.setTimeout(function() {
- is(popup.state, "closed", "Popup shouldn't be shown while dialog is up");
- panelShown = promisePanelElementShown(window, popup);
- let dialog = doc.getElementById("commonDialog");
- dialog.acceptDialog();
- }, 1000);
- };
- startCallbackTimer();
- executeSoon(() => alert("test"));
- yield waitForConditionPromise(() => panelShown, "Timed out waiting for panel promise to be assigned", 100);
- yield panelShown;
-
- yield hideInfoPromise();
- })
-];
diff --git a/browser/components/uitour/test/browser_UITour_observe.js b/browser/components/uitour/test/browser_UITour_observe.js
deleted file mode 100644
index b4b435659..000000000
--- a/browser/components/uitour/test/browser_UITour_observe.js
+++ /dev/null
@@ -1,85 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-function test() {
- requestLongerTimeout(2);
- UITourTest();
-}
-
-var tests = [
- function test_no_params(done) {
- function listener(event, params) {
- is(event, "test-event-1", "Correct event name");
- is(params, null, "No param object");
- gContentAPI.observe(null);
- done();
- }
-
- gContentAPI.observe(listener, () => {
- UITour.notify("test-event-1");
- });
- },
- function test_param_string(done) {
- function listener(event, params) {
- is(event, "test-event-2", "Correct event name");
- is(params, "a param", "Correct param string");
- gContentAPI.observe(null);
- done();
- }
-
- gContentAPI.observe(listener, () => {
- UITour.notify("test-event-2", "a param");
- });
- },
- function test_param_object(done) {
- function listener(event, params) {
- is(event, "test-event-3", "Correct event name");
- is(JSON.stringify(params), JSON.stringify({key: "something"}), "Correct param object");
- gContentAPI.observe(null);
- done();
- }
-
- gContentAPI.observe(listener, () => {
- UITour.notify("test-event-3", {key: "something"});
- });
- },
- function test_background_tab(done) {
- function listener(event, params) {
- is(event, "test-event-background-1", "Correct event name");
- is(params, null, "No param object");
- gContentAPI.observe(null);
- gBrowser.removeCurrentTab();
- done();
- }
-
- gContentAPI.observe(listener, () => {
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- isnot(gBrowser.selectedTab, gTestTab, "Make sure the selected tab changed");
-
- UITour.notify("test-event-background-1");
- });
- },
- // Make sure the tab isn't torn down when switching back to the tour one.
- function test_background_then_foreground_tab(done) {
- let blankTab = null;
- function listener(event, params) {
- is(event, "test-event-4", "Correct event name");
- is(params, null, "No param object");
- gContentAPI.observe(null);
- gBrowser.removeTab(blankTab);
- done();
- }
-
- gContentAPI.observe(listener, () => {
- blankTab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
- isnot(gBrowser.selectedTab, gTestTab, "Make sure the selected tab changed");
- gBrowser.selectedTab = gTestTab;
- is(gBrowser.selectedTab, gTestTab, "Switch back to the test tab");
-
- UITour.notify("test-event-4");
- });
- },
-];
diff --git a/browser/components/uitour/test/browser_UITour_panel_close_annotation.js b/browser/components/uitour/test/browser_UITour_panel_close_annotation.js
deleted file mode 100644
index cff446573..000000000
--- a/browser/components/uitour/test/browser_UITour_panel_close_annotation.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that annotations disappear when their target is hidden.
- */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-var highlight = document.getElementById("UITourHighlight");
-var tooltip = document.getElementById("UITourTooltip");
-
-function test() {
- registerCleanupFunction(() => {
- // Close the find bar in case it's open in the remaining tab
- gBrowser.getFindBar(gBrowser.selectedTab).close();
- });
- UITourTest();
-}
-
-var tests = [
- function test_highlight_move_outside_panel(done) {
- gContentAPI.showInfo("urlbar", "test title", "test text");
- gContentAPI.showHighlight("customize");
- waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Move the highlight outside which should close the app menu.
- gContentAPI.showHighlight("appMenu");
- waitForPopupAtAnchor(highlight.parentElement, document.getElementById("PanelUI-button"), () => {
- isnot(PanelUI.panel.state, "open",
- "Panel should have closed after the highlight moved elsewhere.");
- ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open");
- done();
- }, "Highlight should move to the appMenu button and still be visible");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
-
- function test_highlight_panel_hideMenu(done) {
- gContentAPI.showHighlight("customize");
- gContentAPI.showInfo("search", "test title", "test text");
- waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Close the app menu and make sure the highlight also disappeared.
- gContentAPI.hideMenu("appMenu");
- waitForElementToBeHidden(highlight, function checkPanelIsClosed() {
- isnot(PanelUI.panel.state, "open",
- "Panel still should have closed");
- ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open");
- done();
- }, "Highlight should have disappeared when panel closed");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
-
- function test_highlight_panel_click_find(done) {
- gContentAPI.showHighlight("help");
- gContentAPI.showInfo("searchIcon", "test title", "test text");
- waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Click the find button which should close the panel.
- let findButton = document.getElementById("find-button");
- EventUtils.synthesizeMouseAtCenter(findButton, {});
- waitForElementToBeHidden(highlight, function checkPanelIsClosed() {
- isnot(PanelUI.panel.state, "open",
- "Panel should have closed when the find bar opened");
- ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open");
- done();
- }, "Highlight should have disappeared when panel closed");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
-
- function test_highlight_info_panel_click_find(done) {
- gContentAPI.showHighlight("help");
- gContentAPI.showInfo("customize", "customize me!", "awesome!");
- waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Click the find button which should close the panel.
- let findButton = document.getElementById("find-button");
- EventUtils.synthesizeMouseAtCenter(findButton, {});
- waitForElementToBeHidden(highlight, function checkPanelIsClosed() {
- isnot(PanelUI.panel.state, "open",
- "Panel should have closed when the find bar opened");
- waitForElementToBeHidden(tooltip, function checkTooltipIsClosed() {
- isnot(tooltip.state, "open", "The info panel should have closed too");
- done();
- }, "Tooltip should hide with the menu");
- }, "Highlight should have disappeared when panel closed");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
-
- function test_highlight_panel_open_subview(done) {
- gContentAPI.showHighlight("customize");
- gContentAPI.showInfo("backForward", "test title", "test text");
- waitForElementToBeVisible(highlight, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Click the help button which should open the subview in the panel menu.
- let helpButton = document.getElementById("PanelUI-help");
- EventUtils.synthesizeMouseAtCenter(helpButton, {});
- waitForElementToBeHidden(highlight, function highlightHidden() {
- is(PanelUI.panel.state, "open",
- "Panel should have stayed open when the subview opened");
- ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open");
- PanelUI.hide();
- done();
- }, "Highlight should have disappeared when the subview opened");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
-
- function test_info_panel_open_subview(done) {
- gContentAPI.showHighlight("urlbar");
- gContentAPI.showInfo("customize", "customize me!", "Open a subview");
- waitForElementToBeVisible(tooltip, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Click the help button which should open the subview in the panel menu.
- let helpButton = document.getElementById("PanelUI-help");
- EventUtils.synthesizeMouseAtCenter(helpButton, {});
- waitForElementToBeHidden(tooltip, function tooltipHidden() {
- is(PanelUI.panel.state, "open",
- "Panel should have stayed open when the subview opened");
- is(highlight.parentElement.state, "open", "The highlight should have remained open");
- PanelUI.hide();
- done();
- }, "Tooltip should have disappeared when the subview opened");
- }, "Highlight should be shown after showHighlight() for fixed panel items");
- },
-
- function test_info_move_outside_panel(done) {
- gContentAPI.showInfo("addons", "test title", "test text");
- gContentAPI.showHighlight("urlbar");
- let addonsButton = document.getElementById("add-ons-button");
- waitForPopupAtAnchor(tooltip, addonsButton, function checkPanelIsOpen() {
- isnot(PanelUI.panel.state, "closed", "Panel should have opened");
-
- // Move the info panel outside which should close the app menu.
- gContentAPI.showInfo("appMenu", "Cool menu button", "It's three lines");
- waitForPopupAtAnchor(tooltip, document.getElementById("PanelUI-button"), () => {
- isnot(PanelUI.panel.state, "open",
- "Menu should have closed after the highlight moved elsewhere.");
- is(highlight.parentElement.state, "open", "The highlight should have remained visible");
- done();
- }, "Tooltip should move to the appMenu button and still be visible");
- }, "Tooltip should be shown after showInfo() for a panel item");
- },
-
-];
diff --git a/browser/components/uitour/test/browser_UITour_pocket.js b/browser/components/uitour/test/browser_UITour_pocket.js
deleted file mode 100644
index 29548a475..000000000
--- a/browser/components/uitour/test/browser_UITour_pocket.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-var button;
-
-function test() {
- UITourTest();
-}
-
-var tests = [
- taskify(function* test_menu_show_navbar() {
- is(button.open, false, "Menu should initially be closed");
- gContentAPI.showMenu("pocket");
-
- // The panel gets created dynamically.
- let widgetPanel = null;
- yield waitForConditionPromise(() => {
- widgetPanel = document.getElementById("customizationui-widget-panel");
- return widgetPanel && widgetPanel.state == "open";
- }, "Menu should be visible after showMenu()");
-
- ok(button.open, "Button should know its view is open");
- ok(!widgetPanel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
- ok(button.hasAttribute("open"), "Pocket button should know that the menu is open");
-
- widgetPanel.hidePopup();
- checkPanelIsHidden(widgetPanel);
- }),
- taskify(function* test_menu_show_appMenu() {
- CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_PANEL);
-
- is(PanelUI.multiView.hasAttribute("panelopen"), false, "Multiview should initially be closed");
- gContentAPI.showMenu("pocket");
-
- yield waitForConditionPromise(() => {
- return PanelUI.panel.state == "open";
- }, "Menu should be visible after showMenu()");
-
- ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
- ok(PanelUI.multiView.showingSubView, "Subview should be open");
- ok(PanelUI.multiView.hasAttribute("panelopen"), "Multiview should know it's open");
-
- PanelUI.showMainView();
- PanelUI.panel.hidePopup();
- checkPanelIsHidden(PanelUI.panel);
- }),
-];
-
-// End tests
-
-function checkPanelIsHidden(aPanel) {
- if (aPanel.parentElement) {
- is_hidden(aPanel);
- } else {
- ok(!aPanel.parentElement, "Widget panel should have been removed");
- }
- is(button.hasAttribute("open"), false, "Pocket button should know that the panel is closed");
-}
-
-if (Services.prefs.getBoolPref("extensions.pocket.enabled")) {
- let placement = CustomizableUI.getPlacementOfWidget("pocket-button");
-
- // Add the button to the nav-bar by default.
- if (!placement || placement.area != CustomizableUI.AREA_NAVBAR) {
- CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_NAVBAR);
- }
- registerCleanupFunction(() => {
- CustomizableUI.reset();
- });
-
- let widgetGroupWrapper = CustomizableUI.getWidget("pocket-button");
- button = widgetGroupWrapper.forWindow(window).node;
- ok(button, "Got button node");
-} else {
- todo(false, "Pocket is disabled so skip its UITour tests");
- tests = [];
-}
diff --git a/browser/components/uitour/test/browser_UITour_registerPageID.js b/browser/components/uitour/test/browser_UITour_registerPageID.js
deleted file mode 100644
index 369abb1ed..000000000
--- a/browser/components/uitour/test/browser_UITour_registerPageID.js
+++ /dev/null
@@ -1,108 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-Components.utils.import("resource://gre/modules/UITelemetry.jsm");
-Components.utils.import("resource:///modules/BrowserUITelemetry.jsm");
-
-add_task(function* setup_telemetry() {
- UITelemetry._enabled = true;
-
- registerCleanupFunction(function() {
- Services.prefs.clearUserPref("browser.uitour.seenPageIDs");
- resetSeenPageIDsLazyGetter();
- UITelemetry._enabled = undefined;
- BrowserUITelemetry.setBucket(null);
- delete window.UITelemetry;
- delete window.BrowserUITelemetry;
- });
-});
-
-add_task(setup_UITourTest);
-
-function resetSeenPageIDsLazyGetter() {
- delete UITour.seenPageIDs;
- // This should be kept in sync with how UITour.init() sets this.
- Object.defineProperty(UITour, "seenPageIDs", {
- get: UITour.restoreSeenPageIDs.bind(UITour),
- configurable: true,
- });
-}
-
-function checkExpectedSeenPageIDs(expected) {
- is(UITour.seenPageIDs.size, expected.length, "Should be " + expected.length + " total seen page IDs");
-
- for (let id of expected)
- ok(UITour.seenPageIDs.has(id), "Should have seen '" + id + "' page ID");
-
- let prefData = Services.prefs.getCharPref("browser.uitour.seenPageIDs");
- prefData = new Map(JSON.parse(prefData));
-
- is(prefData.size, expected.length, "Should be " + expected.length + " total seen page IDs persisted");
-
- for (let id of expected)
- ok(prefData.has(id), "Should have seen '" + id + "' page ID persisted");
-}
-
-
-add_UITour_task(function test_seenPageIDs_restore() {
- info("Setting up seenPageIDs to be restored from pref");
- let data = JSON.stringify([
- ["savedID1", { lastSeen: Date.now() }],
- ["savedID2", { lastSeen: Date.now() }],
- // 9 weeks ago, should auto expire.
- ["savedID3", { lastSeen: Date.now() - 9 * 7 * 24 * 60 * 60 * 1000 }],
- ]);
- Services.prefs.setCharPref("browser.uitour.seenPageIDs",
- data);
-
- resetSeenPageIDsLazyGetter();
- checkExpectedSeenPageIDs(["savedID1", "savedID2"]);
-});
-
-add_UITour_task(function* test_seenPageIDs_set_1() {
- yield gContentAPI.registerPageID("testpage1");
-
- yield waitForConditionPromise(() => UITour.seenPageIDs.size == 3, "Waiting for page to be registered.");
-
- checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1"]);
-
- const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
- const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
-
- let bucket = PREFIX + "UITour" + SEP + "testpage1";
- is(BrowserUITelemetry.currentBucket, bucket, "Bucket should have correct name");
-
- gBrowser.selectedTab = gBrowser.addTab("about:blank");
- bucket = PREFIX + "UITour" + SEP + "testpage1" + SEP + "inactive" + SEP + "1m";
- is(BrowserUITelemetry.currentBucket, bucket,
- "After switching tabs, bucket should be expiring");
-
- gBrowser.removeTab(gBrowser.selectedTab);
- gBrowser.selectedTab = gTestTab;
- BrowserUITelemetry.setBucket(null);
-});
-
-add_UITour_task(function* test_seenPageIDs_set_2() {
- yield gContentAPI.registerPageID("testpage2");
-
- yield waitForConditionPromise(() => UITour.seenPageIDs.size == 4, "Waiting for page to be registered.");
-
- checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1", "testpage2"]);
-
- const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
- const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
-
- let bucket = PREFIX + "UITour" + SEP + "testpage2";
- is(BrowserUITelemetry.currentBucket, bucket, "Bucket should have correct name");
-
- gBrowser.removeTab(gTestTab);
- gTestTab = null;
- bucket = PREFIX + "UITour" + SEP + "testpage2" + SEP + "closed" + SEP + "1m";
- is(BrowserUITelemetry.currentBucket, bucket,
- "After closing tab, bucket should be expiring");
-
- BrowserUITelemetry.setBucket(null);
-});
diff --git a/browser/components/uitour/test/browser_UITour_resetProfile.js b/browser/components/uitour/test/browser_UITour_resetProfile.js
deleted file mode 100644
index c91d0a4f2..000000000
--- a/browser/components/uitour/test/browser_UITour_resetProfile.js
+++ /dev/null
@@ -1,48 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-// Test that a reset profile dialog appears when "resetFirefox" event is triggered
-add_UITour_task(function* test_resetFirefox() {
- let canReset = yield getConfigurationPromise("canReset");
- ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile.");
- let dialogPromise = new Promise((resolve) => {
- let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIWindowWatcher);
- winWatcher.registerNotification(function onOpen(subj, topic, data) {
- if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
- subj.addEventListener("load", function onLoad() {
- subj.removeEventListener("load", onLoad);
- if (subj.document.documentURI ==
- "chrome://global/content/resetProfile.xul") {
- winWatcher.unregisterNotification(onOpen);
- ok(true, "Observed search manager window open");
- is(subj.opener, window,
- "Reset Firefox event opened a reset profile window.");
- subj.close();
- resolve();
- }
- });
- }
- });
- });
-
- // make reset possible.
- let profileService = Cc["@mozilla.org/toolkit/profile-service;1"].
- getService(Ci.nsIToolkitProfileService);
- let currentProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
- let profileName = "mochitest-test-profile-temp-" + Date.now();
- let tempProfile = profileService.createProfile(currentProfileDir, profileName);
- canReset = yield getConfigurationPromise("canReset");
- ok(canReset, "Should be able to reset from mochitest's temporary profile once it's in the profile manager.");
- yield gContentAPI.resetFirefox();
- yield dialogPromise;
- tempProfile.remove(false);
- canReset = yield getConfigurationPromise("canReset");
- ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile once removed from the profile manager.");
-});
-
diff --git a/browser/components/uitour/test/browser_UITour_showNewTab.js b/browser/components/uitour/test/browser_UITour_showNewTab.js
deleted file mode 100644
index 2deb08148..000000000
--- a/browser/components/uitour/test/browser_UITour_showNewTab.js
+++ /dev/null
@@ -1,17 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-// Test that we can switch to about:newtab
-add_UITour_task(function* test_aboutNewTab() {
- let newTabLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, "about:newtab");
- info("Showing about:newtab");
- yield gContentAPI.showNewTab();
- info("Waiting for about:newtab to load");
- yield newTabLoaded;
- is(gBrowser.selectedBrowser.currentURI.spec, "about:newtab", "Loaded about:newtab");
-});
diff --git a/browser/components/uitour/test/browser_UITour_sync.js b/browser/components/uitour/test/browser_UITour_sync.js
deleted file mode 100644
index 14ac0c1f6..000000000
--- a/browser/components/uitour/test/browser_UITour_sync.js
+++ /dev/null
@@ -1,105 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-registerCleanupFunction(function() {
- Services.prefs.clearUserPref("services.sync.username");
-});
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_checkSyncSetup_disabled() {
- let result = yield getConfigurationPromise("sync");
- is(result.setup, false, "Sync shouldn't be setup by default");
-});
-
-add_UITour_task(function* test_checkSyncSetup_enabled() {
- Services.prefs.setCharPref("services.sync.username", "uitour@tests.mozilla.org");
- let result = yield getConfigurationPromise("sync");
- is(result.setup, true, "Sync should be setup");
-});
-
-add_UITour_task(function* test_checkSyncCounts() {
- Services.prefs.setIntPref("services.sync.clients.devices.desktop", 4);
- Services.prefs.setIntPref("services.sync.clients.devices.mobile", 5);
- Services.prefs.setIntPref("services.sync.numClients", 9);
- let result = yield getConfigurationPromise("sync");
- is(result.mobileDevices, 5, "mobileDevices should be set");
- is(result.desktopDevices, 4, "desktopDevices should be set");
- is(result.totalDevices, 9, "totalDevices should be set");
-
- Services.prefs.clearUserPref("services.sync.clients.devices.desktop");
- result = yield getConfigurationPromise("sync");
- is(result.mobileDevices, 5, "mobileDevices should be set");
- is(result.desktopDevices, 0, "desktopDevices should be 0");
- is(result.totalDevices, 9, "totalDevices should be set");
-
- Services.prefs.clearUserPref("services.sync.clients.devices.mobile");
- result = yield getConfigurationPromise("sync");
- is(result.mobileDevices, 0, "mobileDevices should be 0");
- is(result.desktopDevices, 0, "desktopDevices should be 0");
- is(result.totalDevices, 9, "totalDevices should be set");
-
- Services.prefs.clearUserPref("services.sync.numClients");
- result = yield getConfigurationPromise("sync");
- is(result.mobileDevices, 0, "mobileDevices should be 0");
- is(result.desktopDevices, 0, "desktopDevices should be 0");
- is(result.totalDevices, 0, "totalDevices should be 0");
-});
-
-// The showFirefoxAccounts API is sync related, so we test that here too...
-add_UITour_task(function* test_firefoxAccountsNoParams() {
- yield gContentAPI.showFirefoxAccounts();
- yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false,
- "about:accounts?action=signup&entrypoint=uitour");
-});
-
-add_UITour_task(function* test_firefoxAccountsValidParams() {
- yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", utm_bar: "bar" });
- yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false,
- "about:accounts?action=signup&entrypoint=uitour&utm_foo=foo&utm_bar=bar");
-});
-
-add_UITour_task(function* test_firefoxAccountsNonAlphaValue() {
- // All characters in the value are allowed, but they must be automatically escaped.
- // (we throw a unicode character in there too - it's not auto-utf8 encoded,
- // but that's ok, so long as it is escaped correctly.)
- let value = "foo& /=?:\\\xa9";
- // encodeURIComponent encodes spaces to %20 but we want "+"
- let expected = encodeURIComponent(value).replace(/%20/g, "+");
- yield gContentAPI.showFirefoxAccounts({ utm_foo: value });
- yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false,
- "about:accounts?action=signup&entrypoint=uitour&utm_foo=" + expected);
-});
-
-// A helper to check the request was ignored due to invalid params.
-function* checkAboutAccountsNotLoaded() {
- try {
- yield waitForConditionPromise(() => {
- return gBrowser.selectedBrowser.currentURI.spec.startsWith("about:accounts");
- }, "Check if about:accounts opened");
- ok(false, "No about:accounts tab should have opened");
- } catch (ex) {
- ok(true, "No about:accounts tab opened");
- }
-}
-
-add_UITour_task(function* test_firefoxAccountsNonObject() {
- // non-string should be rejected.
- yield gContentAPI.showFirefoxAccounts(99);
- yield checkAboutAccountsNotLoaded();
-});
-
-add_UITour_task(function* test_firefoxAccountsNonUtmPrefix() {
- // Any non "utm_" name should should be rejected.
- yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", bar: "bar" });
- yield checkAboutAccountsNotLoaded();
-});
-
-add_UITour_task(function* test_firefoxAccountsNonAlphaName() {
- // Any "utm_" name which includes non-alpha chars should be rejected.
- yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", "utm_bar=": "bar" });
- yield checkAboutAccountsNotLoaded();
-});
diff --git a/browser/components/uitour/test/browser_UITour_toggleReaderMode.js b/browser/components/uitour/test/browser_UITour_toggleReaderMode.js
deleted file mode 100644
index 58313e74b..000000000
--- a/browser/components/uitour/test/browser_UITour_toggleReaderMode.js
+++ /dev/null
@@ -1,16 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function*() {
- ok(!gBrowser.selectedBrowser.currentURI.spec.startsWith("about:reader"),
- "Should not be in reader mode at start of test.");
- yield gContentAPI.toggleReaderMode();
- yield waitForConditionPromise(() => gBrowser.selectedBrowser.currentURI.spec.startsWith("about:reader"));
- ok(gBrowser.selectedBrowser.currentURI.spec.startsWith("about:reader"),
- "Should be in reader mode now.");
-});
diff --git a/browser/components/uitour/test/browser_backgroundTab.js b/browser/components/uitour/test/browser_backgroundTab.js
deleted file mode 100644
index c4117c698..000000000
--- a/browser/components/uitour/test/browser_backgroundTab.js
+++ /dev/null
@@ -1,46 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-requestLongerTimeout(2);
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_bg_getConfiguration() {
- info("getConfiguration is on the allowed list so should work");
- yield* loadForegroundTab();
- let data = yield getConfigurationPromise("availableTargets");
- ok(data, "Got data from getConfiguration");
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-add_UITour_task(function* test_bg_showInfo() {
- info("showInfo isn't on the allowed action list so should be denied");
- yield* loadForegroundTab();
-
- yield showInfoPromise("appMenu", "Hello from the background", "Surprise!").then(
- () => ok(false, "panel shouldn't have shown from a background tab"),
- () => ok(true, "panel wasn't shown from a background tab"));
-
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-
-function* loadForegroundTab() {
- // Spawn a content task that resolves once we're sure the visibilityState was
- // changed. This state is what the tests in this file rely on.
- let promise = ContentTask.spawn(gBrowser.selectedTab.linkedBrowser, null, function* () {
- return new Promise(resolve => {
- let document = content.document;
- document.addEventListener("visibilitychange", function onStateChange() {
- Assert.equal(document.visibilityState, "hidden", "UITour page should be hidden now.");
- document.removeEventListener("visibilitychange", onStateChange);
- resolve();
- });
- });
- });
- yield BrowserTestUtils.openNewForegroundTab(gBrowser);
- yield promise;
- isnot(gBrowser.selectedTab, gTestTab, "Make sure tour tab isn't selected");
-}
diff --git a/browser/components/uitour/test/browser_closeTab.js b/browser/components/uitour/test/browser_closeTab.js
deleted file mode 100644
index 2b998347a..000000000
--- a/browser/components/uitour/test/browser_closeTab.js
+++ /dev/null
@@ -1,18 +0,0 @@
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_closeTab() {
- // Setting gTestTab to null indicates that the tab has already been closed,
- // and if this does not happen the test run will fail.
- let closePromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
- yield gContentAPI.closeTab();
- yield closePromise;
- gTestTab = null;
-});
diff --git a/browser/components/uitour/test/browser_fxa.js b/browser/components/uitour/test/browser_fxa.js
deleted file mode 100644
index 36ac45a62..000000000
--- a/browser/components/uitour/test/browser_fxa.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
- "resource://gre/modules/FxAccounts.jsm");
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-function test() {
- UITourTest();
-}
-
-registerCleanupFunction(function*() {
- yield signOut();
- gFxAccounts.updateAppMenuItem();
-});
-
-var tests = [
- taskify(function* test_highlight_accountStatus_loggedOut() {
- let userData = yield fxAccounts.getSignedInUser();
- is(userData, null, "Not logged in initially");
- yield showMenuPromise("appMenu");
- yield showHighlightPromise("accountStatus");
- let highlight = document.getElementById("UITourHighlightContainer");
- is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target");
- }),
-
- taskify(function* test_highlight_accountStatus_loggedIn() {
- yield setSignedInUser();
- let userData = yield fxAccounts.getSignedInUser();
- isnot(userData, null, "Logged in now");
- gFxAccounts.updateAppMenuItem(); // Causes a leak
- yield showMenuPromise("appMenu");
- yield showHighlightPromise("accountStatus");
- let highlight = document.getElementById("UITourHighlightContainer");
- is(highlight.popupBoxObject.anchorNode.id, "PanelUI-fxa-avatar", "Anchored on avatar");
- is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target");
- }),
-];
-
-// Helpers copied from browser_aboutAccounts.js
-// watch out - these will fire observers which if you aren't careful, may
-// interfere with the tests.
-function setSignedInUser(data) {
- if (!data) {
- data = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- assertion: "foobar",
- sessionToken: "dead",
- kA: "beef",
- kB: "cafe",
- verified: true
- };
- }
- return fxAccounts.setSignedInUser(data);
-}
-
-function signOut() {
- // we always want a "localOnly" signout here...
- return fxAccounts.signOut(true);
-}
diff --git a/browser/components/uitour/test/browser_no_tabs.js b/browser/components/uitour/test/browser_no_tabs.js
deleted file mode 100644
index 62048b156..000000000
--- a/browser/components/uitour/test/browser_no_tabs.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var HiddenFrame = Cu.import("resource:///modules/HiddenFrame.jsm", {}).HiddenFrame;
-
-const HTML_NS = "http://www.w3.org/1999/xhtml";
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-/**
- * Create a frame in the |hiddenDOMWindow| to host a |browser|, then load the URL in the
- * latter.
- *
- * @param aURL
- * The URL to open in the browser.
- **/
-function createHiddenBrowser(aURL) {
- let frame = new HiddenFrame();
- return new Promise(resolve =>
- frame.get().then(aFrame => {
- let doc = aFrame.document;
- let browser = doc.createElementNS(XUL_NS, "browser");
- browser.setAttribute("type", "content");
- browser.setAttribute("disableglobalhistory", "true");
- browser.setAttribute("src", aURL);
-
- doc.documentElement.appendChild(browser);
- resolve({frame: frame, browser: browser});
- }));
-}
-
-/**
- * Remove the browser and the HiddenFrame.
- *
- * @param aFrame
- * The HiddenFrame to dismiss.
- * @param aBrowser
- * The browser to dismiss.
- */
-function destroyHiddenBrowser(aFrame, aBrowser) {
- // Dispose of the hidden browser.
- aBrowser.remove();
-
- // Take care of the frame holding our invisible browser.
- aFrame.destroy();
-}
-
-/**
- * Test that UITour works when called when no tabs are available (e.g., when using windowless
- * browsers).
- */
-add_task(function* test_windowless_UITour() {
- // Get the URL for the test page.
- let pageURL = getRootDirectory(gTestPath) + "uitour.html";
-
- // Allow the URL to use the UITour.
- info("Adding UITour permission to the test page.");
- let pageURI = Services.io.newURI(pageURL, null, null);
- Services.perms.add(pageURI, "uitour", Services.perms.ALLOW_ACTION);
-
- // UITour's ping will resolve this promise.
- let deferredPing = Promise.defer();
-
- // Create a windowless browser and test that UITour works in it.
- let browserPromise = createHiddenBrowser(pageURL);
- browserPromise.then(frameInfo => {
- isnot(frameInfo.browser, null, "The browser must exist and not be null.");
-
- // Load UITour frame script.
- frameInfo.browser.messageManager.loadFrameScript(
- "chrome://browser/content/content-UITour.js", false);
-
- // When the page loads, try to use UITour API.
- frameInfo.browser.addEventListener("load", function loadListener() {
- info("The test page was correctly loaded.");
-
- frameInfo.browser.removeEventListener("load", loadListener, true);
-
- // Get a reference to the UITour API.
- info("Testing access to the UITour API.");
- let contentWindow = Cu.waiveXrays(frameInfo.browser.contentDocument.defaultView);
- isnot(contentWindow, null, "The content window must exist and not be null.");
-
- let uitourAPI = contentWindow.Mozilla.UITour;
-
- // Test the UITour API with a ping.
- uitourAPI.ping(function() {
- info("Ping response received from the UITour API.");
-
- // Make sure to clean up.
- destroyHiddenBrowser(frameInfo.frame, frameInfo.browser);
-
- // Resolve our promise.
- deferredPing.resolve();
- });
- }, true);
- });
-
- // Wait for the UITour ping to complete.
- yield deferredPing.promise;
-});
diff --git a/browser/components/uitour/test/browser_openPreferences.js b/browser/components/uitour/test/browser_openPreferences.js
deleted file mode 100644
index c41865120..000000000
--- a/browser/components/uitour/test/browser_openPreferences.js
+++ /dev/null
@@ -1,36 +0,0 @@
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_openPreferences() {
- let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences");
- yield gContentAPI.openPreferences();
- let tab = yield promiseTabOpened;
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_UITour_task(function* test_openInvalidPreferences() {
- yield gContentAPI.openPreferences(999);
-
- try {
- yield waitForConditionPromise(() => {
- return gBrowser.selectedBrowser.currentURI.spec.startsWith("about:preferences");
- }, "Check if about:preferences opened");
- ok(false, "No about:preferences tab should have opened");
- } catch (ex) {
- ok(true, "No about:preferences tab opened: " + ex);
- }
-});
-
-add_UITour_task(function* test_openPrivacyPreferences() {
- let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#privacy");
- yield gContentAPI.openPreferences("privacy");
- let tab = yield promiseTabOpened;
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/components/uitour/test/browser_openSearchPanel.js b/browser/components/uitour/test/browser_openSearchPanel.js
deleted file mode 100644
index 5faa9db02..000000000
--- a/browser/components/uitour/test/browser_openSearchPanel.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-function test() {
- UITourTest();
-}
-
-var tests = [
- function test_openSearchPanel(done) {
- let searchbar = document.getElementById("searchbar");
-
- // If suggestions are enabled, the panel will attempt to use the network to connect
- // to the suggestions provider, causing the test suite to fail.
- Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref("browser.search.suggest.enabled");
- });
-
- ok(!searchbar.textbox.open, "Popup starts as closed");
- gContentAPI.openSearchPanel(() => {
- ok(searchbar.textbox.open, "Popup was opened");
- searchbar.textbox.closePopup();
- ok(!searchbar.textbox.open, "Popup was closed");
- done();
- });
- },
-];
diff --git a/browser/components/uitour/test/browser_showMenu_controlCenter.js b/browser/components/uitour/test/browser_showMenu_controlCenter.js
deleted file mode 100644
index 0faa5f862..000000000
--- a/browser/components/uitour/test/browser_showMenu_controlCenter.js
+++ /dev/null
@@ -1,44 +0,0 @@
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const CONTROL_CENTER_PANEL = gIdentityHandler._identityPopup;
-const CONTROL_CENTER_MENU_NAME = "controlCenter";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-add_task(setup_UITourTest);
-
-add_UITour_task(function* test_showMenu() {
- is_element_hidden(CONTROL_CENTER_PANEL, "Panel should initially be hidden");
- yield showMenuPromise(CONTROL_CENTER_MENU_NAME);
- is_element_visible(CONTROL_CENTER_PANEL, "Panel should be visible after showMenu");
-
- yield gURLBar.focus();
- is_element_visible(CONTROL_CENTER_PANEL, "Panel should remain visible after focus outside");
-
- yield showMenuPromise(CONTROL_CENTER_MENU_NAME);
- is_element_visible(CONTROL_CENTER_PANEL,
- "Panel should remain visible and callback called after a 2nd showMenu");
-
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "about:blank"
- }, function*() {
- ok(true, "Tab opened");
- });
-
- is_element_hidden(CONTROL_CENTER_PANEL, "Panel should hide upon tab switch");
-});
-
-add_UITour_task(function* test_hideMenu() {
- is_element_hidden(CONTROL_CENTER_PANEL, "Panel should initially be hidden");
- yield showMenuPromise(CONTROL_CENTER_MENU_NAME);
- is_element_visible(CONTROL_CENTER_PANEL, "Panel should be visible after showMenu");
- let hidePromise = promisePanelElementHidden(window, CONTROL_CENTER_PANEL);
- yield gContentAPI.hideMenu(CONTROL_CENTER_MENU_NAME);
- yield hidePromise;
-
- is_element_hidden(CONTROL_CENTER_PANEL, "Panel should hide after hideMenu");
-});
diff --git a/browser/components/uitour/test/browser_trackingProtection.js b/browser/components/uitour/test/browser_trackingProtection.js
deleted file mode 100644
index 32a9920ec..000000000
--- a/browser/components/uitour/test/browser_trackingProtection.js
+++ /dev/null
@@ -1,90 +0,0 @@
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-const PREF_INTRO_COUNT = "privacy.trackingprotection.introCount";
-const PREF_TP_ENABLED = "privacy.trackingprotection.enabled";
-const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html";
-const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html";
-const TOOLTIP_PANEL = document.getElementById("UITourTooltip");
-const TOOLTIP_ANCHOR = document.getElementById("tracking-protection-icon");
-
-var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-registerCleanupFunction(function() {
- UrlClassifierTestUtils.cleanupTestTrackers();
- Services.prefs.clearUserPref(PREF_TP_ENABLED);
- Services.prefs.clearUserPref(PREF_INTRO_COUNT);
-});
-
-function allowOneIntro() {
- Services.prefs.setIntPref(PREF_INTRO_COUNT, TrackingProtection.MAX_INTROS - 1);
-}
-
-add_task(function* setup_test() {
- Services.prefs.setBoolPref(PREF_TP_ENABLED, true);
- yield UrlClassifierTestUtils.addTestTrackers();
-});
-
-add_task(function* test_benignPage() {
- info("Load a test page not containing tracking elements");
- allowOneIntro();
- yield BrowserTestUtils.withNewTab({gBrowser, url: BENIGN_PAGE}, function*() {
- yield waitForConditionPromise(() => {
- return is_visible(TOOLTIP_PANEL);
- }, "Info panel shouldn't appear on a benign page").
- then(() => ok(false, "Info panel shouldn't appear"),
- () => {
- ok(true, "Info panel didn't appear on a benign page");
- });
-
- });
-});
-
-add_task(function* test_trackingPages() {
- info("Load a test page containing tracking elements");
- allowOneIntro();
- yield BrowserTestUtils.withNewTab({gBrowser, url: TRACKING_PAGE}, function*() {
- yield new Promise((resolve, reject) => {
- waitForPopupAtAnchor(TOOLTIP_PANEL, TOOLTIP_ANCHOR, resolve,
- "Intro panel should appear");
- });
-
- is(Services.prefs.getIntPref(PREF_INTRO_COUNT), TrackingProtection.MAX_INTROS, "Check intro count increased");
-
- let step2URL = Services.urlFormatter.formatURLPref("privacy.trackingprotection.introURL") +
- "?step=2&newtab=true";
- let buttons = document.getElementById("UITourTooltipButtons");
-
- info("Click the step text and nothing should happen");
- let tabCount = gBrowser.tabs.length;
- yield EventUtils.synthesizeMouseAtCenter(buttons.children[0], {});
- is(gBrowser.tabs.length, tabCount, "Same number of tabs should be open");
-
- info("Resetting count to test that viewing the tour prevents future panels");
- allowOneIntro();
-
- let panelHiddenPromise = promisePanelElementHidden(window, TOOLTIP_PANEL);
- let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, step2URL);
- info("Clicking the main button");
- EventUtils.synthesizeMouseAtCenter(buttons.children[1], {});
- let tab = yield tabPromise;
- is(Services.prefs.getIntPref(PREF_INTRO_COUNT), TrackingProtection.MAX_INTROS,
- "Check intro count is at the max after opening step 2");
- is(gBrowser.tabs.length, tabCount + 1, "Tour step 2 tab opened");
- yield panelHiddenPromise;
- ok(true, "Panel hid when the button was clicked");
- yield BrowserTestUtils.removeTab(tab);
- });
-
- info("Open another tracking page and make sure we don't show the panel again");
- yield BrowserTestUtils.withNewTab({gBrowser, url: TRACKING_PAGE}, function*() {
- yield waitForConditionPromise(() => {
- return is_visible(TOOLTIP_PANEL);
- }, "Info panel shouldn't appear more than MAX_INTROS").
- then(() => ok(false, "Info panel shouldn't appear again"),
- () => {
- ok(true, "Info panel didn't appear more than MAX_INTROS on tracking pages");
- });
-
- });
-});
diff --git a/browser/components/uitour/test/browser_trackingProtection_tour.js b/browser/components/uitour/test/browser_trackingProtection_tour.js
deleted file mode 100644
index 0ee0e1686..000000000
--- a/browser/components/uitour/test/browser_trackingProtection_tour.js
+++ /dev/null
@@ -1,77 +0,0 @@
-"use strict";
-
-var gTestTab;
-var gContentAPI;
-var gContentWindow;
-
-const { UrlClassifierTestUtils } = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
-
-const TP_ENABLED_PREF = "privacy.trackingprotection.enabled";
-
-add_task(setup_UITourTest);
-
-add_task(function* test_setup() {
- Services.prefs.setBoolPref("privacy.trackingprotection.enabled", true);
- yield UrlClassifierTestUtils.addTestTrackers();
-
- registerCleanupFunction(function() {
- UrlClassifierTestUtils.cleanupTestTrackers();
- Services.prefs.clearUserPref("privacy.trackingprotection.enabled");
- });
-});
-
-add_UITour_task(function* test_unblock_target() {
- yield* checkToggleTarget("controlCenter-trackingUnblock");
-});
-
-add_UITour_task(function* setup_block_target() {
- // Preparation for test_block_target. These are separate since the reload
- // interferes with UITour as it does a teardown. All we really care about
- // is the permission manager entry but UITour tests shouldn't rely on that
- // implementation detail.
- TrackingProtection.disableForCurrentPage();
-});
-
-add_UITour_task(function* test_block_target() {
- yield* checkToggleTarget("controlCenter-trackingBlock");
- TrackingProtection.enableForCurrentPage();
-});
-
-
-function* checkToggleTarget(targetID) {
- let popup = document.getElementById("UITourTooltip");
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
- let doc = content.document;
- let iframe = doc.createElement("iframe");
- iframe.setAttribute("id", "tracking-element");
- iframe.setAttribute("src", "https://tracking.example.com/");
- doc.body.insertBefore(iframe, doc.body.firstChild);
- });
-
- let testTargetAvailability = function* (expectedAvailable) {
- let data = yield getConfigurationPromise("availableTargets");
- let available = (data.targets.indexOf(targetID) != -1);
- is(available, expectedAvailable, "Target has expected availability.");
- };
- yield testTargetAvailability(false);
- yield showMenuPromise("controlCenter");
- yield testTargetAvailability(true);
-
- yield showInfoPromise(targetID, "This is " + targetID,
- "My arrow should be on the side");
- is(popup.popupBoxObject.alignmentPosition, "end_before",
- "Check " + targetID + " position");
-
- let hideMenuPromise =
- promisePanelElementHidden(window, gIdentityHandler._identityPopup);
- yield gContentAPI.hideMenu("controlCenter");
- yield hideMenuPromise;
-
- ok(!is_visible(popup), "The tooltip should now be hidden.");
- yield testTargetAvailability(false);
-
- yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
- content.document.getElementById("tracking-element").remove();
- });
-}
diff --git a/browser/components/uitour/test/head.js b/browser/components/uitour/test/head.js
deleted file mode 100644
index 2b5b994ae..000000000
--- a/browser/components/uitour/test/head.js
+++ /dev/null
@@ -1,449 +0,0 @@
-"use strict";
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "UITour",
- "resource:///modules/UITour.jsm");
-
-
-const SINGLE_TRY_TIMEOUT = 100;
-const NUMBER_OF_TRIES = 30;
-
-function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES) {
- let defer = Promise.defer();
- let tries = 0;
- function checkCondition() {
- if (tries >= tryCount) {
- defer.reject(timeoutMsg);
- }
- var conditionPassed;
- try {
- conditionPassed = condition();
- } catch (e) {
- return defer.reject(e);
- }
- if (conditionPassed) {
- return defer.resolve();
- }
- tries++;
- setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
- return undefined;
- }
- setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
- return defer.promise;
-}
-
-function waitForCondition(condition, nextTest, errorMsg) {
- waitForConditionPromise(condition, errorMsg).then(nextTest, (reason) => {
- ok(false, reason + (reason.stack ? "\n" + reason.stack : ""));
- });
-}
-
-/**
- * Wrapper to partially transition tests to Task. Use `add_UITour_task` instead for new tests.
- */
-function taskify(fun) {
- return (done) => {
- // Output the inner function name otherwise no name will be output.
- info("\t" + fun.name);
- return Task.spawn(fun).then(done, (reason) => {
- ok(false, reason);
- done();
- });
- };
-}
-
-function is_hidden(element) {
- var style = element.ownerGlobal.getComputedStyle(element);
- if (style.display == "none")
- return true;
- if (style.visibility != "visible")
- return true;
- if (style.display == "-moz-popup")
- return ["hiding", "closed"].indexOf(element.state) != -1;
-
- // Hiding a parent element will hide all its children
- if (element.parentNode != element.ownerDocument)
- return is_hidden(element.parentNode);
-
- return false;
-}
-
-function is_visible(element) {
- var style = element.ownerGlobal.getComputedStyle(element);
- if (style.display == "none")
- return false;
- if (style.visibility != "visible")
- return false;
- if (style.display == "-moz-popup" && element.state != "open")
- return false;
-
- // Hiding a parent element will hide all its children
- if (element.parentNode != element.ownerDocument)
- return is_visible(element.parentNode);
-
- return true;
-}
-
-function is_element_visible(element, msg) {
- isnot(element, null, "Element should not be null, when checking visibility");
- ok(is_visible(element), msg);
-}
-
-function waitForElementToBeVisible(element, nextTest, msg) {
- waitForCondition(() => is_visible(element),
- () => {
- ok(true, msg);
- nextTest();
- },
- "Timeout waiting for visibility: " + msg);
-}
-
-function waitForElementToBeHidden(element, nextTest, msg) {
- waitForCondition(() => is_hidden(element),
- () => {
- ok(true, msg);
- nextTest();
- },
- "Timeout waiting for invisibility: " + msg);
-}
-
-function elementVisiblePromise(element, msg) {
- return waitForConditionPromise(() => is_visible(element), "Timeout waiting for visibility: " + msg);
-}
-
-function elementHiddenPromise(element, msg) {
- return waitForConditionPromise(() => is_hidden(element), "Timeout waiting for invisibility: " + msg);
-}
-
-function waitForPopupAtAnchor(popup, anchorNode, nextTest, msg) {
- waitForCondition(() => is_visible(popup) && popup.popupBoxObject.anchorNode == anchorNode,
- () => {
- ok(true, msg);
- is_element_visible(popup, "Popup should be visible");
- nextTest();
- },
- "Timeout waiting for popup at anchor: " + msg);
-}
-
-function getConfigurationPromise(configName) {
- return ContentTask.spawn(gTestTab.linkedBrowser, configName, configName => {
- return new Promise((resolve) => {
- let contentWin = Components.utils.waiveXrays(content);
- contentWin.Mozilla.UITour.getConfiguration(configName, resolve);
- });
- });
-}
-
-function hideInfoPromise(...args) {
- let popup = document.getElementById("UITourTooltip");
- gContentAPI.hideInfo.apply(gContentAPI, args);
- return promisePanelElementHidden(window, popup);
-}
-
-/**
- * `buttons` and `options` require functions from the content scope so we take a
- * function name to call to generate the buttons/options instead of the
- * buttons/options themselves. This makes the signature differ from the content one.
- */
-function showInfoPromise(target, title, text, icon, buttonsFunctionName, optionsFunctionName) {
- let popup = document.getElementById("UITourTooltip");
- let shownPromise = promisePanelElementShown(window, popup);
- return ContentTask.spawn(gTestTab.linkedBrowser, [...arguments], args => {
- let contentWin = Components.utils.waiveXrays(content);
- let [target, title, text, icon, buttonsFunctionName, optionsFunctionName] = args;
- let buttons = buttonsFunctionName ? contentWin[buttonsFunctionName]() : null;
- let options = optionsFunctionName ? contentWin[optionsFunctionName]() : null;
- contentWin.Mozilla.UITour.showInfo(target, title, text, icon, buttons, options);
- }).then(() => shownPromise);
-}
-
-function showHighlightPromise(...args) {
- let popup = document.getElementById("UITourHighlightContainer");
- gContentAPI.showHighlight.apply(gContentAPI, args);
- return promisePanelElementShown(window, popup);
-}
-
-function showMenuPromise(name) {
- return ContentTask.spawn(gTestTab.linkedBrowser, name, name => {
- return new Promise((resolve) => {
- let contentWin = Components.utils.waiveXrays(content);
- contentWin.Mozilla.UITour.showMenu(name, resolve);
- });
- });
-}
-
-function waitForCallbackResultPromise() {
- return ContentTask.spawn(gTestTab.linkedBrowser, null, function*() {
- let contentWin = Components.utils.waiveXrays(content);
- yield ContentTaskUtils.waitForCondition(() => {
- return contentWin.callbackResult;
- }, "callback should be called");
- return {
- data: contentWin.callbackData,
- result: contentWin.callbackResult,
- };
- });
-}
-
-function promisePanelShown(win) {
- let panelEl = win.PanelUI.panel;
- return promisePanelElementShown(win, panelEl);
-}
-
-function promisePanelElementEvent(win, aPanel, aEvent) {
- return new Promise((resolve, reject) => {
- let timeoutId = win.setTimeout(() => {
- aPanel.removeEventListener(aEvent, onPanelEvent);
- reject(aEvent + " event did not happen within 5 seconds.");
- }, 5000);
-
- function onPanelEvent(e) {
- aPanel.removeEventListener(aEvent, onPanelEvent);
- win.clearTimeout(timeoutId);
- // Wait one tick to let UITour.jsm process the event as well.
- executeSoon(resolve);
- }
-
- aPanel.addEventListener(aEvent, onPanelEvent);
- });
-}
-
-function promisePanelElementShown(win, aPanel) {
- return promisePanelElementEvent(win, aPanel, "popupshown");
-}
-
-function promisePanelElementHidden(win, aPanel) {
- return promisePanelElementEvent(win, aPanel, "popuphidden");
-}
-
-function is_element_hidden(element, msg) {
- isnot(element, null, "Element should not be null, when checking visibility");
- ok(is_hidden(element), msg);
-}
-
-function isTourBrowser(aBrowser) {
- let chromeWindow = aBrowser.ownerGlobal;
- return UITour.tourBrowsersByWindow.has(chromeWindow) &&
- UITour.tourBrowsersByWindow.get(chromeWindow).has(aBrowser);
-}
-
-function promisePageEvent() {
- return new Promise((resolve) => {
- Services.mm.addMessageListener("UITour:onPageEvent", function onPageEvent(aMessage) {
- Services.mm.removeMessageListener("UITour:onPageEvent", onPageEvent);
- SimpleTest.executeSoon(resolve);
- });
- });
-}
-
-function loadUITourTestPage(callback, host = "https://example.org/") {
- if (gTestTab)
- gBrowser.removeTab(gTestTab);
-
- let url = getRootDirectory(gTestPath) + "uitour.html";
- url = url.replace("chrome://mochitests/content/", host);
-
- gTestTab = gBrowser.addTab(url);
- gBrowser.selectedTab = gTestTab;
-
- gTestTab.linkedBrowser.addEventListener("load", function onLoad() {
- gTestTab.linkedBrowser.removeEventListener("load", onLoad, true);
-
- if (gMultiProcessBrowser) {
- // When e10s is enabled, make gContentAPI and gContentWindow proxies which has every property
- // return a function which calls the method of the same name on
- // contentWin.Mozilla.UITour/contentWin in a ContentTask.
- let contentWinHandler = {
- get(target, prop, receiver) {
- return (...args) => {
- let taskArgs = {
- methodName: prop,
- args,
- };
- return ContentTask.spawn(gTestTab.linkedBrowser, taskArgs, args => {
- let contentWin = Components.utils.waiveXrays(content);
- return contentWin[args.methodName].apply(contentWin, args.args);
- });
- };
- },
- };
- gContentWindow = new Proxy({}, contentWinHandler);
-
- let UITourHandler = {
- get(target, prop, receiver) {
- return (...args) => {
- let browser = gTestTab.linkedBrowser;
- const proxyFunctionName = "UITourHandler:proxiedfunction-";
- // We need to proxy any callback functions using messages:
- let callbackMap = new Map();
- let fnIndices = [];
- args = args.map((arg, index) => {
- // Replace function arguments with "", and add them to the list of
- // forwarded functions. We'll construct a function on the content-side
- // that forwards all its arguments to a message, and we'll listen for
- // those messages on our side and call the corresponding function with
- // the arguments we got from the content side.
- if (typeof arg == "function") {
- callbackMap.set(index, arg);
- fnIndices.push(index);
- let handler = function(msg) {
- // Please note that this handler assumes that the callback is used only once.
- // That means that a single gContentAPI.observer() call can't be used to observe
- // multiple events.
- browser.messageManager.removeMessageListener(proxyFunctionName + index, handler);
- callbackMap.get(index).apply(null, msg.data);
- };
- browser.messageManager.addMessageListener(proxyFunctionName + index, handler);
- return "";
- }
- return arg;
- });
- let taskArgs = {
- methodName: prop,
- args,
- fnIndices,
- };
- return ContentTask.spawn(browser, taskArgs, function*(args) {
- let contentWin = Components.utils.waiveXrays(content);
- let callbacksCalled = 0;
- let resolveCallbackPromise;
- let allCallbacksCalledPromise = new Promise(resolve => resolveCallbackPromise = resolve);
- let argumentsWithFunctions = args.args.map((arg, index) => {
- if (arg === "" && args.fnIndices.includes(index)) {
- return function() {
- callbacksCalled++;
- sendAsyncMessage("UITourHandler:proxiedfunction-" + index, Array.from(arguments));
- if (callbacksCalled >= args.fnIndices.length) {
- resolveCallbackPromise();
- }
- };
- }
- return arg;
- });
- let rv = contentWin.Mozilla.UITour[args.methodName].apply(contentWin.Mozilla.UITour,
- argumentsWithFunctions);
- if (args.fnIndices.length) {
- yield allCallbacksCalledPromise;
- }
- return rv;
- });
- };
- },
- };
- gContentAPI = new Proxy({}, UITourHandler);
- } else {
- gContentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView);
- gContentAPI = gContentWindow.Mozilla.UITour;
- }
-
- waitForFocus(callback, gTestTab.linkedBrowser);
- }, true);
-}
-
-// Wrapper for UITourTest to be used by add_task tests.
-function* setup_UITourTest() {
- return UITourTest(true);
-}
-
-// Use `add_task(setup_UITourTest);` instead as we will fold this into `setup_UITourTest` once all tests are using `add_UITour_task`.
-function UITourTest(usingAddTask = false) {
- Services.prefs.setBoolPref("browser.uitour.enabled", true);
- let testHttpsUri = Services.io.newURI("https://example.org", null, null);
- let testHttpUri = Services.io.newURI("http://example.org", null, null);
- Services.perms.add(testHttpsUri, "uitour", Services.perms.ALLOW_ACTION);
- Services.perms.add(testHttpUri, "uitour", Services.perms.ALLOW_ACTION);
-
- // If a test file is using add_task, we don't need to have a test function or
- // call `waitForExplicitFinish`.
- if (!usingAddTask) {
- waitForExplicitFinish();
- }
-
- registerCleanupFunction(function() {
- delete window.gContentWindow;
- delete window.gContentAPI;
- if (gTestTab)
- gBrowser.removeTab(gTestTab);
- delete window.gTestTab;
- Services.prefs.clearUserPref("browser.uitour.enabled");
- Services.perms.remove(testHttpsUri, "uitour");
- Services.perms.remove(testHttpUri, "uitour");
- });
-
- // When using tasks, the harness will call the next added task for us.
- if (!usingAddTask) {
- nextTest();
- }
-}
-
-function done(usingAddTask = false) {
- info("== Done test, doing shared checks before teardown ==");
- return new Promise((resolve) => {
- executeSoon(() => {
- if (gTestTab)
- gBrowser.removeTab(gTestTab);
- gTestTab = null;
-
- let highlight = document.getElementById("UITourHighlightContainer");
- is_element_hidden(highlight, "Highlight should be closed/hidden after UITour tab is closed");
-
- let tooltip = document.getElementById("UITourTooltip");
- is_element_hidden(tooltip, "Tooltip should be closed/hidden after UITour tab is closed");
-
- ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up");
- ok(!PanelUI.panel.hasAttribute("panelopen"), "The panel shouldn't have @panelopen");
- isnot(PanelUI.panel.state, "open", "The panel shouldn't be open");
- is(document.getElementById("PanelUI-menu-button").hasAttribute("open"), false, "Menu button should know that the menu is closed");
-
- info("Done shared checks");
- if (usingAddTask) {
- executeSoon(resolve);
- } else {
- executeSoon(nextTest);
- }
- });
- });
-}
-
-function nextTest() {
- if (tests.length == 0) {
- info("finished tests in this file");
- finish();
- return;
- }
- let test = tests.shift();
- info("Starting " + test.name);
- waitForFocus(function() {
- loadUITourTestPage(function() {
- test(done);
- });
- });
-}
-
-/**
- * All new tests that need the help of `loadUITourTestPage` should use this
- * wrapper around their test's generator function to reduce boilerplate.
- */
-function add_UITour_task(func) {
- let genFun = function*() {
- yield new Promise((resolve) => {
- waitForFocus(function() {
- loadUITourTestPage(function() {
- let funcPromise = Task.spawn(func)
- .then(() => done(true),
- (reason) => {
- ok(false, reason);
- return done(true);
- });
- resolve(funcPromise);
- });
- });
- });
- };
- Object.defineProperty(genFun, "name", {
- configurable: true,
- value: func.name,
- });
- add_task(genFun);
-}
diff --git a/browser/components/uitour/test/image.png b/browser/components/uitour/test/image.png
deleted file mode 100644
index 597c7fd2c..000000000
--- a/browser/components/uitour/test/image.png
+++ /dev/null
Binary files differ
diff --git a/browser/components/uitour/test/uitour.html b/browser/components/uitour/test/uitour.html
deleted file mode 100644
index 6c42ac7f8..000000000
--- a/browser/components/uitour/test/uitour.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8" />
- <title>UITour test</title>
- <script type="application/javascript" src="UITour-lib.js">
- </script>
- <script type="application/javascript">
- var callbackResult, callbackData;
- function makeCallback(name) {
- return (function(data) {
- callbackResult = name;
- callbackData = data;
- });
- }
-
- // Defined in content to avoid weird issues when crossing between chrome/content.
- function makeButtons() {
- return [
- {label: "Regular text", style: "text"},
- {label: "Link", callback: makeCallback("link"), style: "link"},
- {label: "Button 1", callback: makeCallback("button1")},
- {label: "Button 2", callback: makeCallback("button2"), icon: "image.png",
- style: "primary"}
- ];
- }
-
- function makeInfoOptions() {
- return {
- closeButtonCallback: makeCallback("closeButton"),
- targetCallback: makeCallback("target"),
- };
- }
- </script>
- </head>
- <body>
- <h1>UITour tests</h1>
- <p>Because Firefox is...</p>
- <p>Never gonna let you down</p>
- <p>Never gonna give you up</p>
- </body>
-</html>
diff --git a/browser/confvars.sh b/browser/confvars.sh
index dabd06ea7..1bc9d1ad0 100755
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -32,8 +32,8 @@ fi
# Enable building ./signmar and running libmar signature tests
MOZ_ENABLE_SIGNMAR=1
-MOZ_APP_VERSION=$FIREFOX_VERSION
-MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION_DISPLAY
+MOZ_APP_VERSION=`cat ${_topsrcdir}/$MOZ_BUILD_APP/config/version.txt`
+MOZ_APP_VERSION_DISPLAY=`cat ${_topsrcdir}/$MOZ_BUILD_APP/config/version_display.txt`
MOZ_EXTENSIONS_DEFAULT=" gio"
# MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
# MOZ_BRANDING_DIRECTORY is the default branding directory used when none is
diff --git a/browser/extensions/formautofill/moz.build b/browser/extensions/formautofill/moz.build
index 92577db53..abcc659ee 100644
--- a/browser/extensions/formautofill/moz.build
+++ b/browser/extensions/formautofill/moz.build
@@ -15,8 +15,4 @@ FINAL_TARGET_PP_FILES.features['formautofill@mozilla.org'] += [
'install.rdf.in'
]
-BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
-
-XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
-
JAR_MANIFESTS += ['jar.mn']
diff --git a/browser/extensions/formautofill/test/browser/.eslintrc.js b/browser/extensions/formautofill/test/browser/.eslintrc.js
deleted file mode 100644
index 52a2004c9..000000000
--- a/browser/extensions/formautofill/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = { // eslint-disable-line no-undef
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js",
- ],
-};
diff --git a/browser/extensions/formautofill/test/browser/browser.ini b/browser/extensions/formautofill/test/browser/browser.ini
deleted file mode 100644
index 500224636..000000000
--- a/browser/extensions/formautofill/test/browser/browser.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[DEFAULT]
-
-[browser_check_installed.js]
diff --git a/browser/extensions/formautofill/test/browser/browser_check_installed.js b/browser/extensions/formautofill/test/browser/browser_check_installed.js
deleted file mode 100644
index b018c0f71..000000000
--- a/browser/extensions/formautofill/test/browser/browser_check_installed.js
+++ /dev/null
@@ -1,14 +0,0 @@
-"use strict";
-
-add_task(function* test_enabled() {
- let addon = yield new Promise(
- resolve => AddonManager.getAddonByID("formautofill@mozilla.org", resolve)
- );
- isnot(addon, null, "Check addon exists");
- is(addon.version, "1.0", "Check version");
- is(addon.name, "Form Autofill", "Check name");
- ok(addon.isCompatible, "Check application compatibility");
- ok(!addon.appDisabled, "Check not app disabled");
- ok(addon.isActive, "Check addon is active");
- is(addon.type, "extension", "Check type is 'extension'");
-});
diff --git a/browser/extensions/formautofill/test/unit/.eslintrc b/browser/extensions/formautofill/test/unit/.eslintrc
deleted file mode 100644
index 8e33fb0c6..000000000
--- a/browser/extensions/formautofill/test/unit/.eslintrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ],
-}
diff --git a/browser/extensions/formautofill/test/unit/head.js b/browser/extensions/formautofill/test/unit/head.js
deleted file mode 100644
index 67e3bd60b..000000000
--- a/browser/extensions/formautofill/test/unit/head.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Provides infrastructure for automated login components tests.
- */
-
- /* exported importAutofillModule, getTempFile */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://testing-common/MockDocument.jsm");
-
-// Redirect the path of the resouce in addon to the exact file path.
-let defineLazyModuleGetter = XPCOMUtils.defineLazyModuleGetter;
-XPCOMUtils.defineLazyModuleGetter = function() {
- let result = /^resource\:\/\/formautofill\/(.+)$/.exec(arguments[2]);
- if (result) {
- arguments[2] = Services.io.newFileURI(do_get_file(result[1])).spec;
- }
- return defineLazyModuleGetter.apply(this, arguments);
-};
-
-// Load the module by Service newFileURI API for running extension's XPCShell test
-function importAutofillModule(module) {
- return Cu.import(Services.io.newFileURI(do_get_file(module)).spec);
-}
-
-XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths",
- "resource://gre/modules/DownloadPaths.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm");
-
-// While the previous test file should have deleted all the temporary files it
-// used, on Windows these might still be pending deletion on the physical file
-// system. Thus, start from a new base number every time, to make a collision
-// with a file that is still pending deletion highly unlikely.
-let gFileCounter = Math.floor(Math.random() * 1000000);
-
-/**
- * Returns a reference to a temporary file, that is guaranteed not to exist, and
- * to have never been created before.
- *
- * @param {string} leafName
- * Suggested leaf name for the file to be created.
- *
- * @returns {nsIFile} pointing to a non-existent file in a temporary directory.
- *
- * @note It is not enough to delete the file if it exists, or to delete the file
- * after calling nsIFile.createUnique, because on Windows the delete
- * operation in the file system may still be pending, preventing a new
- * file with the same name to be created.
- */
-function getTempFile(leafName) {
- // Prepend a serial number to the extension in the suggested leaf name.
- let [base, ext] = DownloadPaths.splitBaseNameAndExtension(leafName);
- let finalLeafName = base + "-" + gFileCounter + ext;
- gFileCounter++;
-
- // Get a file reference under the temporary directory for this test file.
- let file = FileUtils.getFile("TmpD", [finalLeafName]);
- do_check_false(file.exists());
-
- do_register_cleanup(function() {
- if (file.exists()) {
- file.remove(false);
- }
- });
-
- return file;
-}
-
-add_task(function* test_common_initialize() {
- Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", true);
-
- // Clean up after every test.
- do_register_cleanup(() => {
- Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", false);
- });
-});
diff --git a/browser/extensions/formautofill/test/unit/test_autofillFormFields.js b/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
deleted file mode 100644
index a842e84e8..000000000
--- a/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Test for form auto fill content helper fill all inputs function.
- */
-
-"use strict";
-
-let {FormAutofillHandler} = importAutofillModule("FormAutofillContent.jsm");
-
-const TESTCASES = [
- {
- description: "Form without autocomplete property",
- document: `<form><input id="given-name"><input id="family-name">
- <input id="street-addr"><input id="city"><input id="country">
- <input id='email'><input id="tel"></form>`,
- fieldDetails: [],
- profileData: [],
- expectedResult: {
- "given-name": "",
- "family-name": "",
- "street-addr": "",
- "city": "",
- "country": "",
- "email": "",
- "tel": "",
- },
- },
- {
- description: "Form with autocomplete properties and 1 token",
- document: `<form><input id="given-name" autocomplete="given-name">
- <input id="family-name" autocomplete="family-name">
- <input id="street-addr" autocomplete="street-address">
- <input id="city" autocomplete="address-level2">
- <input id="country" autocomplete="country">
- <input id="email" autocomplete="email">
- <input id="tel" autocomplete="tel"></form>`,
- fieldDetails: [
- {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- profileData: [
- {"section": "", "addressType": "", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
- {"section": "", "addressType": "", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
- {"section": "", "addressType": "", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
- {"section": "", "addressType": "", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
- {"section": "", "addressType": "", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
- {"section": "", "addressType": "", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
- {"section": "", "addressType": "", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
- ],
- expectedResult: {
- "given-name": "foo",
- "family-name": "bar",
- "street-addr": "2 Harrison St",
- "city": "San Francisco",
- "country": "US",
- "email": "foo@mozilla.com",
- "tel": "1234567",
- },
- },
- {
- description: "Form with autocomplete properties and 2 tokens",
- document: `<form><input id="given-name" autocomplete="shipping given-name">
- <input id="family-name" autocomplete="shipping family-name">
- <input id="street-addr" autocomplete="shipping street-address">
- <input id="city" autocomplete="shipping address-level2">
- <input id="country" autocomplete="shipping country">
- <input id='email' autocomplete="shipping email">
- <input id="tel" autocomplete="shipping tel"></form>`,
- fieldDetails: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- profileData: [
- {"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
- {"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
- {"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
- {"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
- {"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
- {"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
- {"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
- ],
- expectedResult: {
- "given-name": "foo",
- "family-name": "bar",
- "street-addr": "2 Harrison St",
- "city": "San Francisco",
- "country": "US",
- "email": "foo@mozilla.com",
- "tel": "1234567",
- },
- },
- {
- description: "Form with autocomplete properties and profile is partly matched",
- document: `<form><input id="given-name" autocomplete="shipping given-name">
- <input id="family-name" autocomplete="shipping family-name">
- <input id="street-addr" autocomplete="shipping street-address">
- <input id="city" autocomplete="shipping address-level2">
- <input id="country" autocomplete="shipping country">
- <input id='email' autocomplete="shipping email">
- <input id="tel" autocomplete="shipping tel"></form>`,
- fieldDetails: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- profileData: [
- {"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
- {"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
- {"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
- {"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
- {"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
- {"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5},
- {"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6},
- ],
- expectedResult: {
- "given-name": "foo",
- "family-name": "bar",
- "street-addr": "2 Harrison St",
- "city": "San Francisco",
- "country": "US",
- "email": "",
- "tel": "",
- },
- },
- {
- description: "Form with autocomplete properties but mismatched",
- document: `<form><input id="given-name" autocomplete="shipping given-name">
- <input id="family-name" autocomplete="shipping family-name">
- <input id="street-addr" autocomplete="billing street-address">
- <input id="city" autocomplete="billing address-level2">
- <input id="country" autocomplete="billing country">
- <input id='email' autocomplete="shipping email">
- <input id="tel" autocomplete="shipping tel"></form>`,
- fieldDetails: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- profileData: [
- {"section": "", "addressType": "shipping", "fieldName": "given-name", "contactType": "", "index": 0, "value": "foo"},
- {"section": "", "addressType": "shipping", "fieldName": "family-name", "contactType": "", "index": 1, "value": "bar"},
- {"section": "", "addressType": "shipping", "fieldName": "street-address", "contactType": "", "index": 2, "value": "2 Harrison St"},
- {"section": "", "addressType": "shipping", "fieldName": "address-level2", "contactType": "", "index": 3, "value": "San Francisco"},
- {"section": "", "addressType": "shipping", "fieldName": "country", "contactType": "", "index": 4, "value": "US"},
- {"section": "", "addressType": "shipping", "fieldName": "email", "contactType": "", "index": 5, "value": "foo@mozilla.com"},
- {"section": "", "addressType": "shipping", "fieldName": "tel", "contactType": "", "index": 6, "value": "1234567"},
- ],
- expectedResult: {
- "given-name": "foo",
- "family-name": "bar",
- "street-addr": "",
- "city": "",
- "country": "",
- "email": "foo@mozilla.com",
- "tel": "1234567",
- },
- },
-];
-
-for (let tc of TESTCASES) {
- (function() {
- let testcase = tc;
- add_task(function* () {
- do_print("Starting testcase: " + testcase.description);
-
- let doc = MockDocument.createTestDocument("http://localhost:8080/test/",
- testcase.document);
- let form = doc.querySelector("form");
- let handler = new FormAutofillHandler(form);
-
- handler.fieldDetails = testcase.fieldDetails;
- handler.fieldDetails.forEach((field, index) => {
- field.element = doc.querySelectorAll("input")[index];
- });
-
- handler.autofillFormFields(testcase.profileData);
- for (let id in testcase.expectedResult) {
- Assert.equal(doc.getElementById(id).value, testcase.expectedResult[id],
- "Check the " + id + " fields were filled with correct data");
- }
- });
- })();
-}
diff --git a/browser/extensions/formautofill/test/unit/test_collectFormFields.js b/browser/extensions/formautofill/test/unit/test_collectFormFields.js
deleted file mode 100644
index 52549b746..000000000
--- a/browser/extensions/formautofill/test/unit/test_collectFormFields.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Test for form auto fill content helper collectFormFields functions.
- */
-
-"use strict";
-
-let {FormAutofillHandler} = importAutofillModule("FormAutofillContent.jsm");
-
-const TESTCASES = [
- {
- description: "Form without autocomplete property",
- document: `<form><input id="given-name"><input id="family-name">
- <input id="street-addr"><input id="city"><input id="country">
- <input id='email'><input id="tel"></form>`,
- returnedFormat: [],
- fieldDetails: [],
- },
- {
- description: "Form with autocomplete properties and 1 token",
- document: `<form><input id="given-name" autocomplete="given-name">
- <input id="family-name" autocomplete="family-name">
- <input id="street-addr" autocomplete="street-address">
- <input id="city" autocomplete="address-level2">
- <input id="country" autocomplete="country">
- <input id="email" autocomplete="email">
- <input id="tel" autocomplete="tel"></form>`,
- returnedFormat: [
- {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name", "index": 0},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name", "index": 1},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "index": 2},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "index": 3},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "country", "index": 4},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "email", "index": 5},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "index": 6},
- ],
- fieldDetails: [
- {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- },
- {
- description: "Form with autocomplete properties and 2 tokens",
- document: `<form><input id="given-name" autocomplete="shipping given-name">
- <input id="family-name" autocomplete="shipping family-name">
- <input id="street-addr" autocomplete="shipping street-address">
- <input id="city" autocomplete="shipping address-level2">
- <input id="country" autocomplete="shipping country">
- <input id='email' autocomplete="shipping email">
- <input id="tel" autocomplete="shipping tel"></form>`,
- returnedFormat: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "index": 0},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "index": 1},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "index": 2},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "index": 3},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "index": 4},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "index": 5},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "index": 6},
- ],
- fieldDetails: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- },
- {
- description: "Form with autocomplete properties and profile is partly matched",
- document: `<form><input id="given-name" autocomplete="shipping given-name">
- <input id="family-name" autocomplete="shipping family-name">
- <input id="street-addr" autocomplete="shipping street-address">
- <input id="city" autocomplete="shipping address-level2">
- <input id="country" autocomplete="shipping country">
- <input id='email' autocomplete="shipping email">
- <input id="tel" autocomplete="shipping tel"></form>`,
- returnedFormat: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "index": 0},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "index": 1},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "index": 2},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "index": 3},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "index": 4},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "index": 5},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "index": 6},
- ],
- fieldDetails: [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
- ],
- },
-];
-
-for (let tc of TESTCASES) {
- (function() {
- let testcase = tc;
- add_task(function* () {
- do_print("Starting testcase: " + testcase.description);
-
- let doc = MockDocument.createTestDocument("http://localhost:8080/test/",
- testcase.document);
- let form = doc.querySelector("form");
- let handler = new FormAutofillHandler(form);
-
- Assert.deepEqual(handler.collectFormFields(), testcase.returnedFormat,
- "Check the format of form autofill were returned correctly");
-
- Assert.deepEqual(handler.fieldDetails, testcase.fieldDetails,
- "Check the fieldDetails were set correctly");
- });
- })();
-}
diff --git a/browser/extensions/formautofill/test/unit/test_populateFieldValues.js b/browser/extensions/formautofill/test/unit/test_populateFieldValues.js
deleted file mode 100644
index 1215cbd16..000000000
--- a/browser/extensions/formautofill/test/unit/test_populateFieldValues.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Test for populating field values in Form Autofill Parent.
- */
-
-/* global FormAutofillParent */
-
-"use strict";
-
-importAutofillModule("FormAutofillParent.jsm");
-
-do_get_profile();
-
-const TEST_FIELDS = [
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "organization"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level1"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "postal-code"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
- {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
-];
-
-const TEST_GUID = "test-guid";
-
-const TEST_PROFILE = {
- guid: TEST_GUID,
- organization: "World Wide Web Consortium",
- streetAddress: "32 Vassar Street\nMIT Room 32-G524",
- addressLevel2: "Cambridge",
- addressLevel1: "MA",
- postalCode: "02139",
- country: "US",
- tel: "+1 617 253 5702",
- email: "timbl@w3.org",
-};
-
-function camelCase(str) {
- return str.toLowerCase().replace(/-([a-z])/g, s => s[1].toUpperCase());
-}
-
-add_task(function* test_populateFieldValues() {
- FormAutofillParent.init();
-
- let store = FormAutofillParent.getProfileStore();
- do_check_neq(store, null);
-
- store.get = function(guid) {
- do_check_eq(guid, TEST_GUID);
- return store._clone(TEST_PROFILE);
- };
-
- let notifyUsedCalledCount = 0;
- store.notifyUsed = function(guid) {
- do_check_eq(guid, TEST_GUID);
- notifyUsedCalledCount++;
- };
-
- yield new Promise((resolve) => {
- FormAutofillParent.receiveMessage({
- name: "FormAutofill:PopulateFieldValues",
- data: {
- guid: TEST_GUID,
- fields: TEST_FIELDS,
- },
- target: {
- sendAsyncMessage: function(name, data) {
- do_check_eq(name, "FormAutofill:fillForm");
-
- let fields = data.fields;
- do_check_eq(fields.length, TEST_FIELDS.length);
-
- for (let i = 0; i < fields.length; i++) {
- do_check_eq(fields[i].fieldName, TEST_FIELDS[i].fieldName);
- do_check_eq(fields[i].value,
- TEST_PROFILE[camelCase(fields[i].fieldName)]);
- }
-
- resolve();
- },
- },
- });
- });
-
- do_check_eq(notifyUsedCalledCount, 1);
-
- FormAutofillParent._uninit();
- do_check_null(FormAutofillParent.getProfileStore());
-});
-
-add_task(function* test_populateFieldValues_with_invalid_guid() {
- FormAutofillParent.init();
-
- Assert.throws(() => {
- FormAutofillParent.receiveMessage({
- name: "FormAutofill:PopulateFieldValues",
- data: {
- guid: "invalid-guid",
- fields: TEST_FIELDS,
- },
- target: {},
- });
- }, /No matching profile\./);
-
- FormAutofillParent._uninit();
-});
diff --git a/browser/extensions/formautofill/test/unit/test_profileStorage.js b/browser/extensions/formautofill/test/unit/test_profileStorage.js
deleted file mode 100644
index 018adedb8..000000000
--- a/browser/extensions/formautofill/test/unit/test_profileStorage.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * Tests ProfileStorage object.
- */
-
-/* global ProfileStorage */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import(Services.io.newFileURI(do_get_file("ProfileStorage.jsm")).spec);
-
-const TEST_STORE_FILE_NAME = "test-profile.json";
-
-const TEST_PROFILE_1 = {
- organization: "World Wide Web Consortium",
- streetAddress: "32 Vassar Street\nMIT Room 32-G524",
- addressLevel2: "Cambridge",
- addressLevel1: "MA",
- postalCode: "02139",
- country: "US",
- tel: "+1 617 253 5702",
- email: "timbl@w3.org",
-};
-
-const TEST_PROFILE_2 = {
- streetAddress: "Some Address",
- country: "US",
-};
-
-const TEST_PROFILE_3 = {
- streetAddress: "Other Address",
- postalCode: "12345",
-};
-
-const TEST_PROFILE_WITH_INVALID_FIELD = {
- streetAddress: "Another Address",
- invalidField: "INVALID",
-};
-
-let prepareTestProfiles = Task.async(function* (path) {
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- profileStorage.add(TEST_PROFILE_1);
- profileStorage.add(TEST_PROFILE_2);
- yield profileStorage._saveImmediately();
-});
-
-let do_check_profile_matches = (profileWithMeta, profile) => {
- for (let key in profile) {
- do_check_eq(profileWithMeta[key], profile[key]);
- }
-};
-
-add_task(function* test_initialize() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- do_check_eq(profileStorage._store.data.version, 1);
- do_check_eq(profileStorage._store.data.profiles.length, 0);
-
- let data = profileStorage._store.data;
-
- yield profileStorage._saveImmediately();
-
- profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- Assert.deepEqual(profileStorage._store.data, data);
-});
-
-add_task(function* test_getAll() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- yield prepareTestProfiles(path);
-
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profiles = profileStorage.getAll();
-
- do_check_eq(profiles.length, 2);
- do_check_profile_matches(profiles[0], TEST_PROFILE_1);
- do_check_profile_matches(profiles[1], TEST_PROFILE_2);
-
- // Modifying output shouldn't affect the storage.
- profiles[0].organization = "test";
- do_check_profile_matches(profileStorage.getAll()[0], TEST_PROFILE_1);
-});
-
-add_task(function* test_get() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- yield prepareTestProfiles(path);
-
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profiles = profileStorage.getAll();
- let guid = profiles[0].guid;
-
- let profile = profileStorage.get(guid);
- do_check_profile_matches(profile, TEST_PROFILE_1);
-
- // Modifying output shouldn't affect the storage.
- profile.organization = "test";
- do_check_profile_matches(profileStorage.get(guid), TEST_PROFILE_1);
-
- Assert.throws(() => profileStorage.get("INVALID_GUID"),
- /No matching profile\./);
-});
-
-add_task(function* test_add() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- yield prepareTestProfiles(path);
-
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profiles = profileStorage.getAll();
-
- do_check_eq(profiles.length, 2);
-
- do_check_profile_matches(profiles[0], TEST_PROFILE_1);
- do_check_profile_matches(profiles[1], TEST_PROFILE_2);
-
- do_check_neq(profiles[0].guid, undefined);
- do_check_neq(profiles[0].timeCreated, undefined);
- do_check_eq(profiles[0].timeLastModified, profiles[0].timeCreated);
- do_check_eq(profiles[0].timeLastUsed, 0);
- do_check_eq(profiles[0].timesUsed, 0);
-
- Assert.throws(() => profileStorage.add(TEST_PROFILE_WITH_INVALID_FIELD),
- /"invalidField" is not a valid field\./);
-});
-
-add_task(function* test_update() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- yield prepareTestProfiles(path);
-
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profiles = profileStorage.getAll();
- let guid = profiles[1].guid;
- let timeLastModified = profiles[1].timeLastModified;
-
- do_check_neq(profiles[1].country, undefined);
-
- profileStorage.update(guid, TEST_PROFILE_3);
- yield profileStorage._saveImmediately();
-
- profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profile = profileStorage.get(guid);
-
- do_check_eq(profile.country, undefined);
- do_check_neq(profile.timeLastModified, timeLastModified);
- do_check_profile_matches(profile, TEST_PROFILE_3);
-
- Assert.throws(
- () => profileStorage.update("INVALID_GUID", TEST_PROFILE_3),
- /No matching profile\./
- );
-
- Assert.throws(
- () => profileStorage.update(guid, TEST_PROFILE_WITH_INVALID_FIELD),
- /"invalidField" is not a valid field\./
- );
-});
-
-add_task(function* test_notifyUsed() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- yield prepareTestProfiles(path);
-
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profiles = profileStorage.getAll();
- let guid = profiles[1].guid;
- let timeLastUsed = profiles[1].timeLastUsed;
- let timesUsed = profiles[1].timesUsed;
-
- profileStorage.notifyUsed(guid);
- yield profileStorage._saveImmediately();
-
- profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profile = profileStorage.get(guid);
-
- do_check_eq(profile.timesUsed, timesUsed + 1);
- do_check_neq(profile.timeLastUsed, timeLastUsed);
-
- Assert.throws(() => profileStorage.notifyUsed("INVALID_GUID"),
- /No matching profile\./);
-});
-
-add_task(function* test_remove() {
- let path = getTempFile(TEST_STORE_FILE_NAME).path;
- yield prepareTestProfiles(path);
-
- let profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- let profiles = profileStorage.getAll();
- let guid = profiles[1].guid;
-
- do_check_eq(profiles.length, 2);
-
- profileStorage.remove(guid);
- yield profileStorage._saveImmediately();
-
- profileStorage = new ProfileStorage(path);
- yield profileStorage.initialize();
-
- profiles = profileStorage.getAll();
-
- do_check_eq(profiles.length, 1);
-
- Assert.throws(() => profileStorage.get(guid), /No matching profile\./);
-});
diff --git a/browser/extensions/formautofill/test/unit/xpcshell.ini b/browser/extensions/formautofill/test/unit/xpcshell.ini
deleted file mode 100644
index 2c5763681..000000000
--- a/browser/extensions/formautofill/test/unit/xpcshell.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-support-files =
- ../../content/FormAutofillContent.jsm
- ../../content/FormAutofillParent.jsm
- ../../content/ProfileStorage.jsm
-
-[test_autofillFormFields.js]
-[test_collectFormFields.js]
-[test_populateFieldValues.js]
-[test_profileStorage.js]
diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build
index 9b01ed095..4f95704e6 100644
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -5,11 +5,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += [
- 'aushelper',
- 'e10srollout',
+# 'aushelper',
+# 'e10srollout',
'pdfjs',
- 'pocket',
- 'webcompat',
+# 'pocket',
+# 'webcompat',
]
# Only include the following system add-ons if building Aurora or Nightly
diff --git a/browser/extensions/pdfjs/moz.build b/browser/extensions/pdfjs/moz.build
index a1d2634da..aac3a838c 100644
--- a/browser/extensions/pdfjs/moz.build
+++ b/browser/extensions/pdfjs/moz.build
@@ -4,6 +4,4 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
diff --git a/browser/extensions/pdfjs/test/.eslintrc.js b/browser/extensions/pdfjs/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/extensions/pdfjs/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/extensions/pdfjs/test/browser.ini b/browser/extensions/pdfjs/test/browser.ini
deleted file mode 100644
index fb4aa9afc..000000000
--- a/browser/extensions/pdfjs/test/browser.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[DEFAULT]
-support-files =
- file_pdfjs_test.pdf
- head.js
-
-[browser_pdfjs_main.js]
-[browser_pdfjs_navigation.js]
-[browser_pdfjs_savedialog.js]
-[browser_pdfjs_views.js]
-[browser_pdfjs_zoom.js]
diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_main.js b/browser/extensions/pdfjs/test/browser_pdfjs_main.js
deleted file mode 100644
index 9660e92c1..000000000
--- a/browser/extensions/pdfjs/test/browser_pdfjs_main.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
-const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
-
-add_task(function* test() {
- let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
- let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
- let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
-
- // Make sure pdf.js is the default handler.
- is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
- is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
-
- info('Pref action: ' + handlerInfo.preferredAction);
-
- yield BrowserTestUtils.withNewTab({ gBrowser: gBrowser, url: "about:blank" },
- function* (newTabBrowser) {
- yield waitForPdfJS(newTabBrowser, TESTROOT + "file_pdfjs_test.pdf");
-
- ok(gBrowser.isFindBarInitialized(), "Browser FindBar initialized!");
-
- yield ContentTask.spawn(newTabBrowser, null, function* () {
- //
- // Overall sanity tests
- //
- Assert.ok(content.document.querySelector('div#viewer'), "document content has viewer UI");
- Assert.ok('PDFJS' in content.wrappedJSObject, "window content has PDFJS object");
-
- //
- // Sidebar: open
- //
- var sidebar = content.document.querySelector('button#sidebarToggle'),
- outerContainer = content.document.querySelector('div#outerContainer');
-
- sidebar.click();
- Assert.ok(outerContainer.classList.contains('sidebarOpen'), "sidebar opens on click");
-
- //
- // Sidebar: close
- //
- sidebar.click();
- Assert.ok(!outerContainer.classList.contains('sidebarOpen'), "sidebar closes on click");
-
- //
- // Page change from prev/next buttons
- //
- var prevPage = content.document.querySelector('button#previous'),
- nextPage = content.document.querySelector('button#next');
-
- var pgNumber = content.document.querySelector('input#pageNumber').value;
- Assert.equal(parseInt(pgNumber, 10), 1, "initial page is 1");
-
- //
- // Bookmark button
- //
- var viewBookmark = content.document.querySelector('a#viewBookmark');
- viewBookmark.click();
-
- Assert.ok(viewBookmark.href.length > 0, "viewBookmark button has href");
-
- var viewer = content.wrappedJSObject.PDFViewerApplication;
- yield viewer.close();
- });
- });
-});
diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js b/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js
deleted file mode 100644
index b01a87ec8..000000000
--- a/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-requestLongerTimeout(2);
-
-Components.utils.import("resource://gre/modules/Promise.jsm", this);
-
-const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
-const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
-
-const PDF_OUTLINE_ITEMS = 17;
-const TESTS = [
- {
- action: {
- selector: "button#next",
- event: "click"
- },
- expectedPage: 2,
- message: "navigated to next page using NEXT button"
-
- },
- {
- action: {
- selector: "button#previous",
- event: "click"
- },
- expectedPage: 1,
- message: "navigated to previous page using PREV button"
- },
- {
- action: {
- selector: "button#next",
- event: "click"
- },
- expectedPage: 2,
- message: "navigated to next page using NEXT button"
- },
- {
- action: {
- selector: "input#pageNumber",
- value: 1,
- event: "change"
- },
- expectedPage: 1,
- message: "navigated to first page using pagenumber"
- },
- {
- action: {
- selector: "#thumbnailView a:nth-child(4)",
- event: "click"
- },
- expectedPage: 4,
- message: "navigated to 4th page using thumbnail view"
- },
- {
- action: {
- selector: "#thumbnailView a:nth-child(2)",
- event: "click"
- },
- expectedPage: 2,
- message: "navigated to 2nd page using thumbnail view"
- },
- {
- action: {
- selector: "#viewer",
- event: "keydown",
- keyCode: 36
- },
- expectedPage: 1,
- message: "navigated to 1st page using 'home' key"
- },
- {
- action: {
- selector: "#viewer",
- event: "keydown",
- keyCode: 34
- },
- expectedPage: 2,
- message: "navigated to 2nd page using 'Page Down' key"
- },
- {
- action: {
- selector: "#viewer",
- event: "keydown",
- keyCode: 33
- },
- expectedPage: 1,
- message: "navigated to 1st page using 'Page Up' key"
- },
- {
- action: {
- selector: "#viewer",
- event: "keydown",
- keyCode: 39
- },
- expectedPage: 2,
- message: "navigated to 2nd page using 'right' key"
- },
- {
- action: {
- selector: "#viewer",
- event: "keydown",
- keyCode: 37
- },
- expectedPage: 1,
- message: "navigated to 1st page using 'left' key"
- },
- {
- action: {
- selector: "#viewer",
- event: "keydown",
- keyCode: 35
- },
- expectedPage: 5,
- message: "navigated to last page using 'home' key"
- },
- {
- action: {
- selector: ".outlineItem:nth-child(1) a",
- event: "click"
- },
- expectedPage: 1,
- message: "navigated to 1st page using outline view"
- },
- {
- action: {
- selector: ".outlineItem:nth-child(" + PDF_OUTLINE_ITEMS + ") a",
- event: "click"
- },
- expectedPage: 4,
- message: "navigated to 4th page using outline view"
- },
- {
- action: {
- selector: "input#pageNumber",
- value: 5,
- event: "change"
- },
- expectedPage: 5,
- message: "navigated to 5th page using pagenumber"
- }
-];
-
-add_task(function* test() {
- let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
- let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
-
- // Make sure pdf.js is the default handler.
- is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
- is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
-
- info('Pref action: ' + handlerInfo.preferredAction);
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (newTabBrowser) {
- yield waitForPdfJS(newTabBrowser, TESTROOT + "file_pdfjs_test.pdf");
-
- yield ContentTask.spawn(newTabBrowser, null, function* () {
- // Check if PDF is opened with internal viewer
- Assert.ok(content.document.querySelector("div#viewer"), "document content has viewer UI");
- Assert.ok("PDFJS" in content.wrappedJSObject, "window content has PDFJS object");
- });
-
- yield ContentTask.spawn(newTabBrowser, null, contentSetUp);
-
- yield Task.spawn(runTests(newTabBrowser));
-
- yield ContentTask.spawn(newTabBrowser, null, function*() {
- let pageNumber = content.document.querySelector('input#pageNumber');
- Assert.equal(pageNumber.value, pageNumber.max, "Document is left on the last page");
- });
- });
-});
-
-function* contentSetUp() {
- /**
- * Outline Items gets appended to the document later on we have to
- * wait for them before we start to navigate though document
- *
- * @param document
- * @returns {deferred.promise|*}
- */
- function waitForOutlineItems(document) {
- return new Promise((resolve, reject) => {
- document.addEventListener("outlineloaded", function outlineLoaded(evt) {
- document.removeEventListener("outlineloaded", outlineLoaded);
- var outlineCount = evt.detail.outlineCount;
-
- if (document.querySelectorAll(".outlineItem").length === outlineCount) {
- resolve();
- } else {
- reject();
- }
- });
- });
- }
-
- /**
- * The key navigation has to happen in page-fit, otherwise it won't scroll
- * through a complete page
- *
- * @param document
- * @returns {deferred.promise|*}
- */
- function setZoomToPageFit(document) {
- return new Promise((resolve) => {
- document.addEventListener("pagerendered", function onZoom(e) {
- document.removeEventListener("pagerendered", onZoom);
- document.querySelector("#viewer").click();
- resolve();
- });
-
- var select = document.querySelector("select#scaleSelect");
- select.selectedIndex = 2;
- select.dispatchEvent(new Event("change"));
- });
- }
-
- yield waitForOutlineItems(content.document);
- yield setZoomToPageFit(content.document);
-}
-
-/**
- * As the page changes asynchronously, we have to wait for the event after
- * we trigger the action so we will be at the expected page number after each action
- *
- * @param document
- * @param window
- * @param test
- * @param callback
- */
-function* runTests(browser) {
- yield ContentTask.spawn(browser, TESTS, function* (TESTS) {
- let window = content;
- let document = window.document;
-
- for (let test of TESTS) {
- let deferred = {};
- deferred.promise = new Promise((resolve, reject) => {
- deferred.resolve = resolve;
- deferred.reject = reject;
- });
-
- let pageNumber = document.querySelector('input#pageNumber');
-
- // Add an event-listener to wait for page to change, afterwards resolve the promise
- let timeout = window.setTimeout(() => deferred.reject(), 5000);
- window.addEventListener('pagechange', function pageChange() {
- if (pageNumber.value == test.expectedPage) {
- window.removeEventListener('pagechange', pageChange);
- window.clearTimeout(timeout);
- deferred.resolve(+pageNumber.value);
- }
- });
-
- // Get the element and trigger the action for changing the page
- var el = document.querySelector(test.action.selector);
- Assert.ok(el, "Element '" + test.action.selector + "' has been found");
-
- // The value option is for input case
- if (test.action.value)
- el.value = test.action.value;
-
- // Dispatch the event for changing the page
- if (test.action.event == "keydown") {
- var ev = document.createEvent("KeyboardEvent");
- ev.initKeyEvent("keydown", true, true, null, false, false, false, false,
- test.action.keyCode, 0);
- el.dispatchEvent(ev);
- }
- else {
- var ev = new Event(test.action.event);
- }
- el.dispatchEvent(ev);
-
- let pgNumber = yield deferred.promise;
- Assert.equal(pgNumber, test.expectedPage, test.message);
- }
-
- var viewer = content.wrappedJSObject.PDFViewerApplication;
- yield viewer.close();
- });
-}
diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js b/browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js
deleted file mode 100644
index a6564e591..000000000
--- a/browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
-const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
-
-function test() {
- var oldAction = changeMimeHandler(Ci.nsIHandlerInfo.useSystemDefault, true);
- var tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
- //
- // Test: "Open with" dialog comes up when pdf.js is not selected as the default
- // handler.
- //
- addWindowListener('chrome://mozapps/content/downloads/unknownContentType.xul', finish);
-
- waitForExplicitFinish();
- registerCleanupFunction(function() {
- changeMimeHandler(oldAction[0], oldAction[1]);
- gBrowser.removeTab(tab);
- });
-}
-
-function changeMimeHandler(preferredAction, alwaysAskBeforeHandling) {
- let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
- let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
- let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
- var oldAction = [handlerInfo.preferredAction, handlerInfo.alwaysAskBeforeHandling];
-
- // Change and save mime handler settings
- handlerInfo.alwaysAskBeforeHandling = alwaysAskBeforeHandling;
- handlerInfo.preferredAction = preferredAction;
- handlerService.store(handlerInfo);
-
- Services.obs.notifyObservers(null, 'pdfjs:handlerChanged', null);
-
- // Refresh data
- handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
-
- //
- // Test: Mime handler was updated
- //
- is(handlerInfo.alwaysAskBeforeHandling, alwaysAskBeforeHandling, 'always-ask prompt change successful');
- is(handlerInfo.preferredAction, preferredAction, 'mime handler change successful');
-
- return oldAction;
-}
-
-function addWindowListener(aURL, aCallback) {
- Services.wm.addListener({
- onOpenWindow: function(aXULWindow) {
- info("window opened, waiting for focus");
- Services.wm.removeListener(this);
-
- var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- waitForFocus(function() {
- is(domwindow.document.location.href, aURL, "should have seen the right window open");
- domwindow.close();
- aCallback();
- }, domwindow);
- },
- onCloseWindow: function(aXULWindow) { },
- onWindowTitleChange: function(aXULWindow, aNewTitle) { }
- });
-}
diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_views.js b/browser/extensions/pdfjs/test/browser_pdfjs_views.js
deleted file mode 100644
index d14503e41..000000000
--- a/browser/extensions/pdfjs/test/browser_pdfjs_views.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
-const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
-
-add_task(function* test() {
- let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
- let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
- let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
-
- // Make sure pdf.js is the default handler.
- is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
- is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
-
- info('Pref action: ' + handlerInfo.preferredAction);
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (browser) {
- // check that PDF is opened with internal viewer
- yield waitForPdfJS(browser, TESTROOT + "file_pdfjs_test.pdf");
-
- yield ContentTask.spawn(browser, null, function* () {
- Assert.ok(content.document.querySelector("div#viewer"), "document content has viewer UI");
- Assert.ok("PDFJS" in content.wrappedJSObject, "window content has PDFJS object");
-
- //open sidebar
- var sidebar = content.document.querySelector('button#sidebarToggle');
- var outerContainer = content.document.querySelector('div#outerContainer');
-
- sidebar.click();
- Assert.ok(outerContainer.classList.contains("sidebarOpen"), "sidebar opens on click");
-
- // check that thumbnail view is open
- var thumbnailView = content.document.querySelector('div#thumbnailView');
- var outlineView = content.document.querySelector('div#outlineView');
-
- Assert.equal(thumbnailView.getAttribute("class"), null,
- "Initial view is thumbnail view");
- Assert.equal(outlineView.getAttribute("class"), "hidden",
- "Outline view is hidden initially");
-
- //switch to outline view
- var viewOutlineButton = content.document.querySelector('button#viewOutline');
- viewOutlineButton.click();
-
- Assert.equal(thumbnailView.getAttribute("class"), "hidden",
- "Thumbnail view is hidden when outline is selected");
- Assert.equal(outlineView.getAttribute("class"), "",
- "Outline view is visible when selected");
-
- //switch back to thumbnail view
- var viewThumbnailButton = content.document.querySelector('button#viewThumbnail');
- viewThumbnailButton.click();
-
- Assert.equal(thumbnailView.getAttribute("class"), "",
- "Thumbnail view is visible when selected");
- Assert.equal(outlineView.getAttribute("class"), "hidden",
- "Outline view is hidden when thumbnail is selected");
-
- sidebar.click();
-
- var viewer = content.wrappedJSObject.PDFViewerApplication;
- yield viewer.close();
- });
- });
-});
diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js b/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js
deleted file mode 100644
index f2b73fd99..000000000
--- a/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-requestLongerTimeout(2);
-
-Components.utils.import("resource://gre/modules/Promise.jsm", this);
-
-const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
-const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
-
-const TESTS = [
- {
- action: {
- selector: "button#zoomIn",
- event: "click"
- },
- expectedZoom: 1, // 1 - zoom in
- message: "Zoomed in using the '+' (zoom in) button"
- },
-
- {
- action: {
- selector: "button#zoomOut",
- event: "click"
- },
- expectedZoom: -1, // -1 - zoom out
- message: "Zoomed out using the '-' (zoom out) button"
- },
-
- {
- action: {
- keyboard: true,
- keyCode: 61,
- event: "+"
- },
- expectedZoom: 1, // 1 - zoom in
- message: "Zoomed in using the CTRL++ keys"
- },
-
- {
- action: {
- keyboard: true,
- keyCode: 109,
- event: "-"
- },
- expectedZoom: -1, // -1 - zoom out
- message: "Zoomed out using the CTRL+- keys"
- },
-
- {
- action: {
- selector: "select#scaleSelect",
- index: 5,
- event: "change"
- },
- expectedZoom: -1, // -1 - zoom out
- message: "Zoomed using the zoom picker"
- }
-];
-
-add_task(function* test() {
- let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"]
- .getService(Ci.nsIHandlerService);
- let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
- let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
-
- // Make sure pdf.js is the default handler.
- is(handlerInfo.alwaysAskBeforeHandling, false,
- 'pdf handler defaults to always-ask is false');
- is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally,
- 'pdf handler defaults to internal');
-
- info('Pref action: ' + handlerInfo.preferredAction);
-
- yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
- function* (newTabBrowser) {
- yield waitForPdfJS(newTabBrowser, TESTROOT + "file_pdfjs_test.pdf" + "#zoom=100");
-
- yield ContentTask.spawn(newTabBrowser, TESTS, function* (TESTS) {
- let document = content.document;
-
- function waitForRender() {
- return new Promise((resolve) => {
- document.addEventListener("pagerendered", function onPageRendered(e) {
- if(e.detail.pageNumber !== 1) {
- return;
- }
-
- document.removeEventListener("pagerendered", onPageRendered, true);
- resolve();
- }, true);
- });
- }
-
- // check that PDF is opened with internal viewer
- Assert.ok(content.document.querySelector("div#viewer"), "document content has viewer UI");
- Assert.ok("PDFJS" in content.wrappedJSObject, "window content has PDFJS object");
-
- let initialWidth, previousWidth;
- initialWidth = previousWidth =
- parseInt(content.document.querySelector("div#pageContainer1").style.width);
-
- for (let test of TESTS) {
- // We zoom using an UI element
- var ev;
- if (test.action.selector) {
- // Get the element and trigger the action for changing the zoom
- var el = document.querySelector(test.action.selector);
- Assert.ok(el, "Element '" + test.action.selector + "' has been found");
-
- if (test.action.index){
- el.selectedIndex = test.action.index;
- }
-
- // Dispatch the event for changing the zoom
- ev = new Event(test.action.event);
- }
- // We zoom using keyboard
- else {
- // Simulate key press
- ev = new content.KeyboardEvent("keydown",
- { key: test.action.event,
- keyCode: test.action.keyCode,
- ctrlKey: true });
- el = content;
- }
-
- el.dispatchEvent(ev);
- yield waitForRender();
-
- var pageZoomScale = content.document.querySelector('select#scaleSelect');
-
- // The zoom value displayed in the zoom select
- var zoomValue = pageZoomScale.options[pageZoomScale.selectedIndex].innerHTML;
-
- let pageContainer = content.document.querySelector('div#pageContainer1');
- let actualWidth = parseInt(pageContainer.style.width);
-
- // the actual zoom of the PDF document
- let computedZoomValue = parseInt(((actualWidth/initialWidth).toFixed(2))*100) + "%";
- Assert.equal(computedZoomValue, zoomValue, "Content has correct zoom");
-
- // Check that document zooms in the expected way (in/out)
- let zoom = (actualWidth - previousWidth) * test.expectedZoom;
- Assert.ok(zoom > 0, test.message);
-
- previousWidth = actualWidth;
- }
-
- var viewer = content.wrappedJSObject.PDFViewerApplication;
- yield viewer.close();
- });
- });
-});
diff --git a/browser/extensions/pdfjs/test/file_pdfjs_test.pdf b/browser/extensions/pdfjs/test/file_pdfjs_test.pdf
deleted file mode 100644
index 7ad87e3c2..000000000
--- a/browser/extensions/pdfjs/test/file_pdfjs_test.pdf
+++ /dev/null
Binary files differ
diff --git a/browser/extensions/pdfjs/test/head.js b/browser/extensions/pdfjs/test/head.js
deleted file mode 100644
index d980bceb1..000000000
--- a/browser/extensions/pdfjs/test/head.js
+++ /dev/null
@@ -1,15 +0,0 @@
-function waitForPdfJS(browser, url) {
- // Runs tests after all 'load' event handlers have fired off
- return ContentTask.spawn(browser, url, function* (url) {
- yield new Promise((resolve) => {
- // NB: Add the listener to the global object so that we receive the
- // event fired from the new window.
- addEventListener("documentload", function listener() {
- removeEventListener("documentload", listener, false);
- resolve();
- }, false, true);
-
- content.location = url;
- });
- });
-}
diff --git a/browser/extensions/pocket/moz.build b/browser/extensions/pocket/moz.build
index 495e48a62..52227bb8b 100644
--- a/browser/extensions/pocket/moz.build
+++ b/browser/extensions/pocket/moz.build
@@ -17,6 +17,4 @@ FINAL_TARGET_PP_FILES.features['firefox@getpocket.com'] += [
'install.rdf.in'
]
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
-
JAR_MANIFESTS += ['jar.mn']
diff --git a/browser/extensions/pocket/test/.eslintrc.js b/browser/extensions/pocket/test/.eslintrc.js
deleted file mode 100644
index c764b133d..000000000
--- a/browser/extensions/pocket/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/extensions/pocket/test/browser.ini b/browser/extensions/pocket/test/browser.ini
deleted file mode 100644
index 3e0be8736..000000000
--- a/browser/extensions/pocket/test/browser.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
- test.html
-
-[browser_pocket_ui_check.js]
diff --git a/browser/extensions/pocket/test/browser_pocket_ui_check.js b/browser/extensions/pocket/test/browser_pocket_ui_check.js
deleted file mode 100644
index 12aeaffd6..000000000
--- a/browser/extensions/pocket/test/browser_pocket_ui_check.js
+++ /dev/null
@@ -1,61 +0,0 @@
-"use strict";
-
-function checkWindowProperties(expectPresent, l) {
- for (let name of l) {
- is(!!window.hasOwnProperty(name), expectPresent, "property " + name + (expectPresent ? " is" : " is not") + " present");
- }
-}
-function checkElements(expectPresent, l) {
- for (let id of l) {
- is(!!document.getElementById(id), expectPresent, "element " + id + (expectPresent ? " is" : " is not") + " present");
- }
-}
-
-add_task(function* test_setup() {
- let clearValue = Services.prefs.prefHasUserValue("extensions.pocket.enabled");
- let enabledOnStartup = Services.prefs.getBoolPref("extensions.pocket.enabled");
- registerCleanupFunction(() => {
- if (clearValue) {
- Services.prefs.clearUserPref("extensions.pocket.enabled");
- } else {
- Services.prefs.setBoolPref("extensions.pocket.enabled", enabledOnStartup);
- }
- });
-});
-
-add_task(function*() {
- yield promisePocketEnabled();
-
- checkWindowProperties(true, ["Pocket", "pktUI", "pktUIMessaging"]);
- checkElements(true, ["pocket-button", "panelMenu_pocket", "menu_pocket", "BMB_pocket",
- "panelMenu_pocketSeparator", "menu_pocketSeparator",
- "BMB_pocketSeparator"]);
-
- // check context menu exists
- info("checking content context menu");
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/browser/browser/extensions/pocket/test/test.html");
-
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- let popupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
- yield BrowserTestUtils.synthesizeMouseAtCenter("body", {
- type: "contextmenu",
- button: 2
- }, tab.linkedBrowser);
- yield popupShown;
-
- checkElements(true, ["context-pocket", "context-savelinktopocket"]);
-
- contextMenu.hidePopup();
- yield popupHidden;
- yield BrowserTestUtils.removeTab(tab);
-
- yield promisePocketDisabled();
-
- checkWindowProperties(false, ["Pocket", "pktUI", "pktUIMessaging"]);
- checkElements(false, ["pocket-button", "panelMenu_pocket", "menu_pocket", "BMB_pocket",
- "panelMenu_pocketSeparator", "menu_pocketSeparator",
- "BMB_pocketSeparator", "context-pocket", "context-savelinktopocket"]);
-
- yield promisePocketReset();
-});
diff --git a/browser/extensions/pocket/test/head.js b/browser/extensions/pocket/test/head.js
deleted file mode 100644
index e044a42c7..000000000
--- a/browser/extensions/pocket/test/head.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Currently Pocket is disabled in tests. We want these tests to work under
-// either case that Pocket is disabled or enabled on startup of the browser,
-// and that at the end we're reset to the correct state.
-let enabledOnStartup = false;
-
-// PocketEnabled/Disabled promises return true if it was already
-// Enabled/Disabled, and false if it need to Enable/Disable.
-function promisePocketEnabled() {
- if (Services.prefs.getPrefType("extensions.pocket.enabled") != Services.prefs.PREF_INVALID &&
- Services.prefs.getBoolPref("extensions.pocket.enabled")) {
- info( "pocket was already enabled, assuming enabled by default for tests");
- enabledOnStartup = true;
- return Promise.resolve(true);
- }
- info( "pocket is not enabled");
- return new Promise((resolve, reject) => {
- let listener = {
- onWidgetAfterCreation(widgetid) {
- if (widgetid == "pocket-button") {
- info("pocket-button created");
- CustomizableUI.removeListener(listener);
- resolve(false);
- }
- }
- }
- CustomizableUI.addListener(listener);
- Services.prefs.setBoolPref("extensions.pocket.enabled", true);
- });
-}
-
-function promisePocketDisabled() {
- if (Services.prefs.getPrefType("extensions.pocket.enabled") == Services.prefs.PREF_INVALID ||
- !Services.prefs.getBoolPref("extensions.pocket.enabled")) {
- info("pocket-button already disabled");
- return Promise.resolve(true);
- }
- return new Promise((resolve, reject) => {
- let listener = {
- onWidgetDestroyed: function(widgetid) {
- if (widgetid == "pocket-button") {
- CustomizableUI.removeListener(listener);
- info( "pocket-button destroyed");
- // wait for a full unload of pocket
- BrowserTestUtils.waitForCondition(() => {
- return !window.hasOwnProperty("pktUI");
- }, "pocket properties removed from window").then(() => {
- resolve(false);
- })
- }
- }
- }
- CustomizableUI.addListener(listener);
- info("reset pocket enabled pref");
- // testing/profiles/prefs_general.js uses user_pref to disable pocket, set
- // back to false.
- Services.prefs.setBoolPref("extensions.pocket.enabled", false);
- });
-}
-
-function promisePocketReset() {
- if (enabledOnStartup) {
- info("reset is enabling pocket addon");
- return promisePocketEnabled();
- }
- info("reset is disabling pocket addon");
- return promisePocketDisabled();
-}
diff --git a/browser/extensions/pocket/test/test.html b/browser/extensions/pocket/test/test.html
deleted file mode 100644
index aa08cd566..000000000
--- a/browser/extensions/pocket/test/test.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
- <title>Page Title</title>
- <meta charset="utf-8" />
-</head>
-
-<body>
-</body>
-</html>
diff --git a/browser/extensions/webcompat/moz.build b/browser/extensions/webcompat/moz.build
index 2423511b4..7d592013b 100644
--- a/browser/extensions/webcompat/moz.build
+++ b/browser/extensions/webcompat/moz.build
@@ -14,5 +14,3 @@ FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
FINAL_TARGET_PP_FILES.features['webcompat@mozilla.org'] += [
'install.rdf.in'
]
-
-BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
diff --git a/browser/extensions/webcompat/test/browser/.eslintrc.js b/browser/extensions/webcompat/test/browser/.eslintrc.js
deleted file mode 100644
index 7c8021192..000000000
--- a/browser/extensions/webcompat/test/browser/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/extensions/webcompat/test/browser/browser.ini b/browser/extensions/webcompat/test/browser/browser.ini
deleted file mode 100644
index 500224636..000000000
--- a/browser/extensions/webcompat/test/browser/browser.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[DEFAULT]
-
-[browser_check_installed.js]
diff --git a/browser/extensions/webcompat/test/browser/browser_check_installed.js b/browser/extensions/webcompat/test/browser/browser_check_installed.js
deleted file mode 100644
index b77458054..000000000
--- a/browser/extensions/webcompat/test/browser/browser_check_installed.js
+++ /dev/null
@@ -1,13 +0,0 @@
-"use strict";
-
-add_task(function* test_enabled() {
- let addon = yield new Promise(
- resolve => AddonManager.getAddonByID("webcompat@mozilla.org", resolve)
- );
- isnot(addon, null, "Check addon exists");
- is(addon.version, "1.0", "Check version");
- is(addon.name, "Web Compat", "Check name");
- ok(addon.isCompatible, "Check application compatibility");
- ok(!addon.appDisabled, "Check not app disabled");
- ok(addon.isActive, "Check addon is active");
-});
diff --git a/browser/installer/windows/moz.build b/browser/installer/windows/moz.build
index b953b57a0..12e7831ed 100644
--- a/browser/installer/windows/moz.build
+++ b/browser/installer/windows/moz.build
@@ -4,7 +4,7 @@
# 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/.
-DEFINES['APP_VERSION'] = CONFIG['FIREFOX_VERSION']
+DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_NAME'] = CONFIG['MOZ_APP_NAME']
DEFINES['MOZ_APP_DISPLAYNAME'] = CONFIG['MOZ_APP_DISPLAYNAME']
diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in
index 6b0455bf0..fac5531a6 100644
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -99,7 +99,7 @@ libs-%:
@$(MAKE) -C ../../toolkit/locales libs-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$*
- @$(MAKE) -C ../extensions/pocket/locale AB_CD=$* XPI_NAME=locale-$*
+# @$(MAKE) -C ../extensions/pocket/locale AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../devtools/client/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -B searchplugins AB_CD=$* XPI_NAME=locale-$*
diff --git a/browser/locales/en-US/chrome/browser-region/region.properties b/browser/locales/en-US/chrome/browser-region/region.properties
index e078ed528..e35fc7497 100644
--- a/browser/locales/en-US/chrome/browser-region/region.properties
+++ b/browser/locales/en-US/chrome/browser-region/region.properties
@@ -3,10 +3,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Default search engine
-browser.search.defaultenginename=Google
+browser.search.defaultenginename=DuckDuckGo
# Search engine order (order displayed in the search bar dropdown)s
-browser.search.order.1=Google
+browser.search.order.1=DuckDuckGo
browser.search.order.2=Yahoo
browser.search.order.3=Bing
diff --git a/browser/locales/en-US/chrome/overrides/netError.dtd b/browser/locales/en-US/chrome/overrides/netError.dtd
index 92db8ee3a..6c65c9345 100644
--- a/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -199,7 +199,7 @@ was trying to connect. -->
<!-- LOCALIZATION NOTE (certerror.wrongSystemTime) - The <span id='..' /> tags will be injected with actual values,
please leave them unchanged. -->
-<!ENTITY certerror.wrongSystemTime "<p>&brandShortName; did not connect to <span id='wrongSystemTimeWithoutReference_URL'/> because your computer’s clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTimeWithoutReference_systemDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
+<!ENTITY certerror.wrongSystemTime "<p>A secure connection to <span id='wrongSystemTime_URL'/> isn’t possible because your clock appears to show the wrong time.</p> <p>Your computer thinks it is <span id='wrongSystemTime_systemDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
<!ENTITY certerror.pagetitle1 "Insecure Connection">
<!ENTITY certerror.whatShouldIDo.badStsCertExplanation "This site uses HTTP
diff --git a/browser/locales/generic/profile/bookmarks.html.in b/browser/locales/generic/profile/bookmarks.html.in
index 5b7bdad69..e9121f023 100644
--- a/browser/locales/generic/profile/bookmarks.html.in
+++ b/browser/locales/generic/profile/bookmarks.html.in
@@ -7,15 +7,6 @@
#define mozilla_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=
-#define nightly_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA01JREFUeNpkk01oXFUUx//vzp33ZiaTzkwnyUwmsbbNRpp0GhuVKiVgQIUiLmoX7lyIG10I6qIUrG6KGyuYZbMwiATqxipSMVhQYwWhiwSJwUxKkzbz8ZJ5H/M+7/vunUIE7Vnc1f3/zjn/c46wsCbjIOI4Rlfew+Zf6/h9+RYYYzj70hymZp7GULUCSin+H8IBwLYsfLOwiOfffndK1c2LmhO84jl+2e5ZCTN6Xer0fpp5dmq+frxy5zGAY9n49IOLuHDls8uqE3y07YV0ywwQGA6oZsJRFRT0FnK2Hpw8PTl/7tXZDw8ApF/29YUvufjqxxqLPrnLQBUiQRUI4EcQHQ+EgwbjENl8Pv3H9W/f//m7W9cOAKkXzr+J4pm5umy6S/uEkiAEOlzscWHG5jTbhcsrDJiHsN1CIScJTlc5JaSlldEna9uk8fcGHNO6tOMGqfssQjNFoHOxyAXU9xF5HiRXw2AqhuUEsLs6giCkjbXG549a+O3mMhQneLnthOh0NBiaAdozkTEdpC0Hnm2hKAKR3ESJRigNFZBHCF2zn+p7SMIwRM9kRcI/D5g2xAcd1PQeMtw8xkGuafIRGRgZKfHfCbKlIu5t3IVASYYDDtMzL85il2fLuh6qIkFkWtjrARY3zjENJLwCKgqwOjLcnW30Qh/HnpmGYTJhT1bSdPL0NBpr+6rbs8qhIiPivQtRhDDJQuCViI4BxdJRrx/jBopob25BDmIMnzgZjFTK+2R4tAo4+q8iM9Ba3wBTuxirHELeM5AxFO6FCsnSsHNnFfL9XUiFIo7ypNmB9D3eQkT665nS5Xm72Q5r3KCo04be2MIRKULOUlEkPnJpAbn8AI7XJyEUy/CBhIrJlUdT6D/rP3x1u1yQFjP5bFIbH4HdbHG2j/GJMfiqzneCwVI0oFrD8OgTiKLgl5Ubi0v/uYV3ZqcrE2ff+Do2/LlUxAi/HKQZH9eegupzpxDztL4gIfTU9d3VG+ev/nh7s6/797wiz1K3VpYuDU3MvFWunXg9ly2WTNVNDZaPgIU08V3NMNXVZfmfP68lvt187Br78d5r52hoKaUkiWspQqqHx4+OCQLhFu3KAXNbCYQWzR5SBCr5X3x/M+lrHgowAMP2wWqd+FzxAAAAAElFTkSuQmCC
-
-#define firefox_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAz5JREFUeNpcU0toXFUY/s49596588ikySSmM8rk0UkJEirVTVEjYk1NUdRFFgouXZQI2k2hUCjdiYIuCi4Kuig0DbqQYgU3Yi0iFRuRCBMwaZvMZDTNY95z3/fM8b8jldpzOeeee/i/737n+/+f4ZExf730rkiaZ9NJMx/nmk5HypMqqLr+ZuD4F67N5ZYejmfRsnvhyKsLhSs3zP70SubgYKHSdFENu+gXAprQIGnvBi5ez0m1b6u7M399+PTx+UvtCKtFi2F6195qXK2byir88esy5ksfYND5DhuhRCtUKBNB0Q7w5Z8ee2GgWdjOn250fn5v5j8F5dOHlZD0kWRgAwp3hrKY0S9BJWKIcQ5PShhNG4+1bHx+IocT+RXcrRSDMfFNRvvt3Oyp/icIrRhUl9hoO4kt3F55Bxf3LkLV20jWOohbDjzXxyc/lMH0cRSyCd1xq+dFhu986t7T0CUwIzB8EkW3O5ibhj44ib7NJhiBKRoB/aS4ZWHjbxtjGQYP7nGRTjim1SaQqYiAVAREpHG8vzWJn+6PQ6CF0HPR7nQQczpYeEWHyWMUkwU8MSECGwgJxAWp9xWKNzkuH3oet+JDlIE9Momedh1G4CN0bfhVG9nsS0BQQthJx0V7j3elq7ihqV5ezQTwZmodP9ZGkU/bOPr4Nr53xtDYsaD7Dg4nNqFaH5OCYSSdGhf7daNmuv6wEKqXk/yExKGBHSznFsH6FFpKQ/JAA0ulUejWLt44lkHXsqDaX6C6Nl4Rnq8vK8s/KThDMlJhkI91YOO+iR3XwEelCdTCBLSgijNzd6DLNfhlHfZ6FtWiWBQpq/V2LdSrrNPljBQkoOjuCiPxAMutOIbkPqYSEqeequGZaTLzdhZhS0PlnlB9bvhtr5CuHj3y2Qj8hVQ/kEopxONEEsO/0yATDYXYAdWrE69JEElXq7Hyk0tro+xBU1yZmr4xrIcvptIRCZlJJAYBmRGRkD08aivA7VDvWPqt564Xn41w/AHB1/u7l1/uGxGU8mNcgodUNDIq0JDeLnpzc1uo1Qr76rWbqyf/142PjsXJqdkmN2YDnQ9oGkJNU+t57q7qUv4y9/t64+HYfwQYAN7OczrzUDvGAAAAAElFTkSuQmCC
-
-#define bugzilla_icon data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnYCL7J0pY9wwETY9kYEM9AAAAAEBAYAhVVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1bjTOS1Vb/wAA2/8JEqT/Q0g8kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJnMqoiJtJ/0haST/NEkp/yQnW/8AAPD8AAHY/RsgP/JZUI+GKitih4ObUEAAAAAAAAAAAAAAAAAAAAAAKnouwip5Lv9ooW//a6Jz/y9GIv8JBXb/AADO/gEBvf8AAK7/FRJp/z9BfP8iLGj1AAAAAAAAAAAAAAAAL4YzwiB0I/+UwJ3/bK+C/02eZ/9CTjz/DBa1/wABxf8BAOj/AACp/w8Oc/sJCv//EhCN9AAAAAAAAAAANJA6iC2MMv93tYL/TZ5U/3mzjP9NoWr/NEss/wYIU/8CBOn/ARCX/wwNqP0TD6X/Cgyex5qacDAAAAAAAAAAADKUN/ZirWj/d76R/0SgXf9Ln1P/eLSM/1mda/8rOkb/CQiD/wMQvf8UEnT/MTAt4P//MwUhZyN8AAAAAAAAAAAznDf5UqlZ/228jP9NqnD/Qp9c/0yiVP+Dv5b/VaVw/0VxXf9PZXD/S3pQ/y54Nf8jcCf/I2wn/wAAAAA0ozjIM6E4/zOeOP+Uz6z/XLR+/06scv9BoV3/TqZX/4XBmP9XqHP/hr6Z/yp+Lf8leSr1JXUqbQAAAAA3rTz7Nqo7/zWmOqM3oz7rUK1W/43Mpf9etYD/T61z/0KjXf9Rqln/msup/46/lf8pgy7/JFg6sAAAAAAAAAAAOK8+8jqvOiMAAAAAAAAAADSlOv85pT//kM6o/2K5hP9Ysnv/YLJ2/ziXPv8piS3/V6Ri/yZQQ9wAAAAAAAAAAAAAAAAAAAAAAAAAADetP0E2qzz/OKg98UWsS/+e1K3/pNe4/4XDjv8ojy3/T7df/5fIqv8sjTH/K4kw/yqFLv8AAAAAAAAAAAAAAAA4sT3xN7A8+QAAAAA4qz3yNag6/zSlOf80oTn/csJ+/6/jwv9fjHj/MmRMdQAAAAAAAAAAAAAAAAAAAAAAAAAAOrdA/zm0QHQAAAAAAAAAADasO/k2qTvuRX5lpjqGT/gznDr/O3FXigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADq9QiMAAAAAAAAAAAAAAAA4sj7/Nq09s0uOaSI1qTplM6U68wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrc//zu0P0EAAAAAOK4+UjWsPPgAAAAAAAAAAAAAAAAAAAAA/48AAP8HAAD4AQAA8AAAAOAAAADAAQAAwAMAAMAAAACAAwAAAAMAAHADAADwAAAA5AcAAO4HAAD+bwAA/u8AAA==
-
-#define mdn_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAACYklEQVQ4y3WSTYjNYRTGf+f9/+/NuDN3GKMxt1mYpKR8RT6zEk1iyUo2IysSNspCxEIZRSN07YiUJSWkaUIZizELMzIZlO9h3MzXvf/341jcmTGa69RZvKfnPOc5z3mhQlRd651Ry17tqQQl5uR9ONHC3EtdiPPxWKZ24bhJvQV0OlBHhiV7pTs3WpUdEmeLrnWJAhhOtJA5/3RjqZg8Lrnwy4bQT/DvTb73Qt3N9ymATNvTU15Mvx8vfvTWDrmgT0y+dzuAZM527lM0Xx6jFKvnEKIYvIIqVeMFRCfEiDBWMw9UQUBUT8fBWvmrU9HEUpUWDq2cT23a0P6kQEqEwTFLQCBJpm9mYrV+6lW0ngNr62jb0kw6KvMeXJohZYSLzz9xvOMDJG6aPUKMtZPDObq+iXPbmoG/ooJC0QVaVy2g5AI3Bkq8/jYCkQEBo9ah1hESS1N1Gu9DxXNFRji0oYm+/Stoaa4tK0kcRq1HE4fxHqOKEf4bk16ubphd9iKxGKxFrcOWLB1vvuOCzmg0Irig1MxKMfBznPbOd2DLCmJNHKgSIdzr/kjXhwKbFtVPNQ+NJiw7+YDh0YTFuVr6CwLpaNJDjCYOtR61DldyHL7975c9dqeH4ZESscC7r79BFBI7kY5YrZsCC8qL/kFyR+6yY0UjS3M1PHz5ich71IOIQGSn0cskwdTeryTyfV9+jGzOP3rTQAiIHUNQEBkCeUbkcqguB2JEMGqt4sJlg8lGIsv0+p5dON8YaVgn3veJ85/F61YNtn5uXf3OCF0TQVacP0PiXMVzpfbemlnbna+I/QPSFTsRLd+hHAAAAABJRU5ErkJggg==
-
-#define addon_icon data:image/vndmicrosofticon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKoSURBVDiNjZNLaJRnFIaf75vvy2UGTWr8NYkxl0IFUYkNXSSZQNWFWlxIEVy1FLLo0i4adddVXRnS4kJwYxci2GaRTWlSFGKFGRXNmFBF62VMO4TENBdjMv9k5p//Oy4SLzgqHs7yPc95eTlHiQjvqniPbVYRzuBoR+FQDEvId4neIPNCY945DayNVff/8NUvn9XXNJMv5hhKnTvYP3ymHmj/IMBSbmHjjP8fycxv+MEzGqtatUI1vK7R7wM4J32XUv3Li/l5imGBkbtXlsMw/PF1jXozg3iP3aM0Z8XRBFDr1fl7Og9EnTguXx30p/6fjAIozb/i6C4BdB2z6QOfH27ZUFNL0QUELs/tycs4J2zdGEerCADTM1P8df3PxyUZiKPF8zyGHpwGFLC6QCCRuYA4QQQ6mw4hjhYT77GN2qiBWFnV5sXc0xMAgfKx5foVYKURB2vLPbxoM8auODE6ws/fH+77dHtjhxp5OHzywpWf/IIsRk25Rq0CRFY4UVNNndkmqZFRf3YuWaYUS0aE3RP5MXX3/iCOgu3Y1WYfL90sdSDgxRoYTY5mZ2anjwC/AqEBdM4tMJ4dwYs1YiOGSBkYrVHqlQNxoC34OV8BdxK9gQ+guo7bwdYdrXu92nU6nR7Pzc/PSXxfazTj30IpRaWpIqbX4UQoBDkWJlRwLzVeLBTyGs2UcUX5duzvsfPqNpvDovQhnBIdELGaWFk1hclYmLx2fxmFbNm5qXJNvdi2DQ1WAsO1P/5petshyf6v25gJ0nxUUUeiP531s/kvAcor7MDOL2pjz3JzVKpqUoMTpb8QsSqdeTT98fomjyDv8LP5aKI3uAgQP2orCkGAVRVMZxbQhnQJIAzkm3s3Js6GSfkEQEd4+bpa8+TW71P1ANqoB65I93OA2DgV+Z+omgAAAABJRU5ErkJggg==
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
@@ -27,30 +18,14 @@
<dl><p>
<dt><h3 personal_toolbar_folder="true">@bookmarks_toolbarfolder@</h3></dt>
<dd>@bookmarks_toolbarfolder_description@
-#ifndef NIGHTLY_BUILD
<dl>
- <p><dt><a href="https://www.mozilla.org/@AB_CD@/firefox/central/" icon="@firefox_icon@">@getting_started@</a></dt>
+ <p><dt><a href="http://www.basilisk-browser.org/">Basilisk</a></dt>
</dl>
<p><dt><h3>@firefox_heading@</h3></dt>
<dl><p>
- <dt><a href="https://www.mozilla.org/@AB_CD@/firefox/help/" icon="@mozilla_icon@">@firefox_help@</a>
+ <dt><a href="https://support.mozilla.org/@AB_CD@/products/firefox" icon="@mozilla_icon@">@firefox_help@</a>
<dt><a href="https://www.mozilla.org/@AB_CD@/firefox/customize/" icon="@mozilla_icon@">@firefox_customize@</a>
<dt><a href="https://www.mozilla.org/@AB_CD@/contribute/" icon="@mozilla_icon@">@firefox_community@</a>
<dt><a href="https://www.mozilla.org/@AB_CD@/about/" icon="@mozilla_icon@">@firefox_about@</a>
</dl>
-#else
- <dl>
- <p><dt><a href="https://www.mozilla.org/@AB_CD@/contribute/" icon="@mozilla_icon@">@firefox_community@</a>
- </dl>
- <p><dt><h3>@nightly_heading@</h3></dt>
- <dl><p>
- <dt><a href="https://blog.nightly.mozilla.org/" icon="@nightly_icon@">@nightly_blog@</a>
- <dt><a href="https://bugzilla.mozilla.org/" icon="@bugzilla_icon@" shortcuturl="bz">@bugzilla@</a>
- <dt><a href="https://developer.mozilla.org/" icon="@mdn_icon@" shortcuturl="mdn">@mdn@</a>
- <dt><a href="https://addons.mozilla.org/@AB_CD@/firefox/addon/nightly-tester-tools/" icon="@addon_icon@">@nightly_tester_tools@</a>
- <dt><a href="about:crashes" icon="@mozilla_icon@">@crashes@</a>
- <dt><a href="https://mibbit.com/?server=irc.mozilla.org&channel=%23nightly" icon="@mozilla_icon@">@irc@</a>
- <dt><a href="https://planet.mozilla.org/" icon="@mozilla_icon@">@planet@</a>
- </dl>
-#endif
</dl>
diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn
index eff09189b..6d76d20f0 100644
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -98,7 +98,6 @@
locale/browser/searchplugins/ (.deps/generated_@AB_CD@/*.xml)
locale/browser/searchplugins/list.json (.deps/generated_@AB_CD@/list.json)
#endif
- locale/browser/searchplugins/images/yandex-en.ico (searchplugins/images/yandex-en.ico)
% locale browser-region @AB_CD@ %locale/browser-region/
locale/browser-region/region.properties (%chrome/browser-region/region.properties)
# the following files are browser-specific overrides
diff --git a/browser/locales/search/list.json b/browser/locales/search/list.json
index 5003126fc..9f7d82b4e 100644
--- a/browser/locales/search/list.json
+++ b/browser/locales/search/list.json
@@ -1,840 +1,732 @@
{
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazondotcom", "bing", "ddg", "twitter", "wikipedia"
+ "ddg", "yahoo", "bing", "wikipedia"
]
},
+ "regionOverrides": {
+ "US": {
+ "google": "google-nocodes"
+ },
+ "CA": {
+ "google": "google-nocodes"
+ },
+ "KZ": {
+ "google": "google-nocodes"
+ },
+ "BY": {
+ "google": "google-nocodes"
+ },
+ "RU": {
+ "google": "google-nocodes"
+ },
+ "TR": {
+ "google": "google-nocodes"
+ },
+ "UA": {
+ "google": "google-nocodes"
+ },
+ "CN": {
+ "google": "google-nocodes"
+ },
+ "TW": {
+ "google": "google-nocodes"
+ },
+ "HK": {
+ "google": "google-nocodes"
+ }
+ },
"locales": {
"en-US": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazondotcom", "bing", "ddg", "twitter", "wikipedia"
- ]
- },
- "experimental-hidden": {
- "visibleDefaultEngines": [
- "yahoo-en-CA", "yandex-en", "google-2018"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ach": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"af": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "wikipedia-af"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"an": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-es", "bing", "wikipedia-an", "ddg", "twitter"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ar": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "wikipedia-ar"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"as": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "amazondotcom", "ddg", "wikipedia-as"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ast": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-es", "bing", "diccionariu-alla", "ddg", "wikipedia-ast"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"az": {
"default": {
"visibleDefaultEngines": [
- "google", "amazondotcom", "azerdict", "bing", "ddg", "wikipedia-az", "yandex-az"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"bg": {
"default": {
"visibleDefaultEngines": [
- "google", "diribg", "amazondotcom", "ddg", "portalbgdict", "wikipedia-bg"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"bn-BD": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "ddg", "wikipedia-bn"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"bn-IN": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "amazondotcom", "bing", "ddg", "rediff", "wikipedia-bn"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"br": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-france", "amazon-france", "ddg", "freelang", "klask", "wikipedia-br"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"bs": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "ddg", "olx", "twitter", "wikipedia-bs"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ca": {
"default": {
"visibleDefaultEngines": [
- "google", "bing", "diec2", "ddg", "twitter", "wikipedia-ca"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"cak": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-espanol", "bing", "amazondotcom", "ddg", "wikipedia-es"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"cs": {
"default": {
"visibleDefaultEngines": [
- "google", "seznam-cz", "ddg", "heureka-cz", "mapy-cz", "wikipedia-cz"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"cy": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-en-GB", "amazon-en-GB", "ddg", "palasprint", "termau", "wikipedia-cy"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"da": {
"default": {
"visibleDefaultEngines": [
- "google", "bing", "amazon-en-GB", "ddg", "wikipedia-da"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"de": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-de", "amazondotcom-de", "bing", "ddg", "leo_ende_de", "wikipedia-de"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"dsb": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-de", "bing", "amazondotcom-de", "ddg", "leo_ende_de", "wikipedia-dsb"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"el": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazon-en-GB", "bing", "ddg", "wikipedia-el"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"en-GB": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-en-GB", "bing", "amazon-en-GB", "chambers-en-GB", "ddg", "twitter", "wikipedia"
- ]
- },
- "experimental-hidden": {
- "visibleDefaultEngines": [
- "yandex-en"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"en-ZA": {
"default": {
"visibleDefaultEngines": [
- "google", "bing", "amazondotcom", "ddg", "twitter", "wikipedia"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"eo": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "reta-vortaro", "wikipedia-eo"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"es-AR": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-ar", "amazondotcom", "drae", "ddg", "mercadolibre-ar", "wikipedia-es"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"es-CL": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-cl", "bing", "drae", "ddg", "mercadolibre-cl", "wikipedia-es"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"es-ES": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-es", "bing", "drae", "ddg", "twitter", "wikipedia-es"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"es-MX": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-mx", "bing", "ddg", "mercadolibre-mx", "wikipedia-es"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"et": {
"default": {
"visibleDefaultEngines": [
- "google", "neti-ee", "ddg", "osta-ee", "wikipedia-et", "eki-ee"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"eu": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazon-en-GB", "ddg", "elebila", "wikipedia-eu"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"fa": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazondotcom", "bing", "ddg", "wikipedia-fa"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ff": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-france", "bing", "amazon-france", "ddg", "cnrtl-tlfi-fr", "wikipedia-fr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"fi": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-fi", "bing", "bookplus-fi", "ddg", "wikipedia-fi"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"fr": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-france", "bing", "amazon-france", "ddg", "cnrtl-tlfi-fr", "wikipedia-fr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"fy-NL": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-fy-NL", "bing", "bolcom-fy-NL", "ddg", "marktplaats-fy-NL", "wikipedia-fy-NL"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ga-IE": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-en-GB", "amazon-en-GB", "ddg", "tearma", "twitter", "wikipedia-ga-IE"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"gd": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-en-GB", "faclair-beag", "amazon-en-GB", "bbc-alba", "ddg", "wikipedia-gd"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"gl": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-es", "amazon-en-GB", "ddg", "wikipedia-gl"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"gn": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-es", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-gn"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"gu-IN": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "ddg", "gujaratilexicon", "wikipedia-gu"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"he": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "ddg", "wikipedia-he", "morfix-dic"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"hi-IN": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "ddg", "wikipedia-hi"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"hr": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazon-en-GB", "bing", "ddg", "eudict", "twitter", "wikipedia-hr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"hsb": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-de", "bing", "amazondotcom-de", "ddg", "leo_ende_de", "wikipedia-hsb"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"hu": {
"default": {
"visibleDefaultEngines": [
- "google", "ddg", "sztaki-en-hu", "vatera", "wikipedia-hu"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"hy-AM": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazondotcom", "ddg", "list-am", "wikipedia-hy"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"id": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-id", "ddg", "wikipedia-id"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"is": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "leit-is", "wikipedia-is"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"it": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-it", "bing", "amazon-it", "ddg", "hoepli", "wikipedia-it"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ja-JP-mac": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-jp", "bing", "amazon-jp", "rakuten", "yahoo-jp-auctions", "oshiete-goo", "twitter-ja", "wikipedia-ja", "ddg"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ja": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-jp", "bing", "amazon-jp", "rakuten", "yahoo-jp-auctions", "oshiete-goo", "twitter-ja", "wikipedia-ja", "ddg"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ka": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-ka"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"kab": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-france", "bing", "ddg", "wikipedia-kab"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"kk": {
"default": {
"visibleDefaultEngines": [
- "yandex-kk", "google", "ddg", "flip", "kaz-kk", "twitter", "wikipedia-kk"
- ]
- },
- "KZ": {
- "visibleDefaultEngines": [
- "yandex-kk", "google-nocodes", "ddg", "flip", "kaz-kk", "twitter", "wikipedia-kk"
- ]
- },
- "BY": {
- "visibleDefaultEngines": [
- "yandex-kk", "google-nocodes", "ddg", "flip", "kaz-kk", "twitter", "wikipedia-kk"
- ]
- },
- "RU": {
- "visibleDefaultEngines": [
- "yandex-kk", "google-nocodes", "ddg", "flip", "kaz-kk", "twitter", "wikipedia-kk"
- ]
- },
- "TR": {
- "visibleDefaultEngines": [
- "yandex-kk", "google-nocodes", "ddg", "flip", "kaz-kk", "twitter", "wikipedia-kk"
- ]
- },
- "UA": {
- "visibleDefaultEngines": [
- "yandex-kk", "google-nocodes", "ddg", "flip", "kaz-kk", "twitter", "wikipedia-kk"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"km": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-km"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"kn": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "amazondotcom", "ddg", "kannadastore", "wikipedia-kn"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ko": {
"default": {
"visibleDefaultEngines": [
- "google", "ddg", "naver-kr", "danawa-kr", "daum-kr", "wikipedia-kr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"lij": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-it", "bing", "amazon-it", "ddg", "paroledigenova-lij", "wikipedia-lij"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"lt": {
"default": {
"visibleDefaultEngines": [
- "google", "wikipedia-lt", "bing", "amazondotcom", "ddg", "twitter"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ltg": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "dict-enlv", "ddg", "salidzinilv", "sslv", "wikipedia-lv"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"lv": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "dict-enlv", "ddg", "salidzinilv", "sslv", "wikipedia-lv"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"mai": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "ddg", "twitter", "wikipedia-hi"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"mk": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "wikipedia-mk"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ml": {
"default": {
"visibleDefaultEngines": [
- "google", "webdunia", "bing", "ddg", "rediff", "wikipedia", "wikipedia-ml"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"mr": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "amazondotcom", "ddg", "rediff", "wikipedia-mr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ms": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-ms"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"my": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-my"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"nb-NO": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-NO", "amazon-en-GB", "bing", "ddg", "gulesider-NO", "bok-NO", "qxl-NO", "wikipedia-NO"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ne-NP": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "ddg", "twitter", "wikipedia-ne"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"nl": {
"default": {
"visibleDefaultEngines": [
- "google", "bing", "bolcom-nl", "ddg", "marktplaats-nl", "wikipedia-nl"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"nn-NO": {
"default": {
"visibleDefaultEngines": [
- "google", "bing", "amazon-en-GB", "ddg", "gulesider-NO", "bok-NO", "qxl-NO", "wikipedia-NN"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"or": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "amazondotcom", "ddg", "wikipedia-or"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"pa-IN": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "ddg", "wikipedia-pa"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"pl": {
"default": {
"visibleDefaultEngines": [
- "google", "allegro-pl", "ddg", "pwn-pl", "wikipedia-pl", "wolnelektury-pl"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"pt-BR": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-br", "bing", "buscape", "ddg", "mercadolivre", "twitter", "wikipedia-pt"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"pt-PT": {
"default": {
"visibleDefaultEngines": [
- "google", "amazon-en-GB", "ddg", "priberam", "sapo", "wikipedia-pt"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"rm": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-ch", "bing", "ddg", "leo_ende_de-rm", "pledarigrond", "wikipedia-rm"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ro": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "wikipediaro"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ru": {
"default": {
"visibleDefaultEngines": [
- "yandex-ru", "google", "ddg", "ozonru", "priceru", "wikipedia-ru", "mailru"
- ]
- },
- "RU": {
- "visibleDefaultEngines": [
- "yandex-ru", "google-nocodes", "ddg", "ozonru", "priceru", "wikipedia-ru", "mailru"
- ]
- },
- "BY": {
- "visibleDefaultEngines": [
- "yandex-ru", "google-nocodes", "ddg", "ozonru", "priceru", "wikipedia-ru", "mailru"
- ]
- },
- "KZ": {
- "visibleDefaultEngines": [
- "yandex-ru", "google-nocodes", "ddg", "ozonru", "priceru", "wikipedia-ru", "mailru"
- ]
- },
- "TR": {
- "visibleDefaultEngines": [
- "yandex-ru", "google-nocodes", "ddg", "ozonru", "priceru", "wikipedia-ru", "mailru"
- ]
- },
- "UA": {
- "visibleDefaultEngines": [
- "yandex-ru", "google-nocodes", "ddg", "ozonru", "priceru", "wikipedia-ru", "mailru"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"si": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazondotcom", "ddg", "wikipedia-si"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"sk": {
"default": {
"visibleDefaultEngines": [
- "google", "azet-sk", "atlas-sk", "ddg", "dunaj-sk", "slovnik-sk", "wikipedia-sk", "zoznam-sk"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"sl": {
"default": {
"visibleDefaultEngines": [
- "google", "ceneji", "ddg", "najdi-si", "odpiralni", "twitter", "wikipedia-sl"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"son": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-france", "bing", "amazon-france", "ddg", "cnrtl-tlfi-fr", "wikipedia-fr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"sq": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazon-en-GB", "ddg", "wikipedia-sq"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"sr": {
"default": {
"visibleDefaultEngines": [
- "google", "amazon-en-GB", "bing", "ddg", "wikipedia-sr", "pogodak"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"sv-SE": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-sv-SE", "bing", "allaannonser-sv-SE", "ddg", "prisjakt-sv-SE", "tyda-sv-SE", "wikipedia-sv-SE"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ta": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "ddg", "wikipedia-ta"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"te": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "amazondotcom", "ddg", "wikipedia-te", "wiktionary-te"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"th": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "amazondotcom", "bing", "ddg", "longdo", "wikipedia-th"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"tl": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-tl", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-tl"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"tr": {
"default": {
"visibleDefaultEngines": [
- "yandex-tr", "google", "ddg", "twitter", "wikipedia-tr"
- ]
- },
- "TR": {
- "visibleDefaultEngines": [
- "yandex-tr", "google-nocodes", "ddg", "twitter", "wikipedia-tr"
- ]
- },
- "BY": {
- "visibleDefaultEngines": [
- "yandex-tr", "google-nocodes", "ddg", "twitter", "wikipedia-tr"
- ]
- },
- "KZ": {
- "visibleDefaultEngines": [
- "yandex-tr", "google-nocodes", "ddg", "twitter", "wikipedia-tr"
- ]
- },
- "RU": {
- "visibleDefaultEngines": [
- "yandex-tr", "google-nocodes", "ddg", "twitter", "wikipedia-tr"
- ]
- },
- "UA": {
- "visibleDefaultEngines": [
- "yandex-tr", "google-nocodes", "ddg", "twitter", "wikipedia-tr"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"uk": {
"default": {
"visibleDefaultEngines": [
- "google", "yandex-uk", "meta-ua", "ddg", "wikipedia-uk", "metamarket"
- ]
- },
- "UA": {
- "visibleDefaultEngines": [
- "google-nocodes", "yandex-uk", "meta-ua", "ddg", "wikipedia-uk", "metamarket"
- ]
- },
- "TR": {
- "visibleDefaultEngines": [
- "google-nocodes", "yandex-uk", "meta-ua", "ddg", "wikipedia-uk", "metamarket"
- ]
- },
- "BY": {
- "visibleDefaultEngines": [
- "google-nocodes", "yandex-uk", "meta-ua", "ddg", "wikipedia-uk", "metamarket"
- ]
- },
- "KZ": {
- "visibleDefaultEngines": [
- "google-nocodes", "yandex-uk", "meta-ua", "ddg", "wikipedia-uk", "metamarket"
- ]
- },
- "RU": {
- "visibleDefaultEngines": [
- "google-nocodes", "yandex-uk", "meta-ua", "ddg", "wikipedia-uk", "metamarket"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"ur": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo-in", "bing", "amazon-in", "ddg", "twitter", "wikipedia-ur"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"uz": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-uz"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"vi": {
"default": {
"visibleDefaultEngines": [
- "google", "ddg", "wikipedia-vi", "zing-mp3"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"wo": {
"default": {
"visibleDefaultEngines": [
- "google", "yahoo", "bing", "amazondotcom", "ddg", "wikipedia-wo"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"xh": {
"default": {
"visibleDefaultEngines": [
- "google", "bing", "ddg", "wikipedia"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"zh-CN": {
"default": {
"visibleDefaultEngines": [
- "baidu", "google", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
- ]
- },
- "CN": {
- "visibleDefaultEngines": [
- "baidu", "google-nocodes", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
- ]
- },
- "KZ": {
- "visibleDefaultEngines": [
- "baidu", "google-nocodes", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
- ]
- },
- "BY": {
- "visibleDefaultEngines": [
- "baidu", "google-nocodes", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
- ]
- },
- "RU": {
- "visibleDefaultEngines": [
- "baidu", "google-nocodes", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
- ]
- },
- "TR": {
- "visibleDefaultEngines": [
- "baidu", "google-nocodes", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
- ]
- },
- "UA": {
- "visibleDefaultEngines": [
- "baidu", "google-nocodes", "bing", "ddg", "wikipedia-zh-CN", "amazondotcn"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
},
"zh-TW": {
"default": {
"visibleDefaultEngines": [
- "yahoo-zh-TW", "google", "ddg", "findbook-zh-TW", "wikipedia-zh-TW", "yahoo-zh-TW-HK", "yahoo-bid-zh-TW", "yahoo-answer-zh-TW"
+ "ddg", "yahoo", "bing", "wikipedia"
]
}
}
diff --git a/browser/locales/searchplugins/allaannonser-sv-SE.xml b/browser/locales/searchplugins/allaannonser-sv-SE.xml
deleted file mode 100644
index ed933e60f..000000000
--- a/browser/locales/searchplugins/allaannonser-sv-SE.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Allaannonser</ShortName>
-<Description>Allaannonser</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMA/wD/AP83WBt9AAAACXBIWXMAAAsTAAALEwEAmpwYAAACPElEQVR42nVSS0iUYRQ995tfZ8YZlXF8gqUWUlJgkwUV0cKwRe3ctzDa9Ni1DqKNWtSih1QGtqkWgRa50VW1EMLUENNBMXXKsRpH/Wd0nv//nRZjmUJndeEeOOeee4QkdoCElWAsDHeJFPh3LI2tMR1DZJLD98Wcp8Mp5gKchTx5HW6/lB2ApyzHkpwCU6t4fR7LXyT2HeKAMgCANrQF5WDTFTndAZX3RyETx/AD+ToAZbCuBY1tqDoKpfBrAuM9MjuAsSe0UnLqBjxlIKmDb9jpZWeh/nCTiRX+i3RcjzzinVK2u/T8O5IKABMRWGnub5Vj1+D2bbsx3yuNbWy6DGqEh3M+Lf3iDG8VazPE/0Cn47xXw+4A03HF1KqY31gRkMJqBvv0xMttCX9+xum3ku/l3rNIrnBt3kBmHXYWvj0QQTKKbGKbpUQEIgDgrYKdkUzcgDIgCtl1ABK4iGxSR2ekwA/DxfiSHLqw+Ts7AxEqh4GCUriKEf5EKy3KQLBPR6cBQjlhp8RbqRpa4SlH6D2cRSjarcRwsa5FNpYQ7AXA6hPKXaJ+jKrFIWWlUNuMfC8WP8rPMVYcFk85SOrIFLv2satBRya1bZHUs4P2+HNqW2tbx8LsOc67lTo0RBK53PR0P2/7+LBejz7VG8s6saITUZ0y9VQvuwPscOuRx9QWyc0ugTYnX8lQO8wQimvp9kNEkqswF+D28chVaboER95W+TZTX5vDTD9mB2HOgRpFu1DTjPpzUn7wL+c37UxbeDY2F2wAAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://www.allaannonser.se/hitlist.php" resultdomain="allaannonser.se">
- <Param name="sourceid" value="Mozilla-search"/>
- <Param name="keyword" value="{searchTerms}"/>
- <Param name="order" value="date"/>
- <Param name="desc" value="1"/>
-</Url>
-<SearchForm>http://www.allaannonser.se</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/allegro-pl.xml b/browser/locales/searchplugins/allegro-pl.xml
deleted file mode 100644
index 06c063cc8..000000000
--- a/browser/locales/searchplugins/allegro-pl.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Allegro</ShortName>
-<Description>Wyszukiwanie w aukcjach Allegro</Description>
-<InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAFr/OgBa/zkAWv84AFr/OABa/zgAWv85AFr/PABa/wn///8A////AP///wD///8A////AABa/xYAWv+4AFr//wBa//8AWv//AFr//wBa//8AWv//AFr//wBa//8AWv+H////AP///wD///8A////AP///wAAWv/wAFr//wBa//8AWv//AFr//wBa//8AWv//AFr//wBa//8AWv//AFr/gv///wD///8A////AP///wAAWv9MAFr//wBa//8AWv//AFr/ewBa/zUAWv82AFr/NABa/2YAWv//AFr//wBa/4H///8A////AP///wD///8AAFr/gwBa//8AWv//AFr/if///wD///8A////AP///wAAWv8yAFr//wBa//8AWv+A////AP///wD///8A////AABa/4MAWv//AFr//wBa/8L///8A////AP///wD///8AAFr/MQBa//8AWv//AFr/gP///wD///8A////AP///wAAWv8oAFr//wBa//8AWv//AFr/xABa/34AWv9/AFr/fQBa/5sAWv//AFr//wBa/4D///8A////AP///wD///8A////AABa/5QAWv//AFr//wBa//8AWv//AFr//wBa//8AWv//AFr//wBa//8AWv+A////AP///wD///8A////AP///wD///8AAFr/NwBa/7UAWv//AFr//wBa//8AWv//AFr//wBa//8AWv//AFr/gf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AABa/2IAWv//AFr//wBa/4L///8A////AP///wD///8A////AP///wAAWv/RAFr/ywBa/0b///8A////AABa/woAWv/mAFr//wBa//8AWv85////AP///wD///8A////AP///wD///8AAFr//wBa//8AWv//AFr//wBa//8AWv//AFr//wBa//8AWv/v////AP///wD///8A////AP///wD///8A////AABa/5gAWv//AFr//wBa//8AWv//AFr//wBa//8AWv//AFr/J////wD///8A////AP///wD///8A////AP///wD///8AAFr/FgBa/14AWv+CAFr/gQBa/4IAWv9eAFr/BP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AADwAwAA4AMAAOPjAADD4wAAw+MAAOHDAADgAwAA+AMAAP/jAADzxwAA8AcAAPAPAAD+PwAA//8AAA==</Image>
- <SearchForm>http://allegro.pl</SearchForm>
- <Url method="GET"
- template="http://allegro.pl/listing/listing.php"
- type="text/html">
- <Param name="string" value="{searchTerms}" />
- <Param name="sourceid" value="Mozilla-search" />
- </Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazon-en-GB.xml b/browser/locales/searchplugins/amazon-en-GB.xml
deleted file mode 100644
index bb385d072..000000000
--- a/browser/locales/searchplugins/amazon-en-GB.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.co.uk</ShortName>
-<Description>Amazon.co.uk Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.co.uk/exec/obidos/external-search/" resultdomain="amazon.co.uk">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="ie" value="{inputEncoding}"/>
- <Param name="mode" value="blended"/>
- <Param name="tag" value="firefox-uk-21"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>https://www.amazon.co.uk/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazon-france.xml b/browser/locales/searchplugins/amazon-france.xml
deleted file mode 100644
index 98ec6caa7..000000000
--- a/browser/locales/searchplugins/amazon-france.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.fr</ShortName>
-<Description>Recherche Amazon.fr</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.fr/exec/obidos/external-search/" resultdomain="amazon.fr">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="ie" value="{inputEncoding}"/>
- <Param name="mode" value="blended"/>
- <Param name="tag" value="firefox-fr-21"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>https://www.amazon.fr/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazon-in.xml b/browser/locales/searchplugins/amazon-in.xml
deleted file mode 100644
index b4a656fb0..000000000
--- a/browser/locales/searchplugins/amazon-in.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.in</ShortName>
-<Description>Amazon.in Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.in/exec/obidos/external-search/" resultdomain="amazon.in">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="ie" value="{inputEncoding}"/>
- <Param name="mode" value="blended"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>https://www.amazon.in/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazon-it.xml b/browser/locales/searchplugins/amazon-it.xml
deleted file mode 100644
index c1b321b1d..000000000
--- a/browser/locales/searchplugins/amazon-it.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.it</ShortName>
-<Description>Ricerca Amazon.it</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.it/exec/obidos/external-search/" resultdomain="amazon.it">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="ie" value="{inputEncoding}"/>
- <Param name="mode" value="blended"/>
- <Param name="tag" value="firefoxit-21"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>https://www.amazon.it/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazon-jp.xml b/browser/locales/searchplugins/amazon-jp.xml
deleted file mode 100644
index 96620c30e..000000000
--- a/browser/locales/searchplugins/amazon-jp.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.co.jp</ShortName>
-<Description>Amazon.co.jp Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.co.jp/exec/obidos/external-search/" resultdomain="amazon.co.jp">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="mode" value="blended"/>
- <!--
- <Param name="mode" value="books-jp"/>
- <Param name="mode" value="books-us"/>
- -->
- <Param name="tag" value="mozillajapan-fx-22"/>
- <Param name="sourceid" value="Mozilla-search"/>
- <!--
- <Param name="sz" value="25"/>
- <Param name="rank" value="+salesrank"/>
- <Param name="rank" value="+pricerank"/>
- <Param name="rank" value="+inverse-pricerank"/>
- <Param name="rank" value="+daterank"/>
- <Param name="rank" value="+titlerank"/>
- <Param name="rank" value="-titlerank"/>
- -->
-</Url>
-<SearchForm>https://www.amazon.co.jp/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazondotcn.xml b/browser/locales/searchplugins/amazondotcn.xml
deleted file mode 100644
index 460d41ca0..000000000
--- a/browser/locales/searchplugins/amazondotcn.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>亚马逊</ShortName>
-<Description>亚马逊æœç´¢</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.cn/mn/searchApp" resultdomain="amazon.cn">
- <Param name="keywords" value="{searchTerms}"/>
- <Param name="ix" value="sunray"/>
- <Param name="pageletid" value="headsearch"/>
- <Param name="searchType" value=""/>
- <Param name="Go.x" value="0"/>
- <Param name="Go.y" value="0"/>
- <Param name="bestSaleNum" value="0"/>
-</Url>
-<SearchForm>https://www.amazon.cn/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazondotcom-de.xml b/browser/locales/searchplugins/amazondotcom-de.xml
deleted file mode 100644
index 3f8868d04..000000000
--- a/browser/locales/searchplugins/amazondotcom-de.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.de</ShortName>
-<Description>Amazon.de Suche</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="https://www.amazon.de/exec/obidos/external-search/" resultdomain="amazon.de">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="ie" value="{inputEncoding}"/>
- <Param name="mode" value="blended"/>
- <Param name="tag" value="firefox-de-21"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>https://www.amazon.de/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/amazondotcom.xml b/browser/locales/searchplugins/amazondotcom.xml
deleted file mode 100644
index 8a1d6f247..000000000
--- a/browser/locales/searchplugins/amazondotcom.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Amazon.com</ShortName>
-<Description>Amazon.com Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://completion.amazon.com/search/complete?q={searchTerms}&amp;search-alias=aps&amp;mkt=1"/>
-<Url type="text/html" method="GET" template="https://www.amazon.com/exec/obidos/external-search/" rel="searchform">
- <Param name="field-keywords" value="{searchTerms}"/>
- <Param name="ie" value="{inputEncoding}"/>
- <Param name="mode" value="blended"/>
- <Param name="tag" value="mozilla-20"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/atlas-sk.xml b/browser/locales/searchplugins/atlas-sk.xml
deleted file mode 100644
index c1df83e3e..000000000
--- a/browser/locales/searchplugins/atlas-sk.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Atlas</ShortName>
-<Description>Internetovy portal - Atlas.sk</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALESURBVHjaYvz//z8DMvj7nuHXY4YfLxiA4hziDJzyDIyCyPIAAcSCYP55w/Bi7deHW188e/H5B/tfRg5mVnZuAWEJVXteWR8GVjGIKoAAYoTa8P3mz0tVj27f+8rrIazmxSkgx8TM+v/fr6/vH768vZ+L7aOKZTI7vw5QIUAAAW3+///7ve8H3W+sCHh+59zf/+jgz5//j64fO7e16fPrG0AuQAAxAI35e7n4xVr3L68f/8cNnt27fOXQit+/vgMEEOP/z5d+HMn+r97Eqehw/9Wf5Ue+/vrDyMLCxMLIyMTMKMzDbKPBqi7FBHTMz+/f2Dg4AAKIheH9JUYuTTYZK6DQ07d/Zu36+O0HIzs7MzMTEysrMycH26Zzv0t9OW3Umdk5uYBqAAKI5e+394y8mkysbECOhjRLTzTX9x9/mZiY/v//t+/0g1MvJO+/5t989pe5CicrM8jPAAHExMDE85+ZCxJkInwsqrJ8Pxk43nxl+vybjY2V9d+fn3/+Mjx88+/nb2h0AQQQCxOPIsvvuxDOhpPfGtd8fvWJgY0V6KL/zMyKzBwM//7++/2PCR67AAHExCigwcDMzvDn8/ffDGtOfHvwhoH970c7yftxhi9Nuc/+/vjk9z/mv38Z4dELEEAsDJxijJL2DEws//8w/GdgYmX+//c/44GTDw7/+/Lr509maTEmBsa///4zwKwACCBg0mD8zyPz689v5v8/HDUZTt399+OPMLO8x39GBjZGRqDCn7///vqDSEEAAcQCTBk/vn9/9+79t29fjcV/ZZp9P3Pv7/effxkY/nNyccnJyvAL8EkJMLGxQF0FEEDA+GFgZWVhYWUFJoGvX75JsT4zFXzz7t2nX7//crNwG4rquTiYcnKywm0ACCBGePL+8/fvn99/fv768+Pn71+//gDjAehadnY2QX4eNjZmuAaAAAMA9HBNfsA2E5MAAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://www.atlas.sk/search.php" resultdomain="atlas.sk">
- <Param name="phrase" value="{searchTerms}"/>
- <Param name="sourceid" value="firefox"/>
-</Url>
-<SearchForm>http://www.atlas.sk/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/azerdict.xml b/browser/locales/searchplugins/azerdict.xml
deleted file mode 100644
index ca4a39bfd..000000000
--- a/browser/locales/searchplugins/azerdict.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Azerdict</ShortName>
-<Description>Azərbaycanın Online Lüğəti</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADYAQAA2AEAAAAAAAAAAAAAF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/GuLx8yHU4+Ih1OPiIdTj4iHU4+Ih1OPiIdTj4hjm9vgX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/H9rp6FdYWPFXV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9WWVnnGuLx9Bfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xzg7+xVWVnmV1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/VVtb4Bnk9fUX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/Guj4+hzf7+8c3+/vHN/v7xzf7+8c3+/vHN/v7xjp+v0X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+n6/T+Mk79KdnnCSnZ5wkp2ecJKdnnCSnZ5wkp2ecI5m6TCF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/yPP3dpXV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/x3d7O0X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/N52lwUSBhsBEgYbARIGGwESBhsBEgYbARIGGwDejqsQX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+n6/iHS4d4c4fDsF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/HN/u7y21wMtBiI6/UGZny1dYWO5XV1f/VlhY6Bno+PcX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8Y6Pn9UmJj0VdXV/5XV1f/V1dX/1dXV/9XV1f/V1dX/lJmZ8sX6fr9F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/G9/v8lZWV/VXV1f/V1hY8FFnaMxCh47ALrfBzBzf7vAX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8f2ejpI8/d4Bfp+v4X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAACwAwAAsAMAAAAAAAAAAAAAF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/GOj5/CXI19csucXNLLnFzSy5xc0sucXNLLnFzSy5xc0sucXNLLnFzSy5xc0sucXNLLnFzSy5xc0lzNnbF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xjm9vZSYWLQV1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9ObnDIF+n6/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/NaStwVdXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/8nwc7XF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8zqLHCV1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/iPO3N8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xjo+ftNb3HEV1dX/ldXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/U/jZTBF+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8a4/L0HN/v7xzf7+8c3+/vHN/v7xzf7+8c3+/vHN/v7xzf7+8c3+/vHN/v7xzf7+8c3+/vGOf3+hfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8Y6fr8I8/f3CXH1NYlx9TWJcfU1iXH1NYlx9TWJcfU1iXH1NYlx9TWJcfU1iXH1NYlx9TWJcfU1iLS4d8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/GOf391FhZM1XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/0pydcQX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/80p7HAV1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/yfG09oX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/zOoscJXV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f+I87d4Bfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/GOj5+01wc8NXV1f9V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX+0CJj8IX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xrj8vQc3+/vHN/v7xzf7+8c4O/uIdTj4iHU4+Ih1OPiIdTj4iHU4+Ih1OPiIdTj4iHU4+IZ5vb4F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/GOf4+iXI1dU4oam+Mq21wBjn+fkX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/x7Y5+UxrbfFRoCEvlNhY89XV1f0V1dX/1dXV/9XV1f/UWdpwxfq+/4X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xrk9fUpvsvRPZGXwE5qbcdWWVnnV1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/Htrq3Rfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/y+0wM1UX2DVV1dX+1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1ZYWOgZ6Pj2F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8f2efpV1dX+VdXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/tTYWLSKMLO0hfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/yy4w89XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9WWVnoT2ttyT6TmcEqwMzTGeT09xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/GuLz9VVaWt9XV1f/V1dX/1dXV/9XV1f3U2Fi0kZ+g8IzrbXJINjm6Rfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/HN/v7zuZocE6mqLCJ8XS2Bnn+PsX6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/xfq+/8X6vv/F+r7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://api.azerdict.com/english/autocomplete">
- <Param name="action" value="opensearch" />
- <Param name="query" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="http://azerdict.com/english/" resultdomain="azerdict.com">
- <Param name="word" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://azerdict.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/azet-sk.xml b/browser/locales/searchplugins/azet-sk.xml
deleted file mode 100644
index cfd702196..000000000
--- a/browser/locales/searchplugins/azet-sk.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Azet</ShortName>
-<Description>Azet - portal, kde je vzdy najviac ludi</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANinbf/GdRz/xnUc/8qDNv/Yp23/68+u/9inbf/Yp23/2Kdt/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqDNv/GdRz/xnUc/8Z1HP/Kgzb/xnUc/8Z1HP/GdRz/xnUc/8qDNv8AAAAAAAAAAAAAAAAAAAAAAAAAAOvPrv/GdRz/xnUc/8qDNv8AAAAAAAAAAAAAAADYp23/xnUc/8Z1HP/Kgzb/AAAAAAAAAAAAAAAAAAAAAAAAAADrz67/xnUc/8Z1HP/Yp23/AAAAAAAAAAAAAAAA68+u/8Z1HP/GdRz/yoM2/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMqDNv/GdRz/xnUc/9inbf/rz67/68+u/+vPrv/GdRz/xnUc/8qDNv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2Kdt/8qDNv/GdRz/xnUc/8Z1HP/GdRz/xnUc/8Z1HP/Kgzb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADrz67/2Kdt/8Z1HP/GdRz/yoM2//qu2f/uR5n/7keZ/+5Hmf/uR5n/AAAAAMqDNv/Kgzb/yoM2/wAAAAAAAAAAAAAAAOvPrv/GdRz/xnUc/8qDNv/uR5n/7keZ/+5Hmf/uR5n/7keZ/wAAAADYp23/xnUc/8Z1HP/Kgzb/68+u/+vPrv/Kgzb/xnUc/8Z1HP/Yp23/7keZ/+5Hmf/uR5n/7keZ//qu2f8AAAAAAAAAANinbf/GdRz/xnUc/8Z1HP/GdRz/xnUc/8Z1HP/Yp23/AAAAAAAAAAD6rtn/AAAAAOvPrv/Kgzb/vXsA/9inbf8AAAAAAAAAAOvPrv/rz67/68+u/+vPrv8AAAAAAAAAAAAAAAAAAAAAAAAAAOvPrv/Bfwz/vXsA/717AP/Yp23/AAAAAFnCg/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKgzb/vXsA/717AP/Kgzb/AAAAAFnCg/9ZwoP/WcKD/wAAAAATof//E6H//wAAAAAAAAAAAAAAAAAAAAAAAAAA68+u/8F/DP/Bfwz/68+u/wAAAABZwoP/WcKD/1nCg/8AAAAAE6H//xOh//8Tof//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZwoP/WcKD/1nCg/9ZwoP/AAAAABOh//8Tof//E6H//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFnCg/9ZwoP/AAAAAAAAAAATof//E6H//xOh//8AAAAAAAAAAP4AAAD8AAAA+HAAAPhwAAD8AAAA/gAAAP/gAAAEcAAABAAAAAYBAAChhwAAwX8AAMInAADCIwAA/CMAAP5jAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAABgIAAAv///wDMZgAFtGQUM7VnEkW1ZxJFs2YSRrNnE0OzZxYvs2YaCv///wD///8Av2AgCLhmFBm1ahUYtWoVGK1mFBmuaBcW1YAABv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8As2YSRrVnE7m0ZxTyvm0V/75tFf+/bRX/u2sU/7NnE+6zZxO9s2YTa79AAAS0ZxNqs2cU2LNnFMy0ZxTLs2cT17RnE665XRcL////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD/gAAC////ALNoFFuzZxT2wG0V/7VnFP+zZxP9tGcT+7NmE/m0ZxP7tGcU/7trFP+3aRT/s2cTubNnFNC+bRX/uWoU/7lqFP/CbxX/s2YTr////wD/AAAB////AP///wD///8A////AP///wD///8A////AP///wD///8AqlUAA////wC0aBEstGYT7bpqFP+0ZxP6tGYT/rNmFP+4aRT/wm8V/71sFf+9bBX/vmwV/7dpFP+5ahT/tGcU/7RnE/y0ZxP8s2cT/bZoFP+zZxN5////AICAAAL///8A////AP///wD///8A////AP///wD///8A////AP///wCAgAAC////ALRnE3fBbhX/tGcT+rRnFP+0ZhP+t2kU/7RnFMu0ZxNqs2cSVLVoElO1ZhR/s2YT4bdpFP+0ZhP+tGcU/7NmFP+zZxT/uGkU/7NoE3b///8A/4AAAv///wD///8A////AP///wD///8A////AP///wD///8A/wAAAf///wCqVQADs2YTorxrFP+zZxP9s2cT/bpqFP+zZhTbuGoVJP///wD///8A////AP///wCyZRIrs2cU2LlqFP+zZxP9s2YU/7NnFP+4aRT/tGcTd////wCqVQAD////AP///wD///8A////AP///wD///8A////AP///wD//wAB////ALZtJAezZhOvu2sU/7NnE/20ZxP7wG4V/7NnFLP///8AqnEcCapVAAaZZgAFqlUAA////wCzZhNstmgU/7RnFP+0ZhP+s2cU/7hpFP+0ZxN3////AP//AAH///8A////AP///wD///8A////AP///wD///8A////AP8AAAH///8A////ALNnFJe+bRX/s2YT/LRnE/y7axT/s2cT07tmEQ////8A////AICAAALVgAAG////ALNmEyizZxTzt2kU/7NnE/2zZxT/uGkU/7RnE3f///8A//8AAf///wD///8A////AP///wD///8A////AP///wD///8A////AKpVAAP///8AtGcUZr5sFf+0ZxP7tGYT/rRmE/64aRT/tGcTq7RkFDOxYhQN////AP///wD///8As2YaCrRmE++4aRT/s2cT/bNnFP+4aRT/tGcTd////wD//wAB////AP///wD///8A////AP///wD///8A////AP///wD///8AgIAAAv///wCuaw0TtGcUzMFuFf+zZxT/tGcT+7RmE/y7axT/s2cU9rNnE720ZxScs2YTh7NlFFuzZxI5s2cT7rhpFP+zZxP9s2cU/7hpFP+0ZxN3////AP//AAH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AgIAAAv///wC3aRYutGcUv7VnFP++bRX/u2sU/7VoFP+1ZxT/uWoU/79tFf+/bRX/s2cT/bRnFOezZhP8tGcU/7RmE/6zZxT/uGkU/7RnE3f///8A//8AAf///wD///8A////AAAAAAH/AP8BgACAAoAAgAKAAIACgACAAv8AAAH///8AgIAAAv///wCqgAAGsmgTYLRnE66zZhTRs2cU67RnFP/AbhX/vWwV/7prFP+6ahT/uGkU/7RnFP+zZxT/s2YU/7NnFP+4aRT/tGcTd////wD//wAB////AP///wCAAIACAAAAAf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ALhjDhKzZhQys2cVSrRlFFi1ZhR1tGcUmbNmFNG3aBT/tGcU/7NnFP+zZhT/s2cU/7hpFP+0ZxN3////AP//AAH///8AgACAAv///wD///8AiTtiDYgzZg+SN20OkjdtDogzZg+LLnQL////AJlmAAW7ZhEPu2YRD7RpDxGvYBAQtm0kB////wD///8A////AP///wD/AAABtm0SDrJnFH6zZhT/tGcU/7RmE/6zZxT/uGkU/7JnE3f///8A//8AAYAAgAL///8AizdpLo01bZSMNWu6jTZrvow2bL2MNWu8jDVrxo02a40AAP8Cs2cAJbRnFLC1ZhTAtGcTvLRnE7yzZhPKsmUVSf///wC5dBcLv4AABKpVAAP///8Av2oVDLRmE/C4aRT/s2cT/bNnFP+4aRT/tGcTd////wD//wAB////AI84aimMNWvYmTp1/5I4cP+SOHD/kjhw/5E3b/+XOnT/jDZr1XYAiQ3JeQATtGYW38JvFf+5ahT/uWoU/8ZxFv+0ZxOu////AP///wD///8A////AP///wCzZhJGtGcT+rZoFP+zZxP9s2cU/7dpFP+zZhN2////AP//AAH///8AjDVsh5g6dP+MNWz5jTZr/Iw1bP2MNWz9jDZs+402a/yNNWz4jTlqOv///wCzZheevWwV/7RnFPizZhP8s2YT/LdoFP+zZhOdsmUTNbFpFi63aRYutGYUS7NnE9O4aRT/tGYT/rRmE/6zZxT/tmgU/7RoEkf///8AgIAAAv///wCMNWyVlzp0/4w1a/qNNmz/jDZs/402a/yMNmz/kjdw/5M4cP+NOGpg////ALBmHC2zZxTivWwV/7NmE/y0ZhP8tGcU/7trFP+0ZhP+s2cU67RnE/C4aRT/uWkU/7RmE/6zZxP9tGcT+r1sFf+0ZxPSuGMOEv///wCAgAAC////AIs2a3WXOXT/jDVs/Yw2bPuMNmv8kjhw/5A3bv+NNmvKhy50QoAAgAaqcRwJ////ALZoE0K0ZhPgvWwV/7prFP+0ZhP+tGYT+rNnE/20ZxT/tGcU/7RnE/u0ZxP6tGYT/rhpFP+/bRX/tGcT5LZoFjv///8AgIAAAv///wD///8AkjFtFY02a7WVOXL/lTlz/5U5cv+MNmvcijNtaf///wDmmQAKtGgKhLRnFLexYxUk////ALFpFCeyaBaVsmgV2LZoFP/BbhX/vm0V/75sFP++bBT/vm0U/8FuFf+5ahT/s2cT4rRnFKa0ZBQz////AP8AAAH///8A////AP8A/wH///8AkjdtDow0a12NNWuGjDdsZnAAjxD///8AtGgNYrNnFt28axX/v20V/7VmFNG2ZhJG////AP///wDZQAAUsmUVSbJqGGq0ZhWEs2cihrJoJoexaCeJsWcrcrJnGk+0ZBMp////AP///wCAgAAC////AP///wD///8A////AIAAgAL///8A////AP///wD///8AumwANLNnF8e3aRX/u2sU/7NmE/y0ZhP6wG4V/7NnFcb/AAABQrVaHwDJaxP///8A////AP///wD///8A////AP///wD///8A////AP///wD/AAABgIAAAv///wD///8A////AP///wD///8A////AIAAgAKZM2YF////ALFmG0GzZhXyvWwU/7RnFP+zZhP8tGYU/rRnFP+zaBX/uV0ATQDXeRM6tF3bObRc1T20XZ9As1tXAAD/ASSC8z8khPBVJYLyYCyD7mlxcaoJ////AAAA/wH///8A////AP///wD///8A////AP///wD///8AAAAAAf///wD///8As2YUor1sFf+zZxP7tGYT/rRnFP+zZhP8vW0V/7NnFKT///8ANbZeiz2/Y/85uF//Psho/zm2WsAkbf8HJILzviWJ/f8lhvj/JYv//ySE81X///8AAKr/A////wD///8A////AP///wD///8A////AP///wD/AAAB////AP///wC0ZxS3uGkU/7NmE/yzZxT/s2YT/LdpFP+zZxXyyEUAJQDFZTA7tFz7ObZe/zi1Xfo6umH/ObVaryuA/wYjg/O/JYv//yOE8/gkh/r/I4Py0iCA7xD///8AAID/Av///wD///8A////AP///wD///8A////AP///wD///8A////ALRnE4jBbhX/tGcU/7NnE/21ZxT/v20V/7RmEYT///8AO7Rduzu+Yv84tV38OLRd/Tq8Yv84tVqyK4D/BiOC874liv//JIPz+yOD8/0liv//JIPzgP///wAA//8B////AP///wD///8A////AP///wD///8A////AICAAAL///8As2YRHrRmE8W2aBT/uGkU/7ZoFP+zaBa4/wAAAiu3YFg6tl7/OLZe/zi1Xf44tF39Orxi/zi2WbErgP8GI4LzviWL//8jg/P8I4Py/iSF9/8kg/LtJIbzKv///wAAgP8C////AP///wD///8A////AP///wD///8A////AP8AAAH///8AsWIUDbVnEmG1ZxODtGcTXJ+AIAj///8AObNdsjzBZP84tV37OLVd/zi0Xf06vGL/ObVZtCRt/wcjgvO+JYr//yOD8/wjg/P/I4Pz/SWJ/v8jhPN8////AAAA/wH///8A////AP///wD///8A////AP///wD///8A////AP8AAAH///8A////AP///wD///8A////AP///wA5tV2wPMBj/zi1Xfo4tV3/OLRd/Dq8Yv84tVqfAED/BCOD88Iliv//JIPz+yOD8/8jg/P9JIf6/ySD8o7///8A////AAAA/wH///8A////AP///wD///8A////AP///wD///8A////AP8AAAGqVQADqlUAA/+AAAKAv0AE////ADm1Xm87v2P/Obhf/zi1Xfs5uV//O71i/za1ZFn///8AJIXxlCaO//8jg/P8I4Pz/COD8v8liv//IoPyYf///wAAgIAC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAH///8AM7NmCjm2XY84tV33PMBj/zi1XvA5tFyCJLaSB////wAkie0cI4PzvSWL//8lif7/JYj8/yOD9KEagOYK////AAD//wH///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAD/AAH///8A////ADm2XjE5tVxIObVbLf///wD///8AAKqqA////wAiiO4PIoL0WiSE9Hgig/FKK4D/Bv///wAA//8B////AP///wD///8A////AP/kAwH/+AAB/9AAAv+gAAL/oAAC/0A8Av9AQgL/YDIC/6AOAv+gAAL/0AAC4CgAAs//AAKwIHgCQAAiAoAAPgKAEAACgBAAAoAIAAWAhAALQQMAN7wAf8/IAABf2AQAX9gAAC/4CAAv6AAAF/QQABf78AAb/BAQF//QEBf/7Ggv</Image>
-<Url type="text/html" method="GET" template="http://www.azet.sk/katalog/vyhladavanie/firmy/" resultdomain="azet.sk">
- <Param name="q" value="{searchTerms}"/>
- <Param name="k" value=""/>
-</Url>
-<SearchForm>http://www.azet.sk/katalog/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/baidu.xml b/browser/locales/searchplugins/baidu.xml
deleted file mode 100644
index 8b823e37a..000000000
--- a/browser/locales/searchplugins/baidu.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>百度</ShortName>
-<Description>百度网页æœç´¢</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64, AAABAAIAEBAAAAEACABoBQAAJgAAACAgAAABACAAqBAAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAABAAAAAAAAAAAAAP///wDhMikA9b67AOI3LgDzr6wA8ZyYAO2EfwD//fwA6WxlAOZUTAD3yMUA9bu5AP3u7QDrdm8A6GVeAPfFwwD4z80A6WdgAPrg3gDsfXcA+dTSAP3x8ADsenUA8qaiAPzp6ADujokA+t3cAORFPQDyqKQA4jkxAPnW1ADnWVEA51tUAPvk4wD++PcA7H96APS3swD74uEA4z42AOVPRwDpaWMA9sC+APzs6wDnXVYA6GJbAP3z8gDxoZ0A8qOfAO6LhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIGBQAFBQUABQUFAAUFBQAFBQUABQUFAAUFBQAFBQYAFwUFAAUFBQAFBQUABQUFAAUFBQAFBQUABQUFAAUFBQAFBQIAAQEBAAEBAQABAQEAAQEBAAEBAQABAQEAAQIFAAUFAQABAQEAJTVLAAICAgICAgICAgICAgICAgICAQEBAQEBAQEBAQEBAQECAgEBLgkCKDEaIAIPLgEBAgIBARgCAgICAgICAi8BAQICAQEvAgICAgICAgIwAQECAgEBFigCAgICAgItLgEBAgIBAQErKAICAgIsIwEBAQICAQglHyYnAgIoDSkEKgECAgEYAh4WHyAhIiMCAiQBAgIBGgICGwEBAQEBHAIdAQICARECEhMUFRYXGBkLAQECAgEBDQEOAg8FAgIQAQEBAgIBAQEBCQIKCwICDAEBAQICAQEBAQMEBQEGBwgBAQECAgEBAQEBAQEBAQEBAQEBAgICAgICAgICAgICAgICAgIAAABpAAAAaQAAAGkAAABpAAAAaQAAAGkAAABpAAAAaQAAAGkAAABpAAAAaQAAAGkAAABpAAAAaQAAAGkAAABpKAAAACAAAABAAAAAAQAgAAAAAACAEAAAAAAAAAAAAAAAAAAAAAAAAOEyKUjhMinn4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKefhMilI4TIp5OEyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKeThMin/4TIp//fFw/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////fFw//hMin/4TIp/+EyKf/hMin////////////////////////////97u3/8Z+a/+lpY//nW1T/6nFq/+6JhP/zran/98rI//rg3v/629n/+MzK//CXk//oZV7/5U9H/+EyKf/iNy7/6m5o//nU0v///////////////////////////+EyKf/hMin/4TIp/+EyKf//////////////////////++Lh/+RFPf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TQs//jPzf//////////////////////4TIp/+EyKf/hMin/4TIp///////////////////////pbGX/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/51lR///////////////////////hMin/4TIp/+EyKf/hMin/////////////////++fm/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/++fm/////////////////+EyKf/hMin/4TIp/+EyKf/////////////////2wL7/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/3yMX/////////////////4TIp/+EyKf/hMin/4TIp//////////////////W+u//hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp//jPzf/////////////////hMin/4TIp/+EyKf/hMin/////////////////++fm/+E0LP/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/jQzv//vj3/////////////////+EyKf/hMin/4TIp/+EyKf//////////////////////7YJ8/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp//Otqf//////////////////////4TIp/+EyKf/hMin/4TIp///////////////////////+9fX/5lRM/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/xn5r////////////////////////////hMin/4TIp/+EyKf/hMin////////////////////////////97u3/6GVe/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hNCz/9LKu/////////////////////////////////+EyKf/hMin/4TIp/+EyKf/////////////////////////////////++vr/63hy/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TQs//W5tv/51tT/8qOf//CXk//51NL/////////////////4TIp/+EyKf/hMin/4TIp/////////////////////////////////////////fz/63Zv/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/0sq7/9Lez/+E0LP/hMin/4TIp/+EyKf/1ubb////////////hMin/4TIp/+EyKf/hMin/////////////////9bm2/+lpY//oYlv/86+s///////++Pf/5lZP/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/7ouG///////lT0f/4TIp/+EyKf/hMin/4TIp/+ZRSv///////////+EyKf/hMin/4TIp/+EyKf////////////W+u//hMin/4TIp/+EyKf/hMin/8qai///////74uH/4z42/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+hiW//++vr//////+I5Mf/hMin/4TIp/+EyKf/hMin/4TIp////////////4TIp/+EyKf/hMin/4TIp////////////511W/+EyKf/hMin/4TIp/+EyKf/lSkL////////////2w8D/4jcu/+EyKf/hMin/4TIp/+EyKf/kSED//Ozr////////////4jcu/+EyKf/hMin/4TIp/+EyKf/hMin//vX1///////hMin/4TIp/+EyKf/hMin////////////iNy7/4TIp/+EyKf/hMin/4TIp/+EyKf/++Pf////////////4z83/6GBZ/+EyKf/jQzv/7H96//zs6//////////////////lTUX/4TIp/+EyKf/hMin/4TIp/+RIQP///////////+EyKf/hMin/4TIp/+EyKf///////////+I8M//hMin/4TIp/+EyKf/hMin/4TIp//749////////////////////////////////////////////////////////////+6Lhv/hMin/4TIp/+EyKf/hMin/8aGd////////////4TIp/+EyKf/hMin/4TIp////////////6m5o/+EyKf/hMin/4TIp/+EyKf/mVk///////////////////////////////////////////////fz/9sPA//fKyP///fz//vj3/+t2b//iPDP/5EhA/++VkP/////////////////hMin/4TIp/+EyKf/hMin////////////3ysj/4TIp/+EyKf/hMin/4TIp//bDwP//////8Z+a/+I8M//jQzv/9bu5/////////////fHw/+ZUTP/hMin/4TIp/+ZWT//86ej//////////////////////////////////////+EyKf/hMin/4TIp/+EyKf/////////////////yqKT/5EU9/+dZUf/1vrv///////bDwP/hMin/4TIp/+EyKf/hNCz/++Tj///////xnJj/4TIp/+EyKf/hMin/4TIp/+puaP//////////////////////////////////////4TIp/+EyKf/hMin/4TIp////////////////////////////////////////////6nFq/+EyKf/hMin/4TIp/+EyKf/vlZD//////+t2b//hMin/4TIp/+EyKf/hMin/4TIp//rb2f/////////////////////////////////hMin/4TIp/+EyKf/hMin////////////////////////////////////////////lTUX/4TIp/+EyKf/hMin/4TIp/+pxav//////6nFq/+EyKf/hMin/4TIp/+EyKf/hMin/862p/////////////////////////////////+EyKf/hMin/4TIp/+EyKf///////////////////////////////////////////+RIQP/hMin/4TIp/+EyKf/hMin/6m5o///////ypqL/4TIp/+EyKf/hMin/4TIp/+EyKf/1ubb/////////////////////////////////4TIp/+EyKf/hMin/4TIp////////////////////////////////////////////6nFq/+EyKf/hMin/4TIp/+EyKf/vlZD///////719f/lSkL/4TIp/+EyKf/hMin/5EhA//719f/////////////////////////////////hMin/4TIp/+EyKf/hMin////////////////////////////////////////////3ysj/4TIp/+EyKf/hMin/4jcu//zp6P////////////nY1//kRT3/4TIp/+I8M//4z83//////////////////////////////////////+EyKf/hMin/4TIp/+EyKf/////////////////////////////////////////////////zq6f/5EU9/+VNRf/3yMX///////////////////////3z8v/1u7n//fHw////////////////////////////////////////////4TIp/+EyKf/hMin/4TIp//fKyP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////fKyP/hMin/4TIp/+EyKefhMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMinn4TIpP+EyKcnhMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIp/+EyKf/hMin/4TIpyeEyKT8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://www.baidu.com/su">
- <Param name="wd" value="{searchTerms}"/>
- <Param name="tn" value="monline_dg"/>
- <Param name="ie" value="utf-8"/>
- <Param name="action" value="opensearch"/>
-</Url>
-<Url type="text/html" method="GET" template="https://www.baidu.com/baidu" resultdomain="baidu.com">
- <Param name="wd" value="{searchTerms}"/>
- <Param name="tn" value="monline_dg"/>
- <Param name="ie" value="utf-8"/>
-</Url>
-<SearchForm>https://www.baidu.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/bbc-alba.xml b/browser/locales/searchplugins/bbc-alba.xml
deleted file mode 100644
index a755623a8..000000000
--- a/browser/locales/searchplugins/bbc-alba.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>BBC â” BBC Alba</ShortName>
-<Description>Lorg BBC â” BBC Alba</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBACAAEAAQCwAAAAJgAAACAgEAABAAQA6AIAANYAAAAoAAAAEAAAACAAAAABAAEAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjDAAAUpAAAGMQAABSkAAAYwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2F%2F8AAP%2F%2FAAD%2F%2FwAA%2F%2F8AAP%2F%2FAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAA%2F%2F8AAP%2F%2FAAD%2F%2FwAA%2F%2F8AACgAAAAgAAAAQAAAAAEABAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD%2F%2FwD%2FAAAA%2FwD%2FAP%2F%2FAAD%2F%2F%2F8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2F%2FgAAAD%2F%2BAAAAHj%2FgAAAAPAHgAAA8AeAAAeHAHAAAADwB4AAAPAHgAAIcAAAAAAA%2BIgAAAD4iAAAD3AAAAAAAPAPAAAA8A8AAAiAAAAAAAD3iAAAAPeIAAAAiHeAAAAAiHAAAACIcAAAAAeIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FAEAQBwBAEAcAQBAHAEAQBwBAEAcAQBAHAEAQBwBAEAcAQBAH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2Fw%3D%3D</Image>
-<Url type="application/x-suggestions+json" template="http://search.bbc.co.uk/suggest">
- <Param name="format" value="opensearch"/>
- <Param name="q" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" template="http://search.bbc.co.uk/search" resultdomain="bbc.co.uk">
- <Param name="opensearch" value="all-1"/>
- <Param name="q" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.bbc.co.uk/alba/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/bing.xml b/browser/locales/searchplugins/bing.xml
index 3f7d9d918..d0f2f6e9f 100644
--- a/browser/locales/searchplugins/bing.xml
+++ b/browser/locales/searchplugins/bing.xml
@@ -14,11 +14,5 @@
</Url>
<Url type="text/html" method="GET" template="https://www.bing.com/search" rel="searchform">
<Param name="q" value="{searchTerms}"/>
- <Param name="pc" value="MOZI"/>
- <MozParam name="form" condition="purpose" purpose="contextmenu" value="MOZCON"/>
- <MozParam name="form" condition="purpose" purpose="searchbar" value="MOZSBR"/>
- <MozParam name="form" condition="purpose" purpose="homepage" value="MOZSPG"/>
- <MozParam name="form" condition="purpose" purpose="keyword" value="MOZLBR"/>
- <MozParam name="form" condition="purpose" purpose="newtab" value="MOZTSB"/>
</Url>
</SearchPlugin>
diff --git a/browser/locales/searchplugins/bok-NO.xml b/browser/locales/searchplugins/bok-NO.xml
deleted file mode 100644
index 6c5093fff..000000000
--- a/browser/locales/searchplugins/bok-NO.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Ordbok</ShortName>
-<Description>Norske ordbøker.</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB2UlEQVQ4ja3TzWuSAQDH8edvyqioiIg61FBIRqNDjBi1YIeYk8VeFJJWTy+jIJq5ww5L7ZArNsuY0xE2e2G6YTC1NnGlOdPHR30eH19W8O2wQ8dq7vC7fk7fn1BVNVStuatVVQ2hpjXRGtu7Wk1rIqhtAOqeARW1yeqXEs/efOPhTBLRFcMVSKFqLbTGNtXFp8hTJipOE6rvFtqnOTRF/gMsxQrYX6xz40kc06Mo3TdDnBkKMBNMUlp6iXRVhzRymLJ4AmWig7qzk9Y7cQeQKnXmQlkmZzcQ3QkGHav03A6jHwlwRfSTHuum1L8PyXqUyt2TqA49Dfc5fvouohVTCKlsFe/b70y/TiO645jtK/SOv+esdZEui4/ENQPygI7S9WOU7+wATc95fvl7aKT8CNGExMTzJL3jYYyWAPrheYyWBQyjQYxDr0gMnEY26SiYD/Kj/wAF8yFk23Hq0520ovcRVpJFDMPznDL76LIFmfQm+LCWZyGS5Z4rwuaUDSU8i7L2kbLXQcHaQb5PR75vP2rEg5ArqlwYCzFoXyadq/49nkIe+fFlpNEjKJtxhK9bCg88n8kUav/egFxEcV5C3VhG2JJqrGeU/46onolRyyX2oMS2z9TunX8DKb6IjiC3ONQAAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://www.nob-ordbok.uio.no/perl/ordbok.cgi" resultdomain="uio.no">
- <Param name="OPP" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>http://www.nob-ordbok.uio.no/</SearchForm>
-</SearchPlugin>
-
diff --git a/browser/locales/searchplugins/bolcom-fy-NL.xml b/browser/locales/searchplugins/bolcom-fy-NL.xml
deleted file mode 100644
index e730fcff5..000000000
--- a/browser/locales/searchplugins/bolcom-fy-NL.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>bol.com</ShortName>
-<Description>Sykje by bol.com</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAABMLAAATCwAAAAEAAAAAAAAAAAAA////ANJtQADot6AA3JJvAPXc0ADkpYYA7sq5ANiAVgD77egAzmMxAO3CqwDmr5IA4Jp8ANR4SgDcimMA+eTeAPHSwwD99/UA0Gk5APPWygD34NYA1nxQAOKggADos5gA7MaxAOCYdQD98+8A6r2oANRzRgDcjGkA2oheAP37+QDOZzUA5rWcAPvx6gD56OAA0nFCANZ4TgD12swA7si1AOq7pADkp4oA89TGAOCefQDiooQA0G09ANZ+VADYimAA3pZzAOrBrADtvacA//39AP359wDOZTMA/fXxANBnNwD78+wA0Gs7ANR1SAD34tgA9d7SANiCWAD12MoA3IxlANyOZwDuxrMA3ph3AOq/qgDquaIA6LWeAOazmgDvyLcA78q1AO/IswDswa0A4Jx7AOKkhgDOZTEA0Gc1APvv6ADQazkA+ejeANJxRADUdkoA1HhMANZ6TgDWflAA89jKANZ8UgDWflIA89bIANyMYwDuxrUA6LWcAOKgggDms5gA4qKCAOaxkgDkp4gA5q2SAOzBqwDrwKoA1HZIANR3SgDgnn4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQESP0IoPSABAQEBAQEBATljLgoKCk47AyABAQEBARBVCkxFAz42CgpcNwEBASMOCkwtJh5EMAoKCkEgAQFpCgpfTAoKCgoKCgoKCwFQOAoKOiclCgoKCgoKClk0SQoKCgoPBVMKCgoKCgo2JF4KNl5dZBoMAmUHKk8KCltHCkYfIUMFViIdNgZINgorSQoDPmAKOhkxEwoKMhY2UglPWlsYYh0cFzwvIV5oVjQBDQpNZhcpBAoISlgsCjMBAVBnCmEUVwoKCgoKCkAgAQEBFVQKVgoKCgoKCh8jAQEBAQEjX1EKCgoKJV41AQEBAQEBAQEbEURLJzUBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Image>
-<SearchForm>http://www.bol.com/</SearchForm>
-<Url type="text/html" method="GET" template="http://www.bol.com/nl/s/algemeen/zoekresultaten/Ntt/{searchTerms}/Ntk/media_all/Nty/1/suggestedFor/{searchTerms}/N/0/Ne/0/search/true/searchType/qck/index.html" resultdomain="bol.com">
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/bolcom-nl.xml b/browser/locales/searchplugins/bolcom-nl.xml
deleted file mode 100644
index f3c4e9d81..000000000
--- a/browser/locales/searchplugins/bolcom-nl.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>bol.com</ShortName>
-<Description>Zoeken bij bol.com</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAABMLAAATCwAAAAEAAAAAAAAAAAAA////ANJtQADot6AA3JJvAPXc0ADkpYYA7sq5ANiAVgD77egAzmMxAO3CqwDmr5IA4Jp8ANR4SgDcimMA+eTeAPHSwwD99/UA0Gk5APPWygD34NYA1nxQAOKggADos5gA7MaxAOCYdQD98+8A6r2oANRzRgDcjGkA2oheAP37+QDOZzUA5rWcAPvx6gD56OAA0nFCANZ4TgD12swA7si1AOq7pADkp4oA89TGAOCefQDiooQA0G09ANZ+VADYimAA3pZzAOrBrADtvacA//39AP359wDOZTMA/fXxANBnNwD78+wA0Gs7ANR1SAD34tgA9d7SANiCWAD12MoA3IxlANyOZwDuxrMA3ph3AOq/qgDquaIA6LWeAOazmgDvyLcA78q1AO/IswDswa0A4Jx7AOKkhgDOZTEA0Gc1APvv6ADQazkA+ejeANJxRADUdkoA1HhMANZ6TgDWflAA89jKANZ8UgDWflIA89bIANyMYwDuxrUA6LWcAOKgggDms5gA4qKCAOaxkgDkp4gA5q2SAOzBqwDrwKoA1HZIANR3SgDgnn4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQESP0IoPSABAQEBAQEBATljLgoKCk47AyABAQEBARBVCkxFAz42CgpcNwEBASMOCkwtJh5EMAoKCkEgAQFpCgpfTAoKCgoKCgoKCwFQOAoKOiclCgoKCgoKClk0SQoKCgoPBVMKCgoKCgo2JF4KNl5dZBoMAmUHKk8KCltHCkYfIUMFViIdNgZINgorSQoDPmAKOhkxEwoKMhY2UglPWlsYYh0cFzwvIV5oVjQBDQpNZhcpBAoISlgsCjMBAVBnCmEUVwoKCgoKCkAgAQEBFVQKVgoKCgoKCh8jAQEBAQEjX1EKCgoKJV41AQEBAQEBAQEbEURLJzUBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Image>
-<SearchForm>http://www.bol.com/</SearchForm>
-<Url type="text/html" method="GET" template="http://www.bol.com/nl/s/algemeen/zoekresultaten/Ntt/{searchTerms}/Ntk/media_all/Nty/1/suggestedFor/{searchTerms}/N/0/Ne/0/search/true/searchType/qck/index.html" resultdomain="bol.com">
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/bookplus-fi.xml b/browser/locales/searchplugins/bookplus-fi.xml
deleted file mode 100644
index 55d36354a..000000000
--- a/browser/locales/searchplugins/bookplus-fi.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Bookplus.fi</ShortName>
-<Description>Pikahaku nettikirjakauppa Bookplus.fi:hin</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQYKieTp1k8w2bonzNGmC/jJlfv4wX3fzLltxzCxacXkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQncc8SpK3y0eNsf5HjrL/SI+z/0eOsf9Fiq3/QYKj/zp1kv8yZH3+LVpxyy5ddzwAAAAAAAAAAAAAAABZrt08UqbP3lKlzv9VqtT/WLHd/1q14v9btuT/WrXi/1eu2v9QoMj/RYqt/zhwjP8wX3feM2Z7PAAAAAAAAAAAXLnoy1+GqP9mAAD/ZgAA/2YNEf9mAAD/ZqLL/2XK/f9mAAD/ZDNA/1iw3P9KlLn/OnWS/zJkfcsAAAAAZ8z/eWTG+P5kkbb/ZgAA/2ZRZf9mMT3/Zg4R/2YOEf9mvu7/ZgAA/2Y2Q/9ixPX/WbLe/0mStv86dJD+Nm2IeXDP/8xtzv//Z5a7/2YAAP9mbIf/Zsz//2ZtiP9mAAD/Zpa7/2YAAP9mNkT/Zcr9/2HC8v9UqdP/RIiq/zp1k8x50v/zdNH//2qXu/9mAAD/Zm2I/2bM//9mRFX/ZgAA/2ax3f9mAAD/Zhsi/2ZtiP9koMj/W7bk/0yYvv9AgaDzgNT//nnS//9smLv/ZgAA/2YbIv9mGyL/ZgAA/2ZtiP9mzP//ZgAA/2YAAP9mAAD/ZgAA/2JYbv9Rosv/RIiq/oXW//5+1P//bZi7/2YAAP9mNkT/ZkRV/2YAAP9mepn/Zsz//2YAAP9mNkT/Zr7u/2YpM/9mAAD/VZ3E/0iOsv6L2f/zhdb//3GZu/9mAAD/Zm2I/2bM//9mKTP/Zhsi/2bM//9mAAD/ZjZE/2bM//9mbYj/ZgAA/1uAn/9Lmb7zk9r/zI7Z//94m7v/ZgAA/2dtiP9mzP//Zhsi/2YAAP9mzP//ZgAA/2Y2RP9nvu7/ZjZE/2YAAP9cnMP/UqXOzJvd/3mZ3P/+gp+7/2YAAP9nGyL/Zhsi/2YAAP9mX3f/Zsz//2YAAP9mAAD/ZgAA/2YAAP9lUGT/Xrzr/lqz33kAAAAAot//y5fP7v96c4j/cXGI/2tuiP9ppMz/Z8z//2fM//9nepn/aG2I/2puiP9riqr/as3//2TG+MsAAAAAAAAAAKXh/zym4f/en9///5Lb//+E1v//e9P//3fS//910f//dtH//3jS//950v//d9L//3DP/95qzP88AAAAAAAAAAAAAAAApeH/PKnj/8ul4P/+nd7//5Xc//+Q2v//jdn//4vY//+J2P//hNX//n7U/8t30P88AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAquP/eaji/8yk4P/zod///p3e//6b3v/zk9r/zIvW/3kAAAAAAAAAAAAAAAAAAAAA8A8AAMADAACAAQAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAAIABAADAAwAA8A8AAA==</Image>
-<Url type="text/html" method="GET" template="http://www.bookplus.fi/search.php" resultdomain="bookplus.fi">
- <Param name="Textfield" value="{searchTerms}"/>
- <Param name="mode" value="book"/>
-</Url>
-<SearchForm>http://www.bookplus.fi/search.php</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/buscape.xml b/browser/locales/searchplugins/buscape.xml
deleted file mode 100644
index 9f5f57fd8..000000000
--- a/browser/locales/searchplugins/buscape.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>BuscaPé</ShortName>
-<Description>Comparação de produtos e pesquisa de preços.</Description>
-<InputEncoding>iso-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,R0lGODlhEAAQANUoALu7u/zW1/WFiPm1tnd3d/itryIiIvFSVlVVVd3d3e7u7vimqKqqqvm3uf3i4//6+v3p6u44Pfzb3PJobPBGS/ekpveane86P/FcYPWChe9BRvFZXfFVWfR2evaOkURERBEREYiIiO4zOMzMzDMzM2ZmZpmZmQAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACgALAAAAAAQABAAAAaPQBQgRDShUCZiaHQ8Ik4f0MkIAn1OoCbKYECFpolTCXVNNKGKZwJwCqFI2SP7dDIwvCcSqd00tRliKCVtIQBaBCcjCicIb3FaZCcAiG5QkEdSdGMjJwQoDxsDl6MVIiITDigBqwMFBQsCsRqmIhcWtLi5uBIBrwIdGBS6B6KjHrTEo0cQESIHDcpNGRzQkEEAOw==</Image>
-<Url type="text/html" method="GET" template="http://busca.buscape.com.br/cprocura" resultdomain="buscape.com.br">
- <Param name="produto" value="{searchTerms}"/>
- <Param name="site_origem" value="11642"/>
-</Url>
-<SearchForm>http://www.buscape.com.br/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/ceneji.xml b/browser/locales/searchplugins/ceneji.xml
deleted file mode 100644
index 69d1c0636..000000000
--- a/browser/locales/searchplugins/ceneji.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Ceneje.si</ShortName>
-<Description>Iskalnik Ceneje.si</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image height="16" width="16" type="image/x-icon">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAzUlEQVQ4EWNgGGjACHLA39uz1R7vqLjJz83EwMnByMDEyoTTXWyhL8B6YAqY/j3bJfX3Qu1NmAAh+tdqif8oakACGIIoKlA5DyYL/wdhmCgLjEEsDfImMkDlIctA2f8+30NRw8nOyADCMIAiCRNEpv/ssPqL7EUmNiYGEIYBlr+//sHYWGn0UEdXxPLtO34D0DWg81k+foUHKLocUXxwaCD7EZuuP0Bvfge6FGSZjBQrA7K3wKGBLIDNAGQxUtQi68NgE3I1hgZsAlQxBAAKUEIHR/DoRAAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="http://www.ceneje.si/search_new.aspx" resultdomain="ceneje.si">
- <Param name="q" value="{searchTerms}" />
- <Param name="FF-SearchBox" value="1" />
-</Url>
-<SearchForm>http://www.ceneje.si</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/chambers-en-GB.xml b/browser/locales/searchplugins/chambers-en-GB.xml
deleted file mode 100644
index accc693f0..000000000
--- a/browser/locales/searchplugins/chambers-en-GB.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Chambers (UK)</ShortName>
-<Description>Chambers 21st Century Dictionary Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAARVBMVEV8grz///8cJoz8AgS8CiQ8QpxMUqQsMpRMDly8wtw8EmSMksS8RmT8iozsBgzM0uR8DkScosxscrSkLlzUGizs7vQsEmwP6BukAAAAYUlEQVR4XpXMNxLEIBBE0ekxgLzf+x9VmEKFlO3P+gVN/CmDI9pbWJCyBzqAHF2uggFR2XwFAph/IcTRh77CKhJBRQv4F3hgSGAVeAO6UeRUnQvwAEySy5ByR/ORW/+FthvNOwN3ZVtbCQAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="http://www.chambers.co.uk/search.php" resultdomain="chambers.co.uk">
- <Param name="query" value="{searchTerms}"/>
- <Param name="title" value="21st"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>http://www.chambers.co.uk/search.php</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/cnrtl-tlfi-fr.xml b/browser/locales/searchplugins/cnrtl-tlfi-fr.xml
deleted file mode 100644
index e78af42e2..000000000
--- a/browser/locales/searchplugins/cnrtl-tlfi-fr.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Portail Lexical - CNRTL</ShortName>
-<Description>Centre National de Ressources Textuelles et Lexicales</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAAAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgbUWgbUWfa0SZZECVXzyUXTuUXTuUXTuUXTuUXTuUXTuUXTuUXTuUXTuXYT6eakOgbUWfbESXYD2PVTiMUjiLUTeMUTeMUTeMUTeMUTeMUTeMUTeMUTeLUTePVTebZkGgbUWcaUPAmoTawbTZwbXZwbXZwbXZwbXZwbXZwbXZwbXZwbXZwbXPuKyaaE6aZUCgbUW8kXP639D94dL+4tP+4tP+4tP+4tP+4tP+4tP+4tP+4tP+4tPt08WhcFWbZ0KgbUXXs5z+49T+49T+5df+5tn+5tn+5tn+5tn+5tn+5tn+5tn+5tn74tSvgWGfbESgbUXat6D+49Ty1MS0h2qtflutf1utf1utf1utf1utf1utf1utf1utf1qjcUqgbUWgbUXat6H53tC3i3SXYT6gbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUXat6H12syrfmeXYT6gbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWhbkbat6H02suoe2SSWjmcZ0KdakOdakOdakOdakOdakOdakOdakOdakOea0SgbUWhbkbat6H12syrgW6JTC+OVDWQVzeQVzeQVzeQVzeQVzeQVzeQVzeQVzeUXTudaUOhbkbbuKH74NLXvrGhdmSZaVSaalWaalWaalWaalWaalV3TFNgOUtgOUt9STmaZUChbkbUsZn+5NX739Du08boz8Hoz8Hoz8HozsHozsHozsGFesdCQsxBQchtRVOaZkGgbUWzhmT85dj+5NX+49X+49X+49X+49X+49T+49T+49SPg9BDRNJCQ85yTFidaUOgbUWgbUW8knPnyrft0L/t0L/t0L/t0L/s0L/s0L/s0L+fjLpqYLtoXrqFXV6gbUWgbUWgbkagbUWgbUWhbkahbkahbkahbkagbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUWgbkagbUWgbUWhbkahbkahbkahbkagbUWgbUWgbUWgbUWgbUWgbUWgbUWgbUUAAH9fAADP/gAAz/4AAPr/AADC/gAAwP4AAE5eAAD//wAA//8AAMb+AAD//wAAwP4AAE5eAAD//wAA//8AAMz+</Image>
-<SearchForm>http://www.cnrtl.fr/lexicographie/</SearchForm>
-<Url type="text/html" method="GET" template="http://www.cnrtl.fr/lexicographie/{searchTerms}" resultdomain="cnrtl.fr">
-</Url>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.cnrtl.fr/utilities/OPEN">
- <Param name="query" value="{searchTerms}"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/danawa-kr.xml b/browser/locales/searchplugins/danawa-kr.xml
deleted file mode 100644
index 7354434b1..000000000
--- a/browser/locales/searchplugins/danawa-kr.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>다나와</ShortName>
-<Description>다나와 쇼핑 검색</Description>
-<InputEncoding>EUC-KR</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAI6crmyOnK/4jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv+I6crmyOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/GKMg/xCgGf8QoBn/EKAZ/xCgGf8Uoh3/HKQk/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/G6Qj/3fJfP//////////////////////yurM/xSiHf8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/xWiHv/C58T/////////////////+v36/0GzSP8cpCT/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/xijIf9fv2X//////////////////f79/2vEcP8YoyH/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/HqUm/xaiH/9avWD/9/z3////////////7/nw/1y+Yv8YoyH/I6cr/yOnK/8jpyv/IKYo/xylJf8YoyH/E6Ec/0CzR/+w4LP////////////0+/T/mdad/yapL/8ZoyL/I6cr/yOnK/8jpyv/I6cr/zewP/9jwWn/lNWY/9Xu1v/m9ef/yenL/57Yof9gwGb/HKUl/xijIf8gpij/I6cr/yOnK/8jpyv/I6cr/yOnK/8gpij/HKUl/xijIf8ToRz/EqEb/xSiHf8YoyD/HaUl/yKnKv8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6crmyOnK/4jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv+I6crmwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAI6crCiOnK54jpyv3I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv3I6crniOnKwojpyueI6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6crniOnK/cjpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv3I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/9GtUz////////////////////////////////////////////H6cn/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/3jJff//////////////////////////////////////+f35/0a1TP8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/vuXB//////////////////////////////////////+DzYf/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/z+yRv/+//7/////////////////////////////////tOG3/ySnLP8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/tuK4/////////////////////////////////8zrzv8sqjP/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/2vEcP/////////////////////////////////P7ND/MKw3/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/9Tulr/9/z4////////////////////////////t+K5/yyqM/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/ZcFq//b79v//////////////////////+f35/4XOiv8kpyz/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/Lqs2/6Lapf/+//7//////////////////////8Dmwv9GtU3/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/Ma04/4XOiv/u+O7//////////////////////8boyP9evmT/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/80rjz/a8Rx/7Lgtf/3/Pj/////////////////3/Lg/5jWnP9Itk//I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/9FtEv/bcVy/5PUl/+95L//4fPi///////0+/T/3/Lg/8Pnxv+h2aT/dMd5/0GzSP8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/cjpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv3I6crniOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK54jpysKI6crniOnK/cjpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/8jpyv/I6cr/yOnK/cjpyueI6crCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="text/html" method="GET" template="http://search.danawa.com/dsearch.php" resultdomain="danawa.com">
- <Param name="k1" value="{searchTerms}"/>
- <Param name="from" value="firefox"/>
-</Url>
-<SearchForm>http://search.danawa.com</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/daum-kr.xml b/browser/locales/searchplugins/daum-kr.xml
deleted file mode 100644
index ea4b1e5a0..000000000
--- a/browser/locales/searchplugins/daum-kr.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>다ìŒ</ShortName>
-<Description>ë‹¤ìŒ ê²€ìƒ‰</Description>
-<InputEncoding>utf-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G/wC6Y/8AumP/ALpj/wC09P8AtPT/ALT0/zo8+/86PPv/Ojz7//htBv/6iyr/+osq//qLKv/6iyr/+osq//qLKv8A1p//ANaf/wDWn/8A2v//ANr//wDa//9fYfz/X2H8/zo8+//4bQb/+osq//qLKv/6iyr/+osq//qLKv/6iyr/ANaf/wDWn/8A1p//ANr//wDa//8A2v//X2H8/19h/P86PPv/+G0G//qLKv/6iyr/+osq//qLKv/6iyr/+osq/wDWn/8A1p//ANaf/wDa//8A2v//ANr//19h/P9fYfz/Ojz7//htBv/6iyr/+osq//qLKv/6iyr/+osq//qLKv8A1p//ANaf/wDWn/8A2v//ANr//wDa//9fYfz/X2H8/zo8+//4bQb/+osq//qLKv/6iyr/+osq//qLKv/6iyr/ANaf/wDWn/8A1p//ANr//wDa//8A2v//X2H8/19h/P86PPv/+G0G//qLKv/6iyr/+osq//qLKv/6iyr/+osq/wDWn/8A1p//ANaf/wDa//8A2v//ANr//19h/P9fYfz/Ojz7//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv8AumP/ALpj/wC6Y/8AtPT/ALT0/wC09P86PPv/Ojz7/zo8+/////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv8AumP/ALpj/wC6Y/8AumP/ALpj/wC6Y/8AtPT/ALT0/wC09P8AtPT/ALT0/wC09P86PPv/Ojz7/zo8+/86PPv/Ojz7/zo8+//4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G/wC6Y/8AumP/ALpj/wC6Y/8AumP/ALpj/wC09P8AtPT/ALT0/wC09P8AtPT/ALT0/zo8+/86PPv/Ojz7/zo8+/86PPv/Ojz7//htBv/4bQb/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/ANaf/wDWn/8A1p//ANaf/wDWn/8A1p//ANr//wDa//8A2v//ANr//wDa//8A2v//X2H8/19h/P9fYfz/X2H8/zo8+/86PPv/+G0G//htBv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv8A1p//ANaf/wDWn/8A1p//ANaf/wDWn/8A2v//ANr//wDa//8A2v//ANr//wDa//9fYfz/X2H8/19h/P9fYfz/Ojz7/zo8+//4bQb/+G0G//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq/wDWn/8A1p//ANaf/wDWn/8A1p//ANaf/wDa//8A2v//ANr//wDa//8A2v//ANr//19h/P9fYfz/X2H8/19h/P86PPv/Ojz7//htBv/4bQb/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/ANaf/wDWn/8A1p//ANaf/wDWn/8A1p//ANr//wDa//8A2v//ANr//wDa//8A2v//X2H8/19h/P9fYfz/X2H8/zo8+/86PPv/+G0G//htBv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv8A1p//ANaf/wDWn/8A1p//ANaf/wDWn/8A2v//ANr//wDa//8A2v//ANr//wDa//9fYfz/X2H8/19h/P9fYfz/Ojz7/zo8+//4bQb/+G0G//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq/wDWn/8A1p//ANaf/wDWn/8A1p//ANaf/wDa//8A2v//ANr//wDa//8A2v//ANr//19h/P9fYfz/X2H8/19h/P86PPv/Ojz7//htBv/4bQb/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/ANaf/wDWn/8A1p//ANaf/wDWn/8A1p//ANr//wDa//8A2v//ANr//wDa//8A2v//X2H8/19h/P9fYfz/X2H8/zo8+/86PPv/+G0G//htBv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv8A1p//ANaf/wDWn/8A1p//ANaf/wDWn/8A2v//ANr//wDa//8A2v//ANr//wDa//9fYfz/X2H8/19h/P9fYfz/Ojz7/zo8+//4bQb/+G0G//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq/wDWn/8A1p//ANaf/wDWn/8A1p//ANaf/wDa//8A2v//ANr//wDa//8A2v//ANr//19h/P9fYfz/X2H8/19h/P86PPv/Ojz7//htBv/4bQb/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/ANaf/wDWn/8A1p//ANaf/wDWn/8A1p//ANr//wDa//8A2v//ANr//wDa//8A2v//X2H8/19h/P9fYfz/X2H8/zo8+/86PPv/+G0G//htBv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv8A1p//ANaf/wDWn/8A1p//ANaf/wDWn/8A2v//ANr//wDa//8A2v//ANr//wDa//9fYfz/X2H8/19h/P9fYfz/Ojz7/zo8+//4bQb/+G0G//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq//qLKv/6iyr/+osq/wDWn/8A1p//ANaf/wDWn/8A1p//ANaf/wDa//8A2v//ANr//wDa//8A2v//ANr//19h/P9fYfz/X2H8/19h/P86PPv/Ojz7//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/ALpj/wC6Y/8AumP/ALpj/wC6Y/8AumP/ALT0/wC09P8AtPT/ALT0/wC09P8AtPT/Ojz7/zo8+/86PPv/Ojz7/zo8+/86PPv/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv/4bQb/+G0G//htBv8AumP/ALpj/wC6Y/8AumP/ALpj/wC6Y/8AtPT/ALT0/wC09P8AtPT/ALT0/wC09P86PPv/Ojz7/zo8+/86PPv/Ojz7/zo8+/////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://sug.search.daum.net/search_nsuggest">
- <Param name="mod" value="fxjson" />
- <Param name="code" value="utf_in_out" />
- <Param name="q" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="http://search.daum.net/search" resultdomain="daum.net">
- <Param name="q" value="{searchTerms}"/>
- <Param name="w" value="tot"/>
- <Param name="nil_ch" value="ffsr"/>
-</Url>
-<SearchForm>http://search.daum.net</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/ddg.xml b/browser/locales/searchplugins/ddg.xml
index f076ec869..079c9d6f6 100644
--- a/browser/locales/searchplugins/ddg.xml
+++ b/browser/locales/searchplugins/ddg.xml
@@ -9,12 +9,12 @@
<InputEncoding>UTF-8</InputEncoding>
<Image height="16" width="16">data:image/icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11RgALs6oACbQ9wAj0v8AI9L/ACfQ9wAu0agANdUYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzzN4CNdL/oK/z//////////////////////+jsPv/BDXX/wAz0t4AAAAAAAAAAAAAAAAAAAAAAAAAAAAyzvNSduD//////8jK/v+P+Lf/IbQL/17RPP+J3Y//wOKX//////9YeuX/ADLO8wAAAAAAAAAAAAAAAAAw091piOX/8/X9/1Fx5P9xhu//WOWZ/0W9Lv9Lwjn/J8BB/xyDAP9bdfL/9fP//2mI5v8AMNPdAAAAAAc610YRQ9f//////0Zr4P8AGdD/sb32////////////wrv//wAh1/8MPab/ACPc/05r4///////EkPX/wc610YANtWkrr/y/6S48P8AJ9L/AB3R/+/w/v///////////3+D7f8AQeL/AYTw/wFr5/8AMNb/p7Tv/6698v8AM9WkADLW//////8yXt//AC3V/wAw1/////////////z///8A0P7/AKb1/wWI7P8AuPf/AJ3w/zZW3P//////ADHV/wAx2P//////AzrZ/wAu1/84ZOL////////////e////AND//wC1+f8Atff/AZbv/wY62f8ELNf//////wAw1/8AMtn//////wAw2f8ALNn/kKrz////+//cwbH////////////R////Rcb8/wDO/f8A/P//AHzo//////8AMNj/ADXa//////8vXuL/ACna/4yq9///79T/jUkg/9i+r///////r2Q0/7Cozv8BKdr/AirY/zdZ4P//////ADTa/wI72tOuv/T/prr0/wAl2v+JqPb//7yW/+bUxv/9+/n////u//W+n/+Op/L/ADPd/wAv2v+ru/T/r7/0/wI72tMLQd1DEEjg//////9Cbef/ADng///////////////////////R3///AC3g/wAy3v9SeOn//////xFI4P8LQd1DAAAAAAM64PNmiuz/9/j//2mN7f/m7P3///////////9Cb+n/ACXd/wAt3v9rju3//////2iL7P8DOuDzAAAAAAAAAAAAAAAAAT3g/0p16f//////3OT8/3OS7v8AKt3/ACPc/zhn5/+xw/b//////0956v8CPeD/AAAAAAAAAAAAAAAAAAAAAAAAAAAEPODzBUDh/5uz8//7/f7/////////////////prz0/wtF4v8FQeDzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtF5kYDQOOkADrj/wA44v8AOeP/ADzk/wVB46QPReZGAAAAAAAAAAAAAAAAAAAAAPAPAADgBwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAADAAwAA4AcAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChIzyAnRNFwJ0TQryND0d8nRNH/J0TR/ydE0f8nRNH/I0PR3ydE0K8nRNFwKEjPIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChE00AlRdK/J0XS/ydF0v8nRdL/XXPd/11z3f94i+P/k6Lp/5Oi6f9rf+D/NVDV/ydF0v8nRdL/JUXSvyhE00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAzxAnRNOvJ0XT/ydF0/8lRdK/KEXSYOvu+6/+/v6//v7+v/39/c////////////7+/r/J0fOAKEXSYCVF0r8nRdP/J0XT/ydE068gQM8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlRdUwJ0bT7ydG0/8nRtHPKETTQAAAAADHx8dA2vHhn5TYpN/o9+z/////////////////8PL83ydG0o8lRdUwAAAAAChE00AnRtHPJ0bT/ydG0+8lRdUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKEXVYCdG1P8nRtT/KEbTgAAAAAAmRtZQI0PU38jIyP/F6s//Rrtk/0a7ZP9/yIr/c796/4vLkv+JpNf/M3Kq/zyWh/8zeKTfJkbWUAAAAAAoRtOAJ0bU/ydG1P8oRdVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVF1TAnR9X/J0fV/yhF1WAgQM8QJ0fTrydH1f9CW8//2tra/6Pdsv9Gu2T/Rrtk/0WzWv9Gu2T/Rrtk/0a7ZP9Gu2T/Rrtk/z6egP8nR9X/J0fTryBAzxAoRdVgJ0fV/ydH1f8lRdUwAAAAAAAAAAAAAAAAAAAAAAAAAAAgQM8QJ0fV7ydH1f8oSNVgIEDPECdH1c8nR9X/J0fV/1xwyf/t7e3/o92y/0a7ZP9Gu2T/Ra5U/0a7ZP9Gu2T/Rrtk/0a7ZP9Gu2T/Pp6A/ydH1f8nR9X/J0fVzyBAzxAoSNVgJ0fV/ydH1e8gQM8QAAAAAAAAAAAAAAAAAAAAACdH1q8nR9b/KEjVgCBQzxAnR9bPJ0fW/ydH1v8nR9b/gIzB//r6+v+j3bL/Rrtk/13Ed/+i26//ruG7/z6egf8+noH/Rrtk/0a7ZP86kI//J0fW/ydH1v8nR9b/J0fWzyBQzxAoSNWAJ0fW/ydH1q8AAAAAAAAAAAAAAAAoSNdAJkjW/yZH1s8AAAAAJEfWryZI1v8mSNb/JkjW/yZI1v+jqsT//////+j37P/R7tj////////////W3ff/JkjW/yZI1v8uZbr/PJeI/zJzrP8mSNb/JkjW/yZI1v8mSNb/JEfWrwAAAAAmR9bPJkjW/yhI10AAAAAAAAAAACVI1r8mSNf/KEjXQCZJ1lAmSNf/JkjX/yZI1/8mSNf/JkjX/9HR0f///////////////////////////5Ok6/8mSNf/JkjX/yZI1/8mSNf/JkjX/yZI1/8mSNf/JkjX/yZI1/8mSNf/JknWUChI10AmSNf/JUjWvwAAAAAoSNcgJknY/yZH2M8AAAAAI0nY3yZJ2P8mSdj/JknY/yZJ2P9KZM//39/f////////////////////////////XHfi/yZJ2P8mSdj/JknY/yZJ2P8mSdj/JknY/yZJ2P8mSdj/JknY/yZJ2P8jSdjfAAAAACZH2M8mSdj/KEjXICdJ2HAmSdj/JUjXYCVK2jAmSdj/JknY/yZJ2P8mSdj/JknY/2V4yf/t7e3///////////////////////////9cd+L/HXTj/xSf7/8Nwfj/CdL8/wnS/P8J0vz/ELDz/xt85v8mSdj/JknY/yZJ2P8lStowJUjXYCZJ2P8nSdhwJErZryZK2f8oSNcgJUnajyZK2f8mStn/JkrZ/yZK2f8mStn/iJPA////////////////////////////0ff+/xjV/P8J0vz/Drn1/xiO6/8Yjuv/GI7r/xCw8/8Lyvr/CdL8/xmF6P8mStn/JkrZ/yVJ2o8oSNcgJkrZ/yRK2a8jStrfI0rZ3wAAAAAlSdq/Jkra/yZK2v8mStr/Jkra/yZK2v+xtsf///////////////////////////8o2Pz/CdL8/wvK+v8mStr/Jkra/yZK2v8mStr/Jkra/yZK2v8iW97/Jkra/yZK2v8mStr/JUnavwAAAAAjStnfI0ra3yZK2v8lSdq/AAAAACZH2O8mStr/Jkra/yZK2v8mStr/L1HY/9HR0f///////////////////////////yjY/P8J0vz/CdL8/xCw9P8QsPT/ELD0/xSf7/8ddeX/Jkra/yZK2v8mStr/Jkra/yZK2v8mR9jvAAAAACVJ2r8mStr/Jkvb/yVJ2r8AAAAAJkvb/yZL2/8mS9v/Jkvb/yZL2/9KZtL/4+Pj////////////////////////////4Pn//0fd/f8J0vz/CdL8/wnS/P8J0vz/CdL8/wnS/P8Lyvr/Fpfu/yJc3/8mS9v/Jkvb/yZL2/8AAAAAJUnavyZL2/8mS9z/JUncvwAAAAAmS9z/Jkvc/yZL3P8mS9z/Jkvc/26AyP/x8fH//////////////////////////////////////9H3/v/C9P7/o+7+/2fa+/8Oufb/CdL8/wnS/P8J0vz/CdL8/xiP7P8mS9z/Jkvc/wAAAAAlSdy/Jkvc/yZM3P8lTNy/AAAAACZJ2e8mTNz/Jkzc/yZM3P8mTNz/iJTB////////////qnth/5VaOf/x6eX///////////////////////Hp5f/x6eX/ydL2/yZM3P8kVN7/G37o/xKo8v8QsfT/HXbm/yZM3P8mSdnvAAAAACVM3L8mTNz/I0vc3yZJ2u8AAAAAJUzevyZM3f8mTN3/Jkzd/yZM3f+fqc3///////////+VWjn/v5yI/+re1///////////////////////jk8s/7iRe//J0vb/Jkzd/yZM3f8mTN3/Jkzd/yZM3f8mTN3/Jkzd/yVM3r8AAAAAI0vc3yNL3N8kTd2vJk3d/yhQ3yAlTd2PJk3d/yZN3f8mTd3/Jk3d/6St0v////////////Hp5f/q3tf///////////////////////////+xhm7/49PK/6Cx8P8mTd3/Jk3d/yZN3f8mTd3/Jk3d/yZN3f8mTd3/JU3djyhQ3yAmTd3/JE3drydN33AmTd7/J03fcCVK3zAmTd7/Jk3e/yZN3v8mTd7/pK7S///////Sp5r/////////////////////////////////////////////////T27k/yZN3v8mTd7/Jk3e/yZN3v8mTd7/Jk3e/yZN3v8lSt8wJ03fcCZN3v8nTd9wKFDfICZO3/8mTt3PAAAAACVN3r8mTt//Jk7f/yZO3/+EltX//////+fRyv/SqaD/59LO///////////////////////at63/vIBy/7Glxf8mTt//Jk7f/yZO3/8mTt//Jk7f/yZO3/8mTt//JU3evwAAAAAmTt3PJk7f/yhQ3yAAAAAAJE/dryZO3/8oUN9AKFDfQCZO3/8mTt//Jk7f/zhb2v/o6/T/////////////////////////////////////////////////XHrn/yZO3/8mTt//Jk7f/yZO3/8mTt//Jk7f/yZO3/8oUN9AKFDfQCZO3/8kT92vAAAAAAAAAAAoUN9AJk7g/yZO4M8AAAAAJk/hnyZO4P8mTuD/Jk7g/05v5v/k6fv//////////////////////////////////////3eR7P8mTuD/Jk7g/yZO4P8mTuD/Jk7g/yZO4P8mTuD/Jk/hnwAAAAAmTuDPJk7g/yhQ30AAAAAAAAAAAAAAAAAjT+GfJU/h/yVO4Y8gUN8QIk7gzyVP4f8lT+H/SWnW/0lp1v+bq+H/8fHx/////////////////6Cy8v9OcOb/JU/h/yVP4f8lT+H/JU/h/yVP4f8lT+H/JU/h/yJO4M8gUN8QJU7hjyVP4f8jT+GfAAAAAAAAAAAAAAAAAAAAACBQ3xAlTOHvJU/h/yVQ4mAgUN8QIk7hzyVP4f+ktOv///////////////////////H0/f9phur/JU/h/yVP4f8lT+H/JU/h/yVP4f8lT+H/JU/h/yVP4f8iTuHPIFDfECVQ4mAlT+H/JUzh7yBQ3xAAAAAAAAAAAAAAAAAAAAAAAAAAACVQ3zAlUOLvJVDi/yVQ4mAgUN8QI1Din4mb2//J0/j/ydP4/6299P93ku3/M1vk/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/I1DinyBQ3xAlUOJgJVDi/yVQ4u8lUN8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQ5DAlUOLvJVDi/yVQ4o8AAAAAJFDjQCVQ4r8lUOL/JVDi/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/JVDivyRQ40AAAAAAJVDijyVQ4v8lUOLvJVDkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQ5DAjUeTfJVHj/yNR5N8kUONAAAAAACVQ5DAmUuOAJVHivyNR5N8lUeP/JVHj/yNR5N8lUeK/JlLjgCVQ5DAAAAAAJFDjQCNR5N8lUeP/I1Hk3yVQ5DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBQ3xAjUuSfJVHk/yVR5P8jUeTfJFLkcChQ5yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoUOcgJFLkcCNR5N8lUeT/JVHk/yNS5J8gUN8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkUONAI1LknyVS5P8lUuT/JVLk/yVS5O8lUeS/JVHkvyVR5L8lUeS/JVLk7yVS5P8lUuT/JVLk/yRS468kUONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFDfECVS5GAjUuWfIlPlzyVS5f8lUuX/JVLl/yVS5f8iU+XPI1LlnyVS5GAgUN8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/ggBB/wgAEP4AAAB8AAAAPAAAADiAAAEYAAAAEQAAAIAAAAAAAAAAAgAAAEIAAABCAAAAQgAAAEIAAABCAAAAQAAAAAAAAAABAAAAiAAAABiAAAEcAAAAPAAAAD4AAAB/CAAQ/4IAQf/AfgP/8AAP//wAP/</Image>
<Url type="text/html" method="get" template="https://duckduckgo.com/" rel="searchform">
+ <MozParam name="t" condition="purpose" purpose="contextmenu" value="palemoon"/>
+ <MozParam name="t" condition="purpose" purpose="keyword" value="palemoon"/>
+ <MozParam name="t" condition="purpose" purpose="searchbar" value="palemoon"/>
+ <MozParam name="t" condition="purpose" purpose="homepage" value="palemoon"/>
+ <MozParam name="t" condition="purpose" purpose="newtab" value="palemoon"/>
<Param name="q" value="{searchTerms}"/>
- <MozParam name="t" condition="purpose" purpose="contextmenu" value="ffcm"/>
- <MozParam name="t" condition="purpose" purpose="keyword" value="ffab"/>
- <MozParam name="t" condition="purpose" purpose="searchbar" value="ffsb"/>
- <MozParam name="t" condition="purpose" purpose="homepage" value="ffhp"/>
- <MozParam name="t" condition="purpose" purpose="newtab" value="ffnt"/>
</Url>
<Url type="application/x-suggestions+json" template="https://ac.duckduckgo.com/ac/">
<Param name="q" value="{searchTerms}"/>
diff --git a/browser/locales/searchplugins/diccionariu-alla.xml b/browser/locales/searchplugins/diccionariu-alla.xml
deleted file mode 100644
index 007038a3b..000000000
--- a/browser/locales/searchplugins/diccionariu-alla.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Diccionariu ALLA</ShortName>
-<Description>Diccionariu de la Academia de la Llingua Asturiana</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO719xO73vJspdXypanU76C63fNk8vP0DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2vD4H6XT78eLyO39weL1/3G86/+v2PD/tNzy/32/6fyh0e/C1O73FwAAAAAAAAAAAAAAAAAAAAAAAAAAxub2TKPR7PXJ5fb/W7Hs/6HS7/+YzO3/isju/4/J7f95v+3/3vH6/47K8PK13vU6AAAAAAAAAAAAAAAA2O/3KJPL6vlotun/pdPq/53P7f8/pOz/f8Lu/1iv7P+ExOz/ZLbv/47I6/9nt+v/m87u8M7q9hgAAAAAAAAAAKHS79fi8vr/isbr/37C7/98we3/arfs/12y6/+DxO//Zrft/3G/7/91v+//rdfv/8/o9v+g0e7FAAAAAN7x+St0vOj/fMDs/2C07P+Bwuz/d7/t/5rQ7/+bz/D/kMnu/6jV7/98we//eL7s/6DS8P9cs+7/isfs/Nfx+Biz2fGPweL1/4jH7P9/w+3/bLjs/6fV7/9Gpun/h8bt/3W97v9Cpez/qdTu/2K28P88pO7/q9fw/8bk9/+23fVums7wt7jd8v+Nxun/WK/r/4nH7v+DxfH/d73t/83l8//B4vT/hMXu/57P7/9Uruz/gcTv/5/R8P91vOr/pdTyoJnN77d0ver/n9Du/4DD7f9hs+j/ls3w/4HD7v/N5vT/yOT0/3K+8f+Ryu7/gcTu/0yt7/+Qy+//tdvw/6fV8p+v1u6T2O33/5rP7f9Dper/XrXv/5nN7f9Ip+r/b7vw/4PE7/9Cpe3/rNXv/2K28f+DxO7/jcnv/7Lb9P+73/Zjzer2M37A6P9mtu3/kczv/2+97v92vu7/rdbu/4rH7/+d0O7/lczu/3e/7/99we7/bLrw/3e/7v9+wOr89vf3DAAAAACd0O7b0ur1/57R7v+Awuz/f8Lu/16z7v+Hx+//YLPr/1mw7v98wO//g8Tw/4jF7f/W7fn/odPyvAAAAAAAAAAAyer4MprP7vdYr+r/lsvt/2+77/+Ixu3/Sqvv/4XF7v9HqOz/oNLx/6bT7v9otun/lM3w8uT3+xQAAAAAAAAAAAAAAAC+4vVMl87s9+Py+P92u+r/lczs/5TK7P+Vy+3/q9Xu/1iu6v/N5/T/lszv8NDp9i8AAAAAAAAAAAAAAAAAAAAAAAAAANbt9x+g0e/Le77o/rzf8/+j1PL/eMDt/73f9v+Lx+z7pNPxvdrz+hcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOr3+RW63vRsrtj0na7X8prC4/Zh9v3+CwAAAAAAAAAAAAAAAAAAAAAAAAAA/n8AAPAPAADgBwAAwAMAAIABAACAAQAAAAEAAAAAAAAAAAAAAAEAAIABAACAAQAAwAMAAOAHAADwDwAA/n8AAA==</Image>
-<Url type="text/html" method="POST" template="http://www.academiadelallingua.com/diccionariu/index.php" resultdomain="academiadelallingua.com">
- <Param name="pallabra" value="{searchTerms}" />
-</Url>
-<SearchForm>http://search.ebay.es/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/dict-enlv.xml b/browser/locales/searchplugins/dict-enlv.xml
deleted file mode 100644
index 72bf2e1e9..000000000
--- a/browser/locales/searchplugins/dict-enlv.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Dict.lv En-Lv</ShortName>
-<Description>Angļu - latvieÅ¡u vÄrdnÄ«ca</Description>
-<Image height="16" width="16" type="image/x-icon">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAABF0lEQVQ4EY1TuxHCMAw1nwUYgCaMEAqOmhXICEBHCSOEkg5YgRFIzR13yQo0DJCWkvcSO45sE9CdTrak96TIykAFZL7ZRuPpTL3yxzsQFq6huNnLCMcziA6wEbS8n45XG7annj3KE8AkyaG0ExCUMqO%2B9UNO7WPlJ5TAlfZ5pouA4AS6hqboaOGh%2F3UAfKOG8rtmwIoxtNA2heUs2Fkj3iugEkFn6AVqwDuNWMLyZRoRBABzcGx1j0okoGTw07IDxoW4Q6wqtcAm2ezATwImsG0h7ne3g24HjHFxvom3TC4BJxzjmwVJ6565zC6BGZy7ebwXgdkobw9QjU9lnpEV%2BazciQQE3id4BEisBEQEUfgneoOtQ0p9ALb%2FSSokPYL8AAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="get" template="http://dict.lv/enlv/{searchTerms}" resultdomain="dict.lv" />
-<InputEncoding>UTF-8</InputEncoding>
-<SearchForm>http://dict.lv</SearchForm>
-</SearchPlugin>
-
-
-
diff --git a/browser/locales/searchplugins/diec2.xml b/browser/locales/searchplugins/diec2.xml
deleted file mode 100644
index afba6bb67..000000000
--- a/browser/locales/searchplugins/diec2.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>DIEC2</ShortName>
-<Description>Diccionari de l'Institut d'Estudis Catalans</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAFfKj%2FFAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167%2B3t%2B9f7vOec5%2FzOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP%2FwBr28AAgBw1S4kEsfh%2F4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv%2BCpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH%2BOD%2BQ5%2Bbk4eZm52zv9MWi%2FmvwbyI%2BIfHf%2FryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3%2FldM9sJoFoK0Hr5i3k4%2FEAenqFQyDwdHAoLC%2B0lYqG9MOOLPv8z4W%2Fgi372%2FEAe%2Ftt68ABxmkCZrcCjg%2F1xYW52rlKO58sEQjFu9%2Bcj%2FseFf%2F2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R%2BW%2FQmTdw0ArIZPwE62B7XLbMB%2B7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv%2FmPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5%2BASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1%2BTSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q%2B0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw%2BS3FDrFiOJMCaIkUqSUEko1ZT%2FlBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC%2FpdLoJ3YMeRZfQl9Jr6Afp5%2BmD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA%2BYb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV%2Bjvl%2F9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1%2BrTfaetq%2B2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z%2Bo%2B02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y%2FDMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS%2BKc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw%2BlXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r%2B00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle%2B70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l%2Bs7pAz7GPgKfep%2BHvqa%2BIt89viN%2B1n6Zfgf8nvs7%2Bsv9j%2Fi%2F4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww%2BFUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX%2BX0UKSoyqi7qUbRTdHF09yzWrORZ%2B2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY%2BybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP%2BWDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D%2BmiGT0Z1xjMJT1IreZEZkrkj801WRNberM%2FZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c%2FPbFWyFTNGjtFKuUA4WTC%2BoK3hbGFt4uEi9SFrUM99m%2Fur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl%2FVfPV5bdra3kq3yu3rSOuk626s91m%2Fr0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e%2B2Sba1r%2Fdd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q%2F5n7duEd3T8Wej3ulewf2Re%2FranRvbNyvv7%2ByCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9%2BmfHvjUOihzsPcw83fmX%2B39QjrSHkr0jq%2Fdawto22gPaG97%2BiMo50dXh1Hvrf%2Ffu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1%2F3yfPe549d8Lxw9CL3Ytslt0utPa49R35w%2FeFIr1tv62X3y%2B1XPK509E3rO9Hv03%2F6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r%2Fy%2B2v3qB%2FoP6n%2B0%2FrFlwG3g%2BGDAYM%2FDWQ%2FvDgmHnv6U%2F9OH4dJHzEfVI0YjjY%2BdHx8bDRq98mTOk%2BGnsqcTz8p%2BVv9563Or59%2F94vtLz1j82PAL%2BYvPv655qfNy76uprzrHI8cfvM55PfGm%2FK3O233vuO%2B638e9H5ko%2FED%2BUPPR%2BmPHp9BP9z7nfP78L%2FeE8%2Fsl0p8zAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn%2FAACA6QAAdTAAAOpgAAA6mAAAF2%2BSX8VGAAADAFBMVEX%2F%2F%2F%2F%2F%2F8z%2F%2F5n%2F%2F2b%2F%2FzP%2F%2FwD%2FzP%2F%2FzMz%2FzJn%2FzGb%2FzDP%2FzAD%2Fmf%2F%2Fmcz%2FmZn%2FmWb%2FmTP%2FmQD%2FZv%2F%2FZsz%2FZpn%2FZmb%2FZjP%2FZgD%2FM%2F%2F%2FM8z%2FM5n%2FM2b%2FMzP%2FMwD%2FAP%2F%2FAMz%2FAJn%2FAGb%2FADP%2FAADM%2F%2F%2FM%2F8zM%2F5nM%2F2bM%2FzPM%2FwDMzP%2FMzMzMzJnMzGbMzDPMzADMmf%2FMmczMmZnMmWbMmTPMmQDMZv%2FMZszMZpnMZmbMZjPMZgDMM%2F%2FMM8zMM5nMM2bMMzPMMwDMAP%2FMAMzMAJnMAGbMADPMAACZ%2F%2F%2BZ%2F8yZ%2F5mZ%2F2aZ%2FzOZ%2FwCZzP%2BZzMyZzJmZzGaZzDOZzACZmf%2BZmcyZmZmZmWaZmTOZmQCZZv%2BZZsyZZpmZZmaZZjOZZgCZM%2F%2BZM8yZM5mZM2aZMzOZMwCZAP%2BZAMyZAJmZAGaZADOZAABm%2F%2F9m%2F8xm%2F5lm%2F2Zm%2FzNm%2FwBmzP9mzMxmzJlmzGZmzDNmzABmmf9mmcxmmZlmmWZmmTNmmQBmZv9mZsxmZplmZmZmZjNmZgBmM%2F9mM8xmM5lmM2ZmMzNmMwBmAP9mAMxmAJlmAGZmADNmAAAz%2F%2F8z%2F8wz%2F5kz%2F2Yz%2FzMz%2FwAzzP8zzMwzzJkzzGYzzDMzzAAzmf8zmcwzmZkzmWYzmTMzmQAzZv8zZswzZpkzZmYzZjMzZgAzM%2F8zM8wzM5kzM2YzMzMzMwAzAP8zAMwzAJkzAGYzADMzAAAA%2F%2F8A%2F8wA%2F5kA%2F2YA%2FzMA%2FwAAzP8AzMwAzJkAzGYAzDMAzAAAmf8AmcwAmZkAmWYAmTMAmQAAZv8AZswAZpkAZmYAZjMAZgAAM%2F8AM8wAM5kAM2YAMzMAMwAAAP8AAMwAAJkAAGYAADMAAAD6Fxj8FRb7FBX5EhT8BQf7BQf5Bwj9Cgv8DBD7DQ%2F5DxH6EhX9ExT6ExX8FBb18ez84N3%2B6%2Br5Cgn4Dgz7Dw%2F2Ew%2F5EhH5ExH2FRH3FRL9ExP5FBT9FhX8FRX6FRX4FxX8Fhb7Fxb2Gxj5HRr2HRn3HRv%2F%2F%2F8AAAD5ITrYAAAA%2F3RSTlP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwBm%2FIpZAAAA7ElEQVR42mL4d4PhHwMAAAD%2F%2F2K4cYOFSRAAAAD%2F%2F2L494zhLRPDV4a%2FAAAAAP%2F%2FYrzBwMDAwPDrGQMTw98vDEwM3xkZAAAAAP%2F%2FYvzHdIuL9SOrIhMDw39R8f%2B8DAz%2FGH78ZvjxnoHhHwMEAFiWQx0AQSgAgOeT5IjMSOb%2Fv8Zut7ARwcL124%2BQW%2BRWJbdcfMLSlyFMx3RJknoaQvd22P35qZBjFQBBKArDvxe3ahIi8P3fKZwFJZzjhmAN3qXDNxx%2Bhr0KFDgF6ErXoytbAg%2BUx1zLDFFNcDNkMW0HAeJtwjtDXk3z4Ebit28Ab35LCW4dGm8AAAAASUVORK5CYII%3D</Image>
-<Url type="text/html" method="GET" template="http://dlc.iec.cat/results.asp" resultdomain="iec.cat">
- <Param name="txtEntrada" value="{searchTerms}"/>
- <Param name="OperEntrada" value="0"/>
-</Url>
-<SearchForm>http://dlc.iec.cat</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/diribg.xml b/browser/locales/searchplugins/diribg.xml
deleted file mode 100644
index 81df35a6f..000000000
--- a/browser/locales/searchplugins/diribg.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Дири.бг</ShortName>
-<Description>ТърÑачка Дири на dir.bg</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAUAAAAAAAAAAAAAAAEAAAABAAD///8A7NLCAM+OZgDFd0cAyoNXAOK8pACySgoA+/TxANCPZwC0TAsAwm45AOzTwwDPiFkAuVENAMJmKgDpyLMAynxJAO7UwwDnwKYAvlYPAMp1OwD79PAA0opZAO/VxADXjlwAxFsRAPDWwwD46uEA8NbEAMlfEwDWh00A8tfFAM5kFgDRbiUA2opQAPPZxQDZfDUA02kYAPns4gDWciYA9NrGAOy3jQDZbhoA56VwAO6/mgD228YA/fbxAOB8KgDecxwA7LCAAPHCnAD33McA+ubVAOWALADjeB4A6ppWAOeJOgD43scA/O7jAO+scgDleh8A7aNkAOybVwD53sgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDAwQFAAMGAQAAAAAHCAkJCQkJCQoKCQsAAAAADA0ODwAADxANDQ0RAAAAEhMUFQAAAAAAFhMTFwAAABgZGgAAAAAAABsZGRwAAAAdHQAAAAAAAAAAHh0fAAAAICEAAAAAAAAAACIgIwAAACQlJgAAAAAAAAAnJSgAAAApKisAAAAAAAAsKiotAAAALi8wMS4AAAAyMDAwMwAAAAA0NTY1Nzc4NjU1NjkAAAAAADo7PDw8PD00Pjw/AAAAAAAAAAA5OQAAAD48PwAAAAAAAAAAAAAAAAA+PD8AAAAAAAAAAAAAAAAAPjw/AAAAAAAAAAAAAAAAAD48PwAAAAAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8=</Image>
-<Url type="text/html" method="GET" template="http://www.diri.bg/search.php" resultdomain="diri.bg">
- <Param name="came" value="s" />
- <Param name="u" value="1" />
- <Param name="browser" value="ff" />
- <Param name="textfield" value="{searchTerms}" />
-</Url>
-<SearchForm>http://diri.bg/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/drae.xml b/browser/locales/searchplugins/drae.xml
deleted file mode 100644
index cdc7f3c0b..000000000
--- a/browser/locales/searchplugins/drae.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Diccionario RAE</ShortName>
- <Description>Real Academia Española. Diccionario Usual.</Description>
- <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AP///wDP8eMAw83LAKyLlgCshYMAqpKMSIc/QsyeYl2PmVZPPZlpbgB1enQApru/AL/V2wD///8A////AP///wD///8Az/HjAMHJxgCzn6oAmlZUSIk5NrWjgoOhoWRfwH0jINKAKiefi315GMDc4gDL6fEA////AP///wD///8A////AOj//wDCvrkAjEdOTYkvMv2bYWCYoH+CP59wcUSrgX2Ahiwk/5xBRMGTkpIAfYuJAP///wD///8A////AP///wCOqqMAnpCMOZRFQ9WRW164p4KAfpRmYXaGNTWNnnNxa5dZWbKLIij/gVhVbzI0LQD///8A////AP///wD///8AZ0xMH3hGRoiiZ2eNoGNkrJdjYbqeb22Jk01Lo5xlY66bZGWinGBfx7KNjaF+bm1B////AP///wD///8A////ALB7fE+bVlqzhUJCgZRfYIOfZmipjlhXep58d0WbY2XDoXp6cJZWVG+EMDPTkTU6iP///wD///8A////AP///wClYGJjn2BmtotNS7SCRECnooeJTax9fIibV1OeoHl0ZZlobYKVT1Fvjk9Qs38vM4b///8A////AP///wD///8AS0g/CYA+NoqeR0XfmGhno66ZmG6woKFxiFZXsKmHhGujcXCNjT0+6pNUU7ikgnk4////AP///wD///8A////AKPHvwCdoZ8mhykw3Y9MTbW3o6BlmndyT3hRTlq1nJmJmm1xkZ5TVtWAQD+Td2BXAP///wD///8A////AP///wDg2+YAu6qtJIA5MraJOjXTkmBfY4lRVIiVV1eds5uYL49XV52FJCb3q25qY6V3eAH///8A////AP///wD///8AwtzIAKSjmiiDR0x7ml5fzX4iJuiXVFZynGtvaYUeIuGQPDzem1has4JWVEOeYWQA////AP///wD///8A////AM7/6wCgwLcAjFNRK8XEwwCffXyKhigozZRDSa11MSu9oWBfQJJ+fEBle3YAg316AP///wD///8A////AP///wDAz8cAuL65AMCyqwCpiIQLl2RkbY0+P9GHHBn9gkxKfIx3cQByfHQAYIiAAF+DewD///8A////AP///wD///8AmnN0AJ57egCikI4AlGRkrZE/Q+qWTEivi0BArJU2Pv6VbmuKi3p1AJF3cwCQd3MA////AP///wD///8A////AKmcngCpnJ4App6iALeemiqndW1jiU9Pm55ueZefXFlkv7OxItr6/wDT5u0A0+btAP///wD///8A////AP///wCxq7AAsauwAK6stADBrKcAsZWHAJyAg0ewpqVAtIN3ALmrqgDH9f8AxOTsAMTk7AD///8A////APw/AAD4DwAA8A8AAOAHAADAAwAAwAMAAMADAADAAwAA4AcAAOADAADgBwAA9A8AAPg/AAD4HwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wDO8OQAy+HSALmopQDC2vIAs6GoAJ9gXgClcGgAro2IAMTc2SeHRkqQjU5TiaiOkC6MRTxF08K4I2hWTQBTFR0Az5SYAGRdWQB+Zl0A0fP2AL/c3gC/3N4A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AM7w5ADL4dIAuailAMLa8gCzoagAn2BeAKd1bQCxkI0AqIKCi3EIBv+HQ0TinG5qg4g1LLm9hnyAZ1ZMAFMXHwDRlpsAZl9cAH5lXADR8/YAv9zeAL/c3gD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AzvDkAMvh0gC5qKUAwtnyALKhpwCgYWAAr4iBD5NUUG2JLibvk1RWxaRybZyTQj7RkE5O1H8MCv9mDQu+eTc+V8qanC5lYVoFfmVdANDz9gC/3N4Av9zeAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDO8OQAyuDQALutqwDG5P0AtKOpA5xcX0eYUE2eexES0Z12dpbI6e4RrJGPepZMSrqvko1UmG9wn5A4MOuRMirkkkNB2Gw+Om6ahHoA0P//ANb3+QDX+PoA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AM7w5ADM5dYAtZuWAMHP5gC2qK85jTs1x4MoK/GUQ0HRmGhmYaeUlzOSZnJelmdlQ65wYmmwiY1un398hYgnFtp2Dw//m09TtLKHhWS0x8wEjaKjAIqhogD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A0/frANP36gCugHUAlWJtAZVaX5p6AAD+mGFlm6J0dYaYUEqgn1ZWlZldZICOUFByll1dcJpcX6CWU0qipYCBfZRQT8SAGxfnoVBVqZNtaQYAAQAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDQ9egAzevfCqh9eUF+JiOrfBwZ/513fJyXWGGZlltbnKyJf5aQcWwjhGJhUaFWT6xWVFcAooOKVZpiWaWfdnSPlkhHtHMICvmAFiHxkGBdlVJIQh1cU0oA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAHBgBfYWIeuIOLxpNJQtaMSkvQs724VpJVT6aPTU/Nu7e3X5JxdWBzLy2ilk1FwXszLZKea3J2qIyGdpVPR8N/HibFiEpTwoo4MtCXUlXgvaGeZ5GEeAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAGFTTjOhamWgnpGRLKVwcnKYVFWuhTk+36aAgI2phH9/o3Boo6Fuco6lcHJRfQUA/4g/Otqsi4dlpXt+loo0O9uje3aYn3FzoLORlIC0rrBDKScmHv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAuNzYAqnFumWkYGcJyODpZoVRXoZ1OUrKaXmCrnHV3kJVYVsWPQTO8rY6GYbCDh2qVTkqhjUpD4qR+hZGrjpBrjURBz5ZaVai1mJNloXB1hppoZLOtkItm////AP///wD///8A////AP///wD///8A////AP///wD///8A////AJh6eR6ea3OSj0BBupxQTYWhbWlxll5bl49KT7KjcXKFlmlroXoaIfmRam1ehnx7MbCAel6bam+2nmputKp8dlucZF2ihjg41JFFRsuLNTbvjkZD0o5NVWn///8A////AP///wD///8A////AP///wD///8A////AP///wD///8Au5OQQZ5gY5aRTk2gt4mJa3FBPz9vLTOmsI2Lfa+ZlVybYWmXnVBNoZuIhD+WoJ0ApFpXjpNWUdaPX1+1nXqAa6Jzc1+tfnhDgTM2a3oyOXOQOTm5fBkeiv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCYU1NXjkVMxJRbZrOSYGivhD8/spA3NMqWZ2mBgU1Pe6+RkGS3mpNVoFNPqJxGQLCQR0OdsIqAWJVcYYSOdHucoHJ6bZtYVDyXXVptj1NfZ4Y7Od5uFB6a////AP///wD///8A////AP///wD///8A////AP///wD///8A////AK5ycV+cW1+gmGBfhY9VVZ+XXVe4jTMr6IFWV3ZzU1p1t5efVp9zb4eba2qyllhVw5hkZH6wj4k3oXRwdp1tZ2CcXmOjhyov345CQ7OfZGOPj1pXyH9JS33///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ASkdGFKyIhHeYPj6ofh0a2aSCf5OISEO9pnVtorSPi3+oiopss5+dXKiXoH+YYmqrmllQnJ18fX2rmJJ2t5CJU4M3Pc2TVVbLm11YnIxHR7GmfHmQr3htU////wD///8A////AP///wD///8A////AP///wD///8A////AP///wAfKCIAgGpbFJA/O6qCGBj/om1qp5ZkZ5+MU1SysqOeWqiLjJTI4+ARq4B/h41BSNmZZ1+jl2JguqJ7hnKph4hzj0hGyaF4cYyMNjXUhiAl+ZhqZpOcfnMN////AP///wD///8A////AP///wD///8A////AP///wD///8A////AFJtXABab10CmW1qjKZdYrmLNTLJmFpgiIpESsOujo2HsI2Ne6R6doy0k4RMNTIzFnNnbEi1i4e3s5GMZJ1jZqGTXmGnpoCFdIk3Pem1bHCxRyEnSgAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A8P//AOz//wylrKooh1Zla30OEv9/KiLjlmZrhayGh4W2iX5WqYJ8WJNSVIhkJihskktGgr6spVqvoJ9/iDw+05NeYJ+nfoOGiCor4rV7d7JfQjg/DRMKAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDI1eAA09zoCItzdSN0MzGklkpO64c9NMKqeXGIgn56FoZWWIyzioxtc1lZK6Jub5a/kohiq5SQY7S2r0WRYGVmhTY0zYk9N89zBQbtnWFhiLeIghu/gX4A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AK6HiQCmfYI1p3NwZptoWGaWWFSxjzs5vZFLSruLYV5mjkxMhYs6PLKCVFSYjllgn5JMUZWMP0OMuKGaEKeIhEl9FxryhC0w1ZBNUZ+eWFdzrn+BUKpzdwX///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AyujVAMXk0gu1komOdERFUppsaVKKNDLsgS4264UoJe2IMDizizw+c6BkYZGZcG20hDEyq5BJUaqVSk6Jijw8wZJNSNeaYnCdllxblb91bapoTEc0BQ0IAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDQ/+cA4v//AIyWlw1uPkl/oV5lgZhpZ4+lhISkjkhHyHcLEv+HLC7DpGtvDbWenwyNQEGZhCUq93EAAP+ENDfwmV1bn6FeX3OucnGhWk1KUgkCAwAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AM383wDk//kAdISFAGhgYQCsd3GBnWZncMbi6hayv78giDUxwIQpJPifc3BlpXaATIowO7OFKSX1qmxivplaVn2RRkuXgSklrJSMjUVFX2MAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8Azv/iAOX//AB0hYYAYlJVALeZjAKlcWoIxMnEAMbX0AKOREPHdwkH9IczNdyVSlDWdAAA/3suLtx5e3cPkkM+AKNcYSGhnJUwd5KMBEVYWgAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wDP/OEA4//3AIKVkwBza2sAwKufAMC6tQCvl4YAk05PVYg9Od2WUlR8iDk51YozMLGaTUKqdSAl5VdIQA5LPTYAp46PALi4swCOm5cATlRVAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AMixuADIsbgAybK5AMmzugDGr7gAwb69DJpuZWSRXGR0qYmFYpRTVpePT0rAjj4+t4wtLrKIKCnXmFBShZmekx9JW1sAHSAgAC8/PgAZJCYAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8Aa05YAGpNVwBtUVsAa1BaAG1RXgCfgIJvkVNWt5NXWKyfYmSejTU3vo07N8eUTVC2iDAvwZhZW52JLzvetGln0lxFPyoQAAAAJQsIAC4SDQA9HhUAORsTAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAACQ8MAJBpYo2NNTLojkBEypRDQ9B3BgL5k0tDp5xzcYaCLTHnjkZTu5BLTraWZWC3wJuYVc2mogDIoZ0AyKGdAMihnQDIoZ0A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAGBQQAr6erI7yak2qtj4xpsJGQg5E5PK2niotkm2txa4koL7GfYGCcpWdkeqp/e2nE4Ocbz/j/AMzv/ADM7/wAzO/8AMzv/AD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAUAAAC0usQA0MnFAMWijwKXgn8yhlZTcqBsb6yleoCbpI6WcLSXkz+3eGoMqHFqAMTf4gDR9P8Azez2AM3s9gDN7PYAzez2AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAABQEAALK1vgDJu7cA1KqXAHhhYABcbnAAh1NWlLCMjm686/oAxL+2ALV3aQCmbmkAw93hAM/y/gDM6vQAzOr0AMzq9ADM6vQA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAFAQAAsrW+AMm8twDSqpcAa1JRAISuugDFs7VJq6aYMb7i4gDBt7EAtHZnAKZuagDD3eEAz/L+AMzq9ADM6vQAzOr0AMzq9AD///8A////AP///wD///8A////AP/4H///+B///+AB//+AAf//gAB//wAAf/wAQD/8AAA//AAAH/wAAB/4AAAf+ACAH/gAAB/4AAAf+AAAH/wAAB/8AAA//AAAP/wAAD/8AAAf/AAAP/4AAH//gAD//5AI///wD///wAf//8AD///AA///wAP///AP///+f////n//</Image>
- <Url type="text/html" method="get" template="http://dle.rae.es/" resultdomain="dle.rae.es"
- rel="searchform">
- <Param name="w" value="{searchTerms}"/>
- </Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/dunaj-sk.xml b/browser/locales/searchplugins/dunaj-sk.xml
deleted file mode 100644
index 84ac4b406..000000000
--- a/browser/locales/searchplugins/dunaj-sk.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Dunaj</ShortName>
-<Description>Dunaj.sk - zelena vasim nakupom</Description>
-<InputEncoding>WINDOWS-1250</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACOUlEQVQ4jb2ST0iTcRzGn/e3952b29vLfJtuvrp0zaEzjXA2qCHV0MBTlJ4iCIqKDp28dOpS0C0i+nOIOnQKolAqEKJ/BhmWEuuQdggbvmtm5u/9ve/e7XXv1sUshMAKeu6f5/v9wAP8Y7i/BYONkb3Hjx09zP8BIwCwAZQB+Jy14XPqItXWTSeSqZPb4okBAPymeN9EonfwCYDqdSt09w2+MIu27OLL0wLPO1+O3jkAwPydgmPlXQBAMBhsy9FiFzNMlySK0VL29Q4AJgCQXyASCkdTkdbWvpWC1dSHYwOU5V0cR8CMPBGVzquBQKj9xyWEQuFkQyxxWawiWYMydfuu3iFFUTYbRVMzGdP9Ld03i9ay0OAT7oNmznyYGjur6/QTgAofjcVSy1J0mC99PsKWlnJN8dRIak9SfjT68MZXVb3klmWlQtWL9H36Xq5AP651JaruPBX0VaffTozf1qrqLhzc3y+ndsZhFO36aFvHvsAGWdEWMk8lSawFIK0t4MKdySsFQTpkZafizU0tPZYYujbQv5uIXg+oxlCyy3A4CB4/uHv6+aux62AsD6/XA13/AgCcLMuKsqVn+Jtpd4R9lfOMLs5Q3Qps9PubRY/XkZ3PaQW2NFkw6azPF2wXBCJMv5seyecXVODnlMXI1sRQ2V13wuN2GrbJJt1Obs7hICWqGW6bIzWSKLpg0tE3489uAdBXFdYo1TQ2R+KhpkiXYZVqCEjFsvK5+bnZ9LyaGQew/un+t3wHzZ7XlmdRXP0AAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://www.dunaj.sk/default.asp" resultdomain="dunaj.sk">
- <Param name="bShowGoodsList" value="True"/>
- <Param name="bShowSearchForm" value="True"/>
- <Param name="sSearchBasic" value="{searchTerms}"/>
- <Param name="nDepartmentID" value="10000"/>
- <Param name="sourceid" value="firefox"/>
-</Url>
-<SearchForm>http://www.dunaj.sk/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/eki-ee.xml b/browser/locales/searchplugins/eki-ee.xml
deleted file mode 100644
index 3cce716fb..000000000
--- a/browser/locales/searchplugins/eki-ee.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Õigekeelsussõnaraamat</ShortName>
-<Description>EKI.ee Eesti õigekeelsussõnaraamat ÕS 2013</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAhUML/4A7AP+AOwD/gDsA/4A7AP+AOwD/tY1q///////ezb7/gT0D/4A7AP+AOwD/gDsA/4A7AP+AOwD/klck/4A7AP+AOwD/gDsA/49TH//Pror/z6uC/+DJr///////1sCt/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4pLFf+AOwD/gDsA/4A7AP+gbUH/vIQ//6ZcAP/Gllz//////+HRxP+hbkP/hUMK/4A7AP+AOwD/g0AG/4hIEf+SWCX/yqeC/8qngv/Kp4L/z62H/6xnEf+mXAD/xpZc///////m0rn/tXku/7GEWv+AOwD/jlEd/8qidP/DlFr/yJ1o/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/8aWXP//////4sqt/6ZcAP+/j1b/v5Zs/8OZbP+qZA3/plwA/61pFf/PpXX/z6d3/6ZdAv/Bjk//yJpi/8iaYv/cvpv//////+jVvv+4fjb/uH42/7R2Kf+mXAD/plwA/6ZcAP+taRX/vYJA/9Svhf+zdCb/zJ5r/7p8N/+6fDf/0qt////////bvZj/wIxL/8CMS//SrX//snIj/7mAOP/Qp3j/0qx//6t7UP+ziWT/1bCH/7yAPv+6fDf/vIE//+TJpv/26dX/5c6y/9KsfP+8hUD/v4pJ/8GNTv/SroD/woxQ/8eWX/+AOwD/iUkT/8qcav+6fTn/vIA+/8eVXf/nyJX/5MGF//jt1v/25sP/6dS1/6lhCf/ElFj/yZ1m/8mbY//NpHH/oWw//66BWf/Il2H/4sWe/+fLof/nyp//4rt7/+TBhv/47dr/9+fH//Lix//Im2H/wY5N/6ZdAv+mXAD/rWkV/8GJTP/Ah0n/v4VF/+nOof/huXb/7NSr//Dcuv/x3r7/5sSM//Xny//25L//9+jI//fq0f+5gDn/qmQN/7FxIv/mzq7/5s6x/+PFnv/kwIX/58eR/+vPov/huXf/4bh0/+G4dP/26M//9ufI//bmxP/36Mr/1bGI/8udaf/RqHr/9uS///XlyP/huHX/4bh0/+jIlP/47tv/9OTG/+K7e//huHT/79m2/+TBhf/x3rz/9ujJ/8qaZf+6fDj/v4dI//HevP/qzZ3/6cyb/+3Vrv/x38H/+OvP//fqzv/kv4P/4bh0/+3Wr//huHT/79ew//fpy//r1rX/1q+B/7+HSP/huHT/4bh0/+vQo//huHT/6MiU//jrz//36s7/5L+D/+G4dP/t1q//4bh0/+/XsP/36cr/58aQ/+C/kv+/h0j/4rt6/+G4dP/rz6L/4bh0/+jIlP/468//9+rO/+S/g//huHT/7dav/+G4dP/v17D/9+nK/+fGkP/gv5L/w45T/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAll0s/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/jVAb/+vh2P/////////////////Os53/hkQM/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gT0D/7GGYv+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+EQQj/18Kw/////////////////6+EX/+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/lVwr/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+KShT/vpt8/9rFsf/dybb/3cm2/97Luf/07uj/////////////////rYFb/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+VXCv/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/7WNa//iyq//wY1N/8GNTf/BjU3/w5BS/+vbx/////////////////+tgVv/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/5VcK/+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/wJ+C/9Ovgv+mXAD/plwA/6ZcAP+oYQj/48yw/////////////////62BW/+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP+AOwD/lVwr/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/4A7AP/An4L/0at8/6ZcAP+mXAD/plwA/6hhCP/jzLD/////////////////2se2/8anjf+/nH//lVsq/4A7AP+AOwD/gDsA/4A7AP+AOwD/gDsA/41PG/+RViP/kVYj/5FWI/+kckj/w6OH/8Ojh//Do4f/w6OH/8Ojh//Do4f/xqeM/+PTw/+7gz7/plwA/6ZcAP+mXAD/qGEI/+PMsP/////////////////WtYz/wIxM/8WWXP/Qs5X/iEcQ/4A7AP+AOwD/gDsA/41PGv/Rt53/4cy1/+HNtf/hzbX/4c21/+bVwv/Rq3z/0at8/9GrfP/Rq3z/0at8/9GrfP/Qqnv/wo9R/6hhB/+mXAD/plwA/6ZcAP+oYQj/48yw/////////////////8WWW/+mXAD/q2YQ/+DHqf+NTxr/gDsA/4A7AP+AOwD/roJb/9Cpef+nXgP/plwA/6ZcAP+mXAD/tHcr/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6hhCP/jzLD/////////////////xZZb/6ZcAP+mXQL/0q1//7iQbf+oeVH/qHlR/6p8VP/RtJj/uX42/6ZcAP+mXAD/plwA/6ZcAP+0dyv/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/qGEI/+PMsP/////////////////Fllv/plwA/6ZcAP+rZQ7/x5he/9Wyh//Vsof/0q1//72HRP+mXAD/plwA/6ZcAP+mXAD/plwA/7R3K//kzrP/5M6z/9/Fpf+4fjb/plwA/6ZcAP+oYAf/rmsY/69tG/+vbRv/r20b/69tG/+xcSL/5tG4/////////////////8WWW/+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/tHcr/7p8N/+6fDf/zaBu/9m6lP+oYQj/plwA/8+od//gxab/4cep/+HHqf/hx6n/4cep/+LJrP/17eT/////////////////3sOh/8uhbP/LoWz/y6Fs/8uhbP/LoWz/uoA5/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+0dyv/unw3/7p8N//Il2D/3cCe/6liCv+vbBr/38Sk/7yAPf+6fDf/unw3/7p8N/+6fDf/vIA9/+nWwf////////////n07f/bvZn/2ryX/9q8l//avJf/2ryX/9zAnf/o1b7/tXkt/6ZcAP+mXAD/tnkt/+DGp//jzbH/482x/+jVvv/AiEr/wIhK/82hb//gxqf/snIj/8GOT//auZX/unw3/7p8N/+6fDf/unw3/7p8N/+8gD3/6dbB////////////8OPU/6deBP+mXAD/plwA/6ZcAP+mXAD/plwA/9/Dov/ImmH/plwA/6hhCP/iyq3/w45S/7p8N/+6fDf/xZJZ/9e8of/XvKH/2sKq/+LRv//kz7T/2rmU/8OPVP+6fDf/unw3/7p8N/+6fDf/unw3/8WSWf/x5Nb//v79//7+/f/w5NX/qWIJ/6dfBf+nXwX/p14E/6ZcAP+mXAD/3sOi/8iaYf+mXAD/r2wa/+nWwP+6fDf/unw3/7p8N//Fkln/gDsA/4A7AP+AOwD/k1gm/9u9nf+6fDf/unw3/7p8N/+6fDf/unw3/7p8N//FkVf/7t7H/+rPof/qz6H/79u5//z69f/9+vP//frz//368//v4c//tnow/6ZcAP/TsIP/2bqU/72GQv/Ek1b/7uHR/8udav/LnWr/y51q/9Sug/+AOwD/gDsA/4A7AP+TWCb/272d/7p8N/+6fDf/unw3/7p8N/+6fDf/unw3/86jc//u2bn/4bh0/+G4dP/oypf/+/Xq//foyf/36Mj/9+jI//rx3v/Xtoz/plwA/7JzJP/cwJz/6NW+/+nXwf/u4M//6tjD/+rYw//q2MP/7d/N/4A7AP+AOwD/gDsA/5NYJv/bvZ3/unw3/7p8N/+9gkD/v4VF/7+FRf+/hkb/1a+G/+7Xtf/huHT/4bh0/+jKl//69Oj/9uS///bkvv/25L7/+OvQ/9y+mf+mXAD/plwA/6ZdAv+nXgP/p14E/6deBP+nXgT/p14E/6deBP+2ei7/gDsA/4A7AP+AOwD/m2U3/9y/oP+6fDf/zJ9t/+fSuv/r2cX/69nF/+vZxP/t28H/58eR/+G4dP/huHT/6MqX//v16//46s7/9uXA//bkvv/469D/4cen/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/6ZcAP+mXAD/plwA/7R3K//Cnn7/wp5+/8Ohgf/aw6z/yppm/7+GR//x4s7/5MCF/+K8fP/ivHz/4rx8/+K7ef/huHT/4bh0/+G4dP/oypj/+fLl//PjyP/5793/9uXB//blwv/58eP/7d3I/+nWv//p1r//0Kl4/6ljC/+mXAD/plwA/6ZcAP+mXAD/tHcr/8iXYf/Il2H/yJdh/8SPVP+6fTj/w45S//Lk0f/huHT/4bh0/+G4dP/huXb/58eT/+nMm//pzJv/6cyb//LhxP/x38D/4bl3//TlzP/36cn/9uS+//fnxf/47NL/+OzS//js0v/37+D/wY5P/6ZcAP+mXAD/plwA/6ZcAP+0dyv/unw3/7p8N/+6fDf/unw3/7p8N//Dj1T/8ePN/+G4dP/huHT/471///Pkyv/37Nr/9+zZ//fs2f/269n/8d7A/+TAhf/huHT/8+PJ//fqzf/25L7/9uS+//bkvv/25L7/9uS+//fs1f/QqXn/r20b/69tG/+vbRv/r20b/7yGQf/VsIb/1bCG/9Wwhv/VsIb/1bCG/9/Cof/s1bD/4bh0/+G4dP/s06n/9OXN/+K6eP/huHT/4bh0/+G4dP/huHT/4bh0/+G4dP/z48n/9+rN//bkvv/25L7/9uS+//bkvv/25L7/+O7Y/+fUvP/XtY3/17WN/9e1jf/XtY3/4suu//fr1v/369b/+O/f//Xp1//t1rH/6s2f/+K8fP/huHT/4bh0/+/Ztf/y4cX/471//+O9f//huHX/4bh0/+G4dP/huHT/4bh0//Pjyf/58N3/9+vS//fr0//47NP/9ubD//bkvv/37Nb/2beS/7+FRf+/hUX/v4VF/7+FRf/LnGn/9uS+//bkvv/468//8d/B/+G5dv/huHT/4bh0/+G4dP/huHT/79m1//r16//26dP/9ujR/+vRpf/huXf/4bh0/+G4dP/huHT/8+PJ/+7Wr//oyZf/6MqY/+/at//57df/9uS+//fs1f/Wson/unw3/7p8N/+6fDf/unw3/8WSWf/25MD/9uTA//js0v/x3r7/4bl2/+G4dP/huHT/4bh0/+G4dP/v2bX/+/Tl//fnx//36Mn/+O3Z/+bEjP/huHT/4bh0/+G4dP/z48n/6MiU/+G4dP/huHT/5cKI//ju2v/25L7/9+zW/9m3kf++hEP/u387/7p8N/+6fDf/xZJZ//vz4//78+P/+O7b/+nKmP/hunj/58eS/+rPof/qz6L/6s+i//Tlzf/68uH/9uS+//bkwP/4793/58eS/+G4dP/huHT/4bh0//Pjyf/oyJT/4bh0/+G4dP/lwYb/+O3Z//bkvv/57tn/8eXV/+fRtv/auJP/v4ZG/7p8N//Fkln/6MiU/+jIlP/lw4r/4bl2/+nMnP/z48j/8Ny7//Dcu//w3Lv/9+za//ry4f/25L7/9uTA//jv3f/nx5L/4bh0/+G4dP/huHT/8+PJ/+jIlP/huHT/4bh0/+XBhv/47dn/9uS+//nu2P/w3Lv/5sSN/+3Xs//RqHn/unw3/8WSWf/huHT/4bh0/+G4dP/huHT/79i0/+jIlf/huHT/4bh0/+G4dP/v2bX/+vLh//bkvv/25MD/+O/d/+fHkv/huHT/4bh0/+G4dP/z48n/6MiU/+G4dP/huHT/5cGG//jt2f/25L7/+O7X/+3Vrf/huHT/6c2e/9axhv+6fDf/xZJZ/+G4dP/huHT/4bh0/+G4dP/u2LP/58eS/+G4dP/huHT/4bh0/+/Ztf/68uH/9uS+//bkwP/4793/58eS/+G4dP/huHT/4bh0//Pjyf/oyJT/4bh0/+G4dP/lwYb/+O3Z//bkvv/47tf/7dWt/+G4dP/pzZ7/1rGG/7p8N//Fkln/4bh0/+G4dP/huHT/4bh0/+7Ys//nx5L/4bh0/+G4dP/huHT/79m1//ry4f/25L7/9uTA//jv3f/nx5L/4bh0/+G4dP/huHT/8+PJ/+jIlP/huHT/4bh0/+XBhv/47dn/9uS+//ju1//t1a3/4bh0/+nNnv/WsYb/unw3/8WSWf/mxIz/4bh0/+G4dP/huHT/7tiz/+fHkv/huHT/4bh0/+G4dP/v2bX/+vLh//bkvv/25MD/+O/d/+fHkv/huHT/4bh0/+G4dP/z48n/6MiU/+G4dP/huHT/5cGG//jt2f/25L7/+O7X/+3Vrf/huHT/6c2e/9axhv+6fTr/1K6E/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.eki.ee/dict/soovita.cgi">
- <Param name="D" value="qs"/>
- <Param name="Q" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="http://www.eki.ee/dict/qs/index.cgi" resultdomain="eki.ee">
- <Param name="F" value="M"/>
- <Param name="Q" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.eki.ee/dict/qs/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/elebila.xml b/browser/locales/searchplugins/elebila.xml
deleted file mode 100644
index e75d951dd..000000000
--- a/browser/locales/searchplugins/elebila.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Elebila</ShortName>
- <Description>Euskarazko bilatzailea.</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image height="16" width="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AezWtAHs1rQR7Na0BezWtAHs1rQB6NKwAhTq4O6tN46ajSdqdezWtCHs1rQB7Na0AezWtAHs1rQD///8A////AHs1rQB7Na0CeTSrAHo1rAB7Na0AeTSqAKpM4dqoTODTlEHJl3w1rgl6NawAeTSrAHs1rAB7Na0A////AP///wB6NKwAezWtD4Y6uT+AOLMzejSrAXo0qwCrTuPsgzm1UXcypwB4NKoAfzexJoY7uj99Nq8hejWsAP///wD///8AfzeyLKxO5Oa2Tu/9skzr9ZpE0LN3M6gCqk3i6IU6uFh3M6kAjD3AZ7RR7f+0TO73sEzp9Io8vmv///8A////AJlDz7WjTte4UUt7Rk9Re3h1OaUrejOsAKpN4umFOrhVdzOoAa1M5vuFSbRnSFBzbltJiGF7Nq0X////AP///wCaRM+1oEjWwmxfoN9wbqb/dD6kWnszrQSqTeLohTq4VXczqQGsTOTxiEe6p21upP9vYKLiejaqLP///wD///8AmEPNsrJQ6+KkRNuypUTbrrdS8P+EOrdFqEzg34U6uFV3M6gBq03j86pL4sikQtutq0nhx61O5dj///8A////AJZCzKmpTOHOfzexNYU7uEq0U+3/hDm3RqhM4N+FOrhWdzOoAapN4vOWQ8yDfjawNJRDyIiuT+fd////AP///wB8Nq4YoEjXt6tN492qTeLYkD/Ee3czqACqTeHnhTq4WHgzqQCFOrhHqUzh0atN492mSt3KhDq4RP///wD///8AejWsAHgzqQB5NKsAeDSqAHgzqQCBOLMmsFDo8YU6uFt6NKsAeTSrAHgzqQB5NKsAeDOpAHk0qwD///8A////AHs1rQB7Na0AezWtAHs1rQB5NKoAnEXRuqtN4+x+N7EyejSsAHs1rQB7Na0AezWtAHs1rQB7Na0A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAD//wAAzh8AAN4fAADCYwAAgEEAAIIBAACAAQAAgAEAAIABAACCQQAA/H8AAPx/AAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AezWtAHs1rQB7Na0EezWtCHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AeDOpBIs9v4+mSt3vp0ve76lM4fiRQMageTSqAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAP///wD///8A////AP///wB7Na0AezWtAHs1rQh7Na0SezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHg0qgCRQMagvlb4/79X+v+6VfT/vVf4/6VK3O13M6kRezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0A////AP///wD///8A////AHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AdzOpEahM4O7CWf3/l0PNwXw1rkx/N7JZfjawPXs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQD///8A////AP///wD///8AezWtAHs1rQB7Na0AezWtAHo0rAB6NKwAejSsAHs1rQB7Na0AezWtAHs1rQB3M6kRp0ve7rtV9f9/N7JbeTOqAHo0rAB6NKwAezWtAHs1rQB7Na0AejSsAHo0rAB6NKwAezWtAHs1rQB7Na0AezWtAP///wD///8A////AP///wB7Na0AezWtAHgzqgB5NKwnfzeyWX83slZ8Nq9RdjOoFHczqQB6NawAezWtAHczqRGnS97uulT0/383slV6NKwAezWtAHs1rQB7Na0AeTSrAHczqRB+N7FRfzeyVn43sVl4M6opdzOpAnk0qwB7Na0A////AP///wD///8A////AHo0rAB4M6kEij2+jqxN4/W5VPP/uVPy/7NR6/+kStvskUDGrX42sCh6NawAdzOpEadL3u66VfT/fzeyVXo0rAB7Na0AezWtAHg0qgCAOLNVoUjY4bhT8f+5U/L/t1Lw/6lM4feYRM7Igzm2V3o0rAD///8A////AP///wD///8AeTSrHZA/xaC/V/n/v1b6/7dS8f+5U/P/ulP0/75W+P/EWv//jj/DnngzqQB3M6kRp0ve7rpV9P9/N7JVejSsAHs1rQB5NKsAgTi0WbRR7P7CWP3/uFLy/7hT8v+5U/P/vFX2/8Vb//+lStzkdzOpDf///wD///8A////AP///wCLPb+OtFLt/71U+P+XU8a8gj6zVHk1qUZ2NaVBhjm6bZQ/ya5+N7ApejWsAHczqRGnS97uulX0/383slV6NKwAezWtAHczqQegR9fXwlj9/6VS2eKGSLNtfDSuRnY1pUR+N69QlT7LrYU6uFx6NKwA////AP///wD///8A////AJFAxqq7VfX/qEjh8HZFoBRLSW8ANFlcfTViXqBDRWkeajaYAHs0rQB7Na0AdzOpEadL3u66VfT/fzeyVXo0rAB7Na0AdzOpEahM4O67VPX/gT6yW11NgQA1T1pMN2VhrTlQXkxfOIoAdzWpAHw1rgD///8A////AP///wD///8AkEDFqrpV9P+pSeHuXzKMBCddTIREln7/SJuF/y91W9E8QV8HeTWrAHw1rgB3M6kRp0ve7rpV9P9/N7JVejSsAHs1rQB3M6kRp0ve7rtU9f96NKxKL0hSLjqKbv5JnIb/O4lv/itMTDxrN5oAfjSwAP///wD///8A////AP///wCQQMWquVTz/65P5vmPPcOrgk614YFguP+BX7n/gFi1/ok8vJh9NbA3ejWsAHgzqRGnS97uulX0/383slV6NKwAezWtAHczqRGmS97uvFX2/5VAysKGRLnCf162/4Ffuf9/X7b/h0S6woI2tVJ6NKwJ////AP///wD///8A////AJBAxaq2U/D/vlf5/8JZ/v/FVv//xVP//8VT///GVf//wFf6/65O5v59Nq84dzOoB6dL3u66VfT/fzeyVXo0rAB7Na0AdzOpEaZK3e6/V/r/wVn8/8RY/v/FU///xVP//8ZT///DV/3/uFTy/4o9von///8A////AP///wD///8AkEDFqrhU8v+zUez5kEDFrpBAxamQQMWqkEDFqY9Bw66yU+n5ulX0/4A3slB2M6gDp0ve7rpV9P9/N7JVejSsAHs1rQB3M6kRpkve7r5W+P+YRM7Fjz/DpZBAxaqQQMWqjT/CpaNM2OHCWf3/kUDGqv///wD///8A////AP///wCRQMaqu1X1/6tN4+5zMaQSdTOnAHYzqAB2MqkAazWVEqFP0+68Vff/gDeyUHYzqAOnS97uulX0/383slV6NKwAezWtAHczqRGoS9/uvVb3/383slZzMaQAdjOoAHYzqQBuMpwAhkWxq8NZ//+RQMaq////AP///wD///8A////AIs9v460Ue3/v1f5/5hEzrx+N7FXfjexUn83sleXQ828vVf3/7RR7f99Nq86dzOoBqdL3u66VfT/fzeyVXo0rAB7Na0AdzOpB6BH1tfDWf7/p0vf4oI5tm1+NrFQfjawT4s9v5GyUev5wFj7/4s9v47///8A////AP///wD///8AeTSrHZA/xaC+Vvj/wln9/7tV9f+6VfT/u1X1/8JZ/f+8VfX/kD/FoHgzqQB4M6kQp0ve7rpV9P9/N7JVejSsAHs1rQB5NKsAgTi0WbNR7P7DWf7/vVb3/7pV8/+6VfP/wFj7/8FY+/+iSNjceTSrHf///wD///8A////AP///wB6NKwAeDOqBog8vIagR9bdqEvf8qdL3u6oS9/ymETOx4M5tmp4M6oGezWtAHczqRGnS97uulX0/383slV6NKwAezWtAHs1rQB4NKoAgTi0VplEzsmoS9/yp0ve7qhM3/KgR9bciT2+j3k0qx16NawA////AP///wD///8A////AHs1rQB7Na0AeDOqAHczqQt3M6kSdzOpEXczqRJ3M6kGeTSrAHs1rQB7Na0AdjKoEaZK3e66VfT/fzeyVXo0rAB7Na0AezWtAHs1rQB5NKsAdzOpBnczqRJ3M6kRdzOpEnczqQt4M6oAezWtAHs1rQD///8A////AP///wD///8AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rR9+N7FlrU7l87lU8/9/N7JVejSsAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAP///wD///8A////AP///wB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB3M6kJn0fW2r5X+f/BWPv/ulX0/4A3slV6NKwAezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0A////AP///wD///8A////AHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHk0qgCSQMekqUzh+KhL3/OdRtPWezWtHns1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQB7Na0AezWtAHs1rQD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//////////////////////////8/wP//P8B///+A////h///g4fA/gCHgHwAhwA8AIYAfCOGEfwBhgD8AIYAPAAGADwABgA8OAYePAAGADwAhwA+AIeAf4OHwf//B////gf///8H//////////////////////////////////</Image>
- <Url type="text/html" template="http://elebila.elhuyar.eus/search/" resultdomain="elhuyar.eus">
- <Param name="opensearch" value="on" />
- <Param name="lang" value="eu" />
- <Param name="bilatu" value="{searchTerms}" />
- </Url>
- <SearchForm>http://elebila.elhuyar.eus</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/eudict.xml b/browser/locales/searchplugins/eudict.xml
deleted file mode 100644
index f760fa3a4..000000000
--- a/browser/locales/searchplugins/eudict.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>EUdict Eng->Cro</ShortName>
-<Description>EUdict - englesko-hrvatski rjeÄnik</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/gif;base64,R0lGODlhEAAQAKIAAH6CuJufvmJwrtze4vb4%2BLwxMcZmZtG7uyH5BAAAAAAALAAAAAAQABAAAANvSHTMs0dBZWoNpMpiyLhBMBycMhTYUT0KiS3oYnVZXEczQBXRnRkBhoLDIp4MrGHhQUI2LQ8DRxpTzZhUYNIjOAwALJbIAyiPMAOBYBBQfwPmUDrIFoQABwBG35bACXAAdmlseBFmeXBeOml2C2sJADs%3D</Image>
-<Url type="text/html" method="GET" template="http://www.eudict.com/indexHr.php" resultdomain="eudict.com">
- <Param name="lang" value="engcro"/>
- <Param name="word" value="{searchTerms}"/>
- <Param name="client" value="firefox"/>
-</Url>
-<SearchForm>http://www.eudict.com/indexHr.php</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/faclair-beag.xml b/browser/locales/searchplugins/faclair-beag.xml
deleted file mode 100644
index d13b97535..000000000
--- a/browser/locales/searchplugins/faclair-beag.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Am Faclair Beag</ShortName>
-<Description>Lorg Am Faclair Beag</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,%2F9j%2F4AAQSkZJRgABAQAAAQABAAD%2F%2FgA8Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gMTAwCv%2FbAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf%2FbAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf%2FAABEIABAAEAMBIgACEQEDEQH%2FxAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv%2FxAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5%2Bjp6vHy8%2FT19vf4%2Bfr%2FxAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv%2FxAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4%2BTl5ufo6ery8%2FT19vf4%2Bfr%2F2gAMAwEAAhEDEQA%2FAPyc8bfsbaf8dPAPxs%2BKP%2FBQHwJ%2B3T8ff%2BCl37W%2F7Knhz9t34WftIaHpy6X8BfD%2FAIi8e3Fpp3wz%2BEPi67m0Kx%2BHng7wd4V8BSaB4o%2BJnijxVrHgX4U%2FBf4W%2BG774W%2BBdN%2BH8fw90CbxX8TfAH4QfFX9ivwtqH7ZH7G3hT9pv9o39o%2F4A3Op6y%2F7W37PvgTx1H%2BxN%2By1d2NnqeleMrpPiHaeGrg%2FtM6pp%2BgSa3ovjCHWF8Lfs2SaHfa1Y%2BJtP%2FaA%2BF%2BqXsOrdt%2B0l%2B0L8ff2SPAOmfsW%2Ft8%2FF%2F8AaZ%2FaN%2BOnwITQvD7fsJfEnxb4u8N%2FsifAUaLZaRqnw%2FtfjFqOna7Za7%2B1TJY%2BG20DXvAvh%2FwLeaX8GofDt54a1rwx8ZPiN4N1Cbw%2Fefavgz9sy4%2BLPwo%2BD%2FwU%2FwCCe%2F7SP7Yv7Tf7cP7aX7IOsfsXePP2BU8L6n4K%2FZ3%2BEHxK%2BIVx%2Fa3xW%2BMPgrT0v%2FC%2F7Pvw8%2BH%2FAIJ%2BHh8VeEPh54d%2BGPgnw74N%2BG%2FgPSrr4yfE3x%2F4HtdB8Y2%2FiYA%2F%2F9k%3D</Image>
-<Url type="text/html" method="GET" template="http://www.faclair.com/" resultdomain="faclair.com">
-<Param name="txtSearch" value="{searchTerms}"/>
-</Url>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/findbook-zh-TW.xml b/browser/locales/searchplugins/findbook-zh-TW.xml
deleted file mode 100644
index 17821a445..000000000
--- a/browser/locales/searchplugins/findbook-zh-TW.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Findbook</ShortName>
-<Description>Findbook 書ç±æœå°‹</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAArHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/7a2tv8AAAAArHEA/LZ3AP/LhgT/1YwF/9SMBP/UjAT/1IwE/9SMBP/UjAT/1IwE/9SMBf/UjAX/1IwF/6xxAP+2trb/ypMqDqxxAP+2eAD/y4YC/9OMBf/QgQD/9uvV////////////uXAA/9WMBP/UjAX/1IwF/9SMBf+scQD/tra2/61zAuKscQD/tngA/8uGAv/UjAX/z4EA//Xmyv///////////7pwAP/VjAT/1IwF/9SMBf/UjAX/rHEA/7a2tv+scQD/rHEA/7Z4AP/LhgT/1IwF/8+BAP/15sr///////////+6cAD/1YwE/9SMBf/UjAX/1IwF/6xxAP+2trb/rHEA/6xxAP+2eAD/y4YC/9OMBf/QgQD/9ebK////////////tGQA/9GCAP/PgAD/0YQA/9SMBf+scQD/tra2/6xxAP+scQD/tngA/8uGBP/UjAX/z4EA//Xmyv/////////////////////////////////QggD/rHEA/7a2tv+scQD/rHEA/7Z4AP/LhgL/1IwF/9CBAP/15sr///////////+5hCL/yJg5/8iYO//BjjD/04kA/6xxAP+2trb/rHEA/6xxAP+2eAD/y4YE/9SMBf/OgQD/9ebK////////////um0A/9aKAP/UiQD/1YoA/9SLA/+scQD/tra2/6xxAP+scQD/tngA/8uGBP/UjAX/0IEA//Xmyf///////////7pwAP/VjAT/1IwF/9SLA//Tiwb/rHEA/7a2tv+scQD/rHEA/7Z4AP/LhgL/1IwE/859AP/15sr///////////+1ZwD/04YA/9GEAP/RgAD/zKVa/6xxAP+2trb/rHEA/6xxAP+2eAD/y4YB/9WMBf////////////////////////////////////////////////+scQD/tra2/6xxAP+scQD/tXUA/8uDAP/SkRj/yJc5/8iXOf/Ilzn/yJc5/8iWN//Ilzn/x5c5/8iXOf/Ilzn/rHEA/7a2tv+scQD/rHEA/7B2CP+scQD/rHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/61xAP+2trb/rHEA/6xyAfvp+///6PD//+z2///w+///9f////v//////////////////////////////////////////////6xxAP8AAAAArncM8axxAP+scQD/rHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/6xxAP+scQD/rHEA/691B/mtcwPugAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA%3D%3D</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://findbook.tw/search/suggest?q={searchTerms}&amp;utm_source=ff-bundled&amp;utm_medium=mozsearch&amp;utm_campaign=search" />
-<Url type="text/html" method="GET" template="http://findbook.tw/search" resultdomain="findbook.tw">
- <Param name="q" value="{searchTerms}"/>
- <Param name="utm_source" value="ff-bundled"/>
- <Param name="utm_medium" value="mozsearch"/>
- <Param name="utm_campaign" value="search"/>
-</Url>
-<SearchForm>http://findbook.tw/search</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/flip.xml b/browser/locales/searchplugins/flip.xml
deleted file mode 100644
index b8c0cdb0c..000000000
--- a/browser/locales/searchplugins/flip.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>flip.kz</ShortName>
-<LongName>flip.kz көмегімен іздеÑтіру</LongName>
-<Description>ҚазақÑтандық интернет-дүкенде іздеу</Description>
-<InputEncoding>utf-8</InputEncoding>
-<Image height="16" width="16" type="image/png">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAABGdBTUEAAK%2FINwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADoSURBVHjaYkxY%2BpiNgYGhDogTgFiagTjwFIgXAHETC5BoBOIKBtIAyKJqIGZmAhLJDOSDZJALRNFFO30lGMR4WbDqKNv0guH1lz8wrigTugIHVW6cmrEBDJVcrKhmrr7wEYX%2F7dc%2F%2FAagg23XPpPmAnQwP0oGzr724idD977XqAaAAuTS0x8M7779BQvICrAyhBrwYzXs5ec%2FDKvPQ7wkxMXMoCfNwcBy4sE3hh%2B%2F%2F%2BN0Qd22l3D2h%2B9%2F4WyQhSC9LPg0g0Df%2Fjc45UB6mRgoBBQbgBEL5598R%2FE3IcDIXXLl%2F4B6ASDAAE8uSkx9GD%2FfAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" template="http://www.flip.kz/ajax/search_keyword.php">
- <Param name="q" value="{searchTerms}"/>
- <Param name="type" value="os"/>
-</Url>
-<Url type="text/html" method="get" template="http://www.flip.kz/search" resultdomain="flip.kz">
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://flip.kz/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/freelang.xml b/browser/locales/searchplugins/freelang.xml
deleted file mode 100644
index 017dfeb0b..000000000
--- a/browser/locales/searchplugins/freelang.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Freelang (br)</ShortName>
-<Description>Geriadur Freelang</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAD5+vYAQxGlAHp1DQDMzJoAnp4+AIWEDADc3b0AgH8CAJmZNADS06gAe3oAAJ6ePwCCgQUAfn0AALGxZAB/fQAAgIAAAIGAAABcP14AtrZvAIKDAACGhQsAuLhyAIqKFgDS0acAx8eSAP7+/gB7dg0AeHETALOzaACtrFsAc2ofAMLCiABPJ4MAi4oXAHh4AAB5eAAA+vv3AIGAAgB6eAAAubp2AFw/YABMIYwA9PTqAHx7AACNjBoAmJgyAH9+AABgRlUAgIEAAOjo0wCBgQAApKRKAIGAAwD7+/gAurp3AIKEAAC3t28Ag4QAAPT06wCXljAAzc2cAEUWnAB0ax4AqalVALu8egCjokgAjo4eAKurWACIhxEAhYQJALCwYwDq6tcA4+PKAJ+fQQCgn0EA+fn3AG5gLgB/fgIAyMiTAHp5AAD///8AiosPALe3cQCQkCIAfXwAAEMRpAB/fwAAgH8AAIF/AACBggAAi4sYAIKCAACPjiAA4eLGAJ2ePQChoUUA0NGkAHZtGwDJypcAh4YOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERERERERERERLwc8LBEREREREREREREREFhYWzdVERFYJg0RERERERERES8ZNFgRWEVHClgQERERERFYYExQEVkRLWM1LxFYERFYL1NRVBERWBFYYU9DJCwsJEIaURURERFZWCdbCQAySSVRURMvERFZVUBeK0gDKEQWHmQvEREREUtRBgguBB0YXw0RWREREVg5OyNYIFFdCgsOVRERERERWzIsEQU2PS9YRkpXWBEREQ9BIhERDBcRERFSWBERERERVQtcFBERWBEzEhwRERERERFYMCpaEVkRTjEQWRERERERET8+Hyk4TT8hXBEREREREVgROgJWGwFiOlgREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Image>
-<Url type="text/html" method="POST" template="http://www.freelang.com/enligne/breton.php?lg=fr" resultdomain="freelang.com">
- <Param name="dico" value="fr_bre_fra"/>
- <Param name="mot1" value="{searchTerms}"/>
- <Param name="mot2" value=""/>
- <Param name="entier" value="on"/>
-</Url>
-
-<SearchForm>http://www.freelang.com/enligne/breton.php</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/google-nocodes.xml b/browser/locales/searchplugins/google-nocodes.xml
deleted file mode 100644
index f7583b99d..000000000
--- a/browser/locales/searchplugins/google-nocodes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Google</ShortName>
-<Description>Google Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD9/f2W/f392P39/fn9/f35/f391/39/ZT+/v4uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Cf39/Zn///////////////////////////////////////////39/ZX///8IAAAAAAAAAAAAAAAA/v7+Cf39/cH/////+v35/7TZp/92ul3/WKs6/1iqOv9yuFn/rNWd//j79v///////f39v////wgAAAAAAAAAAP39/Zn/////7PXp/3G3WP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP+Or1j//vDo///////9/f2VAAAAAP///zD/////+vz5/3G3V/9TqDT/WKo6/6LQkf/U6cz/1urO/6rUm/+Zo0r/8IZB//adZ////v7///////7+/i79/f2Y/////4nWzf9Lqkj/Vqo4/9Xqzv///////////////////////ebY//SHRv/0hUL//NjD///////9/f2U/f392v////8sxPH/Ebzt/43RsP/////////////////////////////////4roL/9IVC//i1jf///////f391/39/fr/////Cr37/wW8+/+16/7/////////////////9IVC//SFQv/0hUL/9IVC//SFQv/3pnX///////39/fn9/f36/////wu++/8FvPv/tuz+//////////////////SFQv/0hUL/9IVC//SFQv/0hUL/96p7///////9/f35/f392/////81yfz/CrL5/2uk9v///////////////////////////////////////////////////////f392P39/Zn/////ks/7/zdS7P84Rur/0NT6///////////////////////9/f////////////////////////39/Zb+/v4y//////n5/v9WYu3/NUPq/ztJ6/+VnPT/z9L6/9HU+v+WnfT/Ul7t/+Hj/P////////////////////8wAAAAAP39/Z3/////6Or9/1hj7v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9sdvD////////////9/f2YAAAAAAAAAAD///8K/f39w//////5+f7/paz2/11p7v88Suv/Okfq/1pm7v+iqfX/+fn+///////9/f3B/v7+CQAAAAAAAAAAAAAAAP///wr9/f2d///////////////////////////////////////////9/f2Z/v7+CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f2Z/f392/39/fr9/f36/f392v39/Zj///8wAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/g3+/v5X/f39mf39/cj9/f3q/f39+f39/fn9/f3q/f39yP39/Zn+/v5W////DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f2c/f399f/////////////////////////////////////////////////////9/f31/f39mv7+/iMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/gn9/f2K/f39+////////////////////////////////////////////////////////////////////////////f39+v39/Yf///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4k/f390v////////////////////////////////////////////////////////////////////////////////////////////////39/dD///8iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////MP39/er//////////////////////////+r05v+v16H/gsBs/2WxSf9Wqjj/Vqk3/2OwRv99vWX/pdKV/97u2P////////////////////////////39/ej+/v4vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f3q/////////////////////+v15/+Pxnv/VKk2/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/36+Z//d7tf///////////////////////39/ej///8iAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K/f390//////////////////////E4bn/XKw+/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1apN/+x0pv///////////////////////39/dD///8IAAAAAAAAAAAAAAAAAAAAAP39/Yv/////////////////////sdij/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/YKU1/8qOPv/5wZ////////////////////////39/YcAAAAAAAAAAAAAAAD+/v4l/f39+////////////////8Lgt/9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9utlT/n86N/7faqv+426v/pdKV/3u8ZP9UqDX/U6g0/3egN//jiUH/9IVC//SFQv/82MP//////////////////f39+v7+/iMAAAAAAAAAAP39/Z3////////////////q9Ob/W6w+/1OoNP9TqDT/U6g0/1OoNP9nskz/zOXC/////////////////////////////////+Dv2v+osWP/8YVC//SFQv/0hUL/9IVC//WQVP/++fb//////////////////f39mgAAAAD+/v4O/f399v///////////////4LHj/9TqDT/U6g0/1OoNP9TqDT/dblc//L58P/////////////////////////////////////////////8+v/3p3f/9IVC//SFQv/0hUL/9IVC//rIqf/////////////////9/f31////DP7+/ln////////////////f9v7/Cbz2/zOwhv9TqDT/U6g0/2KwRv/v9+z///////////////////////////////////////////////////////738//1kFT/9IVC//SFQv/0hUL/9plg///////////////////////+/v5W/f39nP///////////////4jf/f8FvPv/Bbz7/yG1s/9QqDz/vN2w//////////////////////////////////////////////////////////////////rHqP/0hUL/9IVC//SFQv/0hUL//vDn//////////////////39/Zn9/f3L////////////////R878/wW8+/8FvPv/Bbz7/y7C5P/7/fr//////////////////////////////////////////////////////////////////ere//SFQv/0hUL/9IVC//SFQv/718H//////////////////f39yP39/ez///////////////8cwvv/Bbz7/wW8+/8FvPv/WNL8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rIqv/////////////////9/f3q/f39+v///////////////we9+/8FvPv/Bbz7/wW8+/993P3///////////////////////////////////////SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+cGf//////////////////39/fn9/f36////////////////B737/wW8+/8FvPv/Bbz7/33c/f//////////////////////////////////////9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6xaX//////////////////f39+f39/e3///////////////8cwvv/Bbz7/wW8+/8FvPv/WdP8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vVv//////////////////9/f3q/f39y////////////////0bN/P8FvPv/Bbz7/wW8+/8hrvn/+/v///////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/cj9/f2c////////////////ht/9/wW8+/8FvPv/FZP1/zRJ6/+zuPf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////f39mf7+/lr////////////////d9v7/B7n7/yB38f81Q+r/NUPq/0hV7P/u8P3////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v5X////D/39/ff///////////////9tkPT/NUPq/zVD6v81Q+r/NUPq/2Fs7//y8v7////////////////////////////////////////////09f7//////////////////////////////////////////////////f399f7+/g0AAAAA/f39n////////////////+Tm/P89Suv/NUPq/zVD6v81Q+r/NUPq/1Bc7f/IzPn/////////////////////////////////x8v5/0xY7P+MlPP////////////////////////////////////////////9/f2cAAAAAAAAAAD+/v4n/f39/P///////////////7W69/81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9ZZe7/k5v0/6609/+vtff/lJv0/1pm7v81Q+r/NUPq/zVD6v+GjvL//v7//////////////////////////////f39+/7+/iQAAAAAAAAAAAAAAAD9/f2N/////////////////////6Cn9f81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v+BivL////////////////////////////9/f2KAAAAAAAAAAAAAAAAAAAAAP7+/gv9/f3V/////////////////////7W69/8+S+v/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/P0zr/7q/+P///////////////////////f390v7+/gkAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3r/////////////////////+Xn/P94gfH/NkTq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NkTq/3Z/8f/l5/z///////////////////////39/er+/v4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f3r///////////////////////////k5vz/nqX1/2p08P9IVez/OEbq/zdF6v9GU+z/aHLv/5qh9f/i5Pz////////////////////////////9/f3q////MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3V/////////////////////////////////////////////////////////////////////////////////////////////////f390v7+/iQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr9/f2N/f39/P///////////////////////////////////////////////////////////////////////////f39+/39/Yv+/v4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4n/f39n/39/ff//////////////////////////////////////////////////////f399v39/Z3+/v4lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Dv7+/lr9/f2c/f39y/39/e39/f36/f39+v39/ez9/f3L/f39nP7+/ln+/v4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=firefox&amp;q={searchTerms}"/>
-<Url type="text/html" method="GET" template="https://www.google.com/search" rel="searchform">
- <Param name="q" value="{searchTerms}"/>
- <Param name="ie" value="utf-8"/>
- <Param name="oe" value="utf-8"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/google.xml b/browser/locales/searchplugins/google.xml
deleted file mode 100644
index 0642d56f9..000000000
--- a/browser/locales/searchplugins/google.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Google</ShortName>
-<Description>Google Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD9/f2W/f392P39/fn9/f35/f391/39/ZT+/v4uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Cf39/Zn///////////////////////////////////////////39/ZX///8IAAAAAAAAAAAAAAAA/v7+Cf39/cH/////+v35/7TZp/92ul3/WKs6/1iqOv9yuFn/rNWd//j79v///////f39v////wgAAAAAAAAAAP39/Zn/////7PXp/3G3WP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP+Or1j//vDo///////9/f2VAAAAAP///zD/////+vz5/3G3V/9TqDT/WKo6/6LQkf/U6cz/1urO/6rUm/+Zo0r/8IZB//adZ////v7///////7+/i79/f2Y/////4nWzf9Lqkj/Vqo4/9Xqzv///////////////////////ebY//SHRv/0hUL//NjD///////9/f2U/f392v////8sxPH/Ebzt/43RsP/////////////////////////////////4roL/9IVC//i1jf///////f391/39/fr/////Cr37/wW8+/+16/7/////////////////9IVC//SFQv/0hUL/9IVC//SFQv/3pnX///////39/fn9/f36/////wu++/8FvPv/tuz+//////////////////SFQv/0hUL/9IVC//SFQv/0hUL/96p7///////9/f35/f392/////81yfz/CrL5/2uk9v///////////////////////////////////////////////////////f392P39/Zn/////ks/7/zdS7P84Rur/0NT6///////////////////////9/f////////////////////////39/Zb+/v4y//////n5/v9WYu3/NUPq/ztJ6/+VnPT/z9L6/9HU+v+WnfT/Ul7t/+Hj/P////////////////////8wAAAAAP39/Z3/////6Or9/1hj7v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9sdvD////////////9/f2YAAAAAAAAAAD///8K/f39w//////5+f7/paz2/11p7v88Suv/Okfq/1pm7v+iqfX/+fn+///////9/f3B/v7+CQAAAAAAAAAAAAAAAP///wr9/f2d///////////////////////////////////////////9/f2Z/v7+CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f2Z/f392/39/fr9/f36/f392v39/Zj///8wAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/g3+/v5X/f39mf39/cj9/f3q/f39+f39/fn9/f3q/f39yP39/Zn+/v5W////DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f2c/f399f/////////////////////////////////////////////////////9/f31/f39mv7+/iMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/gn9/f2K/f39+////////////////////////////////////////////////////////////////////////////f39+v39/Yf///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4k/f390v////////////////////////////////////////////////////////////////////////////////////////////////39/dD///8iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////MP39/er//////////////////////////+r05v+v16H/gsBs/2WxSf9Wqjj/Vqk3/2OwRv99vWX/pdKV/97u2P////////////////////////////39/ej+/v4vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f3q/////////////////////+v15/+Pxnv/VKk2/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/36+Z//d7tf///////////////////////39/ej///8iAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K/f390//////////////////////E4bn/XKw+/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1apN/+x0pv///////////////////////39/dD///8IAAAAAAAAAAAAAAAAAAAAAP39/Yv/////////////////////sdij/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/YKU1/8qOPv/5wZ////////////////////////39/YcAAAAAAAAAAAAAAAD+/v4l/f39+////////////////8Lgt/9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9utlT/n86N/7faqv+426v/pdKV/3u8ZP9UqDX/U6g0/3egN//jiUH/9IVC//SFQv/82MP//////////////////f39+v7+/iMAAAAAAAAAAP39/Z3////////////////q9Ob/W6w+/1OoNP9TqDT/U6g0/1OoNP9nskz/zOXC/////////////////////////////////+Dv2v+osWP/8YVC//SFQv/0hUL/9IVC//WQVP/++fb//////////////////f39mgAAAAD+/v4O/f399v///////////////4LHj/9TqDT/U6g0/1OoNP9TqDT/dblc//L58P/////////////////////////////////////////////8+v/3p3f/9IVC//SFQv/0hUL/9IVC//rIqf/////////////////9/f31////DP7+/ln////////////////f9v7/Cbz2/zOwhv9TqDT/U6g0/2KwRv/v9+z///////////////////////////////////////////////////////738//1kFT/9IVC//SFQv/0hUL/9plg///////////////////////+/v5W/f39nP///////////////4jf/f8FvPv/Bbz7/yG1s/9QqDz/vN2w//////////////////////////////////////////////////////////////////rHqP/0hUL/9IVC//SFQv/0hUL//vDn//////////////////39/Zn9/f3L////////////////R878/wW8+/8FvPv/Bbz7/y7C5P/7/fr//////////////////////////////////////////////////////////////////ere//SFQv/0hUL/9IVC//SFQv/718H//////////////////f39yP39/ez///////////////8cwvv/Bbz7/wW8+/8FvPv/WNL8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rIqv/////////////////9/f3q/f39+v///////////////we9+/8FvPv/Bbz7/wW8+/993P3///////////////////////////////////////SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+cGf//////////////////39/fn9/f36////////////////B737/wW8+/8FvPv/Bbz7/33c/f//////////////////////////////////////9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6xaX//////////////////f39+f39/e3///////////////8cwvv/Bbz7/wW8+/8FvPv/WdP8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vVv//////////////////9/f3q/f39y////////////////0bN/P8FvPv/Bbz7/wW8+/8hrvn/+/v///////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/cj9/f2c////////////////ht/9/wW8+/8FvPv/FZP1/zRJ6/+zuPf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////f39mf7+/lr////////////////d9v7/B7n7/yB38f81Q+r/NUPq/0hV7P/u8P3////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v5X////D/39/ff///////////////9tkPT/NUPq/zVD6v81Q+r/NUPq/2Fs7//y8v7////////////////////////////////////////////09f7//////////////////////////////////////////////////f399f7+/g0AAAAA/f39n////////////////+Tm/P89Suv/NUPq/zVD6v81Q+r/NUPq/1Bc7f/IzPn/////////////////////////////////x8v5/0xY7P+MlPP////////////////////////////////////////////9/f2cAAAAAAAAAAD+/v4n/f39/P///////////////7W69/81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9ZZe7/k5v0/6609/+vtff/lJv0/1pm7v81Q+r/NUPq/zVD6v+GjvL//v7//////////////////////////////f39+/7+/iQAAAAAAAAAAAAAAAD9/f2N/////////////////////6Cn9f81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v+BivL////////////////////////////9/f2KAAAAAAAAAAAAAAAAAAAAAP7+/gv9/f3V/////////////////////7W69/8+S+v/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/P0zr/7q/+P///////////////////////f390v7+/gkAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3r/////////////////////+Xn/P94gfH/NkTq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NkTq/3Z/8f/l5/z///////////////////////39/er+/v4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f3r///////////////////////////k5vz/nqX1/2p08P9IVez/OEbq/zdF6v9GU+z/aHLv/5qh9f/i5Pz////////////////////////////9/f3q////MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3V/////////////////////////////////////////////////////////////////////////////////////////////////f390v7+/iQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr9/f2N/f39/P///////////////////////////////////////////////////////////////////////////f39+/39/Yv+/v4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4n/f39n/39/ff//////////////////////////////////////////////////////f399v39/Z3+/v4lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Dv7+/lr9/f2c/f39y/39/e39/f36/f39+v39/ez9/f3L/f39nP7+/ln+/v4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=firefox&amp;q={searchTerms}"/>
-<Url type="text/html" method="GET" template="https://www.google.com/search" rel="searchform">
- <Param name="q" value="{searchTerms}"/>
- <Param name="ie" value="utf-8"/>
- <Param name="oe" value="utf-8"/>
- <MozParam name="client" condition="purpose" purpose="keyword" value="firefox-b-ab"/>
- <MozParam name="client" condition="purpose" purpose="searchbar" value="firefox-b"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/gujaratilexicon.xml b/browser/locales/searchplugins/gujaratilexicon.xml
deleted file mode 100644
index cda0d9268..000000000
--- a/browser/locales/searchplugins/gujaratilexicon.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>GujaratiLexicon.com</ShortName>
-<Description>English - Gujarati dictionary on www.gujaratilexicon.com</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAA4ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2FyI4ov%2F%2FOKL%2Fqjii%2FxEAAAAAAAAAADii%2FxE4ov93OKL%2FiDii%2F0QAAAAAAAAAAAAAAAAAAAAAOKL%2F%2Fzii%2F%2F8AAAAAOKL%2FiDii%2F%2F84ov%2F%2FOKL%2FmTii%2F6o4ov%2FdOKL%2Fqjii%2F%2F84ov%2FMAAAAAAAAAAAAAAAAAAAAADii%2F%2F84ov%2F%2FAAAAAAAAAAA4ov93OKL%2FzDii%2F%2F84ov%2BqOKL%2FEQAAAAA4ov%2BZOKL%2FzAAAAAA4ov9EAAAAAAAAAAA4ov%2F%2FOKL%2F%2FwAAAAAAAAAAAAAAADii%2F7s4ov%2FuOKL%2F%2Fzii%2F8w4ov9mOKL%2F7jii%2F3c4ov%2FuOKL%2FzAAAAAAAAAAAOKL%2F%2Fzii%2F%2F8AAAAAAAAAADii%2F1U4ov%2F%2FOKL%2FZjii%2F1U4ov%2FMOKL%2F%2Fzii%2F%2B44ov8ROKL%2F%2Fzii%2F8wAAAAAAAAAADii%2F%2F84ov%2F%2FAAAAAAAAAAAAAAAAOKL%2FmTii%2F%2F84ov%2B7OKL%2F%2Fzii%2F8w4ov8RAAAAADii%2F%2F84ov%2FMAAAAAAAAAAA4ov%2F%2FOKL%2F%2FwAAAAAAAAAAAAAAADii%2F7s4ov%2FdAAAAADii%2F3c4ov%2F%2FOKL%2FiAAAAAA4ov%2F%2FOKL%2FzAAAAAAAAAAAOKL%2F%2Fzii%2F%2F8AAAAAAAAAAAAAAAA4ov%2BqOKL%2F%2Fzii%2F7s4ov%2BIOKL%2F%2Fzii%2F%2F8AAAAAOKL%2F%2Fzii%2F8wAAAAAAAAAADii%2F%2F84ov%2F%2FAAAAAAAAAAAAAAAAAAAAADii%2F3c4ov%2BqOKL%2F%2Fzii%2F5k4ov93AAAAADii%2F%2F84ov%2FMAAAAAAAAAAA4ov%2F%2FOKL%2F%2FwAAAAAAAAAAOKL%2Fdzii%2F8w4ov%2FMOKL%2F3Tii%2F%2F84ov%2FdOKL%2FzDii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F5kAAAAAOKL%2F%2Fzii%2F%2F8AAAAAAAAAADii%2FyI4ov9VOKL%2FVTii%2F1U4ov9VOKL%2FVTii%2F1U4ov93OKL%2F%2Fzii%2F904ov9EAAAAADii%2F%2F84ov%2F%2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOKL%2FETii%2F%2F84ov%2FMAAAAAAAAAAA4ov%2F%2FOKL%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADii%2F3c4ov%2F%2FOKL%2FiAAAAAAAAAAAOKL%2F%2Fzii%2F%2F8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADii%2FxE4ov%2FuOKL%2F%2Fzii%2FyIAAAAAAAAAADii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FOKL%2F%2Fzii%2F%2F84ov%2F%2FAAD%2F%2F0%2B%2B%2F%2F9AHv%2F%2FcZ7%2F%2F3Cm%2F%2F92Jv%2F%2FcGb%2F%2F3Mm%2F%2F9wJv%2F%2FfGb%2F%2F3AC%2F%2F9%2F5v%2F%2Ff%2Bb%2F%2F3%2Fm%2F%2F9%2Fzv%2F%2FAAD%2F%2Fw%3D%3D</Image>
-<Url type="text/html" method="GET" template="http://www.gujaratilexicon.com/index.php" resultdomain="gujaratilexicon.com">
- <Param name="action" value="dictionary"/>
- <Param name="mode" value="search"/>
- <Param name="type" value="1"/>
- <Param name="dictype" value="EG"/>
- <Param name="sitem" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.gujaratilexicon.com/index.php?action=dictionary&amp;chngdictype=EG</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/gulesider-NO.xml b/browser/locales/searchplugins/gulesider-NO.xml
deleted file mode 100644
index 87d7814b4..000000000
--- a/browser/locales/searchplugins/gulesider-NO.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Gule sider</ShortName>
-<Description>Gule sider person og firmasøk</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAABI1f7/SNX+/0jV/v9I1f7/SNX+/0jV/v9I1f7/SNX+/0jV/v9K3P//OLDU/wAEBf8AAAD/AAAA/wAAAP8EDhL/StX+/0rV/v9K1f7/StX+/0rV/v9K1f7/StX+/0rV/v9K1f7/Td3//zirzv8AAgP/AAAA/wAAAP8AAAD/AwkM/0zW/f9M1v3/TNb9/0zW/f9M1v3/TNb9/0zW/f9M1v3/TNb9/0/e//85rM7/AAID/wAAAP8AAAD/AAAA/wMKDf9P1/3/T9f9/0/X/f9P1/3/T9f9/0/X/f9P1/3/T9f9/0/X/f9S3///OqzN/wAAAP8AAAD/AAAA/wAAAP8CBwn/UNj9/1DY/f9Q2P3/UNj9/1DX/f9U4f//Vuf//1bn//9W5///We7//z+32v8CCg3/AwcJ/wMHCf8DBwn/BhQZ/1LZ/f9S2f3/Utn9/1LZ/v9T3f7/NJGr/ydmeP8nZnj/J2Z4/ydneP8+qsf/Tcrm/0rD5P9Kw+T/SsPk/0vG5/9T2f3/U9n9/1PZ/f9U2v7/VOD//xM/TP8AAAD/AAAA/wAAAP8AAAD/K3aK/1rs//9V3v//Vd7//1Xe//9V3v//U9n9/1PZ/f9T2f3/VNr+/1Tf//8XSFb/AAAA/wAAAP8AAAD/AAAA/y16j/9Y5v//U9n9/1PZ/f9T2f3/U9n9/1PZ/f9T2f3/U9n9/1Ta/v9U3///F0hW/wAAAP8AAAD/AAAA/wAAAP8teo//WOb//1PZ/f9T2f3/U9n9/1PZ/f9V3v//Vd7//1Xe//9W3///VuT//xRATP8AAAD/AAAA/wAAAP8AAAD/LHWJ/1rs//9V3v//Vd7//1Xe//9V3v//S8Tk/0vE5P9LxOT/S8Tl/07O7P8uh6H/GlNk/xpUZf8aVGX/GlRl/zmjwP9OzOf/S8Tk/0vE5P9LxOT/S8bn/wMICf8DCAn/AwgJ/wMHCf8OLTb/Utr//1bl//9V4///VeP//1jq//9AuNr/AwoN/wMICf8DCAn/AwgJ/wYUGf8AAAD/AAAA/wAAAP8AAAD/CiEp/0/R9f9V3f//U9r+/1Pa/v9Y4v//Pa3N/wAAAP8AAAD/AAAA/wAAAP8CBwn/AAAA/wAAAP8AAAD/AAAA/wskLP9P0fX/VNz//1PZ/f9T2f3/V+H//z2uzv8AAgP/AAAA/wAAAP8AAAD/AwoN/wAAAP8AAAD/AAAA/wAAAP8LIyv/T9H1/1Tc//9T2f3/U9n9/1fh//89rc3/AAID/wAAAP8AAAD/AAAA/wMJDP8AAAD/AAAA/wAAAP8AAAD/DCcw/0/T9/9U3P//U9n9/1PZ/f9X4f//PrLT/wAEBf8AAAD/AAAA/wAAAP8EDhL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
-<Url type="text/html" method="GET" template="http://www.gulesider.no/query" resultdomain="gulesider.no">
- <Param name="what" value="all"/>
- <Param name="search_word" value="{searchTerms}"/>
- <Param name="cmpid" value="fre_partner_fire_gssbtop"/>
-</Url>
-<SearchForm>http://www.gulesider.no/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/heureka-cz.xml b/browser/locales/searchplugins/heureka-cz.xml
deleted file mode 100644
index 0dccb6f5e..000000000
--- a/browser/locales/searchplugins/heureka-cz.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Heuréka</ShortName>
-<Description>Vyhledávání na Heuréka.cz</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAA9fX13/X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX13/X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//769f/59/X/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/+/y9f8mjP7/lMP5//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/09fX//fn1/6XM+P97t/r/ir/6/9jm9v8ahf7/AHb//7fV+P/19fX/9fX1//X19f/19fX/9fX1//X19f/09fX/0eL2/w1///8AdP//NZP9/wJ5//8AdP//A3n//7HT+P/39vX/9fX1//X19f/19fX/9fX1//X19f/19fX/9PT1/w5///8wkf3/8vP1//Dz9f///vT/gbr6/wBy///I3vf/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/5fF+f8Ad///+ff1/8rf9/8Ab///nMj4///79f85lf3/TZ/8//r49f/19fX/9fX1//X19f/19fX/9fX1//X19f98t/r/N5T9//n39f8Nfv//HIb+/wR6///y9PX/g7v6/xOC////+/T/9fX1//X19f/19fX/9fX1//X19f/19fX/grr6/xqF/v/y9PX/Xqj7//359f8bhv7/W6b8/3Cx+v8pjf3//vr1//X19f/19fX/9fX1//X19f/19fX/9fX1/9fm9v8AcP//mcb5//759f/09fX/wdv3/wBz//8Lfv//g7v6//b19f/19fX/9fX1//X19f/19fX/9fX1//X19f/59/X/eLX6/wBw//9Ypfz/nsn5/3W0+v8Ge///LY/9//r49f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//z59f+s0Pj/MpH9/xOC//8giP7/f7n6//r49f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//359f//+/T///r1//b29f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX13/X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX13wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA9fX1gPX19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19YD19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/5vH+f9Amf3/bbD7//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f+bx/n/BHr//wR6//8Eev//9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/m8f5/wR6//8Eev//BHr//xOC/v/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/X5vb/bbD7/zGR/f8Eev//BHr//wR6//9Amf3/m8f5/4y/+f8Eev//BHr//wR6//8Tgv7/yN73//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/bbD7/wR6//8Eev//BHr//wR6//8Eev//BHr//wR6//8Eev//BHr//wR6//8Eev//E4L+/8je9//19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/zGR/f8Eev//BHr//wR6//8iif7/Xqj7/324+v9Amf3/BHr//wR6//8Eev//BHr//xOC/v/I3vf/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f9tsPv/BHr//wR6//8Tgv7/m8f5//X19f/19fX/9fX1//X19f/m7fb/bbD7/wR6//8Eev//BHr//8je9//19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/udb4/wR6//8Eev//E4L+/8je9//19fX/9fX1/9fm9v+51vj/9fX1//X19f/19fX/m8f5/wR6//8Eev//QJn9//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f9eqPv/BHr//wR6//+51vj/9fX1//X19f/X5vb/E4L+/wR6//99uPr/9fX1//X19f/19fX/QJn9/wR6//8Eev//yN73//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/xOC/v8Eev//MZH9//X19f/19fX/9fX1/zGR/f8Eev//BHr//xOC/v/X5vb/9fX1//X19f+51vj/BHr//wR6//99uPr/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/BHr//wR6//9tsPv/9fX1//X19f9tsPv/BHr//wR6//8Eev//BHr//0+g/P/19fX/9fX1//X19f8Eev//BHr//0CZ/f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f8Eev//BHr//324+v/19fX/udb4/wR6//8Eev//MZH9/0+g/P8Eev//BHr//6rP+P/19fX/9fX1/xOC/v8Eev//QJn9//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/wR6//8Eev//bbD7//X19f+bx/n/BHr//xOC/v/I3vf/1+b2/xOC/v8Eev//Ion+/+bt9v/19fX/BHr//wR6//9PoPz/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/Ion+/wR6//8iif7/9fX1//X19f/I3vf/1+b2//X19f/19fX/jL/5/wR6//8Eev//bbD7/6rP+P8Eev//BHr//324+v/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f9tsPv/BHr//wR6//+Mv/n/9fX1//X19f/19fX/9fX1//X19f/19fX/MZH9/wR6//8Eev//MZH9/wR6//8Eev//1+b2//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/9fm9v8Eev//BHr//xOC/v+51vj/9fX1//X19f/19fX/9fX1//X19f+51vj/BHr//wR6//8Eev//BHr//0CZ/f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/4y/+f8Eev//BHr//wR6//99uPr/5u32//X19f/19fX/9fX1/7nW+P8iif7/BHr//wR6//8Tgv7/1+b2//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/16o+/8Eev//BHr//wR6//8Eev//MZH9/0CZ/f8Tgv7/BHr//wR6//8Eev//E4L+/8je9//19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/6rP+P8Tgv7/BHr//wR6//8Eev//BHr//wR6//8Eev//BHr//0CZ/f/X5vb/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1/+bt9v+bx/n/T6D8/0CZ/f9Amf3/QJn9/22w+//I3vf/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fWA9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.heureka.cz/direct/firefox/autocompleter.php">
- <Param name="query" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="http://www.heureka.cz/" resultdomain="heureka.cz">
- <Param name="h[fraze]" value="{searchTerms}"/>
- <Param name="utm_source" value="firefox-search"/>
-</Url>
-<SearchForm>http://www.heureka.cz/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/hoepli.xml b/browser/locales/searchplugins/hoepli.xml
deleted file mode 100644
index ae856aad0..000000000
--- a/browser/locales/searchplugins/hoepli.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Hoepli</ShortName>
-<Description>Dizionario della lingua italiana Hoepli</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,
-iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAEZJREFUeNpi/P//PwMpgAVCMSYehDD+z7dHlsYUZ2IgEQxCDSxofLgvB4+TcMUDLZ2kQKqGBxQ6iZHU1EqyDQAAAAD//wMApAcRQrj9oIAAAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://dizionari.hoepli.it/Dizionario_Italiano/cerca.aspx" resultdomain="hoepli.it">
- <Param name="idD" value="1" />
- <Param name="utm_source" value="mozilla-firefox" />
- <Param name="query" value="{searchTerms}" />
-</Url>
-<SearchForm>http://dizionari.hoepli.it/Dizionario_Italiano.aspx?idD=1</SearchForm>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/images/yandex-en.ico b/browser/locales/searchplugins/images/yandex-en.ico
deleted file mode 100644
index 6398f30e9..000000000
--- a/browser/locales/searchplugins/images/yandex-en.ico
+++ /dev/null
Binary files differ
diff --git a/browser/locales/searchplugins/kannadastore.xml b/browser/locales/searchplugins/kannadastore.xml
deleted file mode 100644
index 794a3ba3e..000000000
--- a/browser/locales/searchplugins/kannadastore.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Kannada Store</ShortName>
-<Description>Kanada Store, Online store</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%06%00%00%00%1F%F3%FFa%00%00%00%01sRGB%00%AE%CE%1C%E9%00%00%00%06bKGD%00%FF%00%FF%00%FF%A0%BD%A7%93%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%07tIME%07%D8%0A%0E%11%0D%25%7B%988%3D%00%00%00%19tEXtComment%00Created%20with%20GIMPW%81%0E%17%00%00%02%96IDAT8%CB%B5S%5DHSq%1C%3D%FF%BB%7B%AFw%DB%DD%A6ss%CEebs%E9%0Cm%AB%F0%23T%10%FB%20la%05%81%91F%F8%D0%93%BD%F4R%0F%BD%D4%7B%09AAbdDA%84f%8C%B0%CC%1E%FAxP%B0%9A%99%18%E9%CA%0F%B4%E9%3Elnn%BB%9B%F7%DF%93%D2%C7%A4%A7~%AF%BF%F3%3B%9Cs8%3F%E0%7FN4%D2g%F9%17%86l%B6%A0%94%8A%81%5E%D7%AB%F3%2B%DD%CE%2C%93%12%81%88%3C%DB%E7%91%1Ek%09%18qEb%07%2F%19o%5B%F4%8AavS%EA%D8%D8%BE%2Fr%A5%93%F7%BD%9D%19)v%5D%8B%B2%92%CA%5E%CF%F1%99s%1FO-%7B%F9%89%9B%03%9A(%00lJ%10%0F%BCv%C5%FD%5E%5C%3E%7D%F6%8E%D9D%3A%00%A0%E7%DE%03m%8C%81%D3%B0%93%B6%1C%3CZ%1E%06%00%26%DD%F1%D2%87%AEN)%E4%AE%CFS%8D%40%FCv%F78%A5%B4%00%00%04VRX%AD%DB%0A%0E45%C7%D7%B1i%15%F0k%5E%AB%A8yZh%AE%06%BAG%D9d%CF%E8r%C5%05w%A0L%D8%C16H%FE%B9%00%00'%80%A1%8D%10%FB%DF%CC%E6%3E%FA%1Cl%CE%B3%08W_%8E%871%1CJ%E0%8C%ED%09%15U%22%AEO%B7%12Be%C8s2%88%17%A8-%D3%2C6%ED%15l%ED%8D%BA%F0%86%02F%9D%7D%D13%95q%AEk%60%95f%A8%B3%08%C7%25%D09%DFF%90%93%09%B5%AC%40%CA%17%07%13%0D%C3a%5DE%89%3Er%BF%BD%D1%11%5EW%CB%00%C0~%87%F2V%9D%3D%E5%DFU%A8%24rL%09%CA%E6%40%CC7BT)!%FB%FD%A0%DF%C7%E04%2C%A0%D6F%A0%15%D7B%BF%DAe%00%80%10%F2i%E9%07%EF%AD)V%80%E3%08h%24%85%E4%D7%04%92%93%3E%C8A%1F8%9D%06%06%A3%0E%16%93%16%5B%8D%CA%DF%82%DF%08%D1%A4%97%19K6%0F%BB%83b%DC%C7%02kI%10%A8%20%0B%3A%18T%0C%EC%25z%24%14%B2%A4%E3%B9%D1%B4%04z%3DK%8A%B6%08%B4F%99A%92%3E%19%D3A%0A)%C4%40%A3%11Pi%D6%60%C8%F3%0E%E6y7%A9(%B7%09%7FY%00%80%3D%A5Y%1D%0F%FB%06%C9%EC%E4%04%8A%84%14%B4%99%02d%15%8F%5C.%09%B3%B0%0C%C1s%03f%83.%E8%AC%A8%9DI%FB%0B%94R%F5%A1%FD%0D%11C%FEv%94%1Dn%C3%82%2C%E2y%FF3%F0%93%2F%D0%D6%D2%8C%BA%EA%DD%88%85%97%8FUUW%F5%A6%B5%00%E0%CA%89%93%AD%A9X%2C%CE%E4%EB)%93%13%5E%C4%FB)7%9A%8E%B8%A0W%B1(-)%06%A7%20%BD%7F%96%EE'%A3%D6%EC%AB%93r%84%7D%00%00%00%00IEND%AEB%60%82</Image>
-<Url type="text/html" method="GET" template="http://www.kannadastore.com/advanced_search_result.php" resultdomain="kannadastore.com">
- <Param name="keywords" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.kannadastore.com/advanced_search_result.php</SearchForm>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/kaz-kk.xml b/browser/locales/searchplugins/kaz-kk.xml
deleted file mode 100644
index cfc32cab8..000000000
--- a/browser/locales/searchplugins/kaz-kk.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>KAZ.KZ</ShortName>
-<LongName>KAZ.KZ көмегімен іздеÑтіру</LongName>
-<Description>ҚазақÑтандық іздеÑтіру жүйеÑÑ–</Description>
-<InputEncoding>utf-8</InputEncoding>
-<Image height="16" width="16" type="image/x-icon">data:image/x-icon;base64,AAABAAMAEBAQAAEABAAoAQAANgAAABAQAAABAAgAaAUAAF4BAAAQEAAAAQAgAGgEAADGBgAAKAAAABAAAAAgAAAAAQAEAAAAAADAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAD82G0A9MxaAO3gugDz8vEA%2FtRcAP7prwD44JkA%2Fs5DAPLy8QDp6ecA%2F8MbAP%2FNPQD%2F1FcA%2F807AP%2FwxwAAAAG7u9AAAAANyFAFuxAAABVwAAhXjQAA1QAALAAM0A27u4iAAADhG4cHiwAAAF7oAAALYAAAe7UAAAVQAAALtQAABVAAAHvoAAALcAAAexuHB4UAAACMDbu7UAAAAOAAuAAAAAAF0AAVAAAAAI0AAADYVmWLEAAAAAHrvtAAAPgfAADhhwAAx4MAAM85AACAfAAACPwAAD58AAA%2BfgAAPnwAAD58AAAI%2FAAAgf0AAM%2F5AADP8wAA8AcAAPgfAAAoAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7%2B%2FgD29fUA6ennAPDjvQD%2B4ZAA%2FuKRAPj49wDw7%2BsA7NurAOzs6gDs6%2BoA6uroAPHlxAD8xisA9%2Ff2APXt1QDw47sA%2Fsw7AOXYswD%2B7LoA8vLxAP7NPAD%2B9NkA7eXMAPLnxwDw7%2B4A6ejmAPHjuAD379oA%2FMo%2FAObl4wDx8fAA49avAObk3QD%2B34UA%2Fuu1APPz8gD%2B4pIA7OzqAPz8%2FADs6%2BkA%2Fu28AP7ORQD08%2FEA%2FuSaAOHSqgDx8O8A6OflAOvdswD48uEA6%2BvpAPf29gD06s0A8OO%2FAO%2Fu7QDr5M0A8ubEAOvZpQDy47kA9vb1APzHLwD025UA5%2BbkAO%2Fu7QD5%2BfkA8%2BnLAOLVrgD%2B5Z4A5eLbAP7RUgD%2F4IgA%2F9hsAP%2FQTgD%2F0E4A%2F9VgAP%2FoqgD%2FwQwA%2F%2BqtAP%2FabAD%2FwQ4A%2F%2BGJAP%2FVXAD%2Fxh4A%2F%2BqtAP%2FNPQD%2F2WgA%2F9JTAP%2FKMAD%2F6KgA%2F9ZfAP%2FRTwD%2F0E0A%2F9NWAP%2FYbAD%2F7sAA%2F8UhAP%2FLOAD%2FyzAA%2F85EAP%2FLOQD%2FxR0A%2F9BBAP%2FUVAD%2F6aYA%2F8guAP%2FbcAD%2Fz0gA%2F8o1AP%2Fz0QD%2F1V8A%2F%2BGNAP%2FjlQD%2FyzkA%2F%2BSZAP%2FXZAD%2F5p0A%2F%2BKRAP%2FbeAD%2FyjUA%2F9NTAP%2FKNgD%2FxiEA%2F89HAP%2FEGQD%2FzD4A%2F%2BeiAP%2FPTAD%2Fz0gA%2F%2BmpAP%2FKMAD%2F1l8A%2F%2BqvAP%2FghgD%2FyTAA%2F803AP%2FTUAD%2FwxkA%2F%2BSTAP%2B%2BAQD%2F3nsA%2F8cmAP%2FFHAD%2FwAUA%2F9FRAP%2FDFwD%2F01gA%2F95%2FAP%2FSUwD%2F5Z0A%2F%2BekAP%2FLNwD%2Fz0UA%2F9BEAP%2FVXgD%2FyCQA%2F%2BafAP%2FhiAD%2F1l8A%2F85AAP%2FEEgD%2FwhIA%2F%2BmtAP%2FTVwD%2F56UA%2F9BMAP%2FNQAD%2FzDoA%2F9djAP%2FCFQD%2F0lAA%2F8AJAP%2FEGwD%2F0VAA%2F8EMAP%2B%2BAAD%2F8McAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWcqo2urqyobxoAAAAAADWol312lX5eUHyqBAEAADJqf0QiACwUW5AGSmcEAAKKh4VtQkURlFc7CA2AiEBoZqBNi2BVYWscKAAHCViTVlMWJl8jEqEqQQAAAAqlZIJ5ITMAAy4OTAAAAAAAcIllWjAAAAA%2FrW4AAAAAAIGreoMbAAAAH61LAAAAAAByq2KnEwsADEM9PgAAAAAAR6xPjistsAUeRjgAAAAAKXufTpmPr6%2BRozEnAAAAPDqGdTRRm5KEJDcAAAAADzZJXS8AHYyYpBclAAADGKJcnjkAAAAQnWNxc5ZZSKZsUhkBAAAAAAJUmnepqWl4dCAAAAD4HwAA4YcAAMeDAADPOQAAgHwAAAj8AAA%2BfAAAPn4AAD58AAA%2BfAAACPwAAIH9AADP%2BQAAz%2FMAAPAHAAD4HwAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAP%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAPLy8Q7%2F5p9g%2F9JQr%2F%2FHJtn%2FwQzz%2F8EM8%2F%2FEG%2BT%2F12Oc%2F%2BGNcvDv7hH%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAPTqzTL%2F12Oc%2F8s3zP%2FMPtD%2F23ih%2F%2BWdcv%2Fnom7%2F2Gyu%2F8EO8f%2FEGeb%2F0lCv8OO9Qv7%2B%2FgH%2F%2F%2F8A%2F%2F%2F%2FAPjy4R7%2F23CP%2F89Mwv7lnoPm5N0k%2F%2F%2F%2FAPTz8Q%2F%2B7Lpb%2F9FPw%2F%2FRUbj%2B4pGE%2F9BOwf%2FUVKvw471C%2F%2F%2F%2FAPb19Qr%2F5JNs%2F803yv%2Fghpv%2F89FE8%2BnLQ%2BXi2ybw47tU%2F9JTvv%2FSU7by47lN8O%2FrFfHlxE7%2Fz0jI%2F9NQr%2B%2Fu7RL%2F6aZZ%2F9BBvv%2FEEu3%2FwQz2%2F74B%2F%2F%2FFIeb%2FzT3Q%2F8s40%2F%2FPSMDx47hO%2FPz8A%2F%2F%2F%2FwD4%2BPcI7Nurbf%2FKMNP%2F3n%2BA%2F9lol%2F%2FGHuL%2BzTzU%2FuKSkf%2FuwGP%2B34WX%2Fsw70v%2FCEu%2F%2B7bxi%2Bfn5Bv%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAOzs6hX%2F0EzJ%2F8s5xv%2FKMM%2F%2Fyjba49avY%2Bvr6Rb%2F%2F%2F8A6ennGOHSqmv8xivh%2F%2Biqff%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A%2F%2BOVjf%2FDGeb%2FxR3i%2F9Zfu%2Bjn5Rr%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwDn5uQb%2F9FQyP%2FVX7r%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAP%2FpqXL%2FwAn2%2F8Yh3v%2FWX7rp6OYZ%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A5uXjHP%2FRUMj%2F1WC5%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F5JmA%2F8AJ9v%2FLMM%2F%2FzDrU5dizYOzr6hX%2F%2F%2F8A6uroF%2BLVrmX8xy%2Fd9NuVi%2F%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A%2F%2BCImP%2FEG%2BT%2F2myT%2F8Uc5P7ORc3%2B5JqF%2F%2FDHWP7hkI38yj%2FN%2FtFSxOvkzUb%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A7OvpFv%2FPR8v%2FzkC%2F%2F%2BqtUv%2FQRLv%2FwAX6%2F74A%2F%2F%2B%2BAP%2F%2Fwxft%2F9NXwevds2Ds7OoV%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A9vb1CuvZpXP%2FyTDT%2F%2BKRbvf29gn%2F4Yl2%2F8gk2%2F%2FTWMb%2F6q92%2Fuu1Zu%2Fu7RL%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A9%2Ff2CfDjv1b%2F0E7A%2F9NWqfHw7xD%2F%2F%2F8A9%2B%2FaJf%2Fee4T%2Fz0XE%2F%2Belef702Tvz8%2FIN%2F%2F%2F%2FAP%2F%2F%2FwDp6ecY7eXMRv%2FprXf%2F0E3C%2F9ZfoPLmxDv%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwD17dUq%2F%2BGId%2F%2FORL3%2FyznW%2F9dkuP%2FnpIr%2F6KiH%2F9hssv%2FNQNH%2FyjXO%2F9Vco%2FLnxzj%2B%2Fv4B%2F%2F%2F%2FAP%2F%2F%2FwD%2F%2F%2F8A%2F%2F%2F%2FAPb19Qr%2F6q1S%2F9Veof%2FKNcr%2FwhXq%2F8IV6v%2FILtH%2F01Os%2F%2BadYvHx8A%2F%2F%2F%2F8A%2F%2F%2F%2FAP%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="text/html" method="get" template="http://search.kaz.kz/search.cgi" resultdomain="kaz.kz">
- <Param name="q" value="{searchTerms}"/>
- <Param name="lang" value="KAZ"/>
-</Url>
-<SearchForm>http://kaz.kz/index_kk.html</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/klask.xml b/browser/locales/searchplugins/klask.xml
deleted file mode 100644
index 321c908d3..000000000
--- a/browser/locales/searchplugins/klask.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Klask</ShortName>
-<Description>Klask, stal ar brezhoneg</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFhYUAioqKAJGRkQCcnJwAn5+fAKampgCnp6cAOqbyALCwsACxsbEAtbW1ALm5uQDBwcEAwsLCAM7OzgDPz88A2traANvb2wDm5uYA+vr6APz8/AD+/v4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhYWFhYWFhYWFhYWFhYWFhYWBwcHFhYWFhAHBwcHARYWFgcHBxYWFg4HBwcHBBYWFhYHBwcWFg0HBwcHCRYWFhYWBwcHFgoHBwcHDBYWFhYWFgcHBwUHBwcHDxYWFhYWFhYHBwcHBwcHERYWFhYWFhYWBwcHBwcHEhYWFhYWFhYWFgcHBwcHBwsWFhYWFhYWFhYHBwcHBwcHCBYWFhYWFhYWBwcHEwcHBwcGFhYWFhYWFgcHBxYUBwcHBwMWFhYWFhYHBwcWFhUHBwcHAhYWFhYWBwcHFhYWFgcHBwcAFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Image>
-<Url type="text/html" method="POST" template="http://www.klask.com/index.php" resultdomain="klask.com">
- <Param name="yc" value="0"/>
- <Param name="dib" value="13"/>
- <Param name="ger" value="{searchTerms}"/>
-</Url>
-
-<SearchForm>http://www.klask.com/index.php</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/leit-is.xml b/browser/locales/searchplugins/leit-is.xml
deleted file mode 100644
index 0e4f230d5..000000000
--- a/browser/locales/searchplugins/leit-is.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>leit.is</ShortName>
-<Description>leit.is - Ãslensk leitarvél</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAALifu/yoi7f8rI+3/KiHt/zMt8P83MvH/MS3J/zAsv/8xLML/MSzB/zEtwf8sKMH/Ix3A/yQdwP8jHMD/KCLB/ygg7f8iGu3/Ihrs/ycg7v8AAOn/AAC+/wAAsP8AALb/AAC1/wAAtf8AALT/AAC4/yAZvv8bFL3/GxO9/yIbwP8rI+3/JBzt/ysk7f8AAO7/oqDr/8rJ5v/Cwev/xMLp/8TC6v/Cwen/ycjs/6Si3/8AALn/JB6//x0Wvv8jHbz/KiLt/yQc7f8vKu3/AADq/9nY/v/R0er/goDQ/5aU1v+TktX/kpHV/5eW1/96eM//AAC8/yEbv/8bFLb/JyDV/yoi7f8kHO3/Lint/wAA6v/R0Pz/o6LX/wAArv8AALj/AAC3/wAAt/8AALb/AAC5/yEbwP8bFLb/HxfV/ysk8/8qIu3/JBzt/y8p7f8AAOr/0tH8/66t3P8AALj/NTHB/ygjv/8oI7//KSS//yUgwP8bFLb/IRnV/yQb8/8qIuz/KiLt/yQc7f8vKe3/AADq/9LR/P+trNv/AAC2/y0ov/8dFr7/HRa+/x0Wv/8cFbb/IBnV/yUd8/8jG+z/KiLt/yoi7f8kHO3/Lynt/wAA6v/S0fz/razb/wAAtv8tKb//HRa+/x0Wv/8cFbb/IBnV/yUd8/8kHOz/Ixvs/yoi7f8qIu3/JBzt/y8p7f8AAOr/0tH8/62s2/8AALb/LSm//x0Wv/8cFbb/IBnV/yUd8/8kHOz/JBzt/yMb7f8qIu3/KiLt/yQc7f8vKe3/AADq/9LR/P+trNv/AAC2/y0pwf8cFbb/IBnV/yUd8/8kHOz/JBzt/yQc7f8jG+3/KiLt/yoi7f8kHO3/Lynt/wAA6v/S0fz/razb/wAAuP8sKLj/IBnV/yUd8/8kHOz/JBzt/yQc7f8kHO3/Ixvt/yoi7f8qIu3/JBzt/y4p7f8AAOr/0dD8/6uq3P8AAK7/LyrW/yUc8/8kHOz/JBzt/yQc7f8kHO3/JBzt/yMb7f8qIu3/KiLt/yQc7f8vKe3/AADq/9rZ/f+0s9f/AADP/zQu9P8kHOz/JBzt/yQc7f8kHO3/JBzt/yQc7f8jG+3/KiLt/ysj7f8kHO3/KiTt/wAA7P+op/b/jYzq/wAA7v8tJ+3/JBzt/yQc7f8kHO3/JBzt/yQc7f8lHe3/Ixvt/ysj7f8oIO3/Ihrt/yIa7f8oIe3/AADr/wAA7v8qI+3/IRns/yMb7f8jG+3/Ixvt/yMb7f8jG+3/Ixvt/yIa7f8oIO3/Lifu/yoi7f8rI+3/KiHt/zMt7v8xKu3/KSHt/ysj7f8qIu3/KiLt/yoi7f8qIu3/KiLt/ysj7f8qIu3/Lifu/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAPDXv/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8xKff/Lifk/ykjwP8pI8D/KSPC/ykjwv8pI8L/KSPC/ykjwv8pI8L/KSPC/ykjwv8pI8L/KSPC/ykjwv8pI8L/KSPC/ykjwv8pI8L/KSPC/zYwxf8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JR33/yMb5P8cFbr/HBa5/x0Wv/8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yYd9/8iG+P/HBW5/xwVuf8dFr//HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8pI8L/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yoh7v8WDfD/AADY/wAAr/8AAK//AAC1/wAAtP8AALT/AAC0/wAAtP8AALT/AAC0/wAAtP8AALT/AAC0/wAAtP8NBrn/IhrA/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/ykjwv8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/GRLv/0Q87f9sZ9D/Yl3M/2Ne0/9jXtL/Y17S/2Ne0v9jXtL/Y17S/2Ne0v9jXtL/Y17S/2Ne0v9jXtL/bGjV/z44x/8SDbr/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/KSPC/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/lpL0////////////////////////////////////////////////////////////////////////////o6Dl/wAAr/8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvf8oIr3/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+NifX///////Hw+/+gnuT/n5zk/6Og5f+joOX/o6Dl/6Og5f+joOX/o6Dl/6Og5f+joOX/o6Dl/6im5v9cV9H/Cga3/x0Wvv8dFr7/HRa+/x0Wvv8dFrz/HBW1/ywl1P8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/4uH9f//////zs3x/wAAs/8AALL/AAC1/wAAtf8AALX/AAC1/wAAtf8AALX/AAC1/wAAtf8AALX/AAC2/w8Huv8gGMD/HRa+/x0Wvv8dFr7/HRa9/xwVtP8gGNH/MSn2/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/i4f1///////U0/P/FA27/xILuv8bFL3/GxS9/xsUvf8bFL3/GxS9/xsUvf8bFL3/GxS9/xsUvf8bFL3/HBW+/x0Wvv8dFr7/HRa+/x0WvP8cFbT/IBnR/yUd9f8xKfH/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+Lh/X//////9TT8/8WD7z/FA27/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFrz/GxW1/yAY0f8lHfX/JR3w/zAo7f8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/4uH9f//////1NPz/xYPvP8UDbv/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr//HRa9/xwVtP8gGNH/JR31/yQc8P8kHOz/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/i4f1///////U0/P/Fg+8/xQNu/8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0WvP8cFbT/IBjR/yUd9f8kHPD/JBzs/yQc7f8wKO7/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+Lh/X//////9TT8/8WD7z/FA27/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr3/HBW0/yAY0f8lHfX/JBzx/yQc7P8kHO3/JBzt/zAo7v8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/4uH9f//////1NPz/xYPvP8UDbv/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa8/xsVtf8gGNH/JR31/yQc8P8kHOz/JBzt/yQc7f8kHO3/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/i4f1///////U0/P/Fg+8/xQNu/8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0WvP8cFbT/IBjR/yUd9f8lHfD/JBzs/yQc7f8kHO3/JBzt/yQc7f8wKO7/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+Lh/X//////9TT8/8WD7z/FA27/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFrz/GxW0/yAY0f8lHfb/JBzw/yQc7P8kHO3/JBzt/yQc7f8kHO3/JBzt/zAo7v8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/4uH9f//////1NPz/xYPvP8UDbv/HRa+/x0Wvv8dFr7/HRa+/x0Wvv8dFr7/HRa9/xsVtP8gGNH/JR32/yQc8f8kHOz/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/i4f1///////U0/P/Fg+8/xQNu/8dFr7/HRa+/x0Wvv8dFr7/HRa+/x0Wvf8cFbT/IBjR/yUd9f8kHPD/JBzs/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8wKO7/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+Lh/X//////9TT8/8WD7z/FA27/x0Wvv8dFr7/HRa+/x0Wv/8dFr3/GxW0/yAY0f8mHfX/JBzw/yQc7P8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/zAo7v8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/4uH9f//////1NPz/xYPvP8UDbv/HRa+/x0Wvv8dFr7/HRa8/xwVtP8gGdH/JR32/yQd8P8kHOz/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/i4f1///////U0/P/Fg+8/xQNu/8dFr7/HRa+/x0Wvf8bFbT/IBjR/yUd9v8lHPH/JBzs/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8wKO7/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+Lh/X//////9TT8/8WD7z/FA27/x0Wvv8dFr3/HBW0/yAY0f8lHfX/JBzw/yQc7P8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/zAo7v8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/4uH9f//////1NPz/xYPvP8UDbv/HRa8/xwVtP8gGNH/JR31/yQc8P8kHOz/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/i4f1///////U0/P/Fg+8/xQNuv8cFbT/IBjR/yUd9f8kHPD/JBzs/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8wKO7/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/wAA6v+Lh/X//////9TT8/8WD7v/Eguy/yAZ0f8lHfX/JR3w/yQc7P8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/zAo7v8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/AADq/42J9f//////19by/xUOs/8XD8//JR31/yUd8P8kHOz/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8AAOr/lpL2///////m5vD/GRHQ/xwS8/8kHPD/JBzs/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8wKO7/MCju/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/xgR7P9EPfD/dnH0/1tV8P8jGvD/Ihnv/yQc7P8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/zAo7v8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/KSHu/xUM7P8AAOr/CgHs/yUd7v8lHe3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/MCju/zAo7v8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8wKO7/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f8kHO3/JBzt/yQc7f88Ne//MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/MCju/zAo7v8wKO7/PDXv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="text/html" method="GET" template="http://leit.is/leita" resultdomain="leit.is">
- <Param name="utf-8" value="✓"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://leit.is/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/leo_ende_de-rm.xml b/browser/locales/searchplugins/leo_ende_de-rm.xml
deleted file mode 100644
index 9c88d1468..000000000
--- a/browser/locales/searchplugins/leo_ende_de-rm.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>LEO Eng-Tud</ShortName>
-<Description>Pledari tudestg-englais da LEO</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAACtElEQVR4nF3Ma0hTYQDG8ec9e8/OOdNd9KjTwAwrmTjNDOxDVFJpIEVFgRkUhRkWXaAkMNDCyqgsumBIReGHiILCIOhDUBG1IE2FrprXXEwTJ7bN7d25vH0owvp//j0PSbc7fxqapnNNM4oIuQykUYGaOgc0B01uNOWlAIPVCllW42YjDceiM1ocQLbLme6wy9/8NA4OCImY26jZSoEIYAPEDM04RguqIFoVADlAc/PJjo5nRwjpBwbtmGkF7wPvAu8Cf5+hdV/TOd9V10413SwC1gMez0KvNzcgSQKNuc9AWQ2EAABihm7UY9HeqrpHbbdeC0XATUACFEUmBNxK0pthK5ul9Xrm2bO99mHb9ZeQKL0hi2kzjAGU0mBwWi3WZ38b9os0a+tY2Cgt8axb6yUCoamGzoAIEVwuZyAw5s7X/2qm108/jmqBs6KALbJICAFA4ywOIGKzuN2pPl/n3CT+W4eGqkdq77ChUfwb5QB1gBdbVDV5YmIiSwXEjNDw7tHjb9iIH4T8PxBTxLRTjL+0UGpljCkONcYaAldeGOFI2r6dRBCIIpnxOIHJwe2SRNVzorKMCc8FgHAOi/OQPL9Sl30BV+LAisKenu6hd75Ygk2gFlmyToVNauZr0SC+jxumaWRlZZ4+2qTP60oMjbu9C/L8A2Vly72Hqx2OJCABiJSs2ojpV9aayvS2tlbOpzmf6uvrDIVGOY/zP4WDwWGf72lLy6W15RugbqGiaJmMZu7YsQ0QGIu5XK7u7g+fPz8Y7Ov/Ojz+pXfMpFLFphV5g6NNSkpS5RqqJM45sHl1xcr1THV3vff/mNTm52TvN8ZKqHWosOKTrxcmvkzl1t2unzl7+UTnM6oZDZm+T/LimvvtH2HJQYLhWVJQ7n9ColFJtkOwwCbeu/uWA7fPH0y+cPUXI+Y0JNj13cUAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="get"
- template="http://dict.leo.org/dictQuery/m-query/conf/ende/query.conf/strlist.json?q={searchTerms}&amp;sort=PLa&amp;shortQuery&amp;noDescription&amp;noQueryURLs"/>
-<Url type="text/html" method="GET" template="http://dict.leo.org/ende" resultdomain="leo.org">
-<Param name="lang" value="de"/>
-<Param name="from" value="fxdesktop"/>
-<Param name="search" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://dict.leo.org</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/leo_ende_de.xml b/browser/locales/searchplugins/leo_ende_de.xml
deleted file mode 100644
index 5b1113e95..000000000
--- a/browser/locales/searchplugins/leo_ende_de.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>LEO Eng-Deu</ShortName>
-<Description>Deutsch-Englisch Wörterbuch von LEO</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAACtElEQVR4nF3Ma0hTYQDG8ec9e8/OOdNd9KjTwAwrmTjNDOxDVFJpIEVFgRkUhRkWXaAkMNDCyqgsumBIReGHiILCIOhDUBG1IE2FrprXXEwTJ7bN7d25vH0owvp//j0PSbc7fxqapnNNM4oIuQykUYGaOgc0B01uNOWlAIPVCllW42YjDceiM1ocQLbLme6wy9/8NA4OCImY26jZSoEIYAPEDM04RguqIFoVADlAc/PJjo5nRwjpBwbtmGkF7wPvAu8Cf5+hdV/TOd9V10413SwC1gMez0KvNzcgSQKNuc9AWQ2EAABihm7UY9HeqrpHbbdeC0XATUACFEUmBNxK0pthK5ul9Xrm2bO99mHb9ZeQKL0hi2kzjAGU0mBwWi3WZ38b9os0a+tY2Cgt8axb6yUCoamGzoAIEVwuZyAw5s7X/2qm108/jmqBs6KALbJICAFA4ywOIGKzuN2pPl/n3CT+W4eGqkdq77ChUfwb5QB1gBdbVDV5YmIiSwXEjNDw7tHjb9iIH4T8PxBTxLRTjL+0UGpljCkONcYaAldeGOFI2r6dRBCIIpnxOIHJwe2SRNVzorKMCc8FgHAOi/OQPL9Sl30BV+LAisKenu6hd75Ygk2gFlmyToVNauZr0SC+jxumaWRlZZ4+2qTP60oMjbu9C/L8A2Vly72Hqx2OJCABiJSs2ojpV9aayvS2tlbOpzmf6uvrDIVGOY/zP4WDwWGf72lLy6W15RugbqGiaJmMZu7YsQ0QGIu5XK7u7g+fPz8Y7Ov/Ojz+pXfMpFLFphV5g6NNSkpS5RqqJM45sHl1xcr1THV3vff/mNTm52TvN8ZKqHWosOKTrxcmvkzl1t2unzl7+UTnM6oZDZm+T/LimvvtH2HJQYLhWVJQ7n9ColFJtkOwwCbeu/uWA7fPH0y+cPUXI+Y0JNj13cUAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="get"
- template="http://dict.leo.org/dictQuery/m-query/conf/ende/query.conf/strlist.json?q={searchTerms}&amp;sort=PLa&amp;shortQuery&amp;noDescription&amp;noQueryURLs"/>
-<Url type="text/html" method="GET" template="http://dict.leo.org/ende" resultdomain="leo.org">
-<Param name="lang" value="de"/>
-<Param name="from" value="fxdesktop"/>
-<Param name="search" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://dict.leo.org</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/list-am.xml b/browser/locales/searchplugins/list-am.xml
deleted file mode 100644
index 7117f098c..000000000
--- a/browser/locales/searchplugins/list-am.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>List.am</ShortName>
- <Description>Õ€Õ¡Õ¶Ö€Õ¡ÕµÕ«Õ¶ Õ¦Õ¥Ö€Õ® ads Õ´Õ¡Õ½Õ«Õ¶: ÕŽÕ¡Õ³Õ¡Õ¼Ö„ Õ¥Ö‚ Õ£Õ¶Õ´Õ¡Õ¶ Õ¢Õ¶Õ¡Õ¯Õ¡Ö€Õ¡Õ¶Õ¶Õ¥Ö€, Õ¯Õ¥Õ¶ÖÕ¡Õ²Õ¡ÕµÕ«Õ¶ Õ«Ö€Õ¥Ö€, Õ¸Ö€Õ¸Õ¶Õ¥Õ¬ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¶Ö„Õ«.</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">
- data:image/gif;base64,R0lGODlhGAAYAIQfAKwVGN9vY/bw0ShPifHln1NqluXMLhxMjbC2ytKTidVDKcvP2vr29OyuoOC8F/PYHejJxNvc4hw4ertQRODCGOPDDx1qsvvoG/XkWM0gGjddmJoyQOCSh+Pm7IObwf///yH5BAEAAB8ALAAAAAAYABYAAAWs4CeOZGmeaKqSyTQlKxpkNADHJKQESgYAENyIE2D0aDdhQ7GkKZIphoAgWCqOiuCKUKE4HLyMArDxRFQEA8b77W0GknghpWawwW+N5iAZIFBqaw4PXgUeHQV8A3MnGF1eFw8Ohgt7B4sodg6QDxgFepcWmCgEX4MUAh4HqweiHmhsGB8RlpcFHVsGFQSzCJcHBQs4UyIRDInBQrPFHwsFZ8rQ0srMJNDRJdclIQA7
- </Image>
- <SearchForm>http://www.list.am/category?q=</SearchForm>
- <Url type="text/html" method="GET" template="http://www.list.am/category" resultdomain="list.am">
- <Param name="q" value="{searchTerms}"/>
- </Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/longdo.xml b/browser/locales/searchplugins/longdo.xml
deleted file mode 100644
index 5df2e6421..000000000
--- a/browser/locales/searchplugins/longdo.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>พจนานุà¸à¸£à¸¡ ลองดู</ShortName>
-<Description>พจนานุà¸à¸£à¸¡ ลองดู</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAcklEQVR42qSTwQ3AIAwDHZSROlOZiZ26k/tqRQtBjrgnECtEF+MJQqURMPsc+XuhQk4CAKCa1MHxe+ZDiz1CqA8FT0hQfHEVoDAdYoZwiAr9txqBaijYpKQk2grY6mBhaiySqLdnzYsDMgvVe5Va5wn3AGu/H1vn5EUlAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://search.longdo.com/Suggest/HeadSearch">
- <Param name="ds" value="head"/>
- <Param name="fxjson" value="1"/>
- <Param name="key" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="http://dict.longdo.org/" resultdomain="longdo.org">
- <Param name="search" value="{searchTerms}"/>
- <Param name="src" value="moz"/>
-</Url>
-<SearchForm>http://dict.longdo.org/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/mailru.xml b/browser/locales/searchplugins/mailru.xml
deleted file mode 100644
index 0507e07d6..000000000
--- a/browser/locales/searchplugins/mailru.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ПоиÑк Mail.Ru</ShortName>
-<Description>Search with ПоиÑк Mail.Ru</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAARCwAAEQsAAAAAAAAAAAAA85MASvOTAOfzkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//KTAP/rjgD/34YA/+CHAP/sjwDl85MASvOTAObzkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//KTAP/qjQD/zHsA/6tpAv+2bgL/4IcA//OTAOfzkwD/85MA//OTAP/wkQD/54wA/9yFAP/VgAD/1YAA/9uFAP/fhgD/yHkA/6VtHf/n3M3/7NzG/9+GAP/zkwD/85MA//OTAP/vkAD/3YUA/79zAv+iYwT/lFoF/5RaBf+iYwT/qWgD/6BpHv/q4dX///////Xlz//rjgD/85MA//OTAP/wkQD/3YUA/7JsAv+yi1b/4dPB//r49f/6+PX/4dPB/6yOYf/p4db///////bp1v/rlhv/8pMA//OTAP/zkwD/54wA/79zAv/Jr4r///////////////////////////////////////Hm1//ikBz/8pMA//OTAP/zkwD/85MA/9yFAP+/klX///////38+f/runb/75cY/++XGP/ruXb//fv5///////DmWH/24UA//OTAP/zkwD/85MA//OTAP/VgQD/5NXB///////gs3f/7pAA//OTAP/zkwD/7Y8A/+G3fv//////5NXB/9WBAP/zkwD/85MA//OTAP/zkwD/1YEA//n38///////y4Ea/+6QAP/zkwD/85MA/+2PAP/Kghr///////r39P/VgQD/85MA//OTAP/zkwD/85MA/9yFAP/69/P//////7N0Gv/bhQD/7pAA/+6QAP/bhAD/snQa///////69/P/3IUA//OTAP/zkwD/85MA//OTAP/ojAD/79zC//////++oHb/rWoC/8d4AP/HeAD/rWoC/8Klff//////79zC/+eMAP/zkwD/85MA//OTAP/zkwD/8JEA/+eqVv///////Pv5/7uedf+UYRr/lGAZ/7uedf/8+/n//////+eqV//wkQD/85MA//OTAP/zkwD/85MA//OTAP/vkAD/78SM/////////////////////////////////+/EjP/vkAD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//CRAP/vr1f/9uDC//359P/9+fT/9uDC//CvVv/wkQD/85MA//OTAP/zkwD/85MA//OTAP/zkwDm85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwDm85MASfOTAObzkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwDm85MASQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAARCwAAEQsAAAAAAAAAAAAA85MAAPOTACfzkwCt85MA8vOTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAPLzkwCt85MAJ2tCBwDzkwAo85MA7/OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwDv85MAKPOTAK3zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/+aLAP/ahAD/2oQA/+aLAP/wkQD/85MA//OTAP/zkwCt85MA8fOTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//CRAP/ghwD/vnMA/55hA/+fYgP/w3UB/+aLAP/zkwD/85MA//OTAPPzkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/wkQD/4IcA/7hvAf+wiVb/8e3n//Ht5v+7j1L/2oQA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/9+HAP+3bwH/s45d//39/P////////////Xv5//ZgwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/+eMAP/dhgD/14IA/9N/AP/TfwD/14IA/92GAP/njAD/8JEA//CRAP/fhwD/t28B/7OPXv/9/fz/////////////////+fLp/+aLAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/+aLAP/TfwD/unEB/6VlBP+YXQT/kVkE/5FZBP+YXQT/pWUE/7pxAf/RfgD/1YAA/7ZuAv+zj17//f38//////////////////79/P/qr17/8JEA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA/+6QAP/bhQD/unEB/5xiDP+wj2L/08Sv/+3o4f/8+/r//Pv6/+3o4f/TxK//sI9i/5lgDf+dYAT/sY1e//39/P/////////////////+/fz/6rFh//CRAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/ukAD/2IIA/61qAv+vi1r/6+Xd////////////////////////////////////////////6+Xd/7+qjf/9/fz//////////////////v38/+qxYf/wkQD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/9yFAP+vbQb/y7WY//////////////////////////////////////////////////////////////////////////////////79/P/qsWH/8JEA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/liwD/unEB/8ixj//////////////////////////////////////////////////////////////////////////////////+/fz/46xh//CRAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/9J/AP+8k13///////////////////////38+f/wypb/8KY+//GWDf/xlg3/8KY+//DKlv/9/Pn//////////////////////860kP/QfgD/75EA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/njAD/vHQK//Hs5f/////////////////48Ob/6qE6//GSAP/zkwD/85MA//OTAP/zkwD/8ZIA/+qhOP/48Ob/////////////////8u3l/7x1DP/njAD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA/92GAP/GnGP//////////////////fv4/+OcOP/xkgD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8ZIA/+OcOP/9+/j/////////////////xpxk/92GAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/14IA/97Kr//////////////////lxJf/644A//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/6o4A/+XEl//////////////////ey7D/14IA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/UgAD/7ubb/////////////////9iZQf/wkQD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/wkQD/15lB//////////////////Hr4v/TfwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA/9OAAP/59/P/////////////////zn8I//CRAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//CRAP/PgRH//////////////////Pv5/9N/AP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/14IA//z7+P/////////////////Cdwv/6o4A//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/6o4A/8J4DP/////////////////9+/n/14IA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/dhgD/9Ozi/////////////////7yIQP/chQD/8ZIA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//GSAP/chQD/vIhA//////////////////Ts4v/dhgD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA/+eMAP/p0bD/////////////////zreX/75zAP/liwD/8ZIA//OTAP/zkwD/85MA//OTAP/xkgD/5YsA/79zAv/Ot5f/////////////////6dGx/+eMAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JEA/+KtZP/////////////////8+/n/qHk5/75zAP/chQD/6o4A//CRAP/wkQD/6o4A/9yFAP++cwD/p3g4//v6+P/////////////////irWX/75EA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/544F//fw5f/////////////////w7OX/oXU4/6hnA//AdAH/zHsA/8x7AP/AdAH/qGcD/6F1OP/w7OX/////////////////9/Dm/+aOBv/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/wkQD/6K5d///////////////////////8+/n/xrKW/6B3Qf+QXRP/kF0T/6B3Qf/Gspb//Pv5///////////////////////orl3/8JEA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/ukAD/7saQ////////////////////////////////////////////////////////////////////////////7saQ/+6QAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/ukQD/78aQ/////////////////////////////////////////////////////////////////+/GkP/ukQD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/wkQD/7rBb//nt3v////////////////////////////////////////////nt3v/usVz/8JEA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/8JQF/++zX//z1az/+/Dh//78+f/9+fT/+ezZ//PVrP/ws17/8JQF//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwDx85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA8/OTAK3zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwCt85MAJ/OTAO/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA7/OTACfzkwAA85MAJfOTAK3zkwDx85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA//OTAP/zkwD/85MA8fOTAK3zkwAl85MAAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://suggests.go.mail.ru/ff3">
- <Param name="q" value="{searchTerms}"/>
- <Param name="gp" value="900200"/>
-</Url>
-<Url type="text/html" method="GET" template="https://go.mail.ru/search" resultdomain="mail.ru">
- <Param name="q" value="{searchTerms}"/>
- <Param name="fr" value="osmi"/>
- <Param name="gp" value="900200"/>
- <Param name="frc" value="900200"/>
-</Url>
-<SearchForm>https://go.mail.ru/?gp=900200</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/mapy-cz.xml b/browser/locales/searchplugins/mapy-cz.xml
deleted file mode 100644
index 4e7511997..000000000
--- a/browser/locales/searchplugins/mapy-cz.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Mapy.cz</ShortName>
-<Description>Vyhledávání na Mapy.cz</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFqSURBVHjajJM9KIVRGMffe11fhdwM7mBQkpIwsPiaFIPFxCYzyWIxKiXDXSxmBimDbrJZiUEhkxADi6/7+lbX9Tv6v2+n05vrqV/vc855z/88H+fEHlqbPSwGLTALF7AOx14BSx6degn5eSiGUY1HoA9uIvaV6MBPM4hbC3fwLr8OJiM2m/8nYAFqXYG85ZfCgL62tcMYTMOyK1AmAquHYWd9HNo07nAFksrtC04gC0NaK4cpJy2TcljEImiS/6QQU5CGThiEOSedrC1gvt2WwJ6K9A37iuwafLXb2Iudgmlhjwp5qG7k4EybfVU/bUXwZgtUQ4MmNy3RlPw12IJXVyChExpV5UvYtnLMSGReczmlZQ7+CATiaokJfxee9fM9zOiA4I6YtUeokViYQr8mViJun33BbhVl8H5+BSqhC85hp8D7uVI3QgGTQi9UwGIQ1h/m66VWwUEgYIq0BKve/2xDm00tvB8BBgA9FU3+lToaKQAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="http://www.mapy.cz/" resultdomain="mapy.cz">
- <Param name="query" value="{searchTerms}"/>
- <Param name="sourceid" value="Searchmodule_3"/>
-</Url>
-<SearchForm>http://www.mapy.cz/</SearchForm>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/marktplaats-fy-NL.xml b/browser/locales/searchplugins/marktplaats-fy-NL.xml
deleted file mode 100644
index 8ad4f61d3..000000000
--- a/browser/locales/searchplugins/marktplaats-fy-NL.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Marktplaats.nl</ShortName>
-<Description>Sykje yn alle kategoryen op Marktplaats.nl</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABC0lEQVR42rSSoU7DUBSGv42FNKHiBtMrEE2KwnRysoIwP4UZ6SOQ9AW2B5hFN+BRCDZVSQKi9WtSeVFUVCwEgehdb0p2xQTHnfz/d3POf+6gyhYcU0OOrBGQpBSV7lcxod9zFBVJChBIZhOGrWk61rKq/z75mAFIwfKW6Xg/0s0eeH6j2Rm3qnXrCaTo7yAFUlAqSmWAp6zX9gBP4AmAh1cjr3PuIntKrVYq1rl2S8GZYwcCSSABPmuATc484lLaAdfRcptMUZn0rIebTXAdgOvFAfcBoJsKmEd2YKtodjryVWyC7k7ZqSf3cZSkvHzw1fC+5eqCcxcg9Al9kpRNzvePVk9HDP79t/4OALMxUpBz00CfAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="http://www.marktplaats.nl/z.html" resultdomain="marktplaats.nl">
- <Param name="client" value="firefox-search"/>
- <Param name="query" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.marktplaats.nl</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/marktplaats-nl.xml b/browser/locales/searchplugins/marktplaats-nl.xml
deleted file mode 100644
index 8d830cc8a..000000000
--- a/browser/locales/searchplugins/marktplaats-nl.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Marktplaats.nl</ShortName>
-<Description>Zoeken in alle categorieën op Marktplaats.nl</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABC0lEQVR42rSSoU7DUBSGv42FNKHiBtMrEE2KwnRysoIwP4UZ6SOQ9AW2B5hFN+BRCDZVSQKi9WtSeVFUVCwEgehdb0p2xQTHnfz/d3POf+6gyhYcU0OOrBGQpBSV7lcxod9zFBVJChBIZhOGrWk61rKq/z75mAFIwfKW6Xg/0s0eeH6j2Rm3qnXrCaTo7yAFUlAqSmWAp6zX9gBP4AmAh1cjr3PuIntKrVYq1rl2S8GZYwcCSSABPmuATc484lLaAdfRcptMUZn0rIebTXAdgOvFAfcBoJsKmEd2YKtodjryVWyC7k7ZqSf3cZSkvHzw1fC+5eqCcxcg9Al9kpRNzvePVk9HDP79t/4OALMxUpBz00CfAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="http://www.marktplaats.nl/z.html" resultdomain="marktplaats.nl">
- <Param name="client" value="firefox-search"/>
- <Param name="query" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.marktplaats.nl</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/mercadolibre-ar.xml b/browser/locales/searchplugins/mercadolibre-ar.xml
deleted file mode 100644
index e9f041528..000000000
--- a/browser/locales/searchplugins/mercadolibre-ar.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>MercadoLibre Argentina</ShortName>
-<Description>MercadoLibre Argentina</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCfDxAAnw8QAJ8ODwCgDAwApgUELqkBAHqmBQSwowgJwaMICcGmBQSxqQEAe6cFBC+hDAwAnw4PAJ8PEACfDxAAnw8QAJ8PEACnBQM1ogkKs3w6Q/lOcoj/MJix/x6kwf8fpsT/LZq0/010iv98OkP5ogkKtKcEAzafDxAAnw8QAJ8PDwCoAwFMfzY/7yqkv/8A2///AN3//xW42/9bqr//UKG3/zSqxv8A1P7/ANz//ymkwP9+N0DwqAMBTp8ODwCqAQEddEVR6QfR8/8A4f//Dbrf/3ybq//hwsP/8bWy/+qlo//rq6n/nIyW/x+w0/8A4f//B9L0/3JHU+qqAQAflxgbjA7D5/8A5P//CbXZ/7SRlv//19T/68TE/9+wsP/+/Pz/9OLi//jFw//IkpT/IqfG/wDk//8Mxun/lhkck25JVsQDwuj/NabA/5Scp//utbP/5by9/+7V1v/////////////////t0tL/67Kw/6iYof9Kobr/Dbrb/2pNW8ecNTqszb7D//ja2f///fv///////js6//w2tr////////////26Oj/3qyt//Lh4f///////+bk/9zEx/+gOj2yohAPPfPW1vz////////+///v7f/nn53/6qyq/+a6uv/pxcX/5LSz///o5v//9/X///n2///////y2Nj8ohERQZcAAACvMTJ11ba5/5C1wv9Wp7//WJau/5aQm//nvLz/6bW0/97Bw/+Wq7f/Yqe8/3GxxP/Cqq//sjMzdpYAAACaAgMAnAAAAJINEVU9dYrSAsbr/wDf//8A1v//Hrvc/zW40/8Ov+P/ANL4/wHE6f84fJTSixAWVp4AAACaAQIAmgIDAJsFBgCjAgAAqgEACo4jKFJvSlWVUmuBvDyDndI6hZ7STm+EvW5LWJWOIypSqwAACqQCAQCdCAkAmgECAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAD//wAA8A8AAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAwAMAAOAHAAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PEJ8ODzufDg9fnw4PfKANDo6gDQ6YoA0OmKANDo6fDg99nw4PYJ8ODzyfDg8Rnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PIJ8OD26gDQ20owkJ46YFBPqoAwH/qAMB/6gDAf+oAwH/qAMB/6gDAf+nBQT6owgJ5KANDrafDg9xnw4PIZ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4POaANDq+mBgb6qAMC/54PEP+GLDP/bUtY/1tidP9Ocof/R3mR/0d5kf9Ocof/WmJ1/21LWf+GLTT/nhAR/6gDAv+mBgX6oA0Os58ODz2fDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PD58ODqGnBAP/ogoK/3g+Sf8/g53/FrXa/wHQ+v8A2f//ANz//wDf//8A3v//ANv//wDe//8A3f//ANr//wHR+/8Vttr/PoSe/3c/Sv+iCwv/pwQD/6ANDqefDg8Rnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8OECKjCQnWpQcH/21LWf8fqsz/ANj//wDb//8A1f//ANH8/wDU/v8A1///C6/V/wi64f8A0vv/BbXd/wHP9v8A3P//ANT+/wDU//8A2///ANj//x6rzv9rTVv/pAgH/6MJCdqfDhAmnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDxAcpgYF4JMdIf8tmbj/ANv//wDX//8A0Pv/AND6/wDU/v8A1///A7jg/0J2jv/JfH3/rHF2/39WYf/EfoD/flNf/0J1jv8OvuL/ANz//wDR/P8A0Pr/ANf//wDc//8rnLv/kh4j/6YFBOSfDxAfnw4PAJ8ODwCfDg8Anw4PAKYGBrmJKTD/E7vf/wDc//8A0Pr/AND6/wDQ+v8A1v//Bbfe/0Fyiv/BcnT/1IOD///////14N//0X18/+/V1P/Vf37//87L/4pJUf8gj6//A8vy/wDT/f8A0Pr/AND6/wDc//8SveH/hysz/6YGBb6fDhAAnw4PAJ8ODwCjCgpXkx0h/xO94f8A2f//AND6/wDQ+v8A0vz/ANz//y2Orf/CcXL/35iX///9/f//////7tPT/9CIif/aoaL/5Lq7///////jurr/0Hl4/++opf9uZ3j/ANT//wDW/v8Az/r/AND6/wDZ//8RwOT/kR8k/6MJCVyfDg8AogoKJKYFBL42kaz/ANz//wDQ+v8A0Pr/ANL8/wXG7/9pa3z/slVY///19P////////////////+7WFn/366v////////////79bW/9CIif///////vj4/7dJSf+DWWX/IabH/wDV//8A0Pr/AND6/wDc//8zlLD/pgYFwqMJCTKoAwJggTM78QDV/f8A0fv/AND6/wDQ+v8A3///NIqi//S1sv/9/Pz/9ebm///////Sjo//z4aG/9KOjv/////////////////58fH//fv7//rx8f/GcXH/7NHS///x7v9+Xmn/AN3//wDS/P8A0Pr/ANH7/wDW//9+Nj/yqAMCbqILC4hVan7/AN7//wDV//8A2v//ANX//wus0v9tUV//z3Fw/82Cgv++XF3/xm9w/9aXmP/s0ND//fv7///////////////////////+/Pz/0YuM//DY2P//////2ZKS/4w8Q/8jj6//AMPt/wDa//8A2f//AOD//1Jugv+dEBGRmRYYk0CIn/8A1P//D6jN/zh8lv97X2v/x35///va2f/y3+D/7tTU//36+v/58fH///////////////////////////////////////36+v/68vP//v38/8l3eP/Wm5v//+/v/+Ofnv+lZWv/Y2Bx/ymJp/8Avuf/Oomj/5EhJZmbEROFg0BJ/5ZocP/KfX7/77Wz///w7v////////////////////////////////////////////////////////////////////////////nw8P/CZmf/362u///////////////////////82tf/45ua/7Zucf+UP0X/mhMWjpwDBFLCW1vp///////////////////////////////////////////+/f3/47i4/9WWl//v19f////////////////////////////x3Nz/v15f/+nHx////////////////////////////////////////////8ZoaOqeBwhhmwMEEKUeH5726ur//////////////////////////////////////9ujpP/Gb3D/6cjI/8Rra//YnJz/////////////////58PD/79eXv/y4OD////////////////////////////////////////////37Oz/piAhopoBAhufDQ4AmgECJ8VvcPT//////////////////////////////////////PPy/8t4ef/y39///////9OSk//EbGz/4bS0/9CJiv/Hc3P/+fDw/////////////////////////////////////////////////8d0dPWaAQIqngwNAJ8ODwCfDQ4AmgMEYtecnf////////////7g3v/mpaP/vnh6/5dncP+ebnb/wnBx/7kuLf/419b///////Hb2//UlJT/5b29/////////////d3a/+OhoP/Ihoj/v3+B/8yJiv/np6b//uPh///////YoaL/mwQFZZ8NDgCfDg8Anw4PAJ8ODwCeDA0AnQoLb818fP+nfYT/Xmx//yqJp/8Hs9r/AMr1/wDI8v8QrdL/LIyq/3Jbaf/dkpH//dfV///z8f//5OL/77Kw/7d0eP9gZnj/JJCv/wut0v8HtNr/DqnO/yWQr/9lanz/u1dY/6APEHKeCwwAnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDQ4AngAASW45RucNv+T/AOb//wDa//8A0v3/ANH7/wDV//8A2v//ANP7/x6Yuf9QcIX/a2d3/1xqff8xhKD/CLfe/wDa//8A2P//ANX//wDa//8A4f//DsHn/2RQYOmdAQFLnwwNAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDhAApgYFEp0QEoxgW23wHqzO/wHT+/8A3P//ANn//wDV//8A0/7/ANj//wDb//8A2f//ANv//wDc//8A2P//ANn//wDc//8B0/z/HazP/15db/GdEROOpwQDE58ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8AoAwNAKgDAhOiCgptgzA4xVhlePYxlLH/F7TY/wrE6/8DzPb/ANH6/wDR+v8Dzfb/CsTs/xe02P8wlbP/V2Z694IxOseiCgttqAMCFKEMDACfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODgCkCAgAqAMBGKcEA0ueDxB2lRodmosmLLOFLja/hS42v4smLLOVGh6ang8Qd6cFBEypAgEZpAgIAJ8NDgCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//////////////////////wAP//wAA//wAAD/wAAAP4AAAB8AAAAPAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAA+AAAAfwAAAP+AAAH/4AAH//wAP/////////////////////////////////</Image>
-<Url type="text/html" method="GET" template="http://www.mercadolibre.com.ar/jm/search" resultdomain="mercadolibre.com.ar">
- <Param name="as_word" value="{searchTerms}"/>
- <Param name="source" value="firefox_box"/>
-</Url>
-<SearchForm>http://www.mercadolibre.com.ar/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/mercadolibre-cl.xml b/browser/locales/searchplugins/mercadolibre-cl.xml
deleted file mode 100644
index 17a654c55..000000000
--- a/browser/locales/searchplugins/mercadolibre-cl.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>MercadoLibre Chile</ShortName>
-<Description>MercadoLibre Chile</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCfDxAAnw8QAJ8ODwCgDAwApgUELqkBAHqmBQSwowgJwaMICcGmBQSxqQEAe6cFBC+hDAwAnw4PAJ8PEACfDxAAnw8QAJ8PEACnBQM1ogkKs3w6Q/lOcoj/MJix/x6kwf8fpsT/LZq0/010iv98OkP5ogkKtKcEAzafDxAAnw8QAJ8PDwCoAwFMfzY/7yqkv/8A2///AN3//xW42/9bqr//UKG3/zSqxv8A1P7/ANz//ymkwP9+N0DwqAMBTp8ODwCqAQEddEVR6QfR8/8A4f//Dbrf/3ybq//hwsP/8bWy/+qlo//rq6n/nIyW/x+w0/8A4f//B9L0/3JHU+qqAQAflxgbjA7D5/8A5P//CbXZ/7SRlv//19T/68TE/9+wsP/+/Pz/9OLi//jFw//IkpT/IqfG/wDk//8Mxun/lhkck25JVsQDwuj/NabA/5Scp//utbP/5by9/+7V1v/////////////////t0tL/67Kw/6iYof9Kobr/Dbrb/2pNW8ecNTqszb7D//ja2f///fv///////js6//w2tr////////////26Oj/3qyt//Lh4f///////+bk/9zEx/+gOj2yohAPPfPW1vz////////+///v7f/nn53/6qyq/+a6uv/pxcX/5LSz///o5v//9/X///n2///////y2Nj8ohERQZcAAACvMTJ11ba5/5C1wv9Wp7//WJau/5aQm//nvLz/6bW0/97Bw/+Wq7f/Yqe8/3GxxP/Cqq//sjMzdpYAAACaAgMAnAAAAJINEVU9dYrSAsbr/wDf//8A1v//Hrvc/zW40/8Ov+P/ANL4/wHE6f84fJTSixAWVp4AAACaAQIAmgIDAJsFBgCjAgAAqgEACo4jKFJvSlWVUmuBvDyDndI6hZ7STm+EvW5LWJWOIypSqwAACqQCAQCdCAkAmgECAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAD//wAA8A8AAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAwAMAAOAHAAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PEJ8ODzufDg9fnw4PfKANDo6gDQ6YoA0OmKANDo6fDg99nw4PYJ8ODzyfDg8Rnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PIJ8OD26gDQ20owkJ46YFBPqoAwH/qAMB/6gDAf+oAwH/qAMB/6gDAf+nBQT6owgJ5KANDrafDg9xnw4PIZ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4POaANDq+mBgb6qAMC/54PEP+GLDP/bUtY/1tidP9Ocof/R3mR/0d5kf9Ocof/WmJ1/21LWf+GLTT/nhAR/6gDAv+mBgX6oA0Os58ODz2fDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PD58ODqGnBAP/ogoK/3g+Sf8/g53/FrXa/wHQ+v8A2f//ANz//wDf//8A3v//ANv//wDe//8A3f//ANr//wHR+/8Vttr/PoSe/3c/Sv+iCwv/pwQD/6ANDqefDg8Rnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8OECKjCQnWpQcH/21LWf8fqsz/ANj//wDb//8A1f//ANH8/wDU/v8A1///C6/V/wi64f8A0vv/BbXd/wHP9v8A3P//ANT+/wDU//8A2///ANj//x6rzv9rTVv/pAgH/6MJCdqfDhAmnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDxAcpgYF4JMdIf8tmbj/ANv//wDX//8A0Pv/AND6/wDU/v8A1///A7jg/0J2jv/JfH3/rHF2/39WYf/EfoD/flNf/0J1jv8OvuL/ANz//wDR/P8A0Pr/ANf//wDc//8rnLv/kh4j/6YFBOSfDxAfnw4PAJ8ODwCfDg8Anw4PAKYGBrmJKTD/E7vf/wDc//8A0Pr/AND6/wDQ+v8A1v//Bbfe/0Fyiv/BcnT/1IOD///////14N//0X18/+/V1P/Vf37//87L/4pJUf8gj6//A8vy/wDT/f8A0Pr/AND6/wDc//8SveH/hysz/6YGBb6fDhAAnw4PAJ8ODwCjCgpXkx0h/xO94f8A2f//AND6/wDQ+v8A0vz/ANz//y2Orf/CcXL/35iX///9/f//////7tPT/9CIif/aoaL/5Lq7///////jurr/0Hl4/++opf9uZ3j/ANT//wDW/v8Az/r/AND6/wDZ//8RwOT/kR8k/6MJCVyfDg8AogoKJKYFBL42kaz/ANz//wDQ+v8A0Pr/ANL8/wXG7/9pa3z/slVY///19P////////////////+7WFn/366v////////////79bW/9CIif///////vj4/7dJSf+DWWX/IabH/wDV//8A0Pr/AND6/wDc//8zlLD/pgYFwqMJCTKoAwJggTM78QDV/f8A0fv/AND6/wDQ+v8A3///NIqi//S1sv/9/Pz/9ebm///////Sjo//z4aG/9KOjv/////////////////58fH//fv7//rx8f/GcXH/7NHS///x7v9+Xmn/AN3//wDS/P8A0Pr/ANH7/wDW//9+Nj/yqAMCbqILC4hVan7/AN7//wDV//8A2v//ANX//wus0v9tUV//z3Fw/82Cgv++XF3/xm9w/9aXmP/s0ND//fv7///////////////////////+/Pz/0YuM//DY2P//////2ZKS/4w8Q/8jj6//AMPt/wDa//8A2f//AOD//1Jugv+dEBGRmRYYk0CIn/8A1P//D6jN/zh8lv97X2v/x35///va2f/y3+D/7tTU//36+v/58fH///////////////////////////////////////36+v/68vP//v38/8l3eP/Wm5v//+/v/+Ofnv+lZWv/Y2Bx/ymJp/8Avuf/Oomj/5EhJZmbEROFg0BJ/5ZocP/KfX7/77Wz///w7v////////////////////////////////////////////////////////////////////////////nw8P/CZmf/362u///////////////////////82tf/45ua/7Zucf+UP0X/mhMWjpwDBFLCW1vp///////////////////////////////////////////+/f3/47i4/9WWl//v19f////////////////////////////x3Nz/v15f/+nHx////////////////////////////////////////////8ZoaOqeBwhhmwMEEKUeH5726ur//////////////////////////////////////9ujpP/Gb3D/6cjI/8Rra//YnJz/////////////////58PD/79eXv/y4OD////////////////////////////////////////////37Oz/piAhopoBAhufDQ4AmgECJ8VvcPT//////////////////////////////////////PPy/8t4ef/y39///////9OSk//EbGz/4bS0/9CJiv/Hc3P/+fDw/////////////////////////////////////////////////8d0dPWaAQIqngwNAJ8ODwCfDQ4AmgMEYtecnf////////////7g3v/mpaP/vnh6/5dncP+ebnb/wnBx/7kuLf/419b///////Hb2//UlJT/5b29/////////////d3a/+OhoP/Ihoj/v3+B/8yJiv/np6b//uPh///////YoaL/mwQFZZ8NDgCfDg8Anw4PAJ8ODwCeDA0AnQoLb818fP+nfYT/Xmx//yqJp/8Hs9r/AMr1/wDI8v8QrdL/LIyq/3Jbaf/dkpH//dfV///z8f//5OL/77Kw/7d0eP9gZnj/JJCv/wut0v8HtNr/DqnO/yWQr/9lanz/u1dY/6APEHKeCwwAnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDQ4AngAASW45RucNv+T/AOb//wDa//8A0v3/ANH7/wDV//8A2v//ANP7/x6Yuf9QcIX/a2d3/1xqff8xhKD/CLfe/wDa//8A2P//ANX//wDa//8A4f//DsHn/2RQYOmdAQFLnwwNAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDhAApgYFEp0QEoxgW23wHqzO/wHT+/8A3P//ANn//wDV//8A0/7/ANj//wDb//8A2f//ANv//wDc//8A2P//ANn//wDc//8B0/z/HazP/15db/GdEROOpwQDE58ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8AoAwNAKgDAhOiCgptgzA4xVhlePYxlLH/F7TY/wrE6/8DzPb/ANH6/wDR+v8Dzfb/CsTs/xe02P8wlbP/V2Z694IxOseiCgttqAMCFKEMDACfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODgCkCAgAqAMBGKcEA0ueDxB2lRodmosmLLOFLja/hS42v4smLLOVGh6ang8Qd6cFBEypAgEZpAgIAJ8NDgCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//////////////////////wAP//wAA//wAAD/wAAAP4AAAB8AAAAPAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAA+AAAAfwAAAP+AAAH/4AAH//wAP/////////////////////////////////</Image>
-<Url type="text/html" method="GET" template="http://www.mercadolibre.cl/jm/search" resultdomain="mercadolibre.cl">
- <Param name="as_word" value="{searchTerms}"/>
- <Param name="source" value="firefox_box"/>
-</Url>
-<SearchForm>http://www.mercadolibre.cl/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/mercadolibre-mx.xml b/browser/locales/searchplugins/mercadolibre-mx.xml
deleted file mode 100644
index 49dd89e18..000000000
--- a/browser/locales/searchplugins/mercadolibre-mx.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>MercadoLibre Mexico</ShortName>
-<Description>MercadoLibre Mexico</Description>
-<InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCfDxAAnw8QAJ8ODwCgDAwApgUELqkBAHqmBQSwowgJwaMICcGmBQSxqQEAe6cFBC+hDAwAnw4PAJ8PEACfDxAAnw8QAJ8PEACnBQM1ogkKs3w6Q/lOcoj/MJix/x6kwf8fpsT/LZq0/010iv98OkP5ogkKtKcEAzafDxAAnw8QAJ8PDwCoAwFMfzY/7yqkv/8A2///AN3//xW42/9bqr//UKG3/zSqxv8A1P7/ANz//ymkwP9+N0DwqAMBTp8ODwCqAQEddEVR6QfR8/8A4f//Dbrf/3ybq//hwsP/8bWy/+qlo//rq6n/nIyW/x+w0/8A4f//B9L0/3JHU+qqAQAflxgbjA7D5/8A5P//CbXZ/7SRlv//19T/68TE/9+wsP/+/Pz/9OLi//jFw//IkpT/IqfG/wDk//8Mxun/lhkck25JVsQDwuj/NabA/5Scp//utbP/5by9/+7V1v/////////////////t0tL/67Kw/6iYof9Kobr/Dbrb/2pNW8ecNTqszb7D//ja2f///fv///////js6//w2tr////////////26Oj/3qyt//Lh4f///////+bk/9zEx/+gOj2yohAPPfPW1vz////////+///v7f/nn53/6qyq/+a6uv/pxcX/5LSz///o5v//9/X///n2///////y2Nj8ohERQZcAAACvMTJ11ba5/5C1wv9Wp7//WJau/5aQm//nvLz/6bW0/97Bw/+Wq7f/Yqe8/3GxxP/Cqq//sjMzdpYAAACaAgMAnAAAAJINEVU9dYrSAsbr/wDf//8A1v//Hrvc/zW40/8Ov+P/ANL4/wHE6f84fJTSixAWVp4AAACaAQIAmgIDAJsFBgCjAgAAqgEACo4jKFJvSlWVUmuBvDyDndI6hZ7STm+EvW5LWJWOIypSqwAACqQCAQCdCAkAmgECAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//AAD//wAA8A8AAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAwAMAAOAHAAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PEJ8ODzufDg9fnw4PfKANDo6gDQ6YoA0OmKANDo6fDg99nw4PYJ8ODzyfDg8Rnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PIJ8OD26gDQ20owkJ46YFBPqoAwH/qAMB/6gDAf+oAwH/qAMB/6gDAf+nBQT6owgJ5KANDrafDg9xnw4PIZ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4POaANDq+mBgb6qAMC/54PEP+GLDP/bUtY/1tidP9Ocof/R3mR/0d5kf9Ocof/WmJ1/21LWf+GLTT/nhAR/6gDAv+mBgX6oA0Os58ODz2fDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PD58ODqGnBAP/ogoK/3g+Sf8/g53/FrXa/wHQ+v8A2f//ANz//wDf//8A3v//ANv//wDe//8A3f//ANr//wHR+/8Vttr/PoSe/3c/Sv+iCwv/pwQD/6ANDqefDg8Rnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8OECKjCQnWpQcH/21LWf8fqsz/ANj//wDb//8A1f//ANH8/wDU/v8A1///C6/V/wi64f8A0vv/BbXd/wHP9v8A3P//ANT+/wDU//8A2///ANj//x6rzv9rTVv/pAgH/6MJCdqfDhAmnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDxAcpgYF4JMdIf8tmbj/ANv//wDX//8A0Pv/AND6/wDU/v8A1///A7jg/0J2jv/JfH3/rHF2/39WYf/EfoD/flNf/0J1jv8OvuL/ANz//wDR/P8A0Pr/ANf//wDc//8rnLv/kh4j/6YFBOSfDxAfnw4PAJ8ODwCfDg8Anw4PAKYGBrmJKTD/E7vf/wDc//8A0Pr/AND6/wDQ+v8A1v//Bbfe/0Fyiv/BcnT/1IOD///////14N//0X18/+/V1P/Vf37//87L/4pJUf8gj6//A8vy/wDT/f8A0Pr/AND6/wDc//8SveH/hysz/6YGBb6fDhAAnw4PAJ8ODwCjCgpXkx0h/xO94f8A2f//AND6/wDQ+v8A0vz/ANz//y2Orf/CcXL/35iX///9/f//////7tPT/9CIif/aoaL/5Lq7///////jurr/0Hl4/++opf9uZ3j/ANT//wDW/v8Az/r/AND6/wDZ//8RwOT/kR8k/6MJCVyfDg8AogoKJKYFBL42kaz/ANz//wDQ+v8A0Pr/ANL8/wXG7/9pa3z/slVY///19P////////////////+7WFn/366v////////////79bW/9CIif///////vj4/7dJSf+DWWX/IabH/wDV//8A0Pr/AND6/wDc//8zlLD/pgYFwqMJCTKoAwJggTM78QDV/f8A0fv/AND6/wDQ+v8A3///NIqi//S1sv/9/Pz/9ebm///////Sjo//z4aG/9KOjv/////////////////58fH//fv7//rx8f/GcXH/7NHS///x7v9+Xmn/AN3//wDS/P8A0Pr/ANH7/wDW//9+Nj/yqAMCbqILC4hVan7/AN7//wDV//8A2v//ANX//wus0v9tUV//z3Fw/82Cgv++XF3/xm9w/9aXmP/s0ND//fv7///////////////////////+/Pz/0YuM//DY2P//////2ZKS/4w8Q/8jj6//AMPt/wDa//8A2f//AOD//1Jugv+dEBGRmRYYk0CIn/8A1P//D6jN/zh8lv97X2v/x35///va2f/y3+D/7tTU//36+v/58fH///////////////////////////////////////36+v/68vP//v38/8l3eP/Wm5v//+/v/+Ofnv+lZWv/Y2Bx/ymJp/8Avuf/Oomj/5EhJZmbEROFg0BJ/5ZocP/KfX7/77Wz///w7v////////////////////////////////////////////////////////////////////////////nw8P/CZmf/362u///////////////////////82tf/45ua/7Zucf+UP0X/mhMWjpwDBFLCW1vp///////////////////////////////////////////+/f3/47i4/9WWl//v19f////////////////////////////x3Nz/v15f/+nHx////////////////////////////////////////////8ZoaOqeBwhhmwMEEKUeH5726ur//////////////////////////////////////9ujpP/Gb3D/6cjI/8Rra//YnJz/////////////////58PD/79eXv/y4OD////////////////////////////////////////////37Oz/piAhopoBAhufDQ4AmgECJ8VvcPT//////////////////////////////////////PPy/8t4ef/y39///////9OSk//EbGz/4bS0/9CJiv/Hc3P/+fDw/////////////////////////////////////////////////8d0dPWaAQIqngwNAJ8ODwCfDQ4AmgMEYtecnf////////////7g3v/mpaP/vnh6/5dncP+ebnb/wnBx/7kuLf/419b///////Hb2//UlJT/5b29/////////////d3a/+OhoP/Ihoj/v3+B/8yJiv/np6b//uPh///////YoaL/mwQFZZ8NDgCfDg8Anw4PAJ8ODwCeDA0AnQoLb818fP+nfYT/Xmx//yqJp/8Hs9r/AMr1/wDI8v8QrdL/LIyq/3Jbaf/dkpH//dfV///z8f//5OL/77Kw/7d0eP9gZnj/JJCv/wut0v8HtNr/DqnO/yWQr/9lanz/u1dY/6APEHKeCwwAnw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDQ4AngAASW45RucNv+T/AOb//wDa//8A0v3/ANH7/wDV//8A2v//ANP7/x6Yuf9QcIX/a2d3/1xqff8xhKD/CLfe/wDa//8A2P//ANX//wDa//8A4f//DsHn/2RQYOmdAQFLnwwNAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDhAApgYFEp0QEoxgW23wHqzO/wHT+/8A3P//ANn//wDV//8A0/7/ANj//wDb//8A2f//ANv//wDc//8A2P//ANn//wDc//8B0/z/HazP/15db/GdEROOpwQDE58ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8AoAwNAKgDAhOiCgptgzA4xVhlePYxlLH/F7TY/wrE6/8DzPb/ANH6/wDR+v8Dzfb/CsTs/xe02P8wlbP/V2Z694IxOseiCgttqAMCFKEMDACfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODgCkCAgAqAMBGKcEA0ueDxB2lRodmosmLLOFLja/hS42v4smLLOVGh6ang8Qd6cFBEypAgEZpAgIAJ8NDgCfDg8Anw4PAJ8ODwCfDg8Anw4PAJ8ODwCfDg8Anw4PAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP//////////////////////wAP//wAA//wAAD/wAAAP4AAAB8AAAAPAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAA+AAAAfwAAAP+AAAH/4AAH//wAP/////////////////////////////////</Image>
-<Url type="text/html" method="GET" template="http://www.mercadolibre.com.mx/jm/search" resultdomain="mercadolibre.com.mx">
- <Param name="as_word" value="{searchTerms}"/>
- <Param name="source" value="firefox_box"/>
-</Url>
-<SearchForm>http://www.mercadolibre.com.mx/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/mercadolivre.xml b/browser/locales/searchplugins/mercadolivre.xml
deleted file mode 100644
index 28be3c307..000000000
--- a/browser/locales/searchplugins/mercadolivre.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>MercadoLivre</ShortName>
-<Description>Onde comprar e vender de Tudo.</Description>
-<InputEncoding>iso-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABnklEQVR4nGNgGPqA8f///wwMDP///7199/2Js28fPvspI/b3758P////Y2IWfPiCjYeX1d9ZREWRj5mFlYGBgeH///+XrrycMONSZtk5LeOw//8Z0FBVuYSm1eaqljNHTjz6//8/4/lLL1asedTRaPr3H8P+A7vF+dM+fDBk5Cj+8OkDL8ctxr+b/zDYCktU6euwF1WfDPaVYsgsPnL+0vPnz/7+RwUXrvw/fALB/fXt/8sX3+z9N7F8/PznyOkPxzdpJMSp/WXtklV3EORjkJJg0NdmOHb624rNXAL/lgmy1967fe8h6/nnr38y8QmyLlj5nFk8zDXotIe04945NacuMhw7x/DkE8Odp1yP95R46Eabe9z7yKy3fstHNSUhhj9/fzoG7mBgWJCcZAD36OalfVuXNJ7dwAvhtjYqMjDMEtVe9+HjVwaIE2cvvcjAuI6BqSIzT3DLCoZdyxj2rWLYvpqhqJSfgSuHgWFVXc9piEpG5Eh58Oz/zj2fn7x79erN+1+//3NzcKtKSznYC+ipMTAwMDAyMmKJyEEAAHOj6iZS/gfAAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="http://pmstrk.mercadolivre.com.br/jm/PmsTrk" resultdomain="mercadolivre.com.br">
- <Param name="tool" value="5668605"/>
- <Param name="go" value="/jm/search%3fas_word={searchTerms}%26as_search_both=N"/>
-</Url>
-<SearchForm>http://www.mercadolivre.com.br/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/meta-ua.xml b/browser/locales/searchplugins/meta-ua.xml
deleted file mode 100644
index 1392dc098..000000000
--- a/browser/locales/searchplugins/meta-ua.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>&lt;META&gt;</ShortName>
-<Description>УкраїнÑька пошукова ÑиÑтема.</Description>
-<InputEncoding>windows-1251</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABgUExURUJicNDy9Oz19AJ2thGF1YvN9Cqa87bm9Eax9C2Uzv/eH2u36wBsqwJ/xHjG812686WGCjSi9ESi26je9MadABqN4JyyxBiAunV2VA5ZmP/1hCeDwCNmj3Ogwhd/vP///4N3QeoAAAAgdFJOU/////////////////////////////////////////8AXFwb7QAAAKZJREFUeNpEj+sWgyAMgykKFE3FG5ub23j/t1zRedZfzXcgaUypA8wo55hD72R7/AF6a4mlCPADROQ4i6WIE3yWkNhHCi7D6MOhb5g5D2FgFiP6n8LdbK9F9QQTLYUlGfscuepiEFTz1nXr7nNNQRq4jbdx3aybW9GUxstsyb3VK3FNKXgsuqqXUxccd9S8JiW+QFNX71H1eelUAbQzrrYQuep/BRgAuVcP4GB+AzgAAAAASUVORK5CYII=</Image>
-<SearchForm>http://search.meta.ua/</SearchForm>
-<Url type="text/html" method="GET" template="http://meta.ua/search.asp" resultdomain="meta.ua">
- <Param name="q" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<Url type="application/x-suggestions+json" method="GET" template="http://meta.ua/suggestions/">
- <Param name="output" value="fxjson"/>
- <Param name="q" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-suggestqueries"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/metamarket.xml b/browser/locales/searchplugins/metamarket.xml
deleted file mode 100644
index 8e3d2d69c..000000000
--- a/browser/locales/searchplugins/metamarket.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>МетаМаркет</ShortName>
-<Description>МетаМаркет - пошук товарів.</Description>
-<InputEncoding>windows-1251</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABgUExURQCZ/wCJ//+sAKnq/1jN/wC5/4/X/wCn/wDi/wDW/wDK/47n/1Xo/wBi//+VAP/AAAB4//r+/wtp9Rfp/4/x/wtt/xfR/xe+/xei/8f3/wDo/wAzmf/MAP9mAP///////4Gaq4UAAAAgdFJOU/////////////////////////////////////////8AXFwb7QAAAJVJREFUeNo8zYsOgyAMQNE6HuJrAwQnTMv//+VaQW8CaU9IgFLLHA/A13HGHGN84DzKL/OpcB6enxtjBuqCJed1DiLM2zgyfJa8BoeIbtoqeDM7RWCdvCEkpdBanBTDyw8iAUJaUDQYp2QTEui+gUwWCZxsoL6SfklO78Dw9opECy13aNBTQHVd90BdLyjlB/dK8BdgAKQCEpRJB2uO</Image>
-<SearchForm>http://metamarket.ua/</SearchForm>
-<Url type="text/html" method="GET" template="http://metamarket.ua/ua/search/" resultdomain="metamarket.ua">
- <Param name="q" value="{searchTerms}"/>
- <Param name="m" value="market"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/morfix-dic.xml b/browser/locales/searchplugins/morfix-dic.xml
deleted file mode 100644
index e5572475f..000000000
--- a/browser/locales/searchplugins/morfix-dic.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!-- milon.morfix.co.il MozSearch plugin
- Compatible with Mozilla Firefox 2+
- Tomer Cohen, September 2006 - http://mozilla.org.il -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>מילון מורפיקס</ShortName>
- <Description></Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+g
-vaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gkdCRktdt52QwAAACR0
-RVh0Q29tbWVudABUb21lciBDb2hlbgp0b21lcmNAZ21haWwuY29tUau7swAAAxxJ
-REFUOMttk91rm2UYxq/7eZ/3fZO8SZqlcflct2at/YjokDJBPNAyHW4Hgw31wP9B
-kP0Bngw2QWHsxFOPdjJPhG1MEaqIddOWDbqxOmrStE3atGk+lrxJ3o/neTxYtlXx
-hpv74Oa64Oa+foQDpZQCAALAAPDhJADiQCsieqGh/4g5gCCAmO85cdFvhZVUJM0R
-O2AGGsTQJFAPgP/chA6IdQBxr7MzIde+m9Vqi+OsUxwl4ULo0dZecK4kXvvsYTqb
-faJpWuO5CQeAXrerBa1QzKuvnmD3L79n7P55grqVDKRrASAO6qfZcmV/69bY2utf
-BkLH37jfdBpNAJKqb09TMZM2kl9cyR+tfnNB37pzBv3GEQCaAgQ9O8sA4ChQ8fF+
-9IdL5vTNTlquCiUG2sUwo+ZGVTemvUzSXniX7NqbAPi+jcqDCisZnLXCpjIARAkI
-jZiOXyw1d5YIVWn6fQYACsCxSFUjuxYFoA181H4pmUsL1uc//n7k65/7RvoJABtA
-iGvInrS8XGptKjxWn2EcAJ6mQiogGgTpAkC372GjTIWVs+c/fliYmR11/thN4dFX
-efiuxYBgBH7o7NxpY/7UB8QBQHZcLJRT0zFnaqrbE/H1QWyCItnruUzW1Q2DfCsB
-MAOAKxXg+hKOyTX/cDKp+A1KKxUPQ7fzj47K1pzrdNHCYeTe+vSiETAPOY1iRt+7
-Ow7hWgAcV2Bvs2PVzEjcJkaSz9+4Tp7jUDqTIfb420uB7dtzuqoaJq721E/XFEkn
-Rp1yGsLVQahtNdVff4vJ4ju5XDcSjChemJkBAO5sL0eM+vejrL2SgvQPvUypYlBK
-Athp2Hhwd8u6xyfPrR8fHx+AoPgwksrr7Qv96UYPwm0PGWAApFQYeAL17bZa/W3T
-uree+GT59Pz79WQyKRhj4MMvuvKVk5srzfyi2N3dAxAeGvgKsEvt4HZZ5Ivs1Y/W
-z5z6sD5bKDicc3WQBVJSBsqVamxp8ddou93ShzsJYo5hjdj5Y2OdyYmJQSKREJqm
-qf+jkQAw3/eZEPIlrgTFGJOapiki+hfKAPAPFp9sbyN2GzAAAAAASUVORK5CYII=
-</Image>
- <Url type="text/html" method="GET" template="http://milon.morfix.co.il/default.aspx" resultdomain="morfix.co.il">
- <Param name="q" value="{searchTerms}"/>
- </Url>
- <SearchForm>http://milon.morfix.co.il/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/najdi-si.xml b/browser/locales/searchplugins/najdi-si.xml
deleted file mode 100644
index 2e396c714..000000000
--- a/browser/locales/searchplugins/najdi-si.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Najdi.si</ShortName>
-<Description>Iskalnik Najdi.si</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABSlBMVEUAO1QQR148aXxghZVhhZUQR19Xfo7O2d75+vv////6+/vP2t9Yf49wkZ/4+vrk6+19m6dCboBCbYB7mqfj6uxzk6FEcIL2+PnC0NYgU2kMRFweUmjAztT29/hGcYMEPle0xs3z9vchVWqEoKzN2d5+nKkfU2ny9fa3x88FP1cAOlMfUmjl6+2ovMV9m6jE0dfc5OeetL2lucLm7O4vXnP19/h8maYFPlcmWG3V3uN7mKX3+PkwX3QqW2/x9PWLprEkVmzQ299/namIoq7U3uLY4eU8aHxtj50YTGMEPVbQ2t/V3+MRSF9+m6j9/v73+foDPVULQlpuj51IcoNoipn+/f6DoKwKQlp2lKGjucFNdocMQ1t6mKXR2+AUSmGkucLBz9Xv8/T8/f3G09kaT2WJpK/U3eK0xc1jh5YNQ1sCO1QORFwNRFwBO1TzxcIvAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YJCQkmNJUQNHcAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAL5JREFUGNNjYMAKGJmYWZhYEXw2dg5OTi5uHhifl49fQFBIWIRDFMIXE5eQlAICaRlZORBfXkFRSVkFCFTV1DU0GRi0tHV0tfT0DTg5DbWMjCW1GLRMTM20zC0sQQJW1jZAAVs7ey0HRw4nO0MtZztboACji6sbu7i7h52hp5e3D1BAy9fPX9w9IDAoOCQ0TAskEB4RGeWppRUdoxgbBxYAgfgEicSk5BQtuECqS1p6RqYWQiArOycXwoIKIAAAP8Amx8T+6hgAAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://www.najdi.si/search.jsp" resultdomain="najdi.si">
- <Param name="q" value="{searchTerms}"/>
- <Param name="o" value="0"/>
- <Param name="foxsbar" value="ff"/>
-</Url>
-<SearchForm>http://www.najdi.si/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/naver-kr.xml b/browser/locales/searchplugins/naver-kr.xml
deleted file mode 100644
index 158f9f269..000000000
--- a/browser/locales/searchplugins/naver-kr.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>네ì´ë²„</ShortName>
-<Description>네ì´ë²„ 검색</Description>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAMgdEADIHb8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgdvwDIHRAAyB2/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgdvwDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf////////////////////////////////8/1lX/AMgd/wDIHf8AyB3/AMgd/8/11f////////////////////////////////8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/////////////////////////////////z/WVf8AyB3/AMgd/wDIHf9/5I7//////////////////////////////////////wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/////////////////////////////////P9ZV/wDIHf8AyB3/P9ZV////////////////////////////////////////////AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf////////////////////////////////8/1lX/AMgd/xDLK//f+OP///////////////////////////////////////////8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/////////////////////////////////z/WVf8AyB3/nuqp/////////////////////////////////////////////////wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/////////////////////////////////P9ZV/0/ZZP//////////////////////////////////////////////////////AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf////////////////////////////////9P2WT/7/zx//////////////////////////////////////////////////////8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/////////////////////////////////+/88f///////////////////////////////////////////////////////////wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3////////////////////////////////////////////////////////////P9dX/////////////////////////////////AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf//////////////////////////////////////////////////////z/XV/0/ZZP////////////////////////////////8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd//////////////////////////////////////////////////////8v0kf/P9ZV/////////////////////////////////wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/////////////////////////////////////////////////b+CA/wDIHf8/1lX/////////////////////////////////AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf///////////////////////////////////////////77xx/8AyB3/AMgd/z/WVf////////////////////////////////8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd///////////////////////////////////////v/PH/H885/wDIHf8AyB3/P9ZV/////////////////////////////////wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3//////////////////////////////////////0/ZZP8AyB3/AMgd/wDIHf8/1lX/////////////////////////////////AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf////////////////////////////////+u7rf/AMgd/wDIHf8AyB3/AMgd/z/WVf////////////////////////////////8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgdvwDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHb8AyB0QAMgdvwDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB2/AMgdEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAABAAAAAgAAAAAQAgAAAAAABABAAAAAAAAAAAAAAAAAAAAAAAAADIHYAAyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHYAAyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf9/5I7///////////++8cf/AMgd/z/WVf////////////////9/5I7/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/f+SO////////////vvHH/wDIHf/f+OP/////////////////f+SO/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/3/kjv///////////77xx/9/5I7//////////////////////3/kjv8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf9/5I7////////////f+OP///////////////////////////9/5I7/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/f+SO////////////////////////////3/jj////////////f+SO/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/3/kjv//////////////////////f+SO/77xx////////////3/kjv8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf9/5I7/////////////////3/jj/wDIHf++8cf///////////9/5I7/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/f+SO/////////////////z/WVf8AyB3/vvHH////////////f+SO/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHYAAyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHf8AyB3/AMgd/wDIHYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://ac.search.naver.com/nx/ac">
- <Param name="of" value="os" />
- <Param name="ie" value="utf-8" />
- <Param name="q" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="http://search.naver.com/search.naver" resultdomain="naver.com">
- <Param name="where" value="nexearch"/>
- <Param name="frm" value="ff"/>
- <Param name="sm" value="oss"/>
- <Param name="ie" value="utf8"/>
- <Param name="query" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://search.naver.com</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/neti-ee.xml b/browser/locales/searchplugins/neti-ee.xml
deleted file mode 100644
index d3b8d6ad8..000000000
--- a/browser/locales/searchplugins/neti-ee.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Neti</ShortName>
-<Description>Neti</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAApBJREFUOBGlkrtv01AUxn92nDhvJ4TQNG0FdCjiIVGpAtEhEzDCgFgqMfAHsDKx8IewITEjkGCohBBCAgaoeAgKKVAVWtqkSZM0ieP4cbl2FZfOXPn6WL7fd853vnuU6VtPBf+xNFWSPbkPRKuDufYap7kKkRiR4gkS5VmUaOIgTvI0nzxaQni0q4vsfl0Es41imwhJcraW0dbeYMxcIjN2ZgQPYqjA8xyab+/Tq1WJ6mmSpyrECpNSnorV2MBsbtCuf8PVkmQL02GSUEHr8+OAnJw6iXH9NpqRx3NcRN8i1uqSbjbo/PrEUI3jyGKaqu0rsNtr9FaeE8uVyC3cYbxc4HhGozUUrGybWK5HxLYxxvfkK7oOAytIoPoe9KvPUM0OmdnL6Lkss4UYN2dSXJzQKWZjEJdb01AjGj5ZHMri5TKBoarvvt34IXu10Y+eRbgCRwi6jpCVBfLZX6oSfItiDmQCv3jggSevyksYKEqcoTnkXT3KpunRtT3qrQFKzwTHAdmKHlEpljL0cej4CXwFqnTVcx2G9d9EjSNsS2BzJxJU83ZNIr2B7NNCcV1KRYP5ks6HLZfWSEFico7+oM1gvYpenJEzYCG0vQQR3yxJ1mT0JV89V2aqEOXFejPwIFCQkJMW3/2DJRFWbYt42pCyfG3IYXKCyj75yvkprs2VePK+xma9G5yHc5CfusBOt4ki/RCSrHjy6oZ2ACrkEyxUjnGjMslqrc+9R1/CkQ4nMRqNczhfRsSiiGwKp2CQLaaZH9OpTCQ5ndN4Vd3h7oOPtE07SOBnDxUEpeRLkVVFp4eSiqOIFIOhw1K1wcPvNZaW64EPI6wfQwWjn0Hn0jDt5wYduV/KA79///+/cYT/C7yAFby9xs1kAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="http://www.neti.ee/cgi-bin/otsing" resultdomain="neti.ee">
- <Param name="query" value="{searchTerms}"/>
- <Param name="src" value="web"/>
-</Url>
-<SearchForm>http://www.neti.ee/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/odpiralni.xml b/browser/locales/searchplugins/odpiralni.xml
deleted file mode 100644
index 3a109bc90..000000000
--- a/browser/locales/searchplugins/odpiralni.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Odpiralni ÄŒasi</ShortName>
-<Description>Odpiralni ÄŒasi v Sloveniji</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAnlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuMS4yIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBJbWFnZVJlYWR5PC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjI5OTk5LzEwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+Mjk5OTkvMTAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KHvZwVAAAA0xJREFUOBE9U99PHFUYPXPv/NjdWXELLlRbgUSRXYxtgEVAcfXR/tBqGpBoaNIE+2rE+NAQH/AvUN980gf6Aib2uZhg0sqq2fWBVEtraRNghbWwdJlhdnfu/Oh3J6E3uZncOznnfOfc71PCMMTExARfWFjwFVrv5POXAs+bcuzD0WajkfB9H3HTPDRN8xZT+PyvKzevESZ8ihkfH4/AQ0NDvaZuzDu2nXMOHbzSl8XJF09C0zQ8fPAQ/95ZQywRh5k0f3cbjamVUum+JFFkBWME5pp+s7a/n3711CkxPvkR6+vL8kMiery/j3Q6jXt37/qLC4vh2t//qC2plh3Pdcd+KxbXmSxb1fV5q1ZLj72dd6/Ozmq53CBPJpP4q1TCl5/PwPM89Pf385kvZtTXR4dd68A6rurGD6DF8iMjlzzh5dIdHd7l6Wk9lXoWtmUTyIcQHuyDAzSbTdi2jYRpYmJyUm9ta/N8z3srP/LmRcY17ePKf9t474MLyvGODjh1RxIjCAJAAWWgA2RTHuqOg/b2drx75oxS3d0DU9knTLjijVRbKzLZLJeJS2AQBgjpK7fCFDqHdO8TTwhSRld3F3umpQWeEHnmus1kmliletN1IzHfJ2CkqURWJJEklgSCCMiCcuy5VknQpiKqTol+RuoENnQd5XIZSzdu4KWel0E5w5ckRKBIItryTi6mappT3d1FpVKJLqlibG1u4uu5OWxvlTF95VMYhhG9hBSQsD3yb9UOwFW1xuhn4dFOBQ/W132VMTQo8e+++RZ7/+/i6lez6O7uhitEFGRAGcmKNzY2fNuyiEAr8M4TnYjFYx9ub+8Eg7lBFovFYNA+//55dHZ1oV6vR6XKXtBUDdVqFT8tLgZkieTYHKfGuN2s1y+UN7deoBBFJpPhvZleJOLx6P2lV+lZp+e0bAvXr/8s1u/dJy6teOuPwmdRKw8PDJ82DL5CrZw4PTAgzp47y0lddmmUvk9NRbkEvywt+bdXV7VYPL7neWJspVhcU46GaTSXG9B140eawtdCMtqbzSCVOkbBgubhcTRQBJL2VoUbThZKhTtPh+loNHt6eowT7c9fCQIxRYPUT02jyio45z6p/sm5do0Z6vfLy8veEeYJlojIHKnXHv0AAAAASUVORK5CYII=</Image>
-<UpdateUrl>http://www.odpiralnicasi.com/opensearch/description.xml</UpdateUrl>
-<Url type="text/html" method="GET" template="http://www.odpiralnicasi.com/spots" resultdomain="odpiralnicasi.com">
- <Param name="q" value="{searchTerms}"/>
- <Param name="source" value="1"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/olx.xml b/browser/locales/searchplugins/olx.xml
deleted file mode 100644
index 4163104d2..000000000
--- a/browser/locales/searchplugins/olx.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>OLX.ba</ShortName>
-<Description>OLX.ba pretraživaÄ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yH///+N////zP//////////////z////5D///8nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///3L////z////////////////////////////////////9v///3IAAAAAAAAAAAAAAAAAAAAA////Bv///7f/////////////////////////////////////////////////////////wP///wYAAAAAAAAAAP///5D///////////////////////////////////////////////////////////////////+cAAAAAP///y3////8/v39/+7i5//8+vv///////////////////////7+///2+/7///////z+//+Ixff/3e79/////zD///+T+/j6/5VCav+UQ2r/iS5a//bu8v////////////////+63fv/H5Lv//7///+v2fn/AHbr/57R+P////+f////261tjP+3f5v//////9Kvv/+bRW3/9vv8/8Hw7//D8O7/qN/x/weC7v9qt/T/GI/v/0Wm8v//////////3v////l4EUP/4cvV///////v4+j/iRlK/3zBx/8Awr7/AL26/5Tn4f/f8P3/AIDt/w6J7v/y+f7///////////n////5hCVT/9q+zP//////693j/4odTv9/zM//MdDN//v+/v//////+v3//wCD7f8XkO///v7////////////5////29i7yf+ILln/8+nt/6FWev/Km7D/m+rp/zfOy////////////4bG9/9GpvL/gML3/3e/9v//////////3v///5P/////2LrI/5dJbv/MobT//v///4Pi4P8uy8j///////7+//9fsvT/8fj+//////9rufX/5/P9/////5////8t/////P/////////////////////G8fD/meXl//////////////////////////////////////////8wAAAAAP///5P///////////////////////////////////////////////////////////////////+cAAAAAAAAAAD///8G////w//////////////////////////////////////////////////////////G////CQAAAAAAAAAAAAAAAP///wb///+T//////////////////////////////////////////////+f////CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD///+T////1f//////////////2P///5n///8zAAAAAAAAAAAAAAAAAAAAAPAPAADgBwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8h////If///43///+N////zP///8z/////////////////////////z////8////+Q////kP///yf///8nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yH///8h////jf///43////M////zP/////////////////////////P////z////5D///+Q////J////ycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///3L///9y////8/////P////////////////////////////////////////////////////////////////////2////9v///3L///9yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////cv///3L////z////8/////////////////////////////////////////////////////////////////////b////2////cv///3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wb///8G////t////7f//////////////////////////////////////////////////////////////////////////////////////////////////////////////8D////A////Bv///wYAAAAAAAAAAAAAAAAAAAAA////Bv///wb///+3////t///////////////////////////////////////////////////////////////////////////////////////////////////////////////wP///8D///8G////BgAAAAAAAAAAAAAAAAAAAAD///+Q////kP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5z///+cAAAAAAAAAAAAAAAAAAAAAP///5D///+Q////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////nP///5wAAAAAAAAAAP///y3///8t/////P////z+/f3//v39/+7i5//u4uf//Pr7//z6+/////////////////////////////////////////////7+///+/v//9vv+//b7/v////////////z+///8/v//iMX3/4jF9//d7v3/3e79/////zD///8w////Lf///y3////8/////P79/f/+/f3/7uLn/+7i5//8+vv//Pr7/////////////////////////////////////////////v7///7+///2+/7/9vv+/////////////P7///z+//+Ixff/iMX3/93u/f/d7v3/////MP///zD///+T////k/v4+v/7+Pr/lUJq/5VCav+UQ2r/lENq/4kuWv+JLlr/9u7y//bu8v////////////////////////////////+63fv/ut37/x+S7/8fku///v////7///+v2fn/r9n5/wB26/8Aduv/ntH4/57R+P////+f////n////5P///+T+/j6//v4+v+VQmr/lUJq/5RDav+UQ2r/iS5a/4kuWv/27vL/9u7y/////////////////////////////////7rd+/+63fv/H5Lv/x+S7//+/////v///6/Z+f+v2fn/AHbr/wB26/+e0fj/ntH4/////5////+f////2////9utbYz/rW2M/7d/m/+3f5v////////////Sr7//0q+//5tFbf+bRW3/9vv8//b7/P/B8O//wfDv/8Pw7v/D8O7/qN/x/6jf8f8Hgu7/B4Lu/2q39P9qt/T/GI/v/xiP7/9FpvL/Raby////////////////3v///97////b////261tjP+tbYz/t3+b/7d/m////////////9Kvv//Sr7//m0Vt/5tFbf/2+/z/9vv8/8Hw7//B8O//w/Du/8Pw7v+o3/H/qN/x/weC7v8Hgu7/arf0/2q39P8Yj+//GI/v/0Wm8v9FpvL////////////////e////3v////n////5eBFD/3gRQ//hy9X/4cvV////////////7+Po/+/j6P+JGUr/iRlK/3zBx/98wcf/AMK+/wDCvv8Avbr/AL26/5Tn4f+U5+H/3/D9/9/w/f8AgO3/AIDt/w6J7v8Oie7/8vn+//L5/v////////////////n////5////+f////l4EUP/eBFD/+HL1f/hy9X////////////v4+j/7+Po/4kZSv+JGUr/fMHH/3zBx/8Awr7/AMK+/wC9uv8Avbr/lOfh/5Tn4f/f8P3/3/D9/wCA7f8AgO3/Donu/w6J7v/y+f7/8vn+////////////////+f////n////5////+YQlU/+EJVP/2r7M/9q+zP///////////+vd4//r3eP/ih1O/4odTv9/zM//f8zP/zHQzf8x0M3/+/7+//v+/v////////////r9///6/f//AIPt/wCD7f8XkO//F5Dv//7+///+/v/////////////////5////+f////n////5hCVT/4QlU//avsz/2r7M////////////693j/+vd4/+KHU7/ih1O/3/Mz/9/zM//MdDN/zHQzf/7/v7/+/7+////////////+v3///r9//8Ag+3/AIPt/xeQ7/8XkO///v7///7+//////////////////n////5////2////9vYu8n/2LvJ/4guWf+ILln/8+nt//Pp7f+hVnr/oVZ6/8qbsP/Km7D/m+rp/5vq6f83zsv/N87L//////////////////////+Gxvf/hsb3/0am8v9GpvL/gML3/4DC9/93v/b/d7/2////////////////3v///97////b////29i7yf/Yu8n/iC5Z/4guWf/z6e3/8+nt/6FWev+hVnr/ypuw/8qbsP+b6un/m+rp/zfOy/83zsv//////////////////////4bG9/+Gxvf/Rqby/0am8v+Awvf/gML3/3e/9v93v/b////////////////e////3v///5P///+T///////////Yusj/2LrI/5dJbv+XSW7/zKG0/8yhtP/+/////v///4Pi4P+D4uD/LsvI/y7LyP////////////7+///+/v//X7L0/1+y9P/x+P7/8fj+////////////a7n1/2u59f/n8/3/5/P9/////5////+f////k////5P//////////9i6yP/Yusj/l0lu/5dJbv/MobT/zKG0//7////+////g+Lg/4Pi4P8uy8j/LsvI/////////////v7///7+//9fsvT/X7L0//H4/v/x+P7///////////9rufX/a7n1/+fz/f/n8/3/////n////5////8t////Lf////z////8///////////////////////////////////////////G8fD/xvHw/5nl5f+Z5eX///////////////////////////////////////////////////////////////////////////////8w////MP///y3///8t/////P////z//////////////////////////////////////////8bx8P/G8fD/meXl/5nl5f///////////////////////////////////////////////////////////////////////////////zD///8wAAAAAAAAAAD///+T////k////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5z///+cAAAAAAAAAAAAAAAAAAAAAP///5P///+T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////nP///5wAAAAAAAAAAAAAAAAAAAAA////Bv///wb////D////w///////////////////////////////////////////////////////////////////////////////////////////////////////////////xv///8b///8J////CQAAAAAAAAAAAAAAAAAAAAD///8G////Bv///8P////D///////////////////////////////////////////////////////////////////////////////////////////////////////////////G////xv///wn///8JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Bv///wb///+T////k/////////////////////////////////////////////////////////////////////////////////////////+f////n////wn///8JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8G////Bv///5P///+T/////////////////////////////////////////////////////////////////////////////////////////5////+f////Cf///wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8w////MP///5P///+T////1f///9X/////////////////////////2P///9j///+Z////mf///zP///8zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD///8w////k////5P////V////1f/////////////////////////Y////2P///5n///+Z////M////zMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP//AAD//AAAP/wAAD/AAAADwAAAA8AAAAPAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAPAAAADwAAAA8AAAAPwAAAP8AAAD/8AAP//AAD/</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.olx.ba/sugestije/firefox_pojmovi">
- <Param name="sta" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="http://www.olx.ba/pretraga" resultdomain="olx.ba">
- <Param name="trazilica" value="{searchTerms}" />
-</Url>
-<SearchForm>http://www.olx.ba/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/oshiete-goo.xml b/browser/locales/searchplugins/oshiete-goo.xml
deleted file mode 100644
index 291cfc1e0..000000000
--- a/browser/locales/searchplugins/oshiete-goo.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>æ•™ãˆã¦ï¼goo</ShortName>
-<Description>æ•™ãˆã¦ï¼goo</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAICAAAAEAIAAoEAAAJgAAABAQAAABACAAKAQAAE4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////S////+f/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5////0v////l/////////////////////////////////////////////////////////////////////+fn+f/Z2fX/////////////////////////////////////////////////////////////////////////////////////5f////////////////////////////////////////////////X1/f+1tez/fX3f/01N0/8zM8z/MzPM/zMzzP8zM8z/MzPM/1dX1f+VleX/2dn1//////////////////////////////////////////////////////////////////////////////////////////////////////+3t+3/QUHQ/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/Xl7X/9vb9v//////////////////////////////////////////////////////////////////////////////////////q6vq/zMzzP8zM8z/MzPM/zMzzP9BQdD/b2/b/4WF4P+FheD/hYXg/2Fh1/86Os7/MzPM/zMzzP8zM8z/Pz/P/9vb9v////////////////////////////////////////////////////////////////////////////Pz/P89Pc7/MzPM/zMzzP9JSdH/vLzu//////////////////////////////////X1/f+kpOj/Pz/P/zMzzP8zM8z/XFzW////////////////////////////////////////////////////////////////////////////wcHv/zMzzP8zM8z/MzPM/9nZ9f/////////////////////////////////////////////////Bwe//MzPM/zMzzP8zM8z/4uL4//////////////////////////////////////////////////////////////////////+8vO7/MzPM/zMzzP84OM3//////////////////////////////////////////////////////+np+v8zM8z/MzPM/zMzzP/Pz/P//////////////////////////////////////////////////////////////////////+Dg9/8zM8z/MzPM/zMzzP+3t+3/////////////////////////////////////////////////qanp/zMzzP8zM8z/MzPM/+np+v///////////////////////////////////////////////////////////////////////////3R03P8zM8z/MzPM/zU1zf+OjuP/4uL4////////////////////////////1tb1/4CA3/8zM8z/MzPM/zMzzP9vb9v/////////////////////////////////////////////////////////////////////////////////+Pj9/29v2/8zM8z/MzPM/zMzzP8zM8z/MzPM/1xc1v9cXNb/XFzW/zU1zf8zM8z/MzPM/zMzzP8zM8z/RkbR/+Li+P//////////////////////////////////////////////////////////////////////////////////////29v2/0ZG0f8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/2Fh1//l5fj//////////////////////////////////////////////////////////////////////////////////////76+7/84OM3/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8/P8//aGjZ/5GR4//Pz/P/////////////////////////////////////////////////////////////////////////////////////////////////UFDT/zMzzP8zM8z/dnbd/8jI8f/W1vX/+Pj9//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/v8zM8z/MzPM/zMzzP/4+P3////////////p6fr/w8Pw/62t6/+8vO7/2dn1/////////////////////////////////////////////////////////////////////////////////////////////////////////////////1BQ0/8zM8z/MzPM/4KC4P+fn+f/YWHX/zMzzP8zM8z/MzPM/zMzzP8zM8z/RkbR/6mp6f//////////////////////////////////////////////////////////////////////////////////////////////////////srLs/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/3Fx3P/6+v7/////////////////////////////////////////////////////////////////////////////////////////////////t7ft/0lJ0f8zM8z/MzPM/zMzzP9JSdH/mprm/62t6/+fn+f/VVXU/zMzzP8zM8z/MzPM/5iY5f//////////////////////////////////////////////////////////////////////////////////////////////////////fX3f/zMzzP8zM8z/WVnW//j4/f//////////////////////e3ve/zMzzP8zM8z/Pz/P//j4/f////////////////////////////////////////////////////////////////////////////////////////////r6/v86Os7/MzPM/zMzzP/Pz/P////////////////////////////4+P3/PT3O/zMzzP8zM8z/z8/z////////////////////////////////////////////////////////////////////////////////////////////4OD3/zMzzP8zM8z/MzPM/+7u+/////////////////////////////////9cXNb/MzPM/zMzzP++vu/////////////////////////////////////////////////////////////////////////////////////////////l5fj/MzPM/zMzzP8zM8z/zc3y////////////////////////////+Pj9/z8/z/8zM8z/MzPM/9HR9P////////////////////////////////////////////////////////////////////////////////////////////////9NTdP/MzPM/zMzzP9ZWdb/9fX9//////////////////////97e97/MzPM/zMzzP9ERND/+vr+/////////////////////////////////////////////////////////////////////////////////////////////////7m57v8zM8z/MzPM/zMzzP9GRtH/n5/n/7e37f+pqen/V1fV/zMzzP8zM8z/MzPM/5+f5////////////////////////////////////////////////////////////////////////////////////////////////////////////5+f5/8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/MzPM/zMzzP95ed3/+vr+/5OT5P9cXNb/sLDr/////////////////////////////////////////////////////////////////////////////////////////////////7m57v9VVdT/MzPM/zMzzP8zM8z/MzPM/zMzzP8zM8z/V1fV///////NzfL/MzPM/zMzzP81Nc3/4OD3///////////////////////////////////////////////////////////////////////////////////////////////////////i4vj/xcXx/62t6/+5ue7/Y2PY/zMzzP8/P8//6en6//Pz/P89Pc7/MzPM/zMzzP+5ue7///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+rq+r/MzPM/zMzzP86Os7/SUnR/zMzzP8zM8z/ODjN/+Xl+P////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/v+CguD/MzPM/zMzzP8zM8z/MzPM/zU1zf+3t+3////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////NzfL/mprm/4WF4P+dneb/5eX4////////////////////////////////////////////////5////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+f///9J////yf/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////J////SSgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////D//////////////////////////////////////////////////////////////////////////////+3/////////////////f3+/6mp6f9vb9v/UlLU/zMzzP9ERND/cXHc/8HB7////////////////////////////////////////////4eH4f8zM8z/ZWXZ/5+f5/+trev/nZ3m/2Fh1/8zM8z/oaHo//////////////////////////////////////86Os7/V1fV////////////////////////////V1fV/0lJ0f//////////////////////////////////////WVnW/0FB0P/W1vX/////////////////2dn1/0FB0P9eXtf//////////////////////////////////////+np+v9LS9L/MzPM/zMzzP9cXNb/ODjN/zMzzP8/P8//0dH0//////////////////////////////////////+RkeP/MzPM/1dX1f+FheD/hYXg/4mJ4v+ysuz/8/P8////////////////////////////////////////////XFzW/1BQ0//i4vj/t7ft/4eH4f+dneb/5+f5/////////////////////////////////////////////////76+7/89Pc7/MzPM/zMzzP9SUtT/MzPM/zg4zf/Pz/P/////////////////////////////////////////////////e3ve/zo6zv/d3ff//////+np+v9LS9L/V1fV/////////////////////////////////////////////////1JS1P9VVdT/////////////////e3ve/0FB0P////////////////////////////////////////////////95ed3/MzPM/7Cw6///////yMjx/z8/z/9tbdr/////////////////////////////////////////////////7u77/15e1/8zM8z/MzPM/zMzzP9NTdP/z8/z/3R03P/i4vj/////////////////////////////////////////////////29v2/7Cw6/92dt3/SUnR/5+f5/8zM8z/oaHo////////////////////////////////////////////////////////////7Oz6/29v2/8zM8z/amra/+7u+//////////////////////H///////////////////////////////////////////////////////////////////////////////BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Image>
-<Url type="text/html" method="GET" template="http://oshiete.goo.ne.jp/search_goo/result/" resultdomain="goo.ne.jp">
- <Param name="MT" value="{searchTerms}"/>
- <Param name="from" value="Firefox30"/>
- <Param name="PT" value="Firefox30"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/osta-ee.xml b/browser/locales/searchplugins/osta-ee.xml
deleted file mode 100644
index 1b5bf8a50..000000000
--- a/browser/locales/searchplugins/osta-ee.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Osta</ShortName>
-<Description>Osta</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA%2BklEQVQoFWP8%2F%2F8%2FAymAiRTFILXYNfw8OuFDk%2BDf5xcwjcOi4f%2BPDz%2FPLQSSn2c7YupB14CsDsj%2BtrUQzRIWZD6yaqA4l3c%2Fq1YAsgIgG6EBTTWLkgO7dQGaaiCXERKsQKt%2FX9vw7%2F0DZBVsRgncIfORRYBsqB%2F%2Bf%2F8AV83hXM%2FIIQCU%2B3VuwZclgUCbkfVANQBNApoHlAA6g9O5gSdmPUQR0FpgWCHrgToJIg0MfqDTmSUNgFyg8V%2FXJELEgSK8qfsh1qJogEjDSWQ9QIN4U%2FYDpdDjAa4ayMDqaQZgKOEHv66u%2F7an%2Ft%2F39xBl%2BJyEbBucjc9JcEXIDAC2WqE7XED1KgAAAABJRU5ErkJggg%3D%3D</Image>
-<Url type="text/html" method="GET" template="http://www.osta.ee/firefox/" resultdomain="osta.ee">
- <Param name="keyword" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.osta.ee/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/ozonru.xml b/browser/locales/searchplugins/ozonru.xml
deleted file mode 100644
index e8002c5eb..000000000
--- a/browser/locales/searchplugins/ozonru.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>OZON.ru</ShortName>
-<Description>OZON.ru provider</Description>
-<InputEncoding>WINDOWS-1251</InputEncoding>
-<Image height="16" width="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACABoBQAAJgAAACAgAAABAAgAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMuWTQDMl1AAzZpVANCfXADQoF4A8b5DAPPGWgDzyF4A9MplAPXPcwD10HgA9dF6AAPO/wAJz/8AJ9X/ADPX/wBO3P8AXd//AGbh/wB45f8A3bmIAN26iwDfv5IA9tSDAPbVhQDgwJUA5MihAPjfowDs2LwA7Nm/APngpgD546wA+ue6AProvACB5v8Ajen/AJDp/wCZ6/8Aou3/ALfx/wC68f8AwMDAAO/fyQD76sEA8eLOAPvsyADy5dMA9evcAP3z3QDJ9P8A1ff/AN75/wD27eEA/fXhAPjw5gD99uYA+fPrAP757wDh+f8A+/bwAPz59QD//fgA/vz6AP/9+gD5/v8A////AMuVSwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsEIwAAAA3ADIHkXwHAAAA2Ac3AAAANwAwo/oABBCMAAAAAABIEowAGO6QfDgHkXz/////MgeRfKsGkXzrBpF8JgAAACYAAAACAAAAyAWRfNCJDQAYEYwAUQWRfHgTBQBtBZF8AAAAAD0EkXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzjORfApuAABoDowAAAAFABwTjAAY7pB8wECRfP////+7QJF8jtYBAEUAAABcEIwAgAAQwBwTjAAY7pB8cAWRfP////8AAAAAPQSRfJARjAB1C4F8twAAAAEAAAACAAAADBOMABgAAAAAAAAAeBGMAEIAAAAAAAAAXBGMAAAAAAAAAAAAAAAAAAwAAAACAAAAAQGQfADs/X9CAAAAAAAAAAMAAABKABoC2IkNAAAAAADYiQ0ABQAAAN/igHy0EYwATxqAfLwCAAAAAADAAAAAAAAAAAACAAAAgAAAAAAAAAD0EowAf89KAGAQ+QAAAADAAAAAAOgSjAACAAAAgAAAAAAAAAB0VYwA7PWmAAIAAABDOlx3b3JrXG96b25fbmV3BwAAAGVcZmF2aWNvbi5pY28AutwAAAAAUBKMABt5SgB8EowAsYvUdwDg/X98EowAAAAAADCj+gD/h9R3/+mQfA4QgXy8AgAAAAAAAAAAAAAAAAAAcBKMADCj+gAmAAAAAAAAAC4QgXwmAAAADBOMAAIAAAAwAAAAJgAAAAAAAAAmAAAAXBKMAP+H1HccE4wA85mDfDgQgXz/////LhCBfBbQSgC8AgAAMKP6ACYAAADAEowAAAAAAAAAQkJCQkJCQkJCQkJCAAAAQkJCQkJCNRVDBRo9QkIAQkJCQkJCMAEbLx0DAj1CQkJCQkI+Oh43QkJCPwUaQkJCQjEJDBwxQkJCQkIrBDxCQjYGLEJCQkJCQkJCOQQ1QkIYGUJCQkJCQkJCQi0XPEJCByFCQkJCQkJCQkIWPEJCQgkgQkJCQkJCQkJCMzJCQkIfCEBCQkJCQkJCQjQSO0JCQAsKOEJCQkJCQkI0EDJCQkJCIhkuI0JCQkJCJBE7QkJCQkJCQhQnQkJCKQ4oQkJCQkJCQkJBEQ8TEA0lQkJCAEJCQkJCQkIyJiY7QkJCAAAAQkJCQkJCQkJCQkJCAADAAwAAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAADAAwAAKAAAACAAAABAAAAAAQAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEhjMAxIc0AMmHNADFiDYAxYk3AMaLOwD4uzYA8bw8APG9PgDxvT8AyI5AAMiQQgDIkEMAypNHAMyYUADNmVMAzptWAM6cWADPnVkA8b5CAPK/RADyv0UA8r9GANGiYgDTpmkA1KdqANetdQDywk4A8sNQAPPDUQDzxVUA88VWAPPGWQDzyF4A9MlhAPTJYwD0zGkA9s5rAPXNbgD1znAA9dF6AADN/wACzf8ABM7/AAXO/wAHzv8AGNL/AB7T/wAj1P8AJtT/ACfV/wAo1f8ALtb/AC/W/wAw1v8AMdf/ADTX/wA52P8AStz/AFPd/wBY3v8AauL/AGvi/wBt4v8AbuP/AHLj/wBz5f8AdeT/AH/m/wDbtoMA3LiHAN26iwDevI8A3r2PAOS6iQD21IEA4sCWAOLDmgDjw5sA48afAOTFnQD32pIA+NuXAPjcmQD43p8A5cunAObMqQDnzasA6M6tAOjQrwD436IA+N+jAOnQsQDp0rMA+eKsAPnkrwD75rQA+ua2APrnuQD657oAlOr/AJfq/gCW6v8AmOv/AKDs/wCj7f8Ape3/AKzv/wCt7/8Aru//AKXw/wCw8P8AtPD/ALvy/wDAwMAA7dvCAO/exwD768QA++vFAPvsxgDw4c0A+uvIAPvuzQDt5dUA8uPQAPLl0wD059UA9OfWAPTo1wD879AA/PDUAPzx1gD88tkAwPP/AMj0/wDP9v8A1vP4ANH1+wDX9/8A3/n/APbt4QD37+UA9vPhAP314QD99eIA+vHnAPjx6AD99+gA/vfoAP346gD++e0A4Pn/AOz7/wDu/P8A+/jzAPz48wD++/IA/Pn0APz59QD+/PUA/vz2APH8/wD0/f8A9v3/APf9/wD//fgA//36AP/++wD4/v8A+f7/AP7+/QD//v0A/P7/AP///gD+//8A////AMKDLQADAAAASgAaAtiJDQAAAAAA2IkNAAUAAADf4oB8tBGMAE8agHy8AgAAAAAAwAAAAAAAAAAAAgAAAIAAAAAAAAAA9BKMAH/PSgBgEPkAAAAAwAAAAADoEowAAgAAAIAAAAAAAAAAdFWMAOz1pgACAAAAQzpcd29ya1xvem9uX25ldwcAAABlXGZhdmljb24uaWNvALrcAAAAAFASjAAbeUoAfBKMALGL1HcA4P1/fBKMAAAAAAAwo/oA/4fUd//pkHwOEIF8vAIAAAAAAAAAAAAAAAAAAHASjAAwo/oAJgAAAAAAAAAuEIF8JgAAAAwTjAACAAAAMAAAACYAAAAAAAAAJgAAAFwSjAD/h9R3HBOMAPOZg3w4EIF8/////y4QgXwW0EoAvAIAADCj+gAmAAAAwBKMAAAAAAAAAAAAsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwAAAAAAAAsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsAAAALCwsLCwsLCwsLCwsLCwsLCAXVFNT1l9sLCwsLCwsAAAsLCwsLCwsLCwsLCwsLCrUA4EAQEFBg1KnrCwsLCwALCwsLCwsLCwsLCwsLCwnhmxsQwTEwuxsbERjrCwsLCwsLCwsLCwsLCwsLCwsKwZsRl1n7CwnHQYsbEPm7CwsLCwsLCwsLCwsLCwsLCwSbFesLCwsLCwsK5YArEbsLCwsLCwsLCwsLCwsKygp7B/ebCwsLCwsLCwsLBXsbF+sLCwsLCwsLCwsHZMIBYdJnqwsLCwsLCwsLCwsLASsVCwsLCwsLCwsJAnCAglVWJggrCwsLCwsLCwsLCwsFexSLCwsLCwsLCFHAghe7CwsLCwsLCwsLCwsLCwsLCwgbFGsLCwsLCwnR8II5ewsLCwsLCwsLCwsLCwsLCwsLCTsUewsLCwsLBSCBeQsLCwsLCwsLCwsLCwsLCwsLCwsI2xTrCwsLCwlBQIW7CwsLCwsLCwsLCwsLCwsLCwsLCwWrGBsLCwsLBkCAmRsLCwsLCwsLCwsLCwsLCwsLCwsLAQGrCwsLCwsFUIHKGwsLCwsLCwsLCwsLCwsLCwsLCwVgOSsLCwsLCwVAgeprCwsLCwsLCwsLCwsLCwsLCwsLBLfLCwsLCwsLBfCBWXsLCwsLCwsLCwsLCwsLCwsLCwsLCJb7CwsLCwsIMICHewsLCwsLCwsLCwsLCwsLCwsLCwsEMumrCwsLCwqCIIKLCwsLCwsLCwsLCwsLCwsLCwsLCwhipqsLCwsLCwgggIU7CwsLCwsLCwsLCwsLCwsLCwsLCMKkSwsLCwsLCwWwgIVKewsLCwsLCwsLCwsLCwsLCwsIsqPrCwsLCwsLCwXAoIJGOVsKOqsLCwsLCwsLCwsLCwbipBsLCwsLCwsLCwhCkJCAePZj+wsLCwsLCwsLCwsLA9KkWwsLCwsLCwsLCwsJR4YZaKLZiwsLCwsLCwsLCwiC4qbbCwsLCwsLCwsLCwsLCwsK81OaSwsLCwsLCwsJk1KjCjsLCwsLCwsLCwsLCwsLCwsIcuOnGtsLCwsKVsNyoscLCwsLCwsLCwsLCwsLCwsLCwsHIrKjZCZ2VANCoqK2mwsLCwsACwsLCwsLCwsLCwsLCwsIc4KioqKioqKjJxsLCwsLAAALCwsLCwsLCwsLCwsLCwsKlrPDMvMTtoorCwsLCwsAAAALCwsLCwsLCwsLCwsLCwr7CwsLCwsLCwsLCwsLAAAAAAAACwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLAAAAAA8AAAD8AAAAOAAAABgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA/AAAA8=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.ozon.ru/JSONSuggestionHandler.ashx">
- <Param name="text" value="{searchTerms}"/>
- <Param name="from" value="firefox"/>
-</Url>
-<Url type="text/html" method="GET" template="http://www.ozon.ru/?" resultdomain="ozon.ru">
- <Param name="context" value="search"/>
- <Param name="text" value="{searchTerms}"/>
- <Param name="from" value="firefox"/>
-</Url>
-<SearchForm>http://www.ozon.ru/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/palasprint.xml b/browser/locales/searchplugins/palasprint.xml
deleted file mode 100644
index 0baa10e0b..000000000
--- a/browser/locales/searchplugins/palasprint.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Palas Print</ShortName>
-<Description>Palas Print - Heb Ffiniau</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAAAAAAAP4ADvb%2BABHO%2FQAQev4AB8j%2FAA6y%2FgAVvv0AEPb%2BAAAG%2BgAMYf4AFGz%2BAA%2Fe%2FQAOof4ACdT%2FAAyg%2FgAScP4AEKf%2BABSe%2FgACDv4AFY39ABVh%2FQANTP8ABxn%2FAAAG%2FgAS9v4AAQH9AAAA%2FAD%2F%2F%2F8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkaGgAAAAAAAAAAAAEHABcAAAAAAAAAAAAAAAABGAAAAAAAAAAAAAAAAAAAARgAAAAAAAAAAAAAAAAAAAEBAAAAAAAAAAAAAAAAAAABBxMUFBUWABcAAAAAAAAAAQcBAQEBARESAAAAAAAAAAEHAAAADwEBEAAAAAAAAAABAQAAAAAAAQEAAAAAAAAAAQEAAAAAAA0BDgAAAAAAAAEHAAAAAAALAQwAAAAAAAABBwAAAAgJAQEKAAAAAAAAAQEEBQUBAQEGAAAAAAAAAAEBAQEBAQIDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D</Image>
-<Url type="text/html" method="GET" template="http://palasprint.com/siopa/search_all.php" resultdomain="palasprint.com">
- <Param name="keywords" value="{searchTerms}"/>
- <Param name="source" value="mozilla"/>
-</Url>
-<SearchForm>http://palasprint.com/siopa/advanced_search.php</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/paroledigenova-lij.xml b/browser/locales/searchplugins/paroledigenova-lij.xml
deleted file mode 100644
index e671db15d..000000000
--- a/browser/locales/searchplugins/paroledigenova-lij.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Parole di Genova</ShortName>
-<Description>Parole di Genova, grande dizionario della lingua genovese</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC%2FxhBQAAAwBQTFRFAAAABQUEBg8UEhISGxcWAhUgEio6GS87KG8gMHEnPHAzHlR1PUFEQGk0Tk9QT1BRUk9NV29PY1RcZ11ZYF1jf1xlbmFnfXl4fXt7Hl6GI2GHLmOFLGSHImuZf3%2BBM4McOYEvPo8yOpExQZgkQZc3QpU6QpY6SJ06S549UJ5CgwwOgQ4PigYIiQsMhBAQiB0XliYgmTYtoRkVqzktvj8x5kk58049gXSFhX6UiH%2BZjIyQi4qak5KVibuJm6CnmqCon6GsppujoKWuoKuzp663pLC7uqavrLXBrrfBrrnFsrfDsbvHucPKuMTQuNbIvtrQyMXRxdPfytPd19PZ2tTX2djfxtXhx9bkydXhytfkytjlzdnmz9zk0N3k0N7r0%2BDv1ub01%2Bf31uf42Ofz2Of22Oj32%2Bv03Ov13uz32uj42un62%2Bv73Ov73u363%2Bz73ez83e393u7%2B3%2B%2F%2F2vD%2F3vD%2F4e384PD%2F4%2FL84fL%2F4%2FT%2F5PX%2F5fb%2F4Pr%2F5%2Fj%2F6Pn%2F6fr%2F6%2Fz%2F7P3%2F7v%2F%2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzK96PwAAAAlwSFlzAAAWJAAAFiQBmxXGFAAAABl0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuNtCDrVoAAADbSURBVChTYyhDAwxYBIoYGqpAwkVlTc5lZUAVBd4sNlb53AJswp7s%2BSCBsnxW18BUfnd78XDGBLBApmxEWaJcdiBfoW8cUMAvL0Umviw%2FKj9MOqewECigrMIrUgAyNFIyCUgylMlzCIoxWXqVMTBL8UhkAQVsFRU4uawtzIUMDI1NioECuWqqahoBwY6i2rqmZjUgWzTVlfxLQkPctPR0jErA1lYAHQkkiyr0S8EuLXNwinGp9rHzCIquBglUVccmpzXVladX1Gc0VgIFqqur6yuqa4E6Kqvrq4oAvlJaDTVq%2F2QAAAAASUVORK5CYII%3D</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.paroledigenova.net/it/api.php">
-<Param name="action" value="opensearch"/>
-<Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="http://www.paroledigenova.net/it/index.php" resultdomain="paroledigenova.net">
- <Param name="search" value="{searchTerms}"/>
- <Param name="fulltext" value="Ricerca" />
-</Url>
-<SearchForm>http://www.paroledigenova.net/it/index.php?title=Speciale:Ricerca</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/pledarigrond.xml b/browser/locales/searchplugins/pledarigrond.xml
deleted file mode 100644
index e4a40f3fc..000000000
--- a/browser/locales/searchplugins/pledarigrond.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Pledari Grond</ShortName>
- <Description>Pledari Grond online: vocabulari rumantsch-tudestg</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6AAAdTAAAOpgAAA6lwAAF2+XqZnUAAABXUlEQVR4nGJk0Jzyn4ECABBATJRoBgGAAKLYAIAAotgAgABicdB8ybC/Zjdc4OM3VoYNZ2UZFhxUZjhwXRwsNiH2DIOD1ksGfbn3YP7FR4IMCTOsGC48FGQACCAUF4Ak+Ll+M8Tb3mOYEHcGrjnf4wZY88M33GAxEHtD0QEGAa5fDAABxIJsQMEiE7BN9UGX4LaBNIPAwsNKYFsN5N8zBJg8ZnjwGmIYQAChGAAyFeQCEDgIdD7Ie3C5M7IMCXZ3gfgeRECTAegFIQaAAEIx4MEbHoYPX9nAfpuwQwMlsBREvjIIcP9isEcyFOQFgADC8AIs4GAA5G95oOYE+7sME7ZrMCTOtGSYn34cLg8QQCgGYAMBfQ4MB2p2gcMEWSPI4AdADBBALCCicZ0e1AvcGAaAvOPQ4gYOD5AXwOqAAbjgkDKYDRBAjJTmBYAAojglAgQQxQYABBDFBgAEGAB/YnDI5He1+AAAAABJRU5ErkJggg==</Image>
- <Url type="text/html" method="GET" template="http://pledarigrond.ch/#searchPhrase={searchTerms}" resultdomain="pledarigrond.ch" />
- <SearchForm>http://www.pledarigrond.ch/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/pogodak.xml b/browser/locales/searchplugins/pogodak.xml
deleted file mode 100644
index b6ed90c4a..000000000
--- a/browser/locales/searchplugins/pogodak.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Погодак</ShortName>
- <Description>Погодак: претраживач Интернета</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AHd72f9yc+n/fn/u/3+A6/9kZ9v/jJPS/////wD///8A////AP///wD///8A////AP///wD///8AuLn1/0ZJ4f9fX+j/qqn0/87P9P/S2Pj/b3Th/xogzv+Fh+//////AP///wD///8A////AP///wD///8Ak5Xx/ysu5P+2tvX////4/+rq6f+9veT/yszh//LzzP/W2Nr/Wl3i/2Zo7P////8A////AP///wD///8AtLf0/w8V3P/a2fT////1/1xf3/8ICtX/DQzT/wAAxP8ODrX/xsjk////6f9HS9X/fYDx/////wD///8A////ACcr3v+houn////z/zU44P8dIOX/paXt/9/e6v+fmsj/NTbG/w0S3v+7ven//v/n/ywu1v/Hx/n/////AKOh7/8pJtP////q/3p86P8iJO3/9PX4////7//x8Nf/9PS+////0f97f+P/Li/o////6f9ubc//U1Lj/////wBaV+P/Y13Q/+/w4/8iJur/tLX4/////f+SlOf/ExDA/1FKwv/5+en/8/Pf/0hJ6f+rrPH/sbDR/z471/////8ARELk/4SB0f/ExeH/MDTt////+//g3vL/AADX/wINvv8AAMf/lofk////5/94evX/eH/5/8fI2f9AQef/5ub//05N6v98ec3/v77d/zEz7P////f/2Njw/wAA0/8wQuL/QHTx/2ma8v++5fn/rKHS/+i/p//IvNH/PT/m/9/h/v9qbvH/VVfO/9na1P8lJ+r/r6/w////9/9+g+L/Hh3o/3p+5//X+e3/nt74/461yv/Y06r/ood+/3JDQf/s0rT/qav6/yEm2f/o6M//eXrq/xcZ7f/i4ez////x/+bn3f/59NH////k/6ie1f+dhnn/rqeG/46vr/+UwML/8erg/////wAnK+v/fIDR////2v88Pen/Exbp/5OT5v/T0Nv/r6vU/zU94P8mMeT/9b+B//6uRv+2mIX/1+7o/////wD///8Aqqv9/wEE4/+2ttH////e/3N35P8VGdv/DgvW/wMA0/87Pdr/3uDs////6v9LTe3/hXbV///qu/////8A////AP///wB7fPn/AAHi/4uM1//9/dv/8fHg/8rJ4P/e3eT////r/93b7P80O/P/OT/7/////wD///8A////AP///wD///8A////AJWW9/8eIun/MDLl/31/6v+qrOz/l5vv/1ZY7f8fH+v/XmDw/////wD///8A////AP///wD///8A////AP///wD///8A////AJia+/9QUvL/Oz7t/1JW8P91d/X/xMT5/////wD///8A////AP///wD///8A+B8AAOAPAADABwAAgAMAAIABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMAHAADgDwAA+B8AAA==</Image>
- <Url type="text/html" method="GET" template="http://www.pogodak.rs/pretraga" resultdomain="pogodak.rs">
- <Param name="q" value="{searchTerms}" />
- <Param name="foxsbar" value="ff"/>
- </Url>
- <SearchForm>http://www.pogodak.rs</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/portalbgdict.xml b/browser/locales/searchplugins/portalbgdict.xml
deleted file mode 100644
index 27f5af418..000000000
--- a/browser/locales/searchplugins/portalbgdict.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Речник на Portal.BG</ShortName>
-<Description>ÐнглийÑко-българÑки речник на Portal.BG</Description>
-<InputEncoding>windows-1251</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC%2FklEQVQ4EX2STUxTaRSGn%2Fbe3ha4bS14KUJBtGhARI0k6kTNxJXOYiK60oStdGGi8S8mGtTEjYnRhXEDxp0mxIXJZHSicaEJcYJKA4uZBBGEBuSnXIH%2B0D%2FaXu%2F91DqLiWfx3Xu%2Bc857zvee12YM7TDSkXIS4fVkR4tkZj9Q9M9SfaIS1SfjkG38zGSrODt2BHVzDYpnDgahvi9MKBSiu2s31VWVKA75%2FzHmupHjAxtwt9ZQ3tIikiSvVxRbzuT9J0ihDvQK%2BGslytDKPAvLCzQVnVwN7kPLG8i5iTy5KrOzaeWdnZzp7%2BfUixdkJiZY2r%2Bdd5%2Fn%2BeDxUVe7kYvaeZG38dHv%2FP3mAU%2FW5TGfMCYu6%2Fv6ROdz4TApXRd3OUnidVmaNjVIp3a0NJnrkMI%2FuVnuRgzsRu0M8bdvRdDqnBodpZBIUJTsRHc1EzESzCUXBaB19PT0sP%2FZWuEPpUHWTvgYP52gq7eXzLc0w2YjcnAP5ZvqiSxOi9vQjdC36I%2BPbHHgXuug5uE1Jh88Jzs8SrrMRbKlEceWRoINfjYno%2FRPj%2FCx58%2BvQOZ2etvDSIaNXzIZbJYOspVXWFpOEtVjjCx4CMfaicQ0VpbjBJwTvFxzm1%2F%2FbRAAVrEdGx3JAMeLw%2Ba%2FaU7FgVblJV%2FRzKBhaiIQpO9CNbX6TQZngnjfXETZmmG8bYaObAOXU9s47mlmQ51CSSGSSdrjkU24NQd%2Bv6vEuKLYGV%2FWaI%2Fs5dJuHafTVKcpLJ9XRSs4v05gTZFdtTEWLSMez9PVDp4Dt4g1Xef1nUYOB%2B7wftaNqrpoalxHi0nu%2BvpqvKr0A0CWDJb0FFNTKQuPm8dU5uczpUkc9hyr%2BQIul4JbLRPyNpf1nyeYbLT6pugfrzOLugXIdOwsw%2FpJEvEs3YeeIktu7HZBm4hbR4kDyznz2xwDt%2B38oZ%2BiUDBIpdJk0nk6tg7Q2pClck2tyYHDSi2ZWON3b9UUxqdokXuvdvJusokKeZE2%2FxDb6iYF48GAU7zbGv27fQHPoxrlB7FOagAAAABJRU5ErkJggg%3D%3D</Image>
-<Url type="text/html" method="GET" template="http://portal.bg/dict/index.php" resultdomain="portal.bg">
- <Param name="encin" value="windows-1251" />
- <Param name="encout" value="windows-1251" />
- <Param name="translate" value="firefox" />
- <Param name="word" value="{searchTerms}" />
-</Url>
-<SearchForm>http://portal.bg/dict/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/priberam.xml b/browser/locales/searchplugins/priberam.xml
deleted file mode 100644
index 9ff992a00..000000000
--- a/browser/locales/searchplugins/priberam.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Priberam</ShortName>
-<Description>Dicionário Priberam</Description>
-<InputEncoding>ISO-8859-15</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAABGdBTUEAANbY1E9YMgAAABl0RVh0
-U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKoSURBVHjaYvz7+dv3r98Y/n7+7u/jCxBA
-jH8/fmVgYGBat23T1+/fAQKI8e+X7wz//xeVlykqKjB8fP4qJj4GqHzR3LkAAQRV9+zlCylxCSYG
-JkYgunXnNohx78qNv5++fXn9Dkgy/Prw5YVwLQsLyy2hSoAAYgRaATTt4ZPHX799+fTh06Mnj4P9
-g5iZmZgYGBmASExEZPfevdHJCbdu3548c+rd+3eZGMCAk5Mz7b/Zg4cP33x8X5Cd+2vHbcaf7z4d
-OXbUwdaOARUABBDUXUDw79+/L9++MTIx8nJxA53FwsDI+Ofvn2vXr/Fy85y7fOnvnz9hQSEga4Ee
-+vPpK5D8+eGzqpLy8wePbpy7CPQ4C8g4Rsblq1ZIiEncvnd36vTpvLw8xaqFDECPyUhJA0kgkpeT
-B5K/P3wBeQ5oCAjdexuiYsvEzARkvz11++f91yzfvn27dv36rvDepcXtC7gvGttarbAq+asuzbh/
-yw4zU1MODg5UXzACBBg45P/9h4uAfPPly+9fv779+M7EzHzt5g0JMXFdLW2oNBMjOKjAwfjh44cL
-Fy98+faVh49XWFRk3qIF2iaGl65cPnv+7NUb1yBqQFoYgKaDkQC/gIG+AR8P77nz58urq46fPPX/
-37/TZ86EBoW8ffcut6jg/qOHIB1AJ0E8ePX0ufrK6o3r1v/6+BkYdNaWlnp6ekDG7UtXwoNDLp89
-B1IGdD9Iw6dvpw4e2bBi9a8PnyEBdvPqVSkpKaBxU/snQkSg6Mt3aAKB+/hj+a6fM/dfZfslvDu+
-rreN+R9Dfnbu5YuXzk/a/PvZ28qwPMbbV65NmTFDVETk04cPMioKroY2CtxibLICDGzMwGA4cPSw
-vZWNoIAgw6+/fx99YFYUZPz39cd/pGDFD4CJBwBLx4gNwqkZawAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="http://www.priberam.pt/dlpo/firefox.aspx" resultdomain="priberam.pt">
- <Param name="pal" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.priberam.pt/dlpo/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/priceru.xml b/browser/locales/searchplugins/priceru.xml
deleted file mode 100644
index 55ea693c2..000000000
--- a/browser/locales/searchplugins/priceru.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Price.ru</ShortName>
-<Description>ПоиÑк предложений и цен</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABhklEQVQ4jX2Sv0vDQBiGn4uF0iK1giJ2sAGHbiLauhSKIGj%2FAmddU1D3Tg4ujoJFcXYSHRREOopuKuogiCB10KVo4o9aK9pzCElzTewLgdx73%2FPm%2By4HbZKmKaVh2I9pStcP8AC0dphisWV43z2eN0T8CzsaG4eLc78PiFJJiE7ww3VZWSdHpn019gi7e76Nq5sTrFC0YyArK60RwD4ogPLBtuulkv1YoSjxn08ArFAUvWAQSeiEs3kRArB2NiTAK1BZL3FrSlK9dvbtQ9VOGk4CoBcMAOpPFaRpyq7G6ZH8ebfcL8YnMvQ83nFxb%2FH8BX0RwUAbDBBJ6PxWH9HC2byIJHRlNL1gkEvb3n9wbWm%2BNUI4mxeN0yNZf6ooQbm0roBe2JF7kTZnZnE6qayXOD6zw5qry4GwNppRA7whDuyqfOiDtewUgPob17pjyj3PpXWGalWaaGg0FTg2tyh8HSx8vCmBjuR3IxD2ddDeidOBA8e39gPrA7XWHZOXkyPyJTMoO9X9AaeeqENksUPXAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="http://price.ru/search" resultdomain="price.ru">
- <Param name="query" value="{searchTerms}"/>
- <Param name="from" value="fx3"/>
-</Url>
-<SearchForm>http://price.ru/index.html</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/prisjakt-sv-SE.xml b/browser/locales/searchplugins/prisjakt-sv-SE.xml
deleted file mode 100644
index 3c7d7fd5d..000000000
--- a/browser/locales/searchplugins/prisjakt-sv-SE.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Prisjakt</ShortName>
-<Description>Prisjakt - jämför priser och produkter</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAQAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKieMACommAAqJaMAKyauAC0prwBMSLsAZF%2FFAH16zQBwa9EAi4nTALu55QCxrvYA7Ov4AP%2F%2F%2FwBwADIAaQBjAG8AAADAHiQAfO8SAEwAAAAoJYAAjAAAAOS%2F9QBxGuYAjAAAAJgFAgAA8BIAGAAAAHDvEgDI7xIA4xq%2BAIwAAACYBQIAAPASABgAAAAAAAAA2T7GABg%2FxgDkCQUAVAAAAGDyEgChUcYA5AkFAFQAAABg8hIAAAAAAMzyEgBghgcAHjvnAPc65wDg8hIAWAcXAKzvEgCw7xIAgP4SAAlI6QBYMOgA%2F%2F%2F%2FAB475wAbrQEAYIYHAODyEgBYBxcABACkAAAApAD%2F%2F%2F8AsAgAAAAAQAAEAKQAZAAAAGIAbQBwADIAaQBjAG8ALgBlAHgAZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHQAAAAAAAAAAAAAAAAAAAACAAAAXPESALgLpADoC8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6AvCAAAAAAAAAAAAAAAAAP%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAX6bnAAAAAAAAAAAAAAAAAAAAAAAoLxQAAAAAAAkOAgACDgIADQAAAADw%2FQAA4P0AAg4CAAkOAgAAAAAA9gvCAODyEgBSAAAAAAAAACTVpAAAAAAA%2F%2F%2F%2FAFzxEgBq8RIAXPESAMzx5wAEwPUARPESAAAAFACoRPkARQAAAHgTFAAAABQAoCAUABzxEgAg8RIAZPMSAPCI%2BgBSAAAAAAAAAJDWpAAAAAAAOor1AAAAAAAA7P0AAAAAAAAAAABwADIAaQBjAG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDO8YApTbGAM0JAQAPAIUAAAAAAJDWpADNCQEAAQAAAAAAAAAAAAAAFTbGAM0JAQAAAAEAwU1BAM0JAQAAAwAABMD1AFik5wB0AAAAAAAAAOjyEgB0AAAAAAAAAAAAAAD%2F%2F%2F8AAAAAAAAAAAAAAAAAAAAAAP%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAKC8UAAAAAABkxfUAqfHnAIwAAAAAAAAAAAAAAAAAAAB88hIAAADdAAADAAAAAAAAyfHnAAADAAAAAN0AjAAAAAAAAAAAAwAAAQAYAAAAAABw8hIAAAAAAKqb9QCzm%2FUA4PUSACQAAgAA7P0AEW5AAAUAAAAkAAIAAPD9AJzyEgACAAAAQKP1AJACAgD5m%2FUA4En8ACOj9QAro%2FUAAAAAAAgCAACgIBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAAAAAAAAAAAAACwgGFQYICwAAAAAAAAANCgUEBAEEBAUKDQAAAAAACgQEBwwCBAQEBAoAAAAACwUEBAQOAwQEBAQFCwAAAAgEBAwODg4OCQQEBAgAAAAGBAQEBAQEBA4EBAQGAAAVFQECAwwODg4MAwIBFRUAAAYEBAQOBAMEBAQEBAYAAAAIBAQECQ4ODg4MBAQIAAAACwUEBAQEAw4EBAQFCwAAAAAKBAQEBAIMBwQECgAAAAAADQoFBAQBBAQFCg0AAAAAAAAACwgGFQYICwAAAAAAAAAAAAAAABUAAAAAAAAAAP%2F%2FRgD%2B%2FwAA8B8AAMAHAADABwAAgAMAFYADAACAAwAAAAEAAIADBhWAAwsAgAMAAMAHDQrABwQB8B8FCv7%2FAAA%3D</Image>
-<Url type="text/html" method="GET" template="http://www.prisjakt.nu/supersearch.php" resultdomain="prisjakt.nu">
- <Param name="s" value="{searchTerms}"/>
- <Param name="r" value="1"/>
- <Param name="e" value="utf8"/>
- <Param name="ref" value="155"/>
-</Url>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.prisjakt.nu/plugins/opensearch/suggestions.php?search={searchTerms}">
-</Url>
-<SearchForm>http://www.prisjakt.nu</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/pwn-pl.xml b/browser/locales/searchplugins/pwn-pl.xml
deleted file mode 100644
index 2b0849f84..000000000
--- a/browser/locales/searchplugins/pwn-pl.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Encyklopedia PWN</ShortName>
- <Description>Wyszukiwanie w Encyklopedii PWN</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAI9UExURQAAAB9YryBWrgmU3SBWrh9YryBWriBWriBWri0zkwmU3Q2L1hCBzg2L1hCBzhR3xiNOqB9YsBxitydFoRhsvxR3xhxitxhsvyNOqB9YsCdEoCo7mi01lSs6mSBWriBWri00lCBWrgqT3CBWriBWrgmU3Ss6mQqR2g2L1iNOqCdEoC0zkyBWriBWridEoCBXryBWris6mSBWri0zlA2K1RCBzh9YsB9YryNOqC0zlCBWrhR3xhCBzhxitxhsvyBWriBWrh9YsBR3xhxitxhsvyBWri0zkyBWriBWriBWriwykx9YryBWriwykyBWriBWriBWri0zkyBXryBWrh9YryBWriBWriBWrisykyBWriBWriBWriBWriBWriBWriBWrh9YryBWriBWriBWriBWriBWriBWriBWriBWriBWriBWriBWrgmU3Q2L1idEoBCBziJNpwWS3Cs6mW6UzBR2xiNOqB9YrxVrvhphtxCAzgyL1hd4xyFZsEWJzD96whl6yBSP1w1/zQiT3Ehrtg6AzguK1SVCn8XQ6B1Xr3eq2hJ1xmiQynmi1D2Z2F2q3hB0xSSX2l605TNbru31+93l8nmKw5XC5io6mBltv4W/5mi553uy3yhFoRdfthp6yODn87LO6svh8iZputTc7is6mFyFxTh0v4Kp1+rv+Ojv+EqNzTuCyLHN6Xyk1YK34ZLD55il0Z3A44an1mKLyBlgthZrvs/U6S08mtrg8DJAnLe/3jNBnGd6vCw7mTZEnjWei8gAAABsdFJOUwBNVQgHMwpZVGO9vQgIvQgICAgICL29vb29u4AO+w0uT3y1kwz+VRX4/VUhCZf9LR/9hWNK/f1gVWQyVVVVVV4gVf39/QhifaW+Y1OvZJK0lWRiMUKef3NlTZSZerKsFimuImocX3IVYkMpUosemJAAAAEISURBVBjTY2BQV1LNaSoszAEBLmYGBgYTjdzWCbMmNlTl5uZy8wIFbExbemeun9zXWJmfz8cDFLB26pq2bt7C2f311SWi/EABO5etGxesWrN6RmdtubgIUMDWecvylWuXzV3UU1chJgQUcDTrWLqieNPm7uKaMklBoICFZsGkxfN3TGlvLiiVEAAKaOnlzdmwa8+2qW15eVLCQAE1w6IlO3fv3bd9epGsNJDPoG1s6eblyxkRyMmpIAMS0Ddn9GZkDWFICGJlkGcBCrAbWXn6RIbGs0f5O3DIgQR0mdzDwuOSM5liAuxVQALKBq7BsWmJKRzp0R46QAEORQYGtoykVJZsliw/NgYAqJdNo4WkE2YAAAAASUVORK5CYII=</Image>
- <SearchForm>http://encyklopedia.pwn.pl/szukaj/</SearchForm>
- <Url method="GET"
- template="http://encyklopedia.pwn.pl/szukaj/{searchTerms}"
- type="text/html" />
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/qxl-NO.xml b/browser/locales/searchplugins/qxl-NO.xml
deleted file mode 100644
index bb2c92f29..000000000
--- a/browser/locales/searchplugins/qxl-NO.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>QXL</ShortName>
-<Description>QXL søk</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA////AAB15wAAdeYABXv1ABV79AAVdesAGIH8ABeB+QAAY9UAAFPEAABdzyMbg//lG4L/7RqB/tkTfvou////AP///wAAdecAAHXmAAV79QAVe/QAFXXrABiB/AAVgfkAC2ziAAAGVgAMWcyKHYf//xuC//8YgPyCEXv4AP///wD///8AAHXnAAB15gAFe/UAFXv0ABV16wAYgfwAFX/3BxN9+AQPUKAbGnzz8huD//8bgv/oFX/8DhV+/AD///8A////AAB15wAAdeYABXv1ABV89gYXePBhG4P/vxuC/dwbgv7ZHYj/2xuD//8bgv//GoH+eBqF/wAahv8A////AP///wAAdeYAAHTmAAd79R8bgv/HG4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xqC/0cITs8ABkPGAP///wD///8ABHvxAAR78QgYgfzRG4L//xuD//8bgP3wGoH+shuC/60bgv7pHYP//xuC//8bg//mADi4HQAemwD///8A////ABiA/QAagf6HHYP//xuC//8Ygf+uDWXaGBZ9/AAYgf4AFX74DRV695QbhP//G4P//xd777IKX74K////AP///wAVf/wzG4L/6xuC//8agf7eBHjwCglj1QAWffwAGoL/ABN48gAOaegAGn36vhuD//8bhP//EX78Wf///wD///8AFXvxcBuC//8bgv//GoH9fBaA/AAVffgAFn/8ABiB/AAMcOMADWjdABJ0608bg///G4L//xuC/4r///8A////ABh68YQbgv//HYP//w508FkIa+cABmzoAAhy7QAXf/oAE332ABV++AAVfvgxG4L//xuC//8bgv+Y////AP///wAVfPVqG4L//x2E//8TdPCHBWLaAAtm4QATffgAGoH/AAdj3wAAX9UACm7pWR2E//8bgv//GoH+h////wD///8AE4D8LBuC/+Ubgv//GoH86gJi1RQRfvgAFX/8ABuE/wAQa94AAVvLBhV89s8dg///HYL//BF9+FD///8A////ABZ//AAagf53HYP//xuC//8af/zHFn/8LxN/+wEbg/8AFHDnIRt++LAdg///G4L//xiE/aITgfkD////AP///wADbO4AA2ztARZ//MEdg///G4P//xuC//sagv7SG4L/zxuC//cbgv//G4L//xuD/9gAObcSACWjAP///wD///8AAF7jAABc4gAKdvQTGoL+rhuC//8bgv//HYP//xuC//8bg///HYP//xqB/sgYgf4hAB6gAAAPigD///8A////AABf5AAAXeMACHb0ABN++QEYffpGGoH+pBqA/NMagf3VG4H+sBV57VUTgPwFGID+AAAfpAAAEI8A////AP/BAAD/wwAA/gMAAPAHAADgBwAAwAMAAMGBAACD4QAAh+EAAIfhAACH4QAAg8EAAMCBAADAAwAA4AcAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8AAHXnAAB15wAAdOYAAXnwAA1++gARgPwAF3ftAA1e1wAYg/8AGIH+ABB77QAagf0AEYH0AAFq4gAAVMwAAFbOAABWzgAAVc0AAFjQChh//MQbg//rG4L/5RuC/+Ubgv/nG4L/5Rh/+yP///8A////AP///wD///8A////AP///wAAdecAAHXnAAB05gABefAADX76ABGA/AAXd+0ADV7XABiD/wAYgf4AEHvtABqB/QARgPQABHHnAABdvQAAXrwAAF69AABbtwADbdlSHYP//xuC//8bgv//G4L//xuC//8WgPywDHv1AP///wD///8A////AP///wD///8A////AAB15wAAdecAAHTmAAF58AANfvoAEYD8ABd37QANXtcAGIP/ABiB/gAQe+0AGoH9ABB/8wAMe/UAA0C9AAARkgAAFJkAABudBhh79dIdhP//G4L//xuC//8bgv//G4L//xV8+jwRefgA////AP///wD///8A////AP///wD///8AAHXnAAB15wAAdOYAAXnwAA1++gARgPwAF3ftAA1e1wAYg/8AGIH+ABB77QAagf0AEH/zAAx59AAVde8AAAg7AAAACAALTKtyHYj//xuC//8bgv//G4L//xuC//8agf7CFX36ABV9+gD///8A////AP///wD///8A////AP///wAAdecAAHXnAAB05gABefAADX76ABGA/AAXd+0ADV7XABiD/wAYgf4AEHvtABqB/QAQf/IACnbwABuJ/wAIQ4QAAAIBARdz3sodhf//G4L//xuC//8bgv//G4L//xh//EUVfvwAFX78AP///wD///8A////AP///wD///8A////AAB15wAAdecAAHTmAAF58AANfvoAEYD8ABd37QANXtcAGIP/ABiB/gAQeuwAGoH8ABB/8wQKdvAFGoL/ARh++AAXevFXG4P//xuC//8bgv//G4L//xuC//8agf6uFn/8ABZ//AAWf/wA////AP///wD///8A////AP///wD///8AAHXnAAB15wAAdOYAAXnwAA1++gARgPwAF3ftAA1e1QAYg/8SGoH9YxiA+q0bgv7MGoL81RqA/NYbgv/PGoL/tBuE/+Ebgv//G4L//xuC//8bgv//G4L//xqA/VAYgPwAGID8ABiA/AD///8A////AP///wD///8A////AP///wAAdecAAHXnAAB05gABefAADX76ABF/+wAYe/MaFXDqghuD/+Qbgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8agv7AFoD9ARiB/gAYgv8AGIL/AP///wD///8A////AP///wD///8A////AAB15wAAdecAAHTmAAF58AANfvoAE3/7ThuC/+obhP//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xiB/kMYgf4AF335ABd79wAXe/cA////AP///wD///8A////AP///wD///8AAHTmAAB05gAAc+UAAHjvABiB/ncbgv/8G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L/thqF/xMAObsAABKXAAAWnQD///8A////AP///wD///8A////AP///wAAeewAAHnsAAB47AAMfPZoHYP//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4b/qAAxsgEAD4kAABCPAP///wD///8A////AP///wD///8A////AA9/9gAQf/UAE4D5NB2D//Ybgv//G4L//xuC//8bgv//G4L//xuC//8bgf7WFn78hxqB/lgagf5SGoH+cxqB/b0bgv/7G4P//xuC//8bgv//G4L//xuC//8dhP//DmzohQBVzwAAV9IA////AP///wD///8A////AP///wD///8AFoD9ABZ//Asagf7UG4L//xuC//8bgv//G4L//xuC//8ag//bD2rcQhRq3gcRfPsAGID9ABiA/gAYgP4AE4D4Ahh/+yMaffmxHYT//xuC//8bgv//G4L//xuC//8diP/8CU6aLwItXgD///8A////AP///wD///8A////AP///wAWgPwAGoH+ThuC//8bgv//G4L//xuC//8bgv//HYL/zRaC/ycJZNMAEmfZABF8/AAYgP0AGID+ABiA/gATgPkAGn76AAxy7wQMe/eRHYP//xuC//8bgv//G4L//xuD//8Zee+XEHHiAP///wD///8A////AP///wD///8A////ABd++gAagf2xG4L//xuC//8bgv//G4L//xqB/vEAbOkgAHHuAAll0gAUZ9oAEXz8ABiA/QAYgP4AGID+ABOA+QAagPwADnLuAAJz7gEbg//FG4P//xuC//8bgv//G4L//xuD//QEdfIg////AP///wD///8A////AP///wD///8AE335IBuC//Qbgv//G4L//xuC//8bgv//GIH8hAJ66gAEfe8ACWvVABRo3AARfPwAGID9ABiA/gAYgf8AEXv0ABJx7gASbusAFHHtABJy7zIagP35G4L//xuC//8bgv//G4P//xd9+3H///8A////AP///wD///8A////AP///wAPgPxSG4L//xuC//8bgv//G4L//xuC//YTfvsjE378ABN+/QARfPgAFXv3ABF6+AAYgP0AGID+ABqD/wASdPAAC1LTAAtV1wALVNYAC1TWABp8+bMbg///G4L//xuC//8bgv//GoH+m////wD///8A////AP///wD///8A////ABZs1X8dhf//G4L//xuC//8bgv//G4P/wxuD/wAbg/8AG4P/ABuD/wAdhP8AFoD9ABuD/wAagf8ADnnoAAh44QAKfOUACnzlAAp85QAIe+QAEHztah2D//8bgv//G4L//xuC//8bgv+x////AP///wD///8A////AP///wD///8AF3vzkRuD//8bgv//G4L//x2D//8RevWjAGnjAAFq5QABauUAAWrlAAFq5QABauUABGznABiA/QAXgPgAFX/2ABV/9gAVf/YAFX/2ABV/9QAYgPlVG4L//xuC//8bgv//G4L//xuC/7v///8A////AP///wD///8A////AP///wAXd+yQG4P//xuC//8bgv//HYP//xV9+acEce8ABnLvAAZy7wAGcu8ABnLvAAZy7wAKdfIAGoH9ABV+/AAVgP0AFYH/ABWB/wAVgf8AFYH/ABaA/lYbgv//G4L//xuC//8bgv//G4L/u////wD///8A////AP///wD///8A////ABd153gbhP//G4L//xuC//8bhP//GHv4zgxQ0AANUNIADVDSAA1Q0gAKTM0AC2biABqF/wAbgv8AE335AAdi4gAHWtwAB1vdAAdb3QAFWNoAEnLvdx2E//8bgv//G4L//xuC//8bgf6u////AP///wD///8A////AP///wD///8AEYD8SBuC//8bgv//G4L//xuC//8dgv/9DHjwNAN05wAEdegAA3LoABB69gAOfPgAFoD8ABqB/wAbhf8ADV3bAABUxgAAXcsAAF7LAABZyQAXd/THHYT//xuC//8bgv//G4L//xqA/Zf///8A////AP///wD///8A////AP///wATf/kUGoL/6xuC//8bgv//G4L//x2D//8SffKlAGLJAABlywAEd+MAEX35AA19+AAWgPwAGoH/ABqF/wATcvEACGXJAABXvwAAUb8AA3TjUx2F//8bgv//G4L//xuC//8bgv//E3/7Yf///wD///8A////AP///wD///8A////AA99+QAWgPyZG4L//xuC//8bgv//G4L//x2H//8IS81DBk7OABuF/wATffoADnz4ABaA/AAagf8AGoX/ABNv8AARYs4AD2LbAA9f4hIafvziG4P//xuC//8bgv//G4L//xqB/ucEde8S////AP///wD///8A////AP///wD///8AFoH+ABiC/zwbgv//G4L//xuC//8bgv//G4L//x2E/+0Wgf1SGH/8ABN9+gAOfPgAFoD8ABqB/wAahf8AFG/wAA9gygAXfPAlHYf/wRuD//8bgv//G4L//xuC//8bgv//G4H/fRqA/wD///8A////AP///wD///8A////AP///wAWfvwAFn78ABqB/rkbgv//G4L//xuC//8bgv//G4L//xuC//gagf6AE376IA58+AIWgPwAGoH/ABqE/wATcfAUFm7iUhp++OEbg///G4L//xuC//8bgv//G4L//xuG/+8VhvshFYX7AP///wD///8A////AP///wD///8A////ABB29AAQdvQAE3n3GBuC/98bgv//G4L//xuC//8bgv//G4L//xuC//8bgv/4GIH9zxqB/qMbgv+dG4L/vhuB/u0bg///G4P//xuC//8bgv//G4L//xuC//8dhf//CVzYXABDtAAARrgA////AP///wD///8A////AP///wD///8AAGXoAABl6AAAY+cACHTzRB2D//Ybgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuH/4QAM7IAAA+JAAAQjwD///8A////AP///wD///8A////AP///wAAXuMAAF7jAABc4gABbe4AFoH8RhqB/u0bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//4agf6KGob/AAA0tgAAEI4AABGUAP///wD///8A////AP///wD///8A////AABf5AAAX+QAAF3iAAJu7wAPf/gAD375IhqB/rwbg///G4L//xuC//8bgv//G4L//xuC//8bgv//G4L//xuC//8bgv//G4P//xuC//8agv/oFn/8URiA/QAahv8AADS2AAAQjgAAEZQA////AP///wD///8A////AP///wD///8AAF/kAABf5AAAXeIAAm7vAA9/+QAPfvgAFn/8BxVx8Fcbgv+zG4L//BuE//8bgv//G4T//x2D//8bgv//G4L//xuD//8YfPPRGH/5dRGA+xgVf/sAGID9ABqG/wAANLYAABCOAAARlAD///8A////AP///wD///8A////AP///wAAX+QAAF/kAABd4gACbu8AD3/5AA9++AAWf/wAEGfkABiB/gEYgf0pFXXybxuB/qIXe/i8FX/6vxuC/60agf6CGoT/QA9p0QcUeOwAD4H8ABV/+wAYgP0AGob/AAA0tgAAEI4AABGUAP///wD///8A////AP//+Af///gP///wD///8B///+Af//4gP//gAD//gAA//wAAf/4AAD/8AAAf+AAAH/ADwA/wD/AP8B/4B+A//AfgP/4H4H/+B+B//gfgf/4H4H/+B+A//gfgP/wH8B/4B/AP8A/4AcAP+AAAH/wAAD/+AAB//wAA//+AAf//4Af/</Image>
-<Url type="text/html" method="GET" template="http://www.qxl.no/search/search.asp" resultdomain="qxl.no">
- <Param name="txtSearch" value="{searchTerms}"/>
- <Param name="InTitleAndDesc" value="1"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>http://www.qxl.no/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/rakuten.xml b/browser/locales/searchplugins/rakuten.xml
deleted file mode 100644
index 85c5b81b3..000000000
--- a/browser/locales/searchplugins/rakuten.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>楽天市場</ShortName>
-<Description>楽天市場 商å“検索</Description>
-<InputEncoding>EUC-JP</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,R0lGODlhEAAQALMOAOefn9psbMswMMMQEPjj4/PPz++/v+OPj99/f9+AgMcgIM9AQOuvr////wAAAL8AACH5BAEAAA4ALAAAAAAQABAAAARf0EnJ0FqIze2YemCoaBsQniEwMeIloOQHJk1NvKDSnTRQNIZThddYPAiNk4UYCDQIpwux1ghEEUTGc6BkhWiLA1DokD3Ag5/1odvlFlzFAkdymFAn1caDH3FWFhh1EhEAOw==</Image>
-<Url type="text/html" method="GET" template="http://pt.afl.rakuten.co.jp/c/013ca98b.cd7c5f0c/" resultdomain="rakuten.co.jp">
- <Param name="sitem" value="{searchTerms}"/>
- <Param name="sv" value="2"/>
- <Param name="p" value="0"/>
-</Url>
-<SearchForm>http://www.rakuten.co.jp/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/rediff.xml b/browser/locales/searchplugins/rediff.xml
deleted file mode 100644
index 445f08951..000000000
--- a/browser/locales/searchplugins/rediff.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Rediff</ShortName>
-<Description>Rediff Search</Description>
-<InputEncoding>utf-8</InputEncoding>
-<Image width="16" height="16">data:image/x-ico;base64,AAABAAEAEBAAAAAAAABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAP8AAP8AAP8lJf9iYv%2BkpP%2FR0f%2Ff3%2F%2FR0f%2BkpP9iYv8lJf8AAP8AAP8AAP8AAP8AAP8AAP9JSf%2Bhof%2Fe3v%2F19f%2F7%2B%2F%2F9%2Ff%2F7%2B%2F%2F19f%2Fe3v%2Bhof9JSf8AAP8AAP8AAP8AAP9JSf%2B9vf%2Ft7f%2F8%2FP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8%2FP%2Ft7f%2B9vf9JSf8AAP8AAP8lJf%2Bhof%2Ft7f%2F%2B%2Fv%2F%2F%2F%2F%2BHh4dAQEBAQECTk5P%2F%2F%2F%2F%2F%2F%2F%2F%2B%2Fv%2Ft7f%2Bhof8lJf8AAP9iYv%2Fe3v%2F8%2FP%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAABwcHD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8%2FP%2Fe3v9iYv8AAP%2BkpP%2F19f%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAABwcHD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F19f%2BkpP8AAP%2FR0f%2F7%2B%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAABwcHD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F7%2B%2F%2FR0f8AAP%2Ff3%2F%2F9%2Ff%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAABwcHD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F9%2Ff%2Ff3%2F8AAP%2FR0f%2F7%2B%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAABwcHD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F7%2B%2F%2FR0f8AAP%2BkpP%2F19f%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAABGRkafn5%2B9vb3%2F%2F%2F%2F%2F%2F%2F%2F19f%2BkpP8AAP9iYv%2Fe3v%2F8%2FP%2F%2F%2F%2F%2F%2F%2F%2F9gYGAAAAAAAAAjIyMyMjI3NzfDw8P8%2FP%2Fe3v9iYv8AAP8lJf%2Bhof%2Ft7f%2F%2B%2Fv%2F%2F%2F%2F%2BHh4dAQEBAQECTk5O3t7dAQEBubnDt7f%2Bhof8lJf8AAP8AAP9JSf%2B8vP%2Ft7f%2F8%2FP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8%2FP%2Ft7f%2B9vf9JSf8AAP8AAP8AAP8AAP9JSf%2Bhof%2Fe3v%2F19f%2F7%2B%2F%2F9%2Ff%2F7%2B%2F%2F19f%2Fe3v%2Bhof9JSf8AAP8AAP8AAP8AAP8AAP8AAP8lJf9iYv%2BkpP%2FR0f%2Ff3%2F%2FR0f%2BkpP9iYv8lJf8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="text/html" method="GET" template="http://search.rediff.com/dirsrch/default.asp" resultdomain="rediff.com">
-<Param name="MT" value="{searchTerms}"/>
-<Param name="sourceid" value="Mozilla-search"/>
-</Url>
-<SearchForm>http://search.rediff.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/reta-vortaro.xml b/browser/locales/searchplugins/reta-vortaro.xml
deleted file mode 100644
index 2491188ea..000000000
--- a/browser/locales/searchplugins/reta-vortaro.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Reta Vortaro</ShortName>
-<Description>Äœenerala reta vortaro en Esperanto / General online dictionary in Esperanto</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAQAAEABAAoAQAAJgAAACAgEAABAAQA6AIAAE4BAAAoAAAAEAAAACAAAAABAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMD%2BwACAgAAAuvOvAMDAAACFixEAwP%2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmZmAGZmZgZmQkZmZCJGZmYiJmZCZiRmZCYkZiJmJWZiRkJmImYlZkJmYkZCZiRmJGZkJmQiQ2ARZmFmZhERACJmQkYiIiQGImQkZiRERmYiREZmJGZmZiIiRmYiImZmImYkZiRmZmYiZiRmJERGZiIiRmYiIiRgZmZmAGZmZggYEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYEAACgAAAAgAAAAQAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIAAAMDAAADA%2F8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzMzMAAAAzMzMzMAAAAzMzMjMzMwAzMzMzMzMwADMzMxETMzMzMzMiIjMzMwAzMzIREjMzMzMhERESMzMDMzMxEREzMzMyERERESMzMzMzIRERIzMzIREjMhESMzMzMxESERMzMxESMzMhETMzMzIRExESMzMREzMzMREzMzMxESMhETMzERMzMzERMzMzIREzMREjMxESMzMhETMzMxESMzIREzMhESMyERIzMzIREzMzERIzMhEREREjMzMxESMzMyERMzMhERESMzMwMhEzMzMxEjMzMyIiMzMzADMzMzMzMzMzMzMzMzMzMwADMzMzMzMzMzMzMzMzMzAAAyEjMzMzISMyERERESMwADMREzMzMhETMRERERETMwAzERMzMyERIzERERERIzMDMxETMzIREjMxETMzMzMzMzMREzMhESMzMREzMzMzMzMzERERERIzMzERMzMzMzMzMxERERESMzMxERESMzMzMzMRERERESMzMRERETMzMzMzERMzMhETMzERERIzMzMzMxETMzMREzMxETMzMzMzMzMREzMyERMzMREzMzMzMzMzEREREREjMzERERERIzMwMxERERESMzMxERERERMzADMhERESIzMzMhEREREjMwADMzMzMzMzADMzMzMzMzAAAAMzMzMzAAAAMzMzMzAADwB%2BAPwAGAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAYAD8AfgDw%3D%3D</Image>
-<SearchForm>http://www.reta-vortaro.de/revo/</SearchForm>
-<Url type="text/html" method="GET" template="http://www.reta-vortaro.de/cgi-bin/sercxu.pl" resultdomain="reta-vortaro.de">
- <Param name="sercxata" value="{searchTerms}"/>
- <Param name="kadroj" value="1"/>
- <Param name="from" value="mozilla"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/salidzinilv.xml b/browser/locales/searchplugins/salidzinilv.xml
deleted file mode 100644
index 464a639a1..000000000
--- a/browser/locales/searchplugins/salidzinilv.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Salidzini.lv</ShortName>
-<Description>Salidzini.lv - Latvijas interneta veikalu mekletajs</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAABoBQAAJgAAACAgAAAAAAAAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wDfn0gA7s+kAPbn0gDmtnQA6sONAPrz6QDz27wA46laAOSvaADpvIAA7MiYAPz59QD47NwA8dayAPXiyQDhpFAA+/bvAPnv4gDpv4YA4aVWAP38+gDv0qkA897BAPfp1wDx2LcA46xkAO3LnAD15c0A4KFMAOi6fADrxZEA+vHlAPTgxADqwYkA7s2hAPv07ADlsGsA7MaUAP39/QD8+PIA6b6DAOGlUwDy2rkA8di0AOKnVwDgoEoA4KJQAPry5wDkrmQA9+rZAPfo1QDmtXIA5K5mAP7+/gDhok0A/PfwAOi9gQD+/fwA/fz8APz69gDgpVQA+/XtAPr06wD68OQA9uTNAOm7fwD05M0A6Lx/AOm9ggDqwIgA68OOAOvEkADsx5UA7cqbAOzKnADuzqMA359JAP7+/QDgoEkA/f38AOCgSwD9/PsA4KNQAPfq2AD36dYA9eXOAOi8gADpvoQA6b+FAOvFkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdBNS9QTk5QUAJQThFEKAE3Ow8KK1IuGz4CUFBQHz8BNzcSSiwlPDdTTDhOUBVXATc3NwdTNzc3NwQJUFAeIgE3Nzc3Nzc3NzcYMlQvMBABNzc3Nzc3NxYEBkMFNiYOATc3Nzc3JR0nWEVFRVgYOwE3NzcWBAwqRUVFCzoXPTcBNzc9FzpFRUVFFBw0Uzc3ATc7GFgLRUUqTRk5Nzc3NwE3IVtFRVhLMTc3Nzc3NzcBN1UqRQsjMzc3Nzc3Nzc3ATcZRkVFWkI3N08NVkA3NwE3E0hFRUVJLQgPJEcYNzcBNxYaRUVFRUVFRVhFIFE3ATc3KQM6RVhYRVgLC1kSNwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAIAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A3Zo+AP7TmQD15c4A6rVuAPOtTwDqwooA8de0AP/z5ADiqV0A+sZ/AOzKnAD/47cA5qRKAOe7fAD7+PIA//DRAPPewQD4v3IA9LNcAO/RqAD/6sUA+OvbAPCmQwD7zIoA6bBjAP/ZogD//usA4aRUAOvGkwDuwYIA355GAPPPngDnqVYA///0APr07ADlsGoA+uTGAPvp0QD57+IA6K1cAOa0dADwxIoA8apJAPDUrgDgoU0A9OHHAPLbvAD32rUA6L2DAP37+gD+8N4A9unVAO7OogD44L4A+smFAOStYwD/9ukA5aVPAPvmywD0sVcA/+7MAOi4eADls28A/e3aAOKnVwD8z44A68OPAPny5gD/+vMA3pxCAOzIlwDqs2oA6cCGAPz69gD///sA+/buAPXjygDpvH8A8tm4AO/ChQDw0qsA7cyfAP/48ADoq1kA9ufSAPHVsQD9/f0A8atNAOSrXwDlokcA36BKAOCjUAD47uAA89y+APLOmwD/8uEA6K5fAOWvaADz38QA7cB/AO7PpQDxqEUA5rVxAPzKhwDrwIkA68ONAP/05wDmpUwA57l6APz38QD78+kA8KlIAOGmVQD979wA9+zdAPfp1wDpun0A6b6CAO3JmgD//v0A/v37APz7+ADenUQA/Pn0AN+fSADyqksA4qhcAOivYQD048wA5bJtAPrlyADqtGwA57Z0APLaugDx2bUA6b6FAO/DhwD/05sA79KpAOvFkQDsx5UA9ujTAPjgwADou34A6sCIAPHVrwD69e0A4KBLAOChSwD+9egA5qRLAPrz6ADjrGAA/OrSAOSxaQD14skA9ODFAPPcvADounsA6Lx9AOi9gADpvYIA7r+AAPHWsgD7yIQA7sGEAOq/hwD7y4kA8NOtAOrBiwDpwo4A68SPAO/PpADty50A/v7/AP3+/gD+/f4A/v78AP38/ADemj8A/fz5AN6bQQD9+vgA/fv3AN+dRQD9+vUA3p1GAP/79ADgn0cA/PjzAPCnRQD89/IA+/fxAPz38ADxqUgA8atKAPn07ADho1EA8qxNAPKsTwD68eYA4qdVAPnw4wDjp1gA+vDiAOapVwD+8uAA56pXAPnu4QD98d4A6KxbAPjt3QDjql8A/e7bAPjs3AD46toA5K5kAPfo1AD359MA++fMAPXkzQD24soA57h5AOi4egDnun0A9N7AAOm7fgDz3b8A6Lt/APLcvwDnvH8A8ty9AOm+gwDqvoYA8di3APvJhgDy2LUA6sGJAOnBiQDvxIgA8dSuAOzGkgDw06oA7MaUAOvHlADw0agA79GnAO7QpwDtyJgA7MmYAO7PowDuzaMA7cqbAO7NoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGwl5NuQly6ICB8fHy8ICAgfHwgfn4gR8uSZMawsLAAAQEBEYsTFAZ/ZxjAxFnJWXHAccUGBsgsPQsNHAEBAQCwAQFhMSuF1FUi0SkahQVJgc87mJgODlttYoo3IwGwALIBARBWruaGT2t4rlKlCFf5rEBCliB+fn6VY1PTAbAAWAEBeZnlU6/uBNJNEH1Lu5SCDINdfCB+frqARCcBsABYAQEBuNgvTtJ9AQEBAQEBAZTnic26IH4gtx2JhAF5AFgBAQF6b3CUuLABAQEBAQEBfd7zWr6+viC1x3cmAXkAWAEBAbB6tLABAQGwsLABAQF9BEjalr4gfAJddyYBeQBYAQGwsLCwAQEBAQEBAQEBesrlrZxyXS5+R3KoPAGwAFgBAbCwsAEBsLABAQEBAbCU3hWShmOagB2VCkSbAbAAWAEBsLCwsAEBAQGwWHp9RQQtHqN2P2glOdYq/TQBsABYAQGwsLCwAQEBekskF53sZo3q5k9PoIYq4UgSVAGwAFgBAbCwAQEBWH1w2E6l/quJok+hT5Gg4DJ45Sh5AbAAWAEBsLABAVhN2WSl/I2j4OBuoZGhbm6RHlBeewEBsABYAQGwsHlLRQQIr2tKopEPD6Ch5E+iqPaTjxABAQGwAFgBAQFYTTXp+R6JoaCgoaEPbqBPqI4VX3VNWAEBAbAAWAEBsMKPLR5K6KGhDw8PD08y7x42UFaZS3mwsAEBsABYAQF9dIiNduBuD6EPbm6Rq3hSh53Vw3kBAbCwAQGwALEBAcwSr+puoOSRoU93744VX9zMlLl5AQEBsLABAbAAsQG9BPgHoW6RT5Gi76+lntvMbzOwAQEBsLCwsAEBsABYATowjqKhD5GhovBT416/M1iwsAEBAQGwsLCwAQGwAFgB0JMHoKGRkaGor1/SMwEBAQEBAQEBAQGwsLABAbAAWAFz9KhuoZHkkWuq28EBAQEBAQEBsHl5sLCwsAEBsABYAUH36+ChoXbia5MXMwEBAQEBAQG5EBC4erCwAQGwAFgB11KobqGhoQ/vrt9wM3p6tLZ7TV51F3BLeQEBAbAAWAE0qmqgoaGh4ur18p3YzijSF3VOUFcwdU2zAQEBsABYAWxQ86KhoaGRT0oeZgifn4cIqjbzrVMSzHoBAQGwALEBRp3/qA9ukU+hT+qrHvv6SB5EkuaR74w1MwEBAbAAsQEBCZAh8WUfHx8fH6enUVGnp6cfpKQfYN1MAQEBsAABAQEBHBYbQxmpGampae04ODjtaWlpaaYDPgEBAQEBALGwsFgkTmYHog+hoaGRkQ8PD5GRkU92P2pQcLGwsLAA/////wAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE=</Image>
-<Url type="text/html" method="GET" template="http://www.salidzini.lv/search.php" resultdomain="salidzini.lv">
- <Param name="q" value="{searchTerms}"/>
- <Param name="utm_source" value="firefox-plugin"/>
-</Url>
-<Url type="application/x-suggestions+json" method="GET" template="http://www.salidzini.lv/suggested_search.php">
- <Param name="q" value="{searchTerms}"/>
- <Param name="utm_source" value="firefox-plugin"/>
-</Url>
-<SearchForm>http://salidzini.lv</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/sapo.xml b/browser/locales/searchplugins/sapo.xml
deleted file mode 100644
index d5f7803a3..000000000
--- a/browser/locales/searchplugins/sapo.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>SAPO</ShortName>
-<Description>Pesquisa SAPO</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXmHT/EnM8/wd6L/8EdRj/BHUY/wd6L/8Sczz/WJh0/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACt+UP8FaTL/B4I8/wmoTv8JO03/Ew62/xMOtv8JME7/CahO/weCPP8GajL/K35Q/wAAAAAAAAAAAAAAABJzPP8Hgjz/Cq5P/wm6Vv8BIwj/DAB8/xcG3v8ZB+b/DACA/wEUBf8JtVT/CahO/weCPP8Sczz/AAAAAECTZP8IkEP/Ca5Q/wquT/8CHA3/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AhwN/wmuUP8Krk//CJBD/0OUZv8IkEP/CahO/wquT/8FYCz/CJBD/wd3N/8DIA//AQwE/wEMBP8CHA3/BWAs/wiQQ/8FYCz/CahO/wquT/8HjkL/CahO/wSIPP8Hdzf/BqQ+/wakPv8GpD7/BqQ+/wakPv8GpD7/BqQ+/wakPv8GpD7/BqQ+/wN9N/8DfTf/CahO/1fAhv8Vm0//Ao82/wOmR/8Pok//BqQ+/wSeNP8Dpkf/A6ZH/wSeNP8GpD7/D6JP/wOmR/8Cjzb/FZtP/13Ejf8AAAAAa8eW/13Ejf8TqFP/AZgu/x2Zfv8xxdP/D6JP/w+iT/8xxdP/HZl+/wGXLP8Sp1L/aMiV/3fLof8AAAAAAAAAAAAAAACc1rv/u+rN/3G0nP8E8Pf/A/D3/xfNz/8Xzc//A/D3/wPw9/9ws5v/wezS/5zWu/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGQkH/BPD3/wAkJv8D8Pf/A/D3/wAsLv8D8Pf/RkJA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARkJB/0vw9v8E8Pf/NrjA/zi1vf8D8Pf/SPH3/0ZCQP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGQkH/etfY/0ZCQf9GQkH/edbY/0ZCQP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZCQf8AAAAAAAAAAEZCQf9+fHz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////////wD///wAP//4AB//8AAP//AAD//wAA//8AAP//gAH//8AD///wD///8A////gf///9n////////w==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://pesquisa.sapo.pt/livesapo?q={searchTerms}" />
-<Url type="text/html" method="GET" template="http://pesquisa.sapo.pt/FF2" resultdomain="sapo.pt">
- <Param name="q" value="{searchTerms}"/>
- <Param name="enc" value="utf-8"/>
-</Url>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/seznam-cz.xml b/browser/locales/searchplugins/seznam-cz.xml
deleted file mode 100644
index 66da3c0fc..000000000
--- a/browser/locales/searchplugins/seznam-cz.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Seznam</ShortName>
-<Description>Vyhledávání na Seznam.cz</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFGSURBVHjalNI/KEVRHMDxc+5DKZM3qNvbXH+ysSBFGMSgLDJKseCtymKwSK+UmVEmTG+RQQxKJgzkleVa3vAGIqXn+p763Tqdrnv51ad3T+fc3/vd3/npKIpUrVBQKdGCbvRhDPP4NButYagaEl5oloMjGEA7fGv/ERvxQjsVzGALnSkVhegwVbgVjONYZccJ6vHCTrCUcPgbb1L2Pc5QxldSglvMOgmeMYeb38rxrOcS9p1908B1FDGEJjeBTrjGKaxhOOEPD3GJI1RNE3XKHAxiQRL6zt4utknw4qV0+wqL6ME0DvAue8W4X/oPk2iHuf89+bwaFeQ99b94kms00eheY1b40pNNWa9mJcihCxOYxKicP8cOLuwEGm0I0J8LglK9UnngOY8PXGMFpzJcyp1E0+1eSfTKy8v83skIV9O+60eAAQAd5lci6mlq3QAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://suggest.seznam.cz/fulltext_ff">
- <Param name="phrase" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://search.seznam.cz/" rel="searchform" resultdomain="seznam.cz">
- <Param name="q" value="{searchTerms}"/>
- <Param name="sourceid" value="firefox"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/slovnik-sk.xml b/browser/locales/searchplugins/slovnik-sk.xml
deleted file mode 100644
index 0b1fdee2f..000000000
--- a/browser/locales/searchplugins/slovnik-sk.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Slovnik.sk (EN-SK)</ShortName>
-<Description>Prekladové slovníky - Slovnik.sk</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAABoBQAAJgAAACAgAAAAAAAAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD5cRMA/rqPAPmWUgD+28cA+YIzAPmqcQD+7OEA+8mlAPifYgD5jEIA9XgjAP6xgAD++O0A/Na4APlnBwD/49IA/aJrAPp+KgD6w54A/vv3APl0HAD7hzoA/fDoAPucVwD6rnoA/Nm/APzo1gD1k00A/XggAP7o3AD4m1wA+qJmAPqUTAD6//4A9nIXAPp5JAD7iD8A+6t2APh4HwD2fCgA+7ODAP/dywD/+PQA+/XuAPvr2wD//PsA/uTWAP3dwAD8pmoA+IAtAPeHOwD3iEAA+5NQAPyBMQD8hDgA/dS7AParcwD9//wA+nYiAPd7IwD/38gA/vTtAPdyGgD+694A+XMfAPR4IAD5fCcA/P3/AP3k0AD7gTUA/NzFAPp4HQD8170A/u7nAP/q2wD5eh4A93khAPqcWwD8sH8A//79APhvEwD5dRoA+ncgAPh3IgD+3ckA94ArAPiJOwD9//8A//3/APZ4HwD87+cA/+vgAPl5IAD7eCEA9nciAPV5IQD3eCMA+XgjAPZ5JAD5fSkA+9i+AP3VuQD4i0EA+JdTAPv//wD+/v4A/P7+AP7//QD8//0A///8AP/9/AD6eB8A+HcgAPl4IQD/4tEA+YM0APiJQAD7lE8A//7/AP3+/wD8/v8A///+AP3//gD+/f8A//7+AP78+wD2eCAA93kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVhgChJJWBNKE48XkOAc1RjawF4WXoBWVlZe2trWQFgKAFZfll7CCtmdG8BfFp9c2B+bQFWMiYCEEQZOWoBb2FzeFkwdVI3OioEW0dIeFFzVTt4MXJoBVkBRhcWB2x4KGJZeHARP3hBZxo0UycBeGOAAXoBaxRPC15CPTYfe1lzTntaLCA8ZIB2IQkVe3gBKGMBAQ9yBhI+GHsvXAF5AV9OblkbHldQcAFKWDguAXuBXnhRfwpAMx1pZSQ1THt4clV7fFlLAyITKXcNHG1Ze3GAAXtrAXkOXV0tAXt4ASNzY3hFAWt7AXt4eAEBfH0BPF5yYXNfgGNODF5eVWMoTlsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAIAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A+m8VAPy4igD6lFAA/9vFAP6EMQD97eIA/adsAP3LqAD2YAAA/8eVAPh6IwD5iUEA//jvAPqvewD+49MA/NO3APudXwD/rl4A/8SLAPq9lgD7xaEA9YIzAPl9LAD84csA+rOEAP/p2wD5mVYA+ql1AP769wD4kEoA/vLpAP3XvgD5dh0A/aJmAPmGOQD/y54A+WsPAPzOsgD/9OMA/ocrAPy7kAD5gi8A+41GAPzCmwD3chgA+H4oAP3QrQD628MA+aRrAP726gD/4NAA+6pxAPzIpAD/xZIA//z7APdvEQD6gjMA9pZSAPyWVAD9694A/bGAAPdkAgD/+/MA//fzAPd3IAD5iD0A/H0pAPzjzwD6oGIA+6x4AP3u5gD+6dcA+XsoAPzm1AD91LsA/8qYAP/fyQD/2sEA+o5BAPqSTQD90rQA/J1bAPz9/AD+9O0A/+zgAPuFNwD3jUMA/MieAP3AmAD8vpMA/LSGAPlzGgD7dh8A94AvAPrZwAD/xI0A+IQ2APvJqgD3m1kA+7F9AP718AD2dx4A/+7iAPl6IQD2dyMA/M6sAP3HowD5rHQA/Kp2APyuewD5cRcA/ebVAPd+KgD5fywA/+PSAPaCMAD5j0cA+Z1cAPugXwD6o2cA/KJqAPq5jAD3qnEA/LeHAPywewD6soAA/f//AP/89gD++PUA928UAPZyFQD4dB4A93kgAPd7JgD/4M0A+oEwAPeBMQD4gzEA/dfBAP3avgD917sA/dW2APrQsQD6mFMA+ZlaAP/GkgD9vI4A/LiNAPyqcwD9s4QA/f77AP/7+QD5bxAA+XchAP/m2QD9hC8A+5xdAP/9+QD/8+wA/fTrAPhwFgD98ucA//DnAP7q3gD4fCUA+IEsAPmGNwD92sQA+os/APiMRQD+07kA/dO2APvRtgD7zq4A+ZhVAPuhZAD6pWsA/KlvAP26iwD6rnoA/f79AP/+/QD/+vUA//nyAP/68AD4cRQA//buAP706QD6eSIA/O7kAPl8JwD+6uAA+n4rAP7o2QD6gjEA+IIzAPyFMQD6hDMA++PRAP3hzQD5hjsA/N/KAPqIPAD7iD4A+Io/APuKQgD5jkUA/NS5APqWUgD7yqkA/MimAPmcXgD7xqIA/J9iAP/LmwD/yJcA+qRoAPvCmQD/xZQA/b+WAP27kgD6tYYA/LB/APizggD//P0A/fz7AP36+QD/+vcA+XcfAPd5IgD4eCMA/+7hAP3s4AD4fywA/oUrAPmALgD+59cA+oEyAPaDMQD949EA94MzAPzhzwD+2sIA+Y1DAP3awAD9y6oA/8qWAP/GlwD6p2wA/b6YAPq+kwD/xIwA/LaKAP79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGopxvDw8IsrK8Q6xcXFi4uL8vLF74mLdXV18IsG7JsAwhNhC5OTk5OTkwv52dn4TU1N2Qvc3JOT3JOT3GETRACJ/Si5ubm5uUBAuLhAQLm5ublAQEBAubkODrm5KGGKAIvYAQEBAQEBgIABAQEBAQGAAQEBAQEBAQEBAQEBJcUAKwuBAQEBAQGAATi8pTQFTNEhiGiBAQEBgAEBAbjZigBfNw4BAQEBt2buIWyVbtc80p6WlDCIpOOAgAEBDpPwAIo3DgEBATik9N2zPM+JaXBw5itQeH2tB1SAAQEOk/AAijcOAYD/pKzgUYleXr4v63NKDGmnLG4nvzgBAQ6TiwCJN7kBgB40XEOiOSJXHHzhfzWwqIaFzW8hoAEBuZOLAIk3ugEBDo6xLgqDDW42Mcjx9Nt46yZeBPxLtgFAk4sAijcOAQEOjTWL5x9cjCDj/5mg9mXMAl2obWBUAbiTiwDFN7oBAbhJNn5v1hCZAQEBQT1StQ1du3N5Ef8BgdyLAMXcuQEBt7hWdPHqZkGgG06tLbUcYl0izG+ptwG43DoAdTe5AQEBAQEBgurLrWwqfrEEQ1/nXXMSbKUBAUDcOgB1N7oBgIABt0HzFg9G0vXHwJub6HIknvsQggEBudyLAHWTugEBATg9rhqSQ3JnhDmihXMNd3/3EEEBAQG5k4sAdZO6AQG3IK8yykroh4dy8quwst/TRbz/AQEBAbmTiwCKN7kBAbnJfyRwhRgNHPoaFdMhcaCAgAEBAQEBuZPEAO/cuQEBva15SrsYLHpaT8NIZrhBoAcHVTgBgAG53MQAije6AQGja1Nemu3SlwWfAQEBgsnU/t7Ro7YBAbqTiwB1k7qAgFWOCESapnZvTFUe5WgRD3bCLANLmAEBupOLACuTugEBHnEDQ7su67Df05BrW9qoOT9KRxmfAQG5k3UAKzcOAQG3Zq4yYkJCilg7ZLDQiSIuQh8qcZ8BAbncigCJNw4BAQG3PWMdUTovhmdCQua+wqrVe40gtwEBuTeJAIo3DgGAgIDkwUzeCJGqx+3FztIjlwlFoZ8BgAG6k8QAijcOAQG2gAHioHSPWbQ+b+B7FlJOaLgBAQEBgLqTxAB1C4EBAQEBAQEBAR4z6RucGwehHgEBAQEBAQGAgdmLAMXYAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBJToAif0ouroOuroOublAQEC5ublAQLhAubm6ug66uihhiQBEExQ3kzc3Nzc3N9wLCwsL+QuTN5M3N9w3NzeTFBNEAL4pnXV1dYmJiSt1ijqLi/AXxYsrK4qKxe+JKyudKYYA/////wAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE=</Image>
-<Url type="text/html" method="GET" template="http://slovnik.azet.sk/" resultdomain="slovnik.azet.sk" rel="searchform">
- <Param name="q" value="{searchTerms}"/>
- <Param name="l" value="en-sk"/>
- <Param name="sourceid" value="firefox"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/sslv.xml b/browser/locales/searchplugins/sslv.xml
deleted file mode 100644
index d0e687e9f..000000000
--- a/browser/locales/searchplugins/sslv.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>SS.lv</ShortName>
-<Description>SS.lv - LielÄkais sludinÄjumu serviss LatvijÄ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEAqgADAIAAAgAAAAAAAAAAAIAAAgBVAAMAAAAAAAAAAACqAAMAgAACAAAAAAAAAAAAgAACAKoAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAACF4sACxqGCGEZhQesG4YIyhqGCMYahgilGYQIPgAAAAAggAAIG4UJVhqGCKUahgjIGoUIxxqGCKgZhQdHAAAAABqGCGEemQn/HI8J/xqGCPIahwj+HJEJ/xqICP8ciQk2GocHRh2WCf8ckQn/GoYI9RqGCP4ckQn/G4oI/xqFCVgahghjG4cIthmGCD0kkgAHEYgADxmGCMkdlQn/GoYJkRqEB00bhgjAGocIRBSJAA0ggAAIGoYIuRyRCf8ahgi+FIkADQAAAAAAAAAAEYgADxuFCF4ahgjgHJEJ/xqFCJ0AAAABAAAAAAAAAAAcjgAJGYQJURqGCNccjwn/GoYIvQAAAAAXgAwWG4YHjxqGCOYbjQj/HJAJ/xqHCP8ahQdFAAAAACKIAA8ZhgiDGoYI3xuMCP8ckAn/G4oI/xqHCVcbgAkcGoUI2BySCf8ckAn/GoYI+BqFCLgbhQhBAAAAABuGDRMahgjLHJEJ/xyQCf8ahgj9G4YIwBuFB0sAAAAAG4cJcxySCf8ahgnwGocIiBuGByYAAAAAAAAAAAAAAAAahQdrHJAJ/xqGCPYahgmTHIgGLQAAAAAAAAAAAP8AARmGCHodlAn/GoYHzxWAAAwAAAAAHIUGLhuGB48YggYrGoUHaxyTCf8ahgjhGIYMFQAAAAAagwcnGoYIhxuGB0wXhQYsGoYH7xyRCf8ahgj2GocI6RuNCP8dlwn/GoUHRRiGDBUahgjqHJIJ/xqGCPcZhgjnG4oI/x6aCf8ahwhiAAAAAByIBi0ahgigGoYJzxmGCNMbhgetGocIZBKAAA4AAAAAGoMHJxqGCJwahgnQGoUI2BqGCbMahgduHocPEQCAAAIAAAAAAAAAAAD/AAEA/wABAAAAAAAAAAAAAAAAAFUAAwAAAAAAAAAAAIAAAgBVAAMAAAAAAAAAAAAAAAAAAAAAAIAAAgBVAAMAAAAAAAAAAACAAAIAgAAEAAAAAQAAAAAAgAACAFUAAwAAAAAAAAAAAP8AAQCAAAQAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAOfnAAAZmQAA/v4AAAEBAAAAAAAAAAAAAGBgAACAgAAAAQEAAAcGAAAICAAAAAAAAICAAABnZwAAmJgAAOfnAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYIFBqGCEYahgh3GoYIlBqGCKMahgifGoYIjRqGCGkahgg0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqGCAgahgg6GoYIbBqGCI8ahgifGoYInxqGCJAahghvGoYIOhqGCAMAAAAAAAAAAAAAAAAAAAAAGoYIJBqGCIsahgjqGoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgi5GoYIKwAAAAAAAAAAAAAAABqGCBMahgh2GoYI1xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYIyRqGCEAAAAAAAAAAAAAAAAAahgi9GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgjsGoYIMwAAAAAAAAAAGoYImhqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI+BqGCEwAAAAAAAAAABqGCMEahgj/GoYI/xqGCP8ahgj/GoYI8hqGCOAahgjnGoYI/xqGCP8ahgj/GoYI/xqGCP8ahgjLGoYIBwAAAAAahgilGoYI/xqGCP8ahgj/GoYI/xqGCPkahgjkGoYI5xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI6BqGCCMAAAAAGoYIwRqGCP8ahgjzGoYImRqGCFIahggZGoYIBxqGCAwahghKGoYI2hqGCP8ahgj/GoYI/xqGCP8ahgg1AAAAABqGCKQahgj/GoYI/hqGCKkahghcGoYIIxqGCAkahggLGoYIQRqGCMoahgj/GoYI/xqGCP8ahgj/GoYIZwAAAAAahgi9GoYIoxqGCCIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAahgiAGoYI/xqGCP8ahgj/GoYI/xqGCFIAAAAAGoYIpxqGCLkahggzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYISRqGCP8ahgj/GoYI/xqGCP8ahgiHAAAAABqGCBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYIEhqGCMAahgj/GoYI/xqGCP8ahgj/GoYIUAAAAAAahggfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqGCAYahgicGoYI/xqGCP8ahgj/GoYI/xqGCIUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYILhqGCIsahgjhGoYI/xqGCP8ahgj/GoYI/xqGCP8ahggwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqGCB0ahgh2GoYI0BqGCP8ahgj/GoYI/xqGCP8ahgj/GoYIYgAAAAAAAAAAAAAAAAAAAAAahggHGoYIWRqGCMcahgj8GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYIxRqGCAUAAAAAAAAAAAAAAAAAAAAAAAAAABqGCEIahgizGoYI8hqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCOYahgghAAAAAAAAAAAAAAAAGoYIUBqGCNEahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCO4ahggxAAAAAAAAAAAAAAAAAAAAABqGCDUahgi8GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj7GoYITAAAAAAAAAAAAAAAABqGCIIahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgi3GoYIMAAAAAAAAAAAAAAAAAAAAAAahghgGoYI9RqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYIzBqGCEUAAAAAAAAAAAAAAAAahghhGoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCPMahgimGoYIQgAAAAAAAAAAAAAAAAAAAAAAAAAAGoYIOxqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj6GoYIvhqGCFIahggFAAAAAAAAAAAAAAAAAAAAABqGCMwahgj/GoYI/xqGCP8ahgj/GoYI/xqGCM0ahghuGoYIHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAahgi2GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgjcGoYIgxqGCCYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYI8RqGCP8ahgj/GoYI/xqGCPMahghmGoYIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYIBxqGCN8ahgj/GoYI/xqGCP8ahgj8GoYIgBqGCAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAahgj5GoYI/xqGCP8ahgj/GoYIkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAahghMGoYIVQAAAAAahggMGoYI5BqGCP8ahgj/GoYI/xqGCMsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYIOBqGCGkahggEAAAAABqGCOEahgj/GoYI/xqGCP8ahgjTGoYIORqGCAIAAAAAGoYIDBqGCDYahghvGoYIyxqGCP8ahgiKAAAAABqGCAIahgjTGoYI/xqGCP8ahgj/GoYI6xqGCEMahggEAAAAABqGCAUahggsGoYIYxqGCLoahgj/GoYIuwAAAAAAAAAAGoYIkxqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI1xqGCMwahgjkGoYI/xqGCP8ahgj/GoYI/xqGCIIAAAAAAAAAABqGCHMahgj/GoYI/xqGCP8ahgj/GoYI/xqGCNkahgjKGoYI2xqGCP8ahgj/GoYI/xqGCP8ahgiwAAAAAAAAAAAahggOGoYIxRqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYIiAAAAAAAAAAAGoYIBRqGCLIahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCLgAAAAAAAAAAAAAAAAahggNGoYImRqGCPgahgj/GoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI6BqGCJoahggrAAAAAAAAAAAAAAAAGoYIAxqGCIUahgjzGoYI/xqGCP8ahgj/GoYI/xqGCP8ahgj/GoYI/xqGCPMahgirGoYIQAAAAAAAAAAAAAAAAAAAAAAAAAAAGoYIKBqGCGgahgiUGoYIthqGCLoahgibGoYIdxqGCEsahggUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqGCCIahghkGoYIlRqGCLoahgjBGoYIqRqGCIIahghVGoYIHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////////////////////////+AP4AeAA4ADgAGAAYAAgACAAIAAj8CPwL+Av4D+AP4A8AD4AOAB4AHAA8ADgA+AB4A/gD+A/wD/g/kD+ICBAIGAAYABgAGAAcABwAHwB/AH////////////////////////////////</Image>
-<Url type="text/html" method="POST" template="https://www.ss.lv/lv/search_result/index.html" resultdomain="ss.lv">
- <Param name="txt" value="{searchTerms}"/>
- <Param name="from" value="firefox-plugin"/>
-</Url>
-<SearchForm>https://www.ss.lv</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/sztaki-en-hu.xml b/browser/locales/searchplugins/sztaki-en-hu.xml
deleted file mode 100644
index 80a90203b..000000000
--- a/browser/locales/searchplugins/sztaki-en-hu.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>SZTAKI angol-magyar</ShortName>
- <Description>Keresés a SZTAKI angol-magyar szótárában</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAN1wAADdcAAAuTgAAITYAACA1AD0wTwCgP2kA1EZ0AOpGdADqPmgA1i5NAKUZKgBDERwAABQiAAAUIgAAFCIAADdcAAA3WwAALUsACjZaAJhNgAD+VY0A/1SMAP9TigD/U4oA/1SMAP9VjgD/TH4A/yxJAKESHgAQEyEAABQiAAAvVgAALlQACjppALlKhAD/SYMA/0iBAP9IgQD/SIEA/0iBAP9IgQD/SIEA/0qEAP9MhwD/LFIAwwsZABARIAAAgZliAIilYJOVu2L/lbpj/pK2YP6NsFr+jbBZ/oyvWP6Mr1j+jK9Y/oyvWP6Mr1j+jLBY/pC1Wf9WZz+iIScXALKnoTbFu7v9zMTI/8vDyP/Y1dv/+/r///36////////////////////////////////////////8vHz/1NTVUGOfLudkF5Y/3oqA/9sFgD/bCsV/8K+vP/3+Pj/9/f3//////////////////////////////////////+Xl5eompL11mJT5P+Laar/m1VA/38cAP+Vc2f/2uDg//T08v/5+fj/////////////////////////////////1tfO2fXm1e3p5vr/jYTw/2pc5P+ifqD/3sfC/2Zeuf/c3dn/5OLv/4B13f2Dd+P+hXni/oV54v6FeeL+hXnk/nluy+rUxdjs5+P4/+zq+v/EvvP/w8H8/+De/f8+KdX/ST2k/+3v4/+Fe9j/DADG/xgBzP8ZA8v/GQPL/xkCzv8cCLnrVUTd1C0W0P8yHNH/NyLS/zci0v8yHNH/LBXR/x8HzP9ZT6b/+fzp/4h+2v8ZAsz/IAvQ/yEL0P8iC9X/Hwy112JR3JgdBMz/IgrN/yAIzf8fB8z/HwfM/ykSzv8sFdL/GADH/2hfqP/q69//cGXG/zUkvP87K77/Py/F/ycZmaTa1vYxurPv/Kif6/+3sO//wr75/7659f9BLNP/IAfM/42B6f+xru//vbzQ/+Xm1//Y2dD/zcnF/8S9tf+UkJk+7ev6AL648I6bker///////Hh0P/s29H/UT/d/xsDzf+9suf/07i3/35v5f+AdvL/4d3+//3z6/++mYudt5yPAPX0+wD29fwH+vbysbaDbv95GwP/xqGY/1NF5f8dBc//sKTi/5hIGf+YTzr/h2Oh/15M2f+wqfC8+fv1De3s7AD+/v0A////APTt6ge5ineNhC4U+seknP9MPeP/FwDO/7Ck5P+URBr/cA4A/4kxB/28lZCXtK7xC/Lz8gDw8PAA/f39AP///wDz7OoA6NnTANzDtjTn2NSVfG/m0D8q1uu6sOfrrnFQ06ZpUpq7jXk6yKecAL+67wDx8fEA7+/vAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAN1wAADdcAAA3XAAAN1wAADFSAAArSAAAJj8AACI4AAAdMAAAFiUAABQhACgcLgBxKEIAsDNVANE6YgDjPmcA7D1mAOw6YADlMlMA1CZAALYaKwB5Eh4AMREdAAAUIQAAFCIAABQiAAAUIgAAFCIAABQiAAAUIgAAFCIAABQiAAA3XAAAN1wAADdcAAA3XAAAMVIAACtIAAAmPwAAIDUAAB0wADIrRwCsQGoA906BAP9TigD/VI0A/1SMAP9UjAD/VIwA/1SMAP9UjQD/U4oA/02AAP89ZQD8JT4AuRIfAD8SHgAAFCIAABQiAAAUIgAAFCIAABQiAAAUIgAAFCIAADdcAAA3XAAAN1wAADdcAAAxUgAAK0cAACQ8AA0rSACNQ28A+FOKAP9UjAD/UokA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UokA/1SNAP9SiQD/PmgA/x4yAJ8RHQAYFCEAABQiAAAUIgAAFCIAABQiAAAUIgAAN1wAADdcAAA3XAAAN1wAADBRAAAqRgAqOV8AzVCFAP9UiwD/UYgA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GIAP9VjQD/T4MA/y5MANwSHgA8EyAAABQiAAAUIgAAFCIAABQiAAA3XAAAN1wAADdcAAA2WwAAMlQAOENvAOdTigD/UokA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9SigD/VIwA/zheAPMVIwBMEyAAABQiAAAUIgAAFCIAADZcAAA2XAAAN1wAADZbACVGdADnU4sA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RhwD/UYcA/1GHAP9RiAD/VY4A/zheAPQSHgA7EyEAABQiAAAUIgAAP2YDAD9nBAA5YgAJPW0AykyEAP9KgwD/SoIA/0qCAP9KggD/SoIA/0qCAP9KggD/SoIA/0qCAP9KggD/SoIA/0qCAP9KggD/SoIA/0qCAP9KggD/SoIA/0qCAP9KggD/SoIA/0qCAP9LgwD/TYcA/yZJAN8NGgAWFSMCABUjAQC5wK4AuL+uALO+pILC1Kr/xdis/MXWrPzF1qz8xdas/MXWrPzE1qz8xNas/MTWrPzD1ar8w9Wq/MPVqvzD1ar8w9Wq/MPVqvzD1ar8w9Wq/MPVqvzD1ar8w9Wq/MPVqvzD1ar8w9Wq/MPVqvzF2Kv8v9Co/1VZT6AzNTAAOTs2AM/P0wDU09ck+fj99f/////////////////////////////////////9+v///fv/////////////////////////////////////////////////////////////////////////////////////////////ysrL/j49PjxAQEEAdWBXAGVaVaeXlZT/mpeW/5aUk/+WlJP/lpST/5aUk/+WlZX/x8nK//Dw8P/k5OT/2tra//39/f//////////////////////////////////////////////////////////////////////////////////////e3t7vDc3NwDYy84dtJR+9XQtEf9kEgD/ah0A/2wgAP9sHwH/bB8A/2cbAf9kTEP/2+Hj///////q6ur/3t7e///////////////////////////////////////////////////////////////////////////////////////IyMj9Ozs7Lndq52KPg+//2sjU/7uCZf+CJgT/eBgA/34iAP9/JAD/gSMA/28aAP9jU0z/4OPk///////l5eX/5OTk//////////////////////////////////////////////////////////////////////////////////b29v9aWlp7gHLjohUAy/8yH9j/nZbz/9jDxv+qaUj/ex8A/3cZAP98IwD/fh8A/4FBKv+Dhoj/6enn///////d3d3/6Ojo/////////////////////////////////////////////////////////////////////////////////4WFhbj////Ov7jx/15N2v8YAMv/RTTe/62l7//Nr67/qmhJ/3wgAP9xEAD/qmlR/9TW1/9/f4T/7u7q///////c3Nz/6+vr////////////////////////////////////////////////////////////////////////////s7Ou1v///+f//////////8W/8v9TQNj/EgDM/0Y24P+uqPP/1724/5hLMP+cWD7//////1VItf9xboP//f74///////c3Nv/1NHm/tfU9/zb2Pb929f2/dvX9v3b1/b929f2/dvX9v3b1/b929f2/dvX9v3b1/b929f2/dvY9/6tq8Lksn1s7uXSzf////7///////39//+so+3/QCvU/xgAzP9TReP/vLPn/93Hw/////7/XUrk/xwKmf+VlpH////+//////+wrM7+JxTD/iURzv4pFcz+KRXN/ikVzf4pFc3+KRXN/ikVzf4pFc3+KRXN/ikVzf4pFc3+KRTS/ikZq+ziy77u7NrO///////////////////////8+/7/0s71/8nE8//T0Pj///////////9gT9z/HgXT/ykbif+lp57//////////f+PiMj/GALH/yMNz/8kD87/JA/O/yQPzv8kD87/JA/O/yQPzv8kD87/JA/O/yQPzv8kDdP/JRSu7OTk/+XZ1/3/1tL2/9bR9v/W0fb/1tH2/9nV9//f3Pj/39z4/97a+P/X0vb/1tL2/1RC2f8kDM//Jg7U/y4jgf+1tqr///////399v94b8H/GQPK/yUQz/8mEc7/JhHO/yYRzv8mEc7/JhHO/yYRzv8mEc7/JhHO/yYQ0/8nF6vkZlbcySYPzv8rFM//KxTP/ysUz/8rFM//KxTP/ysUz/8rFM//KxTP/ysUz/8rFM//KxTP/ysUz/8rFNH/JQ3Q/zMogv+3uK////////j58/90a8L/GwXK/yUQz/8mEc7/JhHO/yYRzv8mEc7/JhHO/yYRzv8mEc7/JxHT/x8PodNwYN+bLBXP/ygRz/8pEs//KRLP/ykSz/8pEs//KRLP/ykSz/8pEs//KRLP/ykSz/8rFM//KxTP/ysUz/8rFNL/JAzR/zMqev/Jy8D///////n68f9pXr//GgPM/yYRz/8mEc7/JhHO/yYRzv8mEc7/JhHO/yYRzv8nEdL/GwyUsoR35Fk9KNP/KBDO/ysUz/8rFM//KxTP/ysUz/8rFM//KxTP/ysUz/8rFM//KxTP/ysUz/8rFM//KxTP/ysUz/8rFNL/IgvL/0pDev/e4NL///////P07/9cT8D/FwDO/x4I0P8eCND/HgjQ/x4I0P8eCND/HgjR/x8Kzf8YCoxxjYHlFlZE2e4aAsv/HwbM/x8HzP8fB8z/HwfM/x8HzP8fB8z/HwfM/x8HzP8fBsz/KBHO/ywVz/8rFM//LBXP/ycPzv8fBtH/FQC6/0hDcP/Ky8X/+Pj2/+Hh4/9wZ7z/Vkq5/1VJuf9WSrn/Vkq5/1ZJuf9aTr3/Sj+m/B0SdSi7tO8ArqbtmH1u4v98buH/fnDi/35w4v99cOL/e27h/3tt4f97beH/e23h/3xu4f8/KtT/KBDO/ysUz/8nD87/RjLV/31v4f98buj/eGzQ/4eGkv+bm5f/oqKg/6Wmm/+goZb/n6CW/5+glv+gopj/oKOZ/6Slmf98fX64UU13Af///gD///8f////8f////////////////z8/v///////////////////////////2FQ3P8iCc3/KxTP/x8HzP92Z+D////////////8+/////7///v7/f///////////////////////v39//bw7v/79/b/8O7t/MXFxTXFxcMA8e/6APLx+wDt6/t4emzh/zkk0/9gT9v/wrzy//7+//////////////jz8f//////Xk3b/yIKzf8rFM//IAjM/3Jj4P////3/6ubz/5aP8/9INtn/QCzU/4+D5v/z8v3////////////9/Pv/zKmf/5NINv+TXEiXoH9zAKB9cADOyfMAz8rzANHM8wWMf+W/gXTj/+fk+v////////////jy8f+1gnT/qGtW//////9fTdv/IgrN/ysUz/8gCMz/c2Th/////P+naVH/xZyQ/7+36/9fUef/FQDM/z0o0/+on+z/+vr+////////////3MvF1rWWjBC5npQAuZ6TAPX1+wD19fsA9fX7APv7/Rz////e//////v49//LqJ3/jkAm/28MAP+fXUT//////19N2/8iCs3/KxTP/yAIzP9zZOH//////5NJLf9xEAD/nVMz/9e5q/+5svH/Rzfh/xMAzP9KNtb/uLDv//n5/u32+fkv8vT1APHz9ADx8/QA///9AP///QD///0A///9AP///yzn19Hbl081/3MTAP95HQD/dxoA/6FhSf//////X03b/yIKzf8rFM//IAjM/3Nk4f//////l080/3gcAP94GwD/eRwA/6VfP//Lraz/q6Pt/0o43P8xG9Dqw73vPfr78wDv7+8A7+/vAO/v7wD9/f0A/f39AP39/QD9/f0A////AOjY0x29kH28iTka/3gbAP91FwD/oWFJ//////9fTdv/IgrN/ysUz/8gCMz/c2Th//////+XTzT/eBwA/30kAP99IwD/dhkA/3gZAP+rakb/6dvYzpyT6y2+uO0A+fnzAO/v7wDv7+8A7+/vAP39/QD9/f0A/f39AP39/QD+//8A693YAOjY0gTZvrR4qGtU7nofBP+dWkH//////15M2/8iCc3/KxTP/yAIzP9zZOH//////5dPNP93GwD/eyEA/3oeAP98IwD/jkAh9qNlS4rcwrANr6ryAL237QD5+fMA7+/vAO/v7wDv7+8A/f39AP39/QD9/f0A/f39AP7//wDq3NcA49DIAOfY0QDo2NIiyaSVlsSaiur/////X03b/xwDzP8kDM3/GQDK/29f4P//////lEsu/3caAP+EMQ//lU0v8a52YKPCmoktv5WDANzFtwCrpe8AvbftAPn58wDv7+8A7+/vAO/v7wD9/f0A/f39AP39/QD9/f0A/v//AOrc1wDj0MgA5NPLAOXUzQDm1c8A7eHdGP///1m5se+agnXjyG5e3+NZR9ntlIno7f///+W8jXzLs4BroMKZiWLJppgfy6mbAMWfkAC8j30A3MS2AKul7wC9t+0A+fnzAO/v7wDv7+8A7+/vAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/</Image>
- <Url type="text/html" method="GET" template="http://szotar.sztaki.hu/search" resultdomain="sztaki.hu">
- <Param name="searchWord" value="{searchTerms}" />
- <Param name="fromlang" value="hun" />
- <Param name="tolang" value="eng" />
- <Param name="ignoreAccents" value="1" />
- <Param name="langcode" value="hu" />
- <Param name="viewMode" value="full" />
- <Param name="u" value="0" />
- <Param name="searchMode" value="WORD_PREFIX" />
- </Url>
- <SearchForm>http://szotar.sztaki.hu/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/tearma.xml b/browser/locales/searchplugins/tearma.xml
deleted file mode 100644
index d0b2a8b24..000000000
--- a/browser/locales/searchplugins/tearma.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>tearma.ie</ShortName>
-<Description>tearma.ie: Cuardach Comhtháite</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/vz//vvz//768//++vP//vvz//7+/P////////////////////////////////////////////779P/12Iz/8MJK//DAQ//wwEP/8MBD//DAQ//wwkv/9tmQ//789v////////////////////////////7+/v/z0HP/8MBD//HGVv/z0HP/89Bz//PQc//z0HP/8cZV//DAQ//00nn//v7+/////////////////8i1t//CqZv/u4g6/7yOTP/FsK//8ezt////////////8ezt/8Wwrv+8jUn/u4g6/8OqoP/Itbf///////////9iLjT/WyQr/1skK/9bJCv/WyQr/5ZzeP///////////5ZzeP9bJCv/WyQr/1skK/9bJCv/Yi40////////////lHB1/41kXv+KVTL/i1pC/5Bqb//Txcf////////////Txcf/kGpv/4tZP/+KVTL/jWRg/5Rwdf/////////////////++/X/8cVU//DARP/22Y7/+OSv//jkr//45K//+OSv//XYi//wwEP/8cdY//78+P////////////////////////////vx1v/xxlb/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8cdZ//zy2v///////////////////////////////////////vz4//rsx//557j/+ee4//nnuP/557j/+uzI//79+f///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////v7+//779P/99+n//fbn//325//99uf//fbn//325//99uf//ffp//779f/+/v7//////////////////////////////////////////////////////////////////////////////////////////////////vv0//ffo//yyWD/8MBE//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBF//LKZP/44qn//vz3//////////////////////////////////////////////////////////////////////////////////vx1f/xxlj/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//yyF7//PPe///////////////////////////////////////////////////////////////////////88tv/8MNM//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//xxFH//PXk/////////////////////////////////////////////////////////////v37//LKYv/wwEP/8MBD//DAQ//ww0z/9deI//ffo//34KT/9+Ck//fgpP/34KT/9+Ck//fgpP/336L/9dWE//DCSf/wwEP/8MBD//DAQ//zzm3//v7+///////////////////////////////////////////////////////56L3/8MBD//DAQ//wwEP/8stk//336v///////////////////////////////////////////////////////PXj//LIXP/wwEP/8MBD//DAQ//67cv//////////////////////////////////////5d0eP+KY2j/imNo/4hYSf+GUTL/hlEy/4ZRMv+JXVb/imNo/41obP/Itrj//v7+///////////////////////+/v7/yLa4/41obP+KY2j/iFxS/4ZRMv+GUTL/hlEy/4haTf+KY2j/imNo/5d0eP//////////////////////aTg+/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1wlLP/f1NX//////////////////////9/U1f9cJSz/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/aTg+//////////////////////9pOD7/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/8Sxs///////////////////////xLCz/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9pOD7//////////////////////2k4Pv9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9rOkD/8e3u///////////////////////x7e7/azpA/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/1skK/9bJCv/WyQr/2k4Pv//////////////////////yri7/8Kusf/CrrH/vZlz/7mGOv+5hjr/uYY6/76beP/CrrH/x7S2//Lu7v/////////////////////////////////y7u7/x7S2/8Kusf+9mG//uYY6/7mGOv+5hjr/vpx8/8Kusf/CrrH/yri7///////////////////////////////////////78tn/8MBD//DAQ//wwEP/8MJJ//jksf/+/fr////////////////////////////////////////////+/Pf/+OGo//DBRv/wwEP/8MBD//DARv/89uX///////////////////////////////////////////////////////7+/v/114n/8MBD//DAQ//wwEP/8MBD//DCS//yyV//8slg//LJYP/yyWD/8slg//LJYP/yyWD/8slf//DCSf/wwEP/8MBD//DAQ//wwEP/9tuX//////////////////////////////////////////////////////////////////789v/zzm7/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//TReP/+/fr///////////////////////////////////////////////////////////////////////789//22Y//8MBF//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DAQ//wwEP/8MBD//DBRv/23Jn//v36///////////////////////////////////////////////////////////////////////////////////////89eP/99+i//TSfP/zz3H/889x//PPcf/zz3H/889x//PPcf/zz3H/889x//TTff/34Kb//ffn/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="text/html" method="GET" template="http://www.tearma.ie/Search.aspx" resultdomain="tearma.ie">
- <Param name="term" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.tearma.ie/Home.aspx</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/termau.xml b/browser/locales/searchplugins/termau.xml
deleted file mode 100644
index 1e89a0961..000000000
--- a/browser/locales/searchplugins/termau.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Porth Termau</ShortName>
-<Description>Porth termau wedi'u safoni</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAAVmTqk0JS6Pg8TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/9CUuj4VmTqk0JS6Pc8TOf/PEzn/zxM5/88TOf/O0vn/zpK5/86Suf/Okrn/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/0JS6Pc8TOf/PEzn/zxM5/88TOf/O0zn/09d6f9ve+7/eoXv/3B87v9WZOr/Pk7n/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/P07n/3F97v+fp/T/hY/w/2l27f9mc+3/c3/u/2x47f9DU+j/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/3F87v+nr/X/Y3Ds/zxM5/86Suf/Okrn/ztL5/9TYer/YW7s/z5O5/88TOf/PEzn/zxM5/88TOf/O0vn/05d6f+nr/X/dYHu/zpK5/88TOf/PEzn/zxM5/88TOf/O0vn/09e6v9KWen/O0vn/zxM5/88TOf/PEzn/zpK5/9ueu3/rLP2/1Be6v87S+f/PEzn/zxM5/88TOf/PEzn/zxM5/8+Tef/RVTo/ztL5/88TOf/PEzn/zxM5/87S+f/go3w/6iv9f9IV+n/O0vn/zxM5/88TOf/PEzn/zxM5/87S+f/UF7q/2p37f9HVuj/O0vn/zxM5/88TOf/O0vn/3+J8P+xt/b/VWPq/zpK5/88TOf/PEzn/zxM5/87TOf/QlLo/5We8v+5v/f/eoXv/ztL5/88TOf/PEzn/zpK5/9ndO3/t733/4GM8P89Tef/O0vn/zxM5/88TOf/OUrn/2h17f+0u/f/ub/3/3+J8P87S+f/PEzn/zxM5/87S+f/SVjp/6Kp9P+zuvb/d4Lv/0dW6P8+Tuf/QlLo/2Rx7P+mrvX/ub/3/7C39v9baev/Okvn/zxM5/88TOf/PEzn/ztL5/9mc+z/sbj2/7e99/+iqvT/k5zy/5yl8/+yufb/ub/3/7a89/97hu//PU3n/zxM5/88TOf/PEzn/zxM5/88TOf/PU3n/2l27f+lrPX/ub/3/7vB+P+7wPf/uL73/6qx9f92ge7/QVDo/ztM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/87S+f/TFvp/2977v+EjvD/hI/w/3J97v9RX+r/PEzn/zxM5/88TOf/PEzn/zxM5/9CUuj3PEzn/zxM5/88TOf/PEzn/ztL5/86Suf/PEzn/zxM5/86Suf/O0vn/zxM5/88TOf/PEzn/zxM5/9CUuj3VmTqk0JS6Pg8TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/9CUuj4VmTqkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAAnKLzCGx47XJVY+rnP0/n/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/z9P5/9XZermbHjtbJ6l8whqdu10RlXo7jxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/9HVujtbHjtbFNh6ug7TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/9XZevlP0/n/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/87S+f/O0vn/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/z9P5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/O0vn/zpK5/88TOf/RVTo/05d6v9PXur/R1bp/z1O5/85Suf/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zpK5/9DUuj/ZHHs/4WP8f+fp/T/rLT2/6629v+lrfX/kJry/3N/7v9PXen/Okvn/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/Xmvr/5Sd8v+3vff/ucD3/6au9f+PmfL/hZDx/4WP8f+Nl/L/nqf0/6Gp9P90f+7/Q1Lo/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/Pk7n/3F97v+utfb/u8H3/6Ws9f9zf+7/TFvp/zxM5/86S+f/Okvn/zxM5/9FVOj/Y3Ds/5Ga8v+HkfH/R1bo/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/9yfu7/tLr3/7rA9/+XoPP/UmDq/zlK5/87S+f/PEzn/zxM5/88TOf/PEzn/ztL5/86Suf/QVHo/3qF7/+Ai/D/QlLo/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86Suf/X2zr/6619v+6wPf/mKDz/0ta6f86Suf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/87S+f/PEzn/3B97v9qdu3/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/O0zn/0NS6P+XoPP/usD3/6y09v9ZZ+v/Okrn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/QE/o/3N+7v9NXOn/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86Suf/Z3Pt/7W79/+5v/f/g43w/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86S+f/UmDq/15s7P86S+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/+Jk/H/usD3/7W79/9hb+z/Okrn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/89Tef/VmTq/z9P6P88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/87S+f/R1fo/5+n9P+6v/f/qbD1/05c6f87S+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/9KWen/QlHo/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/9WZOr/rLP2/7m/9/+fqPT/RVTo/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/O0vn/0VU6P9AT+f/Okvn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/Okrn/19s7P+zuvf/ub73/6Kq9P9HVun/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/0BQ6P9xfe7/lZ7y/4WP8P9TYer/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86Suf/XGnr/7G39v+4vvf/rrX2/1Ri6v87S+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86Suf/anft/7S69v+5v/f/usD3/5uj8/9IV+j/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/9QXur/p671/7i+9/+4vvf/bXnt/zlJ5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/O0vn/0RU6P+bpPP/ub/3/7e99/+3vff/s7r2/19t7P86Suf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/0JR6P+XoPP/ub/3/7m/9/+VnvP/RFPo/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86Suf/bXrt/7a89/+3vff/t733/7e99/+zufb/X2zr/zpK5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/Okrn/3+K8P+6wPf/t733/7a99/9yfu7/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/Okvn/0pZ6f+fp/T/ub/3/7e99/+3vff/uL73/6eu9f9NW+n/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86S+f/WWbr/6619v+4vvf/uL73/6yz9f9ndO3/O0zn/zpL5/88TOf/PEzn/zxM5/88TOf/PEzn/zlJ5/9GVuj/i5Xx/7i+9/+3vff/t733/7e99/+6wPf/hI7w/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/h5Hx/7m/9/+3vff/uL73/6+29v96hu//TVzp/zxM5/86Suf/Okrn/zpK5/9AUOj/X2zr/5af8/+3vvf/t733/7e99/+3vff/uL73/6yz9f9XZer/Okrn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/9SYOr/pKz0/7m/9/+3vff/uL73/7i+9/+mrvX/hY/w/3SA7v9yfu7/e4bv/5Sd8v+yufb/ub/3/7e99/+3vff/t733/7e99/+2vPf/dH/u/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zpL5/9jcOz/rbT2/7m/9/+3vff/t733/7i+9/+5v/f/ub/3/7m/9/+5v/f/ub/3/7e99/+3vff/t733/7e99/+4vvf/uL73/4SO8P9CUej/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/9mc+3/qLD1/7m/9/+3vff/t733/7e99/+3vff/t733/7e99/+3vff/t733/7e99/+3vff/ub/3/7K59v+Ai/D/Q1Po/ztL5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/ztL5/9YZuv/j5ny/7O59v+6wPf/uL73/7i99/+3vff/t733/7i99/+4vvf/ur/3/7e99/+cpfP/aHXs/z5O5/87S+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zpK5/9AT+f/Y3Ds/4yW8v+kq/T/sLf2/7S79/+0uvf/sLf2/6Wt9P+Rm/L/b3vu/0dW6P86Suf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/86Suf/PU3n/0lY6f9aZ+v/ZHHs/2Vy7P9baOv/S1np/z1N5/86Suf/O0vn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/8/T+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/O0vn/zpL5/86Suf/Okrn/zpL5/87S+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/P0/n/1Jg6ug7TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/9VY+rlaHXtekVU6O87TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/87TOf/RlXo7mx47XKepfMIaXXtelJg6uo/T+f/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/PEzn/zxM5/88TOf/P0/n/1Nh6ulqdu10oaj0CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="text/html" method="GET" template="http://termau.cymru/#{searchTerms}" resultdomain="termau.cymru">
-</Url>
-<SearchForm>http://termau.cymru</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/twitter-ja.xml b/browser/locales/searchplugins/twitter-ja.xml
deleted file mode 100644
index e6950d6a2..000000000
--- a/browser/locales/searchplugins/twitter-ja.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Twitter</ShortName>
-<Description>リアルタイム Twitter 検索</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAALAgAAJgAAACAgAAAAAAAAQQQAADECAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAHSSURBVDjLfVO/axRREP6SS0ihlv4FQpoYWxHyHxgCsUxhmToBS4tF7NLZWaiIEHLv7d5dJNEQ0tgYEAmIjeAfYC57++7MGbzLjxu/Nxt27zZrBoadnZnvm3kz7wEqMpZqmdAfBBMIZBzGVGCkorbXq4kFp/yPtBgPZCJzZvYQuNZ+jKhVo75G2LyHVz9uoeFmc6bILaHaepv9v/w6iRcypXbonmNPBB9OBbv82tYfmPgn7NHTnKAaP8E+g8Ztot68k/nXDm8ooNEVhHEP1vXROBbUf/M/Wc0Jwl8zsEkHOxcMtE6Y+A42nodpLtLfR9QWRMmA9jm2eh78aXQY4eF9VvjCgKDWEewM2PIZQc4nD9Sf6hk+sohNqorzW0kN91BBdYKtO9dE/00JZITA50XxsxTHlWarqMYBh/O3UPGqrednx7ox3o+UhbIRT7O1BO9PfIsXI5V9J34WvrqN94buwFi+b3N0k0nrCjAFAp1+Nz1Czd3N2y8Tm6ywYk9JTHKqk/cD9cM17YW89WExbo6Ja1zhvgK3+4Itql+rt8PkO1f6oBysBN3brLrMVhs84wHJvpHoMwnf8CI9ygZd3nbJgymrMvxeSoLjmlCsIJf+a17lP6juZmUWkMzvAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAECElEQVRYw+1XS2gTURS9ia0/EMSCCC4siCIKrly4UVwIrgRR3KgbXQmCCiIiCha7EQRR6cIupHShSeZjf6lttdWFgqBRBPGDKIqF1mQ+1Wp/SZvnvXfmTWfMpJ3U0pUPHplJ3rv33HO/Afi/5nPViTjuKm8rYlFlAoSI8a500R1SGLYUZRH+Hvee6+qqygvxW1KJ1XLd+74aUuY+0OzjoHw/BElj4zQQHxv0HDBUvjR9WQlNYmnJhSjK9dxFUC0LOsYE3M8LSI8LUKw8AmoG5ecqPtP8vgZ04zKeO+jqjUtBDi2qWY+71xPaKKpnpF0uzUpCnxDQOixQ+BSo9iR/3vsh4CF+r5of8D3F75r9udQAKUwx++AJXkhZCe9QBkGEuUSC1swTjhK0VrUmEYzw7SKCyUPrLwEP8IxufQN9aCfKPwCJwdq/lCPluvUG2n4jhQW8bD6Hu+amABvSd/LOTbEENOMjdIyicLuA1om/ADhbMqIZn/DMOMq+7iqPBanUzWfQOUGUjUFnnj5H0WdnQOlfFoxssdix3tjGgnWbrCuGKvdA4LmuSQJ6s9SN0zFwg6lS7Qmms+WngK4pEvAVg+w83MltCAAhAHSGFMwEgGQRq2quwZe2cShJkaYvtey39hEHMfsQL7cjxd1F4dBnPWUKVeMwaLmTkRggGd1oiJI9GxLcLg2NA8s5DTXzCKePbjtBJAVoVoGjmFxEwsgiCi5tFuoDDFinHcb9xWg6CBcjpS9ReReCeF9GOL5TsCEYhRkSs26HmSLXh2R2f8DlJS7Q7BZOwyhWzeZ3P2hijtJRG9wSXuQkIj27m1OKKKPUiQIiCv1ptF4x33rUh/Yb+aVqN8BjIf07HwDy0EPFzU2/ck0rgCpln8MgtOcBgOOiFizRSWt7aQCWA0GHdesSBuOAm+fFOQIoOFXVeBRqaGnvlsGIed5LwWiO/LP11KASg7tmt97fnRoz1Xj5NXc4WQP0Sliw6d4EN6mUdStyew8cbB6uQWGdXL+pPHMrjQLCVe40tHdo1NJoQ47X5XBnfKUykduBQ0U9+jEbKR5IOTc0IwfJb+tnjvwoq+3DCmxEV1iwvzyHtlzbSTnVHMRKuTm6crK8AcelDrGc/a/0r4WUsRcF3ebWzC4YCqt8Rbdo5XmO4IZj9IGSW+PFUuSVyu7BeeABIrdZMNFIfiSrCQQFouwDNHxQLyBQdK6nSPOfgftUSXWtaOlD67BkXkCLXrFV1IYJBAUifcpnspQHFjyjmi+4y8nBs6KIL1cJuRZkt6K1xzCYrvFAqdtptDCNz3dxX8V91Gsufqvn8r/CByJemd/kvJiprui/RAQkMaZR/r1i4W6a0rP/N/gXi6OvmDvBLoiyBV1/AN29Cs9hVFoUAAAAAElFTkSuQmCC</Image>
-<SearchForm>https://twitter.com/search/</SearchForm>
-<Url type="text/html" method="GET" template="https://twitter.com/search/{searchTerms} lang:ja" resultdomain="twitter.com">
- <Param name="partner" value="Firefox"/>
- <Param name="source" value="desktop-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/twitter.xml b/browser/locales/searchplugins/twitter.xml
deleted file mode 100644
index 03d15a2d8..000000000
--- a/browser/locales/searchplugins/twitter.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Twitter</ShortName>
-<Description>Realtime Twitter Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAALAgAAJgAAACAgAAAAAAAAQQQAADECAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAHSSURBVDjLfVO/axRREP6SS0ihlv4FQpoYWxHyHxgCsUxhmToBS4tF7NLZWaiIEHLv7d5dJNEQ0tgYEAmIjeAfYC57++7MGbzLjxu/Nxt27zZrBoadnZnvm3kz7wEqMpZqmdAfBBMIZBzGVGCkorbXq4kFp/yPtBgPZCJzZvYQuNZ+jKhVo75G2LyHVz9uoeFmc6bILaHaepv9v/w6iRcypXbonmNPBB9OBbv82tYfmPgn7NHTnKAaP8E+g8Ztot68k/nXDm8ooNEVhHEP1vXROBbUf/M/Wc0Jwl8zsEkHOxcMtE6Y+A42nodpLtLfR9QWRMmA9jm2eh78aXQY4eF9VvjCgKDWEewM2PIZQc4nD9Sf6hk+sohNqorzW0kN91BBdYKtO9dE/00JZITA50XxsxTHlWarqMYBh/O3UPGqrednx7ox3o+UhbIRT7O1BO9PfIsXI5V9J34WvrqN94buwFi+b3N0k0nrCjAFAp1+Nz1Czd3N2y8Tm6ywYk9JTHKqk/cD9cM17YW89WExbo6Ja1zhvgK3+4Itql+rt8PkO1f6oBysBN3brLrMVhs84wHJvpHoMwnf8CI9ygZd3nbJgymrMvxeSoLjmlCsIJf+a17lP6juZmUWkMzvAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAECElEQVRYw+1XS2gTURS9ia0/EMSCCC4siCIKrly4UVwIrgRR3KgbXQmCCiIiCha7EQRR6cIupHShSeZjf6lttdWFgqBRBPGDKIqF1mQ+1Wp/SZvnvXfmTWfMpJ3U0pUPHplJ3rv33HO/Afi/5nPViTjuKm8rYlFlAoSI8a500R1SGLYUZRH+Hvee6+qqygvxW1KJ1XLd+74aUuY+0OzjoHw/BElj4zQQHxv0HDBUvjR9WQlNYmnJhSjK9dxFUC0LOsYE3M8LSI8LUKw8AmoG5ecqPtP8vgZ04zKeO+jqjUtBDi2qWY+71xPaKKpnpF0uzUpCnxDQOixQ+BSo9iR/3vsh4CF+r5of8D3F75r9udQAKUwx++AJXkhZCe9QBkGEuUSC1swTjhK0VrUmEYzw7SKCyUPrLwEP8IxufQN9aCfKPwCJwdq/lCPluvUG2n4jhQW8bD6Hu+amABvSd/LOTbEENOMjdIyicLuA1om/ADhbMqIZn/DMOMq+7iqPBanUzWfQOUGUjUFnnj5H0WdnQOlfFoxssdix3tjGgnWbrCuGKvdA4LmuSQJ6s9SN0zFwg6lS7Qmms+WngK4pEvAVg+w83MltCAAhAHSGFMwEgGQRq2quwZe2cShJkaYvtey39hEHMfsQL7cjxd1F4dBnPWUKVeMwaLmTkRggGd1oiJI9GxLcLg2NA8s5DTXzCKePbjtBJAVoVoGjmFxEwsgiCi5tFuoDDFinHcb9xWg6CBcjpS9ReReCeF9GOL5TsCEYhRkSs26HmSLXh2R2f8DlJS7Q7BZOwyhWzeZ3P2hijtJRG9wSXuQkIj27m1OKKKPUiQIiCv1ptF4x33rUh/Yb+aVqN8BjIf07HwDy0EPFzU2/ck0rgCpln8MgtOcBgOOiFizRSWt7aQCWA0GHdesSBuOAm+fFOQIoOFXVeBRqaGnvlsGIed5LwWiO/LP11KASg7tmt97fnRoz1Xj5NXc4WQP0Sliw6d4EN6mUdStyew8cbB6uQWGdXL+pPHMrjQLCVe40tHdo1NJoQ47X5XBnfKUykduBQ0U9+jEbKR5IOTc0IwfJb+tnjvwoq+3DCmxEV1iwvzyHtlzbSTnVHMRKuTm6crK8AcelDrGc/a/0r4WUsRcF3ebWzC4YCqt8Rbdo5XmO4IZj9IGSW+PFUuSVyu7BeeABIrdZMNFIfiSrCQQFouwDNHxQLyBQdK6nSPOfgftUSXWtaOlD67BkXkCLXrFV1IYJBAUifcpnspQHFjyjmi+4y8nBs6KIL1cJuRZkt6K1xzCYrvFAqdtptDCNz3dxX8V91Gsufqvn8r/CByJemd/kvJiprui/RAQkMaZR/r1i4W6a0rP/N/gXi6OvmDvBLoiyBV1/AN29Cs9hVFoUAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="https://twitter.com/search" rel="searchform">
- <Param name="q" value="{searchTerms}"/>
- <Param name="partner" value="Firefox"/>
- <Param name="source" value="desktop-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/tyda-sv-SE.xml b/browser/locales/searchplugins/tyda-sv-SE.xml
deleted file mode 100644
index f0aaa6fea..000000000
--- a/browser/locales/searchplugins/tyda-sv-SE.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Tyda.se</ShortName>
-<Description>Tyda.se, lexikon, ordlista och översättning.</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABQklEQVR42mO8fv3GxvVbdu/ay0AcYBYRkrhx4+aXL1+I1cDCxE68agYGBiY4y93Dtbe/Q1lFiVgN4uJi+gZ6PDw8xGrQN9BlYGBwc3eWkJQIDgmIi4+GiEtISsTFR+vp6WDYICHOwMCgoqLMzc2lpKwYlxANcV5gkF9cQjQvHy+6hl079jAwMEybOuvunXvr1m5kYGBwc3dhYGCwtrF88eLlo4eP0TUgg7t37t29c8/dw1VZRUlCQvzokeOfPn/Gp4GBgWHd2o08PNyNzbUMDAzr1236+OEjAQ1Hjxz78uWrhIT4xQuXXjx/gSWU0MCXL1+PHjnGwMCwaydKqmGBsxYtXLpo4VJkOQkJcbg2wjaIioroG+hBHIaiwcbWWkJSAlNDQlIsAwPDzu270WM6IipERUUZU4OEhPjv37+fI3kXAgDUBm6U4URcZQAAAABJRU5ErkJggg==</Image>
-<Url type="text/html" method="GET" template="http://tyda.se" resultdomain="tyda.se">
- <Param name="w" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://tyda.se</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/vatera.xml b/browser/locales/searchplugins/vatera.xml
deleted file mode 100644
index f4899f964..000000000
--- a/browser/locales/searchplugins/vatera.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Vatera.hu</ShortName>
- <Description>Keresés a Vatera.hu piacterén</Description>
- <Language>hu</Language>
- <OutputEncoding>ISO-8859-2</OutputEncoding>
- <InputEncoding>ISO-8859-2</InputEncoding>
- <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAGD/GABa/2MAWv9eAFv/XwBa/2AAWv8RAAAAAAAA/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZv8FAAAAAABZ/4wAZv//AF7//wBe//8AZv//AFn/dQAAAAAAgP8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWv/VAFv//wBa//sAWv/6AF3//wBa/8MAAAAAAID/AgAAAAAAAAAAAAAAAAAAAAAAAAAAAFX/AwAAAAAAXP8yAFv//wBb//8AWf/qAFr/7QBc//8AWv/6AF3/IQAAAAAAgP8CAAAAAAAAAAAAAAAAAAAAAACA/wQAAAAAAFr/fwBf//8AYP//AFn/iQBa/5sAX///AF///wBa/2kAAAAAAID/BAAAAAAAAAAAAAAAAAAAAAAAAP8BAAAAAABa/8sAXf//AF///wBb/zgAWv9PAGD//wBd//8AWv+4AAAAAABV/wMAAAAAAAAAAAAAAAAAgP8CAAAAAABZ/ygAWv/9AFz//wBa/+oAVf8GAFX/GABa//YAXP//AFr/8wBg/xgAAAAAAID/AgAAAAAAAAAAAID/BAAAAAAAWv9xAF///wBe//8AWv+oAAAAAAAAAAAAWv+8AF3//wBf//8AWf9cAAAAAABA/wQAAAAAAAAAAACA/wIAAAAAAFv/vwBd//8AXv//AFn/WQAAAAAAAAAAAFr/bwBf//8AXv//AFr/rAAAAAAAQP8EAAAAAACA/wIAAAAAAF7/HgBa//cAW///AFr/8wBZ/xcAAAAAAAAAAABc/ycAWv/9AFv//wBa/+wAYP8QAAAAAAAA/wEAQP8EAAAAAABZ/2QAX///AF3//wBa/7gAAAAAAFX/AwAA/wEAAAAAAFr/ywBd//8AXv//AFr/TwAAAAAAQP8EAFX/AwAAAAAAWv+vAFz//wBe//8AWf9qAAAAAABA/wQAgP8EAAAAAABa/4AAXv//AF3//wBa/5sAAAAAAID/BAAAAAAAWP8aAFr//wBh//8AXP//AFr/IgAAAAAAgP8CAFX/AwAAAAAAWv8zAF///wBh//8AW//yAE7/DQAAAAAAAAAAAFX/EgBa/1IAWf9TAFn/QgAAAAAAAAAAAAAAAAAAAAAAAAAAAID/AgBa/0cAWv9SAFn/UABV/wwAAAAAAAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AffvAADoFwAA6BcAAPgXAADQCwAA0AsAANALAACgBQAAoYUAAKGFAABBggAAQkIAAEJCAACCQQAAh8EAAH/+AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABV/wMAVf8DAFX/AwBV/wMAVf8DAFX/AwBV/wMAVf8DAFX/AwCA/wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFX/AwAAAAAAW/9iAFr/xgBa/7sAWv+9AFr/vQBa/70AWv+9AFr/vABa/8MAWf9FAAAAAABV/wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAFX/BgBa/+oAYv//AF7//wBf//8AX///AF///wBf//8AXf//AGT//wBa/8QAAAAAAFX/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFX/AwAAAAAAWf9CAF3//wBa//gAWv/8AFr//ABa//sAWv/7AFr/+wBa//sAWv/9AFn/+ABa/x8AAAAAAID/AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8EAAAAAABa/5EAYP//AFr/+gBa//8AWv//AFr//gBa//8AWv//AFr//wBZ//sAYP//AFr/ZgAAAAAAQP8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAgP8CAFr/2gBd//8AWv/9AFr//wBa//8AWv//AFr//wBa//8AWv//AFr/+wBf//8AWv+1AAAAAABV/wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVf8DAAAAAABd/zcAXP//AFr//QBa//8AWv//AFr//wBa//sAWv/8AFr//wBa//8AWv/+AFv//wBa//MAWf8XAAAAAAD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA/wQAAAAAAFr/hQBg//8AWv/6AFr//wBa//sAYP//AFr/pwBa/8EAX///AFr//ABa//8AWf/7AGD//wBc/1kAAAAAAED/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAWf/QAF3//wBa//wAWv//AFn/+wBh//8AWf9FAFv/cwBi//8AWv/6AFr//wBa//sAYP//AFv/qQAAAAAAQP8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA/wIAAAAAAFv/LQBb//8AWv/+AFr//wBa//4AW///AFr/9gBd/wsAWv8zAF3//wBa//0AWv//AFr//QBc//8AWv/rAFX/DwAAAAAAAP8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID/BAAAAAAAWf94AGD//wBa//oAWv//AFr/+wBf//8AWv+4AAAAAABV/wYAWv/cAF3//wBa//0AWv//AFr/+wBf//8AWf9NAAAAAABA/wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CAAAAAABZ/8UAXv//AFr//ABa//8AWv/6AGD//wBa/2kAAAAAAAAAAABb/5UAYP//AFr/+gBa//8AWf/7AGD//wBZ/50AAAAAAED/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID/AgAAAAAAV/8jAFr/+wBa//8AWv/+AFr//gBa//8AWv/7AFf/IwAAAAAAAAAAAFr/RwBe//8AWv/8AFr//wBa//0AXP//AFr/4gBt/wcAAAAAAAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8EAAAAAABZ/2oAYP//AFr/+gBa//8AWv/8AF7//wBa/8YAAAAAAFX/AwAAAAAAVf8MAFv/5wBc//8AWv/9AFr//wBa//wAXv//AFr/QQAAAAAAVf8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABV/wMAAAAAAFr/uQBf//8AWv/7AFr//wBa//oAYP//AFr/egAAAAAAgP8EAED/BAAAAAAAWf+mAGD//wBZ//sAWv//AFr/+gBg//8AWv+QAAAAAACA/wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CAAAAAABc/xkAWv/1AFv//wBa//4AWv//AFr//gBb//8AWv8wAAAAAABV/wMAQP8EAAAAAABb/1cAX///AFr/+wBa//8AWv/9AF3//wBa/9gAAP8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA/wQAAAAAAFr/XQBg//8AWf/7AFr//wBa//wAXf//AFr/1AAAAAAAAAAAAAAAAAAA/wEAAAAAAF3/FgBa//IAW///AFr//gBa//8AWv/9AFz//wBa/zYAAAAAAFX/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAED/BAAAAAAAWv+tAF///wBa//sAWv//AFr/+gBg//8AWv+LAAAAAACA/wQAAAAAAAAAAABV/wMAAAAAAFr/tgBf//8AWv/7AFr//wBa//oAYP//AFr/ggAAAAAAgP8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAAAAAFr/EQBa/+0AW///AFn//gBa//8AWv/9AF3//wBa/z4AAAAAAFX/AwAAAAAAAAAAAED/BAAAAAAAWf9nAGD//wBa//oAWv//AFr//ABe//8AWv/OAAAAAAAA/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAED/BAAAAAAAWf9QAF///wBa//sAWv//AFr//QBc//8AWv/gAFX/BgAAAAAAAP8BAAAAAAAAAAAAgP8CAAAAAABd/yEAWf/7AFr//wBa//4AWv/+AFr//gBa//8AWf8rAAAAAACA/wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQP8EAAAAAABa/58AYP//AFn/+wBa//8AWf/7AGD//wBa/5sAAAAAAED/BAAAAAAAAAAAAAAAAAAAAAAAgP8CAAAAAABa/8QAXv//AFr//ABa//8AWv/6AGD//wBZ/3UAAAAAAID/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAVf8JAFn/5ABc//8AWv/9AFr//wBa//sAX///AFn/TQAAAAAAQP8EAAAAAAAAAAAAAAAAAAAAAACA/wQAAAAAAFn/eABg//8AWv/6AFr//wBa//wAXv//AFv/wgAAAAAAgP8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAVf8DAAAAAABa/0QAXv//AFr//ABa//8AWv/9AFv//wBa/+sAVf8PAAAAAAAA/wEAAAAAAAAAAAAAAAAAAAAAAID/AgAAAAAAWf8uAFv//wBa//4AWv//AFr//gBa//8AWv/6AFX/IQAAAAAAgP8CAAAAAAAAAAAAAAAAAAAAAACA/wQAAAAAAFn/kgBg//8AWv/6AFr//wBa//sAX///AFn/qwAAAAAAQP8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWv/SAF3//wBa//wAWv//AFr/+gBg//8AWf9nAAAAAABA/wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWf/WAFv//wBa//kAWv/7AFr/9gBf//8AWv9dAAAAAABA/wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8EAAAAAABZ/4kAX///AFr/9gBZ//sAWv/3AF7//wBa/7IAAAAAAFX/AwAAAAAAAAAAAAAAAABV/wMAAAAAAFn/QgBj//8AX///AGD//wBg//8AYf//AFv//wBc/xkAAAAAAID/AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABV/wMAAAAAAFn/PABi//8AYP//AGD//wBg//8AYf//AFz//wBe/x4AAAAAAID/AgAAAAAAAAAAAFX/AwAAAAAAWf88AFv/qQBZ/50AWv+fAFn/nQBa/6gAWf9wAAAAAACA/wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CAFn/hgBa/6QAWv+eAFr/nwBa/54AWv+kAFz/JAAAAAAAgP8CAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAID/AgCA/wQAQP8EAED/BABA/wQAgP8EAFX/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA/wQAQP8EAED/BABA/wQAQP8EAID/BAAA/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////4Af//9/7//+gBf//QAX//0AC//9AAv/+gAL//oABf/6AAX/+gAF//QAAv/0BAL/9AYC/+gGAX/oCgF/6AkBf9AJAP/QHQC/0BaAv6AWgL+gFoBfoC9AX0AvQF9AL0AvQF/gL8BfoC6AX6AWgL/gF39//++A//Af/////</Image>
- <Url type="text/html" method="GET" template="http://www.vatera.hu/listings/index.php" resultdomain="vatera.hu">
- <Param name="q" value="{searchTerms}"/>
- <Param name="c" value="0"/>
- <Param name="td" value="on"/>
- </Url>
- <SearchForm>http://www.vatera.hu/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/webdunia.xml b/browser/locales/searchplugins/webdunia.xml
deleted file mode 100644
index 47a0da3c8..000000000
--- a/browser/locales/searchplugins/webdunia.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Webdunia Search</ShortName>
-<Description>Webdunia Search : A Multilingual Search Engine for Indian Content</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCTaLhmR7CwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCTaAhwk2nYcJNr4GZHs9hmR7GoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwk2iAcJNrBHCTa%2Fxwk2v8Zkez%2FGZHs%2FxmR7K8ZkewTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcJNpTHCTa8Rwk2v8cJNr%2FHCTa%2FxmR7P8Zkez%2FGZHs%2FxmR7OIZkew3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwk2sgcJNr%2FHCTa%2Fxwk2v8cJNr%2FGZHs%2FxmR7P8Zkez%2FGZHs%2FxmR7KIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcJNoDHCTa9Bwk2v8cJNr%2FHCTa%2Fxwk2v8Zkez%2FGZHs%2FxmR7P8Zkez%2FGZHsywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwk2igcJNr%2FHCTa%2Fxwk2v8gJ73zJ0OX9TBWmPEggdTyGZHs%2FxmR7P8ZkezyGZHsAQAAAAAAAAAAAAAAAAAAAAAAAAAAHCTaVxwk2v8fJbvaKSiT%2FRlTp%2F8Gvsr%2FRXBY%2FzI0pP8nRb3%2BHnvX3RmR7P0ZkewdAAAAAAAAAAAAAAAAAAAAAAAAAAAbI7KSGyOj8DgufPlWS1r%2FBs7W%2FwPQ2v9Ri13%2FjV8I%2F2VLQf82NJr7Gz%2Fc9BpO4nkAAAAAAAAAAAAAAAAbI6IFGyOiaRsjorU7L4H%2FaFtV%2FzemoP8D1%2BH%2FONnh%2F3HNyP%2BmfBP%2Fn2wG%2F4NpFv83bpb%2FGlHiuhwo22QcKNsEAAAAABsjoggbI6JIGyOi9083bf0strn%2FAPX%2F%2FwDs9v958fb%2F2c20%2F469kv%2BjexL%2FPaaE%2F0V5ff4Zkez2GZHsRhwo2wgAAAAAAAAAABsjogUbI6IsZUBWpUWUk%2F8A9f%2F%2FGd3Y%2F2bLpv997%2B%2F%2FTuPZ%2Fw7V1v8D2%2BP%2FNKCX0xmR7DYZkewMAAAAAAAAAAAAAAAAAAAAAAAAAAB8ST89fEk%2F%2Fz2jn%2F9Wln%2F%2FN8Oo%2Fxri2P8A9f%2F%2FAO%2F5%2FwDv%2Bf9Co5NmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8ST%2B3ekxD%2Fzqspv8U3t%2F%2FAPX%2F%2FwD1%2F%2F8A9f%2F%2FHtPR6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHxJPxB8ST%2B3ZGpk%2F1OHfv9Ll4z%2FGdXY%2FxzR0%2BtOjYUXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4T0U7XnFsh3xJP3Z4T0U7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2Fn%2BAAPg%2FgADwD4AA4AeAAOAHgADAB4AAwAOAAMADgADAA4AAAACAAAAAgACAAYAA4AeAAPAPgADwD4AA%2FD%2BAAP%2F%2FgAA%3D</Image>
-<Url type="text/html" template="http://search.webdunia.com/search.aspx" resultdomain="webdunia.com">
- <Param name="q" value="{searchTerms}"/>
- <Param name="FF" value="SearchBox" />
-</Url>
-<Url type="application/x-suggestions+json" template="http://search.webdunia.com/suggestions.aspx">
- <Param name="q" value="{searchTerms}"/>
- <Param name="stype" value="json"/>
-</Url>
-<SearchForm>http://search.webdunia.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-NN.xml b/browser/locales/searchplugins/wikipedia-NN.xml
deleted file mode 100644
index f8c4e9b49..000000000
--- a/browser/locales/searchplugins/wikipedia-NN.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (nn)</ShortName>
-<Description>Wikipedia, det frie oppslagsverket</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://nn.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://nn.wikipedia.org/wiki/Spesial:Søk"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-NO.xml b/browser/locales/searchplugins/wikipedia-NO.xml
deleted file mode 100644
index 31af946df..000000000
--- a/browser/locales/searchplugins/wikipedia-NO.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (no)</ShortName>
-<Description>Wikipedia, den frie encyklopedi</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://no.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://no.wikipedia.org/wiki/Spesial:Søk"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-af.xml b/browser/locales/searchplugins/wikipedia-af.xml
deleted file mode 100644
index e86550be5..000000000
--- a/browser/locales/searchplugins/wikipedia-af.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (af)</ShortName>
-<Description>Wikipedia, die vrye ensiklopedie</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://af.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://af.wikipedia.org/wiki/Spesiaal:Soek"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-an.xml b/browser/locales/searchplugins/wikipedia-an.xml
deleted file mode 100644
index f86c48190..000000000
--- a/browser/locales/searchplugins/wikipedia-an.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Biquipedia (an)</ShortName>
-<Description>A enciclopedia Libre</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://an.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://an.wikipedia.org/wiki/Especial:Mirar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ar.xml b/browser/locales/searchplugins/wikipedia-ar.xml
deleted file mode 100644
index d241bdf67..000000000
--- a/browser/locales/searchplugins/wikipedia-ar.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ويكيبيديا (ar)</ShortName>
-<Description>ويكيبيديا (ar)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ar.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ar.wikipedia.org/wiki/خاص:بحث"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-as.xml b/browser/locales/searchplugins/wikipedia-as.xml
deleted file mode 100644
index 97b1b44aa..000000000
--- a/browser/locales/searchplugins/wikipedia-as.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (as)</ShortName>
-<Description>ৱিকিপিডিয়া, à¦à¦–ন মà§à¦•à§à¦¤ বিশà§à¦¬à¦•à§‹à¦·</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://as.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://as.wikipedia.org/wiki/বিশেষ:সনà§à¦§à¦¾à¦¨"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ast.xml b/browser/locales/searchplugins/wikipedia-ast.xml
deleted file mode 100644
index aa6bb1df5..000000000
--- a/browser/locales/searchplugins/wikipedia-ast.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Uiquipedia (ast)</ShortName>
-<Description>La enciclopedia llibre</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ast.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ast.wikipedia.org/wiki/Especial:Gueta"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-az.xml b/browser/locales/searchplugins/wikipedia-az.xml
deleted file mode 100644
index 07cef511c..000000000
--- a/browser/locales/searchplugins/wikipedia-az.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vikipediya (az)</ShortName>
-<Description>Vikipediya, açıq ensiklopediya</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://az.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://az.wikipedia.org/wiki/Xüsusi:Axtar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-bg.xml b/browser/locales/searchplugins/wikipedia-bg.xml
deleted file mode 100644
index 3208c8249..000000000
--- a/browser/locales/searchplugins/wikipedia-bg.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Ð£Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ (bg)</ShortName>
-<Description>УикипедиÑ, Ñвободната енциклоподиÑ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://bg.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://bg.wikipedia.org/wiki/Специални:ТърÑене"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-bn.xml b/browser/locales/searchplugins/wikipedia-bn.xml
deleted file mode 100644
index 8073858e9..000000000
--- a/browser/locales/searchplugins/wikipedia-bn.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>উইকিপিডিয়া (bn)</ShortName>
-<Description>উইকিপিডিয়া, মà§à¦•à§à¦¤ বিশà§à¦¬à¦•à§‹à¦·</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://bn.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://bn.wikipedia.org/wiki/বিশেষ:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-br.xml b/browser/locales/searchplugins/wikipedia-br.xml
deleted file mode 100644
index 5696a3a83..000000000
--- a/browser/locales/searchplugins/wikipedia-br.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (br)</ShortName>
-<Description>Wikipedia, an holloueziadur digor</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://br.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://br.wikipedia.org/wiki/Dibar:Klask"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-bs.xml b/browser/locales/searchplugins/wikipedia-bs.xml
deleted file mode 100644
index 86d5cc38e..000000000
--- a/browser/locales/searchplugins/wikipedia-bs.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (bs)</ShortName>
-<Description>Slobodna enciklopedija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://bs.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://bs.wikipedia.org/wiki/Posebno:Pretraga"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ca.xml b/browser/locales/searchplugins/wikipedia-ca.xml
deleted file mode 100644
index 09a630a10..000000000
--- a/browser/locales/searchplugins/wikipedia-ca.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Viquipèdia (ca)</ShortName>
-<Description>L'enciclopèdia lliure</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ca.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ca.wikipedia.org/wiki/Especial:Cerca"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-cy.xml b/browser/locales/searchplugins/wikipedia-cy.xml
deleted file mode 100644
index 18a2805ea..000000000
--- a/browser/locales/searchplugins/wikipedia-cy.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wicipedia (cy)</ShortName>
-<Description>Wicipedia, Y Gwyddioniadur Rhydd</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://cy.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://cy.wikipedia.org/wiki/Arbennig:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-cz.xml b/browser/locales/searchplugins/wikipedia-cz.xml
deleted file mode 100644
index 8595e0569..000000000
--- a/browser/locales/searchplugins/wikipedia-cz.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedie (cs)</ShortName>
-<Description>Wikipedia, svobodná encyclopedie</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://cs.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://cs.wikipedia.org/wiki/Speciální:Hledání"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-da.xml b/browser/locales/searchplugins/wikipedia-da.xml
deleted file mode 100644
index b2ff05258..000000000
--- a/browser/locales/searchplugins/wikipedia-da.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (da)</ShortName>
-<Description>Wikipedia, den frie encyklopædi</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://da.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://da.wikipedia.org/wiki/Speciel:Søgning"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-de.xml b/browser/locales/searchplugins/wikipedia-de.xml
deleted file mode 100644
index 56440461b..000000000
--- a/browser/locales/searchplugins/wikipedia-de.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (de)</ShortName>
-<Description>Wikipedia, die freie Enzyklopädie</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://de.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://de.wikipedia.org/wiki/Spezial:Suche"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-dsb.xml b/browser/locales/searchplugins/wikipedia-dsb.xml
deleted file mode 100644
index cee19b404..000000000
--- a/browser/locales/searchplugins/wikipedia-dsb.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedija (dsb)</ShortName>
-<Description>Wikipedija, lichotna encyklopedija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://dsb.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://dsb.wikipedia.org/wiki/Specialne:PytaÅ›"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-el.xml b/browser/locales/searchplugins/wikipedia-el.xml
deleted file mode 100644
index 40c72079f..000000000
--- a/browser/locales/searchplugins/wikipedia-el.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (el)</ShortName>
-<Description>Βικιπαίδεια, η ελεÏθεÏη εγκυκλοπαίδεια</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://el.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://el.wikipedia.org/wiki/Ειδικό:Αναζήτηση"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-eo.xml b/browser/locales/searchplugins/wikipedia-eo.xml
deleted file mode 100644
index a579788c9..000000000
--- a/browser/locales/searchplugins/wikipedia-eo.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vikipedio (eo)</ShortName>
-<Description>Vikipedio, la libera enciklopedio</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://eo.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://eo.wikipedia.org/wiki/Specialaĵo:Serĉi"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-es.xml b/browser/locales/searchplugins/wikipedia-es.xml
deleted file mode 100644
index 1edf8e1ef..000000000
--- a/browser/locales/searchplugins/wikipedia-es.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (es)</ShortName>
-<Description>Wikipedia, la enciclopedia libre</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://es.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://es.wikipedia.org/wiki/Especial:Buscar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-et.xml b/browser/locales/searchplugins/wikipedia-et.xml
deleted file mode 100644
index 4859a0b10..000000000
--- a/browser/locales/searchplugins/wikipedia-et.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vikipeedia (et)</ShortName>
-<Description>Vikipeedia, vaba entsüklopeedia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://et.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://et.wikipedia.org/wiki/Eri:Otsimine"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-eu.xml b/browser/locales/searchplugins/wikipedia-eu.xml
deleted file mode 100644
index 1792a1760..000000000
--- a/browser/locales/searchplugins/wikipedia-eu.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (eu)</ShortName>
-<Description>Wikipedia, entziklopedia askea</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://eu.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://eu.wikipedia.org/wiki/Berezi:Bilatu"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-fa.xml b/browser/locales/searchplugins/wikipedia-fa.xml
deleted file mode 100644
index 68a4bc846..000000000
--- a/browser/locales/searchplugins/wikipedia-fa.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ویکی‌پدیا (fa)</ShortName>
-<Description>ویکی‌پدیا، دانشنامهٔ آزاد</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://fa.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://fa.wikipedia.org/wiki/ویژه:جستجو"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-fi.xml b/browser/locales/searchplugins/wikipedia-fi.xml
deleted file mode 100644
index ba3418a5b..000000000
--- a/browser/locales/searchplugins/wikipedia-fi.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (fi)</ShortName>
-<Description>Wikipedia (fi), vapaa tietosanakirja</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://fi.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://fi.wikipedia.org/wiki/Toiminnot:Haku"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-fr.xml b/browser/locales/searchplugins/wikipedia-fr.xml
deleted file mode 100644
index 88620ddea..000000000
--- a/browser/locales/searchplugins/wikipedia-fr.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipédia (fr)</ShortName>
-<Description>Wikipédia, l'encyclopédie libre</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://fr.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://fr.wikipedia.org/wiki/Spécial:Recherche"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-fy-NL.xml b/browser/locales/searchplugins/wikipedia-fy-NL.xml
deleted file mode 100644
index f9e531aa4..000000000
--- a/browser/locales/searchplugins/wikipedia-fy-NL.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedy (fy)</ShortName>
-<Description>De fergese ensyklopedy</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://fy.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://fy.wikipedia.org/wiki/Wiki:Sykje"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ga-IE.xml b/browser/locales/searchplugins/wikipedia-ga-IE.xml
deleted file mode 100644
index 5abf6e314..000000000
--- a/browser/locales/searchplugins/wikipedia-ga-IE.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vicipéid (ga)</ShortName>
-<Description>Vicipéid, an Chiclipéid Shaor</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ga.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ga.wikipedia.org/wiki/Speisialta:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-gd.xml b/browser/locales/searchplugins/wikipedia-gd.xml
deleted file mode 100644
index 019305ee4..000000000
--- a/browser/locales/searchplugins/wikipedia-gd.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Uicipeid (gd)</ShortName>
-<Description>Wikipedia, An leabhar mòr-eòlais</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://gd.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://gd.wikipedia.org/wiki/Sònraichte:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-gl.xml b/browser/locales/searchplugins/wikipedia-gl.xml
deleted file mode 100644
index da30f3c04..000000000
--- a/browser/locales/searchplugins/wikipedia-gl.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (gl)</ShortName>
-<Description>Wikipedia, a enciclopedia libre</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://gl.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://gl.wikipedia.org/wiki/Especial:Procurar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-gn.xml b/browser/locales/searchplugins/wikipedia-gn.xml
deleted file mode 100644
index 57947b444..000000000
--- a/browser/locales/searchplugins/wikipedia-gn.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vikipetã (gn)</ShortName>
-<Description>Vikipetã, opaite tembikuaa hekosãsóva renda</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://gn.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://gn.wikipedia.org/wiki/Mba'echĩchĩ:Buscar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-gu.xml b/browser/locales/searchplugins/wikipedia-gu.xml
deleted file mode 100644
index 09d9277de..000000000
--- a/browser/locales/searchplugins/wikipedia-gu.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>વિકિપીડિયા (gu)</ShortName>
-<Description>વીકીપીડિયા, મà«àª•à«àª¤ àªàª¨àª¸àª¾àª¯àª•à«àª²à«‹àªªà«€àª¡àª¿àª¯àª¾</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://gu.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://gu.wikipedia.org/wiki/વિશેષ:શોધ"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-he.xml b/browser/locales/searchplugins/wikipedia-he.xml
deleted file mode 100644
index d9b4730d7..000000000
--- a/browser/locales/searchplugins/wikipedia-he.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ויקיפדיה</ShortName>
-<Description>ויקיפדיה</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://he.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://he.wikipedia.org/wiki/מיוחד:חיפוש"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-hi.xml b/browser/locales/searchplugins/wikipedia-hi.xml
deleted file mode 100755
index 090a78443..000000000
--- a/browser/locales/searchplugins/wikipedia-hi.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>विकिपीडिया (hi)</ShortName>
-<Description>विकिपीडिया (हिनà¥à¤¦à¥€)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://hi.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://hi.wikipedia.org/wiki/विशेष:खोज"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-hr.xml b/browser/locales/searchplugins/wikipedia-hr.xml
deleted file mode 100644
index 0c6a13da2..000000000
--- a/browser/locales/searchplugins/wikipedia-hr.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedija (hr)</ShortName>
-<Description>Wikipedija, slobodna enciklopedija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://hr.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://hr.wikipedia.org/wiki/Posebno:Traži"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-hsb.xml b/browser/locales/searchplugins/wikipedia-hsb.xml
deleted file mode 100644
index 0540ff844..000000000
--- a/browser/locales/searchplugins/wikipedia-hsb.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedija (hsb)</ShortName>
-<Description>Wikipedija, swobodna encyklopedija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://hsb.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://hsb.wikipedia.org/wiki/Specialnje:Pytać"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-hu.xml b/browser/locales/searchplugins/wikipedia-hu.xml
deleted file mode 100644
index 9c7a3e5ea..000000000
--- a/browser/locales/searchplugins/wikipedia-hu.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipédia (hu)</ShortName>
-<Description>Wikipedia, a szabad enciklopédia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://hu.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://hu.wikipedia.org/wiki/Speciális:Keresés"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-hy.xml b/browser/locales/searchplugins/wikipedia-hy.xml
deleted file mode 100644
index d45001783..000000000
--- a/browser/locales/searchplugins/wikipedia-hy.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (hy)</ShortName>
-<Description>ÕŽÕ«Ö„Õ«ÖƒÕ¥Õ¤Õ«Õ¡Õ Õ¡Õ¦Õ¡Õ¿ Õ°Õ¡Õ¶Ö€Õ¡Õ£Õ«Õ¿Õ¡Ö€Õ¡Õ¶</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://hy.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://hy.wikipedia.org/wiki/ÕÕºÕ¡Õ½Õ¡Ö€Õ¯Õ¸Õ²:ÕˆÖ€Õ¸Õ¶Õ¥Õ¬"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-id.xml b/browser/locales/searchplugins/wikipedia-id.xml
deleted file mode 100644
index aaa65e19d..000000000
--- a/browser/locales/searchplugins/wikipedia-id.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (id)</ShortName>
-<Description>Wikipedia, ensiklopedia bebas</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://id.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://id.wikipedia.org/wiki/Istimewa:Pencarian"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-is.xml b/browser/locales/searchplugins/wikipedia-is.xml
deleted file mode 100644
index 453da21f7..000000000
--- a/browser/locales/searchplugins/wikipedia-is.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (is)</ShortName>
-<Description>Wikipedia, the free encyclopedia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjA3MkMyRDY5QjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjA3MkMyRDZBQjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDcyQzJENjdCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDcyQzJENjhCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7lkNGzAAAELklEQVR42uyYa4hUZRjHn3Nm13X2Mu6urtqutrTeVjRUQikoKUoQLIy8hybiBcVMRdFASPwgQTczsCiMvFYGffBDeANFUDEydc31viheat2dyVndmdmdy57+7/I/+HCcKaX1Q3Re+LHnOe9z3sv/PM/znlnLcRz5vzdb/OaL4Ivgi3C/WV01UCAQkNraWqmpGSCVVVWSl5cnZaXl4jgZaWpugp0viURcwpGIJJMpSba1SY+yUlmy5B3ZuGGDXGlokJKSYkmn0pJOp6UDBbsl2iJFRYVi25bEYjFpwzOtra3S3t4umUxGuqqo53WVCGZR9fX1nZgWDAaxgWIJhUpASGyIFLBtSWKDhcFCScTjuE5JXV2dhMNhSaVS2Kwt0WgUYiU6hTCiRSLNGM2BnYF4yccWCWPB6yAC9oGzYC2Iga/pNx/kg/fBs2AcSICvQOMjT2pZD7xFE0kFBd0lHo89zsiv5d8L3o4nwW+dcotUMDo+p11Jn3YKY/qeY9900P0/lv5hUJ+rswc3Nlnd6wDvgmHgR3V/GfgyS0RZf1NrrEeoR/ZD1rDAPzzrHX8wuEYhcr68E6BV2W9RGJMiI9T9wxzwFfAd+AyUgeFgK/iG9ovgAMcpAIvB92AVNzCJ9hoKu4LjjwabmYrGdwtYyb45nPM98DbYyHW4bSr7Pwb9PPszqTwGnGdUZ22DuekX1L074JSy3wC7eV1C/53clFHXVLEz7Hc3UsG38gz9x7O/F+25oC+vPzI1FVwGN0FP8Dz4gmO4fvPYN5X2LI5ZSvsTT9F/iveEgkZyhc8lTrxd3TPhM1LZ08C3vL7HxRplM6AN/AqOgVGgjhts5sKugyi4qvKzhaKZ4voHGMKCe5oF2qHfIj7TyDGucSM/sH5tY7/p+x1cBGm17vmMgikUsxw8kSv/ZoBqqjiCm7zLsBQ+vMuTl/nKbuTJcdIjpmnduIBuKmfNmfcy570BlrMvzpSap+Z2GG2WZ869nr3Ynn7TngZ7wACKbIRdl+s74QgddlPphVzgh6A/c1g8xbND2b24qD/BLVDk8XWUv8MIKuTCTNinVFjfBh+oY82mv+OZs1SNJ1n6ZzLi1nvWsgksyFUbXuVAO5RQjppENxNynyq7AfzE6xsMyyDtfhxDF1mHkZCtSJ9T9mLWIPeZibzuyejb5hlztVr7ZaaBtzlu5GU7Zi7xW8BU0CaqZt7wfnBI+b0GhvIb4iBD7SWOuYfKr+Px+zN4k3loJj/KojYIFINfmALu6TCW0dGbp0gNj+nZLHI203YCOA6WqtNhEF/OWc45ki/kHOuWzW+cgYyyK//mw8MtLEU8AkMqbIMeP5OjfWj3oU9flUL63C5XZ7zZaJXq66+eGajmdJvrG2LkuHNUco1uLapWdarC8v+z5P+U9kXwRfBF8EXwRfBFyNH+EmAA/FQ613UCCjYAAAAASUVORK5CYII=</Image>
-<Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg5QzlEREIwQjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg5QzlEREIxQjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODlDOUREQUVCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODlDOUREQUZCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz41D9uwAAAJWElEQVR42uxcCWxURRj+t3t029IiVCyXLSpo0ERFLVAvNJ4oBRUVL7Se4IUXeOIVjaKmgkHxthweiKJGY/HAKxqwaiwYBBESwQtpgdCWtns//6nfi7/je7v72kI0mS/5s7vvn5n3Zuab/3pNfZZlkYFBjlkCA0MEA0MEA0MEA0MEA0MEA0MEA0MEA0MEA0MEA0MEg87B919+OL/fT4FAgELBIF0zZQqVl5dTSZ8SWr1mHY2oqKBYtIWSiSSlLB81bN5EkUiU4ok4BYMBSqZ8FItEqCmVoBhf6xvOJx+PY6VSRHi/krJS5PP5OiTB4+SFcymVTFI797N4TFJ6foatjVsoNxyi3sW7U3t7hOKxCB+hHGppbqFgfh7ts+cgamlvofy8fIrHk+Tj4ROxKK1Y+S21trbRgvnz+NkilOSxU+r+hghdw+DBg6msbBDV1X1FY8ZUUmtbS8fG+nw5VFVVRUWFPamppYlCoSAlkooI7dTMmxlnMvTzSAS1oe1trdSjqIiJsJWJEKRevYs7iBCLMhH8OfwZo2Zus7R2CcWYHIq0hw4fQX5+nveX1FJ9/bfGIuxqDBgwgPLy8ngD4x0bq7baSllUstcgGj9hAoWjfJ03yrIkESwQgU9wIkXh3FAHESLRKBUV7UZlpaW0dt2PFGlro8WLX6eGhoaOE93xxpb7qL7qpDfydRuKDIlkgsi81P0PBkI53kOhIUOG0LRptzAhijrV//8YIwxluZMlxtJCf3HZz1LM8hbLQpYDWe5gaWJhu0ghliBLNctqlqksB7NsYwmz9GCZw/IFy0Uso9E3ylLIkg/dbEPTnY5TWTawfJ+p4R4sN7GsAgmUtLHczXKYaDNb6JVMB1kUjmd5R+hU2z2hG8HyIMa09U+hj8HOhdo3FZ2+7qVTL5bN2KiVLm1mQd/OMlDTjYPuXpe+86EfZvZnl+EWcbD7e+l4jzi1Zzjo+7I0Ql+j6epYfoFbcSKZcjsLzN7sMoQ0Kz/FS+dSllZ0/MSlzf3Qq3b74dpxuHaOS5/roD/Q7M8uwyU4nPZ+feN1gGfRMc5S4WIVtqPNQ7imXMkacq9UbmJZJgLUXBcGO323ERTfA3rtSViioIM+IPr7tbFshNOsScDlmdImK2nmEfRwqp36+7PoW4cAvzcCfLVfI9NNUMfTLBfiIa5kWa7p/0AwOB2s246TPgaBiY7TQZ7r8VtZkWcwmQQ+fSDTVWgzE1lICqI2aS0yELUQL7H0YymCy1Exy40s37FczTIeYybFfdS8XmE5gOVhlgKM7cMixbR4Rrox5SavweYmsW5JCIHYPVmWIINSGAT3aY+fg+dox3xS+P0uywuwsDqRVFZ2CO5jZ3Mq87qV5es0JBjOUs5yLjK5z1hOhMX+0gub38ON1U33colGG4X/eSPNWJ/hYWzkY5NrRP8rVOou03g8tK1fxLK/sCiVQnctAtACu7bEMoplI/Q/sBzK0gd61e4gkMkeYxzIfBRMqLr2srBcfbCwddD9zjKR5TSWsSw3i+vSwgwDqe37TMJ91PzPxLqp6+vgXvXUfjDLWaL/QvQtzLB/i7DuNiah/88gbNY4Udx8hkub6aLNyS5t9oX+dgfdKOh+cnEVhBOu2hytXVfj/cpSlmYOj2vuS8dY6Fdo13uKOOlUlyj8SZf5qHx9d+36kejzmyCrbjHtTKw8wzqcksXe9YO1kfGaSvObMcZYNz/mhA+ECbkUfkbHAuEK3HzPZfic46ArEM9Q5KCXfl+eAHUSb8MmbczCv7qRLE/cR6JJFF+GuMQRuS6Wb6bDXDLN8024gDDis5DLWtjWNBOuByFfFde2ilrC+V6IQKLqpxhe5aAfIPpPhrvQF2AyxtnexQg4IU7X04gDVu7k1IsQf6R7HsIhuRzfH4OF84q5+FQu69guPHcAcdRH9O+3HfPxWYm9y5oIb7OsFz5GN2vVqBsov1iCTZc4Dye5O8rIO2B1aumvcvj8btx0PcBVzzwU35elKb6Voah2l2aGO/O66Xe4OoVjujCX0dgLZS3fRwngUwSxDwhLeK4XIuxAdG/7+tOErhIbczFMG+GUFos2KnVZikCoq3gB2UthmvpGZ1GAoEwFhHsjiAyhuLbGpc8RMOM1qJH80cVniCCGIK8VQA1Xw/o+D/em4p96ZFy1SALIiQiZoMz9ZoeCRD0iUBkMKZmGa8dmEdycgjYbRUSv+8Xv0eZhTE59X410NBOeQftZLvoJ0Dchyp6LhVqG9NkJd4vovT9M7HQtQtdxEvpsQiDnBBVzfI52zzvo7XU4M819hqLNJWnaVIhUtMIrGarFRg9DXqs/1MdiU1Xa8yICFuomItjvJz7E7+UZCkBeiLAClmyYS6rsRIRntYh8YheJ0EPM9Z5OEuEJkLogQ5HLTo8fzdY1yKDRLrY8CllF/3yjNVOUqFWGcAJOcXfBfsE1Hq5mJAKz7oAfUXW9h0DPr0XkC8R6FnbiGQpFhrK0k+7tKtQ+WjPEQ2+LtezphQgb4DftQGYU/L/EhyKKn4xCVE2WmUBKVOgkZOUuis9mpD9tKEJNTTN+Uvt003sJ7uLap44bHNxKMsM8CUWjIAI7pwDVcshW9JRR4bks5rAQNYtSFNA8YTgmYptlp9L0JOFCbs5izLPRdrtD6mlHt5vQZoKmu0Dc64I01TULgaYTqqBf72Ed5qBPrYPucJYGnDSJcaJKW+pQPZwI/VqntA6HdQPaOKXx+4EgjR7mUY/xvszgShzxCTpXuujzUUqO07//VkGiP8z6L2Izl+OE24tzKU6GJchyB/3zZc0XQl8rgh/lkxcLnYrI54miVxnihs2izTLc3+1vOEeCWAm0Vyf7LQSYNUjPLByWElF/mYENlvO8DylwNSzpr3AtJQ4EqBLxl4XsZBbWdyCqp1uEfgkOYaGL+1AW6zURMFqoWt4X8EAE9VJH1ezfcdG3IS3JFTmxW8CyDRNqwuIP1MxtApOai8XtiwmHRLtb8TxRBJs+4b9XIZJvBUF3E1YsgFStGic4DIsUyfDM67GQTfjdQyxmLsj0IwhmP4edgm/D8/Whv1+0qXavYKM3uNzT/nOARZh3Ma4HMZ6axyNYmyDIF3ex2DlYq3qszQ6sZzE5vyw0MDAwMDAwMDAwQKpm/uGmgZ1SGBgYIhgYIhgYIhgYIhgYIhgYIhgYIhgYIhgYIhh4w58CDAAL8AVXFSeKUgAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://is.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://is.wikipedia.org/wiki/Kerfissíða:Leit"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-it.xml b/browser/locales/searchplugins/wikipedia-it.xml
deleted file mode 100644
index 6e9454197..000000000
--- a/browser/locales/searchplugins/wikipedia-it.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (it)</ShortName>
-<Description>Wikipedia, l'enciclopedia libera</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://it.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://it.wikipedia.org/wiki/Speciale:Ricerca"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ja.xml b/browser/locales/searchplugins/wikipedia-ja.xml
deleted file mode 100644
index f51004d9b..000000000
--- a/browser/locales/searchplugins/wikipedia-ja.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (ja)</ShortName>
-<Description>Wikipedia - フリー百科事典</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ja.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ja.wikipedia.org/wiki/特別:検索"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ka.xml b/browser/locales/searchplugins/wikipedia-ka.xml
deleted file mode 100644
index 53a868d76..000000000
--- a/browser/locales/searchplugins/wikipedia-ka.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ვიკიპედირ(ka)</ShortName>
-<Description>ვიკიპედიáƒ, თáƒáƒ•áƒ˜áƒ¡áƒ£áƒ¤áƒáƒšáƒ˜ ენციკლáƒáƒžáƒ”დიáƒ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ka.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ka.wikipedia.org/wiki/სპეციáƒáƒšáƒ£áƒ áƒ˜:ძიებáƒ"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-kab.xml b/browser/locales/searchplugins/wikipedia-kab.xml
deleted file mode 100644
index 63f01a585..000000000
--- a/browser/locales/searchplugins/wikipedia-kab.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (kab)</ShortName>
-<Description>Wikipedia, tasanayt tilellit</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://kab.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://kab.wikipedia.org/wiki/Uslig:Search" resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/wikipedia-kk.xml b/browser/locales/searchplugins/wikipedia-kk.xml
deleted file mode 100644
index 1e17e5970..000000000
--- a/browser/locales/searchplugins/wikipedia-kk.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Ð£Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ (kk)</ShortName>
-<Description>Ð£Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ (kk)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://kk.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://kk.wikipedia.org/wiki/Ðрнайы:Іздеу"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-km.xml b/browser/locales/searchplugins/wikipedia-km.xml
deleted file mode 100644
index 62bf73d87..000000000
--- a/browser/locales/searchplugins/wikipedia-km.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>វីគីភីឌា (km)</ShortName>
-<Description>វីគីភីឌា សព្វ​វចនា​ធិប្បាយ​សáŸážšáž¸</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://km.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://km.wikipedia.org/wiki/ពិសáŸážŸ:ស្វែងរក"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-kn.xml b/browser/locales/searchplugins/wikipedia-kn.xml
deleted file mode 100644
index 34af446da..000000000
--- a/browser/locales/searchplugins/wikipedia-kn.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (kn)</ShortName>
-<Description>Wikipedia, the free encyclopedia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://kn.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://kn.wikipedia.org/wiki/ವಿಶೇಷ:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-kr.xml b/browser/locales/searchplugins/wikipedia-kr.xml
deleted file mode 100644
index 2ed60c869..000000000
--- a/browser/locales/searchplugins/wikipedia-kr.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>위키백과 (ko)</ShortName>
-<Description>Wikipedia, the free encyclopedia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ko.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ko.wikipedia.org/wiki/특수기능:찾기"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-lij.xml b/browser/locales/searchplugins/wikipedia-lij.xml
deleted file mode 100644
index 23c1bcea4..000000000
--- a/browser/locales/searchplugins/wikipedia-lij.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (lij)</ShortName>
-<Description>Wikipedia, l'enciclopedia libera</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://lij.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://lij.wikipedia.org/wiki/Speçiale:Riçerca"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-lt.xml b/browser/locales/searchplugins/wikipedia-lt.xml
deleted file mode 100644
index f2e0a2d3d..000000000
--- a/browser/locales/searchplugins/wikipedia-lt.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (lt)</ShortName>
-<Description>Vikipedija, laisvoji enciklopedija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://lt.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://lt.wikipedia.org/wiki/Specialus:Paieška"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-lv.xml b/browser/locales/searchplugins/wikipedia-lv.xml
deleted file mode 100644
index 2eccccbb4..000000000
--- a/browser/locales/searchplugins/wikipedia-lv.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vikipēdija</ShortName>
-<Description>VikipÄ“dija, brÄ«vÄ encikopÄ“dija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://lv.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://lv.wikipedia.org/wiki/Special:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-mk.xml b/browser/locales/searchplugins/wikipedia-mk.xml
deleted file mode 100644
index a9782adc4..000000000
--- a/browser/locales/searchplugins/wikipedia-mk.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Википедија (mk)</ShortName>
-<Description>Википедија, Ñлободната енциклопедија</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://mk.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://mk.wikipedia.org/wiki/Специјална:Барај"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ml.xml b/browser/locales/searchplugins/wikipedia-ml.xml
deleted file mode 100644
index b75780316..000000000
--- a/browser/locales/searchplugins/wikipedia-ml.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>വികàµà´•à´¿à´ªàµ€à´¡à´¿à´¯ (ml)</ShortName>
-<Description>വികàµà´•à´¿à´ªàµ€à´¡à´¿à´¯, à´¸àµà´µà´¤à´¨àµà´¤àµà´° സരàµâ€à´µàµà´µà´µà´¿à´œàµà´žà´¾à´¨à´•àµ‹à´¶à´‚ </Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ml.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ml.wikipedia.org/wiki/à´ªàµà´°à´¤àµà´¯àµ‡à´•à´‚:à´…à´¨àµà´µàµ‡à´·à´£à´‚"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-mr.xml b/browser/locales/searchplugins/wikipedia-mr.xml
deleted file mode 100644
index a161599fa..000000000
--- a/browser/locales/searchplugins/wikipedia-mr.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>विकिपीडिया (mr)</ShortName>
-<Description>विकिपीडिया, मोफत माहितीकोष</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://mr.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://mr.wikipedia.org/wiki/विशेष:शोधा"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ms.xml b/browser/locales/searchplugins/wikipedia-ms.xml
deleted file mode 100644
index 13be0d2f4..000000000
--- a/browser/locales/searchplugins/wikipedia-ms.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (ms)</ShortName>
-<Description>Wikipedia, ensiklopedia bebas</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ms.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ms.wikipedia.org/wiki/Khas:Gelintar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-my.xml b/browser/locales/searchplugins/wikipedia-my.xml
deleted file mode 100644
index d6852bd28..000000000
--- a/browser/locales/searchplugins/wikipedia-my.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (my)</ShortName>
-<Description>အá€á€™á€²á€·á€œá€½á€á€ºá€œá€•á€ºá€…ွယ်စုံကျမ်း</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://my.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://my.wikipedia.org/wiki/Special:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ne.xml b/browser/locales/searchplugins/wikipedia-ne.xml
deleted file mode 100644
index 5f704a813..000000000
--- a/browser/locales/searchplugins/wikipedia-ne.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>विकिपीडिया (ne)</ShortName>
-<Description>विकिपिडिया à¤à¤• सà¥à¤µà¤¤à¤¨à¥à¤¤à¥à¤° विशà¥à¤µà¤•à¥‹à¤·</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ne.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ne.wikipedia.org/wiki/विशेष:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-nl.xml b/browser/locales/searchplugins/wikipedia-nl.xml
deleted file mode 100644
index ade5458ad..000000000
--- a/browser/locales/searchplugins/wikipedia-nl.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (nl)</ShortName>
-<Description>De vrije encyclopedie</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://nl.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://nl.wikipedia.org/wiki/Speciaal:Zoeken"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-or.xml b/browser/locales/searchplugins/wikipedia-or.xml
deleted file mode 100644
index 27dafbf8a..000000000
--- a/browser/locales/searchplugins/wikipedia-or.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (or)</ShortName>
-<Description>ୱିକିପିଡ଼ିଆ (ଓଡ଼ିଆ)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://or.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://or.wikipedia.org/wiki/ବିଶେଷ:ଖୋଜନà­à¬¤à­"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-pa.xml b/browser/locales/searchplugins/wikipedia-pa.xml
deleted file mode 100644
index ed13d944c..000000000
--- a/browser/locales/searchplugins/wikipedia-pa.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (pa)</ShortName>
-<Description>ਵਿਕਿਪੀਡਿਆ, ਮà©à¨«à¨¼à¨¤/ਮà©à¨•à¨¤ ਸ਼ਬਦਕੋਸ਼</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://pa.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://pa.wikipedia.org/wiki/ਖ਼ਾਸ:ਖੋਜੋ"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-pl.xml b/browser/locales/searchplugins/wikipedia-pl.xml
deleted file mode 100644
index 2ff566600..000000000
--- a/browser/locales/searchplugins/wikipedia-pl.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (pl)</ShortName>
-<Description>Wikipedia, wolna encyklopedia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://pl.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch" />
- <Param name="search" value="{searchTerms}" />
-</Url>
- <Url method="GET"
- rel="searchform"
- template="https://pl.wikipedia.org/wiki/Specjalna:Szukaj"
- type="text/html">
- <Param name="search" value="{searchTerms}" />
- <Param name="sourceid" value="Mozilla-search" />
- </Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-pt.xml b/browser/locales/searchplugins/wikipedia-pt.xml
deleted file mode 100644
index 86e4b76e4..000000000
--- a/browser/locales/searchplugins/wikipedia-pt.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (pt)</ShortName>
-<Description>Wikipédia, a enciclopédia livre</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://pt.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://pt.wikipedia.org/wiki/Especial:Pesquisar"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-rm.xml b/browser/locales/searchplugins/wikipedia-rm.xml
deleted file mode 100644
index 39702810f..000000000
--- a/browser/locales/searchplugins/wikipedia-rm.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (rm)</ShortName>
-<Description>Vichipedia, l'enciclopedia libra</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://rm.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://rm.wikipedia.org/wiki/Spezial:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ru.xml b/browser/locales/searchplugins/wikipedia-ru.xml
deleted file mode 100644
index a5660bc5d..000000000
--- a/browser/locales/searchplugins/wikipedia-ru.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Ð’Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ (ru)</ShortName>
-<Description>ВикипедиÑ, ÑÐ²Ð¾Ð±Ð¾Ð´Ð½Ð°Ñ ÑнциклопедиÑ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ru.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ru.wikipedia.org/wiki/СлужебнаÑ:ПоиÑк"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-si.xml b/browser/locales/searchplugins/wikipedia-si.xml
deleted file mode 100644
index 6cb6d8102..000000000
--- a/browser/locales/searchplugins/wikipedia-si.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (si)</ShortName>
-<Description>Wikipedia, the free encyclopedia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://si.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://si.wikipedia.org/wiki/විà·à·šà·‚:ගවේෂණය"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-sk.xml b/browser/locales/searchplugins/wikipedia-sk.xml
deleted file mode 100644
index f3cf6f00a..000000000
--- a/browser/locales/searchplugins/wikipedia-sk.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipédia (sk)</ShortName>
-<Description>Wikipédia, slobodná a otvorená encyklopédia</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://sk.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://sk.wikipedia.org/wiki/Špeciálne:Hľadanie"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-sl.xml b/browser/locales/searchplugins/wikipedia-sl.xml
deleted file mode 100644
index 1fd10c25f..000000000
--- a/browser/locales/searchplugins/wikipedia-sl.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedija</ShortName>
-<Description>Wikipedija, prosta enciklopedija</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://sl.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://sl.wikipedia.org/wiki/Posebno:Iskanje"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-sq.xml b/browser/locales/searchplugins/wikipedia-sq.xml
deleted file mode 100644
index a72be35e2..000000000
--- a/browser/locales/searchplugins/wikipedia-sq.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (sq)</ShortName>
-<Description>Wikipedia, enciklopedia e lirë</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://sq.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://sq.wikipedia.org/wiki/Speciale:Kërkim"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-sr.xml b/browser/locales/searchplugins/wikipedia-sr.xml
deleted file mode 100644
index 50feaed8f..000000000
--- a/browser/locales/searchplugins/wikipedia-sr.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Википедија (sr)</ShortName>
-<Description>Претрага Википедије на ÑрпÑком језику</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://sr.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://sr.wikipedia.org/wiki/ПоÑебно:Претражи"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-sv-SE.xml b/browser/locales/searchplugins/wikipedia-sv-SE.xml
deleted file mode 100644
index 23df8087d..000000000
--- a/browser/locales/searchplugins/wikipedia-sv-SE.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (sv)</ShortName>
-<Description>Wikipedia, den fria encyklopedin</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://sv.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://sv.wikipedia.org/wiki/Special:Sök"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ta.xml b/browser/locales/searchplugins/wikipedia-ta.xml
deleted file mode 100644
index f727c1d66..000000000
--- a/browser/locales/searchplugins/wikipedia-ta.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>விகà¯à®•à®¿à®ªà¯à®ªà¯€à®Ÿà®¿à®¯à®¾ (ta)</ShortName>
-<Description>விகà¯à®•à®¿à®ªà¯à®ªà¯€à®Ÿà®¿à®¯à®¾ (ta)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ta.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ta.wikipedia.org/wiki/சிறபà¯à®ªà¯:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-te.xml b/browser/locales/searchplugins/wikipedia-te.xml
deleted file mode 100644
index ec3775ffa..000000000
--- a/browser/locales/searchplugins/wikipedia-te.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>వికీపీడియా (te)</ShortName>
-<Description>వికీపీడియా (te)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://te.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://te.wikipedia.org/wiki/à°ªà±à°°à°¤à±à°¯à±‡à°•:à°…à°¨à±à°µà±‡à°·à°£"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-th.xml b/browser/locales/searchplugins/wikipedia-th.xml
deleted file mode 100644
index 7c62f5457..000000000
--- a/browser/locales/searchplugins/wikipedia-th.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>วิà¸à¸´à¸žà¸µà¹€à¸”ีย</ShortName>
-<Description>วิà¸à¸´à¸žà¸µà¹€à¸”ีย สารานุà¸à¸£à¸¡à¹€à¸ªà¸£à¸µ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://th.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://th.wikipedia.org/wiki/พิเศษ:ค้นหา"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-tl.xml b/browser/locales/searchplugins/wikipedia-tl.xml
deleted file mode 100644
index fbc14236d..000000000
--- a/browser/locales/searchplugins/wikipedia-tl.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (tl)</ShortName>
-<Description>Wikipedia, ang malayang ensiklopedya</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://tl.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://tl.wikipedia.org/wiki/Natatangi:Maghanap"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-tr.xml b/browser/locales/searchplugins/wikipedia-tr.xml
deleted file mode 100644
index 7841ca2ca..000000000
--- a/browser/locales/searchplugins/wikipedia-tr.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (tr)</ShortName>
-<Description>Vikipedi, özgür ansiklopedi</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://tr.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://tr.wikipedia.org/wiki/Özel:Ara"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-uk.xml b/browser/locales/searchplugins/wikipedia-uk.xml
deleted file mode 100644
index 4f7df8371..000000000
--- a/browser/locales/searchplugins/wikipedia-uk.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Ð’Ñ–ÐºÑ–Ð¿ÐµÐ´Ñ–Ñ (uk)</ShortName>
-<Description>ВікіпедіÑ, вільна енциклопедіÑ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://uk.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://uk.wikipedia.org/wiki/Спеціальна:Пошук"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-ur.xml b/browser/locales/searchplugins/wikipedia-ur.xml
deleted file mode 100644
index 6c86ab18d..000000000
--- a/browser/locales/searchplugins/wikipedia-ur.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ویکیپیڈیا (ur)</ShortName>
-<Description>ویکیپیڈیا آزاد دائرۃ المعارÙ</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ur.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ur.wikipedia.org/wiki/خاص:تلاش"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-uz.xml b/browser/locales/searchplugins/wikipedia-uz.xml
deleted file mode 100644
index badfc12c0..000000000
--- a/browser/locales/searchplugins/wikipedia-uz.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Vikipediya (uz)</ShortName>
-<Description>Vikipediya, ochiq ensiklopediya</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://uz.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://uz.wikipedia.org/wiki/Maxsus:Search"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-vi.xml b/browser/locales/searchplugins/wikipedia-vi.xml
deleted file mode 100644
index ba8639b29..000000000
--- a/browser/locales/searchplugins/wikipedia-vi.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (vi)</ShortName>
-<Description>Wikipedia, bách khoa toàn thư mở</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://vi.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://vi.wikipedia.org/wiki/Äặc_biệt:Tìm_kiếm"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-wo.xml b/browser/locales/searchplugins/wikipedia-wo.xml
deleted file mode 100644
index 046ffad38..000000000
--- a/browser/locales/searchplugins/wikipedia-wo.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (wo)</ShortName>
-<Description>Wikipedia, Jimbulang bu Ubbeeku bi</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://wo.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://wo.wikipedia.org/wiki/Jagleel:Ceet"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-zh-CN.xml b/browser/locales/searchplugins/wikipedia-zh-CN.xml
deleted file mode 100644
index 0a6e813f3..000000000
--- a/browser/locales/searchplugins/wikipedia-zh-CN.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>维基百科</ShortName>
-<Description>维基百科,自由的百科全书</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://zh.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://zh.wikipedia.org/wiki/Special:æœç´¢"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia-zh-TW.xml b/browser/locales/searchplugins/wikipedia-zh-TW.xml
deleted file mode 100644
index f25052349..000000000
--- a/browser/locales/searchplugins/wikipedia-zh-TW.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (zh)</ShortName>
-<Description>維基百科,自由的百科全書</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://zh.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://zh.wikipedia.org/wiki/Special:æœç´¢"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
- <Param name="variant" value="zh-tw"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipedia.xml b/browser/locales/searchplugins/wikipedia.xml
index 9bb2634e6..fb72be5d1 100644
--- a/browser/locales/searchplugins/wikipedia.xml
+++ b/browser/locales/searchplugins/wikipedia.xml
@@ -14,6 +14,6 @@
<Url type="text/html" method="GET" template="https://en.wikipedia.org/wiki/Special:Search"
resultdomain="wikipedia.org" rel="searchform">
<Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
+ <Param name="sourceid" value="PaleMoon-search"/>
</Url>
</SearchPlugin>
diff --git a/browser/locales/searchplugins/wikipediaro.xml b/browser/locales/searchplugins/wikipediaro.xml
deleted file mode 100644
index 58021460c..000000000
--- a/browser/locales/searchplugins/wikipediaro.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Wikipedia (ro)</ShortName>
-<Description>Wikipedia, enciclopedia liberă</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://ro.wikipedia.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://ro.wikipedia.org/wiki/Special:Căutare"
- resultdomain="wikipedia.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
- <Param name="sourceid" value="Mozilla-search"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wiktionary-te.xml b/browser/locales/searchplugins/wiktionary-te.xml
deleted file mode 100644
index 851e02089..000000000
--- a/browser/locales/searchplugins/wiktionary-te.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>వికà±à°·à°¨à°°à±€ (te)</ShortName>
-<Description>వికà±à°·à°¨à°°à±€ (te)</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAEAgQAhIOEAMjHyABIR0gA6ejpAGlqaQCpqKkAKCgoAPz9%2FAAZGBkAmJiYANjZ2ABXWFcAent6ALm6uQA8OjwAiIiIiIiIiIiIiI4oiL6IiIiIgzuIV4iIiIhndo53KIiIiB%2FWvXoYiIiIfEZfWBSIiIEGi%2FfoqoiIgzuL84i9iIjpGIoMiEHoiMkos3FojmiLlUipYliEWIF%2BiDe0GoRa7D6GPbjcu1yIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://te.wiktionary.org/w/api.php">
- <Param name="action" value="opensearch"/>
- <Param name="search" value="{searchTerms}"/>
- <Param name="namespace" value="0"/>
-</Url>
-<Url type="text/html" method="get" template="https://te.wiktionary.org/wiki/à°ªà±à°°à°¤à±à°¯à±‡à°•:à°…à°¨à±à°µà±‡à°·à°£"
- resultdomain="wiktionary.org" rel="searchform">
- <Param name="search" value="{searchTerms}"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/wolnelektury-pl.xml b/browser/locales/searchplugins/wolnelektury-pl.xml
deleted file mode 100644
index 2ac3ba4df..000000000
--- a/browser/locales/searchplugins/wolnelektury-pl.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
- <ShortName>Wolne Lektury</ShortName>
- <Description>Biblioteka internetowa WolneLektury.pl</Description>
- <InputEncoding>UTF-8</InputEncoding>
- <Image height="16" width="16" type="image/png">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAZlBMVEWauyuauiubuiubuyqauyqbvCrHuBfHuBfsvADrvgDsvgDsvQDrvgDsvQCbuyvsvgC4ABy8ABy+ABm+ABq/ABq/ABm+ABk9YW4+YW49YW49YnA9Y3E4Y3E4Y3G/ABo+Ym+/ABm4ABw5ZyQ5AAAAInRSTlPbyaSAWzYSADZbgKTJ2///EjZbf6TJ28+kgFs2EgD//4AA+LFVUAAAAFdJREFUeAGdzsEKgDAMA9CklzlwQy/+/zeKoCAuspVdvAx8hwYCpSXoIKNLqC7Elo8RjaxnL/i7KAxyqc1ChkgHuiWjOm3qfwyv5G9xjFa4SfMurbhV4QWhBzKL2hdUYQAAAABJRU5ErkJggg==</Image>
- <SearchForm>https://wolnelektury.pl</SearchForm>
- <Url method="GET"
- template="https://wolnelektury.pl/katalog/jtags/?mozhint=1&amp;q={searchTerms}"
- type="application/x-suggestions+json" />
- <Url method="GET"
- template="https://wolnelektury.pl/szukaj/?q={searchTerms}"
- type="text/html" />
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-NO.xml b/browser/locales/searchplugins/yahoo-NO.xml
deleted file mode 100644
index 8353adf6b..000000000
--- a/browser/locales/searchplugins/yahoo-NO.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Søk</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://no.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://no.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://no.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-answer-zh-TW.xml b/browser/locales/searchplugins/yahoo-answer-zh-TW.xml
deleted file mode 100644
index a12e7f19d..000000000
--- a/browser/locales/searchplugins/yahoo-answer-zh-TW.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo!奇摩知識+</ShortName>
-<Description>Yahoo!奇摩知識+</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/gif;base64,R0lGODlhEAAQAOYAAAAAAP///3dub4eFh15ZYGZXcWxlgltdakxQXF1ulFJWW1VZXlpeY1xgZWZ2iGtucU5WXVFZYFJYXQB1xwB1xgByw1p5jACd9ACH0wCEzACDywB/ycDo/sfr/8rq/FhhZlhfY7O6vgCb6ACQ1wCJzgCHzaTd+qfe+rXk+7nl+8fs/9Lw/9XZ2+bo6Y3W+I/Y+Z3b+Z3c+Z7c+aDc+aXi/qTe+qfh+6rg+rjj+Lzn+8Pq/Mjs/QCi4wCZ2AWc2R2l3Uy56Fa+6Yjc/ojU9YvX+JDa+JLZ+JXb+Z7c9qrk/Mrt/FzB6L7u/8bd5fP9/+j8/+D8/+b+/+X//+f//+r//+////f//4R/df2bAO6lLf/+/Yh0boNuanBnZq6urv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAF8ALAAAAAAQABAAAAeggF+Cgl4IEREHXoOLghAtAZABLR+MghFaAU5KHiuQDIxejzs3MjAmKFItioMQAVEpNUYuRycdAQuLrVUqQzQvRTM5AQq5AVMVJEBESTY6ARKLoQEZPyUbQRxQqowQVj44SxpIVAEPlRBPPQEUMQEsDZVfXU0YE0wBAwXxX1w8I0IBQOz74mCLiAshCAwkiMWABQELGWa54iDilwQOKg4MBAA7</Image>
-<Url type="text/html" method="GET" template="https://tw.knowledge.search.yahoo.com/search" resultDomain="tw.knowledge.search.yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="fr" value="uh3_answers_web_gs"/>
-</Url>
-<SearchForm>https://tw.answers.yahoo.com/</SearchForm>
-</SearchPlugin>
-
diff --git a/browser/locales/searchplugins/yahoo-ar.xml b/browser/locales/searchplugins/yahoo-ar.xml
deleted file mode 100644
index f855f7fe4..000000000
--- a/browser/locales/searchplugins/yahoo-ar.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo Argentina</ShortName>
-<Description>Buscar en Yahoo Argentina</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://ar.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://ar.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://ar.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-bid-zh-TW.xml b/browser/locales/searchplugins/yahoo-bid-zh-TW.xml
deleted file mode 100644
index b290bed8a..000000000
--- a/browser/locales/searchplugins/yahoo-bid-zh-TW.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo!奇摩æ‹è³£</ShortName>
-<Description>Yahoo!奇摩æ‹è³£</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/gif;base64,R0lGODlhEAAQAMQfAP+7Q4aWvf2QBaKtx//MS+6OLI1MMf/XYv+sKkpalEZNepyUa4KOo2ttjpx4Tdh1ALdrI9lSAHhaVWNSa+Z7Ge9zAPdrALVaIR4/ie9rAOZrELXB0Gtzc/9zCJg+Hf///yH5BAEAAB8ALAAAAAAQABAAAAWM4CeO3xAEA6mKw3IQDrOSAUEAiBPMpXsciIdk1XAUfkCBwKBiAG4IAED5UKg4iGxFWfFgNk0lF+KJWBqribgCwUgKlsRok0hMHvj2YNKJfzYMBxcXE4UTEQkbChlxDT9SBZEUGogBiwkSBFE4khoGcgEJAw0GEBSRBRQUF580CQawsbAJO64Kt7i0KiEAOw==</Image>
-<Url type="text/html" method="GET" template="http://tw.search.bid.yahoo.com/search/ac" resultdomain="bid.yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
-</Url>
-<SearchForm>http://tw.search.bid.yahoo.com/search/ac</SearchForm>
-</SearchPlugin> \ No newline at end of file
diff --git a/browser/locales/searchplugins/yahoo-br.xml b/browser/locales/searchplugins/yahoo-br.xml
deleted file mode 100644
index d22ad16ff..000000000
--- a/browser/locales/searchplugins/yahoo-br.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Pesquisa Yahoo</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://br.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://br.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://br.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-ch.xml b/browser/locales/searchplugins/yahoo-ch.xml
deleted file mode 100644
index 946a8fc38..000000000
--- a/browser/locales/searchplugins/yahoo-ch.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Tschertga Yahoo Svizra</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://ch.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://ch.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://ch.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-cl.xml b/browser/locales/searchplugins/yahoo-cl.xml
deleted file mode 100644
index 4796c87c0..000000000
--- a/browser/locales/searchplugins/yahoo-cl.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Buscar en Yahoo Chile</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://cl.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://cl.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://cl.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-de.xml b/browser/locales/searchplugins/yahoo-de.xml
deleted file mode 100644
index dde138bb8..000000000
--- a/browser/locales/searchplugins/yahoo-de.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://de.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://de.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://de.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-en-CA.xml b/browser/locales/searchplugins/yahoo-en-CA.xml
deleted file mode 100644
index b23af314c..000000000
--- a/browser/locales/searchplugins/yahoo-en-CA.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo Canada</ShortName>
-<Description>Yahoo Canada Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://ca.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://ca.search.yahoo.com/yhs/search"
- resultdomain="yahoo.com" rel="searchform">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="hspart" value="mozilla"/>
- <MozParam name="hsimp" condition="purpose" purpose="searchbar" value="yhs-001"/>
- <MozParam name="hsimp" condition="purpose" purpose="keyword" value="yhs-002"/>
- <MozParam name="hsimp" condition="purpose" purpose="homepage" value="yhs-003"/>
- <MozParam name="hsimp" condition="purpose" purpose="newtab" value="yhs-004"/>
- <MozParam name="hsimp" condition="purpose" purpose="contextmenu" value="yhs-005"/>
- <MozParam name="hsimp" condition="purpose" purpose="system" value="yhs-007"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-en-GB.xml b/browser/locales/searchplugins/yahoo-en-GB.xml
deleted file mode 100644
index 9ac91b9f7..000000000
--- a/browser/locales/searchplugins/yahoo-en-GB.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo.co.uk</ShortName>
-<Description>Yahoo UK &amp; Ireland Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://uk.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://uk.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://uk.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-es.xml b/browser/locales/searchplugins/yahoo-es.xml
deleted file mode 100644
index 7d2137b1c..000000000
--- a/browser/locales/searchplugins/yahoo-es.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://es.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://es.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://es.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-espanol.xml b/browser/locales/searchplugins/yahoo-espanol.xml
deleted file mode 100644
index 33d35abe2..000000000
--- a/browser/locales/searchplugins/yahoo-espanol.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://espanol.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://espanol.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://espanol.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-fi.xml b/browser/locales/searchplugins/yahoo-fi.xml
deleted file mode 100644
index 885118c04..000000000
--- a/browser/locales/searchplugins/yahoo-fi.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo-haku</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://fi.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://fi.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://fi.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-france.xml b/browser/locales/searchplugins/yahoo-france.xml
deleted file mode 100644
index aee1f204a..000000000
--- a/browser/locales/searchplugins/yahoo-france.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Recherche Yahoo</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://fr.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://fr.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://fr.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-fy-NL.xml b/browser/locales/searchplugins/yahoo-fy-NL.xml
deleted file mode 100644
index 3ffc5efeb..000000000
--- a/browser/locales/searchplugins/yahoo-fy-NL.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Sykje mei Yahoo</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://nl.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://nl.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://nl.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-id.xml b/browser/locales/searchplugins/yahoo-id.xml
deleted file mode 100644
index 45e46d249..000000000
--- a/browser/locales/searchplugins/yahoo-id.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Pencarian Yahoo</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://id.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://id.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://id.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-in.xml b/browser/locales/searchplugins/yahoo-in.xml
deleted file mode 100644
index d537aaad3..000000000
--- a/browser/locales/searchplugins/yahoo-in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://in.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://in.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://in.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-it.xml b/browser/locales/searchplugins/yahoo-it.xml
deleted file mode 100644
index 5099a6598..000000000
--- a/browser/locales/searchplugins/yahoo-it.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://it.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://it.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://it.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-jp-auctions.xml b/browser/locales/searchplugins/yahoo-jp-auctions.xml
deleted file mode 100644
index 940ea7fef..000000000
--- a/browser/locales/searchplugins/yahoo-jp-auctions.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ヤフオク!</ShortName>
-<Description>ヤフオク! 検索</Description>
-<InputEncoding>EUC-JP</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAKNJREFUOBHFkVELgzAMhHND2f7/r50oRK/jymEVC31YX5ImuS9pisyMkfMaEVP7fwDWeN8uYcovnp4ILhFAHqBaO8dS/COHDZ/bBiwqO2ChdyOMMRZ4nGC/VwAdHk+qsyzFgv6qIxhrfuEK4mIBBWkA50lcLBGt4pMHe3xOyKXrOeUXXHgeUTkKlfNnNgDSJXJbO1p35huAi3r8yyX2CFUzDNgBKmdd7X70FZwAAAAASUVORK5CYII=</Image>
-<Url type="text/html" method="GET" template="http://auctions.search.yahoo.co.jp/search" resultdomain="yahoo.co.jp">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="EUC-JP"/>
- <Param name="fr" value="mozff" />
- <Param name="rls" value="{moz:distributionID}:ja-JP:{moz:official}"/>
-</Url>
-<SearchForm>http://auctions.yahoo.co.jp/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-jp.xml b/browser/locales/searchplugins/yahoo-jp.xml
deleted file mode 100644
index 7a29e5c19..000000000
--- a/browser/locales/searchplugins/yahoo-jp.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo! JAPAN</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMA/24zAP//MwD//zMA//8zAP//MwD//wAAAAAAAAAAMwD/7TMA/+MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkI//8zAP//MwD/bwAAAAAAAAAAAAAAADEA/zQyAP8pNwD/FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5CP//MwD//zIA/3AAAAAAAAAAAAAAAAAAAAAAMgD/wDIA/6cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AP8sMwD/9zMA//8zAP//NwD/FwAAAAAAAAAAAAAAADQA/3EzAP//MQD/PgAAAAAAAAAAAAAAAAAAAAA3AP8OMwD/2DMA//80AP9PMwD/WjMA//8xAP8qAAAAAAAAAAAyAP8kMwD//zMA/9EAAAAIAAAAAAAAAAAAAAADMwD/tDMA//8yAP+JAAAAAAAAAAAxAP85MwD//zQA/1gAAAAAAAAAADMA/9UzAP//MwD/qQAAAAAAAAAAMgD/kzMA//8zAP/EAAAABAAAAAAAAAAAMwD//zMA//8zAP//MwD//zMA/30xAP8+MwD/+TEA/z4yAP+sMwD//zMA//8zAP//MwD//zMA/5oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AADgZwAA+OMAAPjzAADwcQAA4DAAAMMYAADDAAAAA/8AAP//AAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwD//zMA//8zAP//MwD//zMA//8zAP//MwD//zMA//8zAP//MwD//zMA//8zAP//AAAAAAAAAAAAAAAAMQD/HzQA/2MyAP+iAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyAP+dMwD/9jMA//8zAP//MwD//zMA//8zAP//MwD//zMA//8zAP//MwD//zMA/3gAAAAAAAAAAAAAAAAzAP+/MwD//zMA//80AP9UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAD/JzQA/4ozAP//MwD//zMA//8zAP/nMwD/NzQA/ycxAP8VAAAABAAAAAAAAAAAAAAAADMA/1AzAP//MwD/zjMA/18AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMA//8zAP//MwD//zMA/98AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwD//zMA//8zAP//MwD/3wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUA/yIzAP9zMwD/UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAP//MwD//zMA//8zAP/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAD/njMA//8zAP/pMwD/DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAD/TzMA//8zAP//MwD//zMA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAP9QMwD//zMA//80AP+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg0AP+UMwD//zMA//8zAP//MwD//jIA/1IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4A/wszAP/2MwD//zMA//sxAP8qAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwD/lzMA//8zAP//MwD//zMA/84zAP/5MwD/+TIA/1EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMA/7MzAP//MwD//zQA/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIA/1szAP//MwD//zMA//8zAP/fOQD/EjMA/0EzAP/tMwD//DQA/2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgD/ZTMA//8zAP//MwD//zIA/1IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxAP8vMwD/9TMA//8zAP//MwD/+DEA/zQAAAAAAAAAADUA/yIzAP/UMwD//zMA/5YAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAzAP8ZMwD//TMA//8zAP//MwD/3wAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALgD/FjMA/98zAP//MwD//zMA//8yAP9mAAAAAAAAAAAAAAAAAAAAADMA/w8zAP+4MwD//zMA/8MzAP8ZAAAAAAAAAAAAAAAAAAAAAAAAAAAzAP/IMwD//zMA//8zAP//MgD/fwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYzAP/DMwD//zMA//8zAP//MgD/ogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYzAP+zMwD//zMA/+k0AP9JAAAAAAAAAAAAAAAAAAAAADMA/3kzAP//MwD//zMA//8zAP/2MAD/IAAAAAAAAAAAAAAAAAAAAAAAAAABMwD/pDMA//8zAP//MwD//zMA/9YuAP8LAAAAAAAAAAAAAAAAAAAAAAAAAAA1AP8/NAD/YjMA/5ozAP//MwD//zMA//8zAP+/MwD/gzIA/00wAP8QNQD/KzMA//8zAP//MwD//zMA//8zAP+zAAAAAAAAAAAAAAAAAAAAADMA/40zAP//MwD//zMA//8zAP/3MwD/LQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMA/98zAP/fMwD/3zMA/98zAP/fMwD/3zMA/98zAP/fMwD/3zMA/58AAAAAMwD/3TMA//8zAP/fMwD/kTEA/0MzAP88MgD/YDMA/4IzAP+6MwD//zMA//8zAP//MwD//zMA/7oyAP9HNAD/NjAA/yUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AP9FMgD/LgAAAAAAAAAAAAAAADMA//YzAP//MwD//zMA//8zAP//MwD//zMA//8zAP//MwD//zMA//8zAP//MwD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////////////////////////////////////+ABw//gAcP/+AHD//4fz//+H/H//h/w//wf8P/4D/B/+Af4f/AD+D/gYPgfwPB8H4H4PA8B8AAPA/ACAAD//nAA//////////////////////////////////////////////</Image>
-<Url type="text/html" method="GET" template="http://search.yahoo.co.jp/search" resultdomain="yahoo.co.jp">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="mozff" />
-</Url>
-<SearchForm>http://search.yahoo.co.jp/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-mx.xml b/browser/locales/searchplugins/yahoo-mx.xml
deleted file mode 100644
index 60241a6eb..000000000
--- a/browser/locales/searchplugins/yahoo-mx.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://mx.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://mx.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://mx.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-sv-SE.xml b/browser/locales/searchplugins/yahoo-sv-SE.xml
deleted file mode 100644
index 33eb9f022..000000000
--- a/browser/locales/searchplugins/yahoo-sv-SE.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Sök</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://se.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://se.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://se.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-tl.xml b/browser/locales/searchplugins/yahoo-tl.xml
deleted file mode 100644
index d44fe0849..000000000
--- a/browser/locales/searchplugins/yahoo-tl.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo Search</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://sg.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://sg.search.yahoo.com/search" resultdomain="yahoo.com">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="fr" value="moz35" />
-</Url>
-<SearchForm>https://sg.search.yahoo.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-zh-TW-HK.xml b/browser/locales/searchplugins/yahoo-zh-TW-HK.xml
deleted file mode 100644
index 6b06e8cb2..000000000
--- a/browser/locales/searchplugins/yahoo-zh-TW-HK.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo 雅虎香港</ShortName>
-<Description>Yahoo 雅虎香港</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://hk.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://hk.search.yahoo.com/yhs/search"
- resultdomain="yahoo.com" rel="searchform">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="hspart" value="mozilla"/>
- <MozParam name="hsimp" condition="purpose" purpose="searchbar" value="yhs-001"/>
- <MozParam name="hsimp" condition="purpose" purpose="keyword" value="yhs-002"/>
- <MozParam name="hsimp" condition="purpose" purpose="homepage" value="yhs-003"/>
- <MozParam name="hsimp" condition="purpose" purpose="newtab" value="yhs-004"/>
- <MozParam name="hsimp" condition="purpose" purpose="contextmenu" value="yhs-005"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo-zh-TW.xml b/browser/locales/searchplugins/yahoo-zh-TW.xml
deleted file mode 100644
index b408fa790..000000000
--- a/browser/locales/searchplugins/yahoo-zh-TW.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yahoo</ShortName>
-<Description>Yahoo æœå°‹</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC</Image>
-<Url type="application/x-suggestions+json" method="GET"
- template="https://tw.search.yahoo.com/sugg/ff">
- <Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
- <Param name="command" value="{searchTerms}" />
-</Url>
-<Url type="text/html" method="GET" template="https://tw.search.yahoo.com/yhs/search"
- resultdomain="yahoo.com" rel="searchform">
- <Param name="p" value="{searchTerms}"/>
- <Param name="ei" value="UTF-8"/>
- <Param name="hspart" value="mozilla"/>
- <MozParam name="hsimp" condition="purpose" purpose="searchbar" value="yhs-001"/>
- <MozParam name="hsimp" condition="purpose" purpose="keyword" value="yhs-002"/>
- <MozParam name="hsimp" condition="purpose" purpose="homepage" value="yhs-003"/>
- <MozParam name="hsimp" condition="purpose" purpose="newtab" value="yhs-004"/>
- <MozParam name="hsimp" condition="purpose" purpose="contextmenu" value="yhs-005"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yahoo.xml b/browser/locales/searchplugins/yahoo.xml
index 7337bef92..1c890a208 100644
--- a/browser/locales/searchplugins/yahoo.xml
+++ b/browser/locales/searchplugins/yahoo.xml
@@ -10,19 +10,13 @@
<Url type="application/x-suggestions+json" method="GET"
template="https://search.yahoo.com/sugg/ff">
<Param name="output" value="fxjson" />
- <Param name="appid" value="ffd" />
+ <Param name="appid" value="pmd" />
<Param name="command" value="{searchTerms}" />
</Url>
<Url type="text/html" method="GET" template="https://search.yahoo.com/yhs/search"
resultdomain="yahoo.com" rel="searchform">
<Param name="p" value="{searchTerms}"/>
<Param name="ei" value="UTF-8"/>
- <Param name="hspart" value="mozilla"/>
- <MozParam name="hsimp" condition="purpose" purpose="searchbar" value="yhs-001"/>
- <MozParam name="hsimp" condition="purpose" purpose="keyword" value="yhs-002"/>
- <MozParam name="hsimp" condition="purpose" purpose="homepage" value="yhs-003"/>
- <MozParam name="hsimp" condition="purpose" purpose="newtab" value="yhs-004"/>
- <MozParam name="hsimp" condition="purpose" purpose="contextmenu" value="yhs-005"/>
- <MozParam name="hsimp" condition="purpose" purpose="system" value="yhs-007"/>
+ <Param name="hspart" value="palemoon"/>
</Url>
</SearchPlugin>
diff --git a/browser/locales/searchplugins/yandex-az.xml b/browser/locales/searchplugins/yandex-az.xml
deleted file mode 100644
index 71cb613af..000000000
--- a/browser/locales/searchplugins/yandex-az.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yandex</ShortName>
-<Description>İnternetdə axtarış üçün Yandexdən istifadə edin.</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAB50lEQVQ4T43SvWsacRgH8OcPCITSLRQ6BSRL1gxZTNZQsgYC3QKunVoMnTKFhBQSnDqIUa5gxNbBCgriC4pv50sJ1lIR5SROpRVbz+O4b5/flbvedekJH+557nvfH8chdbvdIFMYPAgBICdqt9uKpmnw8huNRuDnX8J5QKvVgmEYnqiqClmWwZ113kmger0OXdf/Wv6EIb0BTo+AgB94ceDKJ5MJuHPOMwlUqVSwWq1sevQaxqvn0O5l6HdvgaMdV75cLtFoNMC9Xd6JisWiedNiPNuB9l4yZ+1jEvBvuXJBURRwL8YzUT6fx2KxsGHrKdQPCXNW794Bvieu3CLegrsnlM1mMZ/PbfqeH6vToDkvb2+Bx49cuWU2m4G7bUqn0xiPx7ZpqYRf29v4cXyMxf4+tLU1V24ZDAbgbptSqRSGw6HL9OwM37n4bXPTvP6bC7lcDtw9oWQyiX6/b/vMH1XZ2MAoEMDXqytM+QBnLtRqNXAvxjNRPB5Hr9ez9Q8PMfD50OM/2P3FBb7wAc680+mIMri3yzuRJEloNpsmORTCJy7INzd/9stLc7dyIZPJgDvnPJNA0WgU1WrVkxJ/4FgsBu6s804CRSKRh0KhgHK5/F+JRAL8fJBnslA4HH7NHhg8CDnLwm8IYz560xw92AAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.net/suggest-ff.cgi">
- <Param name="part" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://yandex.ru/yandsearch" resultdomain="yandex.ru">
- <Param name="text" value="{searchTerms}"/>
-</Url>
-<SearchForm>https://www.yandex.ru/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yandex-en.xml b/browser/locales/searchplugins/yandex-en.xml
deleted file mode 100644
index ab5975f30..000000000
--- a/browser/locales/searchplugins/yandex-en.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yandex</ShortName>
-<Description>Use Yandex to search the Internet.</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">resource://search-plugins/images/yandex-en.ico</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.com/suggest-ff.cgi">
- <Param name="part" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://www.yandex.com/search">
- <Param name="text" value="{searchTerms}"/>
-</Url>
-<SearchForm>https://www.yandex.com/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yandex-kk.xml b/browser/locales/searchplugins/yandex-kk.xml
deleted file mode 100644
index 23d892617..000000000
--- a/browser/locales/searchplugins/yandex-kk.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ЯндекÑ</ShortName>
-<Description>ВоÑпользуйтеÑÑŒ ЯндекÑом Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка в Интернете.</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAB50lEQVQ4T43SvWsacRgH8OcPCITSLRQ6BSRL1gxZTNZQsgYC3QKunVoMnTKFhBQSnDqIUa5gxNbBCgriC4pv50sJ1lIR5SROpRVbz+O4b5/flbvedekJH+557nvfH8chdbvdIFMYPAgBICdqt9uKpmnw8huNRuDnX8J5QKvVgmEYnqiqClmWwZ113kmger0OXdf/Wv6EIb0BTo+AgB94ceDKJ5MJuHPOMwlUqVSwWq1sevQaxqvn0O5l6HdvgaMdV75cLtFoNMC9Xd6JisWiedNiPNuB9l4yZ+1jEvBvuXJBURRwL8YzUT6fx2KxsGHrKdQPCXNW794Bvieu3CLegrsnlM1mMZ/PbfqeH6vToDkvb2+Bx49cuWU2m4G7bUqn0xiPx7ZpqYRf29v4cXyMxf4+tLU1V24ZDAbgbptSqRSGw6HL9OwM37n4bXPTvP6bC7lcDtw9oWQyiX6/b/vMH1XZ2MAoEMDXqytM+QBnLtRqNXAvxjNRPB5Hr9ez9Q8PMfD50OM/2P3FBb7wAc680+mIMri3yzuRJEloNpsmORTCJy7INzd/9stLc7dyIZPJgDvnPJNA0WgU1WrVkxJ/4FgsBu6s804CRSKRh0KhgHK5/F+JRAL8fJBnslA4HH7NHhg8CDnLwm8IYz560xw92AAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.net/suggest-ff.cgi">
- <Param name="part" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://yandex.kz/yandsearch" resultdomain="yandex.kz">
- <MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
- <MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
- <MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
- <MozParam name="clid" condition="purpose" purpose="homepage" value="2186617"/>
- <MozParam name="clid" condition="purpose" purpose="newtab" value="2186620"/>
- <Param name="text" value="{searchTerms}"/>
-</Url>
-<SearchForm>https://www.yandex.kz/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yandex-ru.xml b/browser/locales/searchplugins/yandex-ru.xml
deleted file mode 100644
index 0f7551303..000000000
--- a/browser/locales/searchplugins/yandex-ru.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ЯндекÑ</ShortName>
-<Description>ВоÑпользуйтеÑÑŒ ЯндекÑом Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка в Интернете.</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAB50lEQVQ4T43SvWsacRgH8OcPCITSLRQ6BSRL1gxZTNZQsgYC3QKunVoMnTKFhBQSnDqIUa5gxNbBCgriC4pv50sJ1lIR5SROpRVbz+O4b5/flbvedekJH+557nvfH8chdbvdIFMYPAgBICdqt9uKpmnw8huNRuDnX8J5QKvVgmEYnqiqClmWwZ113kmger0OXdf/Wv6EIb0BTo+AgB94ceDKJ5MJuHPOMwlUqVSwWq1sevQaxqvn0O5l6HdvgaMdV75cLtFoNMC9Xd6JisWiedNiPNuB9l4yZ+1jEvBvuXJBURRwL8YzUT6fx2KxsGHrKdQPCXNW794Bvieu3CLegrsnlM1mMZ/PbfqeH6vToDkvb2+Bx49cuWU2m4G7bUqn0xiPx7ZpqYRf29v4cXyMxf4+tLU1V24ZDAbgbptSqRSGw6HL9OwM37n4bXPTvP6bC7lcDtw9oWQyiX6/b/vMH1XZ2MAoEMDXqytM+QBnLtRqNXAvxjNRPB5Hr9ez9Q8PMfD50OM/2P3FBb7wAc680+mIMri3yzuRJEloNpsmORTCJy7INzd/9stLc7dyIZPJgDvnPJNA0WgU1WrVkxJ/4FgsBu6s804CRSKRh0KhgHK5/F+JRAL8fJBnslA4HH7NHhg8CDnLwm8IYz560xw92AAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.net/suggest-ff.cgi">
- <Param name="part" value="{searchTerms}"/>
-</Url>
-<Url type="text/html" method="GET" template="https://yandex.ru/yandsearch" resultdomain="yandex.ru">
- <MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
- <MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
- <MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
- <MozParam name="clid" condition="purpose" purpose="homepage" value="2186617"/>
- <MozParam name="clid" condition="purpose" purpose="newtab" value="2186620"/>
- <Param name="text" value="{searchTerms}"/>
-</Url>
-<SearchForm>https://www.yandex.ru/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yandex-tr.xml b/browser/locales/searchplugins/yandex-tr.xml
deleted file mode 100644
index e5f56167a..000000000
--- a/browser/locales/searchplugins/yandex-tr.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Yandex</ShortName>
-<Description>Yandex Türkiye arama motoru</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAAsAAAAUwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAAF8AAABfAAAAXwAAADjBwcEAwcHBAMHBwQDBwcEAAAAAUbq6uurExMT/xMTE/8TExP/ExMT/xMTE/8TExP/ExMT/xMTE/8TExP9ubm6QAAAALcTExADExMQAxMTEAAAAAFrHx8f/x8fH/8fHx/+7u8j/AADS/wAA0v+wsMj/x8fH/8fHx//Hx8f/vr6+7h4eHmQAAAAQx8fHAMfHxwAAAABXy8vL/8vLy//Ly8v/v7/M/wAA2/8AANv/s7PN/8vLy//Ly8v/y8vL/8vLy/+kpKS6AAAAM8vLywDLy8sAAAAAU9DQ0P/Q0ND/0NDQ/8TE0f8AAOX/AADl/7i40v/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/2VlZXsAAAAk0NDQAAAAAE/U1NT/1NTU/9TU1P/IyNb/AADw/wAA8P+7u9f/1NTU/9TU1P/U1NT/1NTU/9TU1P/JycnkDw8PUwAAAAcAAABL2dnZ/9nZ2f/Z2dn/np7i/wAA+f8AAPn/goLm/9nZ2f/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ/6ioqKYAAAAqAAAASOLi4v/i4uL/4uLi/0hI9v8AAP//BQX+/yAg+//f3+L/4uLi/+Li4v/i4uL/4uLi/+Li4v/g4OD7AAAARgAAAETx8fH/8fHx/9jZ8v8LD///HiL+/3h6+P8IDP//lJX3//Hx8f/x8fH/8fHx//Hx8f/x8fH/7+/v+wAAAEIAAABA9vb2//b29v+Ah/v/Ex///3N6+//Z2vf/FiL//ys2/v/r7Pb/9vb2//b29v/29vb/9vb2/8jIyKMAAAAkAAAAPPn5+f/09Pn/NEf+/yA0///Gy/r/+fn5/1hn/f8gNP//jpj8//n5+f/5+fn/+fn5//Dw8OMXFxdBAAAABgAAADj7+/v/tb/8/y5K//9GX///+/v7//v7+/+zvfz/Lkr//zhS///l6Pv/+/v7//v7+/+Tk5NnAAAAGfv7+wAAAAA1/f39/3OM/v85Xf//mqz+//39/f/9/f3/9vf9/0do//85Xf//fpX+//39/f/c3NysAAAAH/39/QD9/f0AAAAAMv7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v+VrP//QWn//0Fp///T3PrtPj4+PgAAAAn+/v4A/v7+AAAAACn39/fi////////////////////////////////////////////////tbW1cgAAABf///8A////AP///wAAAAAVAAAAKAAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAABv///8A////AP///wD///8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAADAAAABwAAAA8AAA==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://suggest.yandex.com.tr/suggest-ff.cgi">
- <Param name="part" value="{searchTerms}"/>
- <Param name="uil" value="tr"/>
-</Url>
-<Url type="text/html" rel="searchform" method="GET" template="http://yandex.com.tr/yandsearch" resultdomain="yandex.com.tr">
- <MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
- <MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
- <MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
- <MozParam name="clid" condition="purpose" purpose="homepage" value="2186617"/>
- <MozParam name="clid" condition="purpose" purpose="newtab" value="2186620"/>
- <Param name="text" value="{searchTerms}"/>
-</Url>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/yandex-uk.xml b/browser/locales/searchplugins/yandex-uk.xml
deleted file mode 100644
index b403a1d8f..000000000
--- a/browser/locales/searchplugins/yandex-uk.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>ЯндекÑ</ShortName>
-<Description>Пошук ЯндекÑом.</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAB50lEQVQ4T43SvWsacRgH8OcPCITSLRQ6BSRL1gxZTNZQsgYC3QKunVoMnTKFhBQSnDqIUa5gxNbBCgriC4pv50sJ1lIR5SROpRVbz+O4b5/flbvedekJH+557nvfH8chdbvdIFMYPAgBICdqt9uKpmnw8huNRuDnX8J5QKvVgmEYnqiqClmWwZ113kmger0OXdf/Wv6EIb0BTo+AgB94ceDKJ5MJuHPOMwlUqVSwWq1sevQaxqvn0O5l6HdvgaMdV75cLtFoNMC9Xd6JisWiedNiPNuB9l4yZ+1jEvBvuXJBURRwL8YzUT6fx2KxsGHrKdQPCXNW794Bvieu3CLegrsnlM1mMZ/PbfqeH6vToDkvb2+Bx49cuWU2m4G7bUqn0xiPx7ZpqYRf29v4cXyMxf4+tLU1V24ZDAbgbptSqRSGw6HL9OwM37n4bXPTvP6bC7lcDtw9oWQyiX6/b/vMH1XZ2MAoEMDXqytM+QBnLtRqNXAvxjNRPB5Hr9ez9Q8PMfD50OM/2P3FBb7wAc680+mIMri3yzuRJEloNpsmORTCJy7INzd/9stLc7dyIZPJgDvnPJNA0WgU1WrVkxJ/4FgsBu6s804CRSKRh0KhgHK5/F+JRAL8fJBnslA4HH7NHhg8CDnLwm8IYz560xw92AAAAABJRU5ErkJggg==</Image>
-<Url type="application/x-suggestions+json" method="GET" template="http://suggest.yandex.net/suggest-ff.cgi?part={searchTerms}"/>
-<Url type="text/html" method="GET" template="http://www.yandex.ua/yandsearch" resultdomain="yandex.ua">
- <Param name="text" value="{searchTerms}"/>
- <Param name="from" value="fx3"/>
-</Url>
-<SearchForm>http://www.yandex.ua/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/zing-mp3.xml b/browser/locales/searchplugins/zing-mp3.xml
deleted file mode 100644
index b669e4675..000000000
--- a/browser/locales/searchplugins/zing-mp3.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>Zing MP3</ShortName>
-<Description>Zing MP3 - Tìm nhạc</Description>
-<InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAA//auAP//1wDspn8A/+aAAMeLYQDYxLAAx5N0ANGANQD/wTIA7+ncAP/GdwD07+QA/9eSAOuqhQD/8b0A1MO8AP/AXwD/1IIAvJeDAMKhkADNrJoAwIlgAP/bPQD/0oAA3cm0AN/JtADroTwAsnZdALB1YADbx7IAxYBZAOabVgD/8ccA/8hjAP//jwD/z3kAvY59AMqVcQD7iDAA/850AODFsAD/w1kAvINzAOesegD/+80AxIliANK4pADFkXUA/8hDAP//2wDEimgAxYJmAP/PSQD/0nsA7rJ7AP//uwDgzLcA/80uAP//7QDRv6sA2pNoAP/FXgD/0jEA/+dqAOeUZQDbv6sA//RvANW7pgC9kYAA//xhAP+4QQDp070AuZaDAP/suADCclMAypqQAP/jPAD//+YAxollANh0PAD/xlQA0YhXAP/UiAD/ryEAx4BNAPOqagD/8skA9J1dAMaKYwDQiGAAuIx3AP/YjgD3uH0AyrCeAM63owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQTSS8AAAAAAAAAAAAAAB03IVddHAAAAAAAAAAAAEUoODICASQlAAAAAAAAAAA0KlNKDw0iHwAAAAAAAAAAQic2TjtcMS4AAAAAAAAAAAApWgMOUj4zAAAAAAAAAAAAAAAAAEgRTwAAW14AAAAAAAAAAAA5UVkAACwwAAAAAAAAAAAAGTUFAB4SJgAAAAAAAAAAAAYXFjxVIwcAAAAAAAAAAABfPwgbRkAVAAAAAAAAAAAAFAk6TUMgAAAAAAAAAAAAACtHVARWGgAAAAAAAAAAAABLCxg9CgAAAAAAAAAAAAAAUC1BDAAAAAAAAAAAAAAAAExYEAAAAAAAAPD/AADgfwAAwD8AAMA/AADAPwAA4D8AAP4zAAD+MwAA/iMAAP4DAAD+AwAA/gcAAP4HAAD+DwAA/h8AAP4/AAA=</Image>
-<Url type="text/html" method="GET" template="http://mp3.zing.vn/mp3/search/do.html" resultdomain="zing.vn">
- <Param name="q" value="{searchTerms}"/>
- <Param name="t" value="0"/>
- <Param name="utm_source" value="firefox"/>
-</Url>
-<SearchForm>http://mp3.zing.vn/</SearchForm>
-</SearchPlugin>
diff --git a/browser/locales/searchplugins/zoznam-sk.xml b/browser/locales/searchplugins/zoznam-sk.xml
deleted file mode 100644
index e2d5501e8..000000000
--- a/browser/locales/searchplugins/zoznam-sk.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
-<ShortName>Zoznam</ShortName>
-<Description>Zoznam slovenskeho internetu</Description>
-<InputEncoding>WINDOWS-1250</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAApUlEQVQ4jWNggIJ/DAz//zEw/D+tKv3/dqT3fwYiASNMMy4FZ1WlGRg4OBgEdDQYVJdvZcRpEswFhPBmTu7/p1Wl4RYyohtCrNMZGBgYmBgYGHE7CYsL0TVjuIBUzUQZgE8zQQMIacZrADGacRpArGasBpCiGcMAUjWjGECOZqg67ABXUl5ta/x/d2o0aoo9bKqNO+3rGv+/7Gr8/3BmNknJnGgAAJxPXsbphIDfAAAAAElFTkSuQmCC</Image>
-<Url type="text/html" method="GET" template="http://www.zoznam.sk/hladaj.fcgi" resultdomain="zoznam.sk">
- <Param name="co" value="odkazy"/>
- <Param name="s" value="{searchTerms}"/>
-</Url>
-<SearchForm>http://www.zoznam.sk/</SearchForm>
-</SearchPlugin>
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index d71305198..852a4c911 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -4,12 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
-XPCSHELL_TESTS_MANIFESTS += [
- 'test/unit/social/xpcshell.ini',
- 'test/xpcshell/xpcshell.ini',
-]
-
EXTRA_JS_MODULES += [
'AboutHome.jsm',
'AboutNewTab.jsm',
diff --git a/browser/modules/test/.eslintrc.js b/browser/modules/test/.eslintrc.js
deleted file mode 100644
index e2d7896f8..000000000
--- a/browser/modules/test/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../testing/mochitest/browser.eslintrc.js"
- ]
-};
diff --git a/browser/modules/test/browser.ini b/browser/modules/test/browser.ini
deleted file mode 100644
index af624439c..000000000
--- a/browser/modules/test/browser.ini
+++ /dev/null
@@ -1,42 +0,0 @@
-[DEFAULT]
-support-files =
- head.js
-
-[browser_BrowserUITelemetry_buckets.js]
-[browser_BrowserUITelemetry_defaults.js]
-[browser_BrowserUITelemetry_sidebar.js]
-[browser_BrowserUITelemetry_syncedtabs.js]
-[browser_ContentSearch.js]
-skip-if = true # Bug 1308343
-support-files =
- contentSearch.js
- contentSearchBadImage.xml
- contentSearchSuggestions.sjs
- contentSearchSuggestions.xml
- !/browser/components/search/test/head.js
- !/browser/components/search/test/testEngine.xml
-[browser_NetworkPrioritizer.js]
-[browser_PermissionUI.js]
-[browser_ProcessHangNotifications.js]
-skip-if = !e10s
-[browser_SelfSupportBackend.js]
-support-files =
- ../../components/uitour/test/uitour.html
- ../../components/uitour/UITour-lib.js
-[browser_taskbar_preview.js]
-skip-if = os != "win"
-[browser_UnsubmittedCrashHandler.js]
-run-if = crashreporter
-[browser_UsageTelemetry.js]
-[browser_UsageTelemetry_private_and_restore.js]
-[browser_UsageTelemetry_urlbar.js]
-support-files =
- usageTelemetrySearchSuggestions.sjs
- usageTelemetrySearchSuggestions.xml
-[browser_UsageTelemetry_searchbar.js]
-support-files =
- usageTelemetrySearchSuggestions.sjs
- usageTelemetrySearchSuggestions.xml
-[browser_UsageTelemetry_content.js]
-[browser_UsageTelemetry_content_aboutHome.js]
-[browser_urlBar_zoom.js]
diff --git a/browser/modules/test/browser_BrowserUITelemetry_buckets.js b/browser/modules/test/browser_BrowserUITelemetry_buckets.js
deleted file mode 100644
index f55761705..000000000
--- a/browser/modules/test/browser_BrowserUITelemetry_buckets.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- WHERE'S MAH BUCKET?!
- \
- ___
- .-9 9 `\
- =(:(::)= ;
- |||| \
- |||| `-.
- ,\|\| `,
- / \
- ; `'---.,
- | `\
- ; / |
- \ | /
- ) \ __,.--\ /
- .-' \,..._\ \` .-' .-'
- `-=`` `: | /-/-/`
- `.__/
-*/
-
-"use strict";
-
-
-add_task(function* testBUIT() {
- let s = {};
- Components.utils.import("resource:///modules/BrowserUITelemetry.jsm", s);
- let BUIT = s.BrowserUITelemetry;
-
- registerCleanupFunction(function() {
- BUIT.setBucket(null);
- });
-
-
- // setBucket
- is(BUIT.currentBucket, BUIT.BUCKET_DEFAULT, "Bucket should be default bucket");
- BUIT.setBucket("mah-bucket");
- is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "mah-bucket", "Bucket should have correct name");
- BUIT.setBucket(null);
- is(BUIT.currentBucket, BUIT.BUCKET_DEFAULT, "Bucket should be reset to default");
-
-
- // _toTimeStr
- is(BUIT._toTimeStr(10), "10ms", "Checking time string reprentation, 10ms");
- is(BUIT._toTimeStr(1000 + 10), "1s10ms", "Checking time string reprentation, 1s10ms");
- is(BUIT._toTimeStr((20 * 1000) + 10), "20s10ms", "Checking time string reprentation, 20s10ms");
- is(BUIT._toTimeStr(60 * 1000), "1m", "Checking time string reprentation, 1m");
- is(BUIT._toTimeStr(3 * 60 * 1000), "3m", "Checking time string reprentation, 3m");
- is(BUIT._toTimeStr((3 * 60 * 1000) + 1), "3m1ms", "Checking time string reprentation, 3m1ms");
- is(BUIT._toTimeStr((60 * 60 * 1000) + (10 * 60 * 1000)), "1h10m", "Checking time string reprentation, 1h10m");
- is(BUIT._toTimeStr(100 * 60 * 60 * 1000), "100h", "Checking time string reprentation, 100h");
-
-
- // setExpiringBucket
- BUIT.setExpiringBucket("walrus", [1001, 2001, 3001, 10001]);
- is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "walrus" + BUIT.BUCKET_SEPARATOR + "1s1ms",
- "Bucket should be expiring and have time step of 1s1ms");
-
- yield waitForConditionPromise(function() {
- return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "walrus" + BUIT.BUCKET_SEPARATOR + "2s1ms");
- }, "Bucket should be expiring and have time step of 2s1ms");
-
- yield waitForConditionPromise(function() {
- return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "walrus" + BUIT.BUCKET_SEPARATOR + "3s1ms");
- }, "Bucket should be expiring and have time step of 3s1ms");
-
-
- // Interupt previous expiring bucket
- BUIT.setExpiringBucket("walrus2", [1002, 2002]);
- is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "walrus2" + BUIT.BUCKET_SEPARATOR + "1s2ms",
- "Should be new expiring bucket, with time step of 1s2ms");
-
- yield waitForConditionPromise(function() {
- return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "walrus2" + BUIT.BUCKET_SEPARATOR + "2s2ms");
- }, "Should be new expiring bucket, with time step of 2s2ms");
-
-
- // Let expiring bucket expire
- yield waitForConditionPromise(function() {
- return BUIT.currentBucket == BUIT.BUCKET_DEFAULT;
- }, "Bucket should have expired, default bucket should now be active");
-
-
- // Interupt expiring bucket with normal bucket
- BUIT.setExpiringBucket("walrus3", [1003, 2003]);
- is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "walrus3" + BUIT.BUCKET_SEPARATOR + "1s3ms",
- "Should be new expiring bucket, with time step of 1s3ms");
-
- BUIT.setBucket("mah-bucket");
- is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "mah-bucket", "Bucket should have correct name");
-
- yield waitForConditionPromise(function() {
- return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "mah-bucket");
- }, "Next step of old expiring bucket shouldn't have progressed");
-});
diff --git a/browser/modules/test/browser_BrowserUITelemetry_defaults.js b/browser/modules/test/browser_BrowserUITelemetry_defaults.js
deleted file mode 100644
index ced1bbce0..000000000
--- a/browser/modules/test/browser_BrowserUITelemetry_defaults.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// The purpose of this test is to ensure that by default, BrowserUITelemetry
-// isn't reporting any UI customizations. This is primarily so changes to
-// customizableUI (eg, new buttons, button location changes) also have a
-// corresponding BrowserUITelemetry change.
-
-function test() {
- let s = {};
- Cu.import("resource:///modules/CustomizableUI.jsm", s);
- Cu.import("resource:///modules/BrowserUITelemetry.jsm", s);
-
- let { CustomizableUI, BrowserUITelemetry } = s;
-
- // Bug 1278176 - DevEdition never has the UI in a default state by default.
- if (!AppConstants.MOZ_DEV_EDITION) {
- Assert.ok(CustomizableUI.inDefaultState,
- "No other test should have left CUI in a dirty state.");
- }
-
- let result = BrowserUITelemetry._getWindowMeasurements(window, 0);
-
- // Bug 1278176 - DevEdition always reports the developer-button is moved.
- if (!AppConstants.MOZ_DEV_EDITION) {
- Assert.deepEqual(result.defaultMoved, []);
- }
- Assert.deepEqual(result.nondefaultAdded, []);
- // This one is a bit weird - the "social-share-button" is dynamically added
- // to the toolbar as the feature is first used - but it's listed as being in
- // the toolbar by default so it doesn't end up in nondefaultAdded once it
- // is created. The end result is that it ends up in defaultRemoved before
- // the feature has been activated.
- // Bug 1273358 exists to fix this.
- Assert.deepEqual(result.defaultRemoved, ["social-share-button"]);
-
- // And mochi insists there's only a single window with a single tab when
- // starting a test, so check that for good measure.
- Assert.deepEqual(result.visibleTabs, [1]);
-}
diff --git a/browser/modules/test/browser_BrowserUITelemetry_sidebar.js b/browser/modules/test/browser_BrowserUITelemetry_sidebar.js
deleted file mode 100644
index 5f19eabd5..000000000
--- a/browser/modules/test/browser_BrowserUITelemetry_sidebar.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// Test the sidebar counters in BrowserUITelemetry.
-"use strict";
-
-const { BrowserUITelemetry: BUIT } = Cu.import("resource:///modules/BrowserUITelemetry.jsm", {});
-
-add_task(function* testSidebarOpenClose() {
- // Reset BrowserUITelemetry's world.
- BUIT._countableEvents = {};
-
- yield SidebarUI.show("viewTabsSidebar");
-
- let counts = BUIT._countableEvents[BUIT.currentBucket];
-
- Assert.deepEqual(counts, { sidebar: { viewTabsSidebar: { show: 1 } } });
- yield SidebarUI.hide();
- Assert.deepEqual(counts, { sidebar: { viewTabsSidebar: { show: 1, hide: 1 } } });
-
- yield SidebarUI.show("viewBookmarksSidebar");
- Assert.deepEqual(counts, {
- sidebar: {
- viewTabsSidebar: { show: 1, hide: 1 },
- viewBookmarksSidebar: { show: 1 },
- }
- });
- // Re-open the tabs sidebar while bookmarks is open - bookmarks should
- // record a close.
- yield SidebarUI.show("viewTabsSidebar");
- Assert.deepEqual(counts, {
- sidebar: {
- viewTabsSidebar: { show: 2, hide: 1 },
- viewBookmarksSidebar: { show: 1, hide: 1 },
- }
- });
- yield SidebarUI.hide();
- Assert.deepEqual(counts, {
- sidebar: {
- viewTabsSidebar: { show: 2, hide: 2 },
- viewBookmarksSidebar: { show: 1, hide: 1 },
- }
- });
- // Toggle - this will re-open viewTabsSidebar
- yield SidebarUI.toggle("viewTabsSidebar");
- Assert.deepEqual(counts, {
- sidebar: {
- viewTabsSidebar: { show: 3, hide: 2 },
- viewBookmarksSidebar: { show: 1, hide: 1 },
- }
- });
- yield SidebarUI.toggle("viewTabsSidebar");
- Assert.deepEqual(counts, {
- sidebar: {
- viewTabsSidebar: { show: 3, hide: 3 },
- viewBookmarksSidebar: { show: 1, hide: 1 },
- }
- });
-});
diff --git a/browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js b/browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js
deleted file mode 100644
index d3e1eac57..000000000
--- a/browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// Test the SyncedTabs counters in BrowserUITelemetry.
-"use strict";
-
-const { BrowserUITelemetry: BUIT } = Cu.import("resource:///modules/BrowserUITelemetry.jsm", {});
-const {SyncedTabs} = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
-
-function mockSyncedTabs() {
- // Mock SyncedTabs.jsm
- let mockedInternal = {
- get isConfiguredToSyncTabs() { return true; },
- getTabClients() {
- return Promise.resolve([
- {
- id: "guid_desktop",
- type: "client",
- name: "My Desktop",
- tabs: [
- {
- title: "http://example.com/10",
- lastUsed: 10, // the most recent
- },
- ],
- }
- ]);
- },
- syncTabs() {
- return Promise.resolve();
- },
- hasSyncedThisSession: true,
- };
-
- let oldInternal = SyncedTabs._internal;
- SyncedTabs._internal = mockedInternal;
-
- // configure our broadcasters so we are in the right state.
- document.getElementById("sync-reauth-state").hidden = true;
- document.getElementById("sync-setup-state").hidden = true;
- document.getElementById("sync-syncnow-state").hidden = false;
-
- registerCleanupFunction(() => {
- SyncedTabs._internal = oldInternal;
-
- document.getElementById("sync-reauth-state").hidden = true;
- document.getElementById("sync-setup-state").hidden = false;
- document.getElementById("sync-syncnow-state").hidden = true;
- });
-}
-
-mockSyncedTabs();
-
-function promiseTabsUpdated() {
- return new Promise(resolve => {
- Services.obs.addObserver(function onNotification(aSubject, aTopic, aData) {
- Services.obs.removeObserver(onNotification, aTopic);
- resolve();
- }, "synced-tabs-menu:test:tabs-updated", false);
- });
-}
-
-add_task(function* test_menu() {
- // Reset BrowserUITelemetry's world.
- BUIT._countableEvents = {};
-
- let tabsUpdated = promiseTabsUpdated();
-
- // check the button's functionality
- yield PanelUI.show();
-
- let syncButton = document.getElementById("sync-button");
- syncButton.click();
-
- yield tabsUpdated;
- // Get our 1 tab and click on it.
- let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
- let tabEntry = tabList.firstChild.nextSibling;
- tabEntry.click();
-
- let counts = BUIT._countableEvents[BUIT.currentBucket];
- Assert.deepEqual(counts, {
- "click-builtin-item": { "sync-button": { left: 1 } },
- "synced-tabs": { open: { "toolbarbutton-subview": 1 } },
- });
-});
-
-add_task(function* test_sidebar() {
- // Reset BrowserUITelemetry's world.
- BUIT._countableEvents = {};
-
- yield SidebarUI.show('viewTabsSidebar');
-
- let syncedTabsDeckComponent = SidebarUI.browser.contentWindow.syncedTabsDeckComponent;
-
- syncedTabsDeckComponent._accountStatus = () => Promise.resolve(true);
-
- // Once the tabs container has been selected (which here means "'selected'
- // added to the class list") we are ready to test.
- let container = SidebarUI.browser.contentDocument.querySelector(".tabs-container");
- let promiseUpdated = BrowserTestUtils.waitForAttribute("class", container);
-
- yield syncedTabsDeckComponent.updatePanel();
- yield promiseUpdated;
-
- let selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected");
- let tab = selectedPanel.querySelector(".tab");
- tab.click();
- let counts = BUIT._countableEvents[BUIT.currentBucket];
- Assert.deepEqual(counts, {
- sidebar: {
- viewTabsSidebar: { show: 1 },
- },
- "synced-tabs": { open: { sidebar: 1 } }
- });
- yield SidebarUI.hide();
-});
diff --git a/browser/modules/test/browser_ContentSearch.js b/browser/modules/test/browser_ContentSearch.js
deleted file mode 100644
index 97bd6ac51..000000000
--- a/browser/modules/test/browser_ContentSearch.js
+++ /dev/null
@@ -1,425 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const TEST_MSG = "ContentSearchTest";
-const CONTENT_SEARCH_MSG = "ContentSearch";
-const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js";
-
-// This timeout is absurdly high to avoid random failures like bug 1087120.
-// That bug was reported when the timeout was 5 seconds, so let's try 10.
-const SUGGESTIONS_TIMEOUT = 10000;
-
-var gMsgMan;
-/* eslint no-undef:"error" */
-/* import-globals-from ../../components/search/test/head.js */
-Services.scriptloader.loadSubScript(
- "chrome://mochitests/content/browser/browser/components/search/test/head.js",
- this);
-
-let originalEngine = Services.search.currentEngine;
-
-add_task(function* setup() {
- yield promiseNewEngine("testEngine.xml", {
- setAsCurrent: true,
- testPath: "chrome://mochitests/content/browser/browser/components/search/test/",
- });
-
- registerCleanupFunction(() => {
- Services.search.currentEngine = originalEngine;
- });
-});
-
-add_task(function* GetState() {
- yield addTab();
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "GetState",
- });
- let msg = yield waitForTestMsg("State");
- checkMsg(msg, {
- type: "State",
- data: yield currentStateObj(),
- });
-});
-
-add_task(function* SetCurrentEngine() {
- yield addTab();
- let newCurrentEngine = null;
- let oldCurrentEngine = Services.search.currentEngine;
- let engines = Services.search.getVisibleEngines();
- for (let engine of engines) {
- if (engine != oldCurrentEngine) {
- newCurrentEngine = engine;
- break;
- }
- }
- if (!newCurrentEngine) {
- info("Couldn't find a non-selected search engine, " +
- "skipping this part of the test");
- return;
- }
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "SetCurrentEngine",
- data: newCurrentEngine.name,
- });
- let deferred = Promise.defer();
- Services.obs.addObserver(function obs(subj, topic, data) {
- info("Test observed " + data);
- if (data == "engine-current") {
- ok(true, "Test observed engine-current");
- Services.obs.removeObserver(obs, "browser-search-engine-modified");
- deferred.resolve();
- }
- }, "browser-search-engine-modified", false);
- let searchPromise = waitForTestMsg("CurrentEngine");
- info("Waiting for test to observe engine-current...");
- yield deferred.promise;
- let msg = yield searchPromise;
- checkMsg(msg, {
- type: "CurrentEngine",
- data: yield currentEngineObj(newCurrentEngine),
- });
-
- Services.search.currentEngine = oldCurrentEngine;
- msg = yield waitForTestMsg("CurrentEngine");
- checkMsg(msg, {
- type: "CurrentEngine",
- data: yield currentEngineObj(oldCurrentEngine),
- });
-});
-
-add_task(function* modifyEngine() {
- yield addTab();
- let engine = Services.search.currentEngine;
- let oldAlias = engine.alias;
- engine.alias = "ContentSearchTest";
- let msg = yield waitForTestMsg("CurrentState");
- checkMsg(msg, {
- type: "CurrentState",
- data: yield currentStateObj(),
- });
- engine.alias = oldAlias;
- msg = yield waitForTestMsg("CurrentState");
- checkMsg(msg, {
- type: "CurrentState",
- data: yield currentStateObj(),
- });
-});
-
-add_task(function* search() {
- yield addTab();
- let engine = Services.search.currentEngine;
- let data = {
- engineName: engine.name,
- searchString: "ContentSearchTest",
- healthReportKey: "ContentSearchTest",
- searchPurpose: "ContentSearchTest",
- };
- let submissionURL =
- engine.getSubmission(data.searchString, "", data.whence).uri.spec;
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "Search",
- data: data,
- expectedURL: submissionURL,
- });
- let msg = yield waitForTestMsg("loadStopped");
- Assert.equal(msg.data.url, submissionURL, "Correct search page loaded");
-});
-
-add_task(function* searchInBackgroundTab() {
- // This test is like search(), but it opens a new tab after starting a search
- // in another. In other words, it performs a search in a background tab. The
- // search page should be loaded in the same tab that performed the search, in
- // the background tab.
- yield addTab();
- let engine = Services.search.currentEngine;
- let data = {
- engineName: engine.name,
- searchString: "ContentSearchTest",
- healthReportKey: "ContentSearchTest",
- searchPurpose: "ContentSearchTest",
- };
- let submissionURL =
- engine.getSubmission(data.searchString, "", data.whence).uri.spec;
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "Search",
- data: data,
- expectedURL: submissionURL,
- });
-
- let newTab = gBrowser.addTab();
- gBrowser.selectedTab = newTab;
- registerCleanupFunction(() => gBrowser.removeTab(newTab));
-
- let msg = yield waitForTestMsg("loadStopped");
- Assert.equal(msg.data.url, submissionURL, "Correct search page loaded");
-});
-
-add_task(function* badImage() {
- yield addTab();
- // If the bad image URI caused an exception to be thrown within ContentSearch,
- // then we'll hang waiting for the CurrentState responses triggered by the new
- // engine. That's what we're testing, and obviously it shouldn't happen.
- let vals = yield waitForNewEngine("contentSearchBadImage.xml", 1);
- let engine = vals[0];
- let finalCurrentStateMsg = vals[vals.length - 1];
- let expectedCurrentState = yield currentStateObj();
- let expectedEngine =
- expectedCurrentState.engines.find(e => e.name == engine.name);
- ok(!!expectedEngine, "Sanity check: engine should be in expected state");
- ok(expectedEngine.iconBuffer === null,
- "Sanity check: icon array buffer of engine in expected state " +
- "should be null: " + expectedEngine.iconBuffer);
- checkMsg(finalCurrentStateMsg, {
- type: "CurrentState",
- data: expectedCurrentState,
- });
- // Removing the engine triggers a final CurrentState message. Wait for it so
- // it doesn't trip up subsequent tests.
- Services.search.removeEngine(engine);
- yield waitForTestMsg("CurrentState");
-});
-
-add_task(function* GetSuggestions_AddFormHistoryEntry_RemoveFormHistoryEntry() {
- yield addTab();
-
- // Add the test engine that provides suggestions.
- let vals = yield waitForNewEngine("contentSearchSuggestions.xml", 0);
- let engine = vals[0];
-
- let searchStr = "browser_ContentSearch.js-suggestions-";
-
- // Add a form history suggestion and wait for Satchel to notify about it.
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "AddFormHistoryEntry",
- data: searchStr + "form",
- });
- let deferred = Promise.defer();
- Services.obs.addObserver(function onAdd(subj, topic, data) {
- if (data == "formhistory-add") {
- Services.obs.removeObserver(onAdd, "satchel-storage-changed");
- executeSoon(() => deferred.resolve());
- }
- }, "satchel-storage-changed", false);
- yield deferred.promise;
-
- // Send GetSuggestions using the test engine. Its suggestions should appear
- // in the remote suggestions in the Suggestions response below.
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "GetSuggestions",
- data: {
- engineName: engine.name,
- searchString: searchStr,
- remoteTimeout: SUGGESTIONS_TIMEOUT,
- },
- });
-
- // Check the Suggestions response.
- let msg = yield waitForTestMsg("Suggestions");
- checkMsg(msg, {
- type: "Suggestions",
- data: {
- engineName: engine.name,
- searchString: searchStr,
- formHistory: [searchStr + "form"],
- remote: [searchStr + "foo", searchStr + "bar"],
- },
- });
-
- // Delete the form history suggestion and wait for Satchel to notify about it.
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "RemoveFormHistoryEntry",
- data: searchStr + "form",
- });
- deferred = Promise.defer();
- Services.obs.addObserver(function onRemove(subj, topic, data) {
- if (data == "formhistory-remove") {
- Services.obs.removeObserver(onRemove, "satchel-storage-changed");
- executeSoon(() => deferred.resolve());
- }
- }, "satchel-storage-changed", false);
- yield deferred.promise;
-
- // Send GetSuggestions again.
- gMsgMan.sendAsyncMessage(TEST_MSG, {
- type: "GetSuggestions",
- data: {
- engineName: engine.name,
- searchString: searchStr,
- remoteTimeout: SUGGESTIONS_TIMEOUT,
- },
- });
-
- // The formHistory suggestions in the Suggestions response should be empty.
- msg = yield waitForTestMsg("Suggestions");
- checkMsg(msg, {
- type: "Suggestions",
- data: {
- engineName: engine.name,
- searchString: searchStr,
- formHistory: [],
- remote: [searchStr + "foo", searchStr + "bar"],
- },
- });
-
- // Finally, clean up by removing the test engine.
- Services.search.removeEngine(engine);
- yield waitForTestMsg("CurrentState");
-});
-
-function buffersEqual(actualArrayBuffer, expectedArrayBuffer) {
- let expectedView = new Int8Array(expectedArrayBuffer);
- let actualView = new Int8Array(actualArrayBuffer);
- for (let i = 0; i < expectedView.length; i++) {
- if (actualView[i] != expectedView[i]) {
- return false;
- }
- }
- return true;
-}
-
-function arrayBufferEqual(actualArrayBuffer, expectedArrayBuffer) {
- ok(actualArrayBuffer instanceof ArrayBuffer, "Actual value is ArrayBuffer.");
- ok(expectedArrayBuffer instanceof ArrayBuffer, "Expected value is ArrayBuffer.");
- Assert.equal(actualArrayBuffer.byteLength, expectedArrayBuffer.byteLength,
- "Array buffers have the same length.");
- ok(buffersEqual(actualArrayBuffer, expectedArrayBuffer), "Buffers are equal.");
-}
-
-function checkArrayBuffers(actual, expected) {
- if (actual instanceof ArrayBuffer) {
- arrayBufferEqual(actual, expected);
- }
- if (typeof actual == "object") {
- for (let i in actual) {
- checkArrayBuffers(actual[i], expected[i]);
- }
- }
-}
-
-function checkMsg(actualMsg, expectedMsgData) {
- let actualMsgData = actualMsg.data;
- SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message");
-
- // Engines contain ArrayBuffers which we have to compare byte by byte and
- // not as Objects (like SimpleTest.isDeeply does).
- checkArrayBuffers(actualMsgData, expectedMsgData);
-}
-
-function waitForMsg(name, type) {
- let deferred = Promise.defer();
- info("Waiting for " + name + " message " + type + "...");
- gMsgMan.addMessageListener(name, function onMsg(msg) {
- info("Received " + name + " message " + msg.data.type + "\n");
- if (msg.data.type == type) {
- gMsgMan.removeMessageListener(name, onMsg);
- deferred.resolve(msg);
- }
- });
- return deferred.promise;
-}
-
-function waitForTestMsg(type) {
- return waitForMsg(TEST_MSG, type);
-}
-
-function waitForNewEngine(basename, numImages) {
- info("Waiting for engine to be added: " + basename);
-
- // Wait for the search events triggered by adding the new engine.
- // engine-added engine-loaded
- let expectedSearchEvents = ["CurrentState", "CurrentState"];
- // engine-changed for each of the images
- for (let i = 0; i < numImages; i++) {
- expectedSearchEvents.push("CurrentState");
- }
- let eventPromises = expectedSearchEvents.map(e => waitForTestMsg(e));
-
- // Wait for addEngine().
- let addDeferred = Promise.defer();
- let url = getRootDirectory(gTestPath) + basename;
- Services.search.addEngine(url, null, "", false, {
- onSuccess: function (engine) {
- info("Search engine added: " + basename);
- addDeferred.resolve(engine);
- },
- onError: function (errCode) {
- ok(false, "addEngine failed with error code " + errCode);
- addDeferred.reject();
- },
- });
-
- return Promise.all([addDeferred.promise].concat(eventPromises));
-}
-
-function addTab() {
- let deferred = Promise.defer();
- let tab = gBrowser.addTab();
- gBrowser.selectedTab = tab;
- tab.linkedBrowser.addEventListener("load", function load() {
- tab.linkedBrowser.removeEventListener("load", load, true);
- let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
- gMsgMan = tab.linkedBrowser.messageManager;
- gMsgMan.sendAsyncMessage(CONTENT_SEARCH_MSG, {
- type: "AddToWhitelist",
- data: ["about:blank"],
- });
- waitForMsg(CONTENT_SEARCH_MSG, "AddToWhitelistAck").then(() => {
- gMsgMan.loadFrameScript(url, false);
- deferred.resolve();
- });
- }, true);
- registerCleanupFunction(() => gBrowser.removeTab(tab));
- return deferred.promise;
-}
-
-var currentStateObj = Task.async(function* () {
- let state = {
- engines: [],
- currentEngine: yield currentEngineObj(),
- };
- for (let engine of Services.search.getVisibleEngines()) {
- let uri = engine.getIconURLBySize(16, 16);
- state.engines.push({
- name: engine.name,
- iconBuffer: yield arrayBufferFromDataURI(uri),
- hidden: false,
- });
- }
- return state;
-});
-
-var currentEngineObj = Task.async(function* () {
- let engine = Services.search.currentEngine;
- let uriFavicon = engine.getIconURLBySize(16, 16);
- let bundle = Services.strings.createBundle("chrome://global/locale/autocomplete.properties");
- return {
- name: engine.name,
- placeholder: bundle.formatStringFromName("searchWithEngine", [engine.name], 1),
- iconBuffer: yield arrayBufferFromDataURI(uriFavicon),
- };
-});
-
-function arrayBufferFromDataURI(uri) {
- if (!uri) {
- return Promise.resolve(null);
- }
- let deferred = Promise.defer();
- let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance(Ci.nsIXMLHttpRequest);
- xhr.open("GET", uri, true);
- xhr.responseType = "arraybuffer";
- xhr.onerror = () => {
- deferred.resolve(null);
- };
- xhr.onload = () => {
- deferred.resolve(xhr.response);
- };
- try {
- xhr.send();
- }
- catch (err) {
- return Promise.resolve(null);
- }
- return deferred.promise;
-}
diff --git a/browser/modules/test/browser_NetworkPrioritizer.js b/browser/modules/test/browser_NetworkPrioritizer.js
deleted file mode 100644
index 91557b0fd..000000000
--- a/browser/modules/test/browser_NetworkPrioritizer.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/** Tests for NetworkPrioritizer.jsm (Bug 514490) **/
-
-const LOWEST = Ci.nsISupportsPriority.PRIORITY_LOWEST;
-const LOW = Ci.nsISupportsPriority.PRIORITY_LOW;
-const NORMAL = Ci.nsISupportsPriority.PRIORITY_NORMAL;
-const HIGH = Ci.nsISupportsPriority.PRIORITY_HIGH;
-const HIGHEST = Ci.nsISupportsPriority.PRIORITY_HIGHEST;
-
-const DELTA = NORMAL - LOW; // lower value means higher priority
-
-// Test helper functions.
-// getPriority and setPriority can take a tab or a Browser
-function* getPriority(aBrowser) {
- if (aBrowser.localName == "tab")
- aBrowser = aBrowser.linkedBrowser;
-
- return yield ContentTask.spawn(aBrowser, null, function* () {
- return docShell.QueryInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsIDocumentLoader)
- .loadGroup
- .QueryInterface(Components.interfaces.nsISupportsPriority)
- .priority;
- });
-}
-
-function* setPriority(aBrowser, aPriority) {
- if (aBrowser.localName == "tab")
- aBrowser = aBrowser.linkedBrowser;
-
- yield ContentTask.spawn(aBrowser, aPriority, function* (aPriority) {
- docShell.QueryInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsIDocumentLoader)
- .loadGroup
- .QueryInterface(Ci.nsISupportsPriority)
- .priority = aPriority;
- });
-}
-
-function* isWindowState(aWindow, aTabPriorities) {
- let browsers = aWindow.gBrowser.browsers;
- // Make sure we have the right number of tabs & priorities
- is(browsers.length, aTabPriorities.length,
- "Window has expected number of tabs");
- // aState should be in format [ priority, priority, priority ]
- for (let i = 0; i < browsers.length; i++) {
- is(yield getPriority(browsers[i]), aTabPriorities[i],
- "Tab " + i + " had expected priority");
- }
-}
-
-function promiseWaitForFocus(aWindow) {
- return new Promise((resolve) => {
- waitForFocus(resolve, aWindow);
- });
-}
-
-add_task(function*() {
- // This is the real test. It creates multiple tabs & windows, changes focus,
- // closes windows/tabs to make sure we behave correctly.
- // This test assumes that no priorities have been adjusted and the loadgroup
- // priority starts at 0.
-
- // Call window "window_A" to make the test easier to follow
- let window_A = window;
-
- // Test 1 window, 1 tab case.
- yield isWindowState(window_A, [HIGH]);
-
- // Exising tab is tab_A1
- let tab_A2 = window_A.gBrowser.addTab("http://example.com");
- let tab_A3 = window_A.gBrowser.addTab("about:config");
- yield BrowserTestUtils.browserLoaded(tab_A3.linkedBrowser);
-
- // tab_A2 isn't focused yet
- yield isWindowState(window_A, [HIGH, NORMAL, NORMAL]);
-
- // focus tab_A2 & make sure priority got updated
- window_A.gBrowser.selectedTab = tab_A2;
- yield isWindowState(window_A, [NORMAL, HIGH, NORMAL]);
-
- window_A.gBrowser.removeTab(tab_A2);
- // Next tab is auto selected synchronously as part of removeTab, and we
- // expect the priority to be updated immediately.
- yield isWindowState(window_A, [NORMAL, HIGH]);
-
- // Open another window then play with focus
- let window_B = yield BrowserTestUtils.openNewBrowserWindow();
-
- yield promiseWaitForFocus(window_B);
- yield isWindowState(window_A, [LOW, NORMAL]);
- yield isWindowState(window_B, [HIGH]);
-
- yield promiseWaitForFocus(window_A);
- yield isWindowState(window_A, [NORMAL, HIGH]);
- yield isWindowState(window_B, [NORMAL]);
-
- yield promiseWaitForFocus(window_B);
- yield isWindowState(window_A, [LOW, NORMAL]);
- yield isWindowState(window_B, [HIGH]);
-
- // Cleanup
- window_A.gBrowser.removeTab(tab_A3);
- yield BrowserTestUtils.closeWindow(window_B);
-});
-
-add_task(function*() {
- // This is more a test of nsLoadGroup and how it handles priorities. But since
- // we depend on its behavior, it's good to test it. This is testing that there
- // are no errors if we adjust beyond nsISupportsPriority's bounds.
-
- yield promiseWaitForFocus();
-
- let tab1 = gBrowser.tabs[0];
- let oldPriority = yield getPriority(tab1);
-
- // Set the priority of tab1 to the lowest possible. Selecting the other tab
- // will try to lower it
- yield setPriority(tab1, LOWEST);
-
- let tab2 = gBrowser.addTab("http://example.com");
- yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
- gBrowser.selectedTab = tab2;
- is(yield getPriority(tab1), LOWEST - DELTA, "Can adjust priority beyond 'lowest'");
-
- // Now set priority to "highest" and make sure that no errors occur.
- yield setPriority(tab1, HIGHEST);
- gBrowser.selectedTab = tab1;
-
- is(yield getPriority(tab1), HIGHEST + DELTA, "Can adjust priority beyond 'highest'");
-
- // Cleanup
- gBrowser.removeTab(tab2);
- yield setPriority(tab1, oldPriority);
-});
-
-add_task(function*() {
- // This tests that the priority doesn't get lost when switching the browser's remoteness
-
- if (!gMultiProcessBrowser) {
- return;
- }
-
- let browser = gBrowser.selectedBrowser;
-
- browser.loadURI("http://example.com");
- yield BrowserTestUtils.browserLoaded(browser);
- ok(browser.isRemoteBrowser, "web page should be loaded in remote browser");
- is(yield getPriority(browser), HIGH, "priority of selected tab should be 'high'");
-
- browser.loadURI("about:rights");
- yield BrowserTestUtils.browserLoaded(browser);
- ok(!browser.isRemoteBrowser, "about:rights should switch browser to non-remote");
- is(yield getPriority(browser), HIGH,
- "priority of selected tab should be 'high' when going from remote to non-remote");
-
- browser.loadURI("http://example.com");
- yield BrowserTestUtils.browserLoaded(browser);
- ok(browser.isRemoteBrowser, "going from about:rights to web page should switch browser to remote");
- is(yield getPriority(browser), HIGH,
- "priority of selected tab should be 'high' when going from non-remote to remote");
-});
diff --git a/browser/modules/test/browser_PermissionUI.js b/browser/modules/test/browser_PermissionUI.js
deleted file mode 100644
index 006bc5e66..000000000
--- a/browser/modules/test/browser_PermissionUI.js
+++ /dev/null
@@ -1,445 +0,0 @@
-/**
- * These tests test the ability for the PermissionUI module to open
- * permission prompts to the user. It also tests to ensure that
- * add-ons can introduce their own permission prompts.
- */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Integration.jsm", this);
-Cu.import("resource:///modules/PermissionUI.jsm", this);
-
-/**
- * Given a <xul:browser> at some non-internal web page,
- * return something that resembles an nsIContentPermissionRequest,
- * using the browsers currently loaded document to get a principal.
- *
- * @param browser (<xul:browser>)
- * The browser that we'll create a nsIContentPermissionRequest
- * for.
- * @returns A nsIContentPermissionRequest-ish object.
- */
-function makeMockPermissionRequest(browser) {
- let result = {
- types: null,
- principal: browser.contentPrincipal,
- requester: null,
- _cancelled: false,
- cancel() {
- this._cancelled = true;
- },
- _allowed: false,
- allow() {
- this._allowed = true;
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
- };
-
- // In the e10s-case, nsIContentPermissionRequest will have
- // element defined. window is defined otherwise.
- if (browser.isRemoteBrowser) {
- result.element = browser;
- } else {
- result.window = browser.contentWindow;
- }
-
- return result;
-}
-
-/**
- * For an opened PopupNotification, clicks on the main action,
- * and waits for the panel to fully close.
- *
- * @return {Promise}
- * Resolves once the panel has fired the "popuphidden"
- * event.
- */
-function clickMainAction() {
- let removePromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- let popupNotification = getPopupNotificationNode();
- popupNotification.button.click();
- return removePromise;
-}
-
-/**
- * For an opened PopupNotification, clicks on a secondary action,
- * and waits for the panel to fully close.
- *
- * @param {int} index
- * The 0-indexed index of the secondary menuitem to choose.
- * @return {Promise}
- * Resolves once the panel has fired the "popuphidden"
- * event.
- */
-function clickSecondaryAction(index) {
- let removePromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- let popupNotification = getPopupNotificationNode();
- let menuitems = popupNotification.children;
- menuitems[index].click();
- return removePromise;
-}
-
-/**
- * Makes sure that 1 (and only 1) <xul:popupnotification> is being displayed
- * by PopupNotification, and then returns that <xul:popupnotification>.
- *
- * @return {<xul:popupnotification>}
- */
-function getPopupNotificationNode() {
- // PopupNotification is a bit overloaded here, so to be
- // clear, popupNotifications is a list of <xul:popupnotification>
- // nodes.
- let popupNotifications = PopupNotifications.panel.childNodes;
- Assert.equal(popupNotifications.length, 1,
- "Should be showing a <xul:popupnotification>");
- return popupNotifications[0];
-}
-
-/**
- * Tests the PermissionPromptForRequest prototype to ensure that a prompt
- * can be displayed. Does not test permission handling.
- */
-add_task(function* test_permission_prompt_for_request() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com/",
- }, function*(browser) {
- const kTestNotificationID = "test-notification";
- const kTestMessage = "Test message";
- let mainAction = {
- label: "Main",
- accessKey: "M",
- };
- let secondaryAction = {
- label: "Secondary",
- accessKey: "S",
- };
-
- let mockRequest = makeMockPermissionRequest(browser);
- let TestPrompt = {
- __proto__: PermissionUI.PermissionPromptForRequestPrototype,
- request: mockRequest,
- notificationID: kTestNotificationID,
- message: kTestMessage,
- promptActions: [mainAction, secondaryAction],
- };
-
- let shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- yield shownPromise;
- let notification =
- PopupNotifications.getNotification(kTestNotificationID, browser);
- Assert.ok(notification, "Should have gotten the notification");
-
- Assert.equal(notification.message, kTestMessage,
- "Should be showing the right message");
- Assert.equal(notification.mainAction.label, mainAction.label,
- "The main action should have the right label");
- Assert.equal(notification.mainAction.accessKey, mainAction.accessKey,
- "The main action should have the right access key");
- Assert.equal(notification.secondaryActions.length, 1,
- "There should only be 1 secondary action");
- Assert.equal(notification.secondaryActions[0].label, secondaryAction.label,
- "The secondary action should have the right label");
- Assert.equal(notification.secondaryActions[0].accessKey,
- secondaryAction.accessKey,
- "The secondary action should have the right access key");
- Assert.ok(notification.options.displayURI.equals(mockRequest.principal.URI),
- "Should be showing the URI of the requesting page");
-
- let removePromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- notification.remove();
- yield removePromise;
- });
-});
-
-/**
- * Tests that if the PermissionPrompt sets displayURI to false in popupOptions,
- * then there is no URI shown on the popupnotification.
- */
-add_task(function* test_permission_prompt_for_popupOptions() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com/",
- }, function*(browser) {
- const kTestNotificationID = "test-notification";
- const kTestMessage = "Test message";
- let mainAction = {
- label: "Main",
- accessKey: "M",
- };
- let secondaryAction = {
- label: "Secondary",
- accessKey: "S",
- };
-
- let mockRequest = makeMockPermissionRequest(browser);
- let TestPrompt = {
- __proto__: PermissionUI.PermissionPromptForRequestPrototype,
- request: mockRequest,
- notificationID: kTestNotificationID,
- message: kTestMessage,
- promptActions: [mainAction, secondaryAction],
- popupOptions: {
- displayURI: false,
- },
- };
-
- let shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- yield shownPromise;
- let notification =
- PopupNotifications.getNotification(kTestNotificationID, browser);
-
- Assert.ok(!notification.options.displayURI,
- "Should not show the URI of the requesting page");
-
- let removePromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- notification.remove();
- yield removePromise;
- });
-});
-
-/**
- * Tests that if the PermissionPrompt has the permissionKey
- * set that permissions can be set properly by the user. Also
- * ensures that callbacks for promptActions are properly fired.
- */
-add_task(function* test_with_permission_key() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com",
- }, function*(browser) {
- const kTestNotificationID = "test-notification";
- const kTestMessage = "Test message";
- const kTestPermissionKey = "test-permission-key";
-
- let allowed = false;
- let mainAction = {
- label: "Allow",
- accessKey: "M",
- action: Ci.nsIPermissionManager.ALLOW_ACTION,
- expiryType: Ci.nsIPermissionManager.EXPIRE_SESSION,
- callback: function() {
- allowed = true;
- }
- };
-
- let denied = false;
- let secondaryAction = {
- label: "Deny",
- accessKey: "D",
- action: Ci.nsIPermissionManager.DENY_ACTION,
- expiryType: Ci.nsIPermissionManager.EXPIRE_SESSION,
- callback: function() {
- denied = true;
- }
- };
-
- let mockRequest = makeMockPermissionRequest(browser);
- let principal = mockRequest.principal;
- registerCleanupFunction(function() {
- Services.perms.removeFromPrincipal(principal, kTestPermissionKey);
- });
-
- let TestPrompt = {
- __proto__: PermissionUI.PermissionPromptForRequestPrototype,
- request: mockRequest,
- notificationID: kTestNotificationID,
- permissionKey: kTestPermissionKey,
- message: kTestMessage,
- promptActions: [mainAction, secondaryAction],
- };
-
- let shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- yield shownPromise;
- let notification =
- PopupNotifications.getNotification(kTestNotificationID, browser);
- Assert.ok(notification, "Should have gotten the notification");
-
- let curPerm =
- Services.perms.testPermissionFromPrincipal(principal,
- kTestPermissionKey);
- Assert.equal(curPerm, Ci.nsIPermissionManager.UNKNOWN_ACTION,
- "Should be no permission set to begin with.");
-
- // First test denying the permission request.
- Assert.equal(notification.secondaryActions.length, 1,
- "There should only be 1 secondary action");
- yield clickSecondaryAction(0);
- curPerm = Services.perms.testPermissionFromPrincipal(principal,
- kTestPermissionKey);
- Assert.equal(curPerm, Ci.nsIPermissionManager.DENY_ACTION,
- "Should have denied the action");
- Assert.ok(denied, "The secondaryAction callback should have fired");
- Assert.ok(!allowed, "The mainAction callback should not have fired");
- Assert.ok(mockRequest._cancelled,
- "The request should have been cancelled");
- Assert.ok(!mockRequest._allowed,
- "The request should not have been allowed");
-
- // Clear the permission and pretend we never denied
- Services.perms.removeFromPrincipal(principal, kTestPermissionKey);
- denied = false;
- mockRequest._cancelled = false;
-
- // Bring the PopupNotification back up now...
- shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- yield shownPromise;
-
- // Next test allowing the permission request.
- yield clickMainAction();
- curPerm = Services.perms.testPermissionFromPrincipal(principal,
- kTestPermissionKey);
- Assert.equal(curPerm, Ci.nsIPermissionManager.ALLOW_ACTION,
- "Should have allowed the action");
- Assert.ok(!denied, "The secondaryAction callback should not have fired");
- Assert.ok(allowed, "The mainAction callback should have fired");
- Assert.ok(!mockRequest._cancelled,
- "The request should not have been cancelled");
- Assert.ok(mockRequest._allowed,
- "The request should have been allowed");
- });
-});
-
-/**
- * Tests that the onBeforeShow method will be called before
- * the popup appears.
- */
-add_task(function* test_on_before_show() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com",
- }, function*(browser) {
- const kTestNotificationID = "test-notification";
- const kTestMessage = "Test message";
-
- let mainAction = {
- label: "Test action",
- accessKey: "T",
- };
-
- let mockRequest = makeMockPermissionRequest(browser);
- let beforeShown = false;
-
- let TestPrompt = {
- __proto__: PermissionUI.PermissionPromptForRequestPrototype,
- request: mockRequest,
- notificationID: kTestNotificationID,
- message: kTestMessage,
- promptActions: [mainAction],
- onBeforeShow() {
- beforeShown = true;
- }
- };
-
- let shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- Assert.ok(beforeShown, "Should have called onBeforeShown");
- yield shownPromise;
- let notification =
- PopupNotifications.getNotification(kTestNotificationID, browser);
-
- let removePromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- notification.remove();
- yield removePromise;
- });
-});
-
-/**
- * Tests that we can open a PermissionPrompt without wrapping a
- * nsIContentPermissionRequest.
- */
-add_task(function* test_no_request() {
- yield BrowserTestUtils.withNewTab({
- gBrowser,
- url: "http://example.com",
- }, function*(browser) {
- const kTestNotificationID = "test-notification";
- let allowed = false;
- let mainAction = {
- label: "Allow",
- accessKey: "M",
- callback: function() {
- allowed = true;
- }
- };
-
- let denied = false;
- let secondaryAction = {
- label: "Deny",
- accessKey: "D",
- callback: function() {
- denied = true;
- }
- };
-
- const kTestMessage = "Test message with no request";
- let principal = browser.contentPrincipal;
- let beforeShown = false;
-
- let TestPrompt = {
- __proto__: PermissionUI.PermissionPromptPrototype,
- notificationID: kTestNotificationID,
- principal,
- browser,
- message: kTestMessage,
- promptActions: [mainAction, secondaryAction],
- onBeforeShow() {
- beforeShown = true;
- }
- };
-
- let shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- Assert.ok(beforeShown, "Should have called onBeforeShown");
- yield shownPromise;
- let notification =
- PopupNotifications.getNotification(kTestNotificationID, browser);
-
- Assert.equal(notification.message, kTestMessage,
- "Should be showing the right message");
- Assert.equal(notification.mainAction.label, mainAction.label,
- "The main action should have the right label");
- Assert.equal(notification.mainAction.accessKey, mainAction.accessKey,
- "The main action should have the right access key");
- Assert.equal(notification.secondaryActions.length, 1,
- "There should only be 1 secondary action");
- Assert.equal(notification.secondaryActions[0].label, secondaryAction.label,
- "The secondary action should have the right label");
- Assert.equal(notification.secondaryActions[0].accessKey,
- secondaryAction.accessKey,
- "The secondary action should have the right access key");
- Assert.ok(notification.options.displayURI.equals(principal.URI),
- "Should be showing the URI of the requesting page");
-
- // First test denying the permission request.
- Assert.equal(notification.secondaryActions.length, 1,
- "There should only be 1 secondary action");
- yield clickSecondaryAction(0);
- Assert.ok(denied, "The secondaryAction callback should have fired");
- Assert.ok(!allowed, "The mainAction callback should not have fired");
-
- shownPromise =
- BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- TestPrompt.prompt();
- yield shownPromise;
-
- // Next test allowing the permission request.
- yield clickMainAction();
- Assert.ok(allowed, "The mainAction callback should have fired");
- });
-});
diff --git a/browser/modules/test/browser_ProcessHangNotifications.js b/browser/modules/test/browser_ProcessHangNotifications.js
deleted file mode 100644
index 597be611a..000000000
--- a/browser/modules/test/browser_ProcessHangNotifications.js
+++ /dev/null
@@ -1,189 +0,0 @@
-
-Cu.import("resource://gre/modules/UpdateUtils.jsm");
-
-function getNotificationBox(aWindow) {
- return aWindow.document.getElementById("high-priority-global-notificationbox");
-}
-
-function promiseNotificationShown(aWindow, aName) {
- return new Promise((resolve) => {
- let notification = getNotificationBox(aWindow);
- notification.addEventListener("AlertActive", function active() {
- notification.removeEventListener("AlertActive", active, true);
- is(notification.allNotifications.length, 1, "Notification Displayed.");
- resolve(notification);
- });
- });
-}
-
-function promiseReportCallMade(aValue) {
- return new Promise((resolve) => {
- let old = gTestHangReport.testCallback;
- gTestHangReport.testCallback = function (val) {
- gTestHangReport.testCallback = old;
- is(aValue, val, "was the correct method call made on the hang report object?");
- resolve();
- };
- });
-}
-
-function pushPrefs(...aPrefs) {
- return new Promise((resolve) => {
- SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
- resolve();
- });
-}
-
-function popPrefs() {
- return new Promise((resolve) => {
- SpecialPowers.popPrefEnv(resolve);
- resolve();
- });
-}
-
-let gTestHangReport = {
- SLOW_SCRIPT: 1,
- PLUGIN_HANG: 2,
-
- TEST_CALLBACK_CANCELED: 1,
- TEST_CALLBACK_TERMSCRIPT: 2,
- TEST_CALLBACK_TERMPLUGIN: 3,
-
- _hangType: 1,
- _tcb: function (aCallbackType) {},
-
- get hangType() {
- return this._hangType;
- },
-
- set hangType(aValue) {
- this._hangType = aValue;
- },
-
- set testCallback(aValue) {
- this._tcb = aValue;
- },
-
- QueryInterface: function (aIID) {
- if (aIID.equals(Components.interfaces.nsIHangReport) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_NOINTERFACE;
- },
-
- userCanceled: function () {
- this._tcb(this.TEST_CALLBACK_CANCELED);
- },
-
- terminateScript: function () {
- this._tcb(this.TEST_CALLBACK_TERMSCRIPT);
- },
-
- terminatePlugin: function () {
- this._tcb(this.TEST_CALLBACK_TERMPLUGIN);
- },
-
- isReportForBrowser: function(aFrameLoader) {
- return true;
- }
-};
-
-// on dev edition we add a button for js debugging of hung scripts.
-let buttonCount = (UpdateUtils.UpdateChannel == "aurora" ? 3 : 2);
-
-/**
- * Test if hang reports receive a terminate script callback when the user selects
- * stop in response to a script hang.
- */
-
-add_task(function* terminateScriptTest() {
- let promise = promiseNotificationShown(window, "process-hang");
- Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
- let notification = yield promise;
-
- let buttons = notification.currentNotification.getElementsByTagName("button");
- // Fails on aurora on-push builds, bug 1232204
- // is(buttons.length, buttonCount, "proper number of buttons");
-
- // Click the "Stop It" button, we should get a terminate script callback
- gTestHangReport.hangType = gTestHangReport.SLOW_SCRIPT;
- promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_TERMSCRIPT);
- buttons[0].click();
- yield promise;
-});
-
-/**
- * Test if hang reports receive user canceled callbacks after a user selects wait
- * and the browser frees up from a script hang on its own.
- */
-
-add_task(function* waitForScriptTest() {
- let promise = promiseNotificationShown(window, "process-hang");
- Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
- let notification = yield promise;
-
- let buttons = notification.currentNotification.getElementsByTagName("button");
- // Fails on aurora on-push builds, bug 1232204
- // is(buttons.length, buttonCount, "proper number of buttons");
-
- yield pushPrefs(["browser.hangNotification.waitPeriod", 1000]);
-
- function nocbcheck() {
- ok(false, "received a callback?");
- }
- let oldcb = gTestHangReport.testCallback;
- gTestHangReport.testCallback = nocbcheck;
- // Click the "Wait" button this time, we shouldn't get a callback at all.
- buttons[1].click();
- gTestHangReport.testCallback = oldcb;
-
- // send another hang pulse, we should not get a notification here
- Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
- is(notification.currentNotification, null, "no notification should be visible");
-
- gTestHangReport.testCallback = function() {};
- Services.obs.notifyObservers(gTestHangReport, "clear-hang-report", null);
- gTestHangReport.testCallback = oldcb;
-
- yield popPrefs();
-});
-
-/**
- * Test if hang reports receive user canceled callbacks after the content
- * process stops sending hang notifications.
- */
-
-add_task(function* hangGoesAwayTest() {
- yield pushPrefs(["browser.hangNotification.expiration", 1000]);
-
- let promise = promiseNotificationShown(window, "process-hang");
- Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
- yield promise;
-
- promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_CANCELED);
- Services.obs.notifyObservers(gTestHangReport, "clear-hang-report", null);
- yield promise;
-
- yield popPrefs();
-});
-
-/**
- * Tests if hang reports receive a terminate plugin callback when the user selects
- * stop in response to a plugin hang.
- */
-
-add_task(function* terminatePluginTest() {
- let promise = promiseNotificationShown(window, "process-hang");
- Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
- let notification = yield promise;
-
- let buttons = notification.currentNotification.getElementsByTagName("button");
- // Fails on aurora on-push builds, bug 1232204
- // is(buttons.length, buttonCount, "proper number of buttons");
-
- // Click the "Stop It" button, we should get a terminate script callback
- gTestHangReport.hangType = gTestHangReport.PLUGIN_HANG;
- promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_TERMPLUGIN);
- buttons[0].click();
- yield promise;
-});
diff --git a/browser/modules/test/browser_SelfSupportBackend.js b/browser/modules/test/browser_SelfSupportBackend.js
deleted file mode 100644
index 9e2c1d181..000000000
--- a/browser/modules/test/browser_SelfSupportBackend.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// Pass an empty scope object to the import to prevent "leaked window property"
-// errors in tests.
-var Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
-var PromiseUtils = Cu.import("resource://gre/modules/PromiseUtils.jsm", {}).PromiseUtils;
-var SelfSupportBackend =
- Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackend;
-
-const PREF_SELFSUPPORT_ENABLED = "browser.selfsupport.enabled";
-const PREF_SELFSUPPORT_URL = "browser.selfsupport.url";
-const PREF_UITOUR_ENABLED = "browser.uitour.enabled";
-
-const TEST_WAIT_RETRIES = 60;
-
-const TEST_PAGE_URL = getRootDirectory(gTestPath) + "uitour.html";
-const TEST_PAGE_URL_HTTPS = TEST_PAGE_URL.replace("chrome://mochitests/content/", "https://example.com/");
-
-function sendSessionRestoredNotification() {
- let selfSupportBackendImpl =
- Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackendInternal;
- selfSupportBackendImpl.observe(null, "sessionstore-windows-restored", null);
-}
-
-/**
- * Find a browser, with an IFRAME as parent, who has aURL as the source attribute.
- *
- * @param aURL The URL to look for to identify the browser.
- *
- * @returns {Object} The browser element or null on failure.
- */
-function findSelfSupportBrowser(aURL) {
- let frames = Services.appShell.hiddenDOMWindow.document.querySelectorAll('iframe');
- for (let frame of frames) {
- try {
- let browser = frame.contentDocument.getElementById("win").querySelectorAll('browser')[0];
- let url = browser.getAttribute("src");
- if (url == aURL) {
- return browser;
- }
- } catch (e) {
- continue;
- }
- }
- return null;
-}
-
-/**
- * Wait for self support page to load.
- *
- * @param aURL The URL to look for to identify the browser.
- *
- * @returns {Promise} Return a promise which is resolved when SelfSupport page is fully
- * loaded.
- */
-function promiseSelfSupportLoad(aURL) {
- return new Promise((resolve, reject) => {
- // Find the SelfSupport browser.
- let browserPromise = waitForConditionPromise(() => !!findSelfSupportBrowser(aURL),
- "SelfSupport browser not found.",
- TEST_WAIT_RETRIES);
-
- // Once found, append a "load" listener to catch page loads.
- browserPromise.then(() => {
- let browser = findSelfSupportBrowser(aURL);
- if (browser.contentDocument.readyState === "complete") {
- resolve(browser);
- } else {
- let handler = () => {
- browser.removeEventListener("load", handler, true);
- resolve(browser);
- };
- browser.addEventListener("load", handler, true);
- }
- }, reject);
- });
-}
-
-/**
- * Wait for self support to close.
- *
- * @param aURL The URL to look for to identify the browser.
- *
- * @returns {Promise} Return a promise which is resolved when SelfSupport browser cannot
- * be found anymore.
- */
-function promiseSelfSupportClose(aURL) {
- return waitForConditionPromise(() => !findSelfSupportBrowser(aURL),
- "SelfSupport browser is still open.", TEST_WAIT_RETRIES);
-}
-
-/**
- * Prepare the test environment.
- */
-add_task(function* setupEnvironment() {
- // We always run the SelfSupportBackend in tests to check for weird behaviours.
- // Disable it to test its start-up.
- SelfSupportBackend.uninit();
-
- // Testing prefs are set via |user_pref|, so we need to get their value in order
- // to restore them.
- let selfSupportEnabled = Preferences.get(PREF_SELFSUPPORT_ENABLED, true);
- let uitourEnabled = Preferences.get(PREF_UITOUR_ENABLED, false);
- let selfSupportURL = Preferences.get(PREF_SELFSUPPORT_URL, "");
-
- // Enable the SelfSupport backend and set the page URL. We also make sure UITour
- // is enabled.
- Preferences.set(PREF_SELFSUPPORT_ENABLED, true);
- Preferences.set(PREF_UITOUR_ENABLED, true);
- Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL_HTTPS);
-
- // Whitelist the HTTPS page to use UITour.
- let pageURI = Services.io.newURI(TEST_PAGE_URL_HTTPS, null, null);
- Services.perms.add(pageURI, "uitour", Services.perms.ALLOW_ACTION);
-
- registerCleanupFunction(() => {
- Services.perms.remove(pageURI, "uitour");
- Preferences.set(PREF_SELFSUPPORT_ENABLED, selfSupportEnabled);
- Preferences.set(PREF_UITOUR_ENABLED, uitourEnabled);
- Preferences.set(PREF_SELFSUPPORT_URL, selfSupportURL);
- });
-});
-
-/**
- * Test that the self support page can use the UITour API and close itself.
- */
-add_task(function* test_selfSupport() {
- // Initialise the SelfSupport backend and trigger the load.
- SelfSupportBackend.init();
-
- // SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it.
- info("Sending sessionstore-windows-restored");
- sendSessionRestoredNotification();
-
- // Wait for the SelfSupport page to load.
- info("Waiting for the SelfSupport local page to load.");
- let selfSupportBrowser = yield promiseSelfSupportLoad(TEST_PAGE_URL_HTTPS);
- Assert.ok(!!selfSupportBrowser, "SelfSupport browser must exist.");
-
- // Get a reference to the UITour API.
- info("Testing access to the UITour API.");
- let contentWindow =
- Cu.waiveXrays(selfSupportBrowser.contentDocument.defaultView);
- let uitourAPI = contentWindow.Mozilla.UITour;
-
- // Test the UITour API with a ping.
- let pingPromise = new Promise((resolve) => {
- uitourAPI.ping(resolve);
- });
- yield pingPromise;
- info("Ping succeeded");
-
- let observePromise = ContentTask.spawn(selfSupportBrowser, null, function* checkObserve() {
- yield new Promise(resolve => {
- let win = Cu.waiveXrays(content);
- win.Mozilla.UITour.observe((event, data) => {
- if (event != "Heartbeat:Engaged") {
- return;
- }
- Assert.equal(data.flowId, "myFlowID", "Check flowId");
- Assert.ok(!!data.timestamp, "Check timestamp");
- resolve(data);
- }, () => {});
- });
- });
-
- info("Notifying Heartbeat:Engaged");
- UITour.notify("Heartbeat:Engaged", {
- flowId: "myFlowID",
- timestamp: Date.now(),
- });
- yield observePromise;
- info("Observed in the hidden frame");
-
- // Close SelfSupport from content.
- contentWindow.close();
-
- // Wait until SelfSupport closes.
- info("Waiting for the SelfSupport to close.");
- yield promiseSelfSupportClose(TEST_PAGE_URL_HTTPS);
-
- // Find the SelfSupport browser, again. We don't expect to find it.
- selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL_HTTPS);
- Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist.");
-
- // We shouldn't need this, but let's keep it to make sure closing SelfSupport twice
- // doesn't create any problem.
- SelfSupportBackend.uninit();
-});
-
-/**
- * Test that SelfSupportBackend only allows HTTPS.
- */
-add_task(function* test_selfSupport_noHTTPS() {
- Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL);
-
- SelfSupportBackend.init();
-
- // SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it.
- info("Sending sessionstore-windows-restored");
- sendSessionRestoredNotification();
-
- // Find the SelfSupport browser. We don't expect to find it since we are not using https.
- let selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL);
- Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist.");
-
- // We shouldn't need this, but let's keep it to make sure closing SelfSupport twice
- // doesn't create any problem.
- SelfSupportBackend.uninit();
-})
diff --git a/browser/modules/test/browser_UnsubmittedCrashHandler.js b/browser/modules/test/browser_UnsubmittedCrashHandler.js
deleted file mode 100644
index 2d78c746b..000000000
--- a/browser/modules/test/browser_UnsubmittedCrashHandler.js
+++ /dev/null
@@ -1,680 +0,0 @@
-"use strict";
-
-/**
- * This suite tests the "unsubmitted crash report" notification
- * that is seen when we detect pending crash reports on startup.
- */
-
-const { UnsubmittedCrashHandler } =
- Cu.import("resource:///modules/ContentCrashHandlers.jsm", this);
-const { FileUtils } =
- Cu.import("resource://gre/modules/FileUtils.jsm", this);
-const { makeFakeAppDir } =
- Cu.import("resource://testing-common/AppData.jsm", this);
-const { OS } =
- Cu.import("resource://gre/modules/osfile.jsm", this);
-
-const DAY = 24 * 60 * 60 * 1000; // milliseconds
-const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
-
-/**
- * Returns the directly where the browsing is storing the
- * pending crash reports.
- *
- * @returns nsIFile
- */
-function getPendingCrashReportDir() {
- // The fake UAppData directory that makeFakeAppDir provides
- // is just UAppData under the profile directory.
- return FileUtils.getDir("ProfD", [
- "UAppData",
- "Crash Reports",
- "pending",
- ], false);
-}
-
-/**
- * Synchronously deletes all entries inside the pending
- * crash report directory.
- */
-function clearPendingCrashReports() {
- let dir = getPendingCrashReportDir();
- let entries = dir.directoryEntries;
-
- while (entries.hasMoreElements()) {
- let entry = entries.getNext().QueryInterface(Ci.nsIFile);
- if (entry.isFile()) {
- entry.remove(false);
- }
- }
-}
-
-/**
- * Randomly generates howMany crash report .dmp and .extra files
- * to put into the pending crash report directory. We're not
- * actually creating real crash reports here, just stubbing
- * out enough of the files to satisfy our notification and
- * submission code.
- *
- * @param howMany (int)
- * How many pending crash reports to put in the pending
- * crash report directory.
- * @param accessDate (Date, optional)
- * What date to set as the last accessed time on the created
- * crash reports. This defaults to the current date and time.
- * @returns Promise
- */
-function* createPendingCrashReports(howMany, accessDate) {
- let dir = getPendingCrashReportDir();
- if (!accessDate) {
- accessDate = new Date();
- }
-
- /**
- * Helper function for creating a file in the pending crash report
- * directory.
- *
- * @param fileName (string)
- * The filename for the crash report, not including the
- * extension. This is usually a UUID.
- * @param extension (string)
- * The file extension for the created file.
- * @param accessDate (Date)
- * The date to set lastAccessed to.
- * @param contents (string, optional)
- * Set this to whatever the file needs to contain, if anything.
- * @returns Promise
- */
- let createFile = (fileName, extension, accessDate, contents) => {
- let file = dir.clone();
- file.append(fileName + "." + extension);
- file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- let promises = [OS.File.setDates(file.path, accessDate)];
-
- if (contents) {
- let encoder = new TextEncoder();
- let array = encoder.encode(contents);
- promises.push(OS.File.writeAtomic(file.path, array, {
- tmpPath: file.path + ".tmp",
- }));
- }
- return Promise.all(promises);
- }
-
- let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
- .getService(Ci.nsIUUIDGenerator);
- // CrashSubmit expects there to be a ServerURL key-value
- // pair in the .extra file, so we'll satisfy it.
- let extraFileContents = "ServerURL=" + SERVER_URL;
-
- return Task.spawn(function*() {
- let uuids = [];
- for (let i = 0; i < howMany; ++i) {
- let uuid = uuidGenerator.generateUUID().toString();
- // Strip the {}...
- uuid = uuid.substring(1, uuid.length - 1);
- yield createFile(uuid, "dmp", accessDate);
- yield createFile(uuid, "extra", accessDate, extraFileContents);
- uuids.push(uuid);
- }
- return uuids;
- });
-}
-
-/**
- * Returns a Promise that resolves once CrashSubmit starts sending
- * success notifications for crash submission matching the reportIDs
- * being passed in.
- *
- * @param reportIDs (Array<string>)
- * The IDs for the reports that we expect CrashSubmit to have sent.
- * @returns Promise
- */
-function waitForSubmittedReports(reportIDs) {
- let promises = [];
- for (let reportID of reportIDs) {
- let promise = TestUtils.topicObserved("crash-report-status", (subject, data) => {
- if (data == "success") {
- let propBag = subject.QueryInterface(Ci.nsIPropertyBag2);
- let dumpID = propBag.getPropertyAsAString("minidumpID");
- if (dumpID == reportID) {
- return true;
- }
- }
- return false;
- });
- promises.push(promise);
- }
- return Promise.all(promises);
-}
-
-/**
- * Returns a Promise that resolves once a .dmp.ignore file is created for
- * the crashes in the pending directory matching the reportIDs being
- * passed in.
- *
- * @param reportIDs (Array<string>)
- * The IDs for the reports that we expect CrashSubmit to have been
- * marked for ignoring.
- * @returns Promise
- */
-function waitForIgnoredReports(reportIDs) {
- let dir = getPendingCrashReportDir();
- let promises = [];
- for (let reportID of reportIDs) {
- let file = dir.clone();
- file.append(reportID + ".dmp.ignore");
- promises.push(OS.File.exists(file.path));
- }
- return Promise.all(promises);
-}
-
-let gNotificationBox;
-
-add_task(function* setup() {
- // Pending crash reports are stored in the UAppData folder,
- // which exists outside of the profile folder. In order to
- // not overwrite / clear pending crash reports for the poor
- // soul who runs this test, we use AppData.jsm to point to
- // a special made-up directory inside the profile
- // directory.
- yield makeFakeAppDir();
- // We'll assume that the notifications will be shown in the current
- // browser window's global notification box.
- gNotificationBox = document.getElementById("global-notificationbox");
-
- // If we happen to already be seeing the unsent crash report
- // notification, it's because the developer running this test
- // happened to have some unsent reports in their UAppDir.
- // We'll remove the notification without touching those reports.
- let notification =
- gNotificationBox.getNotificationWithValue("pending-crash-reports");
- if (notification) {
- notification.close();
- }
-
- let env = Cc["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
- let oldServerURL = env.get("MOZ_CRASHREPORTER_URL");
- env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
-
- // nsBrowserGlue starts up UnsubmittedCrashHandler automatically
- // so at this point, it is initialized. It's possible that it
- // was initialized, but is preffed off, so it's inert, so we
- // shut it down, make sure it's preffed on, and then restart it.
- // Note that making the component initialize even when it's
- // disabled is an intentional choice, as this allows for easier
- // simulation of startup and shutdown.
- UnsubmittedCrashHandler.uninit();
- yield SpecialPowers.pushPrefEnv({
- set: [
- ["browser.crashReports.unsubmittedCheck.enabled", true],
- ],
- });
- UnsubmittedCrashHandler.init();
-
- registerCleanupFunction(function() {
- gNotificationBox = null;
- clearPendingCrashReports();
- env.set("MOZ_CRASHREPORTER_URL", oldServerURL);
- });
-});
-
-/**
- * Tests that if there are no pending crash reports, then the
- * notification will not show up.
- */
-add_task(function* test_no_pending_no_notification() {
- // Make absolutely sure there are no pending crash reports first...
- clearPendingCrashReports();
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.equal(notification, null,
- "There should not be a notification if there are no " +
- "pending crash reports");
-});
-
-/**
- * Tests that there is a notification if there is one pending
- * crash report.
- */
-add_task(function* test_one_pending() {
- yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that there is a notification if there is more than one
- * pending crash report.
- */
-add_task(function* test_several_pending() {
- yield createPendingCrashReports(3);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that there is no notification if the only pending crash
- * reports are over 28 days old. Also checks that if we put a newer
- * crash with that older set, that we can still get a notification.
- */
-add_task(function* test_several_pending() {
- // Let's create some crash reports from 30 days ago.
- let oldDate = new Date(Date.now() - (30 * DAY));
- yield createPendingCrashReports(3, oldDate);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.equal(notification, null,
- "There should not be a notification if there are only " +
- "old pending crash reports");
- // Now let's create a new one and check again
- yield createPendingCrashReports(1);
- notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that the notification can submit a report.
- */
-add_task(function* test_can_submit() {
- let reportIDs = yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- // Attempt to submit the notification by clicking on the submit
- // button
- let buttons = notification.querySelectorAll(".notification-button");
- // ...which should be the first button.
- let submit = buttons[0];
-
- let promiseReports = waitForSubmittedReports(reportIDs);
- info("Sending crash report");
- submit.click();
- info("Sent!");
- // We'll not wait for the notification to finish its transition -
- // we'll just remove it right away.
- gNotificationBox.removeNotification(notification, true);
-
- info("Waiting on reports to be received.");
- yield promiseReports;
- info("Received!");
- clearPendingCrashReports();
-});
-
-/**
- * Tests that the notification can submit multiple reports.
- */
-add_task(function* test_can_submit_several() {
- let reportIDs = yield createPendingCrashReports(3);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- // Attempt to submit the notification by clicking on the submit
- // button
- let buttons = notification.querySelectorAll(".notification-button");
- // ...which should be the first button.
- let submit = buttons[0];
-
- let promiseReports = waitForSubmittedReports(reportIDs);
- info("Sending crash reports");
- submit.click();
- info("Sent!");
- // We'll not wait for the notification to finish its transition -
- // we'll just remove it right away.
- gNotificationBox.removeNotification(notification, true);
-
- info("Waiting on reports to be received.");
- yield promiseReports;
- info("Received!");
- clearPendingCrashReports();
-});
-
-/**
- * Tests that choosing "Send Always" flips the autoSubmit pref
- * and sends the pending crash reports.
- */
-add_task(function* test_can_submit_always() {
- let pref = "browser.crashReports.unsubmittedCheck.autoSubmit2";
- Assert.equal(Services.prefs.getBoolPref(pref), false,
- "We should not be auto-submitting by default");
-
- let reportIDs = yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- // Attempt to submit the notification by clicking on the send all
- // button
- let buttons = notification.querySelectorAll(".notification-button");
- // ...which should be the second button.
- let sendAll = buttons[1];
-
- let promiseReports = waitForSubmittedReports(reportIDs);
- info("Sending crash reports");
- sendAll.click();
- info("Sent!");
- // We'll not wait for the notification to finish its transition -
- // we'll just remove it right away.
- gNotificationBox.removeNotification(notification, true);
-
- info("Waiting on reports to be received.");
- yield promiseReports;
- info("Received!");
-
- // Make sure the pref was set
- Assert.equal(Services.prefs.getBoolPref(pref), true,
- "The autoSubmit pref should have been set");
-
- // And revert back to default now.
- Services.prefs.clearUserPref(pref);
-
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if the user has chosen to automatically send
- * crash reports that no notification is displayed to the
- * user.
- */
-add_task(function* test_can_auto_submit() {
- yield SpecialPowers.pushPrefEnv({ set: [
- ["browser.crashReports.unsubmittedCheck.autoSubmit2", true],
- ]});
-
- let reportIDs = yield createPendingCrashReports(3);
- let promiseReports = waitForSubmittedReports(reportIDs);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.equal(notification, null, "There should be no notification");
- info("Waiting on reports to be received.");
- yield promiseReports;
- info("Received!");
-
- clearPendingCrashReports();
- yield SpecialPowers.popPrefEnv();
-});
-
-/**
- * Tests that if the user chooses to dismiss the notification,
- * then the current pending requests won't cause the notification
- * to appear again in the future.
- */
-add_task(function* test_can_ignore() {
- let reportIDs = yield createPendingCrashReports(3);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- // Dismiss the notification by clicking on the "X" button.
- let anonyNodes = document.getAnonymousNodes(notification)[0];
- let closeButton = anonyNodes.querySelector(".close-icon");
- closeButton.click();
- // We'll not wait for the notification to finish its transition -
- // we'll just remove it right away.
- gNotificationBox.removeNotification(notification, true);
- yield waitForIgnoredReports(reportIDs);
-
- notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.equal(notification, null, "There should be no notification");
-
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if the notification is shown, then the
- * lastShownDate is set for today.
- */
-add_task(function* test_last_shown_date() {
- yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- let today = UnsubmittedCrashHandler.dateString(new Date());
- let lastShownDate =
- UnsubmittedCrashHandler.prefs.getCharPref("lastShownDate");
- Assert.equal(today, lastShownDate,
- "Last shown date should be today.");
-
- UnsubmittedCrashHandler.prefs.clearUserPref("lastShownDate");
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if UnsubmittedCrashHandler is uninit with a
- * notification still being shown, that
- * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is
- * set to true.
- */
-add_task(function* test_shutdown_while_showing() {
- yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- UnsubmittedCrashHandler.uninit();
- let shutdownWhileShowing =
- UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing");
- Assert.ok(shutdownWhileShowing,
- "We should have noticed that we uninitted while showing " +
- "the notification.");
- UnsubmittedCrashHandler.prefs.clearUserPref("shutdownWhileShowing");
- UnsubmittedCrashHandler.init();
-
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if UnsubmittedCrashHandler is uninit after
- * the notification has been closed, that
- * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is
- * not set in prefs.
- */
-add_task(function* test_shutdown_while_not_showing() {
- let reportIDs = yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- // Dismiss the notification by clicking on the "X" button.
- let anonyNodes = document.getAnonymousNodes(notification)[0];
- let closeButton = anonyNodes.querySelector(".close-icon");
- closeButton.click();
- // We'll not wait for the notification to finish its transition -
- // we'll just remove it right away.
- gNotificationBox.removeNotification(notification, true);
-
- yield waitForIgnoredReports(reportIDs);
-
- UnsubmittedCrashHandler.uninit();
- Assert.throws(() => {
- UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing");
- }, "We should have noticed that the notification had closed before " +
- "uninitting.");
- UnsubmittedCrashHandler.init();
-
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if
- * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is
- * set and the lastShownDate is today, then we don't decrement
- * browser.crashReports.unsubmittedCheck.chancesUntilSuppress.
- */
-add_task(function* test_dont_decrement_chances_on_same_day() {
- let initChances =
- UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress");
- Assert.ok(initChances > 1, "We should start with at least 1 chance.");
-
- yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- UnsubmittedCrashHandler.uninit();
-
- gNotificationBox.removeNotification(notification, true);
-
- let shutdownWhileShowing =
- UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing");
- Assert.ok(shutdownWhileShowing,
- "We should have noticed that we uninitted while showing " +
- "the notification.");
-
- let today = UnsubmittedCrashHandler.dateString(new Date());
- let lastShownDate =
- UnsubmittedCrashHandler.prefs.getCharPref("lastShownDate");
- Assert.equal(today, lastShownDate,
- "Last shown date should be today.");
-
- UnsubmittedCrashHandler.init();
-
- notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should still be a notification");
-
- let chances =
- UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress");
-
- Assert.equal(initChances, chances,
- "We should not have decremented chances.");
-
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if
- * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is
- * set and the lastShownDate is before today, then we decrement
- * browser.crashReports.unsubmittedCheck.chancesUntilSuppress.
- */
-add_task(function* test_decrement_chances_on_other_day() {
- let initChances =
- UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress");
- Assert.ok(initChances > 1, "We should start with at least 1 chance.");
-
- yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should be a notification");
-
- UnsubmittedCrashHandler.uninit();
-
- gNotificationBox.removeNotification(notification, true);
-
- let shutdownWhileShowing =
- UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing");
- Assert.ok(shutdownWhileShowing,
- "We should have noticed that we uninitted while showing " +
- "the notification.");
-
- // Now pretend that the notification was shown yesterday.
- let yesterday = UnsubmittedCrashHandler.dateString(new Date(Date.now() - DAY));
- UnsubmittedCrashHandler.prefs.setCharPref("lastShownDate", yesterday);
-
- UnsubmittedCrashHandler.init();
-
- notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.ok(notification, "There should still be a notification");
-
- let chances =
- UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress");
-
- Assert.equal(initChances - 1, chances,
- "We should have decremented our chances.");
- UnsubmittedCrashHandler.prefs.clearUserPref("chancesUntilSuppress");
-
- gNotificationBox.removeNotification(notification, true);
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if we've shutdown too many times showing the
- * notification, and we've run out of chances, then
- * browser.crashReports.unsubmittedCheck.suppressUntilDate is
- * set for some days into the future.
- */
-add_task(function* test_can_suppress_after_chances() {
- // Pretend that a notification was shown yesterday.
- let yesterday = UnsubmittedCrashHandler.dateString(new Date(Date.now() - DAY));
- UnsubmittedCrashHandler.prefs.setCharPref("lastShownDate", yesterday);
- UnsubmittedCrashHandler.prefs.setBoolPref("shutdownWhileShowing", true);
- UnsubmittedCrashHandler.prefs.setIntPref("chancesUntilSuppress", 0);
-
- yield createPendingCrashReports(1);
- let notification =
- yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports();
- Assert.equal(notification, null,
- "There should be no notification if we've run out of chances");
-
- // We should have set suppressUntilDate into the future
- let suppressUntilDate =
- UnsubmittedCrashHandler.prefs.getCharPref("suppressUntilDate");
-
- let today = UnsubmittedCrashHandler.dateString(new Date());
- Assert.ok(suppressUntilDate > today,
- "We should be suppressing until some days into the future.");
-
- UnsubmittedCrashHandler.prefs.clearUserPref("chancesUntilSuppress");
- UnsubmittedCrashHandler.prefs.clearUserPref("suppressUntilDate");
- UnsubmittedCrashHandler.prefs.clearUserPref("lastShownDate");
- clearPendingCrashReports();
-});
-
-/**
- * Tests that if there's a suppression date set, then no notification
- * will be shown even if there are pending crash reports.
- */
-add_task(function* test_suppression() {
- let future = UnsubmittedCrashHandler.dateString(new Date(Date.now() + (DAY * 5)));
- UnsubmittedCrashHandler.prefs.setCharPref("suppressUntilDate", future);
- UnsubmittedCrashHandler.uninit();
- UnsubmittedCrashHandler.init();
-
- Assert.ok(UnsubmittedCrashHandler.suppressed,
- "The UnsubmittedCrashHandler should be suppressed.");
- UnsubmittedCrashHandler.prefs.clearUserPref("suppressUntilDate");
-
- UnsubmittedCrashHandler.uninit();
- UnsubmittedCrashHandler.init();
-});
-
-/**
- * Tests that if there's a suppression date set, but we've exceeded
- * it, then we can show the notification again.
- */
-add_task(function* test_end_suppression() {
- let yesterday = UnsubmittedCrashHandler.dateString(new Date(Date.now() - DAY));
- UnsubmittedCrashHandler.prefs.setCharPref("suppressUntilDate", yesterday);
- UnsubmittedCrashHandler.uninit();
- UnsubmittedCrashHandler.init();
-
- Assert.ok(!UnsubmittedCrashHandler.suppressed,
- "The UnsubmittedCrashHandler should not be suppressed.");
- Assert.ok(!UnsubmittedCrashHandler.prefs.prefHasUserValue("suppressUntilDate"),
- "The suppression date should been cleared from preferences.");
-
- UnsubmittedCrashHandler.uninit();
- UnsubmittedCrashHandler.init();
-});
diff --git a/browser/modules/test/browser_UsageTelemetry.js b/browser/modules/test/browser_UsageTelemetry.js
deleted file mode 100644
index a84f33a97..000000000
--- a/browser/modules/test/browser_UsageTelemetry.js
+++ /dev/null
@@ -1,268 +0,0 @@
-"use strict";
-
-const MAX_CONCURRENT_TABS = "browser.engagement.max_concurrent_tab_count";
-const TAB_EVENT_COUNT = "browser.engagement.tab_open_event_count";
-const MAX_CONCURRENT_WINDOWS = "browser.engagement.max_concurrent_window_count";
-const WINDOW_OPEN_COUNT = "browser.engagement.window_open_event_count";
-const TOTAL_URI_COUNT = "browser.engagement.total_uri_count";
-const UNIQUE_DOMAINS_COUNT = "browser.engagement.unique_domains_count";
-const UNFILTERED_URI_COUNT = "browser.engagement.unfiltered_uri_count";
-
-const TELEMETRY_SUBSESSION_TOPIC = "internal-telemetry-after-subsession-split";
-
-/**
- * Waits for the web progress listener associated with this tab to fire an
- * onLocationChange for a non-error page.
- *
- * @param {xul:browser} browser
- * A xul:browser.
- *
- * @return {Promise}
- * @resolves When navigating to a non-error page.
- */
-function browserLocationChanged(browser) {
- return new Promise(resolve => {
- let wpl = {
- onStateChange() {},
- onSecurityChange() {},
- onStatusChange() {},
- onLocationChange(aWebProgress, aRequest, aURI, aFlags) {
- if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) {
- browser.webProgress.removeProgressListener(filter);
- filter.removeProgressListener(wpl);
- resolve();
- }
- },
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIWebProgressListener,
- Ci.nsIWebProgressListener2,
- ]),
- };
- const filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
- .createInstance(Ci.nsIWebProgress);
- filter.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
- browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
- });
-}
-
-/**
- * An helper that checks the value of a scalar if it's expected to be > 0,
- * otherwise makes sure that the scalar it's not reported.
- */
-let checkScalar = (scalars, scalarName, value, msg) => {
- if (value > 0) {
- is(scalars[scalarName], value, msg);
- return;
- }
- ok(!(scalarName in scalars), scalarName + " must not be reported.");
-};
-
-/**
- * Get a snapshot of the scalars and check them against the provided values.
- */
-let checkScalars = (countsObject) => {
- const scalars =
- Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-
- // Check the expected values. Scalars that are never set must not be reported.
- checkScalar(scalars, MAX_CONCURRENT_TABS, countsObject.maxTabs,
- "The maximum tab count must match the expected value.");
- checkScalar(scalars, TAB_EVENT_COUNT, countsObject.tabOpenCount,
- "The number of open tab event count must match the expected value.");
- checkScalar(scalars, MAX_CONCURRENT_WINDOWS, countsObject.maxWindows,
- "The maximum window count must match the expected value.");
- checkScalar(scalars, WINDOW_OPEN_COUNT, countsObject.windowsOpenCount,
- "The number of window open event count must match the expected value.");
- checkScalar(scalars, TOTAL_URI_COUNT, countsObject.totalURIs,
- "The total URI count must match the expected value.");
- checkScalar(scalars, UNIQUE_DOMAINS_COUNT, countsObject.domainCount,
- "The unique domains count must match the expected value.");
- checkScalar(scalars, UNFILTERED_URI_COUNT, countsObject.totalUnfilteredURIs,
- "The unfiltered URI count must match the expected value.");
-};
-
-add_task(function* test_tabsAndWindows() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
-
- let openedTabs = [];
- let expectedTabOpenCount = 0;
- let expectedWinOpenCount = 0;
- let expectedMaxTabs = 0;
- let expectedMaxWins = 0;
-
- // Add a new tab and check that the count is right.
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
- expectedTabOpenCount = 1;
- expectedMaxTabs = 2;
- // This, and all the checks below, also check that initial pages (about:newtab, about:blank, ..)
- // are not counted by the total_uri_count and the unfiltered_uri_count probes.
- checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins,
- windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0,
- totalUnfilteredURIs: 0});
-
- // Add two new tabs in the same window.
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
- expectedTabOpenCount += 2;
- expectedMaxTabs += 2;
- checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins,
- windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0,
- totalUnfilteredURIs: 0});
-
- // Add a new window and then some tabs in it. An empty new windows counts as a tab.
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"));
- // The new window started with a new tab, so account for it.
- expectedTabOpenCount += 4;
- expectedWinOpenCount += 1;
- expectedMaxWins = 2;
- expectedMaxTabs += 4;
-
- // Remove a tab from the first window, the max shouldn't change.
- yield BrowserTestUtils.removeTab(openedTabs.pop());
- checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins,
- windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0,
- totalUnfilteredURIs: 0});
-
- // Remove all the extra windows and tabs.
- for (let tab of openedTabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- yield BrowserTestUtils.closeWindow(win);
-
- // Make sure all the scalars still have the expected values.
- checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins,
- windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0,
- totalUnfilteredURIs: 0});
-});
-
-add_task(function* test_subsessionSplit() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
-
- // Add a new window (that will have 4 tabs).
- let win = yield BrowserTestUtils.openNewBrowserWindow();
- let openedTabs = [];
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank"));
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:mozilla"));
- openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "http://www.example.com"));
-
- // Check that the scalars have the right values. We expect 2 unfiltered URI loads
- // (about:mozilla and www.example.com, but no about:blank) and 1 URI totalURIs
- // (only www.example.com).
- checkScalars({maxTabs: 5, tabOpenCount: 4, maxWindows: 2, windowsOpenCount: 1,
- totalURIs: 1, domainCount: 1, totalUnfilteredURIs: 2});
-
- // Remove a tab.
- yield BrowserTestUtils.removeTab(openedTabs.pop());
-
- // Simulate a subsession split by clearing the scalars (via |snapshotScalars|) and
- // notifying the subsession split topic.
- Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN,
- true /* clearScalars */);
- Services.obs.notifyObservers(null, TELEMETRY_SUBSESSION_TOPIC, "");
-
- // After a subsession split, only the MAX_CONCURRENT_* scalars must be available
- // and have the correct value. No tabs, windows or URIs were opened so other scalars
- // must not be reported.
- checkScalars({maxTabs: 4, tabOpenCount: 0, maxWindows: 2, windowsOpenCount: 0,
- totalURIs: 0, domainCount: 0, totalUnfilteredURIs: 0});
-
- // Remove all the extra windows and tabs.
- for (let tab of openedTabs) {
- yield BrowserTestUtils.removeTab(tab);
- }
- yield BrowserTestUtils.closeWindow(win);
-});
-
-add_task(function* test_URIAndDomainCounts() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
-
- let checkCounts = (countsObject) => {
- // Get a snapshot of the scalars and then clear them.
- const scalars =
- Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
- checkScalar(scalars, TOTAL_URI_COUNT, countsObject.totalURIs,
- "The URI scalar must contain the expected value.");
- checkScalar(scalars, UNIQUE_DOMAINS_COUNT, countsObject.domainCount,
- "The unique domains scalar must contain the expected value.");
- checkScalar(scalars, UNFILTERED_URI_COUNT, countsObject.totalUnfilteredURIs,
- "The unfiltered URI scalar must contain the expected value.");
- };
-
- // Check that about:blank doesn't get counted in the URI total.
- let firstTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
- checkCounts({totalURIs: 0, domainCount: 0, totalUnfilteredURIs: 0});
-
- // Open a different page and check the counts.
- yield BrowserTestUtils.loadURI(firstTab.linkedBrowser, "http://example.com/");
- yield BrowserTestUtils.browserLoaded(firstTab.linkedBrowser);
- checkCounts({totalURIs: 1, domainCount: 1, totalUnfilteredURIs: 1});
-
- // Activating a different tab must not increase the URI count.
- let secondTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
- yield BrowserTestUtils.switchTab(gBrowser, firstTab);
- checkCounts({totalURIs: 1, domainCount: 1, totalUnfilteredURIs: 1});
- yield BrowserTestUtils.removeTab(secondTab);
-
- // Open a new window and set the tab to a new address.
- let newWin = yield BrowserTestUtils.openNewBrowserWindow();
- yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://example.com/");
- yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
- checkCounts({totalURIs: 2, domainCount: 1, totalUnfilteredURIs: 2});
-
- // We should not count AJAX requests.
- const XHR_URL = "http://example.com/r";
- yield ContentTask.spawn(newWin.gBrowser.selectedBrowser, XHR_URL, function(url) {
- return new Promise(resolve => {
- var xhr = new content.window.XMLHttpRequest();
- xhr.open("GET", url);
- xhr.onload = () => resolve();
- xhr.send();
- });
- });
- checkCounts({totalURIs: 2, domainCount: 1, totalUnfilteredURIs: 2});
-
- // Check that we're counting page fragments.
- let loadingStopped = browserLocationChanged(newWin.gBrowser.selectedBrowser);
- yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://example.com/#2");
- yield loadingStopped;
- checkCounts({totalURIs: 3, domainCount: 1, totalUnfilteredURIs: 3});
-
- // Check that a different URI from the example.com domain doesn't increment the unique count.
- yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://test1.example.com/");
- yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
- checkCounts({totalURIs: 4, domainCount: 1, totalUnfilteredURIs: 4});
-
- // Make sure that the unique domains counter is incrementing for a different domain.
- yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "https://example.org/");
- yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
- checkCounts({totalURIs: 5, domainCount: 2, totalUnfilteredURIs: 5});
-
- // Check that we only account for top level loads (e.g. we don't count URIs from
- // embedded iframes).
- yield ContentTask.spawn(newWin.gBrowser.selectedBrowser, null, function* () {
- let doc = content.document;
- let iframe = doc.createElement("iframe");
- let promiseIframeLoaded = ContentTaskUtils.waitForEvent(iframe, "load", false);
- iframe.src = "https://example.org/test";
- doc.body.insertBefore(iframe, doc.body.firstChild);
- yield promiseIframeLoaded;
- });
- checkCounts({totalURIs: 5, domainCount: 2, totalUnfilteredURIs: 5});
-
- // Check that uncommon protocols get counted in the unfiltered URI probe.
- const TEST_PAGE =
- "data:text/html,<a id='target' href='%23par1'>Click me</a><a name='par1'>The paragraph.</a>";
- yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, TEST_PAGE);
- yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
- checkCounts({totalURIs: 5, domainCount: 2, totalUnfilteredURIs: 6});
-
- // Clean up.
- yield BrowserTestUtils.removeTab(firstTab);
- yield BrowserTestUtils.closeWindow(newWin);
-});
diff --git a/browser/modules/test/browser_UsageTelemetry_content.js b/browser/modules/test/browser_UsageTelemetry_content.js
deleted file mode 100644
index 35c6b5a6d..000000000
--- a/browser/modules/test/browser_UsageTelemetry_content.js
+++ /dev/null
@@ -1,121 +0,0 @@
-"use strict";
-
-const BASE_PROBE_NAME = "browser.engagement.navigation.";
-const SCALAR_CONTEXT_MENU = BASE_PROBE_NAME + "contextmenu";
-const SCALAR_ABOUT_NEWTAB = BASE_PROBE_NAME + "about_newtab";
-
-add_task(function* setup() {
- // Create two new search engines. Mark one as the default engine, so
- // the test don't crash. We need to engines for this test as the searchbar
- // in content doesn't display the default search engine among the one-off engines.
- Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- Services.search.addEngineWithDetails("MozSearch2", "", "mozalias2", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- // Make the first engine the default search engine.
- let engineDefault = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engineDefault;
-
- // Move the second engine at the beginning of the one-off list.
- let engineOneOff = Services.search.getEngineByName("MozSearch2");
- Services.search.moveEngine(engineOneOff, 0);
-
- yield SpecialPowers.pushPrefEnv({"set": [
- ["dom.select_events.enabled", true], // We want select events to be fired.
- ["toolkit.telemetry.enabled", true] // And Extended Telemetry to be enabled.
- ]});
-
- // Make sure to restore the engine once we're done.
- registerCleanupFunction(function* () {
- Services.search.currentEngine = originalEngine;
- Services.search.removeEngine(engineDefault);
- Services.search.removeEngine(engineOneOff);
- });
-});
-
-add_task(function* test_context_menu() {
- // Let's reset the Telemetry data.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- // Open a new tab with a page containing some text.
- let tab =
- yield BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/plain;charset=utf8,test%20search");
-
- info("Select all the text in the page.");
- yield ContentTask.spawn(tab.linkedBrowser, "", function*() {
- return new Promise(resolve => {
- content.document.addEventListener("selectionchange", () => resolve(), { once: true });
- content.document.getSelection().selectAllChildren(content.document.body);
- });
- });
-
- info("Open the context menu.");
- let contextMenu = document.getElementById("contentAreaContextMenu");
- let popupPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
- BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 },
- gBrowser.selectedBrowser);
- yield popupPromise;
-
- info("Click on search.");
- let searchItem = contextMenu.getElementsByAttribute("id", "context-searchselect")[0];
- searchItem.click();
-
- info("Validate the search metrics.");
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_CONTEXT_MENU, "search", 1);
- Assert.equal(Object.keys(scalars[SCALAR_CONTEXT_MENU]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.contextmenu', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "contextmenu", null, {engine: "other-MozSearch"}]]);
-
- contextMenu.hidePopup();
- yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_about_newtab() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false);
- yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
- yield ContentTaskUtils.waitForCondition(() => !content.document.hidden);
- });
-
- info("Trigger a simple serch, just text + enter.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield typeInSearchField(tab.linkedBrowser, "test query", "newtab-search-text");
- yield BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser);
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_ABOUT_NEWTAB, "search_enter", 1);
- Assert.equal(Object.keys(scalars[SCALAR_ABOUT_NEWTAB]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.newtab', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "about_newtab", "enter", {engine: "other-MozSearch"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js b/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js
deleted file mode 100644
index 1818ae5fd..000000000
--- a/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js
+++ /dev/null
@@ -1,84 +0,0 @@
-"use strict";
-
-const SCALAR_ABOUT_HOME = "browser.engagement.navigation.about_home";
-
-add_task(function* setup() {
- // about:home uses IndexedDB. However, the test finishes too quickly and doesn't
- // allow it enougth time to save. So it throws. This disables all the uncaught
- // exception in this file and that's the reason why we split about:home tests
- // out of the other UsageTelemetry files.
- ignoreAllUncaughtExceptions();
-
- // Create two new search engines. Mark one as the default engine, so
- // the test don't crash. We need to engines for this test as the searchbar
- // in content doesn't display the default search engine among the one-off engines.
- Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- Services.search.addEngineWithDetails("MozSearch2", "", "mozalias2", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- // Make the first engine the default search engine.
- let engineDefault = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engineDefault;
-
- // Move the second engine at the beginning of the one-off list.
- let engineOneOff = Services.search.getEngineByName("MozSearch2");
- Services.search.moveEngine(engineOneOff, 0);
-
- // Enable Extended Telemetry.
- yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]});
-
- // Make sure to restore the engine once we're done.
- registerCleanupFunction(function* () {
- Services.search.currentEngine = originalEngine;
- Services.search.removeEngine(engineDefault);
- Services.search.removeEngine(engineOneOff);
- });
-});
-
-add_task(function* test_abouthome_simpleQuery() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
-
- info("Setup waiting for AboutHomeLoadSnippetsCompleted.");
- let promiseAboutHomeLoaded = new Promise(resolve => {
- tab.linkedBrowser.addEventListener("AboutHomeLoadSnippetsCompleted", function loadListener(event) {
- tab.linkedBrowser.removeEventListener("AboutHomeLoadSnippetsCompleted", loadListener, true);
- resolve();
- }, true, true);
- });
-
- info("Load about:home.");
- tab.linkedBrowser.loadURI("about:home");
- info("Wait for AboutHomeLoadSnippetsCompleted.");
- yield promiseAboutHomeLoaded;
-
- info("Trigger a simple serch, just test + enter.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield typeInSearchField(tab.linkedBrowser, "test query", "searchText");
- yield BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser);
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_ABOUT_HOME, "search_enter", 1);
- Assert.equal(Object.keys(scalars[SCALAR_ABOUT_HOME]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.abouthome', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "about_home", "enter", {engine: "other-MozSearch"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/modules/test/browser_UsageTelemetry_private_and_restore.js b/browser/modules/test/browser_UsageTelemetry_private_and_restore.js
deleted file mode 100644
index 144a4a03f..000000000
--- a/browser/modules/test/browser_UsageTelemetry_private_and_restore.js
+++ /dev/null
@@ -1,90 +0,0 @@
-"use strict";
-
-const MAX_CONCURRENT_TABS = "browser.engagement.max_concurrent_tab_count";
-const TAB_EVENT_COUNT = "browser.engagement.tab_open_event_count";
-const MAX_CONCURRENT_WINDOWS = "browser.engagement.max_concurrent_window_count";
-const WINDOW_OPEN_COUNT = "browser.engagement.window_open_event_count";
-const TOTAL_URI_COUNT = "browser.engagement.total_uri_count";
-const UNFILTERED_URI_COUNT = "browser.engagement.unfiltered_uri_count";
-const UNIQUE_DOMAINS_COUNT = "browser.engagement.unique_domains_count";
-
-function promiseBrowserStateRestored() {
- return new Promise(resolve => {
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
- resolve();
- }, "sessionstore-browser-state-restored", false);
- });
-}
-
-add_task(function* test_privateMode() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
-
- // Open a private window and load a website in it.
- let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});
- yield BrowserTestUtils.loadURI(privateWin.gBrowser.selectedBrowser, "http://example.com/");
- yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
-
- // Check that tab and window count is recorded.
- const scalars =
- Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-
- ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs in private mode.");
- ok(!(UNFILTERED_URI_COUNT in scalars), "We should not track URIs in private mode.");
- ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains in private mode.");
- is(scalars[TAB_EVENT_COUNT], 1, "The number of open tab event count must match the expected value.");
- is(scalars[MAX_CONCURRENT_TABS], 2, "The maximum tab count must match the expected value.");
- is(scalars[WINDOW_OPEN_COUNT], 1, "The number of window open event count must match the expected value.");
- is(scalars[MAX_CONCURRENT_WINDOWS], 2, "The maximum window count must match the expected value.");
-
- // Clean up.
- yield BrowserTestUtils.closeWindow(privateWin);
-});
-
-add_task(function* test_sessionRestore() {
- const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
- Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
- registerCleanupFunction(() => {
- Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
- });
-
- // Let's reset the counts.
- Services.telemetry.clearScalars();
-
- // The first window will be put into the already open window and the second
- // window will be opened with _openWindowWithState, which is the source of the problem.
- const state = {
- windows: [
- {
- tabs: [
- { entries: [{ url: "http://example.org" }], extData: { "uniq": 3785 } }
- ],
- selected: 1
- }
- ]
- };
-
- // Save the current session.
- let SessionStore =
- Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStore;
-
- // Load the custom state and wait for SSTabRestored, as we want to make sure
- // that the URI counting code was hit.
- let tabRestored = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored");
- SessionStore.setBrowserState(JSON.stringify(state));
- yield tabRestored;
-
- // Check that the URI is not recorded.
- const scalars =
- Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN);
-
- ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs from restored sessions.");
- ok(!(UNFILTERED_URI_COUNT in scalars), "We should not track URIs from restored sessions.");
- ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains from restored sessions.");
-
- // Restore the original session and cleanup.
- let sessionRestored = promiseBrowserStateRestored();
- SessionStore.setBrowserState(JSON.stringify(state));
- yield sessionRestored;
-});
diff --git a/browser/modules/test/browser_UsageTelemetry_searchbar.js b/browser/modules/test/browser_UsageTelemetry_searchbar.js
deleted file mode 100644
index 8aa3ceaee..000000000
--- a/browser/modules/test/browser_UsageTelemetry_searchbar.js
+++ /dev/null
@@ -1,195 +0,0 @@
-"use strict";
-
-const SCALAR_SEARCHBAR = "browser.engagement.navigation.searchbar";
-
-let searchInSearchbar = Task.async(function* (inputText) {
- let win = window;
- yield new Promise(r => waitForFocus(r, win));
- let sb = BrowserSearch.searchBar;
- // Write the search query in the searchbar.
- sb.focus();
- sb.value = inputText;
- sb.textbox.controller.startSearch(inputText);
- // Wait for the popup to show.
- yield BrowserTestUtils.waitForEvent(sb.textbox.popup, "popupshown");
- // And then for the search to complete.
- yield BrowserTestUtils.waitForCondition(() => sb.textbox.controller.searchStatus >=
- Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH,
- "The search in the searchbar must complete.");
-});
-
-/**
- * Click one of the entries in the search suggestion popup.
- *
- * @param {String} entryName
- * The name of the elemet to click on.
- */
-function clickSearchbarSuggestion(entryName) {
- let popup = BrowserSearch.searchBar.textbox.popup;
- let column = popup.tree.columns[0];
-
- for (let rowID = 0; rowID < popup.tree.view.rowCount; rowID++) {
- const suggestion = popup.tree.view.getValueAt(rowID, column);
- if (suggestion !== entryName) {
- continue;
- }
-
- // Make sure the suggestion is visible, just in case.
- let tbo = popup.tree.treeBoxObject;
- tbo.ensureRowIsVisible(rowID);
- // Calculate the click coordinates.
- let rect = tbo.getCoordsForCellItem(rowID, column, "text");
- let x = rect.x + rect.width / 2;
- let y = rect.y + rect.height / 2;
- // Simulate the click.
- EventUtils.synthesizeMouse(popup.tree.body, x, y, {},
- popup.tree.ownerGlobal);
- break;
- }
-}
-
-add_task(function* setup() {
- // Create two new search engines. Mark one as the default engine, so
- // the test don't crash. We need to engines for this test as the searchbar
- // doesn't display the default search engine among the one-off engines.
- Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- Services.search.addEngineWithDetails("MozSearch2", "", "mozalias2", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- // Make the first engine the default search engine.
- let engineDefault = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engineDefault;
-
- // Move the second engine at the beginning of the one-off list.
- let engineOneOff = Services.search.getEngineByName("MozSearch2");
- Services.search.moveEngine(engineOneOff, 0);
-
- // Enable Extended Telemetry.
- yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]});
-
- // Make sure to restore the engine once we're done.
- registerCleanupFunction(function* () {
- Services.search.currentEngine = originalEngine;
- Services.search.removeEngine(engineDefault);
- Services.search.removeEngine(engineOneOff);
- });
-});
-
-add_task(function* test_plainQuery() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Simulate entering a simple search.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInSearchbar("simple query");
- EventUtils.sendKey("return");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_SEARCHBAR, "search_enter", 1);
- Assert.equal(Object.keys(scalars[SCALAR_SEARCHBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.searchbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "searchbar", "enter", {engine: "other-MozSearch"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_oneOff() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Perform a one-off search using the first engine.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInSearchbar("query");
-
- info("Pressing Alt+Down to highlight the first one off engine.");
- EventUtils.synthesizeKey("VK_DOWN", { altKey: true });
- EventUtils.sendKey("return");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_SEARCHBAR, "search_oneoff", 1);
- Assert.equal(Object.keys(scalars[SCALAR_SEARCHBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch2.searchbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "searchbar", "oneoff", {engine: "other-MozSearch2"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_suggestion() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- // Create an engine to generate search suggestions and add it as default
- // for this test.
- const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
- let suggestionEngine = yield new Promise((resolve, reject) => {
- Services.search.addEngine(url, null, "", false, {
- onSuccess(engine) { resolve(engine) },
- onError() { reject() }
- });
- });
-
- let previousEngine = Services.search.currentEngine;
- Services.search.currentEngine = suggestionEngine;
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Perform a one-off search using the first engine.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInSearchbar("query");
- info("Clicking the searchbar suggestion.");
- clickSearchbarSuggestion("queryfoo");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_SEARCHBAR, "search_suggestion", 1);
- Assert.equal(Object.keys(scalars[SCALAR_SEARCHBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- let searchEngineId = 'other-' + suggestionEngine.name;
- checkKeyedHistogram(search_hist, searchEngineId + '.searchbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "searchbar", "suggestion", {engine: searchEngineId}]]);
-
- Services.search.currentEngine = previousEngine;
- Services.search.removeEngine(suggestionEngine);
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/modules/test/browser_UsageTelemetry_urlbar.js b/browser/modules/test/browser_UsageTelemetry_urlbar.js
deleted file mode 100644
index 81d3e28ba..000000000
--- a/browser/modules/test/browser_UsageTelemetry_urlbar.js
+++ /dev/null
@@ -1,220 +0,0 @@
-"use strict";
-
-const SCALAR_URLBAR = "browser.engagement.navigation.urlbar";
-
-// The preference to enable suggestions in the urlbar.
-const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
-// The name of the search engine used to generate suggestions.
-const SUGGESTION_ENGINE_NAME = "browser_UsageTelemetry usageTelemetrySearchSuggestions.xml";
-const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
-
-let searchInAwesomebar = Task.async(function* (inputText, win=window) {
- yield new Promise(r => waitForFocus(r, win));
- // Write the search query in the urlbar.
- win.gURLBar.focus();
- win.gURLBar.value = inputText;
- win.gURLBar.controller.startSearch(inputText);
- // Wait for the popup to show.
- yield BrowserTestUtils.waitForEvent(win.gURLBar.popup, "popupshown");
- // And then for the search to complete.
- yield BrowserTestUtils.waitForCondition(() => win.gURLBar.controller.searchStatus >=
- Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
-});
-
-/**
- * Click one of the entries in the urlbar suggestion popup.
- *
- * @param {String} entryName
- * The name of the elemet to click on.
- */
-function clickURLBarSuggestion(entryName) {
- // The entry in the suggestion list should follow the format:
- // "<search term> <engine name> Search"
- const expectedSuggestionName = entryName + " " + SUGGESTION_ENGINE_NAME + " Search";
- for (let child of gURLBar.popup.richlistbox.children) {
- if (child.label === expectedSuggestionName) {
- // This entry is the search suggestion we're looking for.
- child.click();
- return;
- }
- }
-}
-
-add_task(function* setup() {
- // Create a new search engine.
- Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET",
- "http://example.com/?q={searchTerms}");
-
- // Make it the default search engine.
- let engine = Services.search.getEngineByName("MozSearch");
- let originalEngine = Services.search.currentEngine;
- Services.search.currentEngine = engine;
-
- // And the first one-off engine.
- Services.search.moveEngine(engine, 0);
-
- // Enable search suggestions in the urlbar.
- Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
-
- // Enable the urlbar one-off buttons.
- Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true);
-
- // Enable Extended Telemetry.
- yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]});
-
- // Make sure to restore the engine once we're done.
- registerCleanupFunction(function* () {
- Services.search.currentEngine = originalEngine;
- Services.search.removeEngine(engine);
- Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF, true);
- Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF);
- });
-});
-
-add_task(function* test_simpleQuery() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Simulate entering a simple search.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInAwesomebar("simple query");
- EventUtils.sendKey("return");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_URLBAR, "search_enter", 1);
- Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "urlbar", "enter", {engine: "other-MozSearch"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_searchAlias() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Search using a search alias.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInAwesomebar("mozalias query");
- EventUtils.sendKey("return");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_URLBAR, "search_alias", 1);
- Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "urlbar", "alias", {engine: "other-MozSearch"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_oneOff() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Perform a one-off search using the first engine.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInAwesomebar("query");
-
- info("Pressing Alt+Down to take us to the first one-off engine.");
- EventUtils.synthesizeKey("VK_DOWN", { altKey: true });
- EventUtils.sendKey("return");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_URLBAR, "search_oneoff", 1);
- Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "urlbar", "oneoff", {engine: "other-MozSearch"}]]);
-
- yield BrowserTestUtils.removeTab(tab);
-});
-
-add_task(function* test_suggestion() {
- // Let's reset the counts.
- Services.telemetry.clearScalars();
- Services.telemetry.clearEvents();
- let search_hist = getSearchCountsHistogram();
-
- // Create an engine to generate search suggestions and add it as default
- // for this test.
- const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
- let suggestionEngine = yield new Promise((resolve, reject) => {
- Services.search.addEngine(url, null, "", false, {
- onSuccess(engine) { resolve(engine) },
- onError() { reject() }
- });
- });
-
- let previousEngine = Services.search.currentEngine;
- Services.search.currentEngine = suggestionEngine;
-
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
-
- info("Perform a one-off search using the first engine.");
- let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
- yield searchInAwesomebar("query");
- info("Clicking the urlbar suggestion.");
- clickURLBarSuggestion("queryfoo");
- yield p;
-
- // Check if the scalars contain the expected values.
- const scalars =
- Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- checkKeyedScalar(scalars, SCALAR_URLBAR, "search_suggestion", 1);
- Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1,
- "This search must only increment one entry in the scalar.");
-
- // Make sure SEARCH_COUNTS contains identical values.
- let searchEngineId = 'other-' + suggestionEngine.name;
- checkKeyedHistogram(search_hist, searchEngineId + '.urlbar', 1);
-
- // Also check events.
- let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
- events = events.filter(e => e[1] == "navigation" && e[2] == "search");
- checkEvents(events, [["navigation", "search", "urlbar", "suggestion", {engine: searchEngineId}]]);
-
- Services.search.currentEngine = previousEngine;
- Services.search.removeEngine(suggestionEngine);
- yield BrowserTestUtils.removeTab(tab);
-});
diff --git a/browser/modules/test/browser_taskbar_preview.js b/browser/modules/test/browser_taskbar_preview.js
deleted file mode 100644
index 89295b9e0..000000000
--- a/browser/modules/test/browser_taskbar_preview.js
+++ /dev/null
@@ -1,100 +0,0 @@
-function test() {
- var isWin7OrHigher = false;
- try {
- let version = Cc["@mozilla.org/system-info;1"]
- .getService(Ci.nsIPropertyBag2)
- .getProperty("version");
- isWin7OrHigher = (parseFloat(version) >= 6.1);
- } catch (ex) { }
-
- is(!!Win7Features, isWin7OrHigher, "Win7Features available when it should be");
- if (!isWin7OrHigher)
- return;
-
- const ENABLE_PREF_NAME = "browser.taskbar.previews.enable";
-
- let temp = {};
- Cu.import("resource:///modules/WindowsPreviewPerTab.jsm", temp);
- let AeroPeek = temp.AeroPeek;
-
- waitForExplicitFinish();
-
- gPrefService.setBoolPref(ENABLE_PREF_NAME, true);
-
- is(1, AeroPeek.windows.length, "Got the expected number of windows");
-
- checkPreviews(1, "Browser starts with one preview");
-
- gBrowser.addTab();
- gBrowser.addTab();
- gBrowser.addTab();
-
- checkPreviews(4, "Correct number of previews after adding");
-
- for (let preview of AeroPeek.previews)
- ok(preview.visible, "Preview is shown as expected");
-
- gPrefService.setBoolPref(ENABLE_PREF_NAME, false);
- is(0, AeroPeek.previews.length, "Should have 0 previews when disabled");
-
- gPrefService.setBoolPref(ENABLE_PREF_NAME, true);
- checkPreviews(4, "Previews are back when re-enabling");
- for (let preview of AeroPeek.previews)
- ok(preview.visible, "Preview is shown as expected after re-enabling");
-
- [1, 2, 3, 4].forEach(function (idx) {
- gBrowser.selectedTab = gBrowser.tabs[idx];
- ok(checkSelectedTab(), "Current tab is correctly selected");
- });
-
- // Close #4
- getPreviewForTab(gBrowser.selectedTab).controller.onClose();
- checkPreviews(3, "Expected number of previews after closing selected tab via controller");
- ok(gBrowser.tabs.length == 3, "Successfully closed a tab");
-
- // Select #1
- ok(getPreviewForTab(gBrowser.tabs[0]).controller.onActivate(), "Activation was accepted");
- ok(gBrowser.tabs[0].selected, "Correct tab was selected");
- checkSelectedTab();
-
- // Remove #3 (non active)
- gBrowser.removeTab(gBrowser.tabContainer.lastChild);
- checkPreviews(2, "Expected number of previews after closing unselected via browser");
-
- // Remove #1 (active)
- gBrowser.removeTab(gBrowser.tabContainer.firstChild);
- checkPreviews(1, "Expected number of previews after closing selected tab via browser");
-
- // Add a new tab
- gBrowser.addTab();
- checkPreviews(2);
- // Check default selection
- checkSelectedTab();
-
- // Change selection
- gBrowser.selectedTab = gBrowser.tabs[0];
- checkSelectedTab();
- // Close nonselected tab via controller
- getPreviewForTab(gBrowser.tabs[1]).controller.onClose();
- checkPreviews(1);
-
- if (gPrefService.prefHasUserValue(ENABLE_PREF_NAME))
- gPrefService.setBoolPref(ENABLE_PREF_NAME, !gPrefService.getBoolPref(ENABLE_PREF_NAME));
-
- finish();
-
- function checkPreviews(aPreviews, msg) {
- let nPreviews = AeroPeek.previews.length;
- is(aPreviews, gBrowser.tabs.length, "Browser has expected number of tabs - " + msg);
- is(nPreviews, gBrowser.tabs.length, "Browser has one preview per tab - " + msg);
- is(nPreviews, aPreviews, msg || "Got expected number of previews");
- }
-
- function getPreviewForTab(tab) {
- return window.gTaskbarTabGroup.previewFromTab(tab);
- }
-
- function checkSelectedTab() {
- return getPreviewForTab(gBrowser.selectedTab).active;
- }
-}
diff --git a/browser/modules/test/browser_urlBar_zoom.js b/browser/modules/test/browser_urlBar_zoom.js
deleted file mode 100644
index 9cb5c96c6..000000000
--- a/browser/modules/test/browser_urlBar_zoom.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var initialPageZoom = ZoomManager.zoom;
-const kTimeoutInMS = 20000;
-
-add_task(function* () {
- info("Confirm whether the browser zoom is set to the default level");
- is(initialPageZoom, 1, "Page zoom is set to default (100%)");
- let zoomResetButton = document.getElementById("urlbar-zoom-button");
- is(zoomResetButton.hidden, true, "Zoom reset button is currently hidden");
-
- info("Change zoom and confirm zoom button appears");
- let labelUpdatePromise = BrowserTestUtils.waitForAttribute("label", zoomResetButton);
- FullZoom.enlarge();
- yield labelUpdatePromise;
- info("Zoom increased to " + Math.floor(ZoomManager.zoom * 100) + "%");
- is(zoomResetButton.hidden, false, "Zoom reset button is now visible");
- let pageZoomLevel = Math.floor(ZoomManager.zoom * 100);
- let expectedZoomLevel = 110;
- let buttonZoomLevel = parseInt(zoomResetButton.getAttribute("label"), 10);
- is(buttonZoomLevel, expectedZoomLevel, ("Button label updated successfully to " + Math.floor(ZoomManager.zoom * 100) + "%"));
-
- let zoomResetPromise = promiseObserverNotification("browser-fullZoom:zoomReset");
- zoomResetButton.click();
- yield zoomResetPromise;
- pageZoomLevel = Math.floor(ZoomManager.zoom * 100);
- expectedZoomLevel = 100;
- is(pageZoomLevel, expectedZoomLevel, "Clicking zoom button successfully resets browser zoom to 100%");
- is(zoomResetButton.hidden, true, "Zoom reset button returns to being hidden");
-
-});
-
-add_task(function* () {
- info("Confirm that URL bar zoom button doesn't appear when customizable zoom widget is added to toolbar");
- CustomizableUI.addWidgetToArea("zoom-controls", CustomizableUI.AREA_NAVBAR);
- let zoomCustomizableWidget = document.getElementById("zoom-reset-button");
- let zoomResetButton = document.getElementById("urlbar-zoom-button");
- let zoomChangePromise = promiseObserverNotification("browser-fullZoom:zoomChange");
- FullZoom.enlarge();
- yield zoomChangePromise;
- is(zoomResetButton.hidden, true, "URL zoom button remains hidden despite zoom increase");
- is(parseInt(zoomCustomizableWidget.label, 10), 110, "Customizable zoom widget's label has updated to " + zoomCustomizableWidget.label);
-});
-
-add_task(function* asyncCleanup() {
- // reset zoom level and customizable widget
- ZoomManager.zoom = initialPageZoom;
- is(ZoomManager.zoom, 1, "Zoom level was restored");
- if (document.getElementById("zoom-controls")) {
- CustomizableUI.removeWidgetFromArea("zoom-controls", CustomizableUI.AREA_NAVBAR);
- ok(!document.getElementById("zoom-controls"), "Customizable zoom widget removed from toolbar");
- }
-
-});
-
-function promiseObserverNotification(aObserver) {
- let deferred = Promise.defer();
- function notificationCallback(e) {
- Services.obs.removeObserver(notificationCallback, aObserver, false);
- clearTimeout(timeoutId);
- deferred.resolve();
- }
- let timeoutId = setTimeout(() => {
- Services.obs.removeObserver(notificationCallback, aObserver, false);
- deferred.reject("Notification '" + aObserver + "' did not happen within 20 seconds.");
- }, kTimeoutInMS);
- Services.obs.addObserver(notificationCallback, aObserver, false);
- return deferred.promise;
-}
diff --git a/browser/modules/test/contentSearch.js b/browser/modules/test/contentSearch.js
deleted file mode 100644
index b5dddfe45..000000000
--- a/browser/modules/test/contentSearch.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const TEST_MSG = "ContentSearchTest";
-const SERVICE_EVENT_TYPE = "ContentSearchService";
-const CLIENT_EVENT_TYPE = "ContentSearchClient";
-
-// Forward events from the in-content service to the test.
-content.addEventListener(SERVICE_EVENT_TYPE, event => {
- // The event dispatch code in content.js clones the event detail into the
- // content scope. That's generally the right thing, but causes us to end
- // up with an XrayWrapper to it here, which will screw us up when trying to
- // serialize the object in sendAsyncMessage. Waive Xrays for the benefit of
- // the test machinery.
- sendAsyncMessage(TEST_MSG, Components.utils.waiveXrays(event.detail));
-});
-
-// Forward messages from the test to the in-content service.
-addMessageListener(TEST_MSG, msg => {
- // If the message is a search, stop the page from loading and then tell the
- // test that it loaded.
- if (msg.data.type == "Search") {
- waitForLoadAndStopIt(msg.data.expectedURL, url => {
- sendAsyncMessage(TEST_MSG, {
- type: "loadStopped",
- url: url,
- });
- });
- }
-
- content.dispatchEvent(
- new content.CustomEvent(CLIENT_EVENT_TYPE, {
- detail: msg.data,
- })
- );
-});
-
-function waitForLoadAndStopIt(expectedURL, callback) {
- let Ci = Components.interfaces;
- let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebProgress);
- let listener = {
- onStateChange: function (webProg, req, flags, status) {
- if (req instanceof Ci.nsIChannel) {
- let url = req.originalURI.spec;
- dump("waitForLoadAndStopIt: onStateChange " + url + "\n");
- let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
- Ci.nsIWebProgressListener.STATE_START;
- if ((flags & docStart) && webProg.isTopLevel && url == expectedURL) {
- webProgress.removeProgressListener(listener);
- req.cancel(Components.results.NS_ERROR_FAILURE);
- callback(url);
- }
- }
- },
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference,
- ]),
- };
- webProgress.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL);
- dump("waitForLoadAndStopIt: Waiting for URL to load: " + expectedURL + "\n");
-}
diff --git a/browser/modules/test/contentSearchBadImage.xml b/browser/modules/test/contentSearchBadImage.xml
deleted file mode 100644
index 6e4cb60a5..000000000
--- a/browser/modules/test/contentSearchBadImage.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_ContentSearch contentSearchBadImage.xml</ShortName>
-<Url type="text/html" method="GET" template="http://browser-ContentSearch.com/contentSearchBadImage" rel="searchform"/>
-<Image width="16" height="16">data:image/x-icon;base64,notbase64</Image>
-</SearchPlugin>
diff --git a/browser/modules/test/contentSearchSuggestions.sjs b/browser/modules/test/contentSearchSuggestions.sjs
deleted file mode 100644
index 1978b4f66..000000000
--- a/browser/modules/test/contentSearchSuggestions.sjs
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function handleRequest(req, resp) {
- let suffixes = ["foo", "bar"];
- let data = [req.queryString, suffixes.map(s => req.queryString + s)];
- resp.setHeader("Content-Type", "application/json", false);
- resp.write(JSON.stringify(data));
-}
diff --git a/browser/modules/test/contentSearchSuggestions.xml b/browser/modules/test/contentSearchSuggestions.xml
deleted file mode 100644
index 81c23379c..000000000
--- a/browser/modules/test/contentSearchSuggestions.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_ContentSearch contentSearchSuggestions.xml</ShortName>
-<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/modules/test/contentSearchSuggestions.sjs?{searchTerms}"/>
-<Url type="text/html" method="GET" template="http://browser-ContentSearch.com/contentSearchSuggestions" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/modules/test/head.js b/browser/modules/test/head.js
deleted file mode 100644
index be0215156..000000000
--- a/browser/modules/test/head.js
+++ /dev/null
@@ -1,113 +0,0 @@
-Cu.import("resource://gre/modules/Promise.jsm");
-
-const SINGLE_TRY_TIMEOUT = 100;
-const NUMBER_OF_TRIES = 30;
-
-function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES) {
- let defer = Promise.defer();
- let tries = 0;
- function checkCondition() {
- if (tries >= tryCount) {
- defer.reject(timeoutMsg);
- }
- var conditionPassed;
- try {
- conditionPassed = condition();
- } catch (e) {
- return defer.reject(e);
- }
- if (conditionPassed) {
- return defer.resolve();
- }
- tries++;
- setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
- return undefined;
- }
- setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
- return defer.promise;
-}
-
-function waitForCondition(condition, nextTest, errorMsg) {
- waitForConditionPromise(condition, errorMsg).then(nextTest, (reason) => {
- ok(false, reason + (reason.stack ? "\n" + reason.stack : ""));
- });
-}
-
-/**
- * Checks if the snapshotted keyed scalars contain the expected
- * data.
- *
- * @param {Object} scalars
- * The snapshot of the keyed scalars.
- * @param {String} scalarName
- * The name of the keyed scalar to check.
- * @param {String} key
- * The key that must be within the keyed scalar.
- * @param {String|Boolean|Number} expectedValue
- * The expected value for the provided key in the scalar.
- */
-function checkKeyedScalar(scalars, scalarName, key, expectedValue) {
- Assert.ok(scalarName in scalars,
- scalarName + " must be recorded.");
- Assert.ok(key in scalars[scalarName],
- scalarName + " must contain the '" + key + "' key.");
- Assert.ok(scalars[scalarName][key], expectedValue,
- scalarName + "['" + key + "'] must contain the expected value");
-}
-
-/**
- * An utility function to write some text in the search input box
- * in a content page.
- * @param {Object} browser
- * The browser that contains the content.
- * @param {String} text
- * The string to write in the search field.
- * @param {String} fieldName
- * The name of the field to write to.
- */
-let typeInSearchField = Task.async(function* (browser, text, fieldName) {
- yield ContentTask.spawn(browser, { fieldName, text }, function* ({fieldName, text}) {
- // Avoid intermittent failures.
- if (fieldName === "searchText") {
- content.wrappedJSObject.gContentSearchController.remoteTimeout = 5000;
- }
- // Put the focus on the search box.
- let searchInput = content.document.getElementById(fieldName);
- searchInput.focus();
- searchInput.value = text;
- });
-});
-
-/**
- * Clear and get the SEARCH_COUNTS histogram.
- */
-function getSearchCountsHistogram() {
- let search_hist = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
- search_hist.clear();
- return search_hist;
-}
-
-/**
- * Check that the keyed histogram contains the right value.
- */
-function checkKeyedHistogram(h, key, expectedValue) {
- const snapshot = h.snapshot();
- Assert.ok(key in snapshot, `The histogram must contain ${key}.`);
- Assert.equal(snapshot[key].sum, expectedValue, `The key ${key} must contain ${expectedValue}.`);
-}
-
-function checkEvents(events, expectedEvents) {
- if (!Services.telemetry.canRecordExtended) {
- // Currently we only collect the tested events when extended Telemetry is enabled.
- return;
- }
-
- Assert.equal(events.length, expectedEvents.length, "Should have matching amount of events.");
-
- // Strip timestamps from the events for easier comparison.
- events = events.map(e => e.slice(1));
-
- for (let i = 0; i < events.length; ++i) {
- Assert.deepEqual(events[i], expectedEvents[i], "Events should match.");
- }
-}
diff --git a/browser/modules/test/unit/social/.eslintrc.js b/browser/modules/test/unit/social/.eslintrc.js
deleted file mode 100644
index d35787cd2..000000000
--- a/browser/modules/test/unit/social/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/modules/test/unit/social/blocklist.xml b/browser/modules/test/unit/social/blocklist.xml
deleted file mode 100644
index c8d72d624..000000000
--- a/browser/modules/test/unit/social/blocklist.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
- <emItems>
- <emItem blockID="s1" id="bad.com@services.mozilla.org"></emItem>
- </emItems>
-</blocklist>
diff --git a/browser/modules/test/unit/social/head.js b/browser/modules/test/unit/social/head.js
deleted file mode 100644
index 0beabb685..000000000
--- a/browser/modules/test/unit/social/head.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var Social, SocialService;
-
-var manifests = [
- {
- name: "provider 1",
- origin: "https://example1.com",
- sidebarURL: "https://example1.com/sidebar/",
- },
- {
- name: "provider 2",
- origin: "https://example2.com",
- sidebarURL: "https://example1.com/sidebar/",
- }
-];
-
-const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
-
-// SocialProvider class relies on blocklisting being enabled. To enable
-// blocklisting, we have to setup an app and initialize the blocklist (see
-// initApp below).
-const gProfD = do_get_profile();
-
-function createAppInfo(ID, name, version, platformVersion="1.0") {
- let tmp = {};
- Cu.import("resource://testing-common/AppInfo.jsm", tmp);
- tmp.updateAppInfo({
- ID, name, version, platformVersion,
- crashReporter: true,
- });
- gAppInfo = tmp.getAppInfo();
-}
-
-function initApp() {
- createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
- // prepare a blocklist file for the blocklist service
- var blocklistFile = gProfD.clone();
- blocklistFile.append("blocklist.xml");
- if (blocklistFile.exists())
- blocklistFile.remove(false);
- var source = do_get_file("blocklist.xml");
- source.copyTo(gProfD, "blocklist.xml");
- blocklistFile.lastModifiedTime = Date.now();
-
-
- let internalManager = Cc["@mozilla.org/addons/integration;1"].
- getService(Ci.nsIObserver).
- QueryInterface(Ci.nsITimerCallback);
-
- internalManager.observe(null, "addons-startup", null);
-}
-
-function setManifestPref(manifest) {
- let string = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- string.data = JSON.stringify(manifest);
- Services.prefs.setComplexValue("social.manifest." + manifest.origin, Ci.nsISupportsString, string);
-}
-
-function do_wait_observer(obsTopic, cb) {
- function observer(subject, topic, data) {
- Services.obs.removeObserver(observer, topic);
- cb();
- }
- Services.obs.addObserver(observer, obsTopic, false);
-}
-
-function do_add_providers(cb) {
- // run only after social is already initialized
- SocialService.addProvider(manifests[0], function() {
- do_wait_observer("social:providers-changed", function() {
- do_check_eq(Social.providers.length, 2, "2 providers installed");
- do_execute_soon(cb);
- });
- SocialService.addProvider(manifests[1]);
- });
-}
-
-function do_initialize_social(enabledOnStartup, cb) {
- initApp();
-
- if (enabledOnStartup) {
- // set prefs before initializing social
- manifests.forEach(function (manifest) {
- setManifestPref(manifest);
- });
- // Set both providers active and flag the first one as "current"
- let activeVal = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- let active = {};
- for (let m of manifests)
- active[m.origin] = 1;
- activeVal.data = JSON.stringify(active);
- Services.prefs.setComplexValue("social.activeProviders",
- Ci.nsISupportsString, activeVal);
-
- do_register_cleanup(function() {
- manifests.forEach(function (manifest) {
- Services.prefs.clearUserPref("social.manifest." + manifest.origin);
- });
- Services.prefs.clearUserPref("social.activeProviders");
- });
-
- // expecting 2 providers installed
- do_wait_observer("social:providers-changed", function() {
- do_check_eq(Social.providers.length, 2, "2 providers installed");
- do_execute_soon(cb);
- });
- }
-
- // import and initialize everything
- SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
- do_check_eq(enabledOnStartup, SocialService.hasEnabledProviders, "Service has enabled providers");
- Social = Cu.import("resource:///modules/Social.jsm", {}).Social;
- do_check_false(Social.initialized, "Social is not initialized");
- Social.init();
- do_check_true(Social.initialized, "Social is initialized");
- if (!enabledOnStartup)
- do_execute_soon(cb);
-}
-
-function AsyncRunner() {
- do_test_pending();
- do_register_cleanup(() => this.destroy());
-
- this._callbacks = {
- done: do_test_finished,
- error: function (err) {
- // xpcshell test functions like do_check_eq throw NS_ERROR_ABORT on
- // failure. Ignore those so they aren't rethrown here.
- if (err !== Cr.NS_ERROR_ABORT) {
- if (err.stack) {
- err = err + " - See following stack:\n" + err.stack +
- "\nUseless do_throw stack";
- }
- do_throw(err);
- }
- },
- consoleError: function (scriptErr) {
- // Try to ensure the error is related to the test.
- let filename = scriptErr.sourceName || scriptErr.toString() || "";
- if (filename.indexOf("/toolkit/components/social/") >= 0)
- do_throw(scriptErr);
- },
- };
- this._iteratorQueue = [];
-
- // This catches errors reported to the console, e.g., via Cu.reportError, but
- // not on the runner's stack.
- Cc["@mozilla.org/consoleservice;1"].
- getService(Ci.nsIConsoleService).
- registerListener(this);
-}
-
-AsyncRunner.prototype = {
-
- appendIterator: function appendIterator(iter) {
- this._iteratorQueue.push(iter);
- },
-
- next: function next(arg) {
- if (!this._iteratorQueue.length) {
- this.destroy();
- this._callbacks.done();
- return;
- }
-
- try {
- var { done, value: val } = this._iteratorQueue[0].next(arg);
- if (done) {
- this._iteratorQueue.shift();
- this.next();
- return;
- }
- }
- catch (err) {
- this._callbacks.error(err);
- }
-
- // val is an iterator => prepend it to the queue and start on it
- // val is otherwise truthy => call next
- if (val) {
- if (typeof(val) != "boolean")
- this._iteratorQueue.unshift(val);
- this.next();
- }
- },
-
- destroy: function destroy() {
- Cc["@mozilla.org/consoleservice;1"].
- getService(Ci.nsIConsoleService).
- unregisterListener(this);
- this.destroy = function alreadyDestroyed() {};
- },
-
- observe: function observe(msg) {
- if (msg instanceof Ci.nsIScriptError &&
- !(msg.flags & Ci.nsIScriptError.warningFlag))
- {
- this._callbacks.consoleError(msg);
- }
- },
-};
diff --git a/browser/modules/test/unit/social/test_SocialService.js b/browser/modules/test/unit/social/test_SocialService.js
deleted file mode 100644
index e6f354fed..000000000
--- a/browser/modules/test/unit/social/test_SocialService.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-function run_test() {
- initApp();
-
- // NOTE: none of the manifests here can have a workerURL set, or we attempt
- // to create a FrameWorker and that fails under xpcshell...
- let manifests = [
- { // normal provider
- name: "provider 1",
- origin: "https://example1.com",
- shareURL: "https://example1.com/share/",
- },
- { // provider without workerURL
- name: "provider 2",
- origin: "https://example2.com",
- shareURL: "https://example2.com/share/",
- }
- ];
-
- Cu.import("resource:///modules/SocialService.jsm");
-
- let runner = new AsyncRunner();
- let next = runner.next.bind(runner);
- runner.appendIterator(testAddProviders(manifests, next));
- runner.appendIterator(testGetProvider(manifests, next));
- runner.appendIterator(testGetProviderList(manifests, next));
- runner.appendIterator(testAddRemoveProvider(manifests, next));
- runner.appendIterator(testIsSameOrigin(manifests, next));
- runner.appendIterator(testResolveUri (manifests, next));
- runner.appendIterator(testOrderedProviders(manifests, next));
- runner.appendIterator(testRemoveProviders(manifests, next));
- runner.next();
-}
-
-function* testAddProviders(manifests, next) {
- do_check_false(SocialService.enabled);
- let provider = yield SocialService.addProvider(manifests[0], next);
- do_check_true(SocialService.enabled);
- do_check_false(provider.enabled);
- provider = yield SocialService.addProvider(manifests[1], next);
- do_check_false(provider.enabled);
-}
-
-function* testRemoveProviders(manifests, next) {
- do_check_true(SocialService.enabled);
- yield SocialService.disableProvider(manifests[0].origin, next);
- yield SocialService.disableProvider(manifests[1].origin, next);
- do_check_false(SocialService.enabled);
-}
-
-function* testGetProvider(manifests, next) {
- for (let i = 0; i < manifests.length; i++) {
- let manifest = manifests[i];
- let provider = yield SocialService.getProvider(manifest.origin, next);
- do_check_neq(provider, null);
- do_check_eq(provider.name, manifest.name);
- do_check_eq(provider.workerURL, manifest.workerURL);
- do_check_eq(provider.origin, manifest.origin);
- }
- do_check_eq((yield SocialService.getProvider("bogus", next)), null);
-}
-
-function* testGetProviderList(manifests, next) {
- let providers = yield SocialService.getProviderList(next);
- do_check_true(providers.length >= manifests.length);
- for (let i = 0; i < manifests.length; i++) {
- let providerIdx = providers.map(p => p.origin).indexOf(manifests[i].origin);
- let provider = providers[providerIdx];
- do_check_true(!!provider);
- do_check_false(provider.enabled);
- do_check_eq(provider.workerURL, manifests[i].workerURL);
- do_check_eq(provider.name, manifests[i].name);
- }
-}
-
-function* testAddRemoveProvider(manifests, next) {
- var threw;
- try {
- // Adding a provider whose origin already exists should fail
- SocialService.addProvider(manifests[0]);
- } catch (ex) {
- threw = ex;
- }
- do_check_neq(threw.toString().indexOf("SocialService.addProvider: provider with this origin already exists"), -1);
-
- let originalProviders = yield SocialService.getProviderList(next);
-
- // Check that provider installation succeeds
- let newProvider = yield SocialService.addProvider({
- name: "foo",
- origin: "http://example3.com"
- }, next);
- let retrievedNewProvider = yield SocialService.getProvider(newProvider.origin, next);
- do_check_eq(newProvider, retrievedNewProvider);
-
- let providersAfter = yield SocialService.getProviderList(next);
- do_check_eq(providersAfter.length, originalProviders.length + 1);
- do_check_neq(providersAfter.indexOf(newProvider), -1);
-
- // Now remove the provider
- yield SocialService.disableProvider(newProvider.origin, next);
- providersAfter = yield SocialService.getProviderList(next);
- do_check_eq(providersAfter.length, originalProviders.length);
- do_check_eq(providersAfter.indexOf(newProvider), -1);
- newProvider = yield SocialService.getProvider(newProvider.origin, next);
- do_check_true(!newProvider);
-}
-
-function* testIsSameOrigin(manifests, next) {
- let providers = yield SocialService.getProviderList(next);
- let provider = providers[0];
- // provider.origin is a string.
- do_check_true(provider.isSameOrigin(provider.origin));
- do_check_true(provider.isSameOrigin(Services.io.newURI(provider.origin, null, null)));
- do_check_true(provider.isSameOrigin(provider.origin + "/some-sub-page"));
- do_check_true(provider.isSameOrigin(Services.io.newURI(provider.origin + "/some-sub-page", null, null)));
- do_check_false(provider.isSameOrigin("http://something.com"));
- do_check_false(provider.isSameOrigin(Services.io.newURI("http://something.com", null, null)));
- do_check_false(provider.isSameOrigin("data:text/html,<p>hi"));
- do_check_true(provider.isSameOrigin("data:text/html,<p>hi", true));
- do_check_false(provider.isSameOrigin(Services.io.newURI("data:text/html,<p>hi", null, null)));
- do_check_true(provider.isSameOrigin(Services.io.newURI("data:text/html,<p>hi", null, null), true));
- // we explicitly handle null and return false
- do_check_false(provider.isSameOrigin(null));
-}
-
-function* testResolveUri(manifests, next) {
- let providers = yield SocialService.getProviderList(next);
- let provider = providers[0];
- do_check_eq(provider.resolveUri(provider.origin).spec, provider.origin + "/");
- do_check_eq(provider.resolveUri("foo.html").spec, provider.origin + "/foo.html");
- do_check_eq(provider.resolveUri("/foo.html").spec, provider.origin + "/foo.html");
- do_check_eq(provider.resolveUri("http://somewhereelse.com/foo.html").spec, "http://somewhereelse.com/foo.html");
- do_check_eq(provider.resolveUri("data:text/html,<p>hi").spec, "data:text/html,<p>hi");
-}
-
-function* testOrderedProviders(manifests, next) {
- let providers = yield SocialService.getProviderList(next);
-
- // add visits for only one of the providers
- let visits = [];
- let startDate = Date.now() * 1000;
- for (let i = 0; i < 10; i++) {
- visits.push({
- uri: Services.io.newURI(providers[1].shareURL + i, null, null),
- visitDate: startDate + i
- });
- }
-
- PlacesTestUtils.addVisits(visits).then(next);
- yield;
- let orderedProviders = yield SocialService.getOrderedProviderList(next);
- do_check_eq(orderedProviders[0], providers[1]);
- do_check_eq(orderedProviders[1], providers[0]);
- do_check_true(orderedProviders[0].frecency > orderedProviders[1].frecency);
- PlacesTestUtils.clearHistory().then(next);
- yield;
-}
diff --git a/browser/modules/test/unit/social/test_SocialServiceMigration21.js b/browser/modules/test/unit/social/test_SocialServiceMigration21.js
deleted file mode 100644
index dfe6183bf..000000000
--- a/browser/modules/test/unit/social/test_SocialServiceMigration21.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-const DEFAULT_PREFS = Services.prefs.getDefaultBranch("social.manifest.");
-
-function run_test() {
- // Test must run at startup for migration to occur, so we can only test
- // one migration per test file
- initApp();
-
- // NOTE: none of the manifests here can have a workerURL set, or we attempt
- // to create a FrameWorker and that fails under xpcshell...
- let manifest = { // normal provider
- name: "provider 1",
- origin: "https://example1.com",
- builtin: true // as of fx22 this should be true for default prefs
- };
-
- DEFAULT_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
- Services.prefs.setBoolPref("social.active", true);
-
- Cu.import("resource:///modules/SocialService.jsm");
-
- let runner = new AsyncRunner();
- let next = runner.next.bind(runner);
- runner.appendIterator(testMigration(manifest, next));
- runner.next();
-}
-
-function* testMigration(manifest, next) {
- // look at social.activeProviders, we should have migrated into that, and
- // we should be set as a user level pref after migration
- do_check_false(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
- // we need to access the providers for everything to initialize
- yield SocialService.getProviderList(next);
- do_check_true(SocialService.enabled);
- do_check_true(Services.prefs.prefHasUserValue("social.activeProviders"));
-
- let activeProviders;
- let pref = Services.prefs.getComplexValue("social.activeProviders",
- Ci.nsISupportsString);
- activeProviders = JSON.parse(pref);
- do_check_true(activeProviders[manifest.origin]);
- do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
- do_check_true(JSON.parse(DEFAULT_PREFS.getCharPref(manifest.origin)).builtin);
-
- let userPref = JSON.parse(MANIFEST_PREFS.getCharPref(manifest.origin));
- do_check_true(parseInt(userPref.updateDate) > 0);
- // migrated providers wont have an installDate
- do_check_true(userPref.installDate === 0);
-}
diff --git a/browser/modules/test/unit/social/test_SocialServiceMigration22.js b/browser/modules/test/unit/social/test_SocialServiceMigration22.js
deleted file mode 100644
index 1a3953175..000000000
--- a/browser/modules/test/unit/social/test_SocialServiceMigration22.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-const DEFAULT_PREFS = Services.prefs.getDefaultBranch("social.manifest.");
-
-function run_test() {
- // Test must run at startup for migration to occur, so we can only test
- // one migration per test file
- initApp();
-
- // NOTE: none of the manifests here can have a workerURL set, or we attempt
- // to create a FrameWorker and that fails under xpcshell...
- let manifest = { // normal provider
- name: "provider 1",
- origin: "https://example1.com",
- builtin: true // as of fx22 this should be true for default prefs
- };
-
- DEFAULT_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
-
- // Set both providers active and flag the first one as "current"
- let activeVal = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- let active = {};
- active[manifest.origin] = 1;
- // bad.origin tests that a missing manifest does not break migration, bug 859715
- active["bad.origin"] = 1;
- activeVal.data = JSON.stringify(active);
- Services.prefs.setComplexValue("social.activeProviders",
- Ci.nsISupportsString, activeVal);
-
- Cu.import("resource:///modules/SocialService.jsm");
-
- let runner = new AsyncRunner();
- let next = runner.next.bind(runner);
- runner.appendIterator(testMigration(manifest, next));
- runner.next();
-}
-
-function* testMigration(manifest, next) {
- // look at social.activeProviders, we should have migrated into that, and
- // we should be set as a user level pref after migration
- do_check_false(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
- // we need to access the providers for everything to initialize
- yield SocialService.getProviderList(next);
- do_check_true(SocialService.enabled);
- do_check_true(Services.prefs.prefHasUserValue("social.activeProviders"));
-
- let activeProviders;
- let pref = Services.prefs.getComplexValue("social.activeProviders",
- Ci.nsISupportsString);
- activeProviders = JSON.parse(pref);
- do_check_true(activeProviders[manifest.origin]);
- do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
- do_check_true(JSON.parse(DEFAULT_PREFS.getCharPref(manifest.origin)).builtin);
-
- let userPref = JSON.parse(MANIFEST_PREFS.getCharPref(manifest.origin));
- do_check_true(parseInt(userPref.updateDate) > 0);
- // migrated providers wont have an installDate
- do_check_true(userPref.installDate === 0);
-
- // bug 859715, this should have been removed during migration
- do_check_false(!!activeProviders["bad.origin"]);
-}
diff --git a/browser/modules/test/unit/social/test_SocialServiceMigration29.js b/browser/modules/test/unit/social/test_SocialServiceMigration29.js
deleted file mode 100644
index 824673ddf..000000000
--- a/browser/modules/test/unit/social/test_SocialServiceMigration29.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-
-function run_test() {
- // Test must run at startup for migration to occur, so we can only test
- // one migration per test file
- initApp();
-
- // NOTE: none of the manifests here can have a workerURL set, or we attempt
- // to create a FrameWorker and that fails under xpcshell...
- let manifest = { // normal provider
- name: "provider 1",
- origin: "https://example1.com",
- };
-
- MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
-
- // Set both providers active and flag the first one as "current"
- let activeVal = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- let active = {};
- active[manifest.origin] = 1;
- activeVal.data = JSON.stringify(active);
- Services.prefs.setComplexValue("social.activeProviders",
- Ci.nsISupportsString, activeVal);
-
- // social.enabled pref is the key focus of this test. We set the user pref,
- // and then migration should a) remove the provider from activeProviders and
- // b) unset social.enabled
- Services.prefs.setBoolPref("social.enabled", false);
-
- Cu.import("resource:///modules/SocialService.jsm");
-
- let runner = new AsyncRunner();
- let next = runner.next.bind(runner);
- runner.appendIterator(testMigration(manifest, next));
- runner.next();
-}
-
-function* testMigration(manifest, next) {
- // look at social.activeProviders, we should have migrated into that, and
- // we should be set as a user level pref after migration
- do_check_true(Services.prefs.prefHasUserValue("social.enabled"));
- do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
- // we need to access the providers for everything to initialize
- yield SocialService.getProviderList(next);
- do_check_false(SocialService.enabled);
- do_check_false(Services.prefs.prefHasUserValue("social.enabled"));
- do_check_true(Services.prefs.prefHasUserValue("social.activeProviders"));
-
- let activeProviders;
- let pref = Services.prefs.getComplexValue("social.activeProviders",
- Ci.nsISupportsString).data;
- activeProviders = JSON.parse(pref);
- do_check_true(activeProviders[manifest.origin] == undefined);
- do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
-}
diff --git a/browser/modules/test/unit/social/test_social.js b/browser/modules/test/unit/social/test_social.js
deleted file mode 100644
index 3117306c1..000000000
--- a/browser/modules/test/unit/social/test_social.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function run_test() {
- // we are testing worker startup specifically
- do_test_pending();
- add_test(testStartupEnabled);
- add_test(testDisableAfterStartup);
- do_initialize_social(true, run_next_test);
-}
-
-function testStartupEnabled() {
- // wait on startup before continuing
- do_check_eq(Social.providers.length, 2, "two social providers enabled");
- do_check_true(Social.providers[0].enabled, "provider 0 is enabled");
- do_check_true(Social.providers[1].enabled, "provider 1 is enabled");
- run_next_test();
-}
-
-function testDisableAfterStartup() {
- let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
- SocialService.disableProvider(Social.providers[0].origin, function() {
- do_wait_observer("social:providers-changed", function() {
- do_check_eq(Social.enabled, false, "Social is disabled");
- do_check_eq(Social.providers.length, 0, "no social providers available");
- do_test_finished();
- run_next_test();
- });
- SocialService.disableProvider(Social.providers[0].origin)
- });
-}
diff --git a/browser/modules/test/unit/social/test_socialDisabledStartup.js b/browser/modules/test/unit/social/test_socialDisabledStartup.js
deleted file mode 100644
index a2f7a1d5a..000000000
--- a/browser/modules/test/unit/social/test_socialDisabledStartup.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function run_test() {
- // we are testing worker startup specifically
- do_test_pending();
- add_test(testStartupDisabled);
- add_test(testEnableAfterStartup);
- do_initialize_social(false, run_next_test);
-}
-
-function testStartupDisabled() {
- // wait on startup before continuing
- do_check_false(Social.enabled, "Social is disabled");
- do_check_eq(Social.providers.length, 0, "zero social providers available");
- run_next_test();
-}
-
-function testEnableAfterStartup() {
- do_add_providers(function () {
- do_check_true(Social.enabled, "Social is enabled");
- do_check_eq(Social.providers.length, 2, "two social providers available");
- do_check_true(Social.providers[0].enabled, "provider 0 is enabled");
- do_check_true(Social.providers[1].enabled, "provider 1 is enabled");
- do_test_finished();
- run_next_test();
- });
-}
diff --git a/browser/modules/test/unit/social/xpcshell.ini b/browser/modules/test/unit/social/xpcshell.ini
deleted file mode 100644
index 277dd4f49..000000000
--- a/browser/modules/test/unit/social/xpcshell.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-support-files = blocklist.xml
-
-[test_social.js]
-[test_socialDisabledStartup.js]
-[test_SocialService.js]
-[test_SocialServiceMigration21.js]
-[test_SocialServiceMigration22.js]
-[test_SocialServiceMigration29.js]
diff --git a/browser/modules/test/usageTelemetrySearchSuggestions.sjs b/browser/modules/test/usageTelemetrySearchSuggestions.sjs
deleted file mode 100644
index 1978b4f66..000000000
--- a/browser/modules/test/usageTelemetrySearchSuggestions.sjs
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function handleRequest(req, resp) {
- let suffixes = ["foo", "bar"];
- let data = [req.queryString, suffixes.map(s => req.queryString + s)];
- resp.setHeader("Content-Type", "application/json", false);
- resp.write(JSON.stringify(data));
-}
diff --git a/browser/modules/test/usageTelemetrySearchSuggestions.xml b/browser/modules/test/usageTelemetrySearchSuggestions.xml
deleted file mode 100644
index 76276045d..000000000
--- a/browser/modules/test/usageTelemetrySearchSuggestions.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-<ShortName>browser_UsageTelemetry usageTelemetrySearchSuggestions.xml</ShortName>
-<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/modules/test/usageTelemetrySearchSuggestions.sjs?{searchTerms}"/>
-<Url type="text/html" method="GET" template="http://example.com" rel="searchform"/>
-</SearchPlugin>
diff --git a/browser/modules/test/xpcshell/.eslintrc.js b/browser/modules/test/xpcshell/.eslintrc.js
deleted file mode 100644
index fee088c17..000000000
--- a/browser/modules/test/xpcshell/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
- "extends": [
- "../../../../testing/xpcshell/xpcshell.eslintrc.js"
- ]
-};
diff --git a/browser/modules/test/xpcshell/test_AttributionCode.js b/browser/modules/test/xpcshell/test_AttributionCode.js
deleted file mode 100644
index d979ae845..000000000
--- a/browser/modules/test/xpcshell/test_AttributionCode.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-"use strict";
-
-const {interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource:///modules/AttributionCode.jsm");
-Cu.import('resource://gre/modules/osfile.jsm');
-Cu.import("resource://gre/modules/Services.jsm");
-
-let validAttrCodes = [
- {code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3D(not%20set)",
- parsed: {"source": "google.com", "medium": "organic",
- "campaign": "(not%20set)", "content": "(not%20set)"}},
- {code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D%26content%3D",
- parsed: {"source": "google.com", "medium": "organic"}},
- {code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)",
- parsed: {"source": "google.com", "medium": "organic", "campaign": "(not%20set)"}},
- {code: "source%3Dgoogle.com%26medium%3Dorganic",
- parsed: {"source": "google.com", "medium": "organic"}},
- {code: "source%3Dgoogle.com",
- parsed: {"source": "google.com"}},
- {code: "medium%3Dgoogle.com",
- parsed: {"medium": "google.com"}},
- {code: "campaign%3Dgoogle.com",
- parsed: {"campaign": "google.com"}},
- {code: "content%3Dgoogle.com",
- parsed: {"content": "google.com"}}
-];
-
-let invalidAttrCodes = [
- // Empty string
- "",
- // Not escaped
- "source=google.com&medium=organic&campaign=(not set)&content=(not set)",
- // Too long
- "source%3Dreallyreallyreallyreallyreallyreallyreallyreallyreallylongdomain.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3Dalmostexactlyenoughcontenttomakethisstringlongerthanthe200characterlimit",
- // Unknown key name
- "source%3Dgoogle.com%26medium%3Dorganic%26large%3Dgeneticallymodified",
- // Empty key name
- "source%3Dgoogle.com%26medium%3Dorganic%26%3Dgeneticallymodified"
-];
-
-function* writeAttributionFile(data) {
- let appDir = Services.dirsvc.get("LocalAppData", Ci.nsIFile);
- let file = appDir.clone();
- file.append(Services.appinfo.vendor || "mozilla");
- file.append(AppConstants.MOZ_APP_NAME);
-
- yield OS.File.makeDir(file.path,
- {from: appDir.path, ignoreExisting: true});
-
- file.append("postSigningData");
- yield OS.File.writeAtomic(file.path, data);
-}
-
-/**
- * Test validation of attribution codes,
- * to make sure we reject bad ones and accept good ones.
- */
-add_task(function* testValidAttrCodes() {
- for (let entry of validAttrCodes) {
- AttributionCode._clearCache();
- yield writeAttributionFile(entry.code);
- let result = yield AttributionCode.getAttrDataAsync();
- Assert.deepEqual(result, entry.parsed,
- "Parsed code should match expected value, code was: " + entry.code);
- }
- AttributionCode._clearCache();
-});
-
-/**
- * Make sure codes with various formatting errors are not seen as valid.
- */
-add_task(function* testInvalidAttrCodes() {
- for (let code of invalidAttrCodes) {
- AttributionCode._clearCache();
- yield writeAttributionFile(code);
- let result = yield AttributionCode.getAttrDataAsync();
- Assert.deepEqual(result, {},
- "Code should have failed to parse: " + code);
- }
- AttributionCode._clearCache();
-});
-
-/**
- * Test the cache by deleting the attribution data file
- * and making sure we still get the expected code.
- */
-add_task(function* testDeletedFile() {
- // Set up the test by clearing the cache and writing a valid file.
- yield writeAttributionFile(validAttrCodes[0].code);
- let result = yield AttributionCode.getAttrDataAsync();
- Assert.deepEqual(result, validAttrCodes[0].parsed,
- "The code should be readable directly from the file");
-
- // Delete the file and make sure we can still read the value back from cache.
- yield AttributionCode.deleteFileAsync();
- result = yield AttributionCode.getAttrDataAsync();
- Assert.deepEqual(result, validAttrCodes[0].parsed,
- "The code should be readable from the cache");
-
- // Clear the cache and check we can't read anything.
- AttributionCode._clearCache();
- result = yield AttributionCode.getAttrDataAsync();
- Assert.deepEqual(result, {},
- "Shouldn't be able to get a code after file is deleted and cache is cleared");
-});
diff --git a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
deleted file mode 100644
index 712f52fa6..000000000
--- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
+++ /dev/null
@@ -1,1854 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-"use strict";
-
-/**
- * This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module.
- */
-
-var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource:///modules/DirectoryLinksProvider.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Http.jsm");
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/osfile.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/PlacesUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
- "resource://gre/modules/NetUtil.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
- "resource://gre/modules/NewTabUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
- "resource://testing-common/PlacesTestUtils.jsm");
-
-do_get_profile();
-
-const DIRECTORY_LINKS_FILE = "directoryLinks.json";
-const DIRECTORY_FRECENCY = 1000;
-const SUGGESTED_FRECENCY = Infinity;
-const kURLData = {"directory": [{"url":"http://example.com", "title":"LocalSource"}]};
-const kTestURL = 'data:application/json,' + JSON.stringify(kURLData);
-
-// DirectoryLinksProvider preferences
-const kLocalePref = DirectoryLinksProvider._observedPrefs.prefSelectedLocale;
-const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL;
-const kPingUrlPref = "browser.newtabpage.directory.ping";
-const kNewtabEnhancedPref = "browser.newtabpage.enhanced";
-
-// httpd settings
-var server;
-const kDefaultServerPort = 9000;
-const kBaseUrl = "http://localhost:" + kDefaultServerPort;
-const kExamplePath = "/exampleTest/";
-const kFailPath = "/fail/";
-const kPingPath = "/ping/";
-const kExampleURL = kBaseUrl + kExamplePath;
-const kFailURL = kBaseUrl + kFailPath;
-const kPingUrl = kBaseUrl + kPingPath;
-
-// app/profile/firefox.js are not avaialble in xpcshell: hence, preset them
-Services.prefs.setCharPref(kLocalePref, "en-US");
-Services.prefs.setCharPref(kSourceUrlPref, kTestURL);
-Services.prefs.setCharPref(kPingUrlPref, kPingUrl);
-Services.prefs.setBoolPref(kNewtabEnhancedPref, true);
-
-const kHttpHandlerData = {};
-kHttpHandlerData[kExamplePath] = {"directory": [{"url":"http://example.com", "title":"RemoteSource"}]};
-
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-
-var gLastRequestPath;
-
-var suggestedTile1 = {
- url: "http://turbotax.com",
- type: "affiliate",
- lastVisitDate: 4,
- adgroup_name: "Adgroup1",
- frecent_sites: [
- "taxact.com",
- "hrblock.com",
- "1040.com",
- "taxslayer.com"
- ]
-};
-var suggestedTile2 = {
- url: "http://irs.gov",
- type: "affiliate",
- lastVisitDate: 3,
- adgroup_name: "Adgroup2",
- frecent_sites: [
- "taxact.com",
- "hrblock.com",
- "freetaxusa.com",
- "taxslayer.com"
- ]
-};
-var suggestedTile3 = {
- url: "http://hrblock.com",
- type: "affiliate",
- lastVisitDate: 2,
- adgroup_name: "Adgroup3",
- frecent_sites: [
- "taxact.com",
- "freetaxusa.com",
- "1040.com",
- "taxslayer.com"
- ]
-};
-var suggestedTile4 = {
- url: "http://sponsoredtile.com",
- type: "sponsored",
- lastVisitDate: 1,
- adgroup_name: "Adgroup4",
- frecent_sites: [
- "sponsoredtarget.com"
- ]
-}
-var suggestedTile5 = {
- url: "http://eviltile.com",
- type: "affiliate",
- lastVisitDate: 5,
- explanation: "This is an evil tile <form><button formaction='javascript:alert(1)''>X</button></form> muhahaha",
- adgroup_name: "WE ARE EVIL <link rel='import' href='test.svg'/>",
- frecent_sites: [
- "eviltarget.com"
- ]
-}
-var someOtherSite = {url: "http://someothersite.com", title: "Not_A_Suggested_Site"};
-
-function getHttpHandler(path) {
- let code = 200;
- let body = JSON.stringify(kHttpHandlerData[path]);
- if (path == kFailPath) {
- code = 204;
- }
- return function(aRequest, aResponse) {
- gLastRequestPath = aRequest.path;
- aResponse.setStatusLine(null, code);
- aResponse.setHeader("Content-Type", "application/json");
- aResponse.write(body);
- };
-}
-
-function isIdentical(actual, expected) {
- if (expected == null) {
- do_check_eq(actual, expected);
- }
- else if (typeof expected == "object") {
- // Make sure all the keys match up
- do_check_eq(Object.keys(actual).sort() + "", Object.keys(expected).sort());
-
- // Recursively check each value individually
- Object.keys(expected).forEach(key => {
- isIdentical(actual[key], expected[key]);
- });
- }
- else {
- do_check_eq(actual, expected);
- }
-}
-
-function fetchData() {
- let deferred = Promise.defer();
-
- DirectoryLinksProvider.getLinks(linkData => {
- deferred.resolve(linkData);
- });
- return deferred.promise;
-}
-
-function readJsonFile(jsonFile = DIRECTORY_LINKS_FILE) {
- let decoder = new TextDecoder();
- let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, jsonFile);
- return OS.File.read(directoryLinksFilePath).then(array => {
- let json = decoder.decode(array);
- return JSON.parse(json);
- }, () => { return "" });
-}
-
-function cleanJsonFile(jsonFile = DIRECTORY_LINKS_FILE) {
- let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, jsonFile);
- return OS.File.remove(directoryLinksFilePath);
-}
-
-function LinksChangeObserver() {
- this.deferred = Promise.defer();
- this.onManyLinksChanged = () => this.deferred.resolve();
- this.onDownloadFail = this.onManyLinksChanged;
-}
-
-function promiseDirectoryDownloadOnPrefChange(pref, newValue) {
- let oldValue = Services.prefs.getCharPref(pref);
- if (oldValue != newValue) {
- // if the preference value is already equal to newValue
- // the pref service will not call our observer and we
- // deadlock. Hence only setup observer if values differ
- let observer = new LinksChangeObserver();
- DirectoryLinksProvider.addObserver(observer);
- Services.prefs.setCharPref(pref, newValue);
- return observer.deferred.promise.then(() => {
- DirectoryLinksProvider.removeObserver(observer);
- });
- }
- return Promise.resolve();
-}
-
-function promiseSetupDirectoryLinksProvider(options = {}) {
- return Task.spawn(function*() {
- let linksURL = options.linksURL || kTestURL;
- yield DirectoryLinksProvider.init();
- yield promiseDirectoryDownloadOnPrefChange(kLocalePref, options.locale || "en-US");
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, linksURL);
- do_check_eq(DirectoryLinksProvider._linksURL, linksURL);
- DirectoryLinksProvider._lastDownloadMS = options.lastDownloadMS || 0;
- });
-}
-
-function promiseCleanDirectoryLinksProvider() {
- return Task.spawn(function*() {
- yield promiseDirectoryDownloadOnPrefChange(kLocalePref, "en-US");
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kTestURL);
- yield DirectoryLinksProvider._clearFrequencyCap();
- yield DirectoryLinksProvider._loadInadjacentSites();
- DirectoryLinksProvider._lastDownloadMS = 0;
- DirectoryLinksProvider.reset();
- });
-}
-
-function run_test() {
- // Set up a mock HTTP server to serve a directory page
- server = new HttpServer();
- server.registerPrefixHandler(kExamplePath, getHttpHandler(kExamplePath));
- server.registerPrefixHandler(kFailPath, getHttpHandler(kFailPath));
- server.start(kDefaultServerPort);
- NewTabUtils.init();
-
- run_next_test();
-
- // Teardown.
- do_register_cleanup(function() {
- server.stop(function() { });
- DirectoryLinksProvider.reset();
- Services.prefs.clearUserPref(kLocalePref);
- Services.prefs.clearUserPref(kSourceUrlPref);
- Services.prefs.clearUserPref(kPingUrlPref);
- Services.prefs.clearUserPref(kNewtabEnhancedPref);
- });
-}
-
-
-function setTimeout(fun, timeout) {
- let timer = Components.classes["@mozilla.org/timer;1"]
- .createInstance(Components.interfaces.nsITimer);
- var event = {
- notify: function () {
- fun();
- }
- };
- timer.initWithCallback(event, timeout,
- Components.interfaces.nsITimer.TYPE_ONE_SHOT);
- return timer;
-}
-
-add_task(function test_shouldUpdateSuggestedTile() {
- let suggestedLink = {
- targetedSite: "somesite.com"
- };
-
- // DirectoryLinksProvider has no suggested tile and no top sites => no need to update
- do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 0);
- isIdentical(NewTabUtils.getProviderLinks(), []);
- do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), false);
-
- // DirectoryLinksProvider has a suggested tile and no top sites => need to update
- let origGetProviderLinks = NewTabUtils.getProviderLinks;
- NewTabUtils.getProviderLinks = (provider) => [suggestedLink];
-
- do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 0);
- isIdentical(NewTabUtils.getProviderLinks(), [suggestedLink]);
- do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), true);
-
- // DirectoryLinksProvider has a suggested tile and 8 top sites => no need to update
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 8);
- isIdentical(NewTabUtils.getProviderLinks(), [suggestedLink]);
- do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), false);
-
- // DirectoryLinksProvider has no suggested tile and 8 top sites => need to update
- NewTabUtils.getProviderLinks = origGetProviderLinks;
- do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 8);
- isIdentical(NewTabUtils.getProviderLinks(), []);
- do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), true);
-
- // Cleanup
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
-});
-
-add_task(function* test_updateSuggestedTile() {
- let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"];
-
- // Initial setup
- let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3], "directory": [someOtherSite]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
-
- let testObserver = new TestFirstRun();
- DirectoryLinksProvider.addObserver(testObserver);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- let links = yield fetchData();
-
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = function(site) {
- return topSites.indexOf(site) >= 0;
- }
-
- let origGetProviderLinks = NewTabUtils.getProviderLinks;
- NewTabUtils.getProviderLinks = function(provider) {
- return links;
- }
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined);
-
- function TestFirstRun() {
- this.promise = new Promise(resolve => {
- this.onLinkChanged = (directoryLinksProvider, link) => {
- links.unshift(link);
- let possibleLinks = [suggestedTile1.url, suggestedTile2.url, suggestedTile3.url];
-
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], ["hrblock.com", "1040.com", "freetaxusa.com"]);
- do_check_true(possibleLinks.indexOf(link.url) > -1);
- do_check_eq(link.frecency, SUGGESTED_FRECENCY);
- do_check_eq(link.type, "affiliate");
- resolve();
- };
- });
- }
-
- function TestChangingSuggestedTile() {
- this.count = 0;
- this.promise = new Promise(resolve => {
- this.onLinkChanged = (directoryLinksProvider, link) => {
- this.count++;
- let possibleLinks = [suggestedTile1.url, suggestedTile2.url, suggestedTile3.url];
-
- do_check_true(possibleLinks.indexOf(link.url) > -1);
- do_check_eq(link.type, "affiliate");
- do_check_true(this.count <= 2);
-
- if (this.count == 1) {
- // The removed suggested link is the one we added initially.
- do_check_eq(link.url, links.shift().url);
- do_check_eq(link.frecency, SUGGESTED_FRECENCY);
- } else {
- links.unshift(link);
- do_check_eq(link.frecency, SUGGESTED_FRECENCY);
- }
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], ["hrblock.com", "freetaxusa.com"]);
- resolve();
- }
- });
- }
-
- function TestRemovingSuggestedTile() {
- this.count = 0;
- this.promise = new Promise(resolve => {
- this.onLinkChanged = (directoryLinksProvider, link) => {
- this.count++;
-
- do_check_eq(link.type, "affiliate");
- do_check_eq(this.count, 1);
- do_check_eq(link.frecency, SUGGESTED_FRECENCY);
- do_check_eq(link.url, links.shift().url);
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], []);
- resolve();
- }
- });
- }
-
- // Test first call to '_updateSuggestedTile()', called when fetching directory links.
- yield testObserver.promise;
- DirectoryLinksProvider.removeObserver(testObserver);
-
- // Removing a top site that doesn't have a suggested link should
- // not change the current suggested tile.
- let removedTopsite = topSites.shift();
- do_check_eq(removedTopsite, "site0.com");
- do_check_false(NewTabUtils.isTopPlacesSite(removedTopsite));
- let updateSuggestedTile = DirectoryLinksProvider._handleLinkChanged({
- url: "http://" + removedTopsite,
- type: "history",
- });
- do_check_false(updateSuggestedTile);
-
- // Removing a top site that has a suggested link should
- // remove any current suggested tile and add a new one.
- testObserver = new TestChangingSuggestedTile();
- DirectoryLinksProvider.addObserver(testObserver);
- removedTopsite = topSites.shift();
- do_check_eq(removedTopsite, "1040.com");
- do_check_false(NewTabUtils.isTopPlacesSite(removedTopsite));
- DirectoryLinksProvider.onLinkChanged(DirectoryLinksProvider, {
- url: "http://" + removedTopsite,
- type: "history",
- });
- yield testObserver.promise;
- do_check_eq(testObserver.count, 2);
- DirectoryLinksProvider.removeObserver(testObserver);
-
- // Removing all top sites with suggested links should remove
- // the current suggested link and not replace it.
- topSites = [];
- testObserver = new TestRemovingSuggestedTile();
- DirectoryLinksProvider.addObserver(testObserver);
- DirectoryLinksProvider.onManyLinksChanged();
- yield testObserver.promise;
-
- // Cleanup
- yield promiseCleanDirectoryLinksProvider();
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- NewTabUtils.getProviderLinks = origGetProviderLinks;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
-});
-
-add_task(function* test_suggestedLinksMap() {
- let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3, suggestedTile4], "directory": [someOtherSite]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- let links = yield fetchData();
-
- // Ensure the suggested tiles were not considered directory tiles.
- do_check_eq(links.length, 1);
- let expected_data = [{url: "http://someothersite.com", title: "Not_A_Suggested_Site", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
- isIdentical(links, expected_data);
-
- // Check for correctly saved suggested tiles data.
- expected_data = {
- "taxact.com": [suggestedTile1, suggestedTile2, suggestedTile3],
- "hrblock.com": [suggestedTile1, suggestedTile2],
- "1040.com": [suggestedTile1, suggestedTile3],
- "taxslayer.com": [suggestedTile1, suggestedTile2, suggestedTile3],
- "freetaxusa.com": [suggestedTile2, suggestedTile3],
- "sponsoredtarget.com": [suggestedTile4],
- };
-
- let suggestedSites = [...DirectoryLinksProvider._suggestedLinks.keys()];
- do_check_eq(suggestedSites.indexOf("sponsoredtarget.com"), 5);
- do_check_eq(suggestedSites.length, Object.keys(expected_data).length);
-
- DirectoryLinksProvider._suggestedLinks.forEach((suggestedLinks, site) => {
- let suggestedLinksItr = suggestedLinks.values();
- for (let link of expected_data[site]) {
- let linkCopy = JSON.parse(JSON.stringify(link));
- linkCopy.targetedName = link.adgroup_name;
- linkCopy.explanation = "";
- isIdentical(suggestedLinksItr.next().value, linkCopy);
- }
- })
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_topSitesWithSuggestedLinks() {
- let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"];
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = function(site) {
- return topSites.indexOf(site) >= 0;
- }
-
- // Mock out getProviderLinks() so we don't have to populate cache in NewTabUtils
- let origGetProviderLinks = NewTabUtils.getProviderLinks;
- NewTabUtils.getProviderLinks = function(provider) {
- return [];
- }
-
- // We start off with no top sites with suggested links.
- do_check_eq(DirectoryLinksProvider._topSitesWithSuggestedLinks.size, 0);
-
- let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3], "directory": [someOtherSite]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- yield fetchData();
-
- // Check we've populated suggested links as expected.
- do_check_eq(DirectoryLinksProvider._suggestedLinks.size, 5);
-
- // When many sites change, we update _topSitesWithSuggestedLinks as expected.
- let expectedTopSitesWithSuggestedLinks = ["hrblock.com", "1040.com", "freetaxusa.com"];
- DirectoryLinksProvider._handleManyLinksChanged();
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks);
-
- // Removing site6.com as a topsite has no impact on _topSitesWithSuggestedLinks.
- let popped = topSites.pop();
- DirectoryLinksProvider._handleLinkChanged({url: "http://" + popped});
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks);
-
- // Removing freetaxusa.com as a topsite will remove it from _topSitesWithSuggestedLinks.
- popped = topSites.pop();
- expectedTopSitesWithSuggestedLinks.pop();
- DirectoryLinksProvider._handleLinkChanged({url: "http://" + popped});
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks);
-
- // Re-adding freetaxusa.com as a topsite will add it to _topSitesWithSuggestedLinks.
- topSites.push(popped);
- expectedTopSitesWithSuggestedLinks.push(popped);
- DirectoryLinksProvider._handleLinkChanged({url: "http://" + popped});
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks);
-
- // Cleanup.
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- NewTabUtils.getProviderLinks = origGetProviderLinks;
-});
-
-add_task(function* test_suggestedAttributes() {
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = () => true;
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- let frecent_sites = "addons.mozilla.org,air.mozilla.org,blog.mozilla.org,bugzilla.mozilla.org,developer.mozilla.org,etherpad.mozilla.org,forums.mozillazine.org,hacks.mozilla.org,hg.mozilla.org,mozilla.org,planet.mozilla.org,quality.mozilla.org,support.mozilla.org,treeherder.mozilla.org,wiki.mozilla.org".split(",");
- let imageURI = "https://image/";
- let title = "the title";
- let type = "affiliate";
- let url = "http://test.url/";
- let adgroup_name = "Mozilla";
- let data = {
- suggested: [{
- frecent_sites,
- imageURI,
- title,
- type,
- url,
- adgroup_name
- }]
- };
- let dataURI = "data:application/json," + escape(JSON.stringify(data));
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- // Wait for links to get loaded
- let gLinks = NewTabUtils.links;
- gLinks.addProvider(DirectoryLinksProvider);
- gLinks.populateCache();
- yield new Promise(resolve => {
- NewTabUtils.allPages.register({
- observe: _ => _,
- update() {
- NewTabUtils.allPages.unregister(this);
- resolve();
- }
- });
- });
-
- // Make sure we get the expected attributes on the suggested tile
- let link = gLinks.getLinks()[0];
- do_check_eq(link.imageURI, imageURI);
- do_check_eq(link.targetedName, "Mozilla");
- do_check_eq(link.targetedSite, frecent_sites[0]);
- do_check_eq(link.title, title);
- do_check_eq(link.type, type);
- do_check_eq(link.url, url);
-
- // Cleanup.
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
- gLinks.removeProvider(DirectoryLinksProvider);
- DirectoryLinksProvider.removeObserver(gLinks);
-});
-
-add_task(function* test_frequencyCappedSites_views() {
- Services.prefs.setCharPref(kPingUrlPref, "");
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = () => true;
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- let testUrl = "http://frequency.capped/link";
- let targets = ["top.site.com"];
- let data = {
- suggested: [{
- type: "affiliate",
- frecent_sites: targets,
- url: testUrl,
- frequency_caps: {daily: 5},
- adgroup_name: "Test"
- }],
- directory: [{
- type: "organic",
- url: "http://directory.site/"
- }]
- };
- let dataURI = "data:application/json," + JSON.stringify(data);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- // Wait for links to get loaded
- let gLinks = NewTabUtils.links;
- gLinks.addProvider(DirectoryLinksProvider);
- gLinks.populateCache();
- yield new Promise(resolve => {
- NewTabUtils.allPages.register({
- observe: _ => _,
- update() {
- NewTabUtils.allPages.unregister(this);
- resolve();
- }
- });
- });
-
- function synthesizeAction(action) {
- DirectoryLinksProvider.reportSitesAction([{
- link: {
- targetedSite: targets[0],
- url: testUrl
- }
- }], action, 0);
- }
-
- function checkFirstTypeAndLength(type, length) {
- let links = gLinks.getLinks();
- do_check_eq(links[0].type, type);
- do_check_eq(links.length, length);
- }
-
- // Make sure we get 5 views of the link before it is removed
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("view");
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("view");
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("view");
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("view");
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("view");
- checkFirstTypeAndLength("organic", 1);
-
- // Cleanup.
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
- gLinks.removeProvider(DirectoryLinksProvider);
- DirectoryLinksProvider.removeObserver(gLinks);
- Services.prefs.setCharPref(kPingUrlPref, kPingUrl);
-});
-
-add_task(function* test_frequencyCappedSites_click() {
- Services.prefs.setCharPref(kPingUrlPref, "");
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = () => true;
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- let testUrl = "http://frequency.capped/link";
- let targets = ["top.site.com"];
- let data = {
- suggested: [{
- type: "affiliate",
- frecent_sites: targets,
- url: testUrl,
- adgroup_name: "Test"
- }],
- directory: [{
- type: "organic",
- url: "http://directory.site/"
- }]
- };
- let dataURI = "data:application/json," + JSON.stringify(data);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- // Wait for links to get loaded
- let gLinks = NewTabUtils.links;
- gLinks.addProvider(DirectoryLinksProvider);
- gLinks.populateCache();
- yield new Promise(resolve => {
- NewTabUtils.allPages.register({
- observe: _ => _,
- update() {
- NewTabUtils.allPages.unregister(this);
- resolve();
- }
- });
- });
-
- function synthesizeAction(action) {
- DirectoryLinksProvider.reportSitesAction([{
- link: {
- targetedSite: targets[0],
- url: testUrl
- }
- }], action, 0);
- }
-
- function checkFirstTypeAndLength(type, length) {
- let links = gLinks.getLinks();
- do_check_eq(links[0].type, type);
- do_check_eq(links.length, length);
- }
-
- // Make sure the link disappears after the first click
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("view");
- checkFirstTypeAndLength("affiliate", 2);
- synthesizeAction("click");
- checkFirstTypeAndLength("organic", 1);
-
- // Cleanup.
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
- gLinks.removeProvider(DirectoryLinksProvider);
- DirectoryLinksProvider.removeObserver(gLinks);
- Services.prefs.setCharPref(kPingUrlPref, kPingUrl);
-});
-
-add_task(function* test_fetchAndCacheLinks_local() {
- yield DirectoryLinksProvider.init();
- yield cleanJsonFile();
- // Trigger cache of data or chrome uri files in profD
- yield DirectoryLinksProvider._fetchAndCacheLinks(kTestURL);
- let data = yield readJsonFile();
- isIdentical(data, kURLData);
-});
-
-add_task(function* test_fetchAndCacheLinks_remote() {
- yield DirectoryLinksProvider.init();
- yield cleanJsonFile();
- // this must trigger directory links json download and save it to cache file
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kExampleURL + "%LOCALE%");
- do_check_eq(gLastRequestPath, kExamplePath + "en-US");
- let data = yield readJsonFile();
- isIdentical(data, kHttpHandlerData[kExamplePath]);
-});
-
-add_task(function* test_fetchAndCacheLinks_malformedURI() {
- yield DirectoryLinksProvider.init();
- yield cleanJsonFile();
- let someJunk = "some junk";
- try {
- yield DirectoryLinksProvider._fetchAndCacheLinks(someJunk);
- do_throw("Malformed URIs should fail")
- } catch (e) {
- do_check_eq(e, "Error fetching " + someJunk)
- }
-
- // File should be empty.
- let data = yield readJsonFile();
- isIdentical(data, "");
-});
-
-add_task(function* test_fetchAndCacheLinks_unknownHost() {
- yield DirectoryLinksProvider.init();
- yield cleanJsonFile();
- let nonExistentServer = "http://localhost:56789/";
- try {
- yield DirectoryLinksProvider._fetchAndCacheLinks(nonExistentServer);
- do_throw("BAD URIs should fail");
- } catch (e) {
- do_check_true(e.startsWith("Fetching " + nonExistentServer + " results in error code: "))
- }
-
- // File should be empty.
- let data = yield readJsonFile();
- isIdentical(data, "");
-});
-
-add_task(function* test_fetchAndCacheLinks_non200Status() {
- yield DirectoryLinksProvider.init();
- yield cleanJsonFile();
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kFailURL);
- do_check_eq(gLastRequestPath, kFailPath);
- let data = yield readJsonFile();
- isIdentical(data, {});
-});
-
-// To test onManyLinksChanged observer, trigger a fetch
-add_task(function* test_DirectoryLinksProvider__linkObservers() {
- yield DirectoryLinksProvider.init();
-
- let testObserver = new LinksChangeObserver();
- DirectoryLinksProvider.addObserver(testObserver);
- do_check_eq(DirectoryLinksProvider._observers.size, 1);
- DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
-
- yield testObserver.deferred.promise;
- DirectoryLinksProvider._removeObservers();
- do_check_eq(DirectoryLinksProvider._observers.size, 0);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider__prefObserver_url() {
- yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL});
-
- let links = yield fetchData();
- do_check_eq(links.length, 1);
- let expectedData = [{url: "http://example.com", title: "LocalSource", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
- isIdentical(links, expectedData);
-
- // tests these 2 things:
- // 1. _linksURL is properly set after the pref change
- // 2. invalid source url is correctly handled
- let exampleUrl = 'http://localhost:56789/bad';
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl);
- do_check_eq(DirectoryLinksProvider._linksURL, exampleUrl);
-
- // since the download fail, the directory file must remain the same
- let newLinks = yield fetchData();
- isIdentical(newLinks, expectedData);
-
- // now remove the file, and re-download
- yield cleanJsonFile();
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl + " ");
- // we now should see empty links
- newLinks = yield fetchData();
- isIdentical(newLinks, []);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_getLinks_noDirectoryData() {
- let data = {
- "directory": [],
- };
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- let links = yield fetchData();
- do_check_eq(links.length, 0);
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_getLinks_badData() {
- let data = {
- "en-US": {
- "en-US": [{url: "http://example.com", title: "US"}],
- },
- };
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- // Make sure we get nothing for incorrectly formatted data
- let links = yield fetchData();
- do_check_eq(links.length, 0);
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function test_DirectoryLinksProvider_needsDownload() {
- // test timestamping
- DirectoryLinksProvider._lastDownloadMS = 0;
- do_check_true(DirectoryLinksProvider._needsDownload);
- DirectoryLinksProvider._lastDownloadMS = Date.now();
- do_check_false(DirectoryLinksProvider._needsDownload);
- DirectoryLinksProvider._lastDownloadMS = Date.now() - (60*60*24 + 1)*1000;
- do_check_true(DirectoryLinksProvider._needsDownload);
- DirectoryLinksProvider._lastDownloadMS = 0;
-});
-
-add_task(function* test_DirectoryLinksProvider_fetchAndCacheLinksIfNecessary() {
- yield DirectoryLinksProvider.init();
- yield cleanJsonFile();
- // explicitly change source url to cause the download during setup
- yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL+" "});
- yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary();
-
- // inspect lastDownloadMS timestamp which should be 5 seconds less then now()
- let lastDownloadMS = DirectoryLinksProvider._lastDownloadMS;
- do_check_true((Date.now() - lastDownloadMS) < 5000);
-
- // we should have fetched a new file during setup
- let data = yield readJsonFile();
- isIdentical(data, kURLData);
-
- // attempt to download again - the timestamp should not change
- yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary();
- do_check_eq(DirectoryLinksProvider._lastDownloadMS, lastDownloadMS);
-
- // clean the file and force the download
- yield cleanJsonFile();
- yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
- data = yield readJsonFile();
- isIdentical(data, kURLData);
-
- // make sure that failed download does not corrupt the file, nor changes lastDownloadMS
- lastDownloadMS = DirectoryLinksProvider._lastDownloadMS;
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, "http://");
- yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
- data = yield readJsonFile();
- isIdentical(data, kURLData);
- do_check_eq(DirectoryLinksProvider._lastDownloadMS, lastDownloadMS);
-
- // _fetchAndCacheLinksIfNecessary must return same promise if download is in progress
- let downloadPromise = DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
- let anotherPromise = DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
- do_check_true(downloadPromise === anotherPromise);
- yield downloadPromise;
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_fetchDirectoryOnPrefChange() {
- yield DirectoryLinksProvider.init();
-
- let testObserver = new LinksChangeObserver();
- DirectoryLinksProvider.addObserver(testObserver);
-
- yield cleanJsonFile();
- // ensure that provider does not think it needs to download
- do_check_false(DirectoryLinksProvider._needsDownload);
-
- // change the source URL, which should force directory download
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kExampleURL);
- // then wait for testObserver to fire and test that json is downloaded
- yield testObserver.deferred.promise;
- do_check_eq(gLastRequestPath, kExamplePath);
- let data = yield readJsonFile();
- isIdentical(data, kHttpHandlerData[kExamplePath]);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_fetchDirectoryOnShow() {
- yield promiseSetupDirectoryLinksProvider();
-
- // set lastdownload to 0 to make DirectoryLinksProvider want to download
- DirectoryLinksProvider._lastDownloadMS = 0;
- do_check_true(DirectoryLinksProvider._needsDownload);
-
- // download should happen on view
- yield DirectoryLinksProvider.reportSitesAction([], "view");
- do_check_true(DirectoryLinksProvider._lastDownloadMS != 0);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_fetchDirectoryOnInit() {
- // ensure preferences are set to defaults
- yield promiseSetupDirectoryLinksProvider();
- // now clean to provider, so we can init it again
- yield promiseCleanDirectoryLinksProvider();
-
- yield cleanJsonFile();
- yield DirectoryLinksProvider.init();
- let data = yield readJsonFile();
- isIdentical(data, kURLData);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_getLinksFromCorruptedFile() {
- yield promiseSetupDirectoryLinksProvider();
-
- // write bogus json to a file and attempt to fetch from it
- let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.profileDir, DIRECTORY_LINKS_FILE);
- yield OS.File.writeAtomic(directoryLinksFilePath, '{"en-US":');
- let data = yield fetchData();
- isIdentical(data, []);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_getAllowedLinks() {
- let data = {"directory": [
- {url: "ftp://example.com"},
- {url: "http://example.net"},
- {url: "javascript:5"},
- {url: "https://example.com"},
- {url: "httpJUNKjavascript:42"},
- {url: "data:text/plain,hi"},
- {url: "http/bork:eh"},
- ]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- let links = yield fetchData();
- do_check_eq(links.length, 2);
-
- // The only remaining url should be http and https
- do_check_eq(links[0].url, data["directory"][1].url);
- do_check_eq(links[1].url, data["directory"][3].url);
-});
-
-add_task(function* test_DirectoryLinksProvider_getAllowedImages() {
- let data = {"directory": [
- {url: "http://example.com", imageURI: "ftp://example.com"},
- {url: "http://example.com", imageURI: "http://example.net"},
- {url: "http://example.com", imageURI: "javascript:5"},
- {url: "http://example.com", imageURI: "https://example.com"},
- {url: "http://example.com", imageURI: "httpJUNKjavascript:42"},
- {url: "http://example.com", imageURI: "data:text/plain,hi"},
- {url: "http://example.com", imageURI: "http/bork:eh"},
- ]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- let links = yield fetchData();
- do_check_eq(links.length, 2);
-
- // The only remaining images should be https and data
- do_check_eq(links[0].imageURI, data["directory"][3].imageURI);
- do_check_eq(links[1].imageURI, data["directory"][5].imageURI);
-});
-
-add_task(function* test_DirectoryLinksProvider_getAllowedImages_base() {
- let data = {"directory": [
- {url: "http://example1.com", imageURI: "https://example.com"},
- {url: "http://example2.com", imageURI: "https://tiles.cdn.mozilla.net"},
- {url: "http://example3.com", imageURI: "https://tiles2.cdn.mozilla.net"},
- {url: "http://example4.com", enhancedImageURI: "https://mozilla.net"},
- {url: "http://example5.com", imageURI: "data:text/plain,hi"},
- ]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- // Pretend we're using the default pref to trigger base matching
- DirectoryLinksProvider.__linksURLModified = false;
-
- let links = yield fetchData();
- do_check_eq(links.length, 4);
-
- // The only remaining images should be https with mozilla.net or data URI
- do_check_eq(links[0].url, data["directory"][1].url);
- do_check_eq(links[1].url, data["directory"][2].url);
- do_check_eq(links[2].url, data["directory"][3].url);
- do_check_eq(links[3].url, data["directory"][4].url);
-});
-
-add_task(function* test_DirectoryLinksProvider_getAllowedEnhancedImages() {
- let data = {"directory": [
- {url: "http://example.com", enhancedImageURI: "ftp://example.com"},
- {url: "http://example.com", enhancedImageURI: "http://example.net"},
- {url: "http://example.com", enhancedImageURI: "javascript:5"},
- {url: "http://example.com", enhancedImageURI: "https://example.com"},
- {url: "http://example.com", enhancedImageURI: "httpJUNKjavascript:42"},
- {url: "http://example.com", enhancedImageURI: "data:text/plain,hi"},
- {url: "http://example.com", enhancedImageURI: "http/bork:eh"},
- ]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- let links = yield fetchData();
- do_check_eq(links.length, 2);
-
- // The only remaining enhancedImages should be http and https and data
- do_check_eq(links[0].enhancedImageURI, data["directory"][3].enhancedImageURI);
- do_check_eq(links[1].enhancedImageURI, data["directory"][5].enhancedImageURI);
-});
-
-add_task(function* test_DirectoryLinksProvider_getEnhancedLink() {
- let data = {"enhanced": [
- {url: "http://example.net", enhancedImageURI: "data:,net1"},
- {url: "http://example.com", enhancedImageURI: "data:,com1"},
- {url: "http://example.com", enhancedImageURI: "data:,com2"},
- ]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- let links = yield fetchData();
- do_check_eq(links.length, 0); // There are no directory links.
-
- function checkEnhanced(url, image) {
- let enhanced = DirectoryLinksProvider.getEnhancedLink({url: url});
- do_check_eq(enhanced && enhanced.enhancedImageURI, image);
- }
-
- // Get the expected image for the same site
- checkEnhanced("http://example.net/", "data:,net1");
- checkEnhanced("http://example.net/path", "data:,net1");
- checkEnhanced("https://www.example.net/", "data:,net1");
- checkEnhanced("https://www3.example.net/", "data:,net1");
-
- // Get the image of the last entry
- checkEnhanced("http://example.com", "data:,com2");
-
- // Get the inline enhanced image
- let inline = DirectoryLinksProvider.getEnhancedLink({
- url: "http://example.com/echo",
- enhancedImageURI: "data:,echo",
- });
- do_check_eq(inline.enhancedImageURI, "data:,echo");
- do_check_eq(inline.url, "http://example.com/echo");
-
- // Undefined for not enhanced
- checkEnhanced("http://sub.example.net/", undefined);
- checkEnhanced("http://example.org", undefined);
- checkEnhanced("http://localhost", undefined);
- checkEnhanced("http://127.0.0.1", undefined);
-
- // Make sure old data is not cached
- data = {"enhanced": [
- {url: "http://example.com", enhancedImageURI: "data:,fresh"},
- ]};
- dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- links = yield fetchData();
- do_check_eq(links.length, 0); // There are no directory links.
- checkEnhanced("http://example.net", undefined);
- checkEnhanced("http://example.com", "data:,fresh");
-});
-
-add_task(function* test_DirectoryLinksProvider_enhancedURIs() {
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = () => true;
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- let data = {
- "suggested": [
- {url: "http://example.net", enhancedImageURI: "data:,net1", title:"SuggestedTitle", adgroup_name: "Test", frecent_sites: ["test.com"]}
- ],
- "directory": [
- {url: "http://example.net", enhancedImageURI: "data:,net2", title:"DirectoryTitle"}
- ]
- };
- let dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
-
- // Wait for links to get loaded
- let gLinks = NewTabUtils.links;
- gLinks.addProvider(DirectoryLinksProvider);
- gLinks.populateCache();
- yield new Promise(resolve => {
- NewTabUtils.allPages.register({
- observe: _ => _,
- update() {
- NewTabUtils.allPages.unregister(this);
- resolve();
- }
- });
- });
-
- // Check that we've saved the directory tile.
- let links = yield fetchData();
- do_check_eq(links.length, 1);
- do_check_eq(links[0].title, "DirectoryTitle");
- do_check_eq(links[0].enhancedImageURI, "data:,net2");
-
- // Check that the suggested tile with the same URL replaces the directory tile.
- links = gLinks.getLinks();
- do_check_eq(links.length, 1);
- do_check_eq(links[0].title, "SuggestedTitle");
- do_check_eq(links[0].enhancedImageURI, "data:,net1");
-
- // Cleanup.
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
- gLinks.removeProvider(DirectoryLinksProvider);
-});
-
-add_task(function test_DirectoryLinksProvider_setDefaultEnhanced() {
- function checkDefault(expected) {
- Services.prefs.clearUserPref(kNewtabEnhancedPref);
- do_check_eq(Services.prefs.getBoolPref(kNewtabEnhancedPref), expected);
- }
-
- // Use the default donottrack prefs (enabled = false)
- Services.prefs.clearUserPref("privacy.donottrackheader.enabled");
- checkDefault(true);
-
- // Turn on DNT - no track
- Services.prefs.setBoolPref("privacy.donottrackheader.enabled", true);
- checkDefault(false);
-
- // Turn off DNT header
- Services.prefs.clearUserPref("privacy.donottrackheader.enabled");
- checkDefault(true);
-
- // Clean up
- Services.prefs.clearUserPref("privacy.donottrackheader.value");
-});
-
-add_task(function* test_timeSensetiveSuggestedTiles() {
- // make tile json with start and end dates
- let testStartTime = Date.now();
- // start date is now + 1 seconds
- let startDate = new Date(testStartTime + 1000);
- // end date is now + 3 seconds
- let endDate = new Date(testStartTime + 3000);
- let suggestedTile = Object.assign({
- time_limits: {
- start: startDate.toISOString(),
- end: endDate.toISOString(),
- }
- }, suggestedTile1);
-
- // Initial setup
- let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"];
- let data = {"suggested": [suggestedTile], "directory": [someOtherSite]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
-
- let testObserver = new TestTimingRun();
- DirectoryLinksProvider.addObserver(testObserver);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- let links = yield fetchData();
-
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = function(site) {
- return topSites.indexOf(site) >= 0;
- }
-
- let origGetProviderLinks = NewTabUtils.getProviderLinks;
- NewTabUtils.getProviderLinks = function(provider) {
- return links;
- }
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined);
-
- // this tester will fire twice: when start limit is reached and when tile link
- // is removed upon end of the campaign, in which case deleteFlag will be set
- function TestTimingRun() {
- this.promise = new Promise(resolve => {
- this.onLinkChanged = (directoryLinksProvider, link, ignoreFlag, deleteFlag) => {
- // if we are not deleting, add link to links, so we can catch it's removal
- if (!deleteFlag) {
- links.unshift(link);
- }
-
- isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], ["hrblock.com", "1040.com"]);
- do_check_eq(link.frecency, SUGGESTED_FRECENCY);
- do_check_eq(link.type, "affiliate");
- do_check_eq(link.url, suggestedTile.url);
- let timeDelta = Date.now() - testStartTime;
- if (!deleteFlag) {
- // this is start timeout corresponding to campaign start
- // a seconds must pass and targetedSite must be set
- do_print("TESTING START timeDelta: " + timeDelta);
- do_check_true(timeDelta >= 1000 / 2); // check for at least half time
- do_check_eq(link.targetedSite, "hrblock.com");
- do_check_true(DirectoryLinksProvider._campaignTimeoutID);
- }
- else {
- // this is the campaign end timeout, so 3 seconds must pass
- // and timeout should be cleared
- do_print("TESTING END timeDelta: " + timeDelta);
- do_check_true(timeDelta >= 3000 / 2); // check for at least half time
- do_check_false(link.targetedSite);
- do_check_false(DirectoryLinksProvider._campaignTimeoutID);
- resolve();
- }
- };
- });
- }
-
- // _updateSuggestedTile() is called when fetching directory links.
- yield testObserver.promise;
- DirectoryLinksProvider.removeObserver(testObserver);
-
- // shoudl suggest nothing
- do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined);
-
- // set links back to contain directory tile only
- links.shift();
-
- // drop the end time - we should pick up the tile
- suggestedTile.time_limits.end = null;
- data = {"suggested": [suggestedTile], "directory": [someOtherSite]};
- dataURI = 'data:application/json,' + JSON.stringify(data);
-
- // redownload json and getLinks to force time recomputation
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, dataURI);
-
- // ensure that there's a link returned by _updateSuggestedTile and no timeout
- let deferred = Promise.defer();
- DirectoryLinksProvider.getLinks(() => {
- let link = DirectoryLinksProvider._updateSuggestedTile();
- // we should have a suggested tile and no timeout
- do_check_eq(link.type, "affiliate");
- do_check_eq(link.url, suggestedTile.url);
- do_check_false(DirectoryLinksProvider._campaignTimeoutID);
- deferred.resolve();
- });
- yield deferred.promise;
-
- // repeat the test for end time only
- suggestedTile.time_limits.start = null;
- suggestedTile.time_limits.end = (new Date(Date.now() + 3000)).toISOString();
-
- data = {"suggested": [suggestedTile], "directory": [someOtherSite]};
- dataURI = 'data:application/json,' + JSON.stringify(data);
-
- // redownload json and call getLinks() to force time recomputation
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, dataURI);
-
- // ensure that there's a link returned by _updateSuggestedTile and timeout set
- deferred = Promise.defer();
- DirectoryLinksProvider.getLinks(() => {
- let link = DirectoryLinksProvider._updateSuggestedTile();
- // we should have a suggested tile and timeout set
- do_check_eq(link.type, "affiliate");
- do_check_eq(link.url, suggestedTile.url);
- do_check_true(DirectoryLinksProvider._campaignTimeoutID);
- DirectoryLinksProvider._clearCampaignTimeout();
- deferred.resolve();
- });
- yield deferred.promise;
-
- // Cleanup
- yield promiseCleanDirectoryLinksProvider();
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- NewTabUtils.getProviderLinks = origGetProviderLinks;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
-});
-
-add_task(function test_setupStartEndTime() {
- let currentTime = Date.now();
- let dt = new Date(currentTime);
- let link = {
- time_limits: {
- start: dt.toISOString()
- }
- };
-
- // test ISO translation
- DirectoryLinksProvider._setupStartEndTime(link);
- do_check_eq(link.startTime, currentTime);
-
- // test localtime translation
- let shiftedDate = new Date(currentTime - dt.getTimezoneOffset()*60*1000);
- link.time_limits.start = shiftedDate.toISOString().replace(/Z$/, "");
-
- DirectoryLinksProvider._setupStartEndTime(link);
- do_check_eq(link.startTime, currentTime);
-
- // throw some garbage into date string
- delete link.startTime;
- link.time_limits.start = "no date"
- DirectoryLinksProvider._setupStartEndTime(link);
- do_check_false(link.startTime);
-
- link.time_limits.start = "2015-99999-01T00:00:00"
- DirectoryLinksProvider._setupStartEndTime(link);
- do_check_false(link.startTime);
-
- link.time_limits.start = "20150501T00:00:00"
- DirectoryLinksProvider._setupStartEndTime(link);
- do_check_false(link.startTime);
-});
-
-add_task(function* test_DirectoryLinksProvider_frequencyCapSetup() {
- yield promiseSetupDirectoryLinksProvider();
- yield DirectoryLinksProvider.init();
-
- yield promiseCleanDirectoryLinksProvider();
- yield DirectoryLinksProvider._readFrequencyCapFile();
- isIdentical(DirectoryLinksProvider._frequencyCaps, {});
-
- // setup few links
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "1",
- });
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "2",
- frequency_caps: {daily: 1, total: 2}
- });
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "3",
- frequency_caps: {total: 2}
- });
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "4",
- frequency_caps: {daily: 1}
- });
- let freqCapsObject = DirectoryLinksProvider._frequencyCaps;
- let capObject = freqCapsObject["1"];
- let defaultDaily = capObject.dailyCap;
- let defaultTotal = capObject.totalCap;
- // check if we have defaults set
- do_check_true(capObject.dailyCap > 0);
- do_check_true(capObject.totalCap > 0);
- // check if defaults are properly handled
- do_check_eq(freqCapsObject["2"].dailyCap, 1);
- do_check_eq(freqCapsObject["2"].totalCap, 2);
- do_check_eq(freqCapsObject["3"].dailyCap, defaultDaily);
- do_check_eq(freqCapsObject["3"].totalCap, 2);
- do_check_eq(freqCapsObject["4"].dailyCap, 1);
- do_check_eq(freqCapsObject["4"].totalCap, defaultTotal);
-
- // write object to file
- yield DirectoryLinksProvider._writeFrequencyCapFile();
- // empty out freqCapsObject and read file back
- DirectoryLinksProvider._frequencyCaps = {};
- yield DirectoryLinksProvider._readFrequencyCapFile();
- // re-ran tests - they should all pass
- do_check_eq(freqCapsObject["2"].dailyCap, 1);
- do_check_eq(freqCapsObject["2"].totalCap, 2);
- do_check_eq(freqCapsObject["3"].dailyCap, defaultDaily);
- do_check_eq(freqCapsObject["3"].totalCap, 2);
- do_check_eq(freqCapsObject["4"].dailyCap, 1);
- do_check_eq(freqCapsObject["4"].totalCap, defaultTotal);
-
- // wait a second and prune frequency caps
- yield new Promise(resolve => {
- setTimeout(resolve, 1100);
- });
-
- // update one link and create another
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "3",
- frequency_caps: {daily: 1, total: 2}
- });
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "7",
- frequency_caps: {daily: 1, total: 2}
- });
- // now prune the ones that have been in the object longer than 1 second
- DirectoryLinksProvider._pruneFrequencyCapUrls(1000);
- // make sure all keys but "3" and "7" are deleted
- Object.keys(DirectoryLinksProvider._frequencyCaps).forEach(key => {
- do_check_true(key == "3" || key == "7");
- });
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_getFrequencyCapLogic() {
- yield promiseSetupDirectoryLinksProvider();
- yield DirectoryLinksProvider.init();
-
- // setup suggested links
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "1",
- frequency_caps: {daily: 2, total: 4}
- });
-
- do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1"));
- // exhaust daily views
- DirectoryLinksProvider._addFrequencyCapView("1")
- do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1"));
- DirectoryLinksProvider._addFrequencyCapView("1")
- do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("1"));
-
- // now step into the furture
- let _wasTodayOrig = DirectoryLinksProvider._wasToday;
- DirectoryLinksProvider._wasToday = function () { return false; }
- // exhaust total views
- DirectoryLinksProvider._addFrequencyCapView("1")
- do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1"));
- DirectoryLinksProvider._addFrequencyCapView("1")
- // reached totalViews 4, should return false
- do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("1"));
-
- // add more views by updating configuration
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "1",
- frequency_caps: {daily: 5, total: 10}
- });
- // should be true, since we have more total views
- do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1"));
-
- // set click flag
- DirectoryLinksProvider._setFrequencyCapClick("1");
- // always false after click
- do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("1"));
-
- // use unknown urls and ensure nothing breaks
- DirectoryLinksProvider._addFrequencyCapView("nosuch.url");
- DirectoryLinksProvider._setFrequencyCapClick("nosuch.url");
- // testing unknown url should always return false
- do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("nosuch.url"));
-
- // reset _wasToday back to original function
- DirectoryLinksProvider._wasToday = _wasTodayOrig;
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_getFrequencyCapReportSiteAction() {
- yield promiseSetupDirectoryLinksProvider();
- yield DirectoryLinksProvider.init();
-
- // setup suggested links
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "bar.com",
- frequency_caps: {daily: 2, total: 4}
- });
-
- do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("bar.com"));
- // report site action
- yield DirectoryLinksProvider.reportSitesAction([{
- link: {
- targetedSite: "foo.com",
- url: "bar.com"
- },
- isPinned: function() { return false; },
- }], "view", 0);
-
- // read file content and ensure that view counters are updated
- let data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath);
- do_check_eq(data["bar.com"].dailyViews, 1);
- do_check_eq(data["bar.com"].totalViews, 1);
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_DirectoryLinksProvider_ClickRemoval() {
- yield promiseSetupDirectoryLinksProvider();
- yield DirectoryLinksProvider.init();
- let landingUrl = "http://foo.com";
-
- // setup suggested links
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: landingUrl,
- frequency_caps: {daily: 2, total: 4}
- });
-
- // add views
- DirectoryLinksProvider._addFrequencyCapView(landingUrl)
- DirectoryLinksProvider._addFrequencyCapView(landingUrl)
- // make a click
- DirectoryLinksProvider._setFrequencyCapClick(landingUrl);
-
- // views must be 2 and click must be set
- do_check_eq(DirectoryLinksProvider._frequencyCaps[landingUrl].totalViews, 2);
- do_check_true(DirectoryLinksProvider._frequencyCaps[landingUrl].clicked);
-
- // now insert a visit into places
- yield new Promise(resolve => {
- PlacesUtils.asyncHistory.updatePlaces(
- {
- uri: NetUtil.newURI(landingUrl),
- title: "HELLO",
- visits: [{
- visitDate: Date.now()*1000,
- transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
- }]
- },
- {
- handleError: function () { do_check_true(false); },
- handleResult: function () {},
- handleCompletion: function () { resolve(); }
- }
- );
- });
-
- function UrlDeletionTester() {
- this.promise = new Promise(resolve => {
- this.onDeleteURI = (directoryLinksProvider, link) => {
- resolve();
- };
- this.onClearHistory = (directoryLinksProvider) => {
- resolve();
- };
- });
- }
-
- let testObserver = new UrlDeletionTester();
- DirectoryLinksProvider.addObserver(testObserver);
-
- PlacesUtils.bhistory.removePage(NetUtil.newURI(landingUrl));
- yield testObserver.promise;
- DirectoryLinksProvider.removeObserver(testObserver);
- // views must be 2 and click should not exist
- do_check_eq(DirectoryLinksProvider._frequencyCaps[landingUrl].totalViews, 2);
- do_check_false(DirectoryLinksProvider._frequencyCaps[landingUrl].hasOwnProperty("clicked"));
-
- // verify that disk written data is kosher
- let data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath);
- do_check_eq(data[landingUrl].totalViews, 2);
- do_check_false(data[landingUrl].hasOwnProperty("clicked"));
-
- // now test clear history
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: landingUrl,
- frequency_caps: {daily: 2, total: 4}
- });
- DirectoryLinksProvider._updateFrequencyCapSettings({
- url: "http://bar.com",
- frequency_caps: {daily: 2, total: 4}
- });
-
- DirectoryLinksProvider._setFrequencyCapClick(landingUrl);
- DirectoryLinksProvider._setFrequencyCapClick("http://bar.com");
- // both tiles must have clicked
- do_check_true(DirectoryLinksProvider._frequencyCaps[landingUrl].clicked);
- do_check_true(DirectoryLinksProvider._frequencyCaps["http://bar.com"].clicked);
-
- testObserver = new UrlDeletionTester();
- DirectoryLinksProvider.addObserver(testObserver);
- yield PlacesTestUtils.clearHistory();
-
- yield testObserver.promise;
- DirectoryLinksProvider.removeObserver(testObserver);
- // no clicks should remain in the cap object
- do_check_false(DirectoryLinksProvider._frequencyCaps[landingUrl].hasOwnProperty("clicked"));
- do_check_false(DirectoryLinksProvider._frequencyCaps["http://bar.com"].hasOwnProperty("clicked"));
-
- // verify that disk written data is kosher
- data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath);
- do_check_false(data[landingUrl].hasOwnProperty("clicked"));
- do_check_false(data["http://bar.com"].hasOwnProperty("clicked"));
-
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function test_DirectoryLinksProvider_anonymous() {
- do_check_true(DirectoryLinksProvider._newXHR().mozAnon);
-});
-
-add_task(function* test_sanitizeExplanation() {
- // Note: this is a basic test to ensure we applied sanitization to the link explanation.
- // Full testing for appropriate sanitization is done in parser/xml/test/unit/test_sanitizer.js.
- let data = {"suggested": [suggestedTile5]};
- let dataURI = 'data:application/json,' + encodeURIComponent(JSON.stringify(data));
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- yield fetchData();
-
- let suggestedSites = [...DirectoryLinksProvider._suggestedLinks.keys()];
- do_check_eq(suggestedSites.indexOf("eviltarget.com"), 0);
- do_check_eq(suggestedSites.length, 1);
-
- let suggestedLink = [...DirectoryLinksProvider._suggestedLinks.get(suggestedSites[0]).values()][0];
- do_check_eq(suggestedLink.explanation, "This is an evil tile X muhahaha");
- do_check_eq(suggestedLink.targetedName, "WE ARE EVIL ");
-});
-
-add_task(function* test_inadjecentSites() {
- let suggestedTile = Object.assign({
- check_inadjacency: true
- }, suggestedTile1);
-
- // Initial setup
- let topSites = ["1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"];
- let data = {"suggested": [suggestedTile], "directory": [someOtherSite]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
-
- let testObserver = new TestFirstRun();
- DirectoryLinksProvider.addObserver(testObserver);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- let links = yield fetchData();
-
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = function(site) {
- return topSites.indexOf(site) >= 0;
- }
-
- let origGetProviderLinks = NewTabUtils.getProviderLinks;
- NewTabUtils.getProviderLinks = function(provider) {
- return links;
- }
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => {
- origCurrentTopSiteCount.apply(DirectoryLinksProvider);
- return 8;
- };
-
- // store oroginal inadjacent sites url
- let origInadjacentSitesUrl = DirectoryLinksProvider._inadjacentSitesUrl;
-
- // loading inadjacent sites list function
- function setInadjacentSites(sites) {
- let badSiteB64 = [];
- sites.forEach(site => {
- badSiteB64.push(DirectoryLinksProvider._generateHash(site));
- });
- let theList = {"domains": badSiteB64};
- let uri = 'data:application/json,' + JSON.stringify(theList);
- DirectoryLinksProvider._inadjacentSitesUrl = uri;
- return DirectoryLinksProvider._loadInadjacentSites();
- }
-
- // setup gLinks loader
- let gLinks = NewTabUtils.links;
- gLinks.addProvider(DirectoryLinksProvider);
-
- function updateNewTabCache() {
- gLinks.populateCache();
- return new Promise(resolve => {
- NewTabUtils.allPages.register({
- observe: _ => _,
- update() {
- NewTabUtils.allPages.unregister(this);
- resolve();
- }
- });
- });
- }
-
- // no suggested file
- do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined);
- // _avoidInadjacentSites should be set, since link.check_inadjacency is on
- do_check_true(DirectoryLinksProvider._avoidInadjacentSites);
- // make sure example.com is included in inadjacent sites list
- do_check_true(DirectoryLinksProvider._isInadjacentLink({baseDomain: "example.com"}));
-
- function TestFirstRun() {
- this.promise = new Promise(resolve => {
- this.onLinkChanged = (directoryLinksProvider, link) => {
- do_check_eq(link.url, suggestedTile.url);
- do_check_eq(link.type, "affiliate");
- resolve();
- };
- });
- }
-
- // Test first call to '_updateSuggestedTile()', called when fetching directory links.
- yield testObserver.promise;
- DirectoryLinksProvider.removeObserver(testObserver);
-
- // update newtab cache
- yield updateNewTabCache();
- // this should have set
- do_check_true(DirectoryLinksProvider._avoidInadjacentSites);
-
- // there should be siggested link
- let link = DirectoryLinksProvider._updateSuggestedTile();
- do_check_eq(link.url, "http://turbotax.com");
- // and it should have avoidInadjacentSites flag
- do_check_true(link.check_inadjacency);
-
- // make someothersite.com inadjacent
- yield setInadjacentSites(["someothersite.com"]);
-
- // there should be no suggested link
- link = DirectoryLinksProvider._updateSuggestedTile();
- do_check_false(link);
- do_check_true(DirectoryLinksProvider._newTabHasInadjacentSite);
-
- // _handleLinkChanged must return true on inadjacent site
- do_check_true(DirectoryLinksProvider._handleLinkChanged({
- url: "http://someothersite.com",
- type: "history",
- }));
- // _handleLinkChanged must return false on ok site
- do_check_false(DirectoryLinksProvider._handleLinkChanged({
- url: "http://foobar.com",
- type: "history",
- }));
-
- // change inadjacent list to sites not on newtab page
- yield setInadjacentSites(["foo.com", "bar.com"]);
-
- link = DirectoryLinksProvider._updateSuggestedTile();
- // we should now have a link
- do_check_true(link);
- do_check_eq(link.url, "http://turbotax.com");
-
- // make newtab offending again
- yield setInadjacentSites(["someothersite.com", "foo.com"]);
- // there should be no suggested link
- link = DirectoryLinksProvider._updateSuggestedTile();
- do_check_false(link);
- do_check_true(DirectoryLinksProvider._newTabHasInadjacentSite);
-
- // remove avoidInadjacentSites flag from suggested tile and reload json
- delete suggestedTile.check_inadjacency;
- data = {"suggested": [suggestedTile], "directory": [someOtherSite]};
- dataURI = 'data:application/json,' + JSON.stringify(data);
- yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, dataURI);
- yield fetchData();
-
- // inadjacent checking should be disabled
- do_check_false(DirectoryLinksProvider._avoidInadjacentSites);
- link = DirectoryLinksProvider._updateSuggestedTile();
- do_check_true(link);
- do_check_eq(link.url, "http://turbotax.com");
- do_check_false(DirectoryLinksProvider._newTabHasInadjacentSite);
-
- // _handleLinkChanged should return false now, even if newtab has bad site
- do_check_false(DirectoryLinksProvider._handleLinkChanged({
- url: "http://someothersite.com",
- type: "history",
- }));
-
- // test _isInadjacentLink
- do_check_true(DirectoryLinksProvider._isInadjacentLink({baseDomain: "someothersite.com"}));
- do_check_false(DirectoryLinksProvider._isInadjacentLink({baseDomain: "bar.com"}));
- do_check_true(DirectoryLinksProvider._isInadjacentLink({url: "http://www.someothersite.com"}));
- do_check_false(DirectoryLinksProvider._isInadjacentLink({url: "http://www.bar.com"}));
- // try to crash _isInadjacentLink
- do_check_false(DirectoryLinksProvider._isInadjacentLink({baseDomain: ""}));
- do_check_false(DirectoryLinksProvider._isInadjacentLink({url: ""}));
- do_check_false(DirectoryLinksProvider._isInadjacentLink({url: "http://localhost:8081/"}));
- do_check_false(DirectoryLinksProvider._isInadjacentLink({url: "abracodabra"}));
- do_check_false(DirectoryLinksProvider._isInadjacentLink({}));
-
- // test _checkForInadjacentSites
- do_check_true(DirectoryLinksProvider._checkForInadjacentSites());
-
- // Cleanup
- gLinks.removeProvider(DirectoryLinksProvider);
- DirectoryLinksProvider._inadjacentSitesUrl = origInadjacentSitesUrl;
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- NewTabUtils.getProviderLinks = origGetProviderLinks;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
- yield promiseCleanDirectoryLinksProvider();
-});
-
-add_task(function* test_blockSuggestedTiles() {
- // Initial setup
- let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"];
- let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3], "directory": [someOtherSite]};
- let dataURI = 'data:application/json,' + JSON.stringify(data);
-
- yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
- let links = yield fetchData();
-
- let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite;
- NewTabUtils.isTopPlacesSite = function(site) {
- return topSites.indexOf(site) >= 0;
- }
-
- let origGetProviderLinks = NewTabUtils.getProviderLinks;
- NewTabUtils.getProviderLinks = function(provider) {
- return links;
- }
-
- let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount;
- DirectoryLinksProvider._getCurrentTopSiteCount = () => 8;
-
- // load the links
- yield new Promise(resolve => {
- DirectoryLinksProvider.getLinks(resolve);
- });
-
- // ensure that tile is suggested
- let suggestedLink = DirectoryLinksProvider._updateSuggestedTile();
- do_check_true(suggestedLink.frecent_sites);
-
- // block suggested tile in a regular way
- DirectoryLinksProvider.reportSitesAction([{
- isPinned: function() { return false; },
- link: Object.assign({frecency: 1000}, suggestedLink)
- }], "block", 0);
-
- // suggested tile still must be recommended
- suggestedLink = DirectoryLinksProvider._updateSuggestedTile();
- do_check_true(suggestedLink.frecent_sites);
-
- // timestamp suggested_block in the frequency cap object
- DirectoryLinksProvider.handleSuggestedTileBlock();
- // no more recommendations should be seen
- do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined);
-
- // move lastUpdated for suggested tile into the past
- DirectoryLinksProvider._frequencyCaps["ignore://suggested_block"].lastUpdated = Date.now() - 25*60*60*1000;
- // ensure that suggested tile updates again
- suggestedLink = DirectoryLinksProvider._updateSuggestedTile();
- do_check_true(suggestedLink.frecent_sites);
-
- // Cleanup
- yield promiseCleanDirectoryLinksProvider();
- NewTabUtils.isTopPlacesSite = origIsTopPlacesSite;
- NewTabUtils.getProviderLinks = origGetProviderLinks;
- DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount;
-});
diff --git a/browser/modules/test/xpcshell/test_LaterRun.js b/browser/modules/test/xpcshell/test_LaterRun.js
deleted file mode 100644
index 7b45c7cd5..000000000
--- a/browser/modules/test/xpcshell/test_LaterRun.js
+++ /dev/null
@@ -1,138 +0,0 @@
-"use strict";
-
-const kEnabledPref = "browser.laterrun.enabled";
-const kPagePrefRoot = "browser.laterrun.pages.";
-const kSessionCountPref = "browser.laterrun.bookkeeping.sessionCount";
-const kProfileCreationTime = "browser.laterrun.bookkeeping.profileCreationTime";
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource:///modules/LaterRun.jsm");
-
-Services.prefs.setBoolPref(kEnabledPref, true);
-Components.utils.import("resource://testing-common/AppInfo.jsm");
-updateAppInfo();
-
-add_task(function* test_page_applies() {
- Services.prefs.setCharPref(kPagePrefRoot + "test_LaterRun_unittest.url", "https://www.mozilla.org/%VENDOR%/%NAME%/%ID%/%VERSION%/");
- Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumHoursSinceInstall", 10);
- Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumSessionCount", 3);
-
- let pages = LaterRun.readPages();
- // We have to filter the pages because it's possible Firefox ships with other URLs
- // that get included in this test.
- pages = pages.filter(page => page.pref == kPagePrefRoot + "test_LaterRun_unittest.");
- Assert.equal(pages.length, 1, "Got 1 page");
- let page = pages[0];
- Assert.equal(page.pref, kPagePrefRoot + "test_LaterRun_unittest.", "Should know its own pref");
- Assert.equal(page.minimumHoursSinceInstall, 10, "Needs to have 10 hours since install");
- Assert.equal(page.minimumSessionCount, 3, "Needs to have 3 sessions");
- Assert.equal(page.requireBoth, false, "Either requirement is enough");
- let expectedURL = "https://www.mozilla.org/" +
- Services.appinfo.vendor + "/" +
- Services.appinfo.name + "/" +
- Services.appinfo.ID + "/" +
- Services.appinfo.version + "/";
- Assert.equal(page.url, expectedURL, "URL is stored correctly");
-
- Assert.ok(page.applies({hoursSinceInstall: 1, sessionCount: 3}),
- "Applies when session count has been met.");
- Assert.ok(page.applies({hoursSinceInstall: 1, sessionCount: 4}),
- "Applies when session count has been exceeded.");
- Assert.ok(page.applies({hoursSinceInstall: 10, sessionCount: 2}),
- "Applies when total session time has been met.");
- Assert.ok(page.applies({hoursSinceInstall: 20, sessionCount: 2}),
- "Applies when total session time has been exceeded.");
- Assert.ok(page.applies({hoursSinceInstall: 10, sessionCount: 3}),
- "Applies when both time and session count have been met.");
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 1}),
- "Does not apply when neither time and session count have been met.");
-
- page.requireBoth = true;
-
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 3}),
- "Does not apply when only session count has been met.");
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 4}),
- "Does not apply when only session count has been exceeded.");
- Assert.ok(!page.applies({hoursSinceInstall: 10, sessionCount: 2}),
- "Does not apply when only total session time has been met.");
- Assert.ok(!page.applies({hoursSinceInstall: 20, sessionCount: 2}),
- "Does not apply when only total session time has been exceeded.");
- Assert.ok(page.applies({hoursSinceInstall: 10, sessionCount: 3}),
- "Applies when both time and session count have been met.");
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 1}),
- "Does not apply when neither time and session count have been met.");
-
- // Check that pages that have run never apply:
- Services.prefs.setBoolPref(kPagePrefRoot + "test_LaterRun_unittest.hasRun", true);
- page.requireBoth = false;
-
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 3}),
- "Does not apply when page has already run (sessionCount equal).");
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 4}),
- "Does not apply when page has already run (sessionCount exceeding).");
- Assert.ok(!page.applies({hoursSinceInstall: 10, sessionCount: 2}),
- "Does not apply when page has already run (hoursSinceInstall equal).");
- Assert.ok(!page.applies({hoursSinceInstall: 20, sessionCount: 2}),
- "Does not apply when page has already run (hoursSinceInstall exceeding).");
- Assert.ok(!page.applies({hoursSinceInstall: 10, sessionCount: 3}),
- "Does not apply when page has already run (both criteria equal).");
- Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 1}),
- "Does not apply when page has already run (both criteria insufficient anyway).");
-
- clearAllPagePrefs();
-});
-
-add_task(function* test_get_URL() {
- Services.prefs.setIntPref(kProfileCreationTime, Math.floor((Date.now() - 11 * 60 * 60 * 1000) / 1000));
- Services.prefs.setCharPref(kPagePrefRoot + "test_LaterRun_unittest.url", "https://www.mozilla.org/");
- Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumHoursSinceInstall", 10);
- Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumSessionCount", 3);
- let pages = LaterRun.readPages();
- // We have to filter the pages because it's possible Firefox ships with other URLs
- // that get included in this test.
- pages = pages.filter(page => page.pref == kPagePrefRoot + "test_LaterRun_unittest.");
- Assert.equal(pages.length, 1, "Should only be 1 matching page");
- let page = pages[0];
- let url;
- do {
- url = LaterRun.getURL();
- // We have to loop because it's possible Firefox ships with other URLs that get triggered by
- // this test.
- } while (url && url != "https://www.mozilla.org/");
- Assert.equal(url, "https://www.mozilla.org/", "URL should be as expected when prefs are set.");
- Assert.ok(Services.prefs.prefHasUserValue(kPagePrefRoot + "test_LaterRun_unittest.hasRun"), "Should have set pref");
- Assert.ok(Services.prefs.getBoolPref(kPagePrefRoot + "test_LaterRun_unittest.hasRun"), "Should have set pref to true");
- Assert.ok(page.hasRun, "Other page objects should know it has run, too.");
-
- clearAllPagePrefs();
-});
-
-add_task(function* test_insecure_urls() {
- Services.prefs.setCharPref(kPagePrefRoot + "test_LaterRun_unittest.url", "http://www.mozilla.org/");
- Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumHoursSinceInstall", 10);
- Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumSessionCount", 3);
- let pages = LaterRun.readPages();
- // We have to filter the pages because it's possible Firefox ships with other URLs
- // that get triggered in this test.
- pages = pages.filter(page => page.pref == kPagePrefRoot + "test_LaterRun_unittest.");
- Assert.equal(pages.length, 0, "URL with non-https scheme should get ignored");
- clearAllPagePrefs();
-});
-
-add_task(function* test_dynamic_pref_getter_setter() {
- delete LaterRun._sessionCount;
- Services.prefs.setIntPref(kSessionCountPref, 0);
- Assert.equal(LaterRun.sessionCount, 0, "Should start at 0");
-
- LaterRun.sessionCount++;
- Assert.equal(LaterRun.sessionCount, 1, "Should increment.");
- Assert.equal(Services.prefs.getIntPref(kSessionCountPref), 1, "Should update pref");
-});
-
-function clearAllPagePrefs() {
- let allChangedPrefs = Services.prefs.getChildList(kPagePrefRoot);
- for (let pref of allChangedPrefs) {
- Services.prefs.clearUserPref(pref);
- }
-}
-
diff --git a/browser/modules/test/xpcshell/test_SitePermissions.js b/browser/modules/test/xpcshell/test_SitePermissions.js
deleted file mode 100644
index 808d96599..000000000
--- a/browser/modules/test/xpcshell/test_SitePermissions.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-"use strict";
-
-Components.utils.import("resource:///modules/SitePermissions.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-add_task(function* testPermissionsListing() {
- Assert.deepEqual(SitePermissions.listPermissions().sort(),
- ["camera", "cookie", "desktop-notification", "geo", "image",
- "indexedDB", "install", "microphone", "popup", "screen"],
- "Correct list of all permissions");
-});
-
-add_task(function* testGetAllByURI() {
- // check that it returns an empty array on an invalid URI
- // like a file URI, which doesn't support site permissions
- let wrongURI = Services.io.newURI("file:///example.js", null, null)
- Assert.deepEqual(SitePermissions.getAllByURI(wrongURI), []);
-
- let uri = Services.io.newURI("https://example.com", null, null)
- Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
-
- SitePermissions.set(uri, "camera", SitePermissions.ALLOW);
- Assert.deepEqual(SitePermissions.getAllByURI(uri), [
- { id: "camera", state: SitePermissions.ALLOW }
- ]);
-
- SitePermissions.set(uri, "microphone", SitePermissions.SESSION);
- SitePermissions.set(uri, "desktop-notification", SitePermissions.BLOCK);
-
- Assert.deepEqual(SitePermissions.getAllByURI(uri), [
- { id: "camera", state: SitePermissions.ALLOW },
- { id: "microphone", state: SitePermissions.SESSION },
- { id: "desktop-notification", state: SitePermissions.BLOCK }
- ]);
-
- SitePermissions.remove(uri, "microphone");
- Assert.deepEqual(SitePermissions.getAllByURI(uri), [
- { id: "camera", state: SitePermissions.ALLOW },
- { id: "desktop-notification", state: SitePermissions.BLOCK }
- ]);
-
- SitePermissions.remove(uri, "camera");
- SitePermissions.remove(uri, "desktop-notification");
- Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
-
- // XXX Bug 1303108 - Control Center should only show non-default permissions
- SitePermissions.set(uri, "addon", SitePermissions.BLOCK);
- Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
- SitePermissions.remove(uri, "addon");
-});
-
-add_task(function* testGetPermissionDetailsByURI() {
- // check that it returns an empty array on an invalid URI
- // like a file URI, which doesn't support site permissions
- let wrongURI = Services.io.newURI("file:///example.js", null, null)
- Assert.deepEqual(SitePermissions.getPermissionDetailsByURI(wrongURI), []);
-
- let uri = Services.io.newURI("https://example.com", null, null)
-
- SitePermissions.set(uri, "camera", SitePermissions.ALLOW);
- SitePermissions.set(uri, "cookie", SitePermissions.SESSION);
- SitePermissions.set(uri, "popup", SitePermissions.BLOCK);
-
- let permissions = SitePermissions.getPermissionDetailsByURI(uri);
-
- let camera = permissions.find(({id}) => id === "camera");
- Assert.deepEqual(camera, {
- id: "camera",
- label: "Use the Camera",
- state: SitePermissions.ALLOW,
- availableStates: [
- { id: SitePermissions.UNKNOWN, label: "Always Ask" },
- { id: SitePermissions.ALLOW, label: "Allow" },
- { id: SitePermissions.BLOCK, label: "Block" },
- ]
- });
-
- // check that removed permissions (State.UNKNOWN) are skipped
- SitePermissions.remove(uri, "camera");
- permissions = SitePermissions.getPermissionDetailsByURI(uri);
-
- camera = permissions.find(({id}) => id === "camera");
- Assert.equal(camera, undefined);
-
- // check that different available state values are represented
-
- let cookie = permissions.find(({id}) => id === "cookie");
- Assert.deepEqual(cookie, {
- id: "cookie",
- label: "Set Cookies",
- state: SitePermissions.SESSION,
- availableStates: [
- { id: SitePermissions.ALLOW, label: "Allow" },
- { id: SitePermissions.SESSION, label: "Allow for Session" },
- { id: SitePermissions.BLOCK, label: "Block" },
- ]
- });
-
- let popup = permissions.find(({id}) => id === "popup");
- Assert.deepEqual(popup, {
- id: "popup",
- label: "Open Pop-up Windows",
- state: SitePermissions.BLOCK,
- availableStates: [
- { id: SitePermissions.ALLOW, label: "Allow" },
- { id: SitePermissions.BLOCK, label: "Block" },
- ]
- });
-
- SitePermissions.remove(uri, "cookie");
- SitePermissions.remove(uri, "popup");
-});
diff --git a/browser/modules/test/xpcshell/xpcshell.ini b/browser/modules/test/xpcshell/xpcshell.ini
deleted file mode 100644
index 28df9c4ed..000000000
--- a/browser/modules/test/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-head =
-tail =
-firefox-appdir = browser
-skip-if = toolkit == 'android'
-
-[test_AttributionCode.js]
-skip-if = os != 'win'
-[test_DirectoryLinksProvider.js]
-[test_SitePermissions.js]
-[test_LaterRun.js]
diff --git a/browser/themes/shared/customizableui/panelUI.inc.css b/browser/themes/shared/customizableui/panelUI.inc.css
index b46110ab5..b0bb05415 100644
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -28,65 +28,6 @@
height: 128px;
}
-#PanelUI-popup #PanelUI-contents:empty::before {
- content: "";
- background-image: url(chrome://browser/skin/customizableui/whimsy.png);
- background-size: 64px 64px;
- display: block;
- width: 64px;
- height: 64px;
- position: absolute;
- transition: transform 1s ease-out;
- animation: whimsyMoveX 3.05s linear 0s infinite alternate,
- whimsyMoveY 3.4s linear 0s infinite alternate;
-}
-
-#PanelUI-popup #PanelUI-contents:not(:hover):empty::before {
- filter: grayscale(100%);
-}
-
-#PanelUI-popup #PanelUI-contents:active:empty::before {
- animation: whimsyMoveX 3.05s linear 0s infinite alternate,
- whimsyMoveY 3.4s linear 0s infinite alternate,
- whimsyRotate 1s linear 0s infinite normal;
-}
-
-#PanelUI-popup #PanelUI-contents:-moz-locale-dir(rtl):empty::before {
- animation: whimsyMoveXRTL 3.05s linear 0s infinite alternate,
- whimsyMoveY 3.4s linear 0s infinite alternate;
-}
-
-#PanelUI-popup #PanelUI-contents:-moz-locale-dir(rtl):active:empty::before {
- animation: whimsyMoveXRTL 3.05s linear 0s infinite alternate,
- whimsyMoveY 3.4s linear 0s infinite alternate,
- whimsyRotate 1s linear 0s infinite normal;
-}
-
-@media (min-resolution: 2dppx) {
- #PanelUI-popup #PanelUI-contents:empty::before {
- background-image: url(chrome://browser/skin/customizableui/whimsy@2x.png);
- }
-}
-
-@keyframes whimsyMoveX {
- /* These values are adjusted for the padding on the panel. */
- from { margin-left: -15px; } to { margin-left: calc(100% - 49px); }
-}
-
-@keyframes whimsyMoveXRTL {
- /* These values are adjusted for the padding on the panel. */
- from { margin-right: -15px; } to { margin-right: calc(100% - 49px); }
-}
-
-@keyframes whimsyMoveY {
- /* These values are adjusted for the padding and height of the panel. */
- from { margin-top: -.5em; } to { margin-top: calc(64px - .5em); }
-}
-
-@keyframes whimsyRotate {
- to { transform: perspective(5000px) rotateY(360deg); }
-}
-
#PanelUI-button {
margin-inline-start: 2px;
border-inline-start: 1px solid;
diff --git a/browser/themes/shared/customizableui/whimsy.png b/browser/themes/shared/customizableui/whimsy.png
deleted file mode 100644
index 2e9fdd7eb..000000000
--- a/browser/themes/shared/customizableui/whimsy.png
+++ /dev/null
Binary files differ
diff --git a/browser/themes/shared/customizableui/whimsy@2x.png b/browser/themes/shared/customizableui/whimsy@2x.png
deleted file mode 100644
index 61f55f60f..000000000
--- a/browser/themes/shared/customizableui/whimsy@2x.png
+++ /dev/null
Binary files differ
diff --git a/browser/themes/shared/jar.inc.mn b/browser/themes/shared/jar.inc.mn
index f99f8de3c..dcc1e9dd9 100644
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -48,8 +48,6 @@
skin/classic/browser/customizableui/subView-arrow-back-inverted@2x.png (../shared/customizableui/subView-arrow-back-inverted@2x.png)
skin/classic/browser/customizableui/subView-arrow-back-inverted-rtl.png (../shared/customizableui/subView-arrow-back-inverted-rtl.png)
skin/classic/browser/customizableui/subView-arrow-back-inverted-rtl@2x.png (../shared/customizableui/subView-arrow-back-inverted-rtl@2x.png)
- skin/classic/browser/customizableui/whimsy.png (../shared/customizableui/whimsy.png)
- skin/classic/browser/customizableui/whimsy@2x.png (../shared/customizableui/whimsy@2x.png)
skin/classic/browser/downloads/contentAreaDownloadsView.css (../shared/downloads/contentAreaDownloadsView.css)
skin/classic/browser/downloads/download-blocked.svg (../shared/downloads/download-blocked.svg)
skin/classic/browser/downloads/menubutton-dropmarker.svg (../shared/downloads/menubutton-dropmarker.svg)
diff --git a/build/mobile/b2gautomation.py b/build/mobile/b2gautomation.py
index d49a5f1ac..d73edd419 100644
--- a/build/mobile/b2gautomation.py
+++ b/build/mobile/b2gautomation.py
@@ -241,8 +241,8 @@ class B2GRemoteAutomation(Automation):
self._devicemanager.killProcess('/system/b2g/b2g', sig=signal.SIGABRT)
timeout = 10 # seconds
- starttime = datetime.datetime.now()
- while datetime.datetime.now() - starttime < datetime.timedelta(seconds=timeout):
+ starttime = datetime.datetime.utcnow()
+ while datetime.datetime.utcnow() - starttime < datetime.timedelta(seconds=timeout):
if not self._devicemanager.processExist('/system/b2g/b2g'):
break
time.sleep(1)
diff --git a/build/mobile/remoteautomation.py b/build/mobile/remoteautomation.py
index 7b2fad6cb..1358e0dfe 100644
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -387,9 +387,9 @@ class RemoteAutomation(Automation):
# Get log updates on each interval, but if it is taking
# too long, only do it every 60 seconds
if (not slowLog) or (timer % 60 == 0):
- startRead = datetime.datetime.now()
+ startRead = datetime.datetime.utcnow()
hasOutput = self.read_stdout()
- if (datetime.datetime.now() - startRead) > datetime.timedelta(seconds=5):
+ if (datetime.datetime.utcnow() - startRead) > datetime.timedelta(seconds=5):
slowLog = True
if hasOutput:
noOutputTimer = 0
diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure
index 8b2416152..5e9fcc384 100644
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -686,9 +686,9 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
# Check the compiler version here instead of in `compiler_version` so
# that the `checking` message doesn't pretend the compiler can be used
# to then bail out one line later.
- if info.type == 'gcc' and info.version < '4.8.0':
+ if info.type == 'gcc' and info.version < '4.9.0':
raise FatalCheckError(
- 'Only GCC 4.8 or newer is supported (found version %s).'
+ 'Only GCC 4.9 or newer is supported (found version %s).'
% info.version)
# If you want to bump the version check here search for
diff --git a/build/release/info.py b/build/release/info.py
index 9f42edd5a..7e7a30bce 100644
--- a/build/release/info.py
+++ b/build/release/info.py
@@ -129,7 +129,7 @@ def getReleaseTag(tag):
def generateRelbranchName(version, prefix='GECKO'):
return '%s%s_%s_RELBRANCH' % (
prefix, version.replace('.', ''),
- datetime.now().strftime('%Y%m%d%H'))
+ datetime.utcnow().strftime('%Y%m%d%H'))
def getReleaseName(product, version, buildNumber):
diff --git a/build/variables.py b/build/variables.py
index 7761e6096..de0903af2 100644
--- a/build/variables.py
+++ b/build/variables.py
@@ -17,7 +17,7 @@ def buildid_header(output):
print('Ignoring invalid MOZ_BUILD_DATE: %s' % buildid, file=sys.stderr)
buildid = None
if not buildid:
- buildid = datetime.now().strftime('%Y%m%d%H%M%S')
+ buildid = datetime.utcnow().strftime('%Y%m%d%H%M%S')
output.write("#define MOZ_BUILDID %s\n" % buildid)
diff --git a/config/external/moz.build b/config/external/moz.build
index 029ff8504..c52933db8 100644
--- a/config/external/moz.build
+++ b/config/external/moz.build
@@ -36,6 +36,8 @@ if not CONFIG['MOZ_SYSTEM_LIBVPX']:
if not CONFIG['MOZ_SYSTEM_PNG']:
external_dirs += ['media/libpng']
+external_dirs += ['media/libwebp']
+
if CONFIG['CPU_ARCH'] == 'arm':
external_dirs += ['media/openmax_dl']
diff --git a/db/sqlite3/src/sqlite3.c b/db/sqlite3/src/sqlite3.c
index 04855f547..9c8fd6204 100644
--- a/db/sqlite3/src/sqlite3.c
+++ b/db/sqlite3/src/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.17.0. By combining all the individual C code files into this
+** version 3.19.3. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -391,16 +391,16 @@ extern "C" {
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and an SHA1
-** hash of the entire source tree.
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.17.0"
-#define SQLITE_VERSION_NUMBER 3017000
-#define SQLITE_SOURCE_ID "2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c"
+#define SQLITE_VERSION "3.19.3"
+#define SQLITE_VERSION_NUMBER 3019003
+#define SQLITE_SOURCE_ID "2017-06-08 14:26:16 0ee482a1e0eae22e08edc8978c9733a96603d4509645f348ebf55b579e89636b"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1134,7 +1134,7 @@ struct sqlite3_io_methods {
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
-** integers where the first integer i the new retry count and the second
+** integers where the first integer is the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
@@ -2317,20 +2317,30 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
-** most recent successful [INSERT] into a rowid table or [virtual table]
-** on database connection D.
-** ^Inserts into [WITHOUT ROWID] tables are not recorded.
-** ^If no successful [INSERT]s into rowid tables
-** have ever occurred on the database connection D,
-** then sqlite3_last_insert_rowid(D) returns zero.
-**
-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
-** method, then this routine will return the [rowid] of the inserted
-** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned
-** by this routine reverts to what it was before the trigger or virtual
-** table method began.)^
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
+** on the database connection D, then sqlite3_last_insert_rowid(D) returns
+** zero.
+**
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
+**
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
+** associated with these internal INSERT operations, which leads to
+** unintuitive results. Virtual table implementations that do write to rowid
+** tables in this way can avoid this problem by restoring the original
+** rowid value using [sqlite3_set_last_insert_rowid()] before returning
+** control to the user.
+**
+** ^(If an [INSERT] occurs within a trigger then this routine will
+** return the [rowid] of the inserted row as long as the trigger is
+** running. Once the trigger program ends, the value returned
+** by this routine reverts to what it was before the trigger was fired.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
@@ -2358,6 +2368,16 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** set the value returned by calling sqlite3_last_insert_rowid(D) to R
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+
+/*
** CAPI3REF: Count The Number Of Rows Modified
** METHOD: sqlite3
**
@@ -2468,9 +2488,6 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
-**
-** If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
@@ -2933,6 +2950,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
+** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2960,8 +2978,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are zero-terminated strings that contain additional
-** details about the action to be authorized.
+** to the callback are either NULL pointers or zero-terminated strings
+** that contain additional details about the action to be authorized.
+** Applications must always be prepared to encounter a NULL pointer in any
+** of the third through the sixth parameters of the authorization callback.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
@@ -2970,6 +2990,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
+** ^When a table is referenced by a [SELECT] but no column values are
+** extracted from that table (for example in a query like
+** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
+** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
@@ -3681,9 +3705,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. This limit is not currently
-** enforced, though that might be added in some future release of
-** SQLite.</dd>)^
+** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
@@ -3721,6 +3745,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
+
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
@@ -3961,7 +3986,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
-typedef struct Mem sqlite3_value;
+typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
@@ -5015,10 +5040,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
-** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If there is no metadata
-** associated with the function argument, this sqlite3_get_auxdata() interface
+** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
+** value to the application-defined function. ^N is zero for the left-most
+** function argument. ^If there is no metadata
+** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
@@ -5049,6 +5075,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
+** The value of the N parameter to these interfaces should be non-negative.
+** Future enhancements may make use of negative N values to define new
+** kinds of function caching behavior.
+**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
@@ -9643,7 +9673,7 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
** sqlite3changegroup_output() functions, also available are the streaming
** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
*/
-int sqlite3changegroup_new(sqlite3_changegroup **pp);
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
@@ -9720,7 +9750,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
**
** If no error occurs, SQLITE_OK is returned.
*/
-int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
@@ -9746,7 +9776,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
** responsibility of the caller to eventually free the buffer using a
** call to sqlite3_free().
*/
-int sqlite3changegroup_output(
+SQLITE_API int sqlite3changegroup_output(
sqlite3_changegroup*,
int *pnData, /* OUT: Size of output buffer in bytes */
void **ppData /* OUT: Pointer to output buffer */
@@ -9755,7 +9785,7 @@ int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
*/
-void sqlite3changegroup_delete(sqlite3_changegroup*);
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
/*
** CAPI3REF: Apply A Changeset To A Database
@@ -10144,11 +10174,11 @@ SQLITE_API int sqlite3session_patchset_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3changegroup_add_strm(sqlite3_changegroup*,
+SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
-int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
@@ -10848,7 +10878,7 @@ struct fts5_api {
** Not currently enforced.
*/
#ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 25000
+# define SQLITE_MAX_VDBE_OP 250000000
#endif
/*
@@ -11432,76 +11462,76 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_AS 24
#define TK_WITHOUT 25
#define TK_COMMA 26
-#define TK_OR 27
-#define TK_AND 28
-#define TK_IS 29
-#define TK_MATCH 30
-#define TK_LIKE_KW 31
-#define TK_BETWEEN 32
-#define TK_IN 33
-#define TK_ISNULL 34
-#define TK_NOTNULL 35
-#define TK_NE 36
-#define TK_EQ 37
-#define TK_GT 38
-#define TK_LE 39
-#define TK_LT 40
-#define TK_GE 41
-#define TK_ESCAPE 42
-#define TK_BITAND 43
-#define TK_BITOR 44
-#define TK_LSHIFT 45
-#define TK_RSHIFT 46
-#define TK_PLUS 47
-#define TK_MINUS 48
-#define TK_STAR 49
-#define TK_SLASH 50
-#define TK_REM 51
-#define TK_CONCAT 52
-#define TK_COLLATE 53
-#define TK_BITNOT 54
-#define TK_ID 55
-#define TK_INDEXED 56
-#define TK_ABORT 57
-#define TK_ACTION 58
-#define TK_AFTER 59
-#define TK_ANALYZE 60
-#define TK_ASC 61
-#define TK_ATTACH 62
-#define TK_BEFORE 63
-#define TK_BY 64
-#define TK_CASCADE 65
-#define TK_CAST 66
-#define TK_COLUMNKW 67
-#define TK_CONFLICT 68
-#define TK_DATABASE 69
-#define TK_DESC 70
-#define TK_DETACH 71
-#define TK_EACH 72
-#define TK_FAIL 73
-#define TK_FOR 74
-#define TK_IGNORE 75
-#define TK_INITIALLY 76
-#define TK_INSTEAD 77
-#define TK_NO 78
-#define TK_KEY 79
-#define TK_OF 80
-#define TK_OFFSET 81
-#define TK_PRAGMA 82
-#define TK_RAISE 83
-#define TK_RECURSIVE 84
-#define TK_REPLACE 85
-#define TK_RESTRICT 86
-#define TK_ROW 87
-#define TK_TRIGGER 88
-#define TK_VACUUM 89
-#define TK_VIEW 90
-#define TK_VIRTUAL 91
-#define TK_WITH 92
-#define TK_REINDEX 93
-#define TK_RENAME 94
-#define TK_CTIME_KW 95
-#define TK_ANY 96
+#define TK_ID 27
+#define TK_ABORT 28
+#define TK_ACTION 29
+#define TK_AFTER 30
+#define TK_ANALYZE 31
+#define TK_ASC 32
+#define TK_ATTACH 33
+#define TK_BEFORE 34
+#define TK_BY 35
+#define TK_CASCADE 36
+#define TK_CAST 37
+#define TK_COLUMNKW 38
+#define TK_CONFLICT 39
+#define TK_DATABASE 40
+#define TK_DESC 41
+#define TK_DETACH 42
+#define TK_EACH 43
+#define TK_FAIL 44
+#define TK_FOR 45
+#define TK_IGNORE 46
+#define TK_INITIALLY 47
+#define TK_INSTEAD 48
+#define TK_LIKE_KW 49
+#define TK_MATCH 50
+#define TK_NO 51
+#define TK_KEY 52
+#define TK_OF 53
+#define TK_OFFSET 54
+#define TK_PRAGMA 55
+#define TK_RAISE 56
+#define TK_RECURSIVE 57
+#define TK_REPLACE 58
+#define TK_RESTRICT 59
+#define TK_ROW 60
+#define TK_TRIGGER 61
+#define TK_VACUUM 62
+#define TK_VIEW 63
+#define TK_VIRTUAL 64
+#define TK_WITH 65
+#define TK_REINDEX 66
+#define TK_RENAME 67
+#define TK_CTIME_KW 68
+#define TK_ANY 69
+#define TK_OR 70
+#define TK_AND 71
+#define TK_IS 72
+#define TK_BETWEEN 73
+#define TK_IN 74
+#define TK_ISNULL 75
+#define TK_NOTNULL 76
+#define TK_NE 77
+#define TK_EQ 78
+#define TK_GT 79
+#define TK_LE 80
+#define TK_LT 81
+#define TK_GE 82
+#define TK_ESCAPE 83
+#define TK_BITAND 84
+#define TK_BITOR 85
+#define TK_LSHIFT 86
+#define TK_RSHIFT 87
+#define TK_PLUS 88
+#define TK_MINUS 89
+#define TK_STAR 90
+#define TK_SLASH 91
+#define TK_REM 92
+#define TK_CONCAT 93
+#define TK_COLLATE 94
+#define TK_BITNOT 95
+#define TK_INDEXED 96
#define TK_STRING 97
#define TK_JOIN_KW 98
#define TK_CONSTRAINT 99
@@ -11565,10 +11595,11 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_REGISTER 157
#define TK_VECTOR 158
#define TK_SELECT_COLUMN 159
-#define TK_ASTERISK 160
-#define TK_SPAN 161
-#define TK_SPACE 162
-#define TK_ILLEGAL 163
+#define TK_IF_NULL_ROW 160
+#define TK_ASTERISK 161
+#define TK_SPAN 162
+#define TK_SPACE 163
+#define TK_ILLEGAL 164
/* The token codes above must all fit in 8 bits */
#define TKFLG_MASK 0xff
@@ -12439,7 +12470,7 @@ struct BtreePayload {
const void *pKey; /* Key content for indexes. NULL for tables */
sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */
const void *pData; /* Data for tables. NULL for indexes */
- struct Mem *aMem; /* First of nMem value in the unpacked pKey */
+ sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */
u16 nMem; /* Number of aMem[] value. Might be zero */
int nData; /* Size of pData. 0 if none. */
int nZero; /* Extra zero data appended after pData,nData */
@@ -12459,6 +12490,7 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
+SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);
#ifndef SQLITE_OMIT_INCRBLOB
SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
@@ -12568,7 +12600,7 @@ typedef struct Vdbe Vdbe;
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
-typedef struct Mem Mem;
+typedef struct sqlite3_value Mem;
typedef struct SubProgram SubProgram;
/*
@@ -12625,6 +12657,7 @@ struct SubProgram {
int nOp; /* Elements in aOp[] */
int nMem; /* Number of memory cells required */
int nCsr; /* Number of cursors required */
+ u8 *aOnce; /* Array of OP_Once flags */
void *token; /* id that may be used to recursive triggers */
SubProgram *pNext; /* Next sub-program already visited */
};
@@ -12727,145 +12760,149 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Once 20
#define OP_If 21
#define OP_IfNot 22
-#define OP_SeekLT 23 /* synopsis: key=r[P3@P4] */
-#define OP_SeekLE 24 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGE 25 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGT 26 /* synopsis: key=r[P3@P4] */
-#define OP_Or 27 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
-#define OP_And 28 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_NoConflict 29 /* synopsis: key=r[P3@P4] */
-#define OP_NotFound 30 /* synopsis: key=r[P3@P4] */
-#define OP_Found 31 /* synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 32 /* synopsis: intkey=r[P3] */
-#define OP_NotExists 33 /* synopsis: intkey=r[P3] */
-#define OP_IsNull 34 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 35 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 36 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 37 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 38 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 39 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 40 /* same as TK_LT, synopsis: IF r[P3]<r[P1] */
-#define OP_Ge 41 /* same as TK_GE, synopsis: IF r[P3]>=r[P1] */
-#define OP_ElseNotEq 42 /* same as TK_ESCAPE */
-#define OP_BitAnd 43 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 44 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 45 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
-#define OP_ShiftRight 46 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
-#define OP_Add 47 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 48 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 49 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_Last 53
-#define OP_BitNot 54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_SorterSort 55
-#define OP_Sort 56
-#define OP_Rewind 57
-#define OP_IdxLE 58 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGT 59 /* synopsis: key=r[P3@P4] */
-#define OP_IdxLT 60 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGE 61 /* synopsis: key=r[P3@P4] */
-#define OP_RowSetRead 62 /* synopsis: r[P3]=rowset(P1) */
-#define OP_RowSetTest 63 /* synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 64
-#define OP_FkIfZero 65 /* synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IfPos 66 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero 67 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
-#define OP_DecrJumpZero 68 /* synopsis: if (--r[P1])==0 goto P2 */
-#define OP_IncrVacuum 69
-#define OP_VNext 70
-#define OP_Init 71 /* synopsis: Start at P2 */
-#define OP_Return 72
-#define OP_EndCoroutine 73
-#define OP_HaltIfNull 74 /* synopsis: if r[P3]=null halt */
-#define OP_Halt 75
-#define OP_Integer 76 /* synopsis: r[P2]=P1 */
-#define OP_Int64 77 /* synopsis: r[P2]=P4 */
-#define OP_String 78 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 79 /* synopsis: r[P2..P3]=NULL */
-#define OP_SoftNull 80 /* synopsis: r[P1]=NULL */
-#define OP_Blob 81 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 82 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 83 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 84 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
-#define OP_SCopy 85 /* synopsis: r[P2]=r[P1] */
-#define OP_IntCopy 86 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 87 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 88
-#define OP_Function0 89 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_Function 90 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_AddImm 91 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_RealAffinity 92
-#define OP_Cast 93 /* synopsis: affinity(r[P1]) */
-#define OP_Permutation 94
-#define OP_Compare 95 /* synopsis: r[P1@P3] <-> r[P2@P3] */
-#define OP_Column 96 /* synopsis: r[P3]=PX */
+#define OP_IfNullRow 23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
+#define OP_SeekLT 24 /* synopsis: key=r[P3@P4] */
+#define OP_SeekLE 25 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGE 26 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGT 27 /* synopsis: key=r[P3@P4] */
+#define OP_NoConflict 28 /* synopsis: key=r[P3@P4] */
+#define OP_NotFound 29 /* synopsis: key=r[P3@P4] */
+#define OP_Found 30 /* synopsis: key=r[P3@P4] */
+#define OP_SeekRowid 31 /* synopsis: intkey=r[P3] */
+#define OP_NotExists 32 /* synopsis: intkey=r[P3] */
+#define OP_Last 33
+#define OP_IfSmaller 34
+#define OP_SorterSort 35
+#define OP_Sort 36
+#define OP_Rewind 37
+#define OP_IdxLE 38 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGT 39 /* synopsis: key=r[P3@P4] */
+#define OP_IdxLT 40 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 41 /* synopsis: key=r[P3@P4] */
+#define OP_RowSetRead 42 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 43 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 44
+#define OP_FkIfZero 45 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_IfPos 46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero 47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_DecrJumpZero 48 /* synopsis: if (--r[P1])==0 goto P2 */
+#define OP_IncrVacuum 49
+#define OP_VNext 50
+#define OP_Init 51 /* synopsis: Start at P2 */
+#define OP_Return 52
+#define OP_EndCoroutine 53
+#define OP_HaltIfNull 54 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 55
+#define OP_Integer 56 /* synopsis: r[P2]=P1 */
+#define OP_Int64 57 /* synopsis: r[P2]=P4 */
+#define OP_String 58 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 59 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 60 /* synopsis: r[P1]=NULL */
+#define OP_Blob 61 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 62 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 63 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 64 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 65 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 66 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 67 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 68
+#define OP_Function0 69 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Or 70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_Function 72 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_AddImm 73 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_RealAffinity 74
+#define OP_IsNull 75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 79 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 81 /* same as TK_LT, synopsis: IF r[P3]<r[P1] */
+#define OP_Ge 82 /* same as TK_GE, synopsis: IF r[P3]>=r[P1] */
+#define OP_ElseNotEq 83 /* same as TK_ESCAPE */
+#define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight 87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add 88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_Cast 94 /* synopsis: affinity(r[P1]) */
+#define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_Permutation 96
#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */
-#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 100 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 101
-#define OP_SetCookie 102
-#define OP_ReopenIdx 103 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 104 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 105 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenAutoindex 106 /* synopsis: nColumn=P2 */
-#define OP_OpenEphemeral 107 /* synopsis: nColumn=P2 */
-#define OP_SorterOpen 108
-#define OP_SequenceTest 109 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_OpenPseudo 110 /* synopsis: P3 columns in r[P2] */
-#define OP_Close 111
-#define OP_ColumnsUsed 112
-#define OP_Sequence 113 /* synopsis: r[P2]=cursor[P1].ctr++ */
-#define OP_NewRowid 114 /* synopsis: r[P2]=rowid */
-#define OP_Insert 115 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_InsertInt 116 /* synopsis: intkey=P3 data=r[P2] */
-#define OP_Delete 117
-#define OP_ResetCount 118
-#define OP_SorterCompare 119 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData 120 /* synopsis: r[P2]=data */
-#define OP_RowData 121 /* synopsis: r[P2]=data */
-#define OP_Rowid 122 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 123
-#define OP_SorterInsert 124 /* synopsis: key=r[P2] */
-#define OP_IdxInsert 125 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 126 /* synopsis: key=r[P2@P3] */
-#define OP_Seek 127 /* synopsis: Move P3 to P1.rowid */
-#define OP_IdxRowid 128 /* synopsis: r[P2]=rowid */
-#define OP_Destroy 129
-#define OP_Clear 130
-#define OP_ResetSorter 131
+#define OP_Compare 98 /* synopsis: r[P1@P3] <-> r[P2@P3] */
+#define OP_Column 99 /* synopsis: r[P3]=PX */
+#define OP_Affinity 100 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 101 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 102 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 103
+#define OP_SetCookie 104
+#define OP_ReopenIdx 105 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 106 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 107 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenDup 108
+#define OP_OpenAutoindex 109 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 110 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 111
+#define OP_SequenceTest 112 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 113 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 114
+#define OP_ColumnsUsed 115
+#define OP_Sequence 116 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_NewRowid 117 /* synopsis: r[P2]=rowid */
+#define OP_Insert 118 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_InsertInt 119 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 120
+#define OP_ResetCount 121
+#define OP_SorterCompare 122 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 123 /* synopsis: r[P2]=data */
+#define OP_RowData 124 /* synopsis: r[P2]=data */
+#define OP_Rowid 125 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 126
+#define OP_SorterInsert 127 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 128 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 129 /* synopsis: key=r[P2@P3] */
+#define OP_Seek 130 /* synopsis: Move P3 to P1.rowid */
+#define OP_IdxRowid 131 /* synopsis: r[P2]=rowid */
#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_CreateIndex 133 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_CreateTable 134 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_ParseSchema 135
-#define OP_LoadAnalysis 136
-#define OP_DropTable 137
-#define OP_DropIndex 138
-#define OP_DropTrigger 139
-#define OP_IntegrityCk 140
-#define OP_RowSetAdd 141 /* synopsis: rowset(P1)=r[P2] */
-#define OP_Param 142
-#define OP_FkCounter 143 /* synopsis: fkctr[P1]+=P2 */
-#define OP_MemMax 144 /* synopsis: r[P1]=max(r[P1],r[P2]) */
-#define OP_OffsetLimit 145 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_AggStep0 146 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggStep 147 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggFinal 148 /* synopsis: accum=r[P1] N=P2 */
-#define OP_Expire 149
-#define OP_TableLock 150 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 151
-#define OP_VCreate 152
-#define OP_VDestroy 153
-#define OP_VOpen 154
-#define OP_VColumn 155 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VRename 156
-#define OP_Pagecount 157
-#define OP_MaxPgcnt 158
-#define OP_CursorHint 159
-#define OP_Noop 160
-#define OP_Explain 161
+#define OP_Destroy 133
+#define OP_Clear 134
+#define OP_ResetSorter 135
+#define OP_CreateIndex 136 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 137 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_SqlExec 138
+#define OP_ParseSchema 139
+#define OP_LoadAnalysis 140
+#define OP_DropTable 141
+#define OP_DropIndex 142
+#define OP_DropTrigger 143
+#define OP_IntegrityCk 144
+#define OP_RowSetAdd 145 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Param 146
+#define OP_FkCounter 147 /* synopsis: fkctr[P1]+=P2 */
+#define OP_MemMax 148 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_OffsetLimit 149 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggStep0 150 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep 151 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggFinal 152 /* synopsis: accum=r[P1] N=P2 */
+#define OP_Expire 153
+#define OP_TableLock 154 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 155
+#define OP_VCreate 156
+#define OP_VDestroy 157
+#define OP_VOpen 158
+#define OP_VColumn 159 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 160
+#define OP_Pagecount 161
+#define OP_MaxPgcnt 162
+#define OP_CursorHint 163
+#define OP_Noop 164
+#define OP_Explain 165
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -12880,25 +12917,25 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\
/* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\
-/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x09,\
-/* 24 */ 0x09, 0x09, 0x09, 0x26, 0x26, 0x09, 0x09, 0x09,\
-/* 32 */ 0x09, 0x09, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
-/* 40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\
-/* 48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\
-/* 56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23, 0x0b,\
-/* 64 */ 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,\
-/* 72 */ 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10,\
-/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00,\
-/* 88 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
-/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
+/* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
+/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
+/* 40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\
+/* 48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\
+/* 56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
+/* 64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
+/* 72 */ 0x00, 0x02, 0x02, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
+/* 80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\
+/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x02, 0x12,\
+/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 120 */ 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00, 0x00,\
-/* 128 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
-/* 144 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
-/* 160 */ 0x00, 0x00,}
+/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04,\
+/* 128 */ 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\
+/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 144 */ 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 160 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,}
/* The sqlite3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
@@ -12906,7 +12943,7 @@ typedef struct VdbeOpList VdbeOpList;
** generated this include file strives to group all JUMP opcodes
** together near the beginning of the list.
*/
-#define SQLITE_MX_JUMP_OPCODE 71 /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE 83 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -13870,7 +13907,7 @@ SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
** and the one-based values are used internally.
*/
#ifndef SQLITE_DEFAULT_SYNCHRONOUS
-# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1)
+# define SQLITE_DEFAULT_SYNCHRONOUS 2
#endif
#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
@@ -14076,6 +14113,7 @@ struct sqlite3 {
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
u8 mTrace; /* zero or more SQLITE_TRACE flags */
u8 skipBtreeMutex; /* True if no shared-cache backends */
+ u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */
@@ -14591,6 +14629,7 @@ struct Table {
/* ... also used as column name list in a VIEW */
int tnum; /* Root BTree page for this table */
u32 nTabRef; /* Number of pointers to this Table */
+ u32 tabFlags; /* Mask of TF_* values */
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
@@ -14598,7 +14637,6 @@ struct Table {
#ifdef SQLITE_ENABLE_COSTMULT
LogEst costMult; /* Cost multiplier for using this table */
#endif
- u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
@@ -14622,15 +14660,17 @@ struct Table {
** the TF_OOOHidden attribute would apply in this case. Such tables require
** special handling during INSERT processing.
*/
-#define TF_Readonly 0x01 /* Read-only system table */
-#define TF_Ephemeral 0x02 /* An ephemeral table */
-#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
-#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
-#define TF_Virtual 0x10 /* Is a virtual table */
-#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
-#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
-#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
-
+#define TF_Readonly 0x0001 /* Read-only system table */
+#define TF_Ephemeral 0x0002 /* An ephemeral table */
+#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */
+#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */
+#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */
+#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */
+#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
+#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
+#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
+ ** Index.aiRowLogEst[] values */
+#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -14638,7 +14678,7 @@ struct Table {
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
-# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
+# define IsVirtual(X) ((X)->nModuleArg)
#else
# define IsVirtual(X) 0
#endif
@@ -14873,6 +14913,7 @@ struct Index {
unsigned isResized:1; /* True if resizeIndexObject() has been called */
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
+ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -15182,8 +15223,9 @@ struct Expr {
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
+ int nAlloc; /* Number of a[] slots allocated */
struct ExprList_item { /* For each expression in the list */
- Expr *pExpr; /* The list of expressions */
+ Expr *pExpr; /* The parse tree for this expression */
char *zName; /* Token associated with this expression */
char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
@@ -15197,7 +15239,7 @@ struct ExprList {
} x;
int iConstExprReg; /* Register in which Expr value is cached */
} u;
- } *a; /* Alloc a power of two greater or equal to nExpr */
+ } a[1]; /* One slot for each expression in the list */
};
/*
@@ -16054,14 +16096,17 @@ struct Walker {
int walkerDepth; /* Number of subqueries */
u8 eCode; /* A small processing code */
union { /* Extra data for callback */
- NameContext *pNC; /* Naming context */
- int n; /* A counter */
- int iCur; /* A cursor number */
- SrcList *pSrcList; /* FROM clause */
- struct SrcCount *pSrcCount; /* Counting column references */
- struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
- int *aiCol; /* array of column indexes */
- struct IdxCover *pIdxCover; /* Check for index coverage */
+ NameContext *pNC; /* Naming context */
+ int n; /* A counter */
+ int iCur; /* A cursor number */
+ SrcList *pSrcList; /* FROM clause */
+ struct SrcCount *pSrcCount; /* Counting column references */
+ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
+ int *aiCol; /* array of column indexes */
+ struct IdxCover *pIdxCover; /* Check for index coverage */
+ struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */
+ ExprList *pGroupBy; /* GROUP BY clause */
+ struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */
} u;
};
@@ -16215,6 +16260,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
+SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
SQLITE_PRIVATE int sqlite3MallocSize(void*);
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
@@ -16506,6 +16552,7 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*);
SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
@@ -16529,6 +16576,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
@@ -17238,9 +17286,16 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
+**
+** URI filenames are enabled by default if SQLITE_HAS_CODEC is
+** enabled.
*/
#ifndef SQLITE_USE_URI
-# define SQLITE_USE_URI 0
+# ifdef SQLITE_HAS_CODEC
+# define SQLITE_USE_URI 1
+# else
+# define SQLITE_USE_URI 0
+# endif
#endif
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
@@ -17452,7 +17507,7 @@ static const char * const azCompileOpt[] = {
#if SQLITE_COVERAGE_TEST
"COVERAGE_TEST",
#endif
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
"DEBUG",
#endif
#if SQLITE_DEFAULT_LOCKING_MODE
@@ -17461,6 +17516,12 @@ static const char * const azCompileOpt[] = {
#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
#endif
+#if SQLITE_DEFAULT_SYNCHRONOUS
+ "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS),
+#endif
+#if SQLITE_DEFAULT_WAL_SYNCHRONOUS
+ "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS),
+#endif
#if SQLITE_DIRECT_OVERFLOW_READ
"DIRECT_OVERFLOW_READ",
#endif
@@ -18037,6 +18098,7 @@ struct VdbeFrame {
i64 *anExec; /* Event counters from parent frame */
Mem *aMem; /* Array of memory cells for parent frame */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
+ u8 *aOnce; /* Bitmask used by OP_Once */
void *token; /* Copy of SubProgram.token */
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
AuxData *pAuxData; /* Linked list of auxdata allocations */
@@ -18057,7 +18119,7 @@ struct VdbeFrame {
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
-struct Mem {
+struct sqlite3_value {
union MemValue {
double r; /* Real value used when MEM_Real is set in flags */
i64 i; /* Integer value used when MEM_Int is set in flags */
@@ -18159,11 +18221,11 @@ struct Mem {
** when the VM is halted (if not before).
*/
struct AuxData {
- int iOp; /* Instruction number of OP_Function opcode */
- int iArg; /* Index of function argument. */
+ int iAuxOp; /* Instruction number of OP_Function opcode */
+ int iAuxArg; /* Index of function argument. */
void *pAux; /* Aux data pointer */
- void (*xDelete)(void *); /* Destructor for the aux data */
- AuxData *pNext; /* Next element in list */
+ void (*xDeleteAux)(void*); /* Destructor for the aux data */
+ AuxData *pNextAux; /* Next element in list */
};
/*
@@ -19187,8 +19249,10 @@ static void computeYMD(DateTime *p){
p->Y = 2000;
p->M = 1;
p->D = 1;
+ }else if( !validJulianDay(p->iJD) ){
+ datetimeError(p);
+ return;
}else{
- assert( validJulianDay(p->iJD) );
Z = (int)((p->iJD + 43200000)/86400000);
A = (int)((Z - 1867216.25)/36524.25);
A = Z + 1 + A - (A/4);
@@ -19507,18 +19571,19 @@ static int parseModifier(
** or month or year.
*/
if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
+ if( !p->validJD && !p->validYMD && !p->validHMS ) break;
z += 9;
computeYMD(p);
p->validHMS = 1;
p->h = p->m = 0;
p->s = 0.0;
+ p->rawS = 0;
p->validTZ = 0;
p->validJD = 0;
if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
rc = 0;
}else if( sqlite3_stricmp(z,"year")==0 ){
- computeYMD(p);
p->M = 1;
p->D = 1;
rc = 0;
@@ -20640,7 +20705,9 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
*/
#include <sys/sysctl.h>
#include <malloc/malloc.h>
+#ifdef SQLITE_MIGHT_BE_SINGLE_CORE
#include <libkern/OSAtomic.h>
+#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
static malloc_zone_t* _sqliteZone_;
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
@@ -20833,19 +20900,10 @@ static int sqlite3MemInit(void *NotUsed){
}else{
/* only 1 core, use our own zone to contention over global locks,
** e.g. we have our own dedicated locks */
- bool success;
- malloc_zone_t* newzone = malloc_create_zone(4096, 0);
- malloc_set_zone_name(newzone, "Sqlite_Heap");
- do{
- success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
- (void * volatile *)&_sqliteZone_);
- }while(!_sqliteZone_);
- if( !success ){
- /* somebody registered a zone first */
- malloc_destroy_zone(newzone);
- }
+ _sqliteZone_ = malloc_create_zone(4096, 0);
+ malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
}
-#endif
+#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
UNUSED_PARAMETER(NotUsed);
return SQLITE_OK;
}
@@ -24052,8 +24110,8 @@ static void winMutexEnter(sqlite3_mutex *p){
p->owner = tid;
p->nRef++;
if( p->trace ){
- OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
- tid, p, p->trace, p->nRef));
+ OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
+ tid, p->id, p, p->trace, p->nRef));
}
#endif
}
@@ -24095,8 +24153,8 @@ static int winMutexTry(sqlite3_mutex *p){
#endif
#ifdef SQLITE_DEBUG
if( p->trace ){
- OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
- tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
+ OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
+ tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
}
#endif
return rc;
@@ -24124,8 +24182,8 @@ static void winMutexLeave(sqlite3_mutex *p){
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
- OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
- tid, p, p->trace, p->nRef));
+ OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
+ tid, p->id, p, p->trace, p->nRef));
}
#endif
}
@@ -24386,6 +24444,13 @@ static void mallocWithAlarm(int n, void **pp){
** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
+#ifdef SQLITE_MAX_MEMORY
+ if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
+ *pp = 0;
+ return;
+ }
+#endif
+
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
@@ -24574,7 +24639,7 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
if( db==0 || !isLookaside(db,p) ){
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( db==0 ){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
@@ -24623,11 +24688,12 @@ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
/*
** Free memory that might be associated with a particular database
-** connection.
+** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
+** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
*/
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
+SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( p==0 ) return;
+ assert( p!=0 );
if( db ){
if( db->pnBytesFreed ){
measureAllocationSize(db, p);
@@ -24635,7 +24701,7 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
#endif
@@ -24651,6 +24717,10 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
sqlite3_free(p);
}
+SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
+ assert( db==0 || sqlite3_mutex_held(db->mutex) );
+ if( p ) sqlite3DbFreeNN(db, p);
+}
/*
** Change the size of an existing memory allocation
@@ -25004,7 +25074,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
-#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */
+#define etRADIX 0 /* non-decimal integer types. %x %o */
#define etFLOAT 1 /* Floating point. %f */
#define etEXP 2 /* Exponentional notation. %e and %E */
#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */
@@ -25022,8 +25092,9 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
#define etPOINTER 13 /* The %p conversion */
#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
+#define etDECIMAL 16 /* %d or %u, but not %x, %o */
-#define etINVALID 16 /* Any unrecognized conversion type */
+#define etINVALID 17 /* Any unrecognized conversion type */
/*
@@ -25047,8 +25118,8 @@ typedef struct et_info { /* Information about each format field */
/*
** Allowed values for et_info.flags
*/
-#define FLAG_SIGNED 1 /* True if the value to convert is signed */
-#define FLAG_STRING 4 /* Allow infinity precision */
+#define FLAG_SIGNED 1 /* True if the value to convert is signed */
+#define FLAG_STRING 4 /* Allow infinite precision */
/*
@@ -25058,7 +25129,7 @@ typedef struct et_info { /* Information about each format field */
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
- { 'd', 10, 1, etRADIX, 0, 0 },
+ { 'd', 10, 1, etDECIMAL, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
@@ -25067,7 +25138,7 @@ static const et_info fmtinfo[] = {
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
- { 'u', 10, 0, etRADIX, 0, 0 },
+ { 'u', 10, 0, etDECIMAL, 0, 0 },
{ 'x', 16, 0, etRADIX, 16, 1 },
{ 'X', 16, 0, etRADIX, 0, 4 },
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -25076,7 +25147,7 @@ static const et_info fmtinfo[] = {
{ 'E', 0, 1, etEXP, 14, 0 },
{ 'G', 0, 1, etGENERIC, 14, 0 },
#endif
- { 'i', 10, 1, etRADIX, 0, 0 },
+ { 'i', 10, 1, etDECIMAL, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
@@ -25168,14 +25239,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
int idx; /* A general purpose loop counter */
int width; /* Width of the current field */
etByte flag_leftjustify; /* True if "-" flag is present */
- etByte flag_plussign; /* True if "+" flag is present */
- etByte flag_blanksign; /* True if " " flag is present */
+ etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
etByte flag_alternateform; /* True if "#" flag is present */
etByte flag_altform2; /* True if "!" flag is present */
etByte flag_zeropad; /* True if field width constant starts with zero */
- etByte flag_long; /* True if "l" flag is present */
- etByte flag_longlong; /* True if the "ll" flag is present */
+ etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
etByte done; /* Loop termination flag */
+ etByte cThousand; /* Thousands separator for %d and %u */
etByte xtype = etINVALID; /* Conversion paradigm */
u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
@@ -25218,17 +25288,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
break;
}
/* Find out what flags are present */
- flag_leftjustify = flag_plussign = flag_blanksign =
+ flag_leftjustify = flag_prefix = cThousand =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
- case '+': flag_plussign = 1; break;
- case ' ': flag_blanksign = 1; break;
+ case '+': flag_prefix = '+'; break;
+ case ' ': flag_prefix = ' '; break;
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
+ case ',': cThousand = ','; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
@@ -25298,13 +25369,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
flag_long = 1;
c = *++fmt;
if( c=='l' ){
- flag_longlong = 1;
+ flag_long = 2;
c = *++fmt;
- }else{
- flag_longlong = 0;
}
}else{
- flag_long = flag_longlong = 0;
+ flag_long = 0;
}
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
@@ -25322,15 +25391,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
- ** flag_plussign TRUE if a '+' is present.
+ ** flag_prefix '+' or ' ' or zero
** flag_leftjustify TRUE if a '-' is present or if the
** field width was negative.
** flag_zeropad TRUE if the width began with 0.
- ** flag_long TRUE if the letter 'l' (ell) prefixed
- ** the conversion character.
- ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
- ** the conversion character.
- ** flag_blanksign TRUE if a ' ' is present.
+ ** flag_long 1 for "l", 2 for "ll"
** width The specified field width. This is
** always non-negative. Zero is the default.
** precision The specified precision. The default
@@ -25340,19 +25405,24 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
*/
switch( xtype ){
case etPOINTER:
- flag_longlong = sizeof(char*)==sizeof(i64);
- flag_long = sizeof(char*)==sizeof(long int);
+ flag_long = sizeof(char*)==sizeof(i64) ? 2 :
+ sizeof(char*)==sizeof(long int) ? 1 : 0;
/* Fall through into the next case */
case etORDINAL:
- case etRADIX:
+ case etRADIX:
+ cThousand = 0;
+ /* Fall through into the next case */
+ case etDECIMAL:
if( infop->flags & FLAG_SIGNED ){
i64 v;
if( bArgList ){
v = getIntArg(pArgList);
- }else if( flag_longlong ){
- v = va_arg(ap,i64);
}else if( flag_long ){
- v = va_arg(ap,long int);
+ if( flag_long==2 ){
+ v = va_arg(ap,i64) ;
+ }else{
+ v = va_arg(ap,long int);
+ }
}else{
v = va_arg(ap,int);
}
@@ -25365,17 +25435,17 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
prefix = '-';
}else{
longvalue = v;
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
+ prefix = flag_prefix;
}
}else{
if( bArgList ){
longvalue = (u64)getIntArg(pArgList);
- }else if( flag_longlong ){
- longvalue = va_arg(ap,u64);
}else if( flag_long ){
- longvalue = va_arg(ap,unsigned long int);
+ if( flag_long==2 ){
+ longvalue = va_arg(ap,u64);
+ }else{
+ longvalue = va_arg(ap,unsigned long int);
+ }
}else{
longvalue = va_arg(ap,unsigned int);
}
@@ -25385,16 +25455,17 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
- if( precision<etBUFSIZE-10 ){
+ if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
nOut = etBUFSIZE;
zOut = buf;
}else{
- nOut = precision + 10;
- zOut = zExtra = sqlite3Malloc( nOut );
+ u64 n = (u64)precision + 10 + precision/3;
+ zOut = zExtra = sqlite3Malloc( n );
if( zOut==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
+ nOut = (int)n;
}
bufpt = &zOut[nOut-1];
if( xtype==etORDINAL ){
@@ -25415,8 +25486,23 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}while( longvalue>0 );
}
length = (int)(&zOut[nOut-1]-bufpt);
- for(idx=precision-length; idx>0; idx--){
+ while( precision>length ){
*(--bufpt) = '0'; /* Zero pad */
+ length++;
+ }
+ if( cThousand ){
+ int nn = (length - 1)/3; /* Number of "," to insert */
+ int ix = (length - 1)%3 + 1;
+ bufpt -= nn;
+ for(idx=0; nn>0; idx++){
+ bufpt[idx] = bufpt[idx+nn];
+ ix--;
+ if( ix==0 ){
+ bufpt[++idx] = cThousand;
+ nn--;
+ ix = 3;
+ }
+ }
}
if( prefix ) *(--bufpt) = prefix; /* Add sign */
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
@@ -25443,9 +25529,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
realvalue = -realvalue;
prefix = '-';
}else{
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
+ prefix = flag_prefix;
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
@@ -26217,6 +26301,10 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
int n = 0;
int cnt = 0;
+ if( p==0 ){
+ sqlite3TreeViewLine(pView, "nil-SELECT");
+ return;
+ }
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( p->pWith ){
sqlite3TreeViewWith(pView, p->pWith, 1);
@@ -26325,7 +26413,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */
- char zFlgs[30];
+ char zFlgs[60];
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( pExpr==0 ){
sqlite3TreeViewLine(pView, "nil");
@@ -26333,7 +26421,12 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
return;
}
if( pExpr->flags ){
- sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
+ if( ExprHasProperty(pExpr, EP_FromJoin) ){
+ sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x iRJT=%d",
+ pExpr->flags, pExpr->iRightJoinTable);
+ }else{
+ sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
+ }
}else{
zFlgs[0] = 0;
}
@@ -26552,6 +26645,11 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
break;
}
+ case TK_IF_NULL_ROW: {
+ sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ break;
+ }
default: {
sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
break;
@@ -28271,6 +28369,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
}
}
#endif
+ if( !sqlite3Isdigit(zNum[0]) ) return 0;
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
@@ -29434,145 +29533,149 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 20 */ "Once" OpHelp(""),
/* 21 */ "If" OpHelp(""),
/* 22 */ "IfNot" OpHelp(""),
- /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"),
- /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"),
- /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"),
- /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"),
- /* 27 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
- /* 28 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
- /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"),
- /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"),
- /* 31 */ "Found" OpHelp("key=r[P3@P4]"),
- /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"),
- /* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
- /* 34 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 35 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 36 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 37 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 38 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 39 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 40 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
- /* 41 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
- /* 42 */ "ElseNotEq" OpHelp(""),
- /* 43 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 44 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 45 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
- /* 46 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
- /* 47 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 48 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 49 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 50 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 51 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 52 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 53 */ "Last" OpHelp(""),
- /* 54 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
- /* 55 */ "SorterSort" OpHelp(""),
- /* 56 */ "Sort" OpHelp(""),
- /* 57 */ "Rewind" OpHelp(""),
- /* 58 */ "IdxLE" OpHelp("key=r[P3@P4]"),
- /* 59 */ "IdxGT" OpHelp("key=r[P3@P4]"),
- /* 60 */ "IdxLT" OpHelp("key=r[P3@P4]"),
- /* 61 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 62 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
- /* 63 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
- /* 64 */ "Program" OpHelp(""),
- /* 65 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 66 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 67 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
- /* 68 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
- /* 69 */ "IncrVacuum" OpHelp(""),
- /* 70 */ "VNext" OpHelp(""),
- /* 71 */ "Init" OpHelp("Start at P2"),
- /* 72 */ "Return" OpHelp(""),
- /* 73 */ "EndCoroutine" OpHelp(""),
- /* 74 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
- /* 75 */ "Halt" OpHelp(""),
- /* 76 */ "Integer" OpHelp("r[P2]=P1"),
- /* 77 */ "Int64" OpHelp("r[P2]=P4"),
- /* 78 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 79 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 80 */ "SoftNull" OpHelp("r[P1]=NULL"),
- /* 81 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 82 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 83 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 84 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
- /* 85 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 86 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
- /* 87 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 88 */ "CollSeq" OpHelp(""),
- /* 89 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 90 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 91 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 92 */ "RealAffinity" OpHelp(""),
- /* 93 */ "Cast" OpHelp("affinity(r[P1])"),
- /* 94 */ "Permutation" OpHelp(""),
- /* 95 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
- /* 96 */ "Column" OpHelp("r[P3]=PX"),
+ /* 23 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
+ /* 24 */ "SeekLT" OpHelp("key=r[P3@P4]"),
+ /* 25 */ "SeekLE" OpHelp("key=r[P3@P4]"),
+ /* 26 */ "SeekGE" OpHelp("key=r[P3@P4]"),
+ /* 27 */ "SeekGT" OpHelp("key=r[P3@P4]"),
+ /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 30 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"),
+ /* 32 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 33 */ "Last" OpHelp(""),
+ /* 34 */ "IfSmaller" OpHelp(""),
+ /* 35 */ "SorterSort" OpHelp(""),
+ /* 36 */ "Sort" OpHelp(""),
+ /* 37 */ "Rewind" OpHelp(""),
+ /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 43 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 44 */ "Program" OpHelp(""),
+ /* 45 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 46 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 47 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+ /* 48 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 49 */ "IncrVacuum" OpHelp(""),
+ /* 50 */ "VNext" OpHelp(""),
+ /* 51 */ "Init" OpHelp("Start at P2"),
+ /* 52 */ "Return" OpHelp(""),
+ /* 53 */ "EndCoroutine" OpHelp(""),
+ /* 54 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 55 */ "Halt" OpHelp(""),
+ /* 56 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 57 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 58 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 59 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 60 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 61 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 62 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 63 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 64 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 65 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 66 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 67 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 68 */ "CollSeq" OpHelp(""),
+ /* 69 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 70 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 71 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 72 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 73 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 74 */ "RealAffinity" OpHelp(""),
+ /* 75 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 76 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 77 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 78 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 79 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 80 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 81 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
+ /* 82 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
+ /* 83 */ "ElseNotEq" OpHelp(""),
+ /* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
+ /* 87 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
+ /* 88 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 89 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 90 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 91 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 92 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 94 */ "Cast" OpHelp("affinity(r[P1])"),
+ /* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
+ /* 96 */ "Permutation" OpHelp(""),
/* 97 */ "String8" OpHelp("r[P2]='P4'"),
- /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 100 */ "Count" OpHelp("r[P2]=count()"),
- /* 101 */ "ReadCookie" OpHelp(""),
- /* 102 */ "SetCookie" OpHelp(""),
- /* 103 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 104 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 105 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 106 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 107 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 108 */ "SorterOpen" OpHelp(""),
- /* 109 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 110 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
- /* 111 */ "Close" OpHelp(""),
- /* 112 */ "ColumnsUsed" OpHelp(""),
- /* 113 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
- /* 114 */ "NewRowid" OpHelp("r[P2]=rowid"),
- /* 115 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 116 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
- /* 117 */ "Delete" OpHelp(""),
- /* 118 */ "ResetCount" OpHelp(""),
- /* 119 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
- /* 120 */ "SorterData" OpHelp("r[P2]=data"),
- /* 121 */ "RowData" OpHelp("r[P2]=data"),
- /* 122 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 123 */ "NullRow" OpHelp(""),
- /* 124 */ "SorterInsert" OpHelp("key=r[P2]"),
- /* 125 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 126 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 127 */ "Seek" OpHelp("Move P3 to P1.rowid"),
- /* 128 */ "IdxRowid" OpHelp("r[P2]=rowid"),
- /* 129 */ "Destroy" OpHelp(""),
- /* 130 */ "Clear" OpHelp(""),
- /* 131 */ "ResetSorter" OpHelp(""),
+ /* 98 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
+ /* 99 */ "Column" OpHelp("r[P3]=PX"),
+ /* 100 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 101 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 102 */ "Count" OpHelp("r[P2]=count()"),
+ /* 103 */ "ReadCookie" OpHelp(""),
+ /* 104 */ "SetCookie" OpHelp(""),
+ /* 105 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 106 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 107 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 108 */ "OpenDup" OpHelp(""),
+ /* 109 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 110 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 111 */ "SorterOpen" OpHelp(""),
+ /* 112 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 113 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 114 */ "Close" OpHelp(""),
+ /* 115 */ "ColumnsUsed" OpHelp(""),
+ /* 116 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 117 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 118 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 119 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 120 */ "Delete" OpHelp(""),
+ /* 121 */ "ResetCount" OpHelp(""),
+ /* 122 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 123 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 124 */ "RowData" OpHelp("r[P2]=data"),
+ /* 125 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 126 */ "NullRow" OpHelp(""),
+ /* 127 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 128 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 129 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 130 */ "Seek" OpHelp("Move P3 to P1.rowid"),
+ /* 131 */ "IdxRowid" OpHelp("r[P2]=rowid"),
/* 132 */ "Real" OpHelp("r[P2]=P4"),
- /* 133 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
- /* 134 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
- /* 135 */ "ParseSchema" OpHelp(""),
- /* 136 */ "LoadAnalysis" OpHelp(""),
- /* 137 */ "DropTable" OpHelp(""),
- /* 138 */ "DropIndex" OpHelp(""),
- /* 139 */ "DropTrigger" OpHelp(""),
- /* 140 */ "IntegrityCk" OpHelp(""),
- /* 141 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 142 */ "Param" OpHelp(""),
- /* 143 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
- /* 144 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
- /* 145 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
- /* 146 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 147 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 148 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 149 */ "Expire" OpHelp(""),
- /* 150 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 151 */ "VBegin" OpHelp(""),
- /* 152 */ "VCreate" OpHelp(""),
- /* 153 */ "VDestroy" OpHelp(""),
- /* 154 */ "VOpen" OpHelp(""),
- /* 155 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 156 */ "VRename" OpHelp(""),
- /* 157 */ "Pagecount" OpHelp(""),
- /* 158 */ "MaxPgcnt" OpHelp(""),
- /* 159 */ "CursorHint" OpHelp(""),
- /* 160 */ "Noop" OpHelp(""),
- /* 161 */ "Explain" OpHelp(""),
+ /* 133 */ "Destroy" OpHelp(""),
+ /* 134 */ "Clear" OpHelp(""),
+ /* 135 */ "ResetSorter" OpHelp(""),
+ /* 136 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 137 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 138 */ "SqlExec" OpHelp(""),
+ /* 139 */ "ParseSchema" OpHelp(""),
+ /* 140 */ "LoadAnalysis" OpHelp(""),
+ /* 141 */ "DropTable" OpHelp(""),
+ /* 142 */ "DropIndex" OpHelp(""),
+ /* 143 */ "DropTrigger" OpHelp(""),
+ /* 144 */ "IntegrityCk" OpHelp(""),
+ /* 145 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 146 */ "Param" OpHelp(""),
+ /* 147 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 148 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 149 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+ /* 150 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 151 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 152 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 153 */ "Expire" OpHelp(""),
+ /* 154 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 155 */ "VBegin" OpHelp(""),
+ /* 156 */ "VCreate" OpHelp(""),
+ /* 157 */ "VDestroy" OpHelp(""),
+ /* 158 */ "VOpen" OpHelp(""),
+ /* 159 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 160 */ "VRename" OpHelp(""),
+ /* 161 */ "Pagecount" OpHelp(""),
+ /* 162 */ "MaxPgcnt" OpHelp(""),
+ /* 163 */ "CursorHint" OpHelp(""),
+ /* 164 */ "Noop" OpHelp(""),
+ /* 165 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -37954,7 +38057,34 @@ struct winVfsAppData {
******************************************************************************
*/
#ifndef SQLITE_WIN32_HEAP_CREATE
-# define SQLITE_WIN32_HEAP_CREATE (TRUE)
+# define SQLITE_WIN32_HEAP_CREATE (TRUE)
+#endif
+
+/*
+ * This is the maximum possible initial size of the Win32-specific heap, in
+ * bytes.
+ */
+#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
+# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
+#endif
+
+/*
+ * This is the extra space for the initial size of the Win32-specific heap,
+ * in bytes. This value may be zero.
+ */
+#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
+# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
+#endif
+
+/*
+ * Calculate the maximum legal cache size, in pages, based on the maximum
+ * possible initial heap size and the default page size, setting aside the
+ * needed extra space.
+ */
+#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
+# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
+ (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
+ (SQLITE_DEFAULT_PAGE_SIZE))
#endif
/*
@@ -37963,25 +38093,36 @@ struct winVfsAppData {
*/
#ifndef SQLITE_WIN32_CACHE_SIZE
# if SQLITE_DEFAULT_CACHE_SIZE>=0
-# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
+# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
# else
-# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
+# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
# endif
#endif
/*
+ * Make sure that the calculated cache size, in pages, cannot cause the
+ * initial size of the Win32-specific heap to exceed the maximum amount
+ * of memory that can be specified in the call to HeapCreate.
+ */
+#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
+# undef SQLITE_WIN32_CACHE_SIZE
+# define SQLITE_WIN32_CACHE_SIZE (2000)
+#endif
+
+/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
-# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
- (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
+# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
+ (SQLITE_DEFAULT_PAGE_SIZE) + \
+ (SQLITE_WIN32_HEAP_INIT_EXTRA))
#endif
/*
* The maximum size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
-# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
+# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
#endif
/*
@@ -37989,7 +38130,7 @@ struct winVfsAppData {
* zero for the default behavior.
*/
#ifndef SQLITE_WIN32_HEAP_FLAGS
-# define SQLITE_WIN32_HEAP_FLAGS (0)
+# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
@@ -44086,7 +44227,7 @@ struct PCache {
**
** assert( sqlite3PcachePageSanity(pPg) );
*/
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
PCache *pCache;
assert( pPg!=0 );
@@ -45149,8 +45290,7 @@ static int pcache1InitBulk(PCache1 *pCache){
sqlite3EndBenignMalloc();
if( zBulk ){
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
- int i;
- for(i=0; i<nBulk; i++){
+ do{
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
pX->page.pBuf = zBulk;
pX->page.pExtra = &pX[1];
@@ -45159,7 +45299,7 @@ static int pcache1InitBulk(PCache1 *pCache){
pX->pNext = pCache->pFree;
pCache->pFree = pX;
zBulk += pCache->szAlloc;
- }
+ }while( --nBulk );
}
return pCache->pFree!=0;
}
@@ -46075,7 +46215,7 @@ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
int nFree = 0;
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
assert( sqlite3_mutex_notheld(pcache1.mutex) );
- if( sqlite3GlobalConfig.nPage==0 ){
+ if( sqlite3GlobalConfig.pPage==0 ){
PgHdr1 *p;
pcache1EnterMutex(&pcache1.grp);
while( (nReq<0 || nFree<nReq)
@@ -49035,6 +49175,11 @@ static int pager_playback_one_page(
char *aData; /* Temporary storage for the page */
sqlite3_file *jfd; /* The file descriptor for the journal file */
int isSynced; /* True if journal page is synced */
+#ifdef SQLITE_HAS_CODEC
+ /* The jrnlEnc flag is true if Journal pages should be passed through
+ ** the codec. It is false for pure in-memory journals. */
+ const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
+#endif
assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
@@ -49158,14 +49303,34 @@ static int pager_playback_one_page(
i64 ofst = (pgno-1)*(i64)pPager->pageSize;
testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
assert( !pagerUseWal(pPager) );
+
+ /* Write the data read from the journal back into the database file.
+ ** This is usually safe even for an encrypted database - as the data
+ ** was encrypted before it was written to the journal file. The exception
+ ** is if the data was just read from an in-memory sub-journal. In that
+ ** case it must be encrypted here before it is copied into the database
+ ** file. */
+#ifdef SQLITE_HAS_CODEC
+ if( !jrnlEnc ){
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
+ rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
+ }else
+#endif
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
+
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
+#ifdef SQLITE_HAS_CODEC
+ if( jrnlEnc ){
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
+ sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
+ }else
+#endif
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
}
}else if( !isMainJrnl && pPg==0 ){
/* If this is a rollback of a savepoint and data was not written to
@@ -49217,7 +49382,9 @@ static int pager_playback_one_page(
}
/* Decode the page just read from disk */
- CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
+#if SQLITE_HAS_CODEC
+ if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
+#endif
sqlite3PcacheRelease(pPg);
}
return rc;
@@ -51229,8 +51396,13 @@ static int subjournalPage(PgHdr *pPg){
void *pData = pPg->pData;
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
-
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
+
+#if SQLITE_HAS_CODEC
+ if( !pPager->subjInMemory ){
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
+ }else
+#endif
+ pData2 = pData;
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
if( rc==SQLITE_OK ){
@@ -58382,10 +58554,10 @@ struct BtCursor {
** initialized. */
i8 iPage; /* Index of current page in apPage */
u8 curIntKey; /* Value of apPage[0]->intKey */
- struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
- void *padding1; /* Make object size a multiple of 16 */
- u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
+ u16 ix; /* Current index for apPage[iPage] */
+ u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */
+ struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */
+ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
};
/*
@@ -59361,6 +59533,7 @@ static void invalidateAllOverflowCache(BtShared *pBt){
*/
static void invalidateIncrblobCursors(
Btree *pBtree, /* The database file to check */
+ Pgno pgnoRoot, /* The table that might be changing */
i64 iRow, /* The rowid that might be changing */
int isClearTable /* True if all rows are being deleted */
){
@@ -59371,7 +59544,7 @@ static void invalidateIncrblobCursors(
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
if( (p->curFlags & BTCF_Incrblob)!=0 ){
pBtree->hasIncrblobCur = 1;
- if( isClearTable || p->info.nKey==iRow ){
+ if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){
p->eState = CURSOR_INVALID;
}
}
@@ -59380,7 +59553,7 @@ static void invalidateIncrblobCursors(
#else
/* Stub function when INCRBLOB is omitted */
- #define invalidateIncrblobCursors(x,y,z)
+ #define invalidateIncrblobCursors(w,x,y,z)
#endif /* SQLITE_OMIT_INCRBLOB */
/*
@@ -60179,17 +60352,18 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
/*
-** Defragment the page given. All Cells are moved to the
-** end of the page and all free space is collected into one
-** big FreeBlk that occurs in between the header and cell
-** pointer array and the cell content area.
+** Defragment the page given. This routine reorganizes cells within the
+** page so that there are no free-blocks on the free-block list.
+**
+** Parameter nMaxFrag is the maximum amount of fragmented space that may be
+** present in the page after this routine returns.
**
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
** b-tree page so that there are no freeblocks or fragment bytes, all
** unused bytes are contained in the unallocated space region, and all
** cells are packed tightly at the end of the page.
*/
-static int defragmentPage(MemPage *pPage){
+static int defragmentPage(MemPage *pPage, int nMaxFrag){
int i; /* Loop counter */
int pc; /* Address of the i-th cell */
int hdr; /* Offset to the page header */
@@ -60204,7 +60378,6 @@ static int defragmentPage(MemPage *pPage){
int iCellFirst; /* First allowable cell index */
int iCellLast; /* Last possible cell index */
-
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( pPage->pBt!=0 );
assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
@@ -60216,9 +60389,56 @@ static int defragmentPage(MemPage *pPage){
cellOffset = pPage->cellOffset;
nCell = pPage->nCell;
assert( nCell==get2byte(&data[hdr+3]) );
+ iCellFirst = cellOffset + 2*nCell;
usableSize = pPage->pBt->usableSize;
+
+ /* This block handles pages with two or fewer free blocks and nMaxFrag
+ ** or fewer fragmented bytes. In this case it is faster to move the
+ ** two (or one) blocks of cells using memmove() and add the required
+ ** offsets to each pointer in the cell-pointer array than it is to
+ ** reconstruct the entire page. */
+ if( (int)data[hdr+7]<=nMaxFrag ){
+ int iFree = get2byte(&data[hdr+1]);
+ if( iFree ){
+ int iFree2 = get2byte(&data[iFree]);
+
+ /* pageFindSlot() has already verified that free blocks are sorted
+ ** in order of offset within the page, and that no block extends
+ ** past the end of the page. Provided the two free slots do not
+ ** overlap, this guarantees that the memmove() calls below will not
+ ** overwrite the usableSize byte buffer, even if the database page
+ ** is corrupt. */
+ assert( iFree2==0 || iFree2>iFree );
+ assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
+ assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
+
+ if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
+ u8 *pEnd = &data[cellOffset + nCell*2];
+ u8 *pAddr;
+ int sz2 = 0;
+ int sz = get2byte(&data[iFree+2]);
+ int top = get2byte(&data[hdr+5]);
+ if( iFree2 ){
+ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_BKPT;
+ sz2 = get2byte(&data[iFree2+2]);
+ assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
+ memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
+ sz += sz2;
+ }
+ cbrk = top+sz;
+ assert( cbrk+(iFree-top) <= usableSize );
+ memmove(&data[cbrk], &data[top], iFree-top);
+ for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
+ pc = get2byte(pAddr);
+ if( pc<iFree ){ put2byte(pAddr, pc+sz); }
+ else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
+ }
+ goto defragment_out;
+ }
+ }
+ }
+
cbrk = usableSize;
- iCellFirst = cellOffset + 2*nCell;
iCellLast = usableSize - 4;
for(i=0; i<nCell; i++){
u8 *pAddr; /* The i-th cell pointer */
@@ -60252,16 +60472,18 @@ static int defragmentPage(MemPage *pPage){
}
memcpy(&data[cbrk], &src[pc], size);
}
+ data[hdr+7] = 0;
+
+ defragment_out:
+ if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
+ return SQLITE_CORRUPT_BKPT;
+ }
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
data[hdr+1] = 0;
data[hdr+2] = 0;
- data[hdr+7] = 0;
memset(&data[iCellFirst], 0, cbrk-iCellFirst);
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- if( cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_BKPT;
- }
return SQLITE_OK;
}
@@ -60399,10 +60621,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
assert( pPage->nCell>0 || CORRUPT_DB );
- rc = defragmentPage(pPage);
+ rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
- assert( gap+nByte<=top );
+ assert( gap+2+nByte<=top );
}
@@ -61674,6 +61896,31 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){
#endif
}
+/*
+** If the user has not set the safety-level for this database connection
+** using "PRAGMA synchronous", and if the safety-level is not already
+** set to the value passed to this function as the second parameter,
+** set it so.
+*/
+#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
+static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
+ sqlite3 *db;
+ Db *pDb;
+ if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
+ while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
+ if( pDb->bSyncSet==0
+ && pDb->safety_level!=safety_level
+ && pDb!=&db->aDb[1]
+ ){
+ pDb->safety_level = safety_level;
+ sqlite3PagerSetFlags(pBt->pPager,
+ pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
+ }
+ }
+}
+#else
+# define setDefaultSyncFlag(pBt,safety_level)
+#endif
/*
** Get a reference to pPage1 of the database file. This will
@@ -61747,26 +61994,15 @@ static int lockBtree(BtShared *pBt){
if( rc!=SQLITE_OK ){
goto page1_init_failed;
}else{
-#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
- sqlite3 *db;
- Db *pDb;
- if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
- while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
- if( pDb->bSyncSet==0
- && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1
- ){
- pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1;
- sqlite3PagerSetFlags(pBt->pPager,
- pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
- }
- }
-#endif
+ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
if( isOpen==0 ){
releasePage(pPage1);
return SQLITE_OK;
}
}
rc = SQLITE_NOTADB;
+ }else{
+ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1);
}
#endif
@@ -63115,7 +63351,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
CellInfo info;
int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
- btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
+ btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
@@ -63125,7 +63361,7 @@ static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
if( pCur->info.nSize==0 ){
int iPage = pCur->iPage;
pCur->curFlags |= BTCF_ValidNKey;
- btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
+ btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
}else{
assertCellInfo(pCur);
}
@@ -63332,7 +63568,7 @@ static int accessPayload(
assert( pPage );
assert( eOp==0 || eOp==1 );
assert( pCur->eState==CURSOR_VALID );
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
+ assert( pCur->ix<pPage->nCell );
assert( cursorHoldsMutex(pCur) );
getCellInfo(pCur);
@@ -63519,7 +63755,7 @@ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
}
@@ -63581,7 +63817,7 @@ static const void *fetchPayload(
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
@@ -63632,13 +63868,13 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
}
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- pCur->iPage++;
- pCur->aiIdx[pCur->iPage] = 0;
+ pCur->aiIdx[pCur->iPage++] = pCur->ix;
+ pCur->ix = 0;
return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
pCur, pCur->curPagerFlags);
}
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
@@ -63681,6 +63917,7 @@ static void moveToParent(BtCursor *pCur){
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+ pCur->ix = pCur->aiIdx[pCur->iPage-1];
releasePageNotNull(pCur->apPage[pCur->iPage--]);
}
@@ -63762,7 +63999,7 @@ static int moveToRoot(BtCursor *pCur){
}
skip_init:
- pCur->aiIdx[0] = 0;
+ pCur->ix = 0;
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
@@ -63796,8 +64033,8 @@ static int moveToLeftmost(BtCursor *pCur){
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
+ assert( pCur->ix<pPage->nCell );
+ pgno = get4byte(findCell(pPage, pCur->ix));
rc = moveToChild(pCur, pgno);
}
return rc;
@@ -63822,11 +64059,11 @@ static int moveToRightmost(BtCursor *pCur){
assert( pCur->eState==CURSOR_VALID );
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- pCur->aiIdx[pCur->iPage] = pPage->nCell;
+ pCur->ix = pPage->nCell;
rc = moveToChild(pCur, pgno);
if( rc ) return rc;
}
- pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
+ pCur->ix = pPage->nCell-1;
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
return SQLITE_OK;
@@ -63874,7 +64111,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
for(ii=0; ii<pCur->iPage; ii++){
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
}
- assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
+ assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
assert( pCur->apPage[pCur->iPage]->leaf );
#endif
return SQLITE_OK;
@@ -64021,7 +64258,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
upr = pPage->nCell-1;
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
- pCur->aiIdx[pCur->iPage] = (u16)idx;
+ pCur->ix = (u16)idx;
if( xRecordCompare==0 ){
for(;;){
i64 nCellKey;
@@ -64040,7 +64277,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
if( lwr>upr ){ c = +1; break; }
}else{
assert( nCellKey==intKey );
- pCur->aiIdx[pCur->iPage] = (u16)idx;
+ pCur->ix = (u16)idx;
if( !pPage->leaf ){
lwr = idx;
goto moveto_next_layer;
@@ -64109,7 +64346,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
- pCur->aiIdx[pCur->iPage] = (u16)idx;
+ pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
@@ -64131,7 +64368,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
- pCur->aiIdx[pCur->iPage] = (u16)idx;
+ pCur->ix = (u16)idx;
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
@@ -64143,8 +64380,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- pCur->aiIdx[pCur->iPage] = (u16)idx;
+ assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+ pCur->ix = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_finish;
@@ -64155,7 +64392,7 @@ moveto_next_layer:
}else{
chldPg = get4byte(findCell(pPage, lwr));
}
- pCur->aiIdx[pCur->iPage] = (u16)lwr;
+ pCur->ix = (u16)lwr;
rc = moveToChild(pCur, chldPg);
if( rc ) break;
}
@@ -64182,6 +64419,30 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
}
/*
+** Return an estimate for the number of rows in the table that pCur is
+** pointing to. Return a negative number if no estimate is currently
+** available.
+*/
+SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
+ i64 n;
+ u8 i;
+
+ assert( cursorOwnsBtShared(pCur) );
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+
+ /* Currently this interface is only called by the OP_IfSmaller
+ ** opcode, and it that case the cursor will always be valid and
+ ** will always point to a leaf node. */
+ if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
+ if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1;
+
+ for(n=1, i=0; i<=pCur->iPage; i++){
+ n *= pCur->apPage[i]->nCell;
+ }
+ return n;
+}
+
+/*
** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor
** was already pointing to the last entry in the database before
@@ -64232,7 +64493,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
}
pPage = pCur->apPage[pCur->iPage];
- idx = ++pCur->aiIdx[pCur->iPage];
+ idx = ++pCur->ix;
assert( pPage->isInit );
/* If the database file is corrupt, it is possible for the value of idx
@@ -64256,7 +64517,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
}
moveToParent(pCur);
pPage = pCur->apPage[pCur->iPage];
- }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
+ }while( pCur->ix>=pPage->nCell );
if( pPage->intKey ){
return sqlite3BtreeNext(pCur, pRes);
}else{
@@ -64280,8 +64541,8 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
*pRes = 0;
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
pPage = pCur->apPage[pCur->iPage];
- if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
- pCur->aiIdx[pCur->iPage]--;
+ if( (++pCur->ix)>=pPage->nCell ){
+ pCur->ix--;
return btreeNext(pCur, pRes);
}
if( pPage->leaf ){
@@ -64345,12 +64606,12 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
pPage = pCur->apPage[pCur->iPage];
assert( pPage->isInit );
if( !pPage->leaf ){
- int idx = pCur->aiIdx[pCur->iPage];
+ int idx = pCur->ix;
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ) return rc;
rc = moveToRightmost(pCur);
}else{
- while( pCur->aiIdx[pCur->iPage]==0 ){
+ while( pCur->ix==0 ){
if( pCur->iPage==0 ){
pCur->eState = CURSOR_INVALID;
*pRes = 1;
@@ -64361,7 +64622,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
- pCur->aiIdx[pCur->iPage]--;
+ pCur->ix--;
pPage = pCur->apPage[pCur->iPage];
if( pPage->intKey && !pPage->leaf ){
rc = sqlite3BtreePrevious(pCur, pRes);
@@ -64380,12 +64641,12 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
if( pCur->eState!=CURSOR_VALID
- || pCur->aiIdx[pCur->iPage]==0
+ || pCur->ix==0
|| pCur->apPage[pCur->iPage]->leaf==0
){
return btreePrevious(pCur, pRes);
}
- pCur->aiIdx[pCur->iPage]--;
+ pCur->ix--;
return SQLITE_OK;
}
@@ -65025,7 +65286,7 @@ static int fillInCell(
** Use a call to btreeParseCellPtr() to verify that the values above
** were computed correctly.
*/
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
{
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
@@ -66551,7 +66812,7 @@ static int balance_nonroot(
** free space needs to be up front.
*/
assert( nNew==1 || CORRUPT_DB );
- rc = defragmentPage(apNew[0]);
+ rc = defragmentPage(apNew[0], -1);
testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
(get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
@@ -66707,8 +66968,8 @@ static int balance(BtCursor *pCur){
rc = balance_deeper(pPage, &pCur->apPage[1]);
if( rc==SQLITE_OK ){
pCur->iPage = 1;
+ pCur->ix = 0;
pCur->aiIdx[0] = 0;
- pCur->aiIdx[1] = 0;
assert( pCur->apPage[1]->nOverflow );
}
}else{
@@ -66885,7 +67146,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
assert( pX->pKey==0 );
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced */
- invalidateIncrblobCursors(p, pX->nKey, 0);
+ invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
** to a row with the same key as the new entry being inserted. */
@@ -66897,9 +67158,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** btreeMoveto() call */
if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
loc = 0;
- }else if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0
- && pCur->info.nKey==pX->nKey-1 ){
- loc = -1;
}else if( loc==0 ){
rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
if( rc ) return rc;
@@ -66937,7 +67195,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( rc ) goto end_insert;
assert( szNew==pPage->xCellSize(pPage, newCell) );
assert( szNew <= MX_CELL_SIZE(pBt) );
- idx = pCur->aiIdx[pCur->iPage];
+ idx = pCur->ix;
if( loc==0 ){
CellInfo info;
assert( idx<pPage->nCell );
@@ -66950,12 +67208,18 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
memcpy(newCell, oldCell, 4);
}
rc = clearCell(pPage, oldCell, &info);
- if( info.nSize==szNew && info.nLocal==info.nPayload ){
+ if( info.nSize==szNew && info.nLocal==info.nPayload
+ && (!ISAUTOVACUUM || szNew<pPage->minLocal)
+ ){
/* Overwrite the old cell with the new if they are the same size.
** We could also try to do this if the old cell is smaller, then add
** the leftover space to the free list. But experiments show that
** doing that is no faster then skipping this optimization and just
- ** calling dropCell() and insertCell(). */
+ ** calling dropCell() and insertCell().
+ **
+ ** This optimization cannot be used on an autovacuum database if the
+ ** new entry uses overflow pages, as the insertCell() call below is
+ ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */
assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
memcpy(oldCell, newCell, szNew);
@@ -66965,7 +67229,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( rc ) goto end_insert;
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
- idx = ++pCur->aiIdx[pCur->iPage];
+ idx = ++pCur->ix;
+ pCur->curFlags &= ~BTCF_ValidNKey;
}else{
assert( pPage->leaf );
}
@@ -67061,12 +67326,12 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( pCur->curFlags & BTCF_WriteFlag );
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->eState==CURSOR_VALID );
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
iCellDepth = pCur->iPage;
- iCellIdx = pCur->aiIdx[iCellDepth];
+ iCellIdx = pCur->ix;
pPage = pCur->apPage[iCellDepth];
pCell = findCell(pPage, iCellIdx);
@@ -67115,7 +67380,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
/* If this is a delete operation to remove a row from a table b-tree,
** invalidate any incrblob cursors open on the row being deleted. */
if( pCur->pKeyInfo==0 ){
- invalidateIncrblobCursors(p, pCur->info.nKey, 0);
+ invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
}
/* Make the page containing the entry to be deleted writable. Then free any
@@ -67183,7 +67448,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
pCur->eState = CURSOR_SKIPNEXT;
if( iCellIdx>=pPage->nCell ){
pCur->skipNext = -1;
- pCur->aiIdx[iCellDepth] = pPage->nCell-1;
+ pCur->ix = pPage->nCell-1;
}else{
pCur->skipNext = 1;
}
@@ -67442,7 +67707,7 @@ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
/* Invalidate all incrblob cursors open on table iTable (assuming iTable
** is the root of a table b-tree - if it is not, the following call is
** a no-op). */
- invalidateIncrblobCursors(p, 0, 1);
+ invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
}
sqlite3BtreeLeave(p);
@@ -67696,16 +67961,16 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
return moveToRoot(pCur);
}
moveToParent(pCur);
- }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
+ }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
- pCur->aiIdx[pCur->iPage]++;
+ pCur->ix++;
pPage = pCur->apPage[pCur->iPage];
}
/* Descend to the child node of the cell that the cursor currently
** points at. This is the right-child if (iIdx==pPage->nCell).
*/
- iIdx = pCur->aiIdx[pCur->iPage];
+ iIdx = pCur->ix;
if( iIdx==pPage->nCell ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
}else{
@@ -68090,6 +68355,7 @@ static int checkTreePage(
checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
}
maxKey = info.nKey;
+ keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */
}
/* Check the content overflow list */
@@ -69475,6 +69741,10 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
/* Cannot be both MEM_Int and MEM_Real at the same time */
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+ /* Cannot be both MEM_Null and some other type */
+ assert( (p->flags & MEM_Null)==0 ||
+ (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob))==0 );
+
/* The szMalloc field holds the correct memory allocation size */
assert( p->szMalloc==0
|| p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
@@ -69560,26 +69830,24 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
- if( pMem->szMalloc<n ){
- if( n<32 ) n = 32;
- if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
- pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
- bPreserve = 0;
- }else{
- if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
- pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
- }
- if( pMem->zMalloc==0 ){
- sqlite3VdbeMemSetNull(pMem);
- pMem->z = 0;
- pMem->szMalloc = 0;
- return SQLITE_NOMEM_BKPT;
- }else{
- pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
- }
+ if( n<32 ) n = 32;
+ if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
+ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
+ bPreserve = 0;
+ }else{
+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+ pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
+ }
+ if( pMem->zMalloc==0 ){
+ sqlite3VdbeMemSetNull(pMem);
+ pMem->z = 0;
+ pMem->szMalloc = 0;
+ return SQLITE_NOMEM_BKPT;
+ }else{
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}
- if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
+ if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 ){
@@ -69776,7 +70044,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
ctx.pFunc = pFunc;
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
assert( (pMem->flags & MEM_Dyn)==0 );
- if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
rc = ctx.isError;
}
@@ -69827,7 +70095,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
vdbeMemClearExternAndSetNull(p);
}
if( p->szMalloc ){
- sqlite3DbFree(p->db, p->zMalloc);
+ sqlite3DbFreeNN(p->db, p->zMalloc);
p->szMalloc = 0;
}
p->z = 0;
@@ -69855,7 +70123,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
** If the double is out of range of a 64-bit signed integer then
** return the closest available 64-bit signed integer.
*/
-static i64 doubleToInt64(double r){
+static SQLITE_NOINLINE i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
/* When floating-point is omitted, double and int64 are the same thing */
return r;
@@ -69891,6 +70159,11 @@ static i64 doubleToInt64(double r){
**
** If pMem represents a string value, its encoding might be changed.
*/
+static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
+ i64 value = 0;
+ sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
+ return value;
+}
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
int flags;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -69901,10 +70174,8 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
}else if( flags & (MEM_Str|MEM_Blob) ){
- i64 value = 0;
assert( pMem->z || pMem->n==0 );
- sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
- return value;
+ return memIntValue(pMem);
}else{
return 0;
}
@@ -69916,6 +70187,12 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
** value. If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
+static SQLITE_NOINLINE double memRealValue(Mem *pMem){
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ double val = (double)0;
+ sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
+ return val;
+}
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -69924,10 +70201,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
}else if( pMem->flags & MEM_Int ){
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- double val = (double)0;
- sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
- return val;
+ return memRealValue(pMem);
}else{
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return (double)0;
@@ -70552,7 +70826,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
pRec->aMem[i].db = db;
}
}else{
- sqlite3DbFree(db, pRec);
+ sqlite3DbFreeNN(db, pRec);
pRec = 0;
}
}
@@ -70664,7 +70938,7 @@ static int valueFromFunction(
for(i=0; i<nVal; i++){
sqlite3ValueFree(apVal[i]);
}
- sqlite3DbFree(db, apVal);
+ sqlite3DbFreeNN(db, apVal);
}
*ppVal = pVal;
@@ -70863,7 +71137,7 @@ static void recordFunc(
putVarint32(&aRet[1], iSerial);
sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
- sqlite3DbFree(db, aRet);
+ sqlite3DbFreeNN(db, aRet);
}
}
@@ -71090,7 +71364,7 @@ SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
sqlite3VdbeMemRelease(&aMem[i]);
}
sqlite3KeyInfoUnref(pRec->pKeyInfo);
- sqlite3DbFree(db, pRec);
+ sqlite3DbFreeNN(db, pRec);
}
}
#endif /* ifdef SQLITE_ENABLE_STAT4 */
@@ -71114,7 +71388,7 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
if( !v ) return;
sqlite3VdbeMemRelease((Mem *)v);
- sqlite3DbFree(((Mem*)v)->db, v);
+ sqlite3DbFreeNN(((Mem*)v)->db, v);
}
/*
@@ -71203,6 +71477,7 @@ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
assert( isPrepareV2==1 || isPrepareV2==0 );
if( p==0 ) return;
+ if( !isPrepareV2 ) p->expmask = 0;
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
if( !isPrepareV2 ) return;
#endif
@@ -71231,6 +71506,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
pA->zSql = pB->zSql;
pB->zSql = zTmp;
pB->isPrepareV2 = pA->isPrepareV2;
+ pB->expmask = pA->expmask;
}
/*
@@ -71261,6 +71537,12 @@ static int growOpArray(Vdbe *v, int nOp){
UNUSED_PARAMETER(nOp);
#endif
+ /* Ensure that the size of a VDBE does not grow too large */
+ if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
+ sqlite3OomFault(p->db);
+ return SQLITE_NOMEM;
+ }
+
assert( nOp<=(1024/sizeof(Op)) );
assert( nNew>=(p->nOpAlloc+nOp) );
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
@@ -71949,7 +72231,7 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
*/
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
- sqlite3DbFree(db, pDef);
+ sqlite3DbFreeNN(db, pDef);
}
}
@@ -71960,11 +72242,11 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
*/
static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
freeEphemeralFunction(db, p->pFunc);
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
static void freeP4(sqlite3 *db, int p4type, void *p4){
assert( db );
@@ -72017,14 +72299,14 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
if( aOp ){
Op *pOp;
- for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
+ for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
sqlite3DbFree(db, pOp->zComment);
#endif
}
+ sqlite3DbFreeNN(db, aOp);
}
- sqlite3DbFree(db, aOp);
}
/*
@@ -72697,7 +72979,7 @@ static void releaseMemArray(Mem *p, int N){
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
}else if( p->szMalloc ){
- sqlite3DbFree(db, p->zMalloc);
+ sqlite3DbFreeNN(db, p->zMalloc);
p->szMalloc = 0;
}
@@ -73173,8 +73455,8 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
break;
}
case CURTYPE_BTREE: {
- if( pCx->pBtx ){
- sqlite3BtreeClose(pCx->pBtx);
+ if( pCx->isEphemeral ){
+ if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx);
/* The pCx->pCursor will be close automatically, if it exists, by
** the call above. */
}else{
@@ -73755,13 +74037,13 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
** one, or the complete transaction if there is no statement transaction.
*/
+ if( p->magic!=VDBE_MAGIC_RUN ){
+ return SQLITE_OK;
+ }
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM_BKPT;
}
closeAllCursors(p);
- if( p->magic!=VDBE_MAGIC_RUN ){
- return SQLITE_OK;
- }
checkActiveVdbeCnt(db);
/* No commit or rollback needed if the program never started or if the
@@ -74068,7 +74350,6 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
}
}
#endif
- p->iCurrentTime = 0;
p->magic = VDBE_MAGIC_RESET;
return p->rc & db->errMask;
}
@@ -74107,16 +74388,18 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp,
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
- || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
+ || (pAux->iAuxOp==iOp
+ && pAux->iAuxArg>=0
+ && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
){
- testcase( pAux->iArg==31 );
- if( pAux->xDelete ){
- pAux->xDelete(pAux->pAux);
+ testcase( pAux->iAuxArg==31 );
+ if( pAux->xDeleteAux ){
+ pAux->xDeleteAux(pAux->pAux);
}
- *pp = pAux->pNext;
+ *pp = pAux->pNextAux;
sqlite3DbFree(db, pAux);
}else{
- pp= &pAux->pNext;
+ pp= &pAux->pNextAux;
}
}
}
@@ -74178,7 +74461,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
}
p->magic = VDBE_MAGIC_DEAD;
p->db = 0;
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
/*
@@ -74708,7 +74991,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
p->nField = u;
}
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
@@ -74813,7 +75096,7 @@ debugCompareEnd:
}
#endif
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** Count the number of fields (a.k.a. columns) in the record given by
** pKey,nKey. The verify that this count is less than or equal to the
@@ -75696,8 +75979,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
*/
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
assert( iVar>0 );
- if( iVar>32 ){
- v->expmask = 0xffffffff;
+ if( iVar>=32 ){
+ v->expmask |= 0x80000000;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
@@ -75737,7 +76020,7 @@ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
Mem *pMem = &p->aMem[i];
if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
}
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -75804,7 +76087,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
for(i=0; i<pCsr->nField; i++){
sqlite3VdbeMemRelease(&preupdate.aNew[i]);
}
- sqlite3DbFree(db, preupdate.aNew);
+ sqlite3DbFreeNN(db, preupdate.aNew);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -75967,7 +76250,8 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
sqlite3VdbeMemRelease(&p->aVar[i]);
p->aVar[i].flags = MEM_Null;
}
- if( p->isPrepareV2 && p->expmask ){
+ assert( p->isPrepareV2 || p->expmask==0 );
+ if( p->expmask ){
p->expired = 1;
}
sqlite3_mutex_leave(mutex);
@@ -76616,6 +76900,12 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
/*
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
+**
+** The left-most argument is 0.
+**
+** Undocumented behavior: If iArg is negative then access a cache of
+** auxiliary data pointers that is available to all functions within a
+** single prepared statement. The iArg values must match.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
@@ -76626,17 +76916,24 @@ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
#else
assert( pCtx->pVdbe!=0 );
#endif
- for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
- if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
+ for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
+ if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
+ return pAuxData->pAux;
+ }
}
-
- return (pAuxData ? pAuxData->pAux : 0);
+ return 0;
}
/*
** Set the auxiliary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
+**
+** The left-most argument is 0.
+**
+** Undocumented behavior: If iArg is negative then make the data available
+** to all functions within the current prepared statement using iArg as an
+** access code.
*/
SQLITE_API void sqlite3_set_auxdata(
sqlite3_context *pCtx,
@@ -76648,33 +76945,34 @@ SQLITE_API void sqlite3_set_auxdata(
Vdbe *pVdbe = pCtx->pVdbe;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
- if( iArg<0 ) goto failed;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pVdbe==0 ) goto failed;
#else
assert( pVdbe!=0 );
#endif
- for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
- if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
+ for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
+ if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
+ break;
+ }
}
if( pAuxData==0 ){
pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
if( !pAuxData ) goto failed;
- pAuxData->iOp = pCtx->iOp;
- pAuxData->iArg = iArg;
- pAuxData->pNext = pVdbe->pAuxData;
+ pAuxData->iAuxOp = pCtx->iOp;
+ pAuxData->iAuxArg = iArg;
+ pAuxData->pNextAux = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
if( pCtx->fErrorOrAux==0 ){
pCtx->isError = 0;
pCtx->fErrorOrAux = 1;
}
- }else if( pAuxData->xDelete ){
- pAuxData->xDelete(pAuxData->pAux);
+ }else if( pAuxData->xDeleteAux ){
+ pAuxData->xDeleteAux(pAuxData->pAux);
}
pAuxData->pAux = pAux;
- pAuxData->xDelete = xDelete;
+ pAuxData->xDeleteAux = xDelete;
return;
failed:
@@ -77071,9 +77369,8 @@ static int vdbeUnbind(Vdbe *p, int i){
** as if there had been a schema change, on the first sqlite3_step() call
** following any change to the bindings of that parameter.
*/
- if( p->isPrepareV2 &&
- ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
- ){
+ assert( p->isPrepareV2 || p->expmask==0 );
+ if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
p->expired = 1;
}
return SQLITE_OK;
@@ -77336,10 +77633,12 @@ SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
- if( pTo->isPrepareV2 && pTo->expmask ){
+ assert( pTo->isPrepareV2 || pTo->expmask==0 );
+ if( pTo->expmask ){
pTo->expired = 1;
}
- if( pFrom->isPrepareV2 && pFrom->expmask ){
+ assert( pFrom->isPrepareV2 || pFrom->expmask==0 );
+ if( pFrom->expmask ){
pFrom->expired = 1;
}
return sqlite3TransferBindings(pFromStmt, pToStmt);
@@ -78305,9 +78604,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
}else{
c = 's';
}
-
- sqlite3_snprintf(100, zCsr, "%c", c);
- zCsr += sqlite3Strlen30(zCsr);
+ *(zCsr++) = c;
sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
zCsr += sqlite3Strlen30(zCsr);
for(i=0; i<16 && i<pMem->n; i++){
@@ -78319,9 +78616,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
if( z<32 || z>126 ) *zCsr++ = '.';
else *zCsr++ = z;
}
-
- sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);
- zCsr += sqlite3Strlen30(zCsr);
+ *(zCsr++) = ']';
if( f & MEM_Zero ){
sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
zCsr += sqlite3Strlen30(zCsr);
@@ -78392,6 +78687,7 @@ static void registerTrace(int iReg, Mem *p){
printf("REG[%d] = ", iReg);
memTracePrint(p);
printf("\n");
+ sqlite3VdbeCheckMemInvariants(p);
}
#endif
@@ -78758,7 +79054,7 @@ jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
- ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
+ ** OP_VNext, or OP_SorterNext) all jump here upon
** completion. Check to see if sqlite3_interrupt() has been called
** or if the progress callback needs to be invoked.
**
@@ -79146,7 +79442,7 @@ case OP_Null: { /* out2 */
case OP_SoftNull: {
assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
pOut = &aMem[pOp->p1];
- pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined;
+ pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null;
break;
}
@@ -79489,7 +79785,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
type2 = numericType(pIn2);
pOut = &aMem[pOp->p3];
flags = pIn1->flags | pIn2->flags;
- if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (type1 & type2 & MEM_Int)!=0 ){
iA = pIn1->u.i;
iB = pIn2->u.i;
@@ -79513,6 +79808,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
}
pOut->u.i = iB;
MemSetTypeFlag(pOut, MEM_Int);
+ }else if( (flags & MEM_Null)!=0 ){
+ goto arithmetic_result_is_null;
}else{
bIntint = 0;
fp_math:
@@ -79560,7 +79857,7 @@ arithmetic_result_is_null:
/* Opcode: CollSeq P1 * * P4
**
-** P4 is a pointer to a CollSeq struct. If the next call to a user function
+** P4 is a pointer to a CollSeq object. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
@@ -79660,21 +79957,21 @@ case OP_Function: {
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
- memAboutToChange(p, pCtx->pOut);
+ memAboutToChange(p, pOut);
#ifdef SQLITE_DEBUG
for(i=0; i<pCtx->argc; i++){
assert( memIsValid(pCtx->argv[i]) );
REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
}
#endif
- MemSetTypeFlag(pCtx->pOut, MEM_Null);
+ MemSetTypeFlag(pOut, MEM_Null);
pCtx->fErrorOrAux = 0;
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
if( pCtx->fErrorOrAux ){
if( pCtx->isError ){
- sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
rc = pCtx->isError;
}
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
@@ -79683,12 +79980,12 @@ case OP_Function: {
/* Copy the result of the function into register P3 */
if( pOut->flags & (MEM_Str|MEM_Blob) ){
- sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
- if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
+ sqlite3VdbeChangeEncoding(pOut, encoding);
+ if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
}
- REGISTER_TRACE(pOp->p3, pCtx->pOut);
- UPDATE_MAX_BLOBSIZE(pCtx->pOut);
+ REGISTER_TRACE(pOp->p3, pOut);
+ UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -79841,11 +80138,11 @@ case OP_RealAffinity: { /* in1 */
** Force the value in register P1 to be the type defined by P2.
**
** <ul>
-** <li value="97"> TEXT
-** <li value="98"> BLOB
-** <li value="99"> NUMERIC
-** <li value="100"> INTEGER
-** <li value="101"> REAL
+** <li> P2=='A' &rarr; BLOB
+** <li> P2=='B' &rarr; TEXT
+** <li> P2=='C' &rarr; NUMERIC
+** <li> P2=='D' &rarr; INTEGER
+** <li> P2=='E' &rarr; REAL
** </ul>
**
** A NULL value is not changed by this routine. It remains NULL.
@@ -80189,7 +80486,7 @@ case OP_Compare: {
assert( pKeyInfo!=0 );
p1 = pOp->p1;
p2 = pOp->p2;
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
@@ -80327,19 +80624,39 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
/* Opcode: Once P1 P2 * * *
**
-** If the P1 value is equal to the P1 value on the OP_Init opcode at
-** instruction 0, then jump to P2. If the two P1 values differ, then
-** set the P1 value on this opcode to equal the P1 value on the OP_Init
-** and fall through.
+** Fall through to the next instruction the first time this opcode is
+** encountered on each invocation of the byte-code program. Jump to P2
+** on the second and all subsequent encounters during the same invocation.
+**
+** Top-level programs determine first invocation by comparing the P1
+** operand against the P1 operand on the OP_Init opcode at the beginning
+** of the program. If the P1 values differ, then fall through and make
+** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are
+** the same then take the jump.
+**
+** For subprograms, there is a bitmask in the VdbeFrame that determines
+** whether or not the jump should be taken. The bitmask is necessary
+** because the self-altering code trick does not work for recursive
+** triggers.
*/
case OP_Once: { /* jump */
+ u32 iAddr; /* Address of this instruction */
assert( p->aOp[0].opcode==OP_Init );
- VdbeBranchTaken(p->aOp[0].p1==pOp->p1, 2);
- if( p->aOp[0].p1==pOp->p1 ){
- goto jump_to_p2;
+ if( p->pFrame ){
+ iAddr = (int)(pOp - p->aOp);
+ if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){
+ VdbeBranchTaken(1, 2);
+ goto jump_to_p2;
+ }
+ p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7);
}else{
- pOp->p1 = p->aOp[0].p1;
+ if( p->aOp[0].p1==pOp->p1 ){
+ VdbeBranchTaken(1, 2);
+ goto jump_to_p2;
+ }
}
+ VdbeBranchTaken(0, 2);
+ pOp->p1 = p->aOp[0].p1;
break;
}
@@ -80404,6 +80721,24 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
break;
}
+/* Opcode: IfNullRow P1 P2 P3 * *
+** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2
+**
+** Check the cursor P1 to see if it is currently pointing at a NULL row.
+** If it is, then set register P3 to NULL and jump immediately to P2.
+** If P1 is not on a NULL row, then fall through without making any
+** changes.
+*/
+case OP_IfNullRow: { /* jump */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ assert( p->apCsr[pOp->p1]!=0 );
+ if( p->apCsr[pOp->p1]->nullRow ){
+ sqlite3VdbeMemSetNull(aMem + pOp->p3);
+ goto jump_to_p2;
+ }
+ break;
+}
+
/* Opcode: Column P1 P2 P3 P4 P5
** Synopsis: r[P3]=PX
**
@@ -80415,7 +80750,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
**
** The value extracted is stored in register P3.
**
-** If the column contains fewer than P2 fields, then extract a NULL. Or,
+** If the record contains fewer than P2 fields, then extract a NULL. Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
@@ -80424,7 +80759,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
**
-** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
+** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively. The loading of large blobs can be
** skipped for length() and all content loading can be skipped for typeof().
@@ -80652,8 +80987,13 @@ case OP_Column: {
** 2. the length(X) function if X is a blob, and
** 3. if the content length is zero.
** So we might as well use bogus content rather than reading
- ** content from disk. */
- static u8 aZero[8]; /* This is the bogus content */
+ ** content from disk.
+ **
+ ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the
+ ** buffer passed to it, debugging function VdbeMemPrettyPrint() may
+ ** read up to 16. So 16 bytes of bogus content is supplied.
+ */
+ static u8 aZero[16]; /* This is the bogus content */
sqlite3VdbeSerialGet(aZero, t, pDest);
}else{
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
@@ -80674,24 +81014,24 @@ op_column_out:
**
** Apply affinities to a range of P2 registers starting with P1.
**
-** P4 is a string that is P2 characters long. The nth character of the
-** string indicates the column affinity that should be used for the nth
+** P4 is a string that is P2 characters long. The N-th character of the
+** string indicates the column affinity that should be used for the N-th
** memory cell in the range.
*/
case OP_Affinity: {
const char *zAffinity; /* The affinity to be applied */
- char cAff; /* A single character of affinity */
zAffinity = pOp->p4.z;
assert( zAffinity!=0 );
+ assert( pOp->p2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- while( (cAff = *(zAffinity++))!=0 ){
+ do{
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
- applyAffinity(pIn1, cAff, encoding);
+ applyAffinity(pIn1, *(zAffinity++), encoding);
pIn1++;
- }
+ }while( zAffinity[0] );
break;
}
@@ -80702,8 +81042,8 @@ case OP_Affinity: {
** use as a data record in a database table or as a key
** in an index. The OP_Column opcode can decode the record later.
**
-** P4 may be a string that is P2 characters long. The nth character of the
-** string indicates the column affinity that should be used for the nth
+** P4 may be a string that is P2 characters long. The N-th character of the
+** string indicates the column affinity that should be used for the N-th
** field of the index key.
**
** The mapping from character to affinity is given by the SQLITE_AFF_
@@ -80862,7 +81202,6 @@ case OP_MakeRecord: {
pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
break;
@@ -81492,6 +81831,37 @@ open_cursor_set_hints:
break;
}
+/* Opcode: OpenDup P1 P2 * * *
+**
+** Open a new cursor P1 that points to the same ephemeral table as
+** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral
+** opcode. Only ephemeral cursors may be duplicated.
+**
+** Duplicate ephemeral cursors are used for self-joins of materialized views.
+*/
+case OP_OpenDup: {
+ VdbeCursor *pOrig; /* The original cursor to be duplicated */
+ VdbeCursor *pCx; /* The new cursor */
+
+ pOrig = p->apCsr[pOp->p2];
+ assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */
+
+ pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->isEphemeral = 1;
+ pCx->pKeyInfo = pOrig->pKeyInfo;
+ pCx->isTable = pOrig->isTable;
+ rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
+ pCx->pKeyInfo, pCx->uc.pCursor);
+ /* The sqlite3BtreeCursor() routine can only fail for the first cursor
+ ** opened for a database. Since there is already an open cursor when this
+ ** opcode is run, the sqlite3BtreeCursor() cannot fail */
+ assert( rc==SQLITE_OK );
+ break;
+}
+
+
/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
@@ -82027,10 +82397,12 @@ case OP_Found: { /* jump, in3 */
pIdxKey = &r;
pFree = 0;
}else{
+ assert( pIn3->flags & MEM_Blob );
+ rc = ExpandBlob(pIn3);
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+ if( rc ) goto no_mem;
pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
if( pIdxKey==0 ) goto no_mem;
- assert( pIn3->flags & MEM_Blob );
- (void)ExpandBlob(pIn3);
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
@@ -82047,7 +82419,7 @@ case OP_Found: { /* jump, in3 */
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
- if( pFree ) sqlite3DbFree(db, pFree);
+ if( pFree ) sqlite3DbFreeNN(db, pFree);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
@@ -82838,6 +83210,33 @@ case OP_Last: { /* jump */
break;
}
+/* Opcode: IfSmaller P1 P2 P3 * *
+**
+** Estimate the number of rows in the table P1. Jump to P2 if that
+** estimate is less than approximately 2**(0.1*P3).
+*/
+case OP_IfSmaller: { /* jump */
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ i64 sz;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr );
+ rc = sqlite3BtreeFirst(pCrsr, &res);
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
+ sz = sqlite3BtreeRowCountEst(pCrsr);
+ if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
+ }
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
+ break;
+}
+
/* Opcode: SorterSort P1 P2 * * *
**
@@ -83330,10 +83729,17 @@ case OP_IdxGE: { /* jump */
** might be moved into the newly deleted root page in order to keep all
** root pages contiguous at the beginning of the database. The former
** value of the root page that moved - its value before the move occurred -
-** is stored in register P2. If no page
-** movement was required (because the table being dropped was already
-** the last one in the database) then a zero is stored in register P2.
-** If AUTOVACUUM is disabled then a zero is stored in register P2.
+** is stored in register P2. If no page movement was required (because the
+** table being dropped was already the last one in the database) then a
+** zero is stored in register P2. If AUTOVACUUM is disabled then a zero
+** is stored in register P2.
+**
+** This opcode throws an error if there are any active reader VMs when
+** it is invoked. This is done to avoid the difficulty associated with
+** updating existing cursors when a root page is moved in an AUTOVACUUM
+** database. This error is thrown even if the database is not an AUTOVACUUM
+** db in order to avoid introducing an incompatibility between autovacuum
+** and non-autovacuum modes.
**
** See also: Clear
*/
@@ -83482,6 +83888,18 @@ case OP_CreateTable: { /* out2 */
break;
}
+/* Opcode: SqlExec * * * P4 *
+**
+** Run the SQL statement or statements specified in the P4 string.
+*/
+case OP_SqlExec: {
+ db->nSqlExec++;
+ rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
+ db->nSqlExec--;
+ if( rc ) goto abort_due_to_error;
+ break;
+}
+
/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
@@ -83526,7 +83944,7 @@ case OP_ParseSchema: {
assert( !db->mallocFailed );
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
if( rc==SQLITE_OK ) rc = initData.rc;
- sqlite3DbFree(db, zSql);
+ sqlite3DbFreeNN(db, zSql);
db->init.busy = 0;
}
}
@@ -83602,7 +84020,7 @@ case OP_DropTrigger: {
** register P1 the text of an error message describing any problems.
** If no problems are found, store a NULL in register P1.
**
-** The register P3 contains the maximum number of allowed errors.
+** The register P3 contains one less than the maximum number of allowed errors.
** At most reg(P3) errors will be reported.
** In other words, the analysis stops as soon as reg(P1) errors are
** seen. Reg(P1) is updated with the number of errors remaining.
@@ -83635,14 +84053,14 @@ case OP_IntegrityCk: {
assert( pOp->p5<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
- (int)pnErr->u.i, &nErr);
- pnErr->u.i -= nErr;
+ (int)pnErr->u.i+1, &nErr);
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
assert( z==0 );
}else if( z==0 ){
goto no_mem;
}else{
+ pnErr->u.i -= nErr-1;
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
@@ -83654,7 +84072,7 @@ case OP_IntegrityCk: {
/* Opcode: RowSetAdd P1 P2 * * *
** Synopsis: rowset(P1)=r[P2]
**
-** Insert the integer value held by register P2 into a boolean index
+** Insert the integer value held by register P2 into a RowSet object
** held in register P1.
**
** An assertion fails if P2 is not an integer.
@@ -83674,8 +84092,9 @@ case OP_RowSetAdd: { /* in1, in2 */
/* Opcode: RowSetRead P1 P2 P3 * *
** Synopsis: r[P3]=rowset(P1)
**
-** Extract the smallest value from boolean index P1 and put that value into
-** register P3. Or, if boolean index P1 is initially empty, leave P3
+** Extract the smallest value from the RowSet object in P1
+** and put that value into register P3.
+** Or, if RowSet object P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: { /* jump, in1, out3 */
@@ -83706,15 +84125,14 @@ case OP_RowSetRead: { /* jump, in1, out3 */
** integer in P3 into the RowSet and continue on to the
** next opcode.
**
-** The RowSet object is optimized for the case where successive sets
-** of integers, where each set contains no duplicates. Each set
-** of values is identified by a unique P4 value. The first set
-** must have P4==0, the final set P4=-1. P4 must be either -1 or
-** non-negative. For non-negative values of P4 only the lower 4
-** bits are significant.
+** The RowSet object is optimized for the case where sets of integers
+** are inserted in distinct phases, which each set contains no duplicates.
+** Each set is identified by a unique P4 value. The first set
+** must have P4==0, the final set must have P4==-1, and for all other sets
+** must have P4>0.
**
** This allows optimizations: (a) when P4==0 there is no need to test
-** the rowset object for P3, as it is guaranteed not to contain it,
+** the RowSet object for P3, as it is guaranteed not to contain it,
** (b) when P4==-1 there is no need to insert the value, as it will
** never be tested for, and (c) when a value that is part of set X is
** inserted, there is no need to search to see if the same value was
@@ -83821,7 +84239,8 @@ case OP_Program: { /* jump */
if( pProgram->nCsr==0 ) nMem++;
nByte = ROUND8(sizeof(VdbeFrame))
+ nMem * sizeof(Mem)
- + pProgram->nCsr * sizeof(VdbeCursor *);
+ + pProgram->nCsr * sizeof(VdbeCursor*)
+ + (pProgram->nOp + 7)/8;
pFrame = sqlite3DbMallocZero(db, nByte);
if( !pFrame ){
goto no_mem;
@@ -83872,6 +84291,8 @@ case OP_Program: { /* jump */
p->nMem = pFrame->nChildMem;
p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem];
+ pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr];
+ memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8);
p->aOp = aOp = pProgram->aOp;
p->nOp = pProgram->nOp;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -84901,7 +85322,11 @@ case OP_Init: { /* jump */
sqlite3_free(z);
}else
#endif
- {
+ if( db->nVdbeExec>1 ){
+ char *z = sqlite3MPrintf(db, "-- %s", zTrace);
+ (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, z);
+ sqlite3DbFree(db, z);
+ }else{
(void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
}
}
@@ -86447,37 +86872,36 @@ static int vdbeSorterCompareInt(
assert( (s1>0 && s1<7) || s1==8 || s1==9 );
assert( (s2>0 && s2<7) || s2==8 || s2==9 );
- if( s1>7 && s2>7 ){
- res = s1 - s2;
- }else{
- if( s1==s2 ){
- if( (*v1 ^ *v2) & 0x80 ){
- /* The two values have different signs */
- res = (*v1 & 0x80) ? -1 : +1;
- }else{
- /* The two values have the same sign. Compare using memcmp(). */
- static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
- int i;
- res = 0;
- for(i=0; i<aLen[s1]; i++){
- if( (res = v1[i] - v2[i]) ) break;
+ if( s1==s2 ){
+ /* The two values have the same sign. Compare using memcmp(). */
+ static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 };
+ const u8 n = aLen[s1];
+ int i;
+ res = 0;
+ for(i=0; i<n; i++){
+ if( (res = v1[i] - v2[i])!=0 ){
+ if( ((v1[0] ^ v2[0]) & 0x80)!=0 ){
+ res = v1[0] & 0x80 ? -1 : +1;
}
+ break;
}
+ }
+ }else if( s1>7 && s2>7 ){
+ res = s1 - s2;
+ }else{
+ if( s2>7 ){
+ res = +1;
+ }else if( s1>7 ){
+ res = -1;
}else{
- if( s2>7 ){
- res = +1;
- }else if( s1>7 ){
- res = -1;
- }else{
- res = s1 - s2;
- }
- assert( res!=0 );
+ res = s1 - s2;
+ }
+ assert( res!=0 );
- if( res>0 ){
- if( *v1 & 0x80 ) res = -1;
- }else{
- if( *v2 & 0x80 ) res = +1;
- }
+ if( res>0 ){
+ if( *v1 & 0x80 ) res = -1;
+ }else{
+ if( *v2 & 0x80 ) res = +1;
}
}
@@ -88789,11 +89213,11 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
**
** WRC_Continue Continue descending down the tree.
**
-** WRC_Prune Do not descend into child nodes. But allow
+** WRC_Prune Do not descend into child nodes, but allow
** the walk to continue with sibling nodes.
**
** WRC_Abort Do no more callbacks. Unwind the stack and
-** return the top-level walk call.
+** return from the top-level walk call.
**
** The return value from this routine is WRC_Abort to abandon the tree walk
** and WRC_Continue to continue.
@@ -89155,7 +89579,8 @@ static int lookupName(
}
/* Start at the inner-most context and move outward until a match is found */
- while( pNC && cnt==0 ){
+ assert( pNC && cnt==0 );
+ do{
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
@@ -89340,11 +89765,11 @@ static int lookupName(
/* Advance to the next name context. The loop will exit when either
** we have a match (cnt>0) or when we run out of name contexts.
*/
- if( cnt==0 ){
- pNC = pNC->pNext;
- nSubquery++;
- }
- }
+ if( cnt ) break;
+ pNC = pNC->pNext;
+ nSubquery++;
+ }while( pNC );
+
/*
** If X and Y are NULL (in other words if only the column name Z is
@@ -89534,33 +89959,38 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
&& !defined(SQLITE_OMIT_SUBQUERY) */
- /* A lone identifier is the name of a column.
- */
- case TK_ID: {
- return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
- }
-
- /* A table name and column name: ID.ID
+ /* A column name: ID
+ ** Or table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
+ **
+ ** The TK_ID and TK_OUT cases are combined so that there will only
+ ** be one call to lookupName(). Then the compiler will in-line
+ ** lookupName() for a size reduction and performance increase.
*/
+ case TK_ID:
case TK_DOT: {
const char *zColumn;
const char *zTable;
const char *zDb;
Expr *pRight;
- /* if( pSrcList==0 ) break; */
- notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
- pRight = pExpr->pRight;
- if( pRight->op==TK_ID ){
+ if( pExpr->op==TK_ID ){
zDb = 0;
- zTable = pExpr->pLeft->u.zToken;
- zColumn = pRight->u.zToken;
+ zTable = 0;
+ zColumn = pExpr->u.zToken;
}else{
- assert( pRight->op==TK_DOT );
- zDb = pExpr->pLeft->u.zToken;
- zTable = pRight->pLeft->u.zToken;
- zColumn = pRight->pRight->u.zToken;
+ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
+ pRight = pExpr->pRight;
+ if( pRight->op==TK_ID ){
+ zDb = 0;
+ zTable = pExpr->pLeft->u.zToken;
+ zColumn = pRight->u.zToken;
+ }else{
+ assert( pRight->op==TK_DOT );
+ zDb = pExpr->pLeft->u.zToken;
+ zTable = pRight->pLeft->u.zToken;
+ zColumn = pRight->pRight->u.zToken;
+ }
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
}
@@ -90526,7 +90956,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
- if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
}
if( op==TK_SELECT_COLUMN ){
@@ -90820,7 +91250,6 @@ SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){
}
}
-#ifndef SQLITE_OMIT_SUBQUERY
/*
** Return a pointer to a subexpression of pVector that is the i-th
** column of the vector (numbered starting with 0). The caller must
@@ -90848,9 +91277,7 @@ SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
}
return pVector;
}
-#endif /* !defined(SQLITE_OMIT_SUBQUERY) */
-#ifndef SQLITE_OMIT_SUBQUERY
/*
** Compute and return a new Expr object which when passed to
** sqlite3ExprCode() will generate all necessary code to compute
@@ -90908,7 +91335,6 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
}
return pRet;
}
-#endif /* !define(SQLITE_OMIT_SUBQUERY) */
/*
** If expression pExpr is of type TK_SELECT, generate code to evaluate
@@ -91424,7 +91850,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
- assert( n==sqlite3Strlen30(z) );
+ assert( n==(u32)sqlite3Strlen30(z) );
if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
assert( z[0]=='?' );
@@ -91506,7 +91932,7 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
}
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -91773,15 +92199,11 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
Expr *pPriorSelectCol = 0;
assert( db!=0 );
if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+ pNew = sqlite3DbMallocRawNN(db,
+ sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
if( pNew==0 ) return 0;
- pNew->nExpr = i = p->nExpr;
- if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
- pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) );
- if( pItem==0 ){
- sqlite3DbFree(db, pNew);
- return 0;
- }
+ pNew->nAlloc = pNew->nExpr = p->nExpr;
+ pItem = pNew->a;
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
@@ -91872,7 +92294,7 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
pNew->nId = p->nId;
pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
if( pNew->a==0 ){
- sqlite3DbFree(db, pNew);
+ sqlite3DbFreeNN(db, pNew);
return 0;
}
/* Note that because the size of the allocation for p->a[] is not
@@ -91943,6 +92365,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
ExprList *pList, /* List to which to append. Might be NULL */
Expr *pExpr /* Expression to be appended. Might be NULL */
){
+ struct ExprList_item *pItem;
sqlite3 *db = pParse->db;
assert( db!=0 );
if( pList==0 ){
@@ -91951,23 +92374,20 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
goto no_mem;
}
pList->nExpr = 0;
- pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0]));
- if( pList->a==0 ) goto no_mem;
- }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
- struct ExprList_item *a;
- assert( pList->nExpr>0 );
- a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
- if( a==0 ){
+ pList->nAlloc = 1;
+ }else if( pList->nExpr==pList->nAlloc ){
+ ExprList *pNew;
+ pNew = sqlite3DbRealloc(db, pList,
+ sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
+ if( pNew==0 ){
goto no_mem;
}
- pList->a = a;
- }
- assert( pList->a!=0 );
- if( 1 ){
- struct ExprList_item *pItem = &pList->a[pList->nExpr++];
- memset(pItem, 0, sizeof(*pItem));
- pItem->pExpr = pExpr;
+ pList = pNew;
+ pList->nAlloc *= 2;
}
+ pItem = &pList->a[pList->nExpr++];
+ memset(pItem, 0, sizeof(*pItem));
+ pItem->pExpr = pExpr;
return pList;
no_mem:
@@ -92024,20 +92444,19 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
}
}
- if( pExpr->op==TK_SELECT ){
- if( pList && pList->a[iFirst].pExpr ){
- Expr *pFirst = pList->a[iFirst].pExpr;
- assert( pFirst->op==TK_SELECT_COLUMN );
+ if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
+ Expr *pFirst = pList->a[iFirst].pExpr;
+ assert( pFirst!=0 );
+ assert( pFirst->op==TK_SELECT_COLUMN );
- /* Store the SELECT statement in pRight so it will be deleted when
- ** sqlite3ExprListDelete() is called */
- pFirst->pRight = pExpr;
- pExpr = 0;
+ /* Store the SELECT statement in pRight so it will be deleted when
+ ** sqlite3ExprListDelete() is called */
+ pFirst->pRight = pExpr;
+ pExpr = 0;
- /* Remember the size of the LHS in iTable so that we can check that
- ** the RHS and LHS sizes match during code generation. */
- pFirst->iTable = pColumns->nId;
- }
+ /* Remember the size of the LHS in iTable so that we can check that
+ ** the RHS and LHS sizes match during code generation. */
+ pFirst->iTable = pColumns->nId;
}
vector_append_error:
@@ -92131,16 +92550,16 @@ SQLITE_PRIVATE void sqlite3ExprListCheckLength(
** Delete an entire expression list.
*/
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
- int i;
- struct ExprList_item *pItem;
- assert( pList->a!=0 || pList->nExpr==0 );
- for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
+ int i = pList->nExpr;
+ struct ExprList_item *pItem = pList->a;
+ assert( pList->nExpr>0 );
+ do{
sqlite3ExprDelete(db, pItem->pExpr);
sqlite3DbFree(db, pItem->zName);
sqlite3DbFree(db, pItem->zSpan);
- }
- sqlite3DbFree(db, pList->a);
- sqlite3DbFree(db, pList);
+ pItem++;
+ }while( --i>0 );
+ sqlite3DbFreeNN(db, pList);
}
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
if( pList ) exprListDeleteNN(db, pList);
@@ -92219,10 +92638,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_AGG_COLUMN );
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
return WRC_Continue;
- }else{
- pWalker->eCode = 0;
- return WRC_Abort;
}
+ /* Fall through */
+ case TK_IF_NULL_ROW:
+ testcase( pExpr->op==TK_IF_NULL_ROW );
+ pWalker->eCode = 0;
+ return WRC_Abort;
case TK_VARIABLE:
if( pWalker->eCode==5 ){
/* Silently convert bound parameters that appear inside of CREATE
@@ -92290,6 +92711,65 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
return exprIsConst(p, 3, iCur);
}
+
+/*
+** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
+*/
+static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
+ ExprList *pGroupBy = pWalker->u.pGroupBy;
+ int i;
+
+ /* Check if pExpr is identical to any GROUP BY term. If so, consider
+ ** it constant. */
+ for(i=0; i<pGroupBy->nExpr; i++){
+ Expr *p = pGroupBy->a[i].pExpr;
+ if( sqlite3ExprCompare(pExpr, p, -1)<2 ){
+ CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
+ if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
+ return WRC_Prune;
+ }
+ }
+ }
+
+ /* Check if pExpr is a sub-select. If so, consider it variable. */
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+
+ return exprNodeIsConstant(pWalker, pExpr);
+}
+
+/*
+** Walk the expression tree passed as the first argument. Return non-zero
+** if the expression consists entirely of constants or copies of terms
+** in pGroupBy that sort with the BINARY collation sequence.
+**
+** This routine is used to determine if a term of the HAVING clause can
+** be promoted into the WHERE clause. In order for such a promotion to work,
+** the value of the HAVING clause term must be the same for all members of
+** a "group". The requirement that the GROUP BY term must be BINARY
+** assumes that no other collating sequence will have a finer-grained
+** grouping than binary. In other words (A=B COLLATE binary) implies
+** A=B in every other collating sequence. The requirement that the
+** GROUP BY be BINARY is stricter than necessary. It would also work
+** to promote HAVING clauses that use the same alternative collating
+** sequence as the GROUP BY term, but that is much harder to check,
+** alternative collating sequences are uncommon, and this is only an
+** optimization, so we take the easy way out and simply require the
+** GROUP BY to use the BINARY collating sequence.
+*/
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.eCode = 1;
+ w.xExprCallback = exprNodeIsConstantOrGroupBy;
+ w.u.pGroupBy = pGroupBy;
+ w.pParse = pParse;
+ sqlite3WalkExpr(&w, p);
+ return w.eCode;
+}
+
/*
** Walk an expression tree. Return non-zero if the expression is constant
** or a function call with constant arguments. Return and 0 if there
@@ -92328,6 +92808,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
*/
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
+ if( p==0 ) return 0; /* Can only happen following on OOM */
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
@@ -92835,7 +93316,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
char *zRet;
assert( pExpr->op==TK_IN );
- zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
+ zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
if( zRet ){
int i;
for(i=0; i<nVal; i++){
@@ -93000,7 +93481,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
int i;
sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
dest.zAffSdst = exprINAffinity(pParse, pExpr);
- assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
pSelect->iLimit = 0;
testcase( pSelect->selFlags & SF_Distinct );
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
@@ -93667,6 +94147,10 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
int iCol, /* Index of the column to extract */
int regOut /* Extract the value into this register */
){
+ if( pTab==0 ){
+ sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
+ return;
+ }
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
@@ -93740,7 +94224,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
int i;
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("CLEAR\n");
}
@@ -93823,7 +94307,11 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
}else{
*piFreeable = 0;
if( p->op==TK_SELECT ){
+#if SQLITE_OMIT_SUBQUERY
+ iResult = 0;
+#else
iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
+#endif
}else{
int i;
iResult = pParse->nMem+1;
@@ -94360,6 +94848,17 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
break;
}
+ case TK_IF_NULL_ROW: {
+ int addrINR;
+ addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
+ sqlite3ExprCachePush(pParse);
+ inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+ sqlite3ExprCachePop(pParse);
+ sqlite3VdbeJumpHere(v, addrINR);
+ sqlite3VdbeChangeP3(v, addrINR, inReg);
+ break;
+ }
+
/*
** Form A:
** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
@@ -95149,6 +95648,17 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
}
/*
+** Like sqlite3ExprCompare() except COLLATE operators at the top-level
+** are ignored.
+*/
+SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
+ return sqlite3ExprCompare(
+ sqlite3ExprSkipCollate(pA),
+ sqlite3ExprSkipCollate(pB),
+ iTab);
+}
+
+/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
** be false. Examples:
@@ -96700,6 +97210,7 @@ struct Stat4Accum {
Stat4Sample *aBest; /* Array of nCol best samples */
int iMin; /* Index in a[] of entry with minimum score */
int nSample; /* Current number of samples */
+ int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
int iGet; /* Index of current sample accessed by stat_get() */
Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
sqlite3 *db; /* Database connection, for malloc() */
@@ -96964,6 +97475,13 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
assert( IsStat4 || nEqZero==0 );
#ifdef SQLITE_ENABLE_STAT4
+ /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
+ ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
+ ** other words, if nMaxEqZero is n, then it is guaranteed that there
+ ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
+ if( nEqZero>p->nMaxEqZero ){
+ p->nMaxEqZero = nEqZero;
+ }
if( pNew->isPSample==0 ){
Stat4Sample *pUpgrade = 0;
assert( pNew->anEq[pNew->iCol]>0 );
@@ -97061,12 +97579,22 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
}
}
- /* Update the anEq[] fields of any samples already collected. */
+ /* Check that no sample contains an anEq[] entry with an index of
+ ** p->nMaxEqZero or greater set to zero. */
for(i=p->nSample-1; i>=0; i--){
int j;
- for(j=iChng; j<p->nCol; j++){
- if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
+ }
+
+ /* Update the anEq[] fields of any samples already collected. */
+ if( iChng<p->nMaxEqZero ){
+ for(i=p->nSample-1; i>=0; i--){
+ int j;
+ for(j=iChng; j<p->nCol; j++){
+ if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ }
}
+ p->nMaxEqZero = iChng;
}
#endif
@@ -97596,7 +98124,7 @@ static void analyzeOneTable(
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; j<pPk->nKeyCol; j++){
k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
- assert( k>=0 && k<pTab->nCol );
+ assert( k>=0 && k<pIdx->nColumn );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
}
@@ -97780,27 +98308,14 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
if( i==1 ) continue; /* Do not analyze the TEMP database */
analyzeDatabase(pParse, i);
}
- }else if( pName2->n==0 ){
- /* Form 2: Analyze the database or table named */
- iDb = sqlite3FindDb(db, pName1);
- if( iDb>=0 ){
- analyzeDatabase(pParse, iDb);
- }else{
- z = sqlite3NameFromToken(db, pName1);
- if( z ){
- if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
- analyzeTable(pParse, pIdx->pTable, pIdx);
- }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
- analyzeTable(pParse, pTab, 0);
- }
- sqlite3DbFree(db, z);
- }
- }
+ }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
+ /* Analyze the schema named as the argument */
+ analyzeDatabase(pParse, iDb);
}else{
- /* Form 3: Analyze the fully qualified table name */
+ /* Form 3: Analyze the table or index named as an argument */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
- zDb = db->aDb[iDb].zDbSName;
+ zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
z = sqlite3NameFromToken(db, pTableName);
if( z ){
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
@@ -97810,10 +98325,11 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
}
sqlite3DbFree(db, z);
}
- }
+ }
+ }
+ if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
+ sqlite3VdbeAddOp0(v, OP_Expire);
}
- v = sqlite3GetVdbe(pParse);
- if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
}
/*
@@ -97942,7 +98458,11 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
- if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
+ pIndex->hasStat1 = 1;
+ if( pIndex->pPartIdxWhere==0 ){
+ pTable->nRowLogEst = pIndex->aiRowLogEst[0];
+ pTable->tabFlags |= TF_HasStat1;
+ }
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
@@ -97951,6 +98471,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow;
+ pTable->tabFlags |= TF_HasStat1;
}
return 0;
@@ -98245,15 +98766,20 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
HashElem *i;
char *zSql;
int rc = SQLITE_OK;
+ Schema *pSchema = db->aDb[iDb].pSchema;
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 );
/* Clear any prior statistics */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ pTab->tabFlags &= ~TF_HasStat1;
+ }
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
- pIdx->aiRowLogEst[0] = 0;
+ pIdx->hasStat1 = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
@@ -98276,9 +98802,9 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
- if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
+ if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
}
/* Load the statistics from the sqlite_stat4 table. */
@@ -98288,7 +98814,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
rc = loadStat4(db, sInfo.zDatabase);
db->lookaside.bDisable--;
}
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3_free(pIdx->aiRowEst);
pIdx->aiRowEst = 0;
@@ -99110,6 +99636,18 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
if( db->xAuth==0 ){
return SQLITE_OK;
}
+
+ /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
+ ** callback are either NULL pointers or zero-terminated strings that
+ ** contain additional details about the action to be authorized.
+ **
+ ** The following testcase() macros show that any of the 3rd through 6th
+ ** parameters can be either NULL or a string. */
+ testcase( zArg1==0 );
+ testcase( zArg2==0 );
+ testcase( zArg3==0 );
+ testcase( pParse->zAuthContext==0 );
+
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
,db->auth.zAuthUser
@@ -100273,6 +100811,7 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
p->aCol[p->nCol-1].notNull = (u8)onError;
+ p->tabFlags |= TF_HasNotNull;
}
/*
@@ -102612,6 +103151,9 @@ SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
int i;
+ /* Indexes with default row estimates should not have stat1 data */
+ assert( !pIdx->hasStat1 );
+
/* Set the first entry (number of rows in the index) to the estimated
** number of rows in the table, or half the number of rows in the table
** for a partial index. But do not let the estimate drop below 10. */
@@ -102777,7 +103319,7 @@ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
sqlite3DbFree(db, pList->a[i].zName);
}
sqlite3DbFree(db, pList->a);
- sqlite3DbFree(db, pList);
+ sqlite3DbFreeNN(db, pList);
}
/*
@@ -102967,7 +103509,7 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
sqlite3ExprDelete(db, pItem->pOn);
sqlite3IdListDelete(db, pItem->pUsing);
}
- sqlite3DbFree(db, pList);
+ sqlite3DbFreeNN(db, pList);
}
/*
@@ -104441,7 +104983,14 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* Special case: A DELETE without a WHERE clause deletes everything.
** It is easier just to erase the whole table. Prior to version 3.6.5,
** this optimization caused the row change count (the value returned by
- ** API function sqlite3_count_changes) to be set incorrectly. */
+ ** API function sqlite3_count_changes) to be set incorrectly.
+ **
+ ** The "rcauth==SQLITE_OK" terms is the
+ ** IMPLEMENATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
+ ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
+ ** the truncate optimization is disabled and all rows are deleted
+ ** individually.
+ */
if( rcauth==SQLITE_OK
&& pWhere==0
&& !bComplex
@@ -105195,15 +105744,13 @@ static void instrFunc(
if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
zHaystack = sqlite3_value_blob(argv[0]);
zNeedle = sqlite3_value_blob(argv[1]);
- assert( zNeedle!=0 );
- assert( zHaystack!=0 || nHaystack==0 );
isText = 0;
}else{
zHaystack = sqlite3_value_text(argv[0]);
zNeedle = sqlite3_value_text(argv[1]);
isText = 1;
- if( zHaystack==0 || zNeedle==0 ) return;
}
+ if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
N++;
do{
@@ -107953,8 +108500,16 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask(
** UPDATE statement modifies the rowid fields of the table.
**
** If any foreign key processing will be required, this function returns
-** true. If there is no foreign key related processing, this function
-** returns false.
+** non-zero. If there is no foreign key related processing, this function
+** returns zero.
+**
+** For an UPDATE, this function returns 2 if:
+**
+** * There are any FKs for which pTab is the child and the parent table, or
+** * the UPDATE modifies one or more parent keys for which the action is
+** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
+**
+** Or, assuming some other foreign key processing is required, 1.
*/
SQLITE_PRIVATE int sqlite3FkRequired(
Parse *pParse, /* Parse context */
@@ -107962,12 +108517,13 @@ SQLITE_PRIVATE int sqlite3FkRequired(
int *aChange, /* Non-NULL for UPDATE operations */
int chngRowid /* True for UPDATE that affects rowid */
){
+ int eRet = 0;
if( pParse->db->flags&SQLITE_ForeignKeys ){
if( !aChange ){
/* A DELETE operation. Foreign key processing is required if the
** table in question is either the child or parent table for any
** foreign key constraint. */
- return (sqlite3FkReferences(pTab) || pTab->pFKey);
+ eRet = (sqlite3FkReferences(pTab) || pTab->pFKey);
}else{
/* This is an UPDATE. Foreign key processing is only required if the
** operation modifies one or more child or parent key columns. */
@@ -107975,16 +108531,22 @@ SQLITE_PRIVATE int sqlite3FkRequired(
/* Check if any child key columns are being modified. */
for(p=pTab->pFKey; p; p=p->pNextFrom){
- if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
+ if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
+ if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
+ eRet = 1;
+ }
}
/* Check if any parent key columns are being modified. */
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
+ if( p->aAction[1]!=OE_None ) return 2;
+ eRet = 1;
+ }
}
}
}
- return 0;
+ return eRet;
}
/*
@@ -109800,6 +110362,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
+#ifdef SQLITE_ENABLE_NULL_TRIM
+ if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
+#endif
/* In an UPDATE operation, if this index is the PRIMARY KEY index
** of a WITHOUT ROWID table and there has been no change the
@@ -109955,8 +110520,11 @@ SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
if( pTab->pSchema->file_format<2 ) return;
- for(i=pTab->nCol; i>1 && pTab->aCol[i-1].pDflt==0; i--){}
- sqlite3VdbeChangeP5(v, i);
+ for(i=pTab->nCol-1; i>0; i--){
+ if( pTab->aCol[i].pDflt!=0 ) break;
+ if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
+ }
+ sqlite3VdbeChangeP5(v, i+1);
}
#endif
@@ -110246,7 +110814,7 @@ static int xferOptimization(
return 0; /* tab1 must not have triggers */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pDest->tabFlags & TF_Virtual ){
+ if( IsVirtual(pDest) ){
return 0; /* tab1 must not be a virtual table */
}
#endif
@@ -110308,7 +110876,7 @@ static int xferOptimization(
return 0; /* source and destination must both be WITHOUT ROWID or not */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pSrc->tabFlags & TF_Virtual ){
+ if( IsVirtual(pSrc) ){
return 0; /* tab2 must not be a virtual table */
}
#endif
@@ -110494,8 +111062,6 @@ static int xferOptimization(
** sorted order. */
for(i=0; i<pSrcIdx->nColumn; i++){
const char *zColl = pSrcIdx->azColl[i];
- assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
- || sqlite3StrBINARY==zColl );
if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
@@ -110605,7 +111171,7 @@ SQLITE_API int sqlite3_exec(
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
- azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
+ azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
if( azCols==0 ){
goto exec_out;
}
@@ -110626,6 +111192,7 @@ SQLITE_API int sqlite3_exec(
goto exec_out;
}
}
+ azVals[i] = 0;
}
if( xCallback(pArg, nCol, azVals, azCols) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
@@ -110981,6 +111548,8 @@ struct sqlite3_api_routines {
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
+ /* Version 3.18.0 and later */
+ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
};
/*
@@ -111239,6 +111808,8 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -111664,7 +112235,9 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_system_errno,
/* Version 3.14.0 and later */
sqlite3_trace_v2,
- sqlite3_expanded_sql
+ sqlite3_expanded_sql,
+ /* Version 3.18.0 and later */
+ sqlite3_set_last_insert_rowid
};
/*
@@ -112096,11 +112669,11 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_LOCKING_MODE 22
#define PragTyp_PAGE_COUNT 23
#define PragTyp_MMAP_SIZE 24
-#define PragTyp_PAGE_SIZE 25
-#define PragTyp_SECURE_DELETE 26
-#define PragTyp_SHRINK_MEMORY 27
-#define PragTyp_SOFT_HEAP_LIMIT 28
-#define PragTyp_STATS 29
+#define PragTyp_OPTIMIZE 25
+#define PragTyp_PAGE_SIZE 26
+#define PragTyp_SECURE_DELETE 27
+#define PragTyp_SHRINK_MEMORY 28
+#define PragTyp_SOFT_HEAP_LIMIT 29
#define PragTyp_SYNCHRONOUS 30
#define PragTyp_TABLE_INFO 31
#define PragTyp_TEMP_STORE 32
@@ -112114,6 +112687,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_REKEY 40
#define PragTyp_LOCK_STATUS 41
#define PragTyp_PARSER_TRACE 42
+#define PragTyp_STATS 43
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -112137,47 +112711,48 @@ static const char *const pragCName[] = {
/* 4 */ "notnull",
/* 5 */ "dflt_value",
/* 6 */ "pk",
- /* 7 */ "table", /* Used by: stats */
- /* 8 */ "index",
- /* 9 */ "width",
- /* 10 */ "height",
- /* 11 */ "seqno", /* Used by: index_info */
- /* 12 */ "cid",
- /* 13 */ "name",
- /* 14 */ "seqno", /* Used by: index_xinfo */
- /* 15 */ "cid",
- /* 16 */ "name",
- /* 17 */ "desc",
- /* 18 */ "coll",
- /* 19 */ "key",
- /* 20 */ "seq", /* Used by: index_list */
- /* 21 */ "name",
- /* 22 */ "unique",
- /* 23 */ "origin",
- /* 24 */ "partial",
- /* 25 */ "seq", /* Used by: database_list */
- /* 26 */ "name",
- /* 27 */ "file",
- /* 28 */ "seq", /* Used by: collation_list */
- /* 29 */ "name",
- /* 30 */ "id", /* Used by: foreign_key_list */
- /* 31 */ "seq",
- /* 32 */ "table",
- /* 33 */ "from",
- /* 34 */ "to",
- /* 35 */ "on_update",
- /* 36 */ "on_delete",
- /* 37 */ "match",
- /* 38 */ "table", /* Used by: foreign_key_check */
- /* 39 */ "rowid",
- /* 40 */ "parent",
- /* 41 */ "fkid",
- /* 42 */ "busy", /* Used by: wal_checkpoint */
- /* 43 */ "log",
- /* 44 */ "checkpointed",
- /* 45 */ "timeout", /* Used by: busy_timeout */
- /* 46 */ "database", /* Used by: lock_status */
- /* 47 */ "status",
+ /* 7 */ "tbl", /* Used by: stats */
+ /* 8 */ "idx",
+ /* 9 */ "wdth",
+ /* 10 */ "hght",
+ /* 11 */ "flgs",
+ /* 12 */ "seqno", /* Used by: index_info */
+ /* 13 */ "cid",
+ /* 14 */ "name",
+ /* 15 */ "seqno", /* Used by: index_xinfo */
+ /* 16 */ "cid",
+ /* 17 */ "name",
+ /* 18 */ "desc",
+ /* 19 */ "coll",
+ /* 20 */ "key",
+ /* 21 */ "seq", /* Used by: index_list */
+ /* 22 */ "name",
+ /* 23 */ "unique",
+ /* 24 */ "origin",
+ /* 25 */ "partial",
+ /* 26 */ "seq", /* Used by: database_list */
+ /* 27 */ "name",
+ /* 28 */ "file",
+ /* 29 */ "seq", /* Used by: collation_list */
+ /* 30 */ "name",
+ /* 31 */ "id", /* Used by: foreign_key_list */
+ /* 32 */ "seq",
+ /* 33 */ "table",
+ /* 34 */ "from",
+ /* 35 */ "to",
+ /* 36 */ "on_update",
+ /* 37 */ "on_delete",
+ /* 38 */ "match",
+ /* 39 */ "table", /* Used by: foreign_key_check */
+ /* 40 */ "rowid",
+ /* 41 */ "parent",
+ /* 42 */ "fkid",
+ /* 43 */ "busy", /* Used by: wal_checkpoint */
+ /* 44 */ "log",
+ /* 45 */ "checkpointed",
+ /* 46 */ "timeout", /* Used by: busy_timeout */
+ /* 47 */ "database", /* Used by: lock_status */
+ /* 48 */ "status",
};
/* Definitions of all built-in pragmas */
@@ -112223,7 +112798,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 45, 1,
+ /* ColNames: */ 46, 1,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
@@ -112260,7 +112835,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 28, 2,
+ /* ColNames: */ 29, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
@@ -112295,7 +112870,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "database_list",
/* ePragTyp: */ PragTyp_DATABASE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 25, 3,
+ /* ColNames: */ 26, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
@@ -112332,14 +112907,14 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "foreign_key_check",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema,
- /* ColNames: */ 38, 4,
+ /* ColNames: */ 39, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 30, 8,
+ /* ColNames: */ 31, 8,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -112402,17 +112977,17 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "index_info",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 11, 3,
+ /* ColNames: */ 12, 3,
/* iArg: */ 0 },
{/* zName: */ "index_list",
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 20, 5,
+ /* ColNames: */ 21, 5,
/* iArg: */ 0 },
{/* zName: */ "index_xinfo",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 14, 6,
+ /* ColNames: */ 15, 6,
/* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
@@ -112459,7 +113034,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "lock_status",
/* ePragTyp: */ PragTyp_LOCK_STATUS,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 46, 2,
+ /* ColNames: */ 47, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -112478,6 +113053,13 @@ static const PragmaName aPragmaName[] = {
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#endif
+ {/* zName: */ "optimize",
+ /* ePragTyp: */ PragTyp_OPTIMIZE,
+ /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "page_count",
/* ePragTyp: */ PragTyp_PAGE_COUNT,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
@@ -112576,11 +113158,11 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_SqlTrace },
#endif
#endif
-#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 7, 4,
+ /* ColNames: */ 7, 5,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -112659,7 +113241,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
- /* ColNames: */ 42, 3,
+ /* ColNames: */ 43, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -112670,7 +113252,7 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
-/* Number of pragmas: 60 on by default, 73 total. */
+/* Number of pragmas: 60 on by default, 74 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
@@ -112941,6 +113523,22 @@ static const PragmaName *pragmaLocate(const char *zName){
}
/*
+** Helper subroutine for PRAGMA integrity_check:
+**
+** Generate code to output a single-column result row with the result
+** held in register regResult. Decrement the result count and halt if
+** the maximum number of result rows have been issued.
+*/
+static int integrityCheckResultRow(Vdbe *v, int regResult){
+ int addr;
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+ return addr;
+}
+
+/*
** Process a pragma statement.
**
** Pragmas are of this form:
@@ -113644,7 +114242,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
- }else{
+ }else if( iDb!=1 ){
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
if( iLevel==0 ) iLevel = 1;
pDb->safety_level = iLevel;
@@ -113743,29 +114341,33 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
break;
+#ifdef SQLITE_DEBUG
case PragTyp_STATS: {
Index *pIdx;
HashElem *i;
- pParse->nMem = 4;
+ pParse->nMem = 5;
sqlite3CodeVerifySchema(pParse, iDb);
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
- sqlite3VdbeMultiLoad(v, 1, "ssii",
+ sqlite3VdbeMultiLoad(v, 1, "ssiii",
pTab->zName,
0,
pTab->szTabRow,
- pTab->nRowLogEst);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ pTab->nRowLogEst,
+ pTab->tabFlags);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- sqlite3VdbeMultiLoad(v, 2, "sii",
+ sqlite3VdbeMultiLoad(v, 2, "siii",
pIdx->zName,
pIdx->szIdxRow,
- pIdx->aiRowLogEst[0]);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ pIdx->aiRowLogEst[0],
+ pIdx->hasStat1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
}
}
}
break;
+#endif
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
@@ -113954,33 +114556,37 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( x==0 );
}
addrOk = sqlite3VdbeMakeLabel(v);
- if( pParent && pIdx==0 ){
- int iKey = pFK->aCol[0].iFrom;
- assert( iKey>=0 && iKey<pTab->nCol );
- if( iKey!=pTab->iPKey ){
- sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
- sqlite3ColumnDefault(v, pTab, iKey, regRow);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
- }else{
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
- }
- sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v);
+
+ /* Generate code to read the child key values into registers
+ ** regRow..regRow+n. If any of the child key values are NULL, this
+ ** row cannot cause an FK violation. Jump directly to addrOk in
+ ** this case. */
+ for(j=0; j<pFK->nCol; j++){
+ int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+ }
+
+ /* Generate code to query the parent index for a matching parent
+ ** key. If a match is found, jump to addrOk. */
+ if( pIdx ){
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+ sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ VdbeCoverage(v);
+ }else if( pParent ){
+ int jmp = sqlite3VdbeCurrentAddr(v)+2;
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
sqlite3VdbeGoto(v, addrOk);
- sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ assert( pFK->nCol==1 );
+ }
+
+ /* Generate code to report an FK violation to the caller. */
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
}else{
- for(j=0; j<pFK->nCol; j++){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
- aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
- }
- if( pParent ){
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
- sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
- sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
- VdbeCoverage(v);
- }
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
}
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
sqlite3VdbeResolveLabel(v, addrOk);
@@ -114022,9 +114628,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* Pragma "quick_check" is reduced version of
+ /* PRAGMA integrity_check
+ ** PRAGMA integrity_check(N)
+ ** PRAGMA quick_check
+ ** PRAGMA quick_check(N)
+ **
+ ** Verify the integrity of the database.
+ **
+ ** The "quick_check" is reduced version of
** integrity_check designed to detect most database corruption
- ** without most of the overhead of a full integrity-check.
+ ** without the overhead of cross-checking indexes. Quick_check
+ ** is linear time wherease integrity_check is O(NlogN).
*/
case PragTyp_INTEGRITY_CHECK: {
int i, j, addr, mxErr;
@@ -114055,7 +114669,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
}
}
- sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
+ sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
/* Do an integrity check on each database file */
for(i=0; i<db->nDb; i++){
@@ -114070,10 +114684,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( iDb>=0 && i!=iDb ) continue;
sqlite3CodeVerifySchema(pParse, i);
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
/* Do an integrity check of the B-Tree
**
@@ -114113,12 +114723,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
+ integrityCheckResultRow(v, 2);
sqlite3VdbeJumpHere(v, addr);
/* Make sure all the indices are constructed correctly.
*/
- for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
+ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx, *pPk;
Index *pPrior = 0;
@@ -114126,12 +114736,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
int iDataCur, iIdxCur;
int r1 = -1;
- if( pTab->pIndex==0 ) continue;
+ if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
+ if( pTab->pCheck==0
+ && (pTab->tabFlags & TF_HasNotNull)==0
+ && (pTab->pIndex==0 || isQuick)
+ ){
+ continue; /* No additional checks needed for this table */
+ }
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
1, 0, &iDataCur, &iIdxCur);
@@ -114146,24 +114758,45 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Verify that all NOT NULL columns really are NOT NULL */
for(j=0; j<pTab->nCol; j++){
char *zErr;
- int jmp2, jmp3;
+ int jmp2;
if( j==pTab->iPKey ) continue;
if( pTab->aCol[j].notNull==0 ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
- jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
- sqlite3VdbeAddOp0(v, OP_Halt);
+ integrityCheckResultRow(v, 3);
sqlite3VdbeJumpHere(v, jmp2);
- sqlite3VdbeJumpHere(v, jmp3);
+ }
+ /* Verify CHECK constraints */
+ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
+ ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
+ if( db->mallocFailed==0 ){
+ int addrCkFault = sqlite3VdbeMakeLabel(v);
+ int addrCkOk = sqlite3VdbeMakeLabel(v);
+ char *zErr;
+ int k;
+ pParse->iSelfTab = iDataCur;
+ sqlite3ExprCachePush(pParse);
+ for(k=pCheck->nExpr-1; k>0; k--){
+ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
+ }
+ sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
+ SQLITE_JUMPIFNULL);
+ sqlite3VdbeResolveLabel(v, addrCkFault);
+ zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
+ pTab->zName);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+ integrityCheckResultRow(v, 3);
+ sqlite3VdbeResolveLabel(v, addrCkOk);
+ sqlite3ExprCachePop(pParse);
+ }
+ sqlite3ExprListDelete(db, pCheck);
}
/* Validate index entries for the current row */
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
int ckUniq = sqlite3VdbeMakeLabel(v);
if( pPk==pIdx ) continue;
@@ -114174,16 +114807,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Verify that an index entry exists for the current table row */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
pIdx->nColumn); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeLoadString(v, 3, "row ");
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
sqlite3VdbeLoadString(v, 4, " missing from index ");
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
- jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
- sqlite3VdbeAddOp0(v, OP_Halt);
+ jmp4 = integrityCheckResultRow(v, 3);
sqlite3VdbeJumpHere(v, jmp2);
/* For UNIQUE indexes, verify that only one entry exists with the
** current key. The entry is unique if (1) any column is NULL
@@ -114204,7 +114834,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeJumpHere(v, jmp6);
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
pIdx->nKeyCol); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
sqlite3VdbeGoto(v, jmp5);
sqlite3VdbeResolveLabel(v, uniqOk);
@@ -114215,19 +114844,18 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
- sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- if( pPk==pIdx ) continue;
- addr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
- sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
- sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeLoadString(v, 3, pIdx->zName);
- sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
+ if( !isQuick ){
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pPk==pIdx ) continue;
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ sqlite3VdbeLoadString(v, 3, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+ integrityCheckResultRow(v, 7);
+ sqlite3VdbeJumpHere(v, addr);
+ }
}
#endif /* SQLITE_OMIT_BTREECOUNT */
}
@@ -114236,7 +114864,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
- { OP_If, 1, 4, 0}, /* 1 */
+ { OP_IfNotZero, 1, 4, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0}, /* 3 */
};
@@ -114244,7 +114872,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
if( aOp ){
- aOp[0].p2 = -mxErr;
+ aOp[0].p2 = 1-mxErr;
aOp[2].p4type = P4_STATIC;
aOp[2].p4.z = "ok";
}
@@ -114470,6 +115098,118 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/*
+ ** PRAGMA optimize
+ ** PRAGMA optimize(MASK)
+ ** PRAGMA schema.optimize
+ ** PRAGMA schema.optimize(MASK)
+ **
+ ** Attempt to optimize the database. All schemas are optimized in the first
+ ** two forms, and only the specified schema is optimized in the latter two.
+ **
+ ** The details of optimizations performed by this pragma are expected
+ ** to change and improve over time. Applications should anticipate that
+ ** this pragma will perform new optimizations in future releases.
+ **
+ ** The optional argument is a bitmask of optimizations to perform:
+ **
+ ** 0x0001 Debugging mode. Do not actually perform any optimizations
+ ** but instead return one line of text for each optimization
+ ** that would have been done. Off by default.
+ **
+ ** 0x0002 Run ANALYZE on tables that might benefit. On by default.
+ ** See below for additional information.
+ **
+ ** 0x0004 (Not yet implemented) Record usage and performance
+ ** information from the current session in the
+ ** database file so that it will be available to "optimize"
+ ** pragmas run by future database connections.
+ **
+ ** 0x0008 (Not yet implemented) Create indexes that might have
+ ** been helpful to recent queries
+ **
+ ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all ** of the optimizations listed above except Debug Mode, including new
+ ** optimizations that have not yet been invented. If new optimizations are
+ ** ever added that should be off by default, those off-by-default
+ ** optimizations will have bitmasks of 0x10000 or larger.
+ **
+ ** DETERMINATION OF WHEN TO RUN ANALYZE
+ **
+ ** In the current implementation, a table is analyzed if only if all of
+ ** the following are true:
+ **
+ ** (1) MASK bit 0x02 is set.
+ **
+ ** (2) The query planner used sqlite_stat1-style statistics for one or
+ ** more indexes of the table at some point during the lifetime of
+ ** the current connection.
+ **
+ ** (3) One or more indexes of the table are currently unanalyzed OR
+ ** the number of rows in the table has increased by 25 times or more
+ ** since the last time ANALYZE was run.
+ **
+ ** The rules for when tables are analyzed are likely to change in
+ ** future releases.
+ */
+ case PragTyp_OPTIMIZE: {
+ int iDbLast; /* Loop termination point for the schema loop */
+ int iTabCur; /* Cursor for a table whose size needs checking */
+ HashElem *k; /* Loop over tables of a schema */
+ Schema *pSchema; /* The current schema */
+ Table *pTab; /* A table in the schema */
+ Index *pIdx; /* An index of the table */
+ LogEst szThreshold; /* Size threshold above which reanalysis is needd */
+ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
+ u32 opMask; /* Mask of operations to perform */
+
+ if( zRight ){
+ opMask = (u32)sqlite3Atoi(zRight);
+ if( (opMask & 0x02)==0 ) break;
+ }else{
+ opMask = 0xfffe;
+ }
+ iTabCur = pParse->nTab++;
+ for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
+ if( iDb==1 ) continue;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ pSchema = db->aDb[iDb].pSchema;
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+
+ /* If table pTab has not been used in a way that would benefit from
+ ** having analysis statistics during the current session, then skip it.
+ ** This also has the effect of skipping virtual tables and views */
+ if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
+
+ /* Reanalyze if the table is 25 times larger than the last analysis */
+ szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( !pIdx->hasStat1 ){
+ szThreshold = 0; /* Always analyze if any index lacks statistics */
+ break;
+ }
+ }
+ if( szThreshold ){
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
+ sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur,
+ sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
+ VdbeCoverage(v);
+ }
+ zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
+ db->aDb[iDb].zDbSName, pTab->zName);
+ if( opMask & 0x01 ){
+ int r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
+ }else{
+ sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
+ }
+ }
+ }
+ sqlite3VdbeAddOp0(v, OP_Expire);
+ break;
+ }
+
+ /*
** PRAGMA busy_timeout
** PRAGMA busy_timeout = N
**
@@ -115857,7 +116597,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
sqlite3ExprDelete(db, p->pLimit);
sqlite3ExprDelete(db, p->pOffset);
if( p->pWith ) sqlite3WithDelete(db, p->pWith);
- if( bFree ) sqlite3DbFree(db, p);
+ if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
bFree = 1;
}
@@ -115893,14 +116633,13 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
){
Select *pNew;
Select standin;
- sqlite3 *db = pParse->db;
- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+ pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
if( pNew==0 ){
- assert( db->mallocFailed );
+ assert( pParse->db->mallocFailed );
pNew = &standin;
}
if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
}
pNew->pEList = pEList;
pNew->op = TK_SELECT;
@@ -115913,7 +116652,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = 0;
- if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
+ if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
pNew->pSrc = pSrc;
pNew->pWhere = pWhere;
pNew->pGroupBy = pGroupBy;
@@ -115924,9 +116663,9 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
pNew->pWith = 0;
- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
- if( db->mallocFailed ) {
- clearSelect(db, pNew, pNew!=&standin);
+ assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
+ if( pParse->db->mallocFailed ) {
+ clearSelect(pParse->db, pNew, pNew!=&standin);
pNew = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
@@ -116836,7 +117575,7 @@ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
if( p ){
assert( p->nRef>0 );
p->nRef--;
- if( p->nRef==0 ) sqlite3DbFree(p->db, p);
+ if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
}
}
@@ -117311,6 +118050,7 @@ static void generateColumnTypes(
NameContext sNC;
sNC.pSrcList = pTabList;
sNC.pParse = pParse;
+ sNC.pNext = 0;
for(i=0; i<pEList->nExpr; i++){
Expr *p = pEList->a[i].pExpr;
const char *zType;
@@ -117336,6 +118076,19 @@ static void generateColumnTypes(
}
/*
+** Return the Table objecct in the SrcList that has cursor iCursor.
+** Or return NULL if no such Table object exists in the SrcList.
+*/
+static Table *tableWithCursor(SrcList *pList, int iCursor){
+ int j;
+ for(j=0; j<pList->nSrc; j++){
+ if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab;
+ }
+ return 0;
+}
+
+
+/*
** Generate code that will tell the VDBE the names of columns
** in the result set. This information is used to provide the
** azCol[] values in the callback.
@@ -117346,7 +118099,8 @@ static void generateColumnNames(
ExprList *pEList /* Expressions defining the result set */
){
Vdbe *v = pParse->pVdbe;
- int i, j;
+ int i;
+ Table *pTab;
sqlite3 *db = pParse->db;
int fullNames, shortNames;
@@ -117371,15 +118125,11 @@ static void generateColumnNames(
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
- }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
- Table *pTab;
+ }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
+ && (pTab = tableWithCursor(pTabList, p->iTable))!=0
+ ){
char *zCol;
int iCol = p->iColumn;
- for(j=0; ALWAYS(j<pTabList->nSrc); j++){
- if( pTabList->a[j].iCursor==p->iTable ) break;
- }
- assert( j<pTabList->nSrc );
- pTab = pTabList->a[j].pTab;
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
@@ -117461,7 +118211,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
pColExpr = pColExpr->pRight;
assert( pColExpr!=0 );
}
- if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
+ if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
pTab = pColExpr->pTab;
@@ -118681,7 +119431,7 @@ static int multiSelectOrderBy(
if( pNew==0 ) return SQLITE_NOMEM_BKPT;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
- pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
+ p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
}
}
@@ -118915,9 +119665,24 @@ static int multiSelectOrderBy(
#endif
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+
+/* An instance of the SubstContext object describes an substitution edit
+** to be performed on a parse tree.
+**
+** All references to columns in table iTable are to be replaced by corresponding
+** expressions in pEList.
+*/
+typedef struct SubstContext {
+ Parse *pParse; /* The parsing context */
+ int iTable; /* Replace references to this table */
+ int iNewTable; /* New table number */
+ int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
+ ExprList *pEList; /* Replacement expressions */
+} SubstContext;
+
/* Forward Declarations */
-static void substExprList(Parse*, ExprList*, int, ExprList*);
-static void substSelect(Parse*, Select *, int, ExprList*, int);
+static void substExprList(SubstContext*, ExprList*);
+static void substSelect(SubstContext*, Select*, int);
/*
** Scan through the expression pExpr. Replace every reference to
@@ -118928,29 +119693,38 @@ static void substSelect(Parse*, Select *, int, ExprList*, int);
** This routine is part of the flattening procedure. A subquery
** whose result set is defined by pEList appears as entry in the
** FROM clause of a SELECT such that the VDBE cursor assigned to that
-** FORM clause entry is iTable. This routine make the necessary
+** FORM clause entry is iTable. This routine makes the necessary
** changes to pExpr so that it refers directly to the source table
** of the subquery rather the result set of the subquery.
*/
static Expr *substExpr(
- Parse *pParse, /* Report errors here */
- Expr *pExpr, /* Expr in which substitution occurs */
- int iTable, /* Table to be substituted */
- ExprList *pEList /* Substitute expressions */
+ SubstContext *pSubst, /* Description of the substitution */
+ Expr *pExpr /* Expr in which substitution occurs */
){
- sqlite3 *db = pParse->db;
if( pExpr==0 ) return 0;
- if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
+ if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){
+ pExpr->iRightJoinTable = pSubst->iNewTable;
+ }
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
Expr *pNew;
- Expr *pCopy = pEList->a[pExpr->iColumn].pExpr;
- assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
+ Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
+ Expr ifNullRow;
+ assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
if( sqlite3ExprIsVector(pCopy) ){
- sqlite3VectorErrorMsg(pParse, pCopy);
+ sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
}else{
+ sqlite3 *db = pSubst->pParse->db;
+ if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
+ memset(&ifNullRow, 0, sizeof(ifNullRow));
+ ifNullRow.op = TK_IF_NULL_ROW;
+ ifNullRow.pLeft = pCopy;
+ ifNullRow.iTable = pSubst->iNewTable;
+ pCopy = &ifNullRow;
+ }
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && (pExpr->flags & EP_FromJoin) ){
pNew->iRightJoinTable = pExpr->iRightJoinTable;
@@ -118961,51 +119735,50 @@ static Expr *substExpr(
}
}
}else{
- pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList);
- pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList);
+ if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
+ pExpr->iTable = pSubst->iNewTable;
+ }
+ pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
+ pExpr->pRight = substExpr(pSubst, pExpr->pRight);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1);
+ substSelect(pSubst, pExpr->x.pSelect, 1);
}else{
- substExprList(pParse, pExpr->x.pList, iTable, pEList);
+ substExprList(pSubst, pExpr->x.pList);
}
}
return pExpr;
}
static void substExprList(
- Parse *pParse, /* Report errors here */
- ExprList *pList, /* List to scan and in which to make substitutes */
- int iTable, /* Table to be substituted */
- ExprList *pEList /* Substitute values */
+ SubstContext *pSubst, /* Description of the substitution */
+ ExprList *pList /* List to scan and in which to make substitutes */
){
int i;
if( pList==0 ) return;
for(i=0; i<pList->nExpr; i++){
- pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList);
+ pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
}
}
static void substSelect(
- Parse *pParse, /* Report errors here */
- Select *p, /* SELECT statement in which to make substitutions */
- int iTable, /* Table to be replaced */
- ExprList *pEList, /* Substitute values */
- int doPrior /* Do substitutes on p->pPrior too */
+ SubstContext *pSubst, /* Description of the substitution */
+ Select *p, /* SELECT statement in which to make substitutions */
+ int doPrior /* Do substitutes on p->pPrior too */
){
SrcList *pSrc;
struct SrcList_item *pItem;
int i;
if( !p ) return;
do{
- substExprList(pParse, p->pEList, iTable, pEList);
- substExprList(pParse, p->pGroupBy, iTable, pEList);
- substExprList(pParse, p->pOrderBy, iTable, pEList);
- p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList);
- p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList);
+ substExprList(pSubst, p->pEList);
+ substExprList(pSubst, p->pGroupBy);
+ substExprList(pSubst, p->pOrderBy);
+ p->pHaving = substExpr(pSubst, p->pHaving);
+ p->pWhere = substExpr(pSubst, p->pWhere);
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(pParse, pItem->pSelect, iTable, pEList, 1);
+ substSelect(pSubst, pItem->pSelect, 1);
if( pItem->fg.isTabFunc ){
- substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList);
+ substExprList(pSubst, pItem->u1.pFuncArg);
}
}
}while( doPrior && (p = p->pPrior)!=0 );
@@ -119048,8 +119821,9 @@ static void substSelect(
** FROM-clause subquery that is a candidate for flattening. (2b is
** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
**
-** (3) The subquery is not the right operand of a left outer join
-** (Originally ticket #306. Strengthened by ticket #3300)
+** (3) The subquery is not the right operand of a LEFT JOIN
+** or the subquery is not itself a join and the outer query is not
+** an aggregate.
**
** (4) The subquery is not DISTINCT.
**
@@ -119061,7 +119835,7 @@ static void substSelect(
** DISTINCT.
**
** (7) The subquery has a FROM clause. TODO: For subqueries without
-** A FROM clause, consider adding a FROM close with the special
+** A FROM clause, consider adding a FROM clause with the special
** table sqlite_once that consists of a single row containing a
** single NULL.
**
@@ -119167,6 +119941,8 @@ static int flattenSubquery(
SrcList *pSubSrc; /* The FROM clause of the subquery */
ExprList *pList; /* The result set of the outer query */
int iParent; /* VDBE cursor number of the pSub result set temp table */
+ int iNewParent = -1;/* Replacement table for iParent */
+ int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
int i; /* Loop counter */
Expr *pWhere; /* The WHERE clause */
struct SrcList_item *pSubitem; /* The subquery */
@@ -119193,7 +119969,7 @@ static int flattenSubquery(
return 0; /* Restriction (2b) */
}
}
-
+
pSubSrc = pSub->pSrc;
assert( pSubSrc );
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
@@ -119231,10 +120007,9 @@ static int flattenSubquery(
return 0; /* Restriction (23) */
}
- /* OBSOLETE COMMENT 1:
- ** Restriction 3: If the subquery is a join, make sure the subquery is
- ** not used as the right operand of an outer join. Examples of why this
- ** is not allowed:
+ /*
+ ** If the subquery is the right operand of a LEFT JOIN, then the
+ ** subquery may not be a join itself. Example of why this is not allowed:
**
** t1 LEFT OUTER JOIN (t2 JOIN t3)
**
@@ -119244,28 +120019,27 @@ static int flattenSubquery(
**
** which is not at all the same thing.
**
- ** OBSOLETE COMMENT 2:
- ** Restriction 12: If the subquery is the right operand of a left outer
- ** join, make sure the subquery has no WHERE clause.
- ** An examples of why this is not allowed:
- **
- ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
- **
- ** If we flatten the above, we would get
+ ** If the subquery is the right operand of a LEFT JOIN, then the outer
+ ** query cannot be an aggregate. This is an artifact of the way aggregates
+ ** are processed - there is not mechanism to determine if the LEFT JOIN
+ ** table should be all-NULL.
**
- ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
- **
- ** But the t2.x>0 test will always fail on a NULL row of t2, which
- ** effectively converts the OUTER JOIN into an INNER JOIN.
- **
- ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
- ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
- ** is fraught with danger. Best to avoid the whole thing. If the
- ** subquery is the right term of a LEFT JOIN, then do not flatten.
+ ** See also tickets #306, #350, and #3300.
*/
if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
- return 0;
+ isLeftJoin = 1;
+ if( pSubSrc->nSrc>1 || isAgg ){
+ return 0; /* Restriction (3) */
+ }
}
+#ifdef SQLITE_EXTRA_IFNULLROW
+ else if( iFrom>0 && !isAgg ){
+ /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
+ ** every reference to any result column from subquery in a join, even though
+ ** they are not necessary. This will stress-test the OP_IfNullRow opcode. */
+ isLeftJoin = -1;
+ }
+#endif
/* Restriction 17: If the sub-query is a compound SELECT, then it must
** use only the UNION ALL operator. And none of the simple select queries
@@ -119473,6 +120247,7 @@ static int flattenSubquery(
sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
pSrc->a[i+iFrom] = pSubSrc->a[i];
+ iNewParent = pSubSrc->a[i].iCursor;
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
pSrc->a[iFrom].fg.jointype = jointype;
@@ -119518,6 +120293,9 @@ static int flattenSubquery(
pSub->pOrderBy = 0;
}
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
+ if( isLeftJoin>0 ){
+ setJoinExpr(pWhere, iNewParent);
+ }
if( subqueryIsAgg ){
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
@@ -119530,7 +120308,15 @@ static int flattenSubquery(
}else{
pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
}
- substSelect(pParse, pParent, iParent, pSub->pEList, 0);
+ if( db->mallocFailed==0 ){
+ SubstContext x;
+ x.pParse = pParse;
+ x.iTable = iParent;
+ x.iNewTable = iNewParent;
+ x.isLeftJoin = isLeftJoin;
+ x.pEList = pSub->pEList;
+ substSelect(&x, pParent, 0);
+ }
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
@@ -119632,8 +120418,14 @@ static int pushDownWhereTerms(
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
nChng++;
while( pSubq ){
+ SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
- pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList);
+ x.pParse = pParse;
+ x.iTable = iCursor;
+ x.iNewTable = iCursor;
+ x.isLeftJoin = 0;
+ x.pEList = pSubq->pEList;
+ pNew = substExpr(&x, pNew);
pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
pSubq = pSubq->pPrior;
}
@@ -120626,6 +121418,103 @@ static void explainSimpleCount(
#endif
/*
+** Context object for havingToWhereExprCb().
+*/
+struct HavingToWhereCtx {
+ Expr **ppWhere;
+ ExprList *pGroupBy;
+};
+
+/*
+** sqlite3WalkExpr() callback used by havingToWhere().
+**
+** If the node passed to the callback is a TK_AND node, return
+** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
+**
+** Otherwise, return WRC_Prune. In this case, also check if the
+** sub-expression matches the criteria for being moved to the WHERE
+** clause. If so, add it to the WHERE clause and replace the sub-expression
+** within the HAVING expression with a constant "1".
+*/
+static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op!=TK_AND ){
+ struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
+ if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
+ sqlite3 *db = pWalker->pParse->db;
+ Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
+ if( pNew ){
+ Expr *pWhere = *(p->ppWhere);
+ SWAP(Expr, *pNew, *pExpr);
+ pNew = sqlite3ExprAnd(db, pWhere, pNew);
+ *(p->ppWhere) = pNew;
+ }
+ }
+ return WRC_Prune;
+ }
+ return WRC_Continue;
+}
+
+/*
+** Transfer eligible terms from the HAVING clause of a query, which is
+** processed after grouping, to the WHERE clause, which is processed before
+** grouping. For example, the query:
+**
+** SELECT * FROM <tables> WHERE a=? GROUP BY b HAVING b=? AND c=?
+**
+** can be rewritten as:
+**
+** SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=?
+**
+** A term of the HAVING expression is eligible for transfer if it consists
+** entirely of constants and expressions that are also GROUP BY terms that
+** use the "BINARY" collation sequence.
+*/
+static void havingToWhere(
+ Parse *pParse,
+ ExprList *pGroupBy,
+ Expr *pHaving,
+ Expr **ppWhere
+){
+ struct HavingToWhereCtx sCtx;
+ Walker sWalker;
+
+ sCtx.ppWhere = ppWhere;
+ sCtx.pGroupBy = pGroupBy;
+
+ memset(&sWalker, 0, sizeof(sWalker));
+ sWalker.pParse = pParse;
+ sWalker.xExprCallback = havingToWhereExprCb;
+ sWalker.u.pHavingCtx = &sCtx;
+ sqlite3WalkExpr(&sWalker, pHaving);
+}
+
+/*
+** Check to see if the pThis entry of pTabList is a self-join of a prior view.
+** If it is, then return the SrcList_item for the prior view. If it is not,
+** then return 0.
+*/
+static struct SrcList_item *isSelfJoinView(
+ SrcList *pTabList, /* Search for self-joins in this FROM clause */
+ struct SrcList_item *pThis /* Search for prior reference to this subquery */
+){
+ struct SrcList_item *pItem;
+ for(pItem = pTabList->a; pItem<pThis; pItem++){
+ if( pItem->pSelect==0 ) continue;
+ if( pItem->fg.viaCoroutine ) continue;
+ if( pItem->zName==0 ) continue;
+ if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
+ if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
+ if( sqlite3ExprCompare(pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) ){
+ /* The view was modified by some other optimization such as
+ ** pushDownWhereTerms() */
+ continue;
+ }
+ return pItem;
+ }
+ return 0;
+}
+
+/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
@@ -120764,13 +121653,38 @@ SQLITE_PRIVATE int sqlite3Select(
}
#endif
- /* Generate code for all sub-queries in the FROM clause
+ /* For each term in the FROM clause, do two things:
+ ** (1) Authorized unreferenced tables
+ ** (2) Generate code for all sub-queries
*/
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; i<pTabList->nSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest;
- Select *pSub = pItem->pSelect;
+ Select *pSub;
+
+ /* Issue SQLITE_READ authorizations with a fake column name for any tables that
+ ** are referenced but from which no values are extracted. Examples of where these
+ ** kinds of null SQLITE_READ authorizations would occur:
+ **
+ ** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
+ ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2.""
+ **
+ ** The fake column name is an empty string. It is possible for a table to
+ ** have a column named by the empty string, in which case there is no way to
+ ** distinguish between an unreferenced table and an actual reference to the
+ ** "" column. The original design was for the fake column name to be a NULL,
+ ** which would be unambiguous. But legacy authorization callbacks might
+ ** assume the column name is non-NULL and segfault. The use of an empty string
+ ** for the fake column name seems safer.
+ */
+ if( pItem->colUsed==0 ){
+ sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
+ }
+
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ /* Generate code for all sub-queries in the FROM clause
+ */
+ pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than
@@ -120781,6 +121695,10 @@ SQLITE_PRIVATE int sqlite3Select(
** to be invoked again. */
if( pItem->addrFillSub ){
if( pItem->fg.viaCoroutine==0 ){
+ /* The subroutine that manifests the view might be a one-time routine,
+ ** or it might need to be rerun on each iteration because it
+ ** encodes a correlated subquery. */
+ testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
}
continue;
@@ -120855,6 +121773,8 @@ SQLITE_PRIVATE int sqlite3Select(
int topAddr;
int onceAddr = 0;
int retAddr;
+ struct SrcList_item *pPrior;
+
assert( pItem->addrFillSub==0 );
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
@@ -120868,9 +121788,14 @@ SQLITE_PRIVATE int sqlite3Select(
}else{
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
}
- sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
- sqlite3Select(pParse, pSub, &dest);
+ pPrior = isSelfJoinView(pTabList, pItem);
+ if( pPrior ){
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
+ }else{
+ sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+ explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+ sqlite3Select(pParse, pSub, &dest);
+ }
pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
@@ -120880,8 +121805,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
- }
#endif
+ }
/* Various elements of the SELECT copied into local variables for
** convenience */
@@ -121089,6 +122014,11 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprAnalyzeAggList(&sNC, pEList);
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
if( pHaving ){
+ if( pGroupBy ){
+ assert( pWhere==p->pWhere );
+ havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
+ pWhere = p->pWhere;
+ }
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
@@ -123101,7 +124031,7 @@ SQLITE_PRIVATE void sqlite3Update(
*/
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
- if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
+ if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}else{
@@ -123456,7 +124386,7 @@ SQLITE_PRIVATE void sqlite3Update(
assert( regNew==regNewRowid+1 );
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
- OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
+ OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
regNewRowid
);
if( eOnePass==ONEPASS_MULTI ){
@@ -123467,7 +124397,7 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
#else
- if( hasFK || chngKey ){
+ if( hasFK>1 || chngKey ){
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
}
#endif
@@ -123784,8 +124714,25 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
Vdbe *v = sqlite3GetVdbe(pParse);
- int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
- if( v && (iDb>=2 || iDb==0) ){
+ int iDb = 0;
+ if( v==0 ) return;
+ if( pNm ){
+#ifndef SQLITE_BUG_COMPATIBLE_20160819
+ /* Default behavior: Report an error if the argument to VACUUM is
+ ** not recognized */
+ iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
+ if( iDb<0 ) return;
+#else
+ /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
+ ** to VACUUM are silently ignored. This is a back-out of a bug fix that
+ ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
+ ** The buggy behavior is required for binary compatibility with some
+ ** legacy applications. */
+ iDb = sqlite3FindDb(pParse->db, pNm);
+ if( iDb<0 ) iDb = 0;
+#endif
+ }
+ if( iDb!=1 ){
sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
sqlite3VdbeUsesBtree(v, iDb);
}
@@ -124379,8 +125326,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
assert( iDb>=0 );
- pTable->tabFlags |= TF_Virtual;
- pTable->nModuleArg = 0;
+ assert( pTable->nModuleArg==0 );
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -124668,7 +125614,7 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
int rc;
assert( pTab );
- if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
+ if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
return SQLITE_OK;
}
@@ -124738,7 +125684,7 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
const char *zMod;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
- assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
+ assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
@@ -124792,7 +125738,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
return SQLITE_MISUSE_BKPT;
}
pTab = pCtx->pTab;
- assert( (pTab->tabFlags & TF_Virtual)!=0 );
+ assert( IsVirtual(pTab) );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
@@ -124806,7 +125752,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
&& pParse->pNewTable
&& !db->mallocFailed
&& !pParse->pNewTable->pSelect
- && (pParse->pNewTable->tabFlags & TF_Virtual)==0
+ && !IsVirtual(pParse->pNewTable)
){
if( !pTab->aCol ){
Table *pNew = pParse->pNewTable;
@@ -125094,8 +126040,8 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->pTab;
- if( NEVER(pTab==0) ) return pDef;
- if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
+ if( pTab==0 ) return pDef;
+ if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
@@ -125190,8 +126136,7 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
pMod->pEpoTab = pTab;
pTab->nTabRef = 1;
pTab->pSchema = db->aDb[0].pSchema;
- pTab->tabFlags |= TF_Virtual;
- pTab->nModuleArg = 0;
+ assert( pTab->nModuleArg==0 );
pTab->iPKey = -1;
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(db, pTab, 0);
@@ -125262,7 +126207,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
if( !p ){
rc = SQLITE_MISUSE_BKPT;
}else{
- assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
+ assert( p->pTab==0 || IsVirtual(p->pTab) );
p->pVTable->bConstraint = (u8)va_arg(ap, int);
}
break;
@@ -125430,6 +126375,7 @@ struct WhereLoop {
u16 nEq; /* Number of equality constraints */
u16 nBtm; /* Size of BTM vector */
u16 nTop; /* Size of TOP vector */
+ u16 nIdxCol; /* Index column used for ORDER BY */
Index *pIndex; /* Index used, or NULL */
} btree;
struct { /* Information for virtual tables */
@@ -125701,8 +126647,13 @@ struct WhereLoopBuilder {
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */
#endif
+ unsigned int bldFlags; /* SQLITE_BLDF_* flags */
};
+/* Allowed values for WhereLoopBuider.bldFlags */
+#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
+#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
+
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
@@ -125717,7 +126668,8 @@ struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
- ExprList *pDistinctSet; /* DISTINCT over all these values */
+ ExprList *pResultSet; /* Result set of the query */
+ Expr *pWhere; /* The complete WHERE clause */
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
int iContinue; /* Jump here to continue with next record */
@@ -126878,6 +127830,69 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
}
}
+/* An instance of the IdxExprTrans object carries information about a
+** mapping from an expression on table columns into a column in an index
+** down through the Walker.
+*/
+typedef struct IdxExprTrans {
+ Expr *pIdxExpr; /* The index expression */
+ int iTabCur; /* The cursor of the corresponding table */
+ int iIdxCur; /* The cursor for the index */
+ int iIdxCol; /* The column for the index */
+} IdxExprTrans;
+
+/* The walker node callback used to transform matching expressions into
+** a reference to an index column for an index on an expression.
+**
+** If pExpr matches, then transform it into a reference to the index column
+** that contains the value of pExpr.
+*/
+static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
+ IdxExprTrans *pX = p->u.pIdxTrans;
+ if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
+ pExpr->op = TK_COLUMN;
+ pExpr->iTable = pX->iIdxCur;
+ pExpr->iColumn = pX->iIdxCol;
+ pExpr->pTab = 0;
+ return WRC_Prune;
+ }else{
+ return WRC_Continue;
+ }
+}
+
+/*
+** For an indexes on expression X, locate every instance of expression X in pExpr
+** and change that subexpression into a reference to the appropriate column of
+** the index.
+*/
+static void whereIndexExprTrans(
+ Index *pIdx, /* The Index */
+ int iTabCur, /* Cursor of the table that is being indexed */
+ int iIdxCur, /* Cursor of the index itself */
+ WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
+){
+ int iIdxCol; /* Column number of the index */
+ ExprList *aColExpr; /* Expressions that are indexed */
+ Walker w;
+ IdxExprTrans x;
+ aColExpr = pIdx->aColExpr;
+ if( aColExpr==0 ) return; /* Not an index on expressions */
+ memset(&w, 0, sizeof(w));
+ w.xExprCallback = whereIndexExprTransNode;
+ w.u.pIdxTrans = &x;
+ x.iTabCur = iTabCur;
+ x.iIdxCur = iIdxCur;
+ for(iIdxCol=0; iIdxCol<aColExpr->nExpr; iIdxCol++){
+ if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue;
+ assert( aColExpr->a[iIdxCol].pExpr!=0 );
+ x.iIdxCol = iIdxCol;
+ x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
+ sqlite3WalkExpr(&w, pWInfo->pWhere);
+ sqlite3WalkExprList(&w, pWInfo->pOrderBy);
+ sqlite3WalkExprList(&w, pWInfo->pResultSet);
+ }
+}
+
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
@@ -126901,9 +127916,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
+ int addrHalt; /* addrBrk for the outermost loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
+ Index *pIdx = 0; /* Index used by loop (if any) */
+ int loopAgain; /* True if constraint generator loop should repeat */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
@@ -126942,6 +127960,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeComment((v, "init LEFT JOIN no-match flag"));
}
+ /* Compute a safe address to jump to if we discover that the table for
+ ** this loop is empty and can never contribute content. */
+ for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
+ addrHalt = pWInfo->a[j].addrBrk;
+
/* Special case of a FROM clause subquery implemented as a co-routine */
if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
@@ -127126,7 +128149,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
}else{
- sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
}
@@ -127224,7 +128247,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int endEq; /* True if range end uses ==, >= or <= */
int start_constraints; /* Start of range is constrained */
int nConstraint; /* Number of constraint terms */
- Index *pIdx; /* The index we will be using */
int iIdxCur; /* The VDBE cursor for the index */
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
@@ -127453,6 +128475,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
}
+ /* If pIdx is an index on one or more expressions, then look through
+ ** all the expressions in pWInfo and try to transform matching expressions
+ ** into reference to index columns.
+ */
+ whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
+
+
/* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;
@@ -127468,6 +128497,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}else{
assert( pLevel->p5==0 );
}
+ if( omitTable ) pIdx = 0;
}else
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
@@ -127772,7 +128802,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
+ pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
@@ -127785,43 +128815,56 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
+ **
+ ** This loop may run either once (pIdx==0) or twice (pIdx!=0). If
+ ** it is run twice, then the first iteration codes those sub-expressions
+ ** that can be computed using columns from pIdx only (without seeking
+ ** the main table cursor).
*/
- for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE;
- int skipLikeAddr = 0;
- testcase( pTerm->wtFlags & TERM_VIRTUAL );
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
- testcase( pWInfo->untestedTerms==0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
- pWInfo->untestedTerms = 1;
- continue;
- }
- pE = pTerm->pExpr;
- assert( pE!=0 );
- if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
- continue;
- }
- if( pTerm->wtFlags & TERM_LIKECOND ){
- /* If the TERM_LIKECOND flag is set, that means that the range search
- ** is sufficient to guarantee that the LIKE operator is true, so we
- ** can skip the call to the like(A,B) function. But this only works
- ** for strings. So do not skip the call to the function on the pass
- ** that compares BLOBs. */
+ do{
+ loopAgain = 0;
+ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+ Expr *pE;
+ int skipLikeAddr = 0;
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ testcase( pTerm->wtFlags & TERM_CODED );
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
+ testcase( pWInfo->untestedTerms==0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
+ pWInfo->untestedTerms = 1;
+ continue;
+ }
+ pE = pTerm->pExpr;
+ assert( pE!=0 );
+ if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
+ continue;
+ }
+ if( pIdx && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
+ loopAgain = 1;
+ continue;
+ }
+ if( pTerm->wtFlags & TERM_LIKECOND ){
+ /* If the TERM_LIKECOND flag is set, that means that the range search
+ ** is sufficient to guarantee that the LIKE operator is true, so we
+ ** can skip the call to the like(A,B) function. But this only works
+ ** for strings. So do not skip the call to the function on the pass
+ ** that compares BLOBs. */
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
- continue;
+ continue;
#else
- u32 x = pLevel->iLikeRepCntr;
- assert( x>0 );
- skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1));
- VdbeCoverage(v);
+ u32 x = pLevel->iLikeRepCntr;
+ assert( x>0 );
+ skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
+ VdbeCoverage(v);
#endif
+ }
+ sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
+ if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
+ pTerm->wtFlags |= TERM_CODED;
}
- sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
- if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
- pTerm->wtFlags |= TERM_CODED;
- }
+ pIdx = 0;
+ }while( loopAgain );
/* Insert code to test for implied constraints based on transitivity
** of the "==" operator.
@@ -128097,15 +129140,6 @@ static int isLikeOrGlob(
#endif
pList = pExpr->x.pList;
pLeft = pList->a[1].pExpr;
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
- ){
- /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
- ** be the name of an indexed column with TEXT affinity. */
- return 0;
- }
- assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
op = pRight->op;
@@ -128122,6 +129156,23 @@ static int isLikeOrGlob(
z = pRight->u.zToken;
}
if( z ){
+
+ /* If the RHS begins with a digit or a minus sign, then the LHS must
+ ** be an ordinary column (not a virtual table column) with TEXT affinity.
+ ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
+ ** even though "lhs LIKE rhs" is true. But if the RHS does not start
+ ** with a digit or '-', then "lhs LIKE rhs" will always be false if
+ ** the LHS is numeric and so the optimization still works.
+ */
+ if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
+ if( pLeft->op!=TK_COLUMN
+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+ || IsVirtual(pLeft->pTab) /* Value might be numeric */
+ ){
+ sqlite3ValueFree(pVal);
+ return 0;
+ }
+ }
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
@@ -128706,8 +129757,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
** Expression pExpr is one operand of a comparison operator that might
** be useful for indexing. This routine checks to see if pExpr appears
** in any index. Return TRUE (1) if pExpr is an indexed term and return
-** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
-** number of the table that is indexed and *piColumn to the column number
+** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
+** number of the table that is indexed and aiCurCol[1] to the column number
** of the column that is indexed, or XN_EXPR (-2) if an expression is being
** indexed.
**
@@ -128715,18 +129766,37 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
** true even if that particular column is not indexed, because the column
** might be added to an automatic index later.
*/
-static int exprMightBeIndexed(
+static SQLITE_NOINLINE int exprMightBeIndexed2(
SrcList *pFrom, /* The FROM clause */
- int op, /* The specific comparison operator */
Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- Expr *pExpr, /* An operand of a comparison operator */
- int *piCur, /* Write the referenced table cursor number here */
- int *piColumn /* Write the referenced table column number here */
+ int *aiCurCol, /* Write the referenced table cursor and column here */
+ Expr *pExpr /* An operand of a comparison operator */
){
Index *pIdx;
int i;
int iCur;
-
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
+ iCur = pFrom->a[i].iCursor;
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->aColExpr==0 ) continue;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ aiCurCol[0] = iCur;
+ aiCurCol[1] = XN_EXPR;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+static int exprMightBeIndexed(
+ SrcList *pFrom, /* The FROM clause */
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
+ int *aiCurCol, /* Write the referenced table cursor & column here */
+ Expr *pExpr, /* An operand of a comparison operator */
+ int op /* The specific comparison operator */
+){
/* If this expression is a vector to the left or right of a
** inequality constraint (>, <, >= or <=), perform the processing
** on the first element of the vector. */
@@ -128738,26 +129808,13 @@ static int exprMightBeIndexed(
}
if( pExpr->op==TK_COLUMN ){
- *piCur = pExpr->iTable;
- *piColumn = pExpr->iColumn;
+ aiCurCol[0] = pExpr->iTable;
+ aiCurCol[1] = pExpr->iColumn;
return 1;
}
if( mPrereq==0 ) return 0; /* No table references */
if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
- for(i=0; mPrereq>1; i++, mPrereq>>=1){}
- iCur = pFrom->a[i].iCursor;
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->aColExpr==0 ) continue;
- for(i=0; i<pIdx->nKeyCol; i++){
- if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
- if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
- *piCur = iCur;
- *piColumn = XN_EXPR;
- return 1;
- }
- }
- }
- return 0;
+ return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}
/*
@@ -128837,7 +129894,7 @@ static void exprAnalyze(
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) ){
- int iCur, iColumn;
+ int aiCurCol[2];
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
@@ -128848,14 +129905,14 @@ static void exprAnalyze(
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
}
- if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
- pTerm->leftCursor = iCur;
- pTerm->u.leftColumn = iColumn;
+ if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
+ pTerm->leftCursor = aiCurCol[0];
+ pTerm->u.leftColumn = aiCurCol[1];
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
- && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
){
WhereTerm *pNew;
Expr *pDup;
@@ -128885,8 +129942,8 @@ static void exprAnalyze(
pNew = pTerm;
}
exprCommute(pParse, pDup);
- pNew->leftCursor = iCur;
- pNew->u.leftColumn = iColumn;
+ pNew->leftCursor = aiCurCol[0];
+ pNew->u.leftColumn = aiCurCol[1];
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
@@ -129245,11 +130302,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
Bitmask mask;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
- mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
- return mask;
+ return sqlite3WhereGetMask(pMaskSet, p->iTable);
}
+ mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
assert( !ExprHasProperty(p, EP_TokenOnly) );
- mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
+ if( p->pRight ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
@@ -129541,7 +130598,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
if( pTerm->leftCursor==iCur
&& pTerm->u.leftColumn==iColumn
&& (iColumn!=XN_EXPR
- || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
+ || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
+ pScan->pIdxExpr,iCur)==0)
&& (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
){
if( (pTerm->eOperator & WO_EQUIV)!=0
@@ -129848,14 +130906,16 @@ static LogEst estLog(LogEst N){
** value stored in its output register.
*/
static void translateColumnToCopy(
- Vdbe *v, /* The VDBE containing code to translate */
+ Parse *pParse, /* Parsing context */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
int iRegister, /* The first column is in this register */
int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
){
+ Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
int iEnd = sqlite3VdbeCurrentAddr(v);
+ if( pParse->db->mallocFailed ) return;
for(; iStart<iEnd; iStart++, pOp++){
if( pOp->p1!=iTabCur ) continue;
if( pOp->opcode==OP_Column ){
@@ -130133,7 +131193,9 @@ static void constructAutomaticIndex(
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
if( pTabItem->fg.viaCoroutine ){
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
- translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1);
+ testcase( pParse->db->mallocFailed );
+ translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
+ pTabItem->regResult, 1);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
@@ -131113,7 +132175,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
p->u.vtab.idxStr = 0;
}else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
- sqlite3DbFree(db, p->u.btree.pIndex);
+ sqlite3DbFreeNN(db, p->u.btree.pIndex);
p->u.btree.pIndex = 0;
}
}
@@ -131123,7 +132185,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
** Deallocate internal memory used by a WhereLoop object
*/
static void whereLoopClear(sqlite3 *db, WhereLoop *p){
- if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
whereLoopClearUnion(db, p);
whereLoopInit(p);
}
@@ -131138,7 +132200,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
if( paNew==0 ) return SQLITE_NOMEM_BKPT;
memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
- if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
p->aLTerm = paNew;
p->nLSlot = n;
return SQLITE_OK;
@@ -131168,7 +132230,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
*/
static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
whereLoopClear(db, p);
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
/*
@@ -131189,7 +132251,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
pWInfo->pLoops = p->pNextLoop;
whereLoopDelete(db, p);
}
- sqlite3DbFree(db, pWInfo);
+ sqlite3DbFreeNN(db, pWInfo);
}
}
@@ -131718,6 +132780,11 @@ static int whereLoopAddBtreeIndex(
continue;
}
+ if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
+ pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
+ }else{
+ pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
+ }
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
pNew->u.btree.nBtm = saved_nBtm;
@@ -132265,7 +133332,15 @@ static int whereLoopAddBtree(
}
}
+ pBuilder->bldFlags = 0;
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
+ if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
+ /* If a non-unique index is used, or if a prefix of the key for
+ ** unique index is used (making the index functionally non-unique)
+ ** then the sqlite_stat1 data becomes important for scoring the
+ ** plan */
+ pTab->tabFlags |= TF_StatsUsed;
+ }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec);
pBuilder->nRecValid = 0;
@@ -132567,7 +133642,7 @@ static int whereLoopAddVirtual(
}
if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
- sqlite3DbFree(pParse->db, p);
+ sqlite3DbFreeNN(pParse->db, p);
return rc;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -132751,7 +133826,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
}
/*
-** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
+** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
** parameters) to see if it outputs rows in the requested ORDER BY
** (or GROUP BY) without requiring a separate sort operation. Return N:
**
@@ -132846,6 +133921,8 @@ static i8 wherePathSatisfiesOrderBy(
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
if( pLoop->u.vtab.isOrdered ) obSat = obDone;
break;
+ }else{
+ pLoop->u.btree.nIdxCol = 0;
}
iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
@@ -132991,6 +134068,7 @@ static i8 wherePathSatisfiesOrderBy(
if( !pColl ) pColl = db->pDfltColl;
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
}
+ pLoop->u.btree.nIdxCol = j+1;
isMatch = 1;
break;
}
@@ -133422,7 +134500,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( nFrom==0 ){
sqlite3ErrorMsg(pParse, "no query solution");
- sqlite3DbFree(db, pSpace);
+ sqlite3DbFreeNN(db, pSpace);
return SQLITE_ERROR;
}
@@ -133445,9 +134523,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
&& nRowEst
){
Bitmask notUsed;
- int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
- if( rc==pWInfo->pDistinctSet->nExpr ){
+ if( rc==pWInfo->pResultSet->nExpr ){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
}
@@ -133498,7 +134576,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->nRowOut = pFrom->nRow;
/* Free temporary memory and return success */
- sqlite3DbFree(db, pSpace);
+ sqlite3DbFreeNN(db, pSpace);
return SQLITE_OK;
}
@@ -133576,7 +134654,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
if( pLoop->wsFlags ){
pLoop->nOut = (LogEst)1;
pWInfo->a[0].pWLoop = pLoop;
- pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
+ assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] );
+ pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
pWInfo->a[0].iTabCur = iCur;
pWInfo->nRowOut = 1;
if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr;
@@ -133684,7 +134763,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
- ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
+ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
** If WHERE_USE_LIMIT, then the limit amount */
@@ -133760,7 +134839,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
- pWInfo->pDistinctSet = pDistinctSet;
+ pWInfo->pWhere = pWhere;
+ pWInfo->pResultSet = pResultSet;
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
@@ -133838,13 +134918,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( db->mallocFailed ) goto whereBeginError;
if( wctrlFlags & WHERE_WANT_DISTINCT ){
- if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
+ if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
/* The DISTINCT marking is pointless. Ignore it. */
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}else if( pOrderBy==0 ){
/* Try to ORDER BY the result set to make distinct processing easier */
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
- pWInfo->pOrderBy = pDistinctSet;
+ pWInfo->pOrderBy = pResultSet;
}
}
@@ -133920,10 +135000,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
#endif
/* Attempt to omit tables from the join that do not effect the result */
if( pWInfo->nLevel>=2
- && pDistinctSet!=0
+ && pResultSet!=0
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
- Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
+ Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
@@ -134070,6 +135150,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
+ && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
){
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
}
@@ -134158,14 +135239,43 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
int addr;
pLevel = &pWInfo->a[i];
pLoop = pLevel->pWLoop;
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
if( pLevel->op!=OP_Noop ){
+#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
+ int addrSeek = 0;
+ Index *pIdx;
+ int n;
+ if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
+ && (pLoop->wsFlags & WHERE_INDEXED)!=0
+ && (pIdx = pLoop->u.btree.pIndex)->hasStat1
+ && (n = pLoop->u.btree.nIdxCol)>0
+ && pIdx->aiRowLogEst[n]>=36
+ ){
+ int r1 = pParse->nMem+1;
+ int j, op;
+ for(j=0; j<n; j++){
+ sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
+ }
+ pParse->nMem += n+1;
+ op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
+ addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
+ VdbeCoverageIf(v, op==OP_SeekLT);
+ VdbeCoverageIf(v, op==OP_SeekGT);
+ sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
+ }
+#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
+ /* The common case: Advance to the next row */
+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
VdbeCoverageIf(v, pLevel->op==OP_Next);
VdbeCoverageIf(v, pLevel->op==OP_Prev);
VdbeCoverageIf(v, pLevel->op==OP_VNext);
+#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
+ if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
+#endif
+ }else{
+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
}
if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
@@ -134238,8 +135348,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** the co-routine into OP_Copy of result contained in a register.
** OP_Rowid becomes OP_Null.
*/
- if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
- translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
+ if( pTabItem->fg.viaCoroutine ){
+ testcase( pParse->db->mallocFailed );
+ translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
pTabItem->regResult, 0);
continue;
}
@@ -134287,6 +135398,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
+ }else if( pOp->opcode==OP_IfNullRow ){
+ pOp->p1 = pLevel->iIdxCur;
}
}
}
@@ -134596,7 +135709,7 @@ static void disableLookaside(Parse *pParse){
#define YYCODETYPE unsigned char
#define YYNOCODE 252
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 96
+#define YYWILDCARD 69
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
@@ -134703,462 +135816,462 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (1567)
+#define YY_ACTTAB_COUNT (1566)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100,
- /* 10 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98,
- /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95,
- /* 30 */ 94, 94, 94, 93, 351, 325, 977, 977, 824, 824,
- /* 40 */ 826, 947, 354, 99, 100, 90, 842, 842, 854, 857,
- /* 50 */ 846, 846, 97, 97, 98, 98, 98, 98, 338, 96,
- /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
- /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 977, 977,
- /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100,
- /* 90 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98,
- /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95,
- /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325,
- /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90,
- /* 130 */ 842, 842, 854, 857, 846, 846, 97, 97, 98, 98,
- /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94,
- /* 150 */ 94, 94, 93, 351, 958, 958, 325, 268, 428, 413,
- /* 160 */ 411, 61, 752, 752, 99, 100, 90, 842, 842, 854,
- /* 170 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 60,
- /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 190 */ 351, 325, 270, 329, 273, 277, 959, 960, 250, 99,
- /* 200 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
- /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95,
- /* 220 */ 95, 94, 94, 94, 93, 351, 325, 938, 1326, 698,
- /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 842, 842, 854,
- /* 240 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 347,
- /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 260 */ 351, 325, 938, 1327, 384, 699, 1327, 381, 379, 99,
- /* 270 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
- /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95,
- /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178,
- /* 300 */ 833, 936, 373, 700, 99, 100, 90, 842, 842, 854,
- /* 310 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 375,
- /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 330 */ 351, 325, 1276, 947, 354, 818, 936, 739, 739, 99,
- /* 340 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
- /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95,
- /* 360 */ 95, 94, 94, 94, 93, 351, 325, 969, 227, 92,
- /* 370 */ 89, 178, 373, 300, 99, 100, 90, 842, 842, 854,
- /* 380 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 921,
- /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99,
- /* 410 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97,
- /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95,
- /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 958,
- /* 440 */ 958, 158, 25, 422, 99, 100, 90, 842, 842, 854,
- /* 450 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 450,
- /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 470 */ 351, 443, 224, 224, 420, 958, 958, 962, 325, 52,
- /* 480 */ 52, 959, 960, 176, 415, 78, 99, 100, 90, 842,
- /* 490 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98,
- /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94,
- /* 510 */ 94, 93, 351, 325, 428, 418, 298, 959, 960, 962,
- /* 520 */ 81, 99, 88, 90, 842, 842, 854, 857, 846, 846,
- /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96,
- /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 843,
- /* 550 */ 843, 855, 858, 996, 318, 343, 379, 100, 90, 842,
- /* 560 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98,
- /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94,
- /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340,
- /* 590 */ 929, 52, 52, 90, 842, 842, 854, 857, 846, 846,
- /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96,
- /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445,
- /* 620 */ 847, 3, 1203, 361, 360, 378, 344, 813, 958, 958,
- /* 630 */ 1300, 86, 445, 729, 3, 212, 169, 287, 405, 282,
- /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245,
- /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83,
- /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246,
- /* 670 */ 959, 960, 194, 455, 670, 402, 399, 398, 448, 243,
- /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224,
- /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427,
- /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452,
- /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1271,
- /* 720 */ 1271, 23, 958, 958, 86, 445, 397, 3, 228, 429,
- /* 730 */ 895, 824, 824, 826, 827, 19, 203, 720, 52, 52,
- /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229,
- /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85,
- /* 760 */ 352, 352, 120, 157, 959, 960, 58, 977, 409, 355,
- /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86,
- /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96,
- /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
- /* 800 */ 832, 120, 452, 451, 813, 887, 819, 83, 84, 977,
- /* 810 */ 813, 132, 410, 920, 85, 352, 352, 132, 407, 789,
- /* 820 */ 958, 958, 92, 89, 178, 917, 448, 262, 370, 261,
- /* 830 */ 82, 914, 80, 262, 370, 261, 776, 824, 824, 826,
- /* 840 */ 827, 19, 934, 434, 96, 96, 96, 96, 95, 95,
- /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 958,
- /* 860 */ 958, 819, 959, 960, 120, 92, 89, 178, 945, 2,
- /* 870 */ 918, 965, 268, 1, 976, 76, 445, 762, 3, 708,
- /* 880 */ 901, 901, 387, 958, 958, 757, 919, 371, 740, 778,
- /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450,
- /* 900 */ 24, 959, 960, 83, 84, 369, 958, 958, 177, 226,
- /* 910 */ 85, 352, 352, 885, 315, 314, 313, 215, 311, 10,
- /* 920 */ 10, 683, 448, 349, 348, 959, 960, 909, 777, 157,
- /* 930 */ 120, 958, 958, 337, 776, 416, 711, 310, 450, 434,
- /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 959, 960,
- /* 950 */ 908, 832, 792, 452, 451, 9, 9, 819, 10, 10,
- /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171,
- /* 970 */ 170, 167, 339, 959, 960, 247, 984, 702, 702, 450,
- /* 980 */ 715, 233, 686, 982, 889, 983, 182, 914, 824, 824,
- /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10,
- /* 1000 */ 10, 889, 891, 749, 958, 958, 917, 268, 985, 198,
- /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825,
- /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91,
- /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 1040 */ 351, 157, 810, 371, 382, 359, 959, 960, 358, 268,
- /* 1050 */ 450, 918, 368, 324, 824, 824, 826, 450, 709, 450,
- /* 1060 */ 264, 380, 889, 450, 877, 746, 253, 919, 255, 433,
- /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12,
- /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162,
- /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450,
- /* 1100 */ 709, 1210, 450, 132, 450, 39, 39, 450, 40, 40,
- /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28,
- /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450,
- /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767,
- /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47,
- /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172,
- /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122,
- /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 898, 56, 56,
- /* 1180 */ 450, 897, 35, 35, 450, 267, 450, 817, 450, 817,
- /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817,
- /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119,
- /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111,
- /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 912,
- /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331,
- /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 937, 197,
- /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436,
- /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 933,
- /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202,
- /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 884,
- /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74,
- /* 1300 */ 726, 727, 785, 783, 880, 202, 999, 208, 894, 893,
- /* 1310 */ 894, 893, 694, 816, 763, 116, 774, 1290, 431, 432,
- /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289,
- /* 1330 */ 679, 884, 681, 952, 291, 218, 293, 7, 316, 828,
- /* 1340 */ 173, 805, 259, 364, 252, 911, 376, 713, 295, 435,
- /* 1350 */ 308, 168, 955, 993, 135, 400, 990, 284, 882, 881,
- /* 1360 */ 205, 928, 926, 59, 333, 62, 144, 156, 130, 72,
- /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383,
- /* 1380 */ 67, 896, 140, 141, 142, 148, 389, 812, 775, 266,
- /* 1390 */ 219, 190, 154, 391, 913, 876, 271, 406, 191, 322,
- /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421,
- /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346,
- /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 967, 239,
- /* 1430 */ 769, 102, 862, 438, 426, 240, 424, 442, 73, 213,
- /* 1440 */ 688, 238, 22, 453, 953, 214, 217, 216, 454, 677,
- /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166,
- /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 892,
- /* 1470 */ 327, 890, 811, 328, 134, 128, 136, 138, 743, 258,
- /* 1480 */ 907, 184, 143, 129, 910, 186, 63, 64, 145, 187,
- /* 1490 */ 906, 65, 8, 66, 13, 188, 202, 899, 265, 149,
- /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396,
- /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131,
- /* 1520 */ 830, 860, 70, 751, 16, 414, 755, 4, 174, 220,
- /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 875,
- /* 1540 */ 861, 859, 916, 864, 915, 207, 206, 942, 163, 437,
- /* 1550 */ 948, 943, 164, 209, 1002, 441, 863, 165, 210, 829,
- /* 1560 */ 695, 87, 312, 211, 1292, 1291, 309,
+ /* 0 */ 325, 411, 343, 752, 752, 203, 946, 354, 976, 98,
+ /* 10 */ 98, 98, 98, 91, 96, 96, 96, 96, 95, 95,
+ /* 20 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 813,
+ /* 30 */ 978, 978, 98, 98, 98, 98, 20, 96, 96, 96,
+ /* 40 */ 96, 95, 95, 94, 94, 94, 93, 351, 92, 89,
+ /* 50 */ 178, 99, 100, 90, 853, 856, 845, 845, 97, 97,
+ /* 60 */ 98, 98, 98, 98, 351, 96, 96, 96, 96, 95,
+ /* 70 */ 95, 94, 94, 94, 93, 351, 325, 340, 976, 262,
+ /* 80 */ 365, 251, 212, 169, 287, 405, 282, 404, 199, 791,
+ /* 90 */ 242, 412, 21, 957, 379, 280, 93, 351, 792, 95,
+ /* 100 */ 95, 94, 94, 94, 93, 351, 978, 978, 96, 96,
+ /* 110 */ 96, 96, 95, 95, 94, 94, 94, 93, 351, 813,
+ /* 120 */ 329, 242, 412, 913, 832, 913, 132, 99, 100, 90,
+ /* 130 */ 853, 856, 845, 845, 97, 97, 98, 98, 98, 98,
+ /* 140 */ 450, 96, 96, 96, 96, 95, 95, 94, 94, 94,
+ /* 150 */ 93, 351, 325, 825, 349, 348, 120, 819, 120, 75,
+ /* 160 */ 52, 52, 957, 958, 959, 760, 984, 146, 361, 262,
+ /* 170 */ 370, 261, 957, 982, 961, 983, 92, 89, 178, 371,
+ /* 180 */ 230, 371, 978, 978, 817, 361, 360, 101, 824, 824,
+ /* 190 */ 826, 384, 24, 964, 381, 428, 413, 369, 985, 380,
+ /* 200 */ 985, 708, 325, 99, 100, 90, 853, 856, 845, 845,
+ /* 210 */ 97, 97, 98, 98, 98, 98, 373, 96, 96, 96,
+ /* 220 */ 96, 95, 95, 94, 94, 94, 93, 351, 957, 132,
+ /* 230 */ 897, 450, 978, 978, 896, 60, 94, 94, 94, 93,
+ /* 240 */ 351, 957, 958, 959, 961, 103, 361, 957, 385, 334,
+ /* 250 */ 702, 52, 52, 99, 100, 90, 853, 856, 845, 845,
+ /* 260 */ 97, 97, 98, 98, 98, 98, 698, 96, 96, 96,
+ /* 270 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 455,
+ /* 280 */ 670, 450, 227, 61, 157, 243, 344, 114, 701, 888,
+ /* 290 */ 147, 832, 957, 373, 747, 957, 320, 957, 958, 959,
+ /* 300 */ 194, 10, 10, 402, 399, 398, 888, 890, 978, 978,
+ /* 310 */ 762, 171, 170, 157, 397, 337, 957, 958, 959, 702,
+ /* 320 */ 825, 310, 153, 957, 819, 321, 82, 23, 80, 99,
+ /* 330 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98,
+ /* 340 */ 98, 98, 894, 96, 96, 96, 96, 95, 95, 94,
+ /* 350 */ 94, 94, 93, 351, 325, 824, 824, 826, 277, 231,
+ /* 360 */ 300, 957, 958, 959, 957, 958, 959, 888, 194, 25,
+ /* 370 */ 450, 402, 399, 398, 957, 355, 300, 450, 957, 74,
+ /* 380 */ 450, 1, 397, 132, 978, 978, 957, 224, 224, 813,
+ /* 390 */ 10, 10, 957, 958, 959, 968, 132, 52, 52, 415,
+ /* 400 */ 52, 52, 739, 739, 339, 99, 100, 90, 853, 856,
+ /* 410 */ 845, 845, 97, 97, 98, 98, 98, 98, 790, 96,
+ /* 420 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
+ /* 430 */ 325, 789, 428, 418, 706, 428, 427, 1270, 1270, 262,
+ /* 440 */ 370, 261, 957, 957, 958, 959, 757, 957, 958, 959,
+ /* 450 */ 450, 756, 450, 734, 713, 957, 958, 959, 443, 711,
+ /* 460 */ 978, 978, 734, 394, 92, 89, 178, 447, 447, 447,
+ /* 470 */ 51, 51, 52, 52, 439, 778, 700, 92, 89, 178,
+ /* 480 */ 172, 99, 100, 90, 853, 856, 845, 845, 97, 97,
+ /* 490 */ 98, 98, 98, 98, 198, 96, 96, 96, 96, 95,
+ /* 500 */ 95, 94, 94, 94, 93, 351, 325, 428, 408, 916,
+ /* 510 */ 699, 957, 958, 959, 92, 89, 178, 224, 224, 157,
+ /* 520 */ 241, 221, 419, 299, 776, 917, 416, 375, 450, 415,
+ /* 530 */ 58, 324, 737, 737, 920, 379, 978, 978, 379, 777,
+ /* 540 */ 449, 918, 363, 740, 296, 686, 9, 9, 52, 52,
+ /* 550 */ 234, 330, 234, 256, 417, 741, 280, 99, 100, 90,
+ /* 560 */ 853, 856, 845, 845, 97, 97, 98, 98, 98, 98,
+ /* 570 */ 450, 96, 96, 96, 96, 95, 95, 94, 94, 94,
+ /* 580 */ 93, 351, 325, 423, 72, 450, 833, 120, 368, 450,
+ /* 590 */ 10, 10, 5, 301, 203, 450, 177, 976, 253, 420,
+ /* 600 */ 255, 776, 200, 175, 233, 10, 10, 842, 842, 36,
+ /* 610 */ 36, 1299, 978, 978, 729, 37, 37, 349, 348, 425,
+ /* 620 */ 203, 260, 776, 976, 232, 937, 1326, 876, 338, 1326,
+ /* 630 */ 422, 854, 857, 99, 100, 90, 853, 856, 845, 845,
+ /* 640 */ 97, 97, 98, 98, 98, 98, 268, 96, 96, 96,
+ /* 650 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 846,
+ /* 660 */ 450, 985, 818, 985, 1209, 450, 916, 976, 720, 350,
+ /* 670 */ 350, 350, 935, 177, 450, 937, 1327, 254, 198, 1327,
+ /* 680 */ 12, 12, 917, 403, 450, 27, 27, 250, 978, 978,
+ /* 690 */ 118, 721, 162, 976, 38, 38, 268, 176, 918, 776,
+ /* 700 */ 433, 1275, 946, 354, 39, 39, 317, 998, 325, 99,
+ /* 710 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98,
+ /* 720 */ 98, 98, 935, 96, 96, 96, 96, 95, 95, 94,
+ /* 730 */ 94, 94, 93, 351, 450, 330, 450, 358, 978, 978,
+ /* 740 */ 717, 317, 936, 341, 900, 900, 387, 673, 674, 675,
+ /* 750 */ 275, 996, 318, 999, 40, 40, 41, 41, 268, 99,
+ /* 760 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98,
+ /* 770 */ 98, 98, 450, 96, 96, 96, 96, 95, 95, 94,
+ /* 780 */ 94, 94, 93, 351, 325, 450, 356, 450, 999, 450,
+ /* 790 */ 692, 331, 42, 42, 791, 270, 450, 273, 450, 228,
+ /* 800 */ 450, 298, 450, 792, 450, 28, 28, 29, 29, 31,
+ /* 810 */ 31, 450, 817, 450, 978, 978, 43, 43, 44, 44,
+ /* 820 */ 45, 45, 11, 11, 46, 46, 893, 78, 893, 268,
+ /* 830 */ 268, 105, 105, 47, 47, 99, 100, 90, 853, 856,
+ /* 840 */ 845, 845, 97, 97, 98, 98, 98, 98, 450, 96,
+ /* 850 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
+ /* 860 */ 325, 450, 117, 450, 749, 158, 450, 696, 48, 48,
+ /* 870 */ 229, 919, 450, 928, 450, 415, 450, 335, 450, 245,
+ /* 880 */ 450, 33, 33, 49, 49, 450, 50, 50, 246, 817,
+ /* 890 */ 978, 978, 34, 34, 122, 122, 123, 123, 124, 124,
+ /* 900 */ 56, 56, 268, 81, 249, 35, 35, 197, 196, 195,
+ /* 910 */ 325, 99, 100, 90, 853, 856, 845, 845, 97, 97,
+ /* 920 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95,
+ /* 930 */ 95, 94, 94, 94, 93, 351, 450, 696, 450, 817,
+ /* 940 */ 978, 978, 975, 884, 106, 106, 268, 886, 268, 944,
+ /* 950 */ 2, 892, 268, 892, 336, 716, 53, 53, 107, 107,
+ /* 960 */ 325, 99, 100, 90, 853, 856, 845, 845, 97, 97,
+ /* 970 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95,
+ /* 980 */ 95, 94, 94, 94, 93, 351, 450, 746, 450, 742,
+ /* 990 */ 978, 978, 715, 267, 108, 108, 446, 331, 332, 133,
+ /* 1000 */ 223, 175, 301, 225, 386, 933, 104, 104, 121, 121,
+ /* 1010 */ 325, 99, 88, 90, 853, 856, 845, 845, 97, 97,
+ /* 1020 */ 98, 98, 98, 98, 817, 96, 96, 96, 96, 95,
+ /* 1030 */ 95, 94, 94, 94, 93, 351, 450, 347, 450, 167,
+ /* 1040 */ 978, 978, 932, 815, 372, 319, 202, 202, 374, 263,
+ /* 1050 */ 395, 202, 74, 208, 726, 727, 119, 119, 112, 112,
+ /* 1060 */ 325, 407, 100, 90, 853, 856, 845, 845, 97, 97,
+ /* 1070 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95,
+ /* 1080 */ 95, 94, 94, 94, 93, 351, 450, 757, 450, 345,
+ /* 1090 */ 978, 978, 756, 278, 111, 111, 74, 719, 718, 709,
+ /* 1100 */ 286, 883, 754, 1289, 257, 77, 109, 109, 110, 110,
+ /* 1110 */ 908, 285, 810, 90, 853, 856, 845, 845, 97, 97,
+ /* 1120 */ 98, 98, 98, 98, 911, 96, 96, 96, 96, 95,
+ /* 1130 */ 95, 94, 94, 94, 93, 351, 86, 445, 450, 3,
+ /* 1140 */ 1202, 450, 745, 132, 352, 120, 689, 86, 445, 785,
+ /* 1150 */ 3, 767, 202, 377, 448, 352, 907, 120, 55, 55,
+ /* 1160 */ 450, 57, 57, 828, 879, 448, 450, 208, 450, 709,
+ /* 1170 */ 450, 883, 237, 434, 436, 120, 440, 429, 362, 120,
+ /* 1180 */ 54, 54, 132, 450, 434, 832, 52, 52, 26, 26,
+ /* 1190 */ 30, 30, 382, 132, 409, 444, 832, 694, 264, 390,
+ /* 1200 */ 116, 269, 272, 32, 32, 83, 84, 120, 274, 120,
+ /* 1210 */ 120, 276, 85, 352, 452, 451, 83, 84, 819, 730,
+ /* 1220 */ 714, 428, 430, 85, 352, 452, 451, 120, 120, 819,
+ /* 1230 */ 378, 218, 281, 828, 783, 816, 86, 445, 410, 3,
+ /* 1240 */ 763, 774, 431, 432, 352, 302, 303, 823, 697, 824,
+ /* 1250 */ 824, 826, 827, 19, 448, 691, 680, 679, 681, 951,
+ /* 1260 */ 824, 824, 826, 827, 19, 289, 159, 291, 293, 7,
+ /* 1270 */ 316, 173, 259, 434, 805, 364, 252, 910, 376, 713,
+ /* 1280 */ 295, 435, 168, 993, 400, 832, 284, 881, 880, 205,
+ /* 1290 */ 954, 308, 927, 86, 445, 990, 3, 925, 333, 144,
+ /* 1300 */ 130, 352, 72, 135, 59, 83, 84, 761, 137, 366,
+ /* 1310 */ 802, 448, 85, 352, 452, 451, 139, 226, 819, 140,
+ /* 1320 */ 156, 62, 315, 314, 313, 215, 311, 367, 393, 683,
+ /* 1330 */ 434, 185, 141, 912, 142, 160, 148, 812, 875, 383,
+ /* 1340 */ 189, 67, 832, 180, 389, 248, 895, 775, 219, 824,
+ /* 1350 */ 824, 826, 827, 19, 247, 190, 266, 154, 391, 271,
+ /* 1360 */ 191, 192, 83, 84, 682, 406, 733, 182, 322, 85,
+ /* 1370 */ 352, 452, 451, 732, 183, 819, 342, 132, 181, 711,
+ /* 1380 */ 731, 421, 76, 445, 705, 3, 323, 704, 283, 724,
+ /* 1390 */ 352, 771, 703, 966, 723, 71, 204, 6, 288, 290,
+ /* 1400 */ 448, 772, 770, 769, 79, 292, 824, 824, 826, 827,
+ /* 1410 */ 19, 294, 297, 438, 346, 442, 102, 861, 753, 434,
+ /* 1420 */ 238, 426, 73, 305, 239, 304, 326, 240, 424, 306,
+ /* 1430 */ 307, 832, 213, 688, 22, 952, 453, 214, 216, 217,
+ /* 1440 */ 454, 677, 115, 676, 671, 125, 126, 235, 127, 669,
+ /* 1450 */ 327, 83, 84, 359, 353, 244, 166, 328, 85, 352,
+ /* 1460 */ 452, 451, 134, 179, 819, 357, 113, 891, 811, 889,
+ /* 1470 */ 136, 128, 138, 743, 258, 184, 906, 143, 145, 63,
+ /* 1480 */ 64, 65, 66, 129, 909, 905, 187, 186, 8, 13,
+ /* 1490 */ 188, 265, 898, 149, 202, 824, 824, 826, 827, 19,
+ /* 1500 */ 388, 987, 150, 161, 285, 685, 392, 396, 151, 722,
+ /* 1510 */ 193, 68, 14, 401, 279, 15, 69, 236, 831, 830,
+ /* 1520 */ 131, 859, 751, 70, 16, 414, 755, 4, 784, 220,
+ /* 1530 */ 222, 174, 152, 437, 779, 201, 17, 77, 74, 18,
+ /* 1540 */ 874, 860, 858, 915, 863, 914, 207, 206, 941, 163,
+ /* 1550 */ 210, 942, 209, 164, 441, 862, 165, 211, 829, 695,
+ /* 1560 */ 87, 312, 309, 947, 1291, 1290,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28,
- /* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- /* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
- /* 30 */ 49, 50, 51, 52, 53, 19, 55, 55, 132, 133,
- /* 40 */ 134, 1, 2, 27, 28, 29, 30, 31, 32, 33,
- /* 50 */ 34, 35, 36, 37, 38, 39, 40, 41, 187, 43,
- /* 60 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 70 */ 47, 48, 49, 50, 51, 52, 53, 61, 97, 97,
- /* 80 */ 19, 49, 50, 51, 52, 53, 70, 26, 27, 28,
- /* 90 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- /* 100 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
- /* 110 */ 49, 50, 51, 52, 53, 144, 145, 146, 147, 19,
- /* 120 */ 16, 22, 92, 172, 173, 52, 53, 27, 28, 29,
- /* 130 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- /* 140 */ 40, 41, 81, 43, 44, 45, 46, 47, 48, 49,
- /* 150 */ 50, 51, 52, 53, 55, 56, 19, 152, 207, 208,
- /* 160 */ 115, 24, 117, 118, 27, 28, 29, 30, 31, 32,
- /* 170 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 79,
- /* 180 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 190 */ 53, 19, 88, 157, 90, 23, 97, 98, 193, 27,
- /* 200 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- /* 210 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47,
- /* 220 */ 48, 49, 50, 51, 52, 53, 19, 22, 23, 172,
- /* 230 */ 23, 26, 119, 120, 27, 28, 29, 30, 31, 32,
- /* 240 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 187,
- /* 250 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 260 */ 53, 19, 22, 23, 228, 23, 26, 231, 152, 27,
- /* 270 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- /* 280 */ 38, 39, 40, 41, 172, 43, 44, 45, 46, 47,
- /* 290 */ 48, 49, 50, 51, 52, 53, 19, 221, 222, 223,
- /* 300 */ 23, 96, 152, 172, 27, 28, 29, 30, 31, 32,
- /* 310 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152,
- /* 320 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 330 */ 53, 19, 0, 1, 2, 23, 96, 190, 191, 27,
- /* 340 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- /* 350 */ 38, 39, 40, 41, 238, 43, 44, 45, 46, 47,
- /* 360 */ 48, 49, 50, 51, 52, 53, 19, 185, 218, 221,
- /* 370 */ 222, 223, 152, 152, 27, 28, 29, 30, 31, 32,
- /* 380 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 241,
- /* 390 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 400 */ 53, 19, 152, 168, 169, 170, 22, 190, 191, 27,
- /* 410 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- /* 420 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47,
- /* 430 */ 48, 49, 50, 51, 52, 53, 19, 19, 218, 55,
- /* 440 */ 56, 24, 22, 152, 27, 28, 29, 30, 31, 32,
- /* 450 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152,
- /* 460 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 470 */ 53, 250, 194, 195, 56, 55, 56, 55, 19, 172,
- /* 480 */ 173, 97, 98, 152, 206, 138, 27, 28, 29, 30,
- /* 490 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- /* 500 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 510 */ 51, 52, 53, 19, 207, 208, 152, 97, 98, 97,
- /* 520 */ 138, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- /* 530 */ 36, 37, 38, 39, 40, 41, 181, 43, 44, 45,
- /* 540 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 30,
- /* 550 */ 31, 32, 33, 247, 248, 19, 152, 28, 29, 30,
- /* 560 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- /* 570 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 580 */ 51, 52, 53, 19, 168, 169, 170, 238, 19, 53,
- /* 590 */ 152, 172, 173, 29, 30, 31, 32, 33, 34, 35,
- /* 600 */ 36, 37, 38, 39, 40, 41, 152, 43, 44, 45,
- /* 610 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 20,
- /* 620 */ 101, 22, 23, 169, 170, 56, 207, 85, 55, 56,
- /* 630 */ 23, 19, 20, 26, 22, 99, 100, 101, 102, 103,
- /* 640 */ 104, 105, 238, 152, 152, 210, 47, 48, 112, 152,
- /* 650 */ 108, 109, 110, 54, 55, 56, 221, 222, 223, 47,
- /* 660 */ 48, 119, 120, 172, 173, 66, 54, 55, 56, 152,
- /* 670 */ 97, 98, 99, 148, 149, 102, 103, 104, 66, 154,
- /* 680 */ 23, 156, 83, 26, 230, 152, 113, 152, 163, 194,
- /* 690 */ 195, 92, 92, 30, 95, 83, 97, 98, 207, 208,
- /* 700 */ 101, 206, 179, 180, 92, 172, 173, 95, 152, 97,
- /* 710 */ 98, 188, 99, 101, 219, 102, 103, 104, 152, 119,
- /* 720 */ 120, 196, 55, 56, 19, 20, 113, 22, 193, 163,
- /* 730 */ 11, 132, 133, 134, 135, 136, 24, 65, 172, 173,
- /* 740 */ 207, 208, 250, 152, 132, 133, 134, 135, 136, 193,
- /* 750 */ 78, 84, 47, 48, 49, 98, 199, 152, 86, 54,
- /* 760 */ 55, 56, 196, 152, 97, 98, 209, 55, 163, 244,
- /* 770 */ 107, 66, 152, 207, 208, 164, 175, 172, 173, 19,
- /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43,
- /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97,
- /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175,
- /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110,
- /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134,
- /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48,
- /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55,
- /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147,
- /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179,
- /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124,
- /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152,
- /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5,
- /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172,
- /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152,
- /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83,
- /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98,
- /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173,
- /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47,
- /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152,
- /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133,
- /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172,
- /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30,
- /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97,
- /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42,
- /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152,
- /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152,
- /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75,
- /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172,
- /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24,
- /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152,
- /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173,
- /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172,
- /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152,
- /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213,
- /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172,
- /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26,
- /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173,
- /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173,
- /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152,
- /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152,
- /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173,
- /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173,
- /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163,
- /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167,
- /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108,
- /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163,
- /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23,
- /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26,
- /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55,
- /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26,
- /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132,
- /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191,
- /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210,
- /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97,
- /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227,
- /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175,
- /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130,
- /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159,
- /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235,
- /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177,
- /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125,
- /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53,
- /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229,
- /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25,
- /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151,
- /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22,
- /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23,
- /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16,
- /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122,
- /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80,
- /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79,
- /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68,
- /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23,
- /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23,
- /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24,
- /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23,
- /* 1560 */ 23, 22, 15, 122, 122, 122, 23,
+ /* 0 */ 19, 115, 19, 117, 118, 24, 1, 2, 27, 79,
+ /* 10 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ /* 20 */ 90, 91, 92, 93, 94, 144, 145, 146, 147, 58,
+ /* 30 */ 49, 50, 79, 80, 81, 82, 22, 84, 85, 86,
+ /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 221, 222,
+ /* 50 */ 223, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 60 */ 79, 80, 81, 82, 94, 84, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 91, 92, 93, 94, 19, 94, 97, 108,
+ /* 80 */ 109, 110, 99, 100, 101, 102, 103, 104, 105, 32,
+ /* 90 */ 119, 120, 78, 27, 152, 112, 93, 94, 41, 88,
+ /* 100 */ 89, 90, 91, 92, 93, 94, 49, 50, 84, 85,
+ /* 110 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 58,
+ /* 120 */ 157, 119, 120, 163, 68, 163, 65, 70, 71, 72,
+ /* 130 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ /* 140 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 150 */ 93, 94, 19, 97, 88, 89, 196, 101, 196, 26,
+ /* 160 */ 172, 173, 96, 97, 98, 210, 100, 22, 152, 108,
+ /* 170 */ 109, 110, 27, 107, 27, 109, 221, 222, 223, 219,
+ /* 180 */ 238, 219, 49, 50, 152, 169, 170, 54, 132, 133,
+ /* 190 */ 134, 228, 232, 171, 231, 207, 208, 237, 132, 237,
+ /* 200 */ 134, 179, 19, 70, 71, 72, 73, 74, 75, 76,
+ /* 210 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86,
+ /* 220 */ 87, 88, 89, 90, 91, 92, 93, 94, 27, 65,
+ /* 230 */ 30, 152, 49, 50, 34, 52, 90, 91, 92, 93,
+ /* 240 */ 94, 96, 97, 98, 97, 22, 230, 27, 48, 217,
+ /* 250 */ 27, 172, 173, 70, 71, 72, 73, 74, 75, 76,
+ /* 260 */ 77, 78, 79, 80, 81, 82, 172, 84, 85, 86,
+ /* 270 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 148,
+ /* 280 */ 149, 152, 218, 24, 152, 154, 207, 156, 172, 152,
+ /* 290 */ 22, 68, 27, 152, 163, 27, 164, 96, 97, 98,
+ /* 300 */ 99, 172, 173, 102, 103, 104, 169, 170, 49, 50,
+ /* 310 */ 90, 88, 89, 152, 113, 186, 96, 97, 98, 96,
+ /* 320 */ 97, 160, 57, 27, 101, 164, 137, 196, 139, 70,
+ /* 330 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 340 */ 81, 82, 11, 84, 85, 86, 87, 88, 89, 90,
+ /* 350 */ 91, 92, 93, 94, 19, 132, 133, 134, 23, 218,
+ /* 360 */ 152, 96, 97, 98, 96, 97, 98, 230, 99, 22,
+ /* 370 */ 152, 102, 103, 104, 27, 244, 152, 152, 27, 26,
+ /* 380 */ 152, 22, 113, 65, 49, 50, 27, 194, 195, 58,
+ /* 390 */ 172, 173, 96, 97, 98, 185, 65, 172, 173, 206,
+ /* 400 */ 172, 173, 190, 191, 186, 70, 71, 72, 73, 74,
+ /* 410 */ 75, 76, 77, 78, 79, 80, 81, 82, 175, 84,
+ /* 420 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ /* 430 */ 19, 175, 207, 208, 23, 207, 208, 119, 120, 108,
+ /* 440 */ 109, 110, 27, 96, 97, 98, 116, 96, 97, 98,
+ /* 450 */ 152, 121, 152, 179, 180, 96, 97, 98, 250, 106,
+ /* 460 */ 49, 50, 188, 19, 221, 222, 223, 168, 169, 170,
+ /* 470 */ 172, 173, 172, 173, 250, 124, 172, 221, 222, 223,
+ /* 480 */ 26, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 490 */ 79, 80, 81, 82, 50, 84, 85, 86, 87, 88,
+ /* 500 */ 89, 90, 91, 92, 93, 94, 19, 207, 208, 12,
+ /* 510 */ 23, 96, 97, 98, 221, 222, 223, 194, 195, 152,
+ /* 520 */ 199, 23, 19, 225, 26, 28, 152, 152, 152, 206,
+ /* 530 */ 209, 164, 190, 191, 241, 152, 49, 50, 152, 124,
+ /* 540 */ 152, 44, 219, 46, 152, 21, 172, 173, 172, 173,
+ /* 550 */ 183, 107, 185, 16, 163, 58, 112, 70, 71, 72,
+ /* 560 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ /* 570 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 580 */ 93, 94, 19, 207, 130, 152, 23, 196, 64, 152,
+ /* 590 */ 172, 173, 22, 152, 24, 152, 98, 27, 61, 96,
+ /* 600 */ 63, 26, 211, 212, 186, 172, 173, 49, 50, 172,
+ /* 610 */ 173, 23, 49, 50, 26, 172, 173, 88, 89, 186,
+ /* 620 */ 24, 238, 124, 27, 238, 22, 23, 103, 187, 26,
+ /* 630 */ 152, 73, 74, 70, 71, 72, 73, 74, 75, 76,
+ /* 640 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86,
+ /* 650 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 101,
+ /* 660 */ 152, 132, 23, 134, 140, 152, 12, 97, 36, 168,
+ /* 670 */ 169, 170, 69, 98, 152, 22, 23, 140, 50, 26,
+ /* 680 */ 172, 173, 28, 51, 152, 172, 173, 193, 49, 50,
+ /* 690 */ 22, 59, 24, 97, 172, 173, 152, 152, 44, 124,
+ /* 700 */ 46, 0, 1, 2, 172, 173, 22, 23, 19, 70,
+ /* 710 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 720 */ 81, 82, 69, 84, 85, 86, 87, 88, 89, 90,
+ /* 730 */ 91, 92, 93, 94, 152, 107, 152, 193, 49, 50,
+ /* 740 */ 181, 22, 23, 111, 108, 109, 110, 7, 8, 9,
+ /* 750 */ 16, 247, 248, 69, 172, 173, 172, 173, 152, 70,
+ /* 760 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 770 */ 81, 82, 152, 84, 85, 86, 87, 88, 89, 90,
+ /* 780 */ 91, 92, 93, 94, 19, 152, 242, 152, 69, 152,
+ /* 790 */ 166, 167, 172, 173, 32, 61, 152, 63, 152, 193,
+ /* 800 */ 152, 152, 152, 41, 152, 172, 173, 172, 173, 172,
+ /* 810 */ 173, 152, 152, 152, 49, 50, 172, 173, 172, 173,
+ /* 820 */ 172, 173, 172, 173, 172, 173, 132, 138, 134, 152,
+ /* 830 */ 152, 172, 173, 172, 173, 70, 71, 72, 73, 74,
+ /* 840 */ 75, 76, 77, 78, 79, 80, 81, 82, 152, 84,
+ /* 850 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ /* 860 */ 19, 152, 22, 152, 195, 24, 152, 27, 172, 173,
+ /* 870 */ 193, 193, 152, 152, 152, 206, 152, 217, 152, 152,
+ /* 880 */ 152, 172, 173, 172, 173, 152, 172, 173, 152, 152,
+ /* 890 */ 49, 50, 172, 173, 172, 173, 172, 173, 172, 173,
+ /* 900 */ 172, 173, 152, 138, 152, 172, 173, 108, 109, 110,
+ /* 910 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 920 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
+ /* 930 */ 89, 90, 91, 92, 93, 94, 152, 97, 152, 152,
+ /* 940 */ 49, 50, 26, 193, 172, 173, 152, 152, 152, 146,
+ /* 950 */ 147, 132, 152, 134, 217, 181, 172, 173, 172, 173,
+ /* 960 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 970 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
+ /* 980 */ 89, 90, 91, 92, 93, 94, 152, 193, 152, 193,
+ /* 990 */ 49, 50, 181, 193, 172, 173, 166, 167, 245, 246,
+ /* 1000 */ 211, 212, 152, 22, 217, 152, 172, 173, 172, 173,
+ /* 1010 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 1020 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
+ /* 1030 */ 89, 90, 91, 92, 93, 94, 152, 187, 152, 123,
+ /* 1040 */ 49, 50, 23, 23, 23, 26, 26, 26, 23, 23,
+ /* 1050 */ 23, 26, 26, 26, 7, 8, 172, 173, 172, 173,
+ /* 1060 */ 19, 90, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 1070 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
+ /* 1080 */ 89, 90, 91, 92, 93, 94, 152, 116, 152, 217,
+ /* 1090 */ 49, 50, 121, 23, 172, 173, 26, 100, 101, 27,
+ /* 1100 */ 101, 27, 23, 122, 152, 26, 172, 173, 172, 173,
+ /* 1110 */ 152, 112, 163, 72, 73, 74, 75, 76, 77, 78,
+ /* 1120 */ 79, 80, 81, 82, 163, 84, 85, 86, 87, 88,
+ /* 1130 */ 89, 90, 91, 92, 93, 94, 19, 20, 152, 22,
+ /* 1140 */ 23, 152, 163, 65, 27, 196, 163, 19, 20, 23,
+ /* 1150 */ 22, 213, 26, 19, 37, 27, 152, 196, 172, 173,
+ /* 1160 */ 152, 172, 173, 27, 23, 37, 152, 26, 152, 97,
+ /* 1170 */ 152, 97, 210, 56, 163, 196, 163, 163, 100, 196,
+ /* 1180 */ 172, 173, 65, 152, 56, 68, 172, 173, 172, 173,
+ /* 1190 */ 172, 173, 152, 65, 163, 163, 68, 23, 152, 234,
+ /* 1200 */ 26, 152, 152, 172, 173, 88, 89, 196, 152, 196,
+ /* 1210 */ 196, 152, 95, 96, 97, 98, 88, 89, 101, 152,
+ /* 1220 */ 152, 207, 208, 95, 96, 97, 98, 196, 196, 101,
+ /* 1230 */ 96, 233, 152, 97, 152, 152, 19, 20, 207, 22,
+ /* 1240 */ 152, 152, 152, 191, 27, 152, 152, 152, 152, 132,
+ /* 1250 */ 133, 134, 135, 136, 37, 152, 152, 152, 152, 152,
+ /* 1260 */ 132, 133, 134, 135, 136, 210, 197, 210, 210, 198,
+ /* 1270 */ 150, 184, 239, 56, 201, 214, 214, 201, 239, 180,
+ /* 1280 */ 214, 227, 198, 38, 176, 68, 175, 175, 175, 122,
+ /* 1290 */ 155, 200, 159, 19, 20, 40, 22, 159, 159, 22,
+ /* 1300 */ 70, 27, 130, 243, 240, 88, 89, 90, 189, 18,
+ /* 1310 */ 201, 37, 95, 96, 97, 98, 192, 5, 101, 192,
+ /* 1320 */ 220, 240, 10, 11, 12, 13, 14, 159, 18, 17,
+ /* 1330 */ 56, 158, 192, 201, 192, 220, 189, 189, 201, 159,
+ /* 1340 */ 158, 137, 68, 31, 45, 33, 236, 159, 159, 132,
+ /* 1350 */ 133, 134, 135, 136, 42, 158, 235, 22, 177, 159,
+ /* 1360 */ 158, 158, 88, 89, 159, 107, 174, 55, 177, 95,
+ /* 1370 */ 96, 97, 98, 174, 62, 101, 47, 65, 66, 106,
+ /* 1380 */ 174, 125, 19, 20, 174, 22, 177, 176, 174, 182,
+ /* 1390 */ 27, 216, 174, 174, 182, 107, 159, 22, 215, 215,
+ /* 1400 */ 37, 216, 216, 216, 137, 215, 132, 133, 134, 135,
+ /* 1410 */ 136, 215, 159, 177, 94, 177, 129, 224, 205, 56,
+ /* 1420 */ 226, 126, 128, 203, 229, 204, 114, 229, 127, 202,
+ /* 1430 */ 201, 68, 25, 162, 26, 13, 161, 153, 153, 6,
+ /* 1440 */ 151, 151, 178, 151, 151, 165, 165, 178, 165, 4,
+ /* 1450 */ 249, 88, 89, 141, 3, 142, 22, 249, 95, 96,
+ /* 1460 */ 97, 98, 246, 15, 101, 67, 16, 23, 120, 23,
+ /* 1470 */ 131, 111, 123, 20, 16, 125, 1, 123, 131, 78,
+ /* 1480 */ 78, 78, 78, 111, 96, 1, 122, 35, 5, 22,
+ /* 1490 */ 107, 140, 53, 53, 26, 132, 133, 134, 135, 136,
+ /* 1500 */ 43, 60, 107, 24, 112, 20, 19, 52, 22, 29,
+ /* 1510 */ 105, 22, 22, 52, 23, 22, 22, 52, 23, 23,
+ /* 1520 */ 39, 23, 116, 26, 22, 26, 23, 22, 96, 23,
+ /* 1530 */ 23, 122, 22, 24, 124, 35, 35, 26, 26, 35,
+ /* 1540 */ 23, 23, 23, 23, 11, 23, 22, 26, 23, 22,
+ /* 1550 */ 122, 23, 26, 22, 24, 23, 22, 122, 23, 23,
+ /* 1560 */ 22, 15, 23, 1, 122, 122,
};
-#define YY_SHIFT_USE_DFLT (1567)
+#define YY_SHIFT_USE_DFLT (1566)
#define YY_SHIFT_COUNT (455)
-#define YY_SHIFT_MIN (-94)
-#define YY_SHIFT_MAX (1549)
+#define YY_SHIFT_MIN (-114)
+#define YY_SHIFT_MAX (1562)
static const short yy_shift_ofst[] = {
- /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19,
- /* 10 */ 16, 16, 100, 760, 760, 760, 760, 760, 760, 760,
- /* 20 */ 876, 876, 573, 542, 719, 600, 61, 137, 172, 207,
- /* 30 */ 242, 277, 312, 347, 382, 417, 459, 459, 459, 459,
- /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
- /* 50 */ 459, 459, 459, 494, 459, 529, 564, 564, 705, 760,
- /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
- /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
- /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
- /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760,
- /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746,
- /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73,
- /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99,
- /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949,
- /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
- /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113,
- /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922,
- /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949,
- /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
- /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949,
- /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949,
- /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118,
- /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418,
- /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882,
- /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238,
- /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239,
- /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238,
- /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290,
- /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304,
- /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280,
- /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414,
- /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567,
- /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104,
- /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273,
- /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177,
- /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452,
- /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479,
- /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367,
- /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429,
- /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491,
- /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498,
- /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475,
- /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517,
- /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527,
- /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436,
- /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549,
+ /* 0 */ 5, 1117, 1312, 1128, 1274, 1274, 1274, 1274, 61, -19,
+ /* 10 */ 57, 57, 183, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ /* 20 */ 66, 66, 201, -29, 331, 318, 133, 259, 335, 411,
+ /* 30 */ 487, 563, 639, 689, 765, 841, 891, 891, 891, 891,
+ /* 40 */ 891, 891, 891, 891, 891, 891, 891, 891, 891, 891,
+ /* 50 */ 891, 891, 891, 941, 891, 991, 1041, 1041, 1217, 1274,
+ /* 60 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ /* 70 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ /* 80 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ /* 90 */ 1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ /* 100 */ 1274, 1274, 1274, 1274, -70, -47, -47, -47, -47, -47,
+ /* 110 */ 24, 11, 146, 296, 524, 444, 529, 529, 296, 3,
+ /* 120 */ 2, -30, 1566, 1566, 1566, -17, -17, -17, 145, 145,
+ /* 130 */ 497, 497, 265, 603, 653, 296, 296, 296, 296, 296,
+ /* 140 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
+ /* 150 */ 296, 296, 296, 296, 296, 701, 1078, 147, 147, 2,
+ /* 160 */ 164, 164, 164, 164, 164, 164, 1566, 1566, 1566, 223,
+ /* 170 */ 56, 56, 268, 269, 220, 347, 351, 415, 359, 296,
+ /* 180 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
+ /* 190 */ 296, 296, 296, 296, 296, 632, 632, 632, 296, 296,
+ /* 200 */ 498, 296, 296, 296, 570, 296, 296, 654, 296, 296,
+ /* 210 */ 296, 296, 296, 296, 296, 296, 296, 296, 636, 200,
+ /* 220 */ 596, 596, 596, 575, -114, 971, 740, 454, 503, 503,
+ /* 230 */ 1134, 454, 1134, 353, 588, 628, 762, 503, 189, 762,
+ /* 240 */ 762, 916, 330, 668, 1245, 1167, 1167, 1255, 1255, 1167,
+ /* 250 */ 1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172,
+ /* 260 */ 1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167,
+ /* 270 */ 1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258,
+ /* 280 */ 1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288,
+ /* 290 */ 1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267,
+ /* 300 */ 1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407,
+ /* 310 */ 1408, 1422, 1422, 1433, 1433, 1433, 1433, 1566, 1566, 1566,
+ /* 320 */ 1566, 1566, 1566, 1566, 1566, 558, 537, 684, 719, 734,
+ /* 330 */ 799, 840, 1019, 14, 1020, 1021, 1025, 1026, 1027, 1070,
+ /* 340 */ 1072, 997, 1047, 999, 1079, 1126, 1074, 1141, 694, 819,
+ /* 350 */ 1174, 1136, 981, 1445, 1451, 1434, 1313, 1448, 1398, 1450,
+ /* 360 */ 1444, 1446, 1348, 1339, 1360, 1349, 1453, 1350, 1458, 1475,
+ /* 370 */ 1354, 1347, 1401, 1402, 1403, 1404, 1372, 1388, 1452, 1364,
+ /* 380 */ 1484, 1483, 1467, 1383, 1351, 1439, 1468, 1440, 1441, 1457,
+ /* 390 */ 1395, 1479, 1485, 1487, 1392, 1405, 1486, 1455, 1489, 1490,
+ /* 400 */ 1491, 1493, 1461, 1480, 1494, 1465, 1481, 1495, 1496, 1498,
+ /* 410 */ 1497, 1406, 1502, 1503, 1505, 1499, 1409, 1506, 1507, 1432,
+ /* 420 */ 1500, 1510, 1410, 1511, 1501, 1512, 1504, 1517, 1511, 1518,
+ /* 430 */ 1519, 1520, 1521, 1522, 1524, 1533, 1525, 1527, 1509, 1526,
+ /* 440 */ 1528, 1531, 1530, 1526, 1532, 1534, 1535, 1536, 1538, 1428,
+ /* 450 */ 1435, 1442, 1443, 1539, 1546, 1562,
};
-#define YY_REDUCE_USE_DFLT (-130)
+#define YY_REDUCE_USE_DFLT (-174)
#define YY_REDUCE_COUNT (324)
-#define YY_REDUCE_MIN (-129)
-#define YY_REDUCE_MAX (1300)
+#define YY_REDUCE_MIN (-173)
+#define YY_REDUCE_MAX (1293)
static const short yy_reduce_ofst[] = {
- /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435,
- /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790,
- /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76,
- /* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
- /* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
- /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898,
- /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950,
- /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984,
- /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021,
- /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062,
- /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76,
- /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76,
- /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220,
- /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620,
- /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047,
- /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808,
- /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57,
- /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438,
- /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908,
- /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101,
- /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171,
- /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102,
- /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130,
- /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183,
- /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205,
- /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193,
- /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231,
- /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232,
- /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201,
- /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215,
- /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278,
- /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228,
- /* 320 */ 1288, 1291, 1276, 1277, 1295,
+ /* 0 */ -119, 1014, 131, 1031, -12, 225, 228, 300, -40, -45,
+ /* 10 */ 243, 256, 293, 129, 218, 418, 79, 376, 433, 298,
+ /* 20 */ 16, 137, 367, 323, -38, 391, -173, -173, -173, -173,
+ /* 30 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
+ /* 40 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
+ /* 50 */ -173, -173, -173, -173, -173, -173, -173, -173, 374, 437,
+ /* 60 */ 443, 508, 513, 522, 532, 582, 584, 620, 633, 635,
+ /* 70 */ 637, 644, 646, 648, 650, 652, 659, 661, 696, 709,
+ /* 80 */ 711, 714, 720, 722, 724, 726, 728, 733, 772, 784,
+ /* 90 */ 786, 822, 834, 836, 884, 886, 922, 934, 936, 986,
+ /* 100 */ 989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173,
+ /* 110 */ -173, -173, -173, 544, -37, 274, 299, 501, 161, -173,
+ /* 120 */ 193, -173, -173, -173, -173, 22, 22, 22, 64, 141,
+ /* 130 */ 212, 342, 208, 504, 504, 132, 494, 606, 677, 678,
+ /* 140 */ 750, 794, 796, -58, 32, 383, 660, 737, 386, 787,
+ /* 150 */ 800, 441, 872, 224, 850, 803, 949, 624, 830, 669,
+ /* 160 */ 961, 979, 983, 1011, 1013, 1032, 753, 789, 321, 94,
+ /* 170 */ 116, 304, 375, 210, 388, 392, 478, 545, 649, 721,
+ /* 180 */ 727, 736, 752, 795, 853, 952, 958, 1004, 1040, 1046,
+ /* 190 */ 1049, 1050, 1056, 1059, 1067, 559, 774, 811, 1068, 1080,
+ /* 200 */ 938, 1082, 1083, 1088, 962, 1089, 1090, 1052, 1093, 1094,
+ /* 210 */ 1095, 388, 1096, 1103, 1104, 1105, 1106, 1107, 965, 998,
+ /* 220 */ 1055, 1057, 1058, 938, 1069, 1071, 1120, 1073, 1061, 1062,
+ /* 230 */ 1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112,
+ /* 240 */ 1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139,
+ /* 250 */ 1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132,
+ /* 260 */ 1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189,
+ /* 270 */ 1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206,
+ /* 280 */ 1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183,
+ /* 290 */ 1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194,
+ /* 300 */ 1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271,
+ /* 310 */ 1275, 1284, 1285, 1289, 1290, 1292, 1293, 1201, 1208, 1216,
+ /* 320 */ 1280, 1281, 1264, 1269, 1283,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1281, 1271, 1271, 1271, 1203, 1203, 1203, 1203, 1271, 1096,
- /* 10 */ 1125, 1125, 1255, 1332, 1332, 1332, 1332, 1332, 1332, 1202,
- /* 20 */ 1332, 1332, 1332, 1332, 1271, 1100, 1131, 1332, 1332, 1332,
- /* 30 */ 1332, 1204, 1205, 1332, 1332, 1332, 1254, 1256, 1141, 1140,
- /* 40 */ 1139, 1138, 1237, 1112, 1136, 1129, 1133, 1204, 1198, 1199,
- /* 50 */ 1197, 1201, 1205, 1332, 1132, 1167, 1182, 1166, 1332, 1332,
+ /* 0 */ 1280, 1270, 1270, 1270, 1202, 1202, 1202, 1202, 1270, 1096,
+ /* 10 */ 1125, 1125, 1254, 1332, 1332, 1332, 1332, 1332, 1332, 1201,
+ /* 20 */ 1332, 1332, 1332, 1332, 1270, 1100, 1131, 1332, 1332, 1332,
+ /* 30 */ 1332, 1203, 1204, 1332, 1332, 1332, 1253, 1255, 1141, 1140,
+ /* 40 */ 1139, 1138, 1236, 1112, 1136, 1129, 1133, 1203, 1197, 1198,
+ /* 50 */ 1196, 1200, 1204, 1332, 1132, 1167, 1181, 1166, 1332, 1332,
/* 60 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 70 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 80 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 90 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /* 100 */ 1332, 1332, 1332, 1332, 1176, 1181, 1188, 1180, 1177, 1169,
+ /* 100 */ 1332, 1332, 1332, 1332, 1175, 1180, 1187, 1179, 1176, 1169,
/* 110 */ 1168, 1170, 1171, 1332, 1019, 1067, 1332, 1332, 1332, 1172,
- /* 120 */ 1332, 1173, 1185, 1184, 1183, 1262, 1289, 1288, 1332, 1332,
+ /* 120 */ 1332, 1173, 1184, 1183, 1182, 1261, 1288, 1287, 1332, 1332,
/* 130 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 140 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /* 150 */ 1332, 1332, 1332, 1332, 1332, 1281, 1271, 1025, 1025, 1332,
- /* 160 */ 1271, 1271, 1271, 1271, 1271, 1271, 1267, 1100, 1091, 1332,
+ /* 150 */ 1332, 1332, 1332, 1332, 1332, 1280, 1270, 1025, 1025, 1332,
+ /* 160 */ 1270, 1270, 1270, 1270, 1270, 1270, 1266, 1100, 1091, 1332,
/* 170 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /* 180 */ 1259, 1257, 1332, 1218, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 180 */ 1258, 1256, 1332, 1217, 1332, 1332, 1332, 1332, 1332, 1332,
/* 190 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 200 */ 1332, 1332, 1332, 1332, 1096, 1332, 1332, 1332, 1332, 1332,
- /* 210 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1283, 1332, 1232,
+ /* 210 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1282, 1332, 1231,
/* 220 */ 1096, 1096, 1096, 1098, 1080, 1090, 1004, 1135, 1114, 1114,
- /* 230 */ 1321, 1135, 1321, 1042, 1303, 1039, 1125, 1114, 1200, 1125,
+ /* 230 */ 1321, 1135, 1321, 1042, 1302, 1039, 1125, 1114, 1199, 1125,
/* 240 */ 1125, 1097, 1090, 1332, 1324, 1105, 1105, 1323, 1323, 1105,
/* 250 */ 1146, 1070, 1135, 1076, 1076, 1076, 1076, 1105, 1016, 1135,
- /* 260 */ 1146, 1070, 1070, 1135, 1105, 1016, 1236, 1318, 1105, 1105,
- /* 270 */ 1016, 1211, 1105, 1016, 1105, 1016, 1211, 1068, 1068, 1068,
- /* 280 */ 1057, 1211, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
- /* 290 */ 1118, 1113, 1118, 1113, 1118, 1113, 1105, 1206, 1105, 1332,
- /* 300 */ 1211, 1215, 1215, 1211, 1130, 1119, 1128, 1126, 1135, 1022,
- /* 310 */ 1060, 1286, 1286, 1282, 1282, 1282, 1282, 1329, 1329, 1267,
- /* 320 */ 1298, 1298, 1044, 1044, 1298, 1332, 1332, 1332, 1332, 1332,
- /* 330 */ 1332, 1293, 1332, 1220, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 260 */ 1146, 1070, 1070, 1135, 1105, 1016, 1235, 1318, 1105, 1105,
+ /* 270 */ 1016, 1210, 1105, 1016, 1105, 1016, 1210, 1068, 1068, 1068,
+ /* 280 */ 1057, 1210, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
+ /* 290 */ 1118, 1113, 1118, 1113, 1118, 1113, 1105, 1205, 1105, 1332,
+ /* 300 */ 1210, 1214, 1214, 1210, 1130, 1119, 1128, 1126, 1135, 1022,
+ /* 310 */ 1060, 1285, 1285, 1281, 1281, 1281, 1281, 1329, 1329, 1266,
+ /* 320 */ 1297, 1297, 1044, 1044, 1297, 1332, 1332, 1332, 1332, 1332,
+ /* 330 */ 1332, 1292, 1332, 1219, 1332, 1332, 1332, 1332, 1332, 1332,
/* 340 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /* 350 */ 1332, 1332, 1152, 1332, 1000, 1264, 1332, 1332, 1263, 1332,
+ /* 350 */ 1332, 1332, 1152, 1332, 1000, 1263, 1332, 1332, 1262, 1332,
/* 360 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 370 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1320,
- /* 380 */ 1332, 1332, 1332, 1332, 1332, 1332, 1235, 1234, 1332, 1332,
+ /* 380 */ 1332, 1332, 1332, 1332, 1332, 1332, 1234, 1233, 1332, 1332,
/* 390 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
/* 400 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /* 410 */ 1332, 1082, 1332, 1332, 1332, 1307, 1332, 1332, 1332, 1332,
+ /* 410 */ 1332, 1082, 1332, 1332, 1332, 1306, 1332, 1332, 1332, 1332,
/* 420 */ 1332, 1332, 1332, 1127, 1332, 1120, 1332, 1332, 1311, 1332,
- /* 430 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1273,
- /* 440 */ 1332, 1332, 1332, 1272, 1332, 1332, 1332, 1332, 1332, 1154,
+ /* 430 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1272,
+ /* 440 */ 1332, 1332, 1332, 1271, 1332, 1332, 1332, 1332, 1332, 1154,
/* 450 */ 1332, 1153, 1157, 1332, 1010, 1332,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -135181,100 +136294,73 @@ static const YYACTIONTYPE yy_default[] = {
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 55, /* EXPLAIN => ID */
- 55, /* QUERY => ID */
- 55, /* PLAN => ID */
- 55, /* BEGIN => ID */
+ 27, /* EXPLAIN => ID */
+ 27, /* QUERY => ID */
+ 27, /* PLAN => ID */
+ 27, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 55, /* DEFERRED => ID */
- 55, /* IMMEDIATE => ID */
- 55, /* EXCLUSIVE => ID */
+ 27, /* DEFERRED => ID */
+ 27, /* IMMEDIATE => ID */
+ 27, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 55, /* END => ID */
- 55, /* ROLLBACK => ID */
- 55, /* SAVEPOINT => ID */
- 55, /* RELEASE => ID */
+ 27, /* END => ID */
+ 27, /* ROLLBACK => ID */
+ 27, /* SAVEPOINT => ID */
+ 27, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 55, /* IF => ID */
+ 27, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 55, /* TEMP => ID */
+ 27, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
- 55, /* WITHOUT => ID */
+ 27, /* WITHOUT => ID */
0, /* COMMA => nothing */
- 0, /* OR => nothing */
- 0, /* AND => nothing */
- 0, /* IS => nothing */
- 55, /* MATCH => ID */
- 55, /* LIKE_KW => ID */
- 0, /* BETWEEN => nothing */
- 0, /* IN => nothing */
- 0, /* ISNULL => nothing */
- 0, /* NOTNULL => nothing */
- 0, /* NE => nothing */
- 0, /* EQ => nothing */
- 0, /* GT => nothing */
- 0, /* LE => nothing */
- 0, /* LT => nothing */
- 0, /* GE => nothing */
- 0, /* ESCAPE => nothing */
- 0, /* BITAND => nothing */
- 0, /* BITOR => nothing */
- 0, /* LSHIFT => nothing */
- 0, /* RSHIFT => nothing */
- 0, /* PLUS => nothing */
- 0, /* MINUS => nothing */
- 0, /* STAR => nothing */
- 0, /* SLASH => nothing */
- 0, /* REM => nothing */
- 0, /* CONCAT => nothing */
- 0, /* COLLATE => nothing */
- 0, /* BITNOT => nothing */
0, /* ID => nothing */
- 0, /* INDEXED => nothing */
- 55, /* ABORT => ID */
- 55, /* ACTION => ID */
- 55, /* AFTER => ID */
- 55, /* ANALYZE => ID */
- 55, /* ASC => ID */
- 55, /* ATTACH => ID */
- 55, /* BEFORE => ID */
- 55, /* BY => ID */
- 55, /* CASCADE => ID */
- 55, /* CAST => ID */
- 55, /* COLUMNKW => ID */
- 55, /* CONFLICT => ID */
- 55, /* DATABASE => ID */
- 55, /* DESC => ID */
- 55, /* DETACH => ID */
- 55, /* EACH => ID */
- 55, /* FAIL => ID */
- 55, /* FOR => ID */
- 55, /* IGNORE => ID */
- 55, /* INITIALLY => ID */
- 55, /* INSTEAD => ID */
- 55, /* NO => ID */
- 55, /* KEY => ID */
- 55, /* OF => ID */
- 55, /* OFFSET => ID */
- 55, /* PRAGMA => ID */
- 55, /* RAISE => ID */
- 55, /* RECURSIVE => ID */
- 55, /* REPLACE => ID */
- 55, /* RESTRICT => ID */
- 55, /* ROW => ID */
- 55, /* TRIGGER => ID */
- 55, /* VACUUM => ID */
- 55, /* VIEW => ID */
- 55, /* VIRTUAL => ID */
- 55, /* WITH => ID */
- 55, /* REINDEX => ID */
- 55, /* RENAME => ID */
- 55, /* CTIME_KW => ID */
+ 27, /* ABORT => ID */
+ 27, /* ACTION => ID */
+ 27, /* AFTER => ID */
+ 27, /* ANALYZE => ID */
+ 27, /* ASC => ID */
+ 27, /* ATTACH => ID */
+ 27, /* BEFORE => ID */
+ 27, /* BY => ID */
+ 27, /* CASCADE => ID */
+ 27, /* CAST => ID */
+ 27, /* COLUMNKW => ID */
+ 27, /* CONFLICT => ID */
+ 27, /* DATABASE => ID */
+ 27, /* DESC => ID */
+ 27, /* DETACH => ID */
+ 27, /* EACH => ID */
+ 27, /* FAIL => ID */
+ 27, /* FOR => ID */
+ 27, /* IGNORE => ID */
+ 27, /* INITIALLY => ID */
+ 27, /* INSTEAD => ID */
+ 27, /* LIKE_KW => ID */
+ 27, /* MATCH => ID */
+ 27, /* NO => ID */
+ 27, /* KEY => ID */
+ 27, /* OF => ID */
+ 27, /* OFFSET => ID */
+ 27, /* PRAGMA => ID */
+ 27, /* RAISE => ID */
+ 27, /* RECURSIVE => ID */
+ 27, /* REPLACE => ID */
+ 27, /* RESTRICT => ID */
+ 27, /* ROW => ID */
+ 27, /* TRIGGER => ID */
+ 27, /* VACUUM => ID */
+ 27, /* VIEW => ID */
+ 27, /* VIRTUAL => ID */
+ 27, /* WITH => ID */
+ 27, /* REINDEX => ID */
+ 27, /* RENAME => ID */
+ 27, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
@@ -135366,25 +136452,25 @@ static const char *const yyTokenName[] = {
"ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
"TABLE", "CREATE", "IF", "NOT",
"EXISTS", "TEMP", "LP", "RP",
- "AS", "WITHOUT", "COMMA", "OR",
- "AND", "IS", "MATCH", "LIKE_KW",
- "BETWEEN", "IN", "ISNULL", "NOTNULL",
- "NE", "EQ", "GT", "LE",
- "LT", "GE", "ESCAPE", "BITAND",
- "BITOR", "LSHIFT", "RSHIFT", "PLUS",
- "MINUS", "STAR", "SLASH", "REM",
- "CONCAT", "COLLATE", "BITNOT", "ID",
- "INDEXED", "ABORT", "ACTION", "AFTER",
- "ANALYZE", "ASC", "ATTACH", "BEFORE",
- "BY", "CASCADE", "CAST", "COLUMNKW",
- "CONFLICT", "DATABASE", "DESC", "DETACH",
- "EACH", "FAIL", "FOR", "IGNORE",
- "INITIALLY", "INSTEAD", "NO", "KEY",
- "OF", "OFFSET", "PRAGMA", "RAISE",
- "RECURSIVE", "REPLACE", "RESTRICT", "ROW",
- "TRIGGER", "VACUUM", "VIEW", "VIRTUAL",
- "WITH", "REINDEX", "RENAME", "CTIME_KW",
- "ANY", "STRING", "JOIN_KW", "CONSTRAINT",
+ "AS", "WITHOUT", "COMMA", "ID",
+ "ABORT", "ACTION", "AFTER", "ANALYZE",
+ "ASC", "ATTACH", "BEFORE", "BY",
+ "CASCADE", "CAST", "COLUMNKW", "CONFLICT",
+ "DATABASE", "DESC", "DETACH", "EACH",
+ "FAIL", "FOR", "IGNORE", "INITIALLY",
+ "INSTEAD", "LIKE_KW", "MATCH", "NO",
+ "KEY", "OF", "OFFSET", "PRAGMA",
+ "RAISE", "RECURSIVE", "REPLACE", "RESTRICT",
+ "ROW", "TRIGGER", "VACUUM", "VIEW",
+ "VIRTUAL", "WITH", "REINDEX", "RENAME",
+ "CTIME_KW", "ANY", "OR", "AND",
+ "IS", "BETWEEN", "IN", "ISNULL",
+ "NOTNULL", "NE", "EQ", "GT",
+ "LE", "LT", "GE", "ESCAPE",
+ "BITAND", "BITOR", "LSHIFT", "RSHIFT",
+ "PLUS", "MINUS", "STAR", "SLASH",
+ "REM", "CONCAT", "COLLATE", "BITNOT",
+ "INDEXED", "STRING", "JOIN_KW", "CONSTRAINT",
"DEFAULT", "NULL", "PRIMARY", "UNIQUE",
"CHECK", "REFERENCES", "AUTOINCR", "ON",
"INSERT", "DELETE", "UPDATE", "SET",
@@ -135604,143 +136690,143 @@ static const char *const yyRuleName[] = {
/* 171 */ "expr ::= expr PLUS|MINUS expr",
/* 172 */ "expr ::= expr STAR|SLASH|REM expr",
/* 173 */ "expr ::= expr CONCAT expr",
- /* 174 */ "likeop ::= LIKE_KW|MATCH",
- /* 175 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 176 */ "expr ::= expr likeop expr",
- /* 177 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 178 */ "expr ::= expr ISNULL|NOTNULL",
- /* 179 */ "expr ::= expr NOT NULL",
- /* 180 */ "expr ::= expr IS expr",
- /* 181 */ "expr ::= expr IS NOT expr",
- /* 182 */ "expr ::= NOT expr",
- /* 183 */ "expr ::= BITNOT expr",
- /* 184 */ "expr ::= MINUS expr",
- /* 185 */ "expr ::= PLUS expr",
- /* 186 */ "between_op ::= BETWEEN",
- /* 187 */ "between_op ::= NOT BETWEEN",
- /* 188 */ "expr ::= expr between_op expr AND expr",
- /* 189 */ "in_op ::= IN",
- /* 190 */ "in_op ::= NOT IN",
- /* 191 */ "expr ::= expr in_op LP exprlist RP",
- /* 192 */ "expr ::= LP select RP",
- /* 193 */ "expr ::= expr in_op LP select RP",
- /* 194 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 195 */ "expr ::= EXISTS LP select RP",
- /* 196 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 197 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 198 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 199 */ "case_else ::= ELSE expr",
- /* 200 */ "case_else ::=",
- /* 201 */ "case_operand ::= expr",
- /* 202 */ "case_operand ::=",
- /* 203 */ "exprlist ::=",
- /* 204 */ "nexprlist ::= nexprlist COMMA expr",
- /* 205 */ "nexprlist ::= expr",
- /* 206 */ "paren_exprlist ::=",
- /* 207 */ "paren_exprlist ::= LP exprlist RP",
- /* 208 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 209 */ "uniqueflag ::= UNIQUE",
- /* 210 */ "uniqueflag ::=",
- /* 211 */ "eidlist_opt ::=",
- /* 212 */ "eidlist_opt ::= LP eidlist RP",
- /* 213 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 214 */ "eidlist ::= nm collate sortorder",
- /* 215 */ "collate ::=",
- /* 216 */ "collate ::= COLLATE ID|STRING",
- /* 217 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 218 */ "cmd ::= VACUUM",
- /* 219 */ "cmd ::= VACUUM nm",
- /* 220 */ "cmd ::= PRAGMA nm dbnm",
- /* 221 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 222 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 223 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 224 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 225 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 226 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 227 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 228 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 229 */ "trigger_time ::= BEFORE",
- /* 230 */ "trigger_time ::= AFTER",
- /* 231 */ "trigger_time ::= INSTEAD OF",
- /* 232 */ "trigger_time ::=",
- /* 233 */ "trigger_event ::= DELETE|INSERT",
- /* 234 */ "trigger_event ::= UPDATE",
- /* 235 */ "trigger_event ::= UPDATE OF idlist",
- /* 236 */ "when_clause ::=",
- /* 237 */ "when_clause ::= WHEN expr",
- /* 238 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 239 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 240 */ "trnm ::= nm DOT nm",
- /* 241 */ "tridxby ::= INDEXED BY nm",
- /* 242 */ "tridxby ::= NOT INDEXED",
- /* 243 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 244 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
- /* 245 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 246 */ "trigger_cmd ::= select",
- /* 247 */ "expr ::= RAISE LP IGNORE RP",
- /* 248 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 249 */ "raisetype ::= ROLLBACK",
- /* 250 */ "raisetype ::= ABORT",
- /* 251 */ "raisetype ::= FAIL",
- /* 252 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 253 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 254 */ "cmd ::= DETACH database_kw_opt expr",
- /* 255 */ "key_opt ::=",
- /* 256 */ "key_opt ::= KEY expr",
- /* 257 */ "cmd ::= REINDEX",
- /* 258 */ "cmd ::= REINDEX nm dbnm",
- /* 259 */ "cmd ::= ANALYZE",
- /* 260 */ "cmd ::= ANALYZE nm dbnm",
- /* 261 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 262 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 263 */ "add_column_fullname ::= fullname",
- /* 264 */ "cmd ::= create_vtab",
- /* 265 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 266 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 267 */ "vtabarg ::=",
- /* 268 */ "vtabargtoken ::= ANY",
- /* 269 */ "vtabargtoken ::= lp anylist RP",
- /* 270 */ "lp ::= LP",
- /* 271 */ "with ::=",
- /* 272 */ "with ::= WITH wqlist",
- /* 273 */ "with ::= WITH RECURSIVE wqlist",
- /* 274 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 275 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 276 */ "input ::= cmdlist",
- /* 277 */ "cmdlist ::= cmdlist ecmd",
- /* 278 */ "cmdlist ::= ecmd",
- /* 279 */ "ecmd ::= SEMI",
- /* 280 */ "ecmd ::= explain cmdx SEMI",
- /* 281 */ "explain ::=",
- /* 282 */ "trans_opt ::=",
- /* 283 */ "trans_opt ::= TRANSACTION",
- /* 284 */ "trans_opt ::= TRANSACTION nm",
- /* 285 */ "savepoint_opt ::= SAVEPOINT",
- /* 286 */ "savepoint_opt ::=",
- /* 287 */ "cmd ::= create_table create_table_args",
- /* 288 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 289 */ "columnlist ::= columnname carglist",
- /* 290 */ "nm ::= ID|INDEXED",
- /* 291 */ "nm ::= STRING",
- /* 292 */ "nm ::= JOIN_KW",
- /* 293 */ "typetoken ::= typename",
- /* 294 */ "typename ::= ID|STRING",
- /* 295 */ "signed ::= plus_num",
- /* 296 */ "signed ::= minus_num",
- /* 297 */ "carglist ::= carglist ccons",
- /* 298 */ "carglist ::=",
- /* 299 */ "ccons ::= NULL onconf",
- /* 300 */ "conslist_opt ::= COMMA conslist",
- /* 301 */ "conslist ::= conslist tconscomma tcons",
- /* 302 */ "conslist ::= tcons",
- /* 303 */ "tconscomma ::=",
- /* 304 */ "defer_subclause_opt ::= defer_subclause",
- /* 305 */ "resolvetype ::= raisetype",
- /* 306 */ "selectnowith ::= oneselect",
- /* 307 */ "oneselect ::= values",
- /* 308 */ "sclp ::= selcollist COMMA",
- /* 309 */ "as ::= ID|STRING",
- /* 310 */ "expr ::= term",
+ /* 174 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 175 */ "expr ::= expr likeop expr",
+ /* 176 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 177 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 178 */ "expr ::= expr NOT NULL",
+ /* 179 */ "expr ::= expr IS expr",
+ /* 180 */ "expr ::= expr IS NOT expr",
+ /* 181 */ "expr ::= NOT expr",
+ /* 182 */ "expr ::= BITNOT expr",
+ /* 183 */ "expr ::= MINUS expr",
+ /* 184 */ "expr ::= PLUS expr",
+ /* 185 */ "between_op ::= BETWEEN",
+ /* 186 */ "between_op ::= NOT BETWEEN",
+ /* 187 */ "expr ::= expr between_op expr AND expr",
+ /* 188 */ "in_op ::= IN",
+ /* 189 */ "in_op ::= NOT IN",
+ /* 190 */ "expr ::= expr in_op LP exprlist RP",
+ /* 191 */ "expr ::= LP select RP",
+ /* 192 */ "expr ::= expr in_op LP select RP",
+ /* 193 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 194 */ "expr ::= EXISTS LP select RP",
+ /* 195 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 196 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 197 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 198 */ "case_else ::= ELSE expr",
+ /* 199 */ "case_else ::=",
+ /* 200 */ "case_operand ::= expr",
+ /* 201 */ "case_operand ::=",
+ /* 202 */ "exprlist ::=",
+ /* 203 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 204 */ "nexprlist ::= expr",
+ /* 205 */ "paren_exprlist ::=",
+ /* 206 */ "paren_exprlist ::= LP exprlist RP",
+ /* 207 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 208 */ "uniqueflag ::= UNIQUE",
+ /* 209 */ "uniqueflag ::=",
+ /* 210 */ "eidlist_opt ::=",
+ /* 211 */ "eidlist_opt ::= LP eidlist RP",
+ /* 212 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 213 */ "eidlist ::= nm collate sortorder",
+ /* 214 */ "collate ::=",
+ /* 215 */ "collate ::= COLLATE ID|STRING",
+ /* 216 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 217 */ "cmd ::= VACUUM",
+ /* 218 */ "cmd ::= VACUUM nm",
+ /* 219 */ "cmd ::= PRAGMA nm dbnm",
+ /* 220 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 221 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 222 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 223 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 224 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 225 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 226 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 227 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 228 */ "trigger_time ::= BEFORE",
+ /* 229 */ "trigger_time ::= AFTER",
+ /* 230 */ "trigger_time ::= INSTEAD OF",
+ /* 231 */ "trigger_time ::=",
+ /* 232 */ "trigger_event ::= DELETE|INSERT",
+ /* 233 */ "trigger_event ::= UPDATE",
+ /* 234 */ "trigger_event ::= UPDATE OF idlist",
+ /* 235 */ "when_clause ::=",
+ /* 236 */ "when_clause ::= WHEN expr",
+ /* 237 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 238 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 239 */ "trnm ::= nm DOT nm",
+ /* 240 */ "tridxby ::= INDEXED BY nm",
+ /* 241 */ "tridxby ::= NOT INDEXED",
+ /* 242 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 243 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+ /* 244 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 245 */ "trigger_cmd ::= select",
+ /* 246 */ "expr ::= RAISE LP IGNORE RP",
+ /* 247 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 248 */ "raisetype ::= ROLLBACK",
+ /* 249 */ "raisetype ::= ABORT",
+ /* 250 */ "raisetype ::= FAIL",
+ /* 251 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 252 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 253 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 254 */ "key_opt ::=",
+ /* 255 */ "key_opt ::= KEY expr",
+ /* 256 */ "cmd ::= REINDEX",
+ /* 257 */ "cmd ::= REINDEX nm dbnm",
+ /* 258 */ "cmd ::= ANALYZE",
+ /* 259 */ "cmd ::= ANALYZE nm dbnm",
+ /* 260 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 261 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 262 */ "add_column_fullname ::= fullname",
+ /* 263 */ "cmd ::= create_vtab",
+ /* 264 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 265 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 266 */ "vtabarg ::=",
+ /* 267 */ "vtabargtoken ::= ANY",
+ /* 268 */ "vtabargtoken ::= lp anylist RP",
+ /* 269 */ "lp ::= LP",
+ /* 270 */ "with ::=",
+ /* 271 */ "with ::= WITH wqlist",
+ /* 272 */ "with ::= WITH RECURSIVE wqlist",
+ /* 273 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 274 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 275 */ "input ::= cmdlist",
+ /* 276 */ "cmdlist ::= cmdlist ecmd",
+ /* 277 */ "cmdlist ::= ecmd",
+ /* 278 */ "ecmd ::= SEMI",
+ /* 279 */ "ecmd ::= explain cmdx SEMI",
+ /* 280 */ "explain ::=",
+ /* 281 */ "trans_opt ::=",
+ /* 282 */ "trans_opt ::= TRANSACTION",
+ /* 283 */ "trans_opt ::= TRANSACTION nm",
+ /* 284 */ "savepoint_opt ::= SAVEPOINT",
+ /* 285 */ "savepoint_opt ::=",
+ /* 286 */ "cmd ::= create_table create_table_args",
+ /* 287 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 288 */ "columnlist ::= columnname carglist",
+ /* 289 */ "nm ::= ID|INDEXED",
+ /* 290 */ "nm ::= STRING",
+ /* 291 */ "nm ::= JOIN_KW",
+ /* 292 */ "typetoken ::= typename",
+ /* 293 */ "typename ::= ID|STRING",
+ /* 294 */ "signed ::= plus_num",
+ /* 295 */ "signed ::= minus_num",
+ /* 296 */ "carglist ::= carglist ccons",
+ /* 297 */ "carglist ::=",
+ /* 298 */ "ccons ::= NULL onconf",
+ /* 299 */ "conslist_opt ::= COMMA conslist",
+ /* 300 */ "conslist ::= conslist tconscomma tcons",
+ /* 301 */ "conslist ::= tcons",
+ /* 302 */ "tconscomma ::=",
+ /* 303 */ "defer_subclause_opt ::= defer_subclause",
+ /* 304 */ "resolvetype ::= raisetype",
+ /* 305 */ "selectnowith ::= oneselect",
+ /* 306 */ "oneselect ::= values",
+ /* 307 */ "sclp ::= selcollist COMMA",
+ /* 308 */ "as ::= ID|STRING",
+ /* 309 */ "expr ::= term",
+ /* 310 */ "likeop ::= LIKE_KW|MATCH",
/* 311 */ "exprlist ::= nexprlist",
/* 312 */ "nmnum ::= plus_num",
/* 313 */ "nmnum ::= nm",
@@ -136377,7 +137463,6 @@ static const struct {
{ 173, 3 },
{ 173, 3 },
{ 173, 3 },
- { 221, 1 },
{ 221, 2 },
{ 173, 3 },
{ 173, 5 },
@@ -136514,6 +137599,7 @@ static const struct {
{ 209, 2 },
{ 210, 1 },
{ 173, 1 },
+ { 221, 1 },
{ 208, 1 },
{ 230, 1 },
{ 230, 1 },
@@ -136656,7 +137742,7 @@ static void yy_reduce(
case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
case 90: /* distinct ::= */ yytestcase(yyruleno==90);
- case 215: /* collate ::= */ yytestcase(yyruleno==215);
+ case 214: /* collate ::= */ yytestcase(yyruleno==214);
{yymsp[1].minor.yy194 = 0;}
break;
case 17: /* ifnotexists ::= IF NOT EXISTS */
@@ -136800,9 +137886,9 @@ static void yy_reduce(
break;
case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
- case 187: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==187);
- case 190: /* in_op ::= NOT IN */ yytestcase(yyruleno==190);
- case 216: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==216);
+ case 186: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==186);
+ case 189: /* in_op ::= NOT IN */ yytestcase(yyruleno==189);
+ case 215: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==215);
{yymsp[-1].minor.yy194 = 1;}
break;
case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
@@ -136966,9 +138052,9 @@ static void yy_reduce(
case 91: /* sclp ::= */
case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
- case 203: /* exprlist ::= */ yytestcase(yyruleno==203);
- case 206: /* paren_exprlist ::= */ yytestcase(yyruleno==206);
- case 211: /* eidlist_opt ::= */ yytestcase(yyruleno==211);
+ case 202: /* exprlist ::= */ yytestcase(yyruleno==202);
+ case 205: /* paren_exprlist ::= */ yytestcase(yyruleno==205);
+ case 210: /* eidlist_opt ::= */ yytestcase(yyruleno==210);
{yymsp[1].minor.yy148 = 0;}
break;
case 92: /* selcollist ::= sclp expr as */
@@ -136994,8 +138080,8 @@ static void yy_reduce(
break;
case 95: /* as ::= AS nm */
case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
- case 225: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
- case 226: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==226);
+ case 224: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==224);
+ case 225: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 97: /* from ::= */
@@ -137078,14 +138164,14 @@ static void yy_reduce(
case 112: /* on_opt ::= ON expr */
case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
- case 199: /* case_else ::= ELSE expr */ yytestcase(yyruleno==199);
+ case 198: /* case_else ::= ELSE expr */ yytestcase(yyruleno==198);
{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
break;
case 113: /* on_opt ::= */
case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
- case 200: /* case_else ::= */ yytestcase(yyruleno==200);
- case 202: /* case_operand ::= */ yytestcase(yyruleno==202);
+ case 199: /* case_else ::= */ yytestcase(yyruleno==199);
+ case 201: /* case_operand ::= */ yytestcase(yyruleno==201);
{yymsp[1].minor.yy72 = 0;}
break;
case 115: /* indexed_opt ::= INDEXED BY nm */
@@ -137232,7 +138318,7 @@ static void yy_reduce(
yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z;
yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n;
- if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf;
+ if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf|EP_Resolved;
}
yymsp[0].minor.yy190 = yylhsminor.yy190;
break;
@@ -137322,13 +138408,10 @@ static void yy_reduce(
case 173: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==173);
{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
break;
- case 174: /* likeop ::= LIKE_KW|MATCH */
-{yymsp[0].minor.yy0=yymsp[0].minor.yy0;/*A-overwrites-X*/}
- break;
- case 175: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 174: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
- case 176: /* expr ::= expr likeop expr */
+ case 175: /* expr ::= expr likeop expr */
{
ExprList *pList;
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
@@ -137341,7 +138424,7 @@ static void yy_reduce(
if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
}
break;
- case 177: /* expr ::= expr likeop expr ESCAPE expr */
+ case 176: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
@@ -137355,39 +138438,39 @@ static void yy_reduce(
if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
}
break;
- case 178: /* expr ::= expr ISNULL|NOTNULL */
+ case 177: /* expr ::= expr ISNULL|NOTNULL */
{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
break;
- case 179: /* expr ::= expr NOT NULL */
+ case 178: /* expr ::= expr NOT NULL */
{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
break;
- case 180: /* expr ::= expr IS expr */
+ case 179: /* expr ::= expr IS expr */
{
spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
}
break;
- case 181: /* expr ::= expr IS NOT expr */
+ case 180: /* expr ::= expr IS NOT expr */
{
spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
}
break;
- case 182: /* expr ::= NOT expr */
- case 183: /* expr ::= BITNOT expr */ yytestcase(yyruleno==183);
+ case 181: /* expr ::= NOT expr */
+ case 182: /* expr ::= BITNOT expr */ yytestcase(yyruleno==182);
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
break;
- case 184: /* expr ::= MINUS expr */
+ case 183: /* expr ::= MINUS expr */
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
break;
- case 185: /* expr ::= PLUS expr */
+ case 184: /* expr ::= PLUS expr */
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
break;
- case 186: /* between_op ::= BETWEEN */
- case 189: /* in_op ::= IN */ yytestcase(yyruleno==189);
+ case 185: /* between_op ::= BETWEEN */
+ case 188: /* in_op ::= IN */ yytestcase(yyruleno==188);
{yymsp[0].minor.yy194 = 0;}
break;
- case 188: /* expr ::= expr between_op expr AND expr */
+ case 187: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
@@ -137401,7 +138484,7 @@ static void yy_reduce(
yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
}
break;
- case 191: /* expr ::= expr in_op LP exprlist RP */
+ case 190: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy148==0 ){
/* Expressions of the form
@@ -137454,14 +138537,14 @@ static void yy_reduce(
yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 192: /* expr ::= LP select RP */
+ case 191: /* expr ::= LP select RP */
{
spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
}
break;
- case 193: /* expr ::= expr in_op LP select RP */
+ case 192: /* expr ::= expr in_op LP select RP */
{
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
@@ -137469,7 +138552,7 @@ static void yy_reduce(
yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 194: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 193: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
@@ -137480,7 +138563,7 @@ static void yy_reduce(
yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
}
break;
- case 195: /* expr ::= EXISTS LP select RP */
+ case 194: /* expr ::= EXISTS LP select RP */
{
Expr *p;
spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
@@ -137488,7 +138571,7 @@ static void yy_reduce(
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
}
break;
- case 196: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 195: /* expr ::= CASE case_operand case_exprlist case_else END */
{
spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/
yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0);
@@ -137501,80 +138584,80 @@ static void yy_reduce(
}
}
break;
- case 197: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 196: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
- case 198: /* case_exprlist ::= WHEN expr THEN expr */
+ case 197: /* case_exprlist ::= WHEN expr THEN expr */
{
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
- case 201: /* case_operand ::= expr */
+ case 200: /* case_operand ::= expr */
{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
break;
- case 204: /* nexprlist ::= nexprlist COMMA expr */
+ case 203: /* nexprlist ::= nexprlist COMMA expr */
{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
break;
- case 205: /* nexprlist ::= expr */
+ case 204: /* nexprlist ::= expr */
{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
break;
- case 207: /* paren_exprlist ::= LP exprlist RP */
- case 212: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==212);
+ case 206: /* paren_exprlist ::= LP exprlist RP */
+ case 211: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==211);
{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
break;
- case 208: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 207: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194,
&yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF);
}
break;
- case 209: /* uniqueflag ::= UNIQUE */
- case 250: /* raisetype ::= ABORT */ yytestcase(yyruleno==250);
+ case 208: /* uniqueflag ::= UNIQUE */
+ case 249: /* raisetype ::= ABORT */ yytestcase(yyruleno==249);
{yymsp[0].minor.yy194 = OE_Abort;}
break;
- case 210: /* uniqueflag ::= */
+ case 209: /* uniqueflag ::= */
{yymsp[1].minor.yy194 = OE_None;}
break;
- case 213: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 212: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
}
break;
- case 214: /* eidlist ::= nm collate sortorder */
+ case 213: /* eidlist ::= nm collate sortorder */
{
yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
}
break;
- case 217: /* cmd ::= DROP INDEX ifexists fullname */
+ case 216: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
break;
- case 218: /* cmd ::= VACUUM */
+ case 217: /* cmd ::= VACUUM */
{sqlite3Vacuum(pParse,0);}
break;
- case 219: /* cmd ::= VACUUM nm */
+ case 218: /* cmd ::= VACUUM nm */
{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
break;
- case 220: /* cmd ::= PRAGMA nm dbnm */
+ case 219: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 221: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 220: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 222: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 221: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 223: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 222: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 224: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 223: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 227: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 226: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
@@ -137582,53 +138665,53 @@ static void yy_reduce(
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
}
break;
- case 228: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 227: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 229: /* trigger_time ::= BEFORE */
+ case 228: /* trigger_time ::= BEFORE */
{ yymsp[0].minor.yy194 = TK_BEFORE; }
break;
- case 230: /* trigger_time ::= AFTER */
+ case 229: /* trigger_time ::= AFTER */
{ yymsp[0].minor.yy194 = TK_AFTER; }
break;
- case 231: /* trigger_time ::= INSTEAD OF */
+ case 230: /* trigger_time ::= INSTEAD OF */
{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
break;
- case 232: /* trigger_time ::= */
+ case 231: /* trigger_time ::= */
{ yymsp[1].minor.yy194 = TK_BEFORE; }
break;
- case 233: /* trigger_event ::= DELETE|INSERT */
- case 234: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==234);
+ case 232: /* trigger_event ::= DELETE|INSERT */
+ case 233: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==233);
{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
break;
- case 235: /* trigger_event ::= UPDATE OF idlist */
+ case 234: /* trigger_event ::= UPDATE OF idlist */
{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
break;
- case 236: /* when_clause ::= */
- case 255: /* key_opt ::= */ yytestcase(yyruleno==255);
+ case 235: /* when_clause ::= */
+ case 254: /* key_opt ::= */ yytestcase(yyruleno==254);
{ yymsp[1].minor.yy72 = 0; }
break;
- case 237: /* when_clause ::= WHEN expr */
- case 256: /* key_opt ::= KEY expr */ yytestcase(yyruleno==256);
+ case 236: /* when_clause ::= WHEN expr */
+ case 255: /* key_opt ::= KEY expr */ yytestcase(yyruleno==255);
{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
break;
- case 238: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 237: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy145!=0 );
yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
}
break;
- case 239: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 238: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy145!=0 );
yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
}
break;
- case 240: /* trnm ::= nm DOT nm */
+ case 239: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -137636,33 +138719,33 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 241: /* tridxby ::= INDEXED BY nm */
+ case 240: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 242: /* tridxby ::= NOT INDEXED */
+ case 241: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 243: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+ case 242: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
break;
- case 244: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
+ case 243: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
break;
- case 245: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+ case 244: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
break;
- case 246: /* trigger_cmd ::= select */
+ case 245: /* trigger_cmd ::= select */
{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
break;
- case 247: /* expr ::= RAISE LP IGNORE RP */
+ case 246: /* expr ::= RAISE LP IGNORE RP */
{
spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
@@ -137671,7 +138754,7 @@ static void yy_reduce(
}
}
break;
- case 248: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 247: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
@@ -137680,130 +138763,131 @@ static void yy_reduce(
}
}
break;
- case 249: /* raisetype ::= ROLLBACK */
+ case 248: /* raisetype ::= ROLLBACK */
{yymsp[0].minor.yy194 = OE_Rollback;}
break;
- case 251: /* raisetype ::= FAIL */
+ case 250: /* raisetype ::= FAIL */
{yymsp[0].minor.yy194 = OE_Fail;}
break;
- case 252: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 251: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
}
break;
- case 253: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 252: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
}
break;
- case 254: /* cmd ::= DETACH database_kw_opt expr */
+ case 253: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
}
break;
- case 257: /* cmd ::= REINDEX */
+ case 256: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 258: /* cmd ::= REINDEX nm dbnm */
+ case 257: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 259: /* cmd ::= ANALYZE */
+ case 258: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 260: /* cmd ::= ANALYZE nm dbnm */
+ case 259: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 261: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 260: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
}
break;
- case 262: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 261: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
- case 263: /* add_column_fullname ::= fullname */
+ case 262: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
}
break;
- case 264: /* cmd ::= create_vtab */
+ case 263: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 265: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 264: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 266: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 265: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194);
}
break;
- case 267: /* vtabarg ::= */
+ case 266: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 268: /* vtabargtoken ::= ANY */
- case 269: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==269);
- case 270: /* lp ::= LP */ yytestcase(yyruleno==270);
+ case 267: /* vtabargtoken ::= ANY */
+ case 268: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==268);
+ case 269: /* lp ::= LP */ yytestcase(yyruleno==269);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 271: /* with ::= */
+ case 270: /* with ::= */
{yymsp[1].minor.yy285 = 0;}
break;
- case 272: /* with ::= WITH wqlist */
+ case 271: /* with ::= WITH wqlist */
{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
break;
- case 273: /* with ::= WITH RECURSIVE wqlist */
+ case 272: /* with ::= WITH RECURSIVE wqlist */
{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
break;
- case 274: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 273: /* wqlist ::= nm eidlist_opt AS LP select RP */
{
yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
}
break;
- case 275: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 274: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
{
yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
}
break;
default:
- /* (276) input ::= cmdlist */ yytestcase(yyruleno==276);
- /* (277) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==277);
- /* (278) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=278);
- /* (279) ecmd ::= SEMI */ yytestcase(yyruleno==279);
- /* (280) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==280);
- /* (281) explain ::= */ yytestcase(yyruleno==281);
- /* (282) trans_opt ::= */ yytestcase(yyruleno==282);
- /* (283) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==283);
- /* (284) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==284);
- /* (285) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==285);
- /* (286) savepoint_opt ::= */ yytestcase(yyruleno==286);
- /* (287) cmd ::= create_table create_table_args */ yytestcase(yyruleno==287);
- /* (288) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==288);
- /* (289) columnlist ::= columnname carglist */ yytestcase(yyruleno==289);
- /* (290) nm ::= ID|INDEXED */ yytestcase(yyruleno==290);
- /* (291) nm ::= STRING */ yytestcase(yyruleno==291);
- /* (292) nm ::= JOIN_KW */ yytestcase(yyruleno==292);
- /* (293) typetoken ::= typename */ yytestcase(yyruleno==293);
- /* (294) typename ::= ID|STRING */ yytestcase(yyruleno==294);
- /* (295) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
- /* (296) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=296);
- /* (297) carglist ::= carglist ccons */ yytestcase(yyruleno==297);
- /* (298) carglist ::= */ yytestcase(yyruleno==298);
- /* (299) ccons ::= NULL onconf */ yytestcase(yyruleno==299);
- /* (300) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==300);
- /* (301) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==301);
- /* (302) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=302);
- /* (303) tconscomma ::= */ yytestcase(yyruleno==303);
- /* (304) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=304);
- /* (305) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=305);
- /* (306) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=306);
- /* (307) oneselect ::= values */ yytestcase(yyruleno==307);
- /* (308) sclp ::= selcollist COMMA */ yytestcase(yyruleno==308);
- /* (309) as ::= ID|STRING */ yytestcase(yyruleno==309);
- /* (310) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=310);
+ /* (275) input ::= cmdlist */ yytestcase(yyruleno==275);
+ /* (276) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==276);
+ /* (277) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=277);
+ /* (278) ecmd ::= SEMI */ yytestcase(yyruleno==278);
+ /* (279) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==279);
+ /* (280) explain ::= */ yytestcase(yyruleno==280);
+ /* (281) trans_opt ::= */ yytestcase(yyruleno==281);
+ /* (282) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==282);
+ /* (283) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==283);
+ /* (284) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==284);
+ /* (285) savepoint_opt ::= */ yytestcase(yyruleno==285);
+ /* (286) cmd ::= create_table create_table_args */ yytestcase(yyruleno==286);
+ /* (287) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==287);
+ /* (288) columnlist ::= columnname carglist */ yytestcase(yyruleno==288);
+ /* (289) nm ::= ID|INDEXED */ yytestcase(yyruleno==289);
+ /* (290) nm ::= STRING */ yytestcase(yyruleno==290);
+ /* (291) nm ::= JOIN_KW */ yytestcase(yyruleno==291);
+ /* (292) typetoken ::= typename */ yytestcase(yyruleno==292);
+ /* (293) typename ::= ID|STRING */ yytestcase(yyruleno==293);
+ /* (294) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=294);
+ /* (295) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
+ /* (296) carglist ::= carglist ccons */ yytestcase(yyruleno==296);
+ /* (297) carglist ::= */ yytestcase(yyruleno==297);
+ /* (298) ccons ::= NULL onconf */ yytestcase(yyruleno==298);
+ /* (299) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==299);
+ /* (300) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==300);
+ /* (301) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=301);
+ /* (302) tconscomma ::= */ yytestcase(yyruleno==302);
+ /* (303) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=303);
+ /* (304) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=304);
+ /* (305) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=305);
+ /* (306) oneselect ::= values */ yytestcase(yyruleno==306);
+ /* (307) sclp ::= selcollist COMMA */ yytestcase(yyruleno==307);
+ /* (308) as ::= ID|STRING */ yytestcase(yyruleno==308);
+ /* (309) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=309);
+ /* (310) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==310);
/* (311) exprlist ::= nexprlist */ yytestcase(yyruleno==311);
/* (312) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=312);
/* (313) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=313);
@@ -138856,14 +139940,14 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*/
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
int nErr = 0; /* Number of errors encountered */
- int i; /* Loop counter */
void *pEngine; /* The LEMON-generated LALR(1) parser */
+ int n = 0; /* Length of the next token token */
int tokenType; /* type of the next token */
int lastTokenParsed = -1; /* type of the previous token */
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
- unsigned char zSpace[sizeof(yyParser)]; /* Space for parser engine object */
+ yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
#endif
assert( zSql!=0 );
@@ -138873,11 +139957,10 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
- i = 0;
assert( pzErrMsg!=0 );
/* sqlite3ParserTrace(stdout, "parser: "); */
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
- pEngine = zSpace;
+ pEngine = &sEngine;
sqlite3ParserInit(pEngine);
#else
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
@@ -138891,12 +139974,10 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( pParse->nVar==0 );
assert( pParse->pVList==0 );
while( 1 ){
- assert( i>=0 );
- if( zSql[i]!=0 ){
- pParse->sLastToken.z = &zSql[i];
- pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType);
- i += pParse->sLastToken.n;
- if( i>mxSqlLen ){
+ if( zSql[0]!=0 ){
+ n = sqlite3GetToken((u8*)zSql, &tokenType);
+ mxSqlLen -= n;
+ if( mxSqlLen<0 ){
pParse->rc = SQLITE_TOOBIG;
break;
}
@@ -138910,6 +139991,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
}else{
tokenType = TK_SEMI;
}
+ zSql -= n;
}
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
@@ -138918,18 +140000,21 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
break;
}
if( tokenType==TK_ILLEGAL ){
- sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
- &pParse->sLastToken);
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
break;
}
+ zSql += n;
}else{
+ pParse->sLastToken.z = zSql;
+ pParse->sLastToken.n = n;
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
+ zSql += n;
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
assert( nErr==0 );
- pParse->zTail = &zSql[i];
+ pParse->zTail = zSql;
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
@@ -138984,7 +140069,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
pParse->pAinc = p->pNext;
- sqlite3DbFree(db, p);
+ sqlite3DbFreeNN(db, p);
}
while( pParse->pZombieTab ){
Table *p = pParse->pZombieTab;
@@ -140305,6 +141390,21 @@ SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
}
/*
+** Set the value returned by the sqlite3_last_insert_rowid() API function.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ db->lastRowid = iRowid;
+ sqlite3_mutex_leave(db->mutex);
+}
+
+/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
SQLITE_API int sqlite3_changes(sqlite3 *db){
@@ -142463,16 +143563,18 @@ opendb_out:
#endif
#if defined(SQLITE_HAS_CODEC)
if( rc==SQLITE_OK ){
- const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
- if( zHexKey && zHexKey[0] ){
+ const char *zKey;
+ if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
u8 iByte;
int i;
- char zKey[40];
- for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){
- iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]);
- if( (i&1)!=0 ) zKey[i/2] = iByte;
+ char zDecoded[40];
+ for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
+ if( (i&1)!=0 ) zDecoded[i/2] = iByte;
}
- sqlite3_key_v2(db, 0, zKey, i/2);
+ sqlite3_key_v2(db, 0, zDecoded, i/2);
+ }else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){
+ sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey));
}
}
#endif
@@ -145054,8 +146156,9 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
** Return the number of bytes read, or 0 on error.
** The value is stored in *v.
*/
-SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
- const char *pStart = p;
+SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
+ const unsigned char *p = (const unsigned char*)pBuf;
+ const unsigned char *pStart = p;
u32 a;
u64 b;
int shift;
@@ -145076,8 +146179,8 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
}
/*
-** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a
-** 32-bit integer before it is returned.
+** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to
+** a non-negative 32-bit integer before it is returned.
*/
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
u32 a;
@@ -145093,7 +146196,9 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
a = (a & 0x0FFFFFFF );
- *pi = (int)(a | ((u32)(*p & 0x0F) << 28));
+ *pi = (int)(a | ((u32)(*p & 0x07) << 28));
+ assert( 0==(a & 0x80000000) );
+ assert( *pi>=0 );
return 5;
}
@@ -145923,65 +147028,66 @@ static int fts3InitVtab(
break;
}
}
- if( iOpt==SizeofArray(aFts4Opt) ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
- rc = SQLITE_ERROR;
- }else{
- switch( iOpt ){
- case 0: /* MATCHINFO */
- if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bNoDocsize = 1;
- break;
+ switch( iOpt ){
+ case 0: /* MATCHINFO */
+ if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
+ rc = SQLITE_ERROR;
+ }
+ bNoDocsize = 1;
+ break;
- case 1: /* PREFIX */
- sqlite3_free(zPrefix);
- zPrefix = zVal;
- zVal = 0;
- break;
+ case 1: /* PREFIX */
+ sqlite3_free(zPrefix);
+ zPrefix = zVal;
+ zVal = 0;
+ break;
- case 2: /* COMPRESS */
- sqlite3_free(zCompress);
- zCompress = zVal;
- zVal = 0;
- break;
+ case 2: /* COMPRESS */
+ sqlite3_free(zCompress);
+ zCompress = zVal;
+ zVal = 0;
+ break;
- case 3: /* UNCOMPRESS */
- sqlite3_free(zUncompress);
- zUncompress = zVal;
- zVal = 0;
- break;
+ case 3: /* UNCOMPRESS */
+ sqlite3_free(zUncompress);
+ zUncompress = zVal;
+ zVal = 0;
+ break;
- case 4: /* ORDER */
- if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
- && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
- ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
- break;
+ case 4: /* ORDER */
+ if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
+ && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
+ ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
+ rc = SQLITE_ERROR;
+ }
+ bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
+ break;
- case 5: /* CONTENT */
- sqlite3_free(zContent);
- zContent = zVal;
- zVal = 0;
- break;
+ case 5: /* CONTENT */
+ sqlite3_free(zContent);
+ zContent = zVal;
+ zVal = 0;
+ break;
- case 6: /* LANGUAGEID */
- assert( iOpt==6 );
- sqlite3_free(zLanguageid);
- zLanguageid = zVal;
- zVal = 0;
- break;
+ case 6: /* LANGUAGEID */
+ assert( iOpt==6 );
+ sqlite3_free(zLanguageid);
+ zLanguageid = zVal;
+ zVal = 0;
+ break;
- case 7: /* NOTINDEXED */
- azNotindexed[nNotindexed++] = zVal;
- zVal = 0;
- break;
- }
+ case 7: /* NOTINDEXED */
+ azNotindexed[nNotindexed++] = zVal;
+ zVal = 0;
+ break;
+
+ default:
+ assert( iOpt==SizeofArray(aFts4Opt) );
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
+ rc = SQLITE_ERROR;
+ break;
}
sqlite3_free(zVal);
}
@@ -146102,7 +147208,9 @@ static int fts3InitVtab(
char *z;
int n = 0;
z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
- memcpy(zCsr, z, n);
+ if( n>0 ){
+ memcpy(zCsr, z, n);
+ }
zCsr[n] = '\0';
sqlite3Fts3Dequote(zCsr);
p->azColumn[iCol] = zCsr;
@@ -146548,7 +147656,8 @@ static int fts3ScanInteriorNode(
isFirstTerm = 0;
zCsr += fts3GetVarint32(zCsr, &nSuffix);
- if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
+ assert( nPrefix>=0 && nSuffix>=0 );
+ if( &zCsr[nSuffix]>zEnd ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
@@ -147358,7 +148467,7 @@ SQLITE_PRIVATE int sqlite3Fts3FirstFilter(
fts3ColumnlistCopy(0, &p);
}
- while( p<pEnd && *p==0x01 ){
+ while( p<pEnd ){
sqlite3_int64 iCol;
p++;
p += sqlite3Fts3GetVarint(p, &iCol);
@@ -148038,33 +149147,38 @@ static int fts3ColumnMethod(
/* The column value supplied by SQLite must be in range. */
assert( iCol>=0 && iCol<=p->nColumn+2 );
- if( iCol==p->nColumn+1 ){
- /* This call is a request for the "docid" column. Since "docid" is an
- ** alias for "rowid", use the xRowid() method to obtain the value.
- */
- sqlite3_result_int64(pCtx, pCsr->iPrevId);
- }else if( iCol==p->nColumn ){
- /* The extra column whose name is the same as the table.
- ** Return a blob which is a pointer to the cursor. */
- sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
- }else if( iCol==p->nColumn+2 && pCsr->pExpr ){
- sqlite3_result_int64(pCtx, pCsr->iLangid);
- }else{
- /* The requested column is either a user column (one that contains
- ** indexed data), or the language-id column. */
- rc = fts3CursorSeek(0, pCsr);
+ switch( iCol-p->nColumn ){
+ case 0:
+ /* The special 'table-name' column */
+ sqlite3_result_blob(pCtx, &pCsr, sizeof(Fts3Cursor*), SQLITE_TRANSIENT);
+ sqlite3_result_subtype(pCtx, SQLITE_BLOB);
+ break;
- if( rc==SQLITE_OK ){
- if( iCol==p->nColumn+2 ){
- int iLangid = 0;
- if( p->zLanguageid ){
- iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1);
- }
- sqlite3_result_int(pCtx, iLangid);
- }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
+ case 1:
+ /* The docid column */
+ sqlite3_result_int64(pCtx, pCsr->iPrevId);
+ break;
+
+ case 2:
+ if( pCsr->pExpr ){
+ sqlite3_result_int64(pCtx, pCsr->iLangid);
+ break;
+ }else if( p->zLanguageid==0 ){
+ sqlite3_result_int(pCtx, 0);
+ break;
+ }else{
+ iCol = p->nColumn;
+ /* fall-through */
+ }
+
+ default:
+ /* A user column. Or, if this is a full-table scan, possibly the
+ ** language-id column. Seek the cursor. */
+ rc = fts3CursorSeek(0, pCsr);
+ if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
}
- }
+ break;
}
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
@@ -148113,8 +149227,10 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
Fts3Table *p = (Fts3Table*)pVtab;
- int rc = sqlite3Fts3PendingTermsFlush(p);
+ int rc;
+ i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
+ rc = sqlite3Fts3PendingTermsFlush(p);
if( rc==SQLITE_OK
&& p->nLeafAdd>(nMinMerge/16)
&& p->nAutoincrmerge && p->nAutoincrmerge!=0xff
@@ -148129,6 +149245,7 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
}
sqlite3Fts3SegmentsClose(p);
+ sqlite3_set_last_insert_rowid(p->db, iLastRowid);
return rc;
}
@@ -148141,17 +149258,11 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
static int fts3SetHasStat(Fts3Table *p){
int rc = SQLITE_OK;
if( p->bHasStat==2 ){
- const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
- char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
- if( zSql ){
- sqlite3_stmt *pStmt = 0;
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- if( rc==SQLITE_OK ){
- int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
- rc = sqlite3_finalize(pStmt);
- if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat;
- }
- sqlite3_free(zSql);
+ char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
+ if( zTbl ){
+ int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
+ sqlite3_free(zTbl);
+ p->bHasStat = (res==SQLITE_OK);
}else{
rc = SQLITE_NOMEM;
}
@@ -148258,18 +149369,16 @@ static int fts3FunctionArg(
sqlite3_value *pVal, /* argv[0] passed to function */
Fts3Cursor **ppCsr /* OUT: Store cursor handle here */
){
- Fts3Cursor *pRet;
- if( sqlite3_value_type(pVal)!=SQLITE_BLOB
- || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
- ){
+ int rc = SQLITE_OK;
+ if( sqlite3_value_subtype(pVal)==SQLITE_BLOB ){
+ *ppCsr = *(Fts3Cursor**)sqlite3_value_blob(pVal);
+ }else{
char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
sqlite3_result_error(pContext, zErr, -1);
sqlite3_free(zErr);
- return SQLITE_ERROR;
+ rc = SQLITE_ERROR;
}
- memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
- *ppCsr = pRet;
- return SQLITE_OK;
+ return rc;
}
/*
@@ -148656,7 +149765,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
#endif
/* Create the virtual table wrapper around the hash-table and overload
- ** the two scalar functions. If this is successful, register the
+ ** the four scalar functions. If this is successful, register the
** module with sqlite.
*/
if( SQLITE_OK==rc
@@ -149239,7 +150348,7 @@ static int fts3EvalIncrPhraseNext(
** one incremental token. In which case the bIncr flag is set. */
assert( p->bIncr==1 );
- if( p->nToken==1 && p->bIncr ){
+ if( p->nToken==1 ){
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
&pDL->iDocid, &pDL->pList, &pDL->nList
);
@@ -149472,6 +150581,7 @@ static void fts3EvalTokenCosts(
** the number of overflow pages consumed by a record B bytes in size.
*/
static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
+ int rc = SQLITE_OK;
if( pCsr->nRowAvg==0 ){
/* The average document size, which is required to calculate the cost
** of each doclist, has not yet been determined. Read the required
@@ -149484,7 +150594,6 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
** data stored in all rows of each column of the table, from left
** to right.
*/
- int rc;
Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
sqlite3_stmt *pStmt;
sqlite3_int64 nDoc = 0;
@@ -149511,11 +150620,10 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
assert( pCsr->nRowAvg>0 );
rc = sqlite3_reset(pStmt);
- if( rc!=SQLITE_OK ) return rc;
}
*pnPage = pCsr->nRowAvg;
- return SQLITE_OK;
+ return rc;
}
/*
@@ -149865,7 +150973,8 @@ static void fts3EvalNextRow(
pExpr->iDocid = pLeft->iDocid;
pExpr->bEof = (pLeft->bEof || pRight->bEof);
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
- if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
+ assert( pRight->eType==FTSQUERY_PHRASE );
+ if( pRight->pPhrase->doclist.aAll ){
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
memset(pDl->pList, 0, pDl->nList);
@@ -149894,7 +151003,7 @@ static void fts3EvalNextRow(
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
fts3EvalNextRow(pCsr, pLeft, pRc);
- }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){
+ }else if( pLeft->bEof || iCmp>0 ){
fts3EvalNextRow(pCsr, pRight, pRc);
}else{
fts3EvalNextRow(pCsr, pLeft, pRc);
@@ -149986,7 +151095,6 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
*/
if( *pRc==SQLITE_OK
&& pExpr->eType==FTSQUERY_NEAR
- && pExpr->bEof==0
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
){
Fts3Expr *p;
@@ -149995,42 +151103,39 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
/* Allocate temporary working space. */
for(p=pExpr; p->pLeft; p=p->pLeft){
+ assert( p->pRight->pPhrase->doclist.nList>0 );
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
- if( nTmp==0 ){
+ aTmp = sqlite3_malloc(nTmp*2);
+ if( !aTmp ){
+ *pRc = SQLITE_NOMEM;
res = 0;
}else{
- aTmp = sqlite3_malloc(nTmp*2);
- if( !aTmp ){
- *pRc = SQLITE_NOMEM;
- res = 0;
- }else{
- char *aPoslist = p->pPhrase->doclist.pList;
- int nToken = p->pPhrase->nToken;
-
- for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
- Fts3Phrase *pPhrase = p->pRight->pPhrase;
- int nNear = p->nNear;
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
-
- aPoslist = pExpr->pRight->pPhrase->doclist.pList;
- nToken = pExpr->pRight->pPhrase->nToken;
- for(p=pExpr->pLeft; p && res; p=p->pLeft){
- int nNear;
- Fts3Phrase *pPhrase;
- assert( p->pParent && p->pParent->pLeft==p );
- nNear = p->pParent->nNear;
- pPhrase = (
- p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
- );
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
+ char *aPoslist = p->pPhrase->doclist.pList;
+ int nToken = p->pPhrase->nToken;
+
+ for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
+ Fts3Phrase *pPhrase = p->pRight->pPhrase;
+ int nNear = p->nNear;
+ res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
- sqlite3_free(aTmp);
+ aPoslist = pExpr->pRight->pPhrase->doclist.pList;
+ nToken = pExpr->pRight->pPhrase->nToken;
+ for(p=pExpr->pLeft; p && res; p=p->pLeft){
+ int nNear;
+ Fts3Phrase *pPhrase;
+ assert( p->pParent && p->pParent->pLeft==p );
+ nNear = p->pParent->nNear;
+ pPhrase = (
+ p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
+ );
+ res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+ }
}
+
+ sqlite3_free(aTmp);
}
return res;
@@ -159739,11 +160844,14 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
** Convert the text beginning at *pz into an integer and return
** its value. Advance *pz to point to the first character past
** the integer.
+**
+** This function used for parameters to merge= and incrmerge=
+** commands.
*/
static int fts3Getint(const char **pz){
const char *z = *pz;
int i = 0;
- while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0';
+ while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
*pz = z;
return i;
}
@@ -162309,16 +163417,16 @@ static int unicodeAddExceptions(
){
const unsigned char *z = (const unsigned char *)zIn;
const unsigned char *zTerm = &z[nIn];
- int iCode;
+ unsigned int iCode;
int nEntry = 0;
assert( bAlnum==0 || bAlnum==1 );
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
- if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic(iCode)==0
+ assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
+ if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
+ && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
){
nEntry++;
}
@@ -162335,13 +163443,13 @@ static int unicodeAddExceptions(
z = (const unsigned char *)zIn;
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic(iCode)==0
+ if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
+ && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
){
int i, j;
- for(i=0; i<nNew && aNew[i]<iCode; i++);
+ for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
- aNew[i] = iCode;
+ aNew[i] = (int)iCode;
nNew++;
}
}
@@ -162491,7 +163599,7 @@ static int unicodeNext(
){
unicode_cursor *pCsr = (unicode_cursor *)pC;
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
- int iCode = 0;
+ unsigned int iCode = 0;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
@@ -162503,7 +163611,7 @@ static int unicodeNext(
** the input. */
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- if( unicodeIsAlnum(p, iCode) ) break;
+ if( unicodeIsAlnum(p, (int)iCode) ) break;
zStart = z;
}
if( zStart>=zTerm ) return SQLITE_DONE;
@@ -162523,7 +163631,7 @@ static int unicodeNext(
/* Write the folded case of the last character read to the output */
zEnd = z;
- iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
+ iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
@@ -162531,8 +163639,8 @@ static int unicodeNext(
/* If the cursor is not at EOF, read the next character */
if( z>=zTerm ) break;
READ_UTF8(z, zTerm, iCode);
- }while( unicodeIsAlnum(p, iCode)
- || sqlite3FtsUnicodeIsdiacritic(iCode)
+ }while( unicodeIsAlnum(p, (int)iCode)
+ || sqlite3FtsUnicodeIsdiacritic((int)iCode)
);
/* Set the output variables and return. */
@@ -162696,9 +163804,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
- if( c<128 ){
- return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
- }else if( c<(1<<22) ){
+ if( (unsigned int)c<128 ){
+ return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
+ }else if( (unsigned int)c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes = 0;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
@@ -162891,16 +163999,17 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
int ret = c;
- assert( c>=0 );
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
+ const struct TableEntry *p;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
+ assert( c>aEntry[0].iCode );
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
@@ -162911,14 +164020,12 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
iHi = iTest-1;
}
}
- assert( iRes<0 || c>=aEntry[iRes].iCode );
- if( iRes>=0 ){
- const struct TableEntry *p = &aEntry[iRes];
- if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
- ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
- assert( ret>0 );
- }
+ assert( iRes>=0 && c>=aEntry[iRes].iCode );
+ p = &aEntry[iRes];
+ if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
+ ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
+ assert( ret>0 );
}
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
@@ -163395,15 +164502,15 @@ static i64 readInt64(u8 *p){
memcpy(&x, p, 8);
return x;
#else
- return (
- (((i64)p[0]) << 56) +
- (((i64)p[1]) << 48) +
- (((i64)p[2]) << 40) +
- (((i64)p[3]) << 32) +
- (((i64)p[4]) << 24) +
- (((i64)p[5]) << 16) +
- (((i64)p[6]) << 8) +
- (((i64)p[7]) << 0)
+ return (i64)(
+ (((u64)p[0]) << 56) +
+ (((u64)p[1]) << 48) +
+ (((u64)p[2]) << 40) +
+ (((u64)p[3]) << 32) +
+ (((u64)p[4]) << 24) +
+ (((u64)p[5]) << 16) +
+ (((u64)p[6]) << 8) +
+ (((u64)p[7]) << 0)
);
#endif
}
@@ -166135,12 +167242,36 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
, pRtree->zDb, pRtree->zName, zNewName
);
if( zSql ){
+ nodeBlobReset(pRtree);
rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
return rc;
}
+/*
+** The xSavepoint method.
+**
+** This module does not need to do anything to support savepoints. However,
+** it uses this hook to close any open blob handle. This is done because a
+** DROP TABLE command - which fortunately always opens a savepoint - cannot
+** succeed if there are any open blob handles. i.e. if the blob handle were
+** not closed here, the following would fail:
+**
+** BEGIN;
+** INSERT INTO rtree...
+** DROP TABLE <tablename>; -- Would fail with SQLITE_LOCKED
+** COMMIT;
+*/
+static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
+ Rtree *pRtree = (Rtree *)pVtab;
+ int iwt = pRtree->inWrTrans;
+ UNUSED_PARAMETER(iSavepoint);
+ pRtree->inWrTrans = 0;
+ nodeBlobReset(pRtree);
+ pRtree->inWrTrans = iwt;
+ return SQLITE_OK;
+}
/*
** This function populates the pRtree->nRowEst variable with an estimate
@@ -166187,7 +167318,7 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
}
static sqlite3_module rtreeModule = {
- 0, /* iVersion */
+ 2, /* iVersion */
rtreeCreate, /* xCreate - create a table */
rtreeConnect, /* xConnect - connect to an existing table */
rtreeBestIndex, /* xBestIndex - Determine search strategy */
@@ -166207,7 +167338,7 @@ static sqlite3_module rtreeModule = {
rtreeEndTransaction, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
- 0, /* xSavepoint */
+ rtreeSavepoint, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
};
@@ -168464,6 +169595,7 @@ struct sqlite3rbu {
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
const char *zVfsName; /* Name of automatically created rbu vfs */
rbu_file *pTargetFd; /* File handle open on target db */
+ int nPagePerSector; /* Pages per sector for pTargetFd */
i64 iOalSz;
i64 nPhaseOneStep;
@@ -170728,6 +171860,23 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
p->rc = SQLITE_DONE;
p->eStage = RBU_STAGE_DONE;
+ }else{
+ int nSectorSize;
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
+ assert( p->nPagePerSector==0 );
+ nSectorSize = pDb->pMethods->xSectorSize(pDb);
+ if( nSectorSize>p->pgsz ){
+ p->nPagePerSector = nSectorSize / p->pgsz;
+ }else{
+ p->nPagePerSector = 1;
+ }
+
+ /* Call xSync() on the wal file. This causes SQLite to sync the
+ ** directory in which the target database and the wal file reside, in
+ ** case it has not been synced since the rename() call in
+ ** rbuMoveOalFile(). */
+ p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
}
}
}
@@ -171383,9 +172532,26 @@ SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){
p->rc = SQLITE_DONE;
}
}else{
- RbuFrame *pFrame = &p->aFrame[p->nStep];
- rbuCheckpointFrame(p, pFrame);
- p->nStep++;
+ /* At one point the following block copied a single frame from the
+ ** wal file to the database file. So that one call to sqlite3rbu_step()
+ ** checkpointed a single frame.
+ **
+ ** However, if the sector-size is larger than the page-size, and the
+ ** application calls sqlite3rbu_savestate() or close() immediately
+ ** after this step, then rbu_step() again, then a power failure occurs,
+ ** then the database page written here may be damaged. Work around
+ ** this by checkpointing frames until the next page in the aFrame[]
+ ** lies on a different disk sector to the current one. */
+ u32 iSector;
+ do{
+ RbuFrame *pFrame = &p->aFrame[p->nStep];
+ iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
+ rbuCheckpointFrame(p, pFrame);
+ p->nStep++;
+ }while( p->nStep<p->nFrame
+ && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
+ && p->rc==SQLITE_OK
+ );
}
p->nProgress++;
}
@@ -171826,6 +172992,12 @@ SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
}
+ /* Sync the db file if currently doing an incremental checkpoint */
+ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+ }
+
rbuSaveState(p, p->eStage);
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
@@ -171950,6 +173122,12 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
}
+ /* Sync the db file */
+ if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+ }
+
p->rc = rc;
rbuSaveState(p, p->eStage);
rc = p->rc;
@@ -178317,6 +179495,7 @@ static const char jsonIsSpace[] = {
** but the definitions need to be repeated for separate compilation. */
typedef sqlite3_uint64 u64;
typedef unsigned int u32;
+ typedef unsigned short int u16;
typedef unsigned char u8;
#endif
@@ -178365,9 +179544,10 @@ static const char * const jsonType[] = {
#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
#define JNODE_REMOVE 0x04 /* Do not output */
-#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
-#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
-#define JNODE_LABEL 0x20 /* Is a label of an object */
+#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
+#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
+#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
+#define JNODE_LABEL 0x40 /* Is a label of an object */
/* A single node of parsed JSON
@@ -178375,12 +179555,13 @@ static const char * const jsonType[] = {
struct JsonNode {
u8 eType; /* One of the JSON_ type values */
u8 jnFlags; /* JNODE flags */
- u8 iVal; /* Replacement value when JNODE_REPLACE */
u32 n; /* Bytes of content, or number of sub-nodes */
union {
const char *zJContent; /* Content for INT, REAL, and STRING */
u32 iAppend; /* More terms for ARRAY and OBJECT */
u32 iKey; /* Key for ARRAY objects in json_tree() */
+ u32 iReplace; /* Replacement content for JNODE_REPLACE */
+ JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */
} u;
};
@@ -178394,8 +179575,19 @@ struct JsonParse {
u32 *aUp; /* Index of parent of each node */
u8 oom; /* Set to true if out of memory */
u8 nErr; /* Number of errors seen */
+ u16 iDepth; /* Nesting depth */
+ int nJson; /* Length of the zJson string in bytes */
};
+/*
+** Maximum nesting depth of JSON for this implementation.
+**
+** This limit is needed to avoid a stack overflow in the recursive
+** descent parser. A depth of 2000 is far deeper than any sane JSON
+** should go.
+*/
+#define JSON_MAX_DEPTH 2000
+
/**************************************************************************
** Utility routines for dealing with JsonString objects
**************************************************************************/
@@ -178628,6 +179820,14 @@ static void jsonParseReset(JsonParse *pParse){
}
/*
+** Free a JsonParse object that was obtained from sqlite3_malloc().
+*/
+static void jsonParseFree(JsonParse *pParse){
+ jsonParseReset(pParse);
+ sqlite3_free(pParse);
+}
+
+/*
** Convert the JsonNode pNode into a pure JSON string and
** append to pOut. Subsubstructure is also included. Return
** the number of JsonNode objects that are encoded.
@@ -178637,6 +179837,13 @@ static void jsonRenderNode(
JsonString *pOut, /* Write JSON here */
sqlite3_value **aReplace /* Replacement values */
){
+ if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
+ if( pNode->jnFlags & JNODE_REPLACE ){
+ jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
+ return;
+ }
+ pNode = pNode->u.pPatch;
+ }
switch( pNode->eType ){
default: {
assert( pNode->eType==JSON_NULL );
@@ -178668,12 +179875,7 @@ static void jsonRenderNode(
jsonAppendChar(pOut, '[');
for(;;){
while( j<=pNode->n ){
- if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
- if( pNode[j].jnFlags & JNODE_REPLACE ){
- jsonAppendSeparator(pOut);
- jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
- }
- }else{
+ if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
jsonAppendSeparator(pOut);
jsonRenderNode(&pNode[j], pOut, aReplace);
}
@@ -178695,11 +179897,7 @@ static void jsonRenderNode(
jsonAppendSeparator(pOut);
jsonRenderNode(&pNode[j], pOut, aReplace);
jsonAppendChar(pOut, ':');
- if( pNode[j+1].jnFlags & JNODE_REPLACE ){
- jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
- }else{
- jsonRenderNode(&pNode[j+1], pOut, aReplace);
- }
+ jsonRenderNode(&pNode[j+1], pOut, aReplace);
}
j += 1 + jsonNodeSize(&pNode[j+1]);
}
@@ -178926,7 +180124,6 @@ static int jsonParseAddNode(
p = &pParse->aNode[pParse->nNode];
p->eType = (u8)eType;
p->jnFlags = 0;
- p->iVal = 0;
p->n = n;
p->u.zJContent = zContent;
return pParse->nNode++;
@@ -178955,15 +180152,18 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
int iThis;
int x;
JsonNode *pNode;
- while( safe_isspace(pParse->zJson[i]) ){ i++; }
- if( (c = pParse->zJson[i])=='{' ){
+ const char *z = pParse->zJson;
+ while( safe_isspace(z[i]) ){ i++; }
+ if( (c = z[i])=='{' ){
/* Parse object */
iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
if( iThis<0 ) return -1;
for(j=i+1;;j++){
- while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ while( safe_isspace(z[j]) ){ j++; }
+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
x = jsonParseValue(pParse, j);
if( x<0 ){
+ pParse->iDepth--;
if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
return -1;
}
@@ -178972,14 +180172,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
if( pNode->eType!=JSON_STRING ) return -1;
pNode->jnFlags |= JNODE_LABEL;
j = x;
- while( safe_isspace(pParse->zJson[j]) ){ j++; }
- if( pParse->zJson[j]!=':' ) return -1;
+ while( safe_isspace(z[j]) ){ j++; }
+ if( z[j]!=':' ) return -1;
j++;
x = jsonParseValue(pParse, j);
+ pParse->iDepth--;
if( x<0 ) return -1;
j = x;
- while( safe_isspace(pParse->zJson[j]) ){ j++; }
- c = pParse->zJson[j];
+ while( safe_isspace(z[j]) ){ j++; }
+ c = z[j];
if( c==',' ) continue;
if( c!='}' ) return -1;
break;
@@ -178991,15 +180192,17 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
if( iThis<0 ) return -1;
for(j=i+1;;j++){
- while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ while( safe_isspace(z[j]) ){ j++; }
+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
x = jsonParseValue(pParse, j);
+ pParse->iDepth--;
if( x<0 ){
if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
return -1;
}
j = x;
- while( safe_isspace(pParse->zJson[j]) ){ j++; }
- c = pParse->zJson[j];
+ while( safe_isspace(z[j]) ){ j++; }
+ c = z[j];
if( c==',' ) continue;
if( c!=']' ) return -1;
break;
@@ -179011,13 +180214,16 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
u8 jnFlags = 0;
j = i+1;
for(;;){
- c = pParse->zJson[j];
- if( c==0 ) return -1;
+ c = z[j];
+ if( (c & ~0x1f)==0 ){
+ /* Control characters are not allowed in strings */
+ return -1;
+ }
if( c=='\\' ){
- c = pParse->zJson[++j];
+ c = z[++j];
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|| c=='n' || c=='r' || c=='t'
- || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){
+ || (c=='u' && jsonIs4Hex(z+j+1)) ){
jnFlags = JNODE_ESCAPE;
}else{
return -1;
@@ -179027,55 +180233,60 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
}
j++;
}
- jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
+ jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
return j+1;
}else if( c=='n'
- && strncmp(pParse->zJson+i,"null",4)==0
- && !safe_isalnum(pParse->zJson[i+4]) ){
+ && strncmp(z+i,"null",4)==0
+ && !safe_isalnum(z[i+4]) ){
jsonParseAddNode(pParse, JSON_NULL, 0, 0);
return i+4;
}else if( c=='t'
- && strncmp(pParse->zJson+i,"true",4)==0
- && !safe_isalnum(pParse->zJson[i+4]) ){
+ && strncmp(z+i,"true",4)==0
+ && !safe_isalnum(z[i+4]) ){
jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
return i+4;
}else if( c=='f'
- && strncmp(pParse->zJson+i,"false",5)==0
- && !safe_isalnum(pParse->zJson[i+5]) ){
+ && strncmp(z+i,"false",5)==0
+ && !safe_isalnum(z[i+5]) ){
jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
return i+5;
}else if( c=='-' || (c>='0' && c<='9') ){
/* Parse number */
u8 seenDP = 0;
u8 seenE = 0;
+ assert( '-' < '0' );
+ if( c<='0' ){
+ j = c=='-' ? i+1 : i;
+ if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
+ }
j = i+1;
for(;; j++){
- c = pParse->zJson[j];
+ c = z[j];
if( c>='0' && c<='9' ) continue;
if( c=='.' ){
- if( pParse->zJson[j-1]=='-' ) return -1;
+ if( z[j-1]=='-' ) return -1;
if( seenDP ) return -1;
seenDP = 1;
continue;
}
if( c=='e' || c=='E' ){
- if( pParse->zJson[j-1]<'0' ) return -1;
+ if( z[j-1]<'0' ) return -1;
if( seenE ) return -1;
seenDP = seenE = 1;
- c = pParse->zJson[j+1];
+ c = z[j+1];
if( c=='+' || c=='-' ){
j++;
- c = pParse->zJson[j+1];
+ c = z[j+1];
}
if( c<'0' || c>'9' ) return -1;
continue;
}
break;
}
- if( pParse->zJson[j-1]<'0' ) return -1;
+ if( z[j-1]<'0' ) return -1;
jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
- j - i, &pParse->zJson[i]);
+ j - i, &z[i]);
return j;
}else if( c=='}' ){
return -2; /* End of {...} */
@@ -179107,6 +180318,7 @@ static int jsonParse(
i = jsonParseValue(pParse, 0);
if( pParse->oom ) i = -1;
if( i>0 ){
+ assert( pParse->iDepth==0 );
while( safe_isspace(zJson[i]) ) i++;
if( zJson[i] ) i = -1;
}
@@ -179167,6 +180379,49 @@ static int jsonParseFindParents(JsonParse *pParse){
}
/*
+** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
+*/
+#define JSON_CACHE_ID (-429938)
+
+/*
+** Obtain a complete parse of the JSON found in the first argument
+** of the argv array. Use the sqlite3_get_auxdata() cache for this
+** parse if it is available. If the cache is not available or if it
+** is no longer valid, parse the JSON again and return the new parse,
+** and also register the new parse so that it will be available for
+** future sqlite3_get_auxdata() calls.
+*/
+static JsonParse *jsonParseCached(
+ sqlite3_context *pCtx,
+ sqlite3_value **argv
+){
+ const char *zJson = (const char*)sqlite3_value_text(argv[0]);
+ int nJson = sqlite3_value_bytes(argv[0]);
+ JsonParse *p;
+ if( zJson==0 ) return 0;
+ p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
+ if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
+ p->nErr = 0;
+ return p; /* The cached entry matches, so return it */
+ }
+ p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+ if( p==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ return 0;
+ }
+ memset(p, 0, sizeof(*p));
+ p->zJson = (char*)&p[1];
+ memcpy((char*)p->zJson, zJson, nJson+1);
+ if( jsonParse(p, pCtx, p->zJson) ){
+ sqlite3_free(p);
+ return 0;
+ }
+ p->nJson = nJson;
+ sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
+ return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
+}
+
+/*
** Compare the OBJECT label at pNode against zKey,nKey. Return true on
** a match.
*/
@@ -179392,6 +180647,25 @@ static void jsonWrongNumArgs(
sqlite3_free(zMsg);
}
+/*
+** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
+*/
+static void jsonRemoveAllNulls(JsonNode *pNode){
+ int i, n;
+ assert( pNode->eType==JSON_OBJECT );
+ n = pNode->n;
+ for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
+ switch( pNode[i].eType ){
+ case JSON_NULL:
+ pNode[i].jnFlags |= JNODE_REMOVE;
+ break;
+ case JSON_OBJECT:
+ jsonRemoveAllNulls(&pNode[i]);
+ break;
+ }
+ }
+}
+
/****************************************************************************
** SQL functions used for testing and debugging
@@ -179512,29 +180786,30 @@ static void jsonArrayLengthFunc(
int argc,
sqlite3_value **argv
){
- JsonParse x; /* The parse */
+ JsonParse *p; /* The parse */
sqlite3_int64 n = 0;
u32 i;
JsonNode *pNode;
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- assert( x.nNode );
+ p = jsonParseCached(ctx, argv);
+ if( p==0 ) return;
+ assert( p->nNode );
if( argc==2 ){
const char *zPath = (const char*)sqlite3_value_text(argv[1]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
+ pNode = jsonLookup(p, zPath, 0, ctx);
}else{
- pNode = x.aNode;
+ pNode = p->aNode;
}
if( pNode==0 ){
- x.nErr = 1;
- }else if( pNode->eType==JSON_ARRAY ){
+ return;
+ }
+ if( pNode->eType==JSON_ARRAY ){
assert( (pNode->jnFlags & JNODE_APPEND)==0 );
for(i=1; i<=pNode->n; n++){
i += jsonNodeSize(&pNode[i]);
}
}
- if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
- jsonParseReset(&x);
+ sqlite3_result_int64(ctx, n);
}
/*
@@ -179550,20 +180825,21 @@ static void jsonExtractFunc(
int argc,
sqlite3_value **argv
){
- JsonParse x; /* The parse */
+ JsonParse *p; /* The parse */
JsonNode *pNode;
const char *zPath;
JsonString jx;
int i;
if( argc<2 ) return;
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ p = jsonParseCached(ctx, argv);
+ if( p==0 ) return;
jsonInit(&jx, ctx);
jsonAppendChar(&jx, '[');
for(i=1; i<argc; i++){
zPath = (const char*)sqlite3_value_text(argv[i]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
- if( x.nErr ) break;
+ pNode = jsonLookup(p, zPath, 0, ctx);
+ if( p->nErr ) break;
if( argc>2 ){
jsonAppendSeparator(&jx);
if( pNode ){
@@ -179581,9 +180857,107 @@ static void jsonExtractFunc(
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
jsonReset(&jx);
+}
+
+/* This is the RFC 7396 MergePatch algorithm.
+*/
+static JsonNode *jsonMergePatch(
+ JsonParse *pParse, /* The JSON parser that contains the TARGET */
+ u32 iTarget, /* Node of the TARGET in pParse */
+ JsonNode *pPatch /* The PATCH */
+){
+ u32 i, j;
+ u32 iRoot;
+ JsonNode *pTarget;
+ if( pPatch->eType!=JSON_OBJECT ){
+ return pPatch;
+ }
+ assert( iTarget>=0 && iTarget<pParse->nNode );
+ pTarget = &pParse->aNode[iTarget];
+ assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
+ if( pTarget->eType!=JSON_OBJECT ){
+ jsonRemoveAllNulls(pPatch);
+ return pPatch;
+ }
+ iRoot = iTarget;
+ for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
+ u32 nKey;
+ const char *zKey;
+ assert( pPatch[i].eType==JSON_STRING );
+ assert( pPatch[i].jnFlags & JNODE_LABEL );
+ nKey = pPatch[i].n;
+ zKey = pPatch[i].u.zJContent;
+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+ for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
+ assert( pTarget[j].eType==JSON_STRING );
+ assert( pTarget[j].jnFlags & JNODE_LABEL );
+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+ if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
+ if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
+ if( pPatch[i+1].eType==JSON_NULL ){
+ pTarget[j+1].jnFlags |= JNODE_REMOVE;
+ }else{
+ JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
+ if( pNew==0 ) return 0;
+ pTarget = &pParse->aNode[iTarget];
+ if( pNew!=&pTarget[j+1] ){
+ pTarget[j+1].u.pPatch = pNew;
+ pTarget[j+1].jnFlags |= JNODE_PATCH;
+ }
+ }
+ break;
+ }
+ }
+ if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
+ int iStart, iPatch;
+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+ jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
+ iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+ if( pParse->oom ) return 0;
+ jsonRemoveAllNulls(pPatch);
+ pTarget = &pParse->aNode[iTarget];
+ pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
+ pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
+ iRoot = iStart;
+ pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
+ pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
+ }
+ }
+ return pTarget;
+}
+
+/*
+** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
+** object that is the result of running the RFC 7396 MergePatch() algorithm
+** on the two arguments.
+*/
+static void jsonPatchFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The JSON that is being patched */
+ JsonParse y; /* The patch */
+ JsonNode *pResult; /* The result of the merge */
+
+ UNUSED_PARAM(argc);
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
+ jsonParseReset(&x);
+ return;
+ }
+ pResult = jsonMergePatch(&x, 0, y.aNode);
+ assert( pResult!=0 || x.oom );
+ if( pResult ){
+ jsonReturnJson(pResult, ctx, 0);
+ }else{
+ sqlite3_result_error_nomem(ctx);
+ }
jsonParseReset(&x);
+ jsonParseReset(&y);
}
+
/*
** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
** object that contains all name/value given in arguments. Or if any name
@@ -179687,11 +181061,11 @@ static void jsonReplaceFunc(
if( x.nErr ) goto replace_err;
if( pNode ){
pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->iVal = (u8)(i+1);
+ pNode->u.iReplace = i + 1;
}
}
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
}else{
jsonReturnJson(x.aNode, ctx, argv);
}
@@ -179741,11 +181115,11 @@ static void jsonSetFunc(
goto jsonSetDone;
}else if( pNode && (bApnd || bIsSet) ){
pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->iVal = (u8)(i+1);
+ pNode->u.iReplace = i + 1;
}
}
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
}else{
jsonReturnJson(x.aNode, ctx, argv);
}
@@ -180388,6 +181762,7 @@ SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
{ "json_extract", -1, 0, jsonExtractFunc },
{ "json_insert", -1, 0, jsonSetFunc },
{ "json_object", -1, 0, jsonObjectFunc },
+ { "json_patch", 2, 0, jsonPatchFunc },
{ "json_quote", 1, 0, jsonQuoteFunc },
{ "json_remove", -1, 0, jsonRemoveFunc },
{ "json_replace", -1, 0, jsonReplaceFunc },
@@ -181081,7 +182456,9 @@ typedef short i16;
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
-#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
+#ifndef ArraySize
+# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
+#endif
#define testcase(x)
#define ALWAYS(x) 1
@@ -181495,9 +182872,9 @@ static int sqlite3Fts5IndexBeginWrite(
/*
** Flush any data stored in the in-memory hash tables to the database.
-** If the bCommit flag is true, also close any open blob handles.
+** Also close any open blob handles.
*/
-static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
+static int sqlite3Fts5IndexSync(Fts5Index *p);
/*
** Discard any data stored in the in-memory hash tables. Do not write it
@@ -181667,7 +183044,7 @@ static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
-static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit);
+static int sqlite3Fts5StorageSync(Fts5Storage *p);
static int sqlite3Fts5StorageRollback(Fts5Storage *p);
static int sqlite3Fts5StorageConfigValue(
@@ -181703,6 +183080,7 @@ struct Fts5Token {
/* Parse a MATCH expression. */
static int sqlite3Fts5ExprNew(
Fts5Config *pConfig,
+ int iCol, /* Column on LHS of MATCH operator */
const char *zExpr,
Fts5Expr **ppNew,
char **pzErr
@@ -181787,7 +183165,7 @@ static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
-static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
+static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
@@ -181844,12 +183222,12 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
#define FTS5_NOT 3
#define FTS5_TERM 4
#define FTS5_COLON 5
-#define FTS5_LP 6
-#define FTS5_RP 7
-#define FTS5_MINUS 8
-#define FTS5_LCP 9
-#define FTS5_RCP 10
-#define FTS5_STRING 11
+#define FTS5_MINUS 6
+#define FTS5_LCP 7
+#define FTS5_RCP 8
+#define FTS5_STRING 9
+#define FTS5_LP 10
+#define FTS5_RP 11
#define FTS5_COMMA 12
#define FTS5_PLUS 13
#define FTS5_STAR 14
@@ -181985,16 +183363,16 @@ typedef union {
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
-#define fts5YYNSTATE 29
-#define fts5YYNRULE 26
-#define fts5YY_MAX_SHIFT 28
-#define fts5YY_MIN_SHIFTREDUCE 45
-#define fts5YY_MAX_SHIFTREDUCE 70
-#define fts5YY_MIN_REDUCE 71
-#define fts5YY_MAX_REDUCE 96
-#define fts5YY_ERROR_ACTION 97
-#define fts5YY_ACCEPT_ACTION 98
-#define fts5YY_NO_ACTION 99
+#define fts5YYNSTATE 33
+#define fts5YYNRULE 27
+#define fts5YY_MAX_SHIFT 32
+#define fts5YY_MIN_SHIFTREDUCE 50
+#define fts5YY_MAX_SHIFTREDUCE 76
+#define fts5YY_MIN_REDUCE 77
+#define fts5YY_MAX_REDUCE 103
+#define fts5YY_ERROR_ACTION 104
+#define fts5YY_ACCEPT_ACTION 105
+#define fts5YY_NO_ACTION 106
/************* End control #defines *******************************************/
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
@@ -182066,50 +183444,54 @@ typedef union {
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define fts5YY_ACTTAB_COUNT (85)
+#define fts5YY_ACTTAB_COUNT (98)
static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15,
- /* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5,
- /* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53,
- /* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68,
- /* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27,
- /* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21,
- /* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59,
- /* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69,
- /* 80 */ 25, 66, 8, 14, 2,
+ /* 0 */ 105, 19, 63, 6, 26, 66, 65, 24, 24, 17,
+ /* 10 */ 63, 6, 26, 16, 65, 54, 24, 18, 63, 6,
+ /* 20 */ 26, 10, 65, 12, 24, 75, 59, 63, 6, 26,
+ /* 30 */ 13, 65, 75, 24, 20, 63, 6, 26, 74, 65,
+ /* 40 */ 56, 24, 27, 63, 6, 26, 73, 65, 21, 24,
+ /* 50 */ 23, 15, 30, 11, 1, 64, 22, 25, 9, 65,
+ /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77,
+ /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12,
+ /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32,
+ /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
- /* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17,
- /* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19,
- /* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20,
- /* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26,
- /* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21,
- /* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24,
- /* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11,
- /* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14,
- /* 80 */ 13, 11, 5, 11, 3,
+ /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
+ /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
+ /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20,
+ /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22,
+ /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24,
+ /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22,
+ /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0,
+ /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9,
+ /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25,
+ /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9,
};
-#define fts5YY_SHIFT_USE_DFLT (85)
-#define fts5YY_SHIFT_COUNT (28)
+#define fts5YY_SHIFT_USE_DFLT (98)
+#define fts5YY_SHIFT_COUNT (32)
#define fts5YY_SHIFT_MIN (0)
-#define fts5YY_SHIFT_MAX (81)
+#define fts5YY_SHIFT_MAX (90)
static const unsigned char fts5yy_shift_ofst[] = {
- /* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1,
- /* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63,
- /* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81,
+ /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14,
+ /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69,
+ /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87,
+ /* 30 */ 88, 39, 71,
};
-#define fts5YY_REDUCE_USE_DFLT (-17)
-#define fts5YY_REDUCE_COUNT (14)
-#define fts5YY_REDUCE_MIN (-16)
-#define fts5YY_REDUCE_MAX (54)
+#define fts5YY_REDUCE_USE_DFLT (-18)
+#define fts5YY_REDUCE_COUNT (16)
+#define fts5YY_REDUCE_MIN (-17)
+#define fts5YY_REDUCE_MAX (67)
static const signed char fts5yy_reduce_ofst[] = {
- /* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13,
- /* 10 */ 13, 22, 54, 13, 51,
+ /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17,
+ /* 10 */ 67, 12, 12, 12, 20, 27, 35,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96,
- /* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97,
- /* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72,
+ /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104,
+ /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104,
+ /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104,
+ /* 30 */ 104, 97, 104,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -182215,11 +183597,11 @@ static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
"$", "OR", "AND", "NOT",
- "TERM", "COLON", "LP", "RP",
- "MINUS", "LCP", "RCP", "STRING",
+ "TERM", "COLON", "MINUS", "LCP",
+ "RCP", "STRING", "LP", "RP",
"COMMA", "PLUS", "STAR", "error",
"input", "expr", "cnearset", "exprlist",
- "nearset", "colset", "colsetlist", "nearphrases",
+ "colset", "colsetlist", "nearset", "nearphrases",
"phrase", "neardist_opt", "star_opt",
};
#endif /* NDEBUG */
@@ -182229,31 +183611,32 @@ static const char *const fts5yyTokenName[] = {
*/
static const char *const fts5yyRuleName[] = {
/* 0 */ "input ::= expr",
- /* 1 */ "expr ::= expr AND expr",
- /* 2 */ "expr ::= expr OR expr",
- /* 3 */ "expr ::= expr NOT expr",
- /* 4 */ "expr ::= LP expr RP",
- /* 5 */ "expr ::= exprlist",
- /* 6 */ "exprlist ::= cnearset",
- /* 7 */ "exprlist ::= exprlist cnearset",
- /* 8 */ "cnearset ::= nearset",
- /* 9 */ "cnearset ::= colset COLON nearset",
- /* 10 */ "colset ::= MINUS LCP colsetlist RCP",
- /* 11 */ "colset ::= LCP colsetlist RCP",
- /* 12 */ "colset ::= STRING",
- /* 13 */ "colset ::= MINUS STRING",
- /* 14 */ "colsetlist ::= colsetlist STRING",
- /* 15 */ "colsetlist ::= STRING",
- /* 16 */ "nearset ::= phrase",
- /* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
- /* 18 */ "nearphrases ::= phrase",
- /* 19 */ "nearphrases ::= nearphrases phrase",
- /* 20 */ "neardist_opt ::=",
- /* 21 */ "neardist_opt ::= COMMA STRING",
- /* 22 */ "phrase ::= phrase PLUS STRING star_opt",
- /* 23 */ "phrase ::= STRING star_opt",
- /* 24 */ "star_opt ::= STAR",
- /* 25 */ "star_opt ::=",
+ /* 1 */ "colset ::= MINUS LCP colsetlist RCP",
+ /* 2 */ "colset ::= LCP colsetlist RCP",
+ /* 3 */ "colset ::= STRING",
+ /* 4 */ "colset ::= MINUS STRING",
+ /* 5 */ "colsetlist ::= colsetlist STRING",
+ /* 6 */ "colsetlist ::= STRING",
+ /* 7 */ "expr ::= expr AND expr",
+ /* 8 */ "expr ::= expr OR expr",
+ /* 9 */ "expr ::= expr NOT expr",
+ /* 10 */ "expr ::= colset COLON LP expr RP",
+ /* 11 */ "expr ::= LP expr RP",
+ /* 12 */ "expr ::= exprlist",
+ /* 13 */ "exprlist ::= cnearset",
+ /* 14 */ "exprlist ::= exprlist cnearset",
+ /* 15 */ "cnearset ::= nearset",
+ /* 16 */ "cnearset ::= colset COLON nearset",
+ /* 17 */ "nearset ::= phrase",
+ /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 19 */ "nearphrases ::= phrase",
+ /* 20 */ "nearphrases ::= nearphrases phrase",
+ /* 21 */ "neardist_opt ::=",
+ /* 22 */ "neardist_opt ::= COMMA STRING",
+ /* 23 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 24 */ "phrase ::= STRING star_opt",
+ /* 25 */ "star_opt ::= STAR",
+ /* 26 */ "star_opt ::=",
};
#endif /* NDEBUG */
@@ -182383,16 +183766,16 @@ static void fts5yy_destructor(
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
}
break;
- case 20: /* nearset */
- case 23: /* nearphrases */
+ case 20: /* colset */
+ case 21: /* colsetlist */
{
- sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
+ sqlite3_free((fts5yypminor->fts5yy11));
}
break;
- case 21: /* colset */
- case 22: /* colsetlist */
+ case 22: /* nearset */
+ case 23: /* nearphrases */
{
- sqlite3_free((fts5yypminor->fts5yy11));
+ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
}
break;
case 24: /* phrase */
@@ -182652,23 +184035,24 @@ static const struct {
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} fts5yyRuleInfo[] = {
{ 16, 1 },
+ { 20, 4 },
+ { 20, 3 },
+ { 20, 1 },
+ { 20, 2 },
+ { 21, 2 },
+ { 21, 1 },
{ 17, 3 },
{ 17, 3 },
{ 17, 3 },
+ { 17, 5 },
{ 17, 3 },
{ 17, 1 },
{ 19, 1 },
{ 19, 2 },
{ 18, 1 },
{ 18, 3 },
- { 21, 4 },
- { 21, 3 },
- { 21, 1 },
- { 21, 2 },
- { 22, 2 },
{ 22, 1 },
- { 20, 1 },
- { 20, 5 },
+ { 22, 5 },
{ 23, 1 },
{ 23, 2 },
{ 25, 0 },
@@ -182743,87 +184127,94 @@ static void fts5yy_reduce(
case 0: /* input ::= expr */
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
break;
- case 1: /* expr ::= expr AND expr */
+ case 1: /* colset ::= MINUS LCP colsetlist RCP */
+{
+ fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+}
+ break;
+ case 2: /* colset ::= LCP colsetlist RCP */
+{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
+ break;
+ case 3: /* colset ::= STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ break;
+ case 4: /* colset ::= MINUS STRING */
+{
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+}
+ break;
+ case 5: /* colsetlist ::= colsetlist STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
+ fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ break;
+ case 6: /* colsetlist ::= STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ break;
+ case 7: /* expr ::= expr AND expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 2: /* expr ::= expr OR expr */
+ case 8: /* expr ::= expr OR expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 3: /* expr ::= expr NOT expr */
+ case 9: /* expr ::= expr NOT expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 4: /* expr ::= LP expr RP */
+ case 10: /* expr ::= colset COLON LP expr RP */
+{
+ sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
+ fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
+}
+ fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ break;
+ case 11: /* expr ::= LP expr RP */
{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
break;
- case 5: /* expr ::= exprlist */
- case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
+ case 12: /* expr ::= exprlist */
+ case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 7: /* exprlist ::= exprlist cnearset */
+ case 14: /* exprlist ::= exprlist cnearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
}
fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 8: /* cnearset ::= nearset */
+ case 15: /* cnearset ::= nearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 9: /* cnearset ::= colset COLON nearset */
+ case 16: /* cnearset ::= colset COLON nearset */
{
- sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11);
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
+ sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
- case 10: /* colset ::= MINUS LCP colsetlist RCP */
-{
- fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
-}
- break;
- case 11: /* colset ::= LCP colsetlist RCP */
-{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
- break;
- case 12: /* colset ::= STRING */
-{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
-}
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 13: /* colset ::= MINUS STRING */
-{
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
-}
- break;
- case 14: /* colsetlist ::= colsetlist STRING */
-{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
- fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 15: /* colsetlist ::= STRING */
-{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
-}
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 16: /* nearset ::= phrase */
+ case 17: /* nearset ::= phrase */
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
@@ -182831,40 +184222,40 @@ static void fts5yy_reduce(
}
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 18: /* nearphrases ::= phrase */
+ case 19: /* nearphrases ::= phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 19: /* nearphrases ::= nearphrases phrase */
+ case 20: /* nearphrases ::= nearphrases phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 20: /* neardist_opt ::= */
+ case 21: /* neardist_opt ::= */
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
break;
- case 21: /* neardist_opt ::= COMMA STRING */
+ case 22: /* neardist_opt ::= COMMA STRING */
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
break;
- case 22: /* phrase ::= phrase PLUS STRING star_opt */
+ case 23: /* phrase ::= phrase PLUS STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 23: /* phrase ::= STRING star_opt */
+ case 24: /* phrase ::= STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 24: /* star_opt ::= STAR */
+ case 25: /* star_opt ::= STAR */
{ fts5yymsp[0].minor.fts5yy4 = 1; }
break;
- case 25: /* star_opt ::= */
+ case 26: /* star_opt ::= */
{ fts5yymsp[1].minor.fts5yy4 = 0; }
break;
default:
@@ -183906,9 +185297,11 @@ static void sqlite3Fts5BufferAppendBlob(
const u8 *pData
){
assert_nc( *pRc || nData>=0 );
- if( fts5BufferGrow(pRc, pBuf, nData) ) return;
- memcpy(&pBuf->p[pBuf->n], pData, nData);
- pBuf->n += nData;
+ if( nData ){
+ if( fts5BufferGrow(pRc, pBuf, nData) ) return;
+ memcpy(&pBuf->p[pBuf->n], pData, nData);
+ pBuf->n += nData;
+ }
}
/*
@@ -184085,8 +185478,8 @@ static void *sqlite3Fts5MallocZero(int *pRc, int nByte){
void *pRet = 0;
if( *pRc==SQLITE_OK ){
pRet = sqlite3_malloc(nByte);
- if( pRet==0 && nByte>0 ){
- *pRc = SQLITE_NOMEM;
+ if( pRet==0 ){
+ if( nByte>0 ) *pRc = SQLITE_NOMEM;
}else{
memset(pRet, 0, nByte);
}
@@ -185407,6 +186800,7 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); }
static int sqlite3Fts5ExprNew(
Fts5Config *pConfig, /* FTS5 Configuration */
+ int iCol,
const char *zExpr, /* Expression text */
Fts5Expr **ppNew,
char **pzErr
@@ -185431,6 +186825,18 @@ static int sqlite3Fts5ExprNew(
}while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
+ /* If the LHS of the MATCH expression was a user column, apply the
+ ** implicit column-filter. */
+ if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
+ int n = sizeof(Fts5Colset);
+ Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
+ if( pColset ){
+ pColset->nCol = 1;
+ pColset->aiCol[0] = iCol;
+ sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
+ }
+ }
+
assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
if( sParse.rc==SQLITE_OK ){
*ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
@@ -186304,7 +187710,10 @@ static int fts5ExprNodeNext_OR(
|| (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
){
int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ){
+ pNode->bNomatch = 0;
+ return rc;
+ }
}
}
}
@@ -186335,7 +187744,10 @@ static int fts5ExprNodeTest_AND(
if( cmp>0 ){
/* Advance pChild until it points to iLast or laster */
rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ){
+ pAnd->bNomatch = 0;
+ return rc;
+ }
}
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
@@ -186374,6 +187786,8 @@ static int fts5ExprNodeNext_AND(
int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
if( rc==SQLITE_OK ){
rc = fts5ExprNodeTest_AND(pExpr, pNode);
+ }else{
+ pNode->bNomatch = 0;
}
return rc;
}
@@ -186416,6 +187830,9 @@ static int fts5ExprNodeNext_NOT(
if( rc==SQLITE_OK ){
rc = fts5ExprNodeTest_NOT(pExpr, pNode);
}
+ if( rc!=SQLITE_OK ){
+ pNode->bNomatch = 0;
+ }
return rc;
}
@@ -187069,25 +188486,110 @@ static Fts5Colset *sqlite3Fts5ParseColset(
return pRet;
}
+/*
+** If argument pOrig is NULL, or if (*pRc) is set to anything other than
+** SQLITE_OK when this function is called, NULL is returned.
+**
+** Otherwise, a copy of (*pOrig) is made into memory obtained from
+** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
+** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
+*/
+static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
+ Fts5Colset *pRet;
+ if( pOrig ){
+ int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
+ pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
+ if( pRet ){
+ memcpy(pRet, pOrig, nByte);
+ }
+ }else{
+ pRet = 0;
+ }
+ return pRet;
+}
+
+/*
+** Remove from colset pColset any columns that are not also in colset pMerge.
+*/
+static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
+ int iIn = 0; /* Next input in pColset */
+ int iMerge = 0; /* Next input in pMerge */
+ int iOut = 0; /* Next output slot in pColset */
+
+ while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
+ int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
+ if( iDiff==0 ){
+ pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
+ iMerge++;
+ iIn++;
+ }else if( iDiff>0 ){
+ iMerge++;
+ }else{
+ iIn++;
+ }
+ }
+ pColset->nCol = iOut;
+}
+
+/*
+** Recursively apply colset pColset to expression node pNode and all of
+** its decendents. If (*ppFree) is not NULL, it contains a spare copy
+** of pColset. This function may use the spare copy and set (*ppFree) to
+** zero, or it may create copies of pColset using fts5CloneColset().
+*/
+static void fts5ParseSetColset(
+ Fts5Parse *pParse,
+ Fts5ExprNode *pNode,
+ Fts5Colset *pColset,
+ Fts5Colset **ppFree
+){
+ if( pParse->rc==SQLITE_OK ){
+ assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
+ || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
+ || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
+ );
+ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ if( pNear->pColset ){
+ fts5MergeColset(pNear->pColset, pColset);
+ if( pNear->pColset->nCol==0 ){
+ pNode->eType = FTS5_EOF;
+ pNode->xNext = 0;
+ }
+ }else if( *ppFree ){
+ pNear->pColset = pColset;
+ *ppFree = 0;
+ }else{
+ pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
+ }
+ }else{
+ int i;
+ assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
+ for(i=0; i<pNode->nChild; i++){
+ fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
+ }
+ }
+ }
+}
+
+/*
+** Apply colset pColset to expression node pExpr and all of its descendents.
+*/
static void sqlite3Fts5ParseSetColset(
Fts5Parse *pParse,
- Fts5ExprNearset *pNear,
+ Fts5ExprNode *pExpr,
Fts5Colset *pColset
){
+ Fts5Colset *pFree = pColset;
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
pParse->rc = SQLITE_ERROR;
pParse->zErr = sqlite3_mprintf(
"fts5: column queries are not supported (detail=none)"
);
- sqlite3_free(pColset);
- return;
- }
-
- if( pNear ){
- pNear->pColset = pColset;
}else{
- sqlite3_free(pColset);
+ fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
}
+ sqlite3_free(pFree);
}
static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
@@ -187541,7 +189043,7 @@ static void fts5ExprFunction(
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
+ rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
}
if( rc==SQLITE_OK ){
char *zText;
@@ -187938,9 +189440,10 @@ struct Fts5Hash {
/*
** Each entry in the hash table is represented by an object of the
-** following type. Each object, its key (zKey[]) and its current data
-** are stored in a single memory allocation. The position list data
-** immediately follows the key data in memory.
+** following type. Each object, its key (a nul-terminated string) and
+** its current data are stored in a single memory allocation. The
+** key immediately follows the object in memory. The position list
+** data immediately follows the key data in memory.
**
** The data that follows the key is in a similar, but not identical format
** to the doclist data stored in the database. It is:
@@ -187964,20 +189467,20 @@ struct Fts5HashEntry {
int nAlloc; /* Total size of allocation */
int iSzPoslist; /* Offset of space for 4-byte poslist size */
int nData; /* Total bytes of data (incl. structure) */
- int nKey; /* Length of zKey[] in bytes */
+ int nKey; /* Length of key in bytes */
u8 bDel; /* Set delete-flag @ iSzPoslist */
u8 bContent; /* Set content-flag (detail=none mode) */
i16 iCol; /* Column of last value written */
int iPos; /* Position of last value written */
i64 iRowid; /* Rowid of last value written */
- char zKey[8]; /* Nul-terminated entry key */
};
/*
-** Size of Fts5HashEntry without the zKey[] array.
+** Eqivalent to:
+**
+** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
*/
-#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8)
-
+#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
/*
@@ -188075,7 +189578,7 @@ static int fts5HashResize(Fts5Hash *pHash){
int iHash;
Fts5HashEntry *p = apOld[i];
apOld[i] = p->pHashNext;
- iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
+ iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), strlen(fts5EntryKey(p)));
p->pHashNext = apNew[iHash];
apNew[iHash] = p;
}
@@ -188146,9 +189649,10 @@ static int sqlite3Fts5HashWrite(
/* Attempt to locate an existing hash entry */
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
- if( p->zKey[0]==bByte
+ char *zKey = fts5EntryKey(p);
+ if( zKey[0]==bByte
&& p->nKey==nToken
- && memcmp(&p->zKey[1], pToken, nToken)==0
+ && memcmp(&zKey[1], pToken, nToken)==0
){
break;
}
@@ -188157,7 +189661,8 @@ static int sqlite3Fts5HashWrite(
/* If an existing hash entry cannot be found, create a new one. */
if( p==0 ){
/* Figure out how much space to allocate */
- int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64;
+ char *zKey;
+ int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
if( nByte<128 ) nByte = 128;
/* Grow the Fts5Hash.aSlot[] array if necessary. */
@@ -188170,14 +189675,15 @@ static int sqlite3Fts5HashWrite(
/* Allocate new Fts5HashEntry and add it to the hash table. */
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
if( !p ) return SQLITE_NOMEM;
- memset(p, 0, FTS5_HASHENTRYSIZE);
+ memset(p, 0, sizeof(Fts5HashEntry));
p->nAlloc = nByte;
- p->zKey[0] = bByte;
- memcpy(&p->zKey[1], pToken, nToken);
- assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
+ zKey = fts5EntryKey(p);
+ zKey[0] = bByte;
+ memcpy(&zKey[1], pToken, nToken);
+ assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
p->nKey = nToken;
- p->zKey[nToken+1] = '\0';
- p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
+ zKey[nToken+1] = '\0';
+ p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
p->pHashNext = pHash->aSlot[iHash];
pHash->aSlot[iHash] = p;
pHash->nEntry++;
@@ -188295,9 +189801,11 @@ static Fts5HashEntry *fts5HashEntryMerge(
p1 = 0;
}else{
int i = 0;
- while( p1->zKey[i]==p2->zKey[i] ) i++;
+ char *zKey1 = fts5EntryKey(p1);
+ char *zKey2 = fts5EntryKey(p2);
+ while( zKey1[i]==zKey2[i] ) i++;
- if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){
+ if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
/* p2 is smaller */
*ppOut = p2;
ppOut = &p2->pScanNext;
@@ -188340,7 +189848,7 @@ static int fts5HashEntrySort(
for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
Fts5HashEntry *pIter;
for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
- if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){
+ if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
Fts5HashEntry *pEntry = pIter;
pEntry->pScanNext = 0;
for(i=0; ap[i]; i++){
@@ -188373,16 +189881,18 @@ static int sqlite3Fts5HashQuery(
int *pnDoclist /* OUT: Size of doclist in bytes */
){
unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
+ char *zKey;
Fts5HashEntry *p;
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
- if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break;
+ zKey = fts5EntryKey(p);
+ if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
}
if( p ){
fts5HashAddPoslistSize(pHash, p);
- *ppDoclist = (const u8*)&p->zKey[nTerm+1];
- *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
+ *ppDoclist = (const u8*)&zKey[nTerm+1];
+ *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
}else{
*ppDoclist = 0;
*pnDoclist = 0;
@@ -188415,11 +189925,12 @@ static void sqlite3Fts5HashScanEntry(
){
Fts5HashEntry *p;
if( (p = pHash->pScan) ){
- int nTerm = (int)strlen(p->zKey);
+ char *zKey = fts5EntryKey(p);
+ int nTerm = (int)strlen(zKey);
fts5HashAddPoslistSize(pHash, p);
- *pzTerm = p->zKey;
- *ppDoclist = (const u8*)&p->zKey[nTerm+1];
- *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
+ *pzTerm = zKey;
+ *ppDoclist = (const u8*)&zKey[nTerm+1];
+ *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
}else{
*pzTerm = 0;
*ppDoclist = 0;
@@ -189058,7 +190569,6 @@ static void fts5CloseReader(Fts5Index *p){
}
}
-
/*
** Retrieve a record from the %_data table.
**
@@ -191309,7 +192819,8 @@ static void fts5MultiIterNext2(
){
assert( pIter->bSkipEmpty );
if( p->rc==SQLITE_OK ){
- do {
+ *pbNewTerm = 0;
+ do{
int iFirst = pIter->aFirst[1].iFirst;
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
int bNewTerm = 0;
@@ -191322,8 +192833,6 @@ static void fts5MultiIterNext2(
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
fts5MultiIterSetEof(pIter);
*pbNewTerm = 1;
- }else{
- *pbNewTerm = 0;
}
fts5AssertMultiIterSetup(p, pIter);
@@ -191589,23 +193098,23 @@ static int fts5IndexExtractCol(
return p - (*pa);
}
-static int fts5IndexExtractColset (
+static void fts5IndexExtractColset(
+ int *pRc,
Fts5Colset *pColset, /* Colset to filter on */
const u8 *pPos, int nPos, /* Position list */
Fts5Buffer *pBuf /* Output buffer */
){
- int rc = SQLITE_OK;
- int i;
-
- fts5BufferZero(pBuf);
- for(i=0; i<pColset->nCol; i++){
- const u8 *pSub = pPos;
- int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
- if( nSub ){
- fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
+ if( *pRc==SQLITE_OK ){
+ int i;
+ fts5BufferZero(pBuf);
+ for(i=0; i<pColset->nCol; i++){
+ const u8 *pSub = pPos;
+ int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
+ if( nSub ){
+ fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
+ }
}
}
- return rc;
}
/*
@@ -191729,8 +193238,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
pIter->base.pData = a;
}else{
+ int *pRc = &pIter->pIndex->rc;
fts5BufferZero(&pIter->poslist);
- fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
+ fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
pIter->base.pData = pIter->poslist.p;
pIter->base.nData = pIter->poslist.n;
}
@@ -192275,9 +193785,6 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
Fts5PageWriter *pPage = &pWriter->writer;
i64 iRowid;
-static int nCall = 0;
-nCall++;
-
assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
/* Set the szLeaf header field. */
@@ -192626,6 +194133,7 @@ static void fts5IndexMergeLevel(
int bOldest; /* True if the output segment is the oldest */
int eDetail = p->pConfig->eDetail;
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
+ int bTermWritten = 0; /* True if current term already output */
assert( iLvl<pStruct->nLevel );
assert( pLvl->nMerge<=pLvl->nSeg );
@@ -192679,18 +194187,22 @@ static void fts5IndexMergeLevel(
int nTerm;
const u8 *pTerm;
- /* Check for key annihilation. */
- if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
-
pTerm = fts5MultiIterTerm(pIter, &nTerm);
if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
if( pnRem && writer.nLeafWritten>nRem ){
break;
}
+ fts5BufferSet(&p->rc, &term, nTerm, pTerm);
+ bTermWritten =0;
+ }
+ /* Check for key annihilation. */
+ if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
+
+ if( p->rc==SQLITE_OK && bTermWritten==0 ){
/* This is a new term. Append a term to the output segment. */
fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
- fts5BufferSet(&p->rc, &term, nTerm, pTerm);
+ bTermWritten = 1;
}
/* Append the rowid to the output */
@@ -193522,7 +195034,7 @@ static void fts5SetupPrefixIter(
if( pData ){
pData->p = (u8*)&pData[1];
pData->nn = pData->szLeaf = doclist.n;
- memcpy(pData->p, doclist.p, doclist.n);
+ if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
fts5MultiIterNew2(p, pData, bDesc, ppIter);
}
fts5BufferFree(&doclist);
@@ -193561,10 +195073,10 @@ static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
/*
** Commit data to disk.
*/
-static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
+static int sqlite3Fts5IndexSync(Fts5Index *p){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
- if( bCommit ) fts5CloseReader(p);
+ fts5CloseReader(p);
return fts5IndexReturn(p);
}
@@ -193761,7 +195273,7 @@ static int sqlite3Fts5IndexQuery(
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
int iIdx = 0; /* Index to search */
- memcpy(&buf.p[1], pToken, nToken);
+ if( nToken ) memcpy(&buf.p[1], pToken, nToken);
/* Figure out which index to search and set iIdx accordingly. If this
** is a prefix query for which there is no prefix index, set iIdx to
@@ -193810,7 +195322,7 @@ static int sqlite3Fts5IndexQuery(
}
if( p->rc ){
- sqlite3Fts5IterClose(&pRet->base);
+ sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
pRet = 0;
fts5CloseReader(p);
}
@@ -195428,6 +196940,7 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
Fts5Table *pTab = (Fts5Table*)pVTab;
Fts5Config *pConfig = pTab->pConfig;
+ const int nCol = pConfig->nCol;
int idxFlags = 0; /* Parameter passed through to xFilter() */
int bHasMatch;
int iNext;
@@ -195453,24 +196966,34 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
int aColMap[3];
aColMap[0] = -1;
- aColMap[1] = pConfig->nCol;
- aColMap[2] = pConfig->nCol+1;
+ aColMap[1] = nCol;
+ aColMap[2] = nCol+1;
/* Set idxFlags flags for all WHERE clause terms that will be used. */
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
- int j;
- for(j=0; j<ArraySize(aConstraint); j++){
- struct Constraint *pC = &aConstraint[j];
- if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
- if( p->usable ){
+ int iCol = p->iColumn;
+
+ if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
+ || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
+ ){
+ /* A MATCH operator or equivalent */
+ if( p->usable ){
+ idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
+ aConstraint[0].iConsIndex = i;
+ }else{
+ /* As there exists an unusable MATCH constraint this is an
+ ** unusable plan. Set a prohibitively high cost. */
+ pInfo->estimatedCost = 1e50;
+ return SQLITE_OK;
+ }
+ }else{
+ int j;
+ for(j=1; j<ArraySize(aConstraint); j++){
+ struct Constraint *pC = &aConstraint[j];
+ if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
pC->iConsIndex = i;
idxFlags |= pC->fts5op;
- }else if( j==0 ){
- /* As there exists an unusable MATCH constraint this is an
- ** unusable plan. Set a prohibitively high cost. */
- pInfo->estimatedCost = 1e50;
- return SQLITE_OK;
}
}
}
@@ -196045,6 +197568,7 @@ static int fts5FilterMethod(
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
+ int iCol; /* Column on LHS of MATCH operator */
char **pzErrmsg = pConfig->pzErrmsg;
UNUSED_PARAM(zUnused);
@@ -196075,6 +197599,8 @@ static int fts5FilterMethod(
if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
+ iCol = (idxNum>>16);
+ assert( iCol>=0 && iCol<=pConfig->nCol );
assert( iVal==nVal );
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
@@ -196121,7 +197647,7 @@ static int fts5FilterMethod(
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
}else{
char **pzErr = &pTab->base.zErrMsg;
- rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr);
+ rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
if( rc==SQLITE_OK ){
if( bOrderByRank ){
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
@@ -196501,7 +198027,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
fts5TripCursors(pTab);
- rc = sqlite3Fts5StorageSync(pTab->pStorage, 1);
+ rc = sqlite3Fts5StorageSync(pTab->pStorage);
pTab->pConfig->pzErrmsg = 0;
return rc;
}
@@ -197312,7 +198838,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
fts5TripCursors(pTab);
- return sqlite3Fts5StorageSync(pTab->pStorage, 0);
+ return sqlite3Fts5StorageSync(pTab->pStorage);
}
/*
@@ -197325,7 +198851,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
fts5TripCursors(pTab);
- return sqlite3Fts5StorageSync(pTab->pStorage, 0);
+ return sqlite3Fts5StorageSync(pTab->pStorage);
}
/*
@@ -197536,7 +199062,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2017-06-08 14:26:16 0ee482a1e0eae22e08edc8978c9733a96603d4509645f348ebf55b579e89636b", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
@@ -197872,7 +199398,7 @@ static void fts5StorageRenameOne(
static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
Fts5Config *pConfig = pStorage->pConfig;
- int rc = sqlite3Fts5StorageSync(pStorage, 1);
+ int rc = sqlite3Fts5StorageSync(pStorage);
fts5StorageRenameOne(pConfig, &rc, "data", zName);
fts5StorageRenameOne(pConfig, &rc, "idx", zName);
@@ -198199,11 +199725,6 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap
}
}
- /* Write the averages record */
- if( rc==SQLITE_OK ){
- rc = fts5StorageSaveTotals(p);
- }
-
return rc;
}
@@ -198407,11 +199928,6 @@ static int sqlite3Fts5StorageIndexInsert(
}
sqlite3_free(buf.p);
- /* Write the averages record */
- if( rc==SQLITE_OK ){
- rc = fts5StorageSaveTotals(p);
- }
-
return rc;
}
@@ -198745,13 +200261,18 @@ static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
/*
** Flush any data currently held in-memory to disk.
*/
-static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
- if( bCommit && p->bTotalsValid ){
- int rc = fts5StorageSaveTotals(p);
+static int sqlite3Fts5StorageSync(Fts5Storage *p){
+ int rc = SQLITE_OK;
+ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
+ if( p->bTotalsValid ){
+ rc = fts5StorageSaveTotals(p);
p->bTotalsValid = 0;
- if( rc!=SQLITE_OK ) return rc;
}
- return sqlite3Fts5IndexSync(p->pIndex, bCommit);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexSync(p->pIndex);
+ }
+ sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
+ return rc;
}
static int sqlite3Fts5StorageRollback(Fts5Storage *p){
diff --git a/db/sqlite3/src/sqlite3.h b/db/sqlite3/src/sqlite3.h
index c062c0a3d..3deb9c79b 100644
--- a/db/sqlite3/src/sqlite3.h
+++ b/db/sqlite3/src/sqlite3.h
@@ -114,16 +114,16 @@ extern "C" {
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and an SHA1
-** hash of the entire source tree.
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.17.0"
-#define SQLITE_VERSION_NUMBER 3017000
-#define SQLITE_SOURCE_ID "2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c"
+#define SQLITE_VERSION "3.19.3"
+#define SQLITE_VERSION_NUMBER 3019003
+#define SQLITE_SOURCE_ID "2017-06-08 14:26:16 0ee482a1e0eae22e08edc8978c9733a96603d4509645f348ebf55b579e89636b"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -857,7 +857,7 @@ struct sqlite3_io_methods {
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
-** integers where the first integer i the new retry count and the second
+** integers where the first integer is the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
@@ -2040,20 +2040,30 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
-** most recent successful [INSERT] into a rowid table or [virtual table]
-** on database connection D.
-** ^Inserts into [WITHOUT ROWID] tables are not recorded.
-** ^If no successful [INSERT]s into rowid tables
-** have ever occurred on the database connection D,
-** then sqlite3_last_insert_rowid(D) returns zero.
-**
-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
-** method, then this routine will return the [rowid] of the inserted
-** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned
-** by this routine reverts to what it was before the trigger or virtual
-** table method began.)^
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
+** on the database connection D, then sqlite3_last_insert_rowid(D) returns
+** zero.
+**
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
+**
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
+** associated with these internal INSERT operations, which leads to
+** unintuitive results. Virtual table implementations that do write to rowid
+** tables in this way can avoid this problem by restoring the original
+** rowid value using [sqlite3_set_last_insert_rowid()] before returning
+** control to the user.
+**
+** ^(If an [INSERT] occurs within a trigger then this routine will
+** return the [rowid] of the inserted row as long as the trigger is
+** running. Once the trigger program ends, the value returned
+** by this routine reverts to what it was before the trigger was fired.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
@@ -2081,6 +2091,16 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** set the value returned by calling sqlite3_last_insert_rowid(D) to R
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+
+/*
** CAPI3REF: Count The Number Of Rows Modified
** METHOD: sqlite3
**
@@ -2191,9 +2211,6 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
-**
-** If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
@@ -2656,6 +2673,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
+** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2683,8 +2701,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are zero-terminated strings that contain additional
-** details about the action to be authorized.
+** to the callback are either NULL pointers or zero-terminated strings
+** that contain additional details about the action to be authorized.
+** Applications must always be prepared to encounter a NULL pointer in any
+** of the third through the sixth parameters of the authorization callback.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
@@ -2693,6 +2713,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
+** ^When a table is referenced by a [SELECT] but no column values are
+** extracted from that table (for example in a query like
+** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
+** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
@@ -3404,9 +3428,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. This limit is not currently
-** enforced, though that might be added in some future release of
-** SQLite.</dd>)^
+** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
@@ -3444,6 +3468,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
+
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
@@ -3684,7 +3709,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
-typedef struct Mem sqlite3_value;
+typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
@@ -4738,10 +4763,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
-** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If there is no metadata
-** associated with the function argument, this sqlite3_get_auxdata() interface
+** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
+** value to the application-defined function. ^N is zero for the left-most
+** function argument. ^If there is no metadata
+** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
@@ -4772,6 +4798,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
+** The value of the N parameter to these interfaces should be non-negative.
+** Future enhancements may make use of negative N values to define new
+** kinds of function caching behavior.
+**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
@@ -9366,7 +9396,7 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
** sqlite3changegroup_output() functions, also available are the streaming
** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
*/
-int sqlite3changegroup_new(sqlite3_changegroup **pp);
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
@@ -9443,7 +9473,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
**
** If no error occurs, SQLITE_OK is returned.
*/
-int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
@@ -9469,7 +9499,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
** responsibility of the caller to eventually free the buffer using a
** call to sqlite3_free().
*/
-int sqlite3changegroup_output(
+SQLITE_API int sqlite3changegroup_output(
sqlite3_changegroup*,
int *pnData, /* OUT: Size of output buffer in bytes */
void **ppData /* OUT: Pointer to output buffer */
@@ -9478,7 +9508,7 @@ int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
*/
-void sqlite3changegroup_delete(sqlite3_changegroup*);
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
/*
** CAPI3REF: Apply A Changeset To A Database
@@ -9867,11 +9897,11 @@ SQLITE_API int sqlite3session_patchset_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3changegroup_add_strm(sqlite3_changegroup*,
+SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
-int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
diff --git a/devtools/client/framework/test/browser.ini b/devtools/client/framework/test/browser.ini
index f34cd66f0..2404490ce 100644
--- a/devtools/client/framework/test/browser.ini
+++ b/devtools/client/framework/test/browser.ini
@@ -91,5 +91,3 @@ skip-if = os == "mac" && os_version == "10.8" || os == "win" && os_version == "5
[browser_toolbox_window_title_frame_select.js]
[browser_toolbox_zoom.js]
[browser_two_tabs.js]
-# We want this test to run for mochitest-dt as well, so we include it here:
-[../../../../browser/base/content/test/general/browser_parsable_css.js]
diff --git a/devtools/shared/gcli/source/lib/gcli/commands/commands.js b/devtools/shared/gcli/source/lib/gcli/commands/commands.js
index 67793b2dc..0af4be620 100644
--- a/devtools/shared/gcli/source/lib/gcli/commands/commands.js
+++ b/devtools/shared/gcli/source/lib/gcli/commands/commands.js
@@ -335,10 +335,10 @@ Parameter.prototype.toJson = function() {
};
// Values do not need to be serializable, so we don't try. For the client
- // side (which doesn't do any executing) we don't actually care what the
- // default value is, just that it exists
+ // side (which doesn't do any executing) we only care whether default value is
+ // undefined, null, or something else.
if (this.paramSpec.defaultValue !== undefined) {
- json.defaultValue = {};
+ json.defaultValue = (this.paramSpec.defaultValue === null) ? null : {};
}
if (this.paramSpec.description != null) {
json.description = this.paramSpec.description;
diff --git a/devtools/shared/gcli/source/lib/gcli/commands/help.js b/devtools/shared/gcli/source/lib/gcli/commands/help.js
index 317f80240..7d1cc9087 100644
--- a/devtools/shared/gcli/source/lib/gcli/commands/help.js
+++ b/devtools/shared/gcli/source/lib/gcli/commands/help.js
@@ -69,7 +69,7 @@ function getHelpManData(commandData, context) {
}
else {
// We need defaultText to work the text version of defaultValue
- input = l10n.lookupFormat('helpManOptional');
+ input = l10n.lookup('helpManOptional');
/*
var val = param.type.stringify(param.defaultValue);
input = Promise.resolve(val).then(function(defaultValue) {
diff --git a/devtools/shared/webconsole/test/chrome.ini b/devtools/shared/webconsole/test/chrome.ini
index ae867b821..fde5a79fd 100644
--- a/devtools/shared/webconsole/test/chrome.ini
+++ b/devtools/shared/webconsole/test/chrome.ini
@@ -8,8 +8,6 @@ support-files =
network_requests_iframe.html
sandboxed_iframe.html
console-test-worker.js
- !/browser/base/content/test/general/browser_star_hsts.sjs
- !/browser/base/content/test/general/pinning_headers.sjs
[test_basics.html]
[test_bug819670_getter_throws.html]
diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp
index b273d00c9..576f3052a 100644
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2282,6 +2282,7 @@ SetMemoryGCModePrefChangedCallback(const char* aPrefName, void* aClosure)
{
bool enableZoneGC = Preferences::GetBool("javascript.options.mem.gc_per_zone");
bool enableIncrementalGC = Preferences::GetBool("javascript.options.mem.gc_incremental");
+ bool enableGenerationalGC = Preferences::GetBool("javascript.options.mem.gc_generational");
JSGCMode mode;
if (enableIncrementalGC) {
mode = JSGC_MODE_INCREMENTAL;
@@ -2291,6 +2292,7 @@ SetMemoryGCModePrefChangedCallback(const char* aPrefName, void* aClosure)
mode = JSGC_MODE_GLOBAL;
}
JS_SetGCParameter(sContext, JSGC_MODE, mode);
+ JS_SetGGCMode(sContext, enableGenerationalGC);
}
static void
@@ -2485,6 +2487,9 @@ nsJSContext::EnsureStatics()
Preferences::RegisterCallbackAndCall(SetMemoryGCSliceTimePrefChangedCallback,
"javascript.options.mem.gc_incremental_slice_ms");
+ Preferences::RegisterCallbackAndCall(SetMemoryGCModePrefChangedCallback,
+ "javascript.options.mem.gc_generational");
+
Preferences::RegisterCallbackAndCall(SetMemoryGCCompactingPrefChangedCallback,
"javascript.options.mem.gc_compacting");
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp
index 6c732db6c..a6d20e363 100644
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -2630,7 +2630,10 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
}
nsAutoCString sourceMapURL;
- rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-SourceMap"), sourceMapURL);
+ rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("SourceMap"), sourceMapURL);
+ if (NS_FAILED(rv)) {
+ rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-SourceMap"), sourceMapURL);
+ }
if (NS_SUCCEEDED(rv)) {
aRequest->mHasSourceMapURL = true;
aRequest->mSourceMapURL = NS_ConvertUTF8toUTF16(sourceMapURL);
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index 2ed39627e..b0a430fe4 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -68,6 +68,8 @@
#include "CanvasImageCache.h"
#include <algorithm>
+#include <stdlib.h>
+#include <time.h>
#include "jsapi.h"
#include "jsfriendapi.h"
@@ -2083,6 +2085,18 @@ CanvasRenderingContext2D::GetInputStream(const char* aMimeType,
return NS_ERROR_FAILURE;
}
+ bool PoisonData = Preferences::GetBool("canvas.poisondata",false);
+ if (PoisonData) {
+ srand(time(NULL));
+ // Image buffer is always a packed BGRA array (BGRX -> BGR[FF])
+ // so always 4-byte pixels.
+ // GetImageBuffer => SurfaceToPackedBGRA [=> ConvertBGRXToBGRA]
+ for (int32_t j = 0; j < mWidth * mHeight * 4; ++j) {
+ if (imageBuffer[j] !=0 && imageBuffer[j] != 255)
+ imageBuffer[j] += rand() % 3 - 1;
+ }
+ }
+
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(),
format, encoder, aEncoderOptions,
aStream);
@@ -5698,6 +5712,14 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
return imageData.forget();
}
+inline uint8_t PoisonValue(uint8_t v)
+{
+ if (v==0 || v==255)
+ return v; //don't fuzz edges to prevent overflow/underflow
+
+ return v + rand() %3 -1;
+}
+
nsresult
CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
int32_t aX,
@@ -5712,6 +5734,10 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
MOZ_ASSERT(aWidth && aHeight);
+ bool PoisonData = Preferences::GetBool("canvas.poisondata",false);
+ if (PoisonData)
+ srand(time(NULL));
+
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
if (!len.isValid()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
@@ -5784,21 +5810,31 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
uint8_t* dst = data + dstWriteRect.y * (aWidth * 4) + dstWriteRect.x * 4;
+ uint8_t a,r,g,b;
+
if (mOpaque) {
for (int32_t j = 0; j < dstWriteRect.height; ++j) {
for (int32_t i = 0; i < dstWriteRect.width; ++i) {
// XXX Is there some useful swizzle MMX we can use here?
#if MOZ_LITTLE_ENDIAN
- uint8_t b = *src++;
- uint8_t g = *src++;
- uint8_t r = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
src++;
#else
src++;
- uint8_t r = *src++;
- uint8_t g = *src++;
- uint8_t b = *src++;
+ r = *src++;
+ g = *src++;
+ b = *src++;
#endif
+
+ // Poison data for trackers if enabled
+ if (PoisonData) {
+ PoisonValue(r);
+ PoisonValue(g);
+ PoisonValue(b);
+ }
+
*dst++ = r;
*dst++ = g;
*dst++ = b;
@@ -5812,16 +5848,25 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
for (int32_t i = 0; i < dstWriteRect.width; ++i) {
// XXX Is there some useful swizzle MMX we can use here?
#if MOZ_LITTLE_ENDIAN
- uint8_t b = *src++;
- uint8_t g = *src++;
- uint8_t r = *src++;
- uint8_t a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+ a = *src++;
#else
- uint8_t a = *src++;
- uint8_t r = *src++;
- uint8_t g = *src++;
- uint8_t b = *src++;
+ a = *src++;
+ r = *src++;
+ g = *src++;
+ b = *src++;
#endif
+
+ // Poison data for trackers if enabled
+ if (PoisonData) {
+ PoisonValue(a);
+ PoisonValue(r);
+ PoisonValue(g);
+ PoisonValue(b);
+ }
+
// Convert to non-premultiplied color
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + r];
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + g];
diff --git a/dom/system/NetworkGeolocationProvider.js b/dom/system/NetworkGeolocationProvider.js
index ea2abe55f..ad15ed802 100644
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -219,9 +219,20 @@ WifiGeoCoordsObject.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords])
};
-function WifiGeoPositionObject(lat, lng, acc) {
+function WifiGeoPositionObject(lat, lng, acc, cc, tz, zip, city, rc, region, country, isp, org, as) {
this.coords = new WifiGeoCoordsObject(lat, lng, acc, 0, 0);
this.address = null;
+ this.countrycode = cc;
+ this.timezone = tz;
+ this.zipcode = zip;
+ this.postalcode = zip;
+ this.city = city;
+ this.regioncode = rc;
+ this.region = region;
+ this.country = country;
+ this.isp = isp;
+ this.org = org;
+ this.as = as;
this.timestamp = Date.now();
}
@@ -431,41 +442,54 @@ WifiGeoPositionProvider.prototype = {
let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
- this.notifyListener("locationUpdatePending");
+ // XXX: Dead code?
+ // this.notifyListener("locationUpdatePending");
try {
- xhr.open("POST", url, true);
+ xhr.open("GET", url, true);
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
} catch (e) {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
return;
}
- xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.responseType = "json";
xhr.mozBackgroundRequest = true;
xhr.timeout = Services.prefs.getIntPref("geo.wifi.xhr.timeout");
+
xhr.ontimeout = (function() {
LOG("Location request XHR timed out.")
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
}).bind(this);
+
xhr.onerror = (function() {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
}).bind(this);
+
xhr.onload = (function() {
LOG("server returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if ((xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) ||
- !xhr.response || !xhr.response.location) {
+ !xhr.response || xhr.response.status == 'fail') {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
return;
}
- let newLocation = new WifiGeoPositionObject(xhr.response.location.lat,
- xhr.response.location.lng,
- xhr.response.accuracy);
+ let newLocation = new WifiGeoPositionObject(xhr.response.lat,
+ xhr.response.lon,
+ null, //accuracy not provided
+ xhr.response.countryCode,
+ xhr.response.timezone,
+ xhr.response.zip,
+ xhr.response.city,
+ xhr.response.region,
+ xhr.response.regionName,
+ xhr.response.country,
+ xhr.response.isp,
+ xhr.response.org,
+ xhr.response.as);
this.notifyListener("update", [newLocation]);
gCachedRequest = new CachedRequest(newLocation, data.cellTowers, data.wifiAccessPoints);
@@ -478,6 +502,7 @@ WifiGeoPositionProvider.prototype = {
notifyListener: function(listenerFunc, args) {
args = args || [];
+ LOG("Notify listener " + listenerFunc);
try {
this.listener[listenerFunc].apply(this.listener, args);
} catch(e) {
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index d1d76e3d1..1f5616873 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -290,13 +290,6 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
return;
}
-#ifdef JS_GC_ZEAL
- if (prefName.EqualsLiteral(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL) ||
- prefName.EqualsLiteral(PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL)) {
- return;
- }
-#endif
-
// Context options.
JS::ContextOptions contextOptions;
contextOptions.setAsmJS(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asmjs")))
@@ -317,37 +310,6 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
}
}
-#ifdef JS_GC_ZEAL
-void
-LoadGCZealOptions(const char* /* aPrefName */, void* /* aClosure */)
-{
- AssertIsOnMainThread();
-
- RuntimeService* rts = RuntimeService::GetService();
- if (!rts) {
- // May be shutting down, just bail.
- return;
- }
-
- int32_t gczeal = GetWorkerPref<int32_t>(NS_LITERAL_CSTRING(PREF_GCZEAL), -1);
- if (gczeal < 0) {
- gczeal = 0;
- }
-
- int32_t frequency =
- GetWorkerPref<int32_t>(NS_LITERAL_CSTRING("gcZeal.frequency"), -1);
- if (frequency < 0) {
- frequency = JS_DEFAULT_ZEAL_FREQ;
- }
-
- RuntimeService::SetDefaultGCZeal(uint8_t(gczeal), uint32_t(frequency));
-
- if (rts) {
- rts->UpdateAllWorkerGCZeal();
- }
-}
-#endif
-
void
UpdateCommonJSGCMemoryOption(RuntimeService* aRuntimeService,
const nsACString& aPrefName, JSGCParamKey aKey)
@@ -994,10 +956,6 @@ InitJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSContext* aWorkerCx)
js::SetCTypesActivityCallback(aWorkerCx, CTypesActivityCallback);
-#ifdef JS_GC_ZEAL
- JS_SetGCZeal(aWorkerCx, settings.gcZeal, settings.gcZealFrequency);
-#endif
-
return true;
}
@@ -1981,10 +1939,6 @@ RuntimeService::Init()
sDefaultJSSettings.chrome.maxScriptRuntime = -1;
sDefaultJSSettings.chrome.compartmentOptions.behaviors().setVersion(JSVERSION_LATEST);
sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC;
-#ifdef JS_GC_ZEAL
- sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ;
- sDefaultJSSettings.gcZeal = 0;
-#endif
SetDefaultJSGCSettings(JSGC_MAX_BYTES, WORKER_DEFAULT_RUNTIME_HEAPSIZE);
SetDefaultJSGCSettings(JSGC_ALLOCATION_THRESHOLD,
WORKER_DEFAULT_ALLOCATION_THRESHOLD);
@@ -2033,12 +1987,6 @@ RuntimeService::Init()
LoadJSGCMemoryOptions,
PREF_WORKERS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX,
nullptr)) ||
-#ifdef JS_GC_ZEAL
- NS_FAILED(Preferences::RegisterCallback(
- LoadGCZealOptions,
- PREF_JS_OPTIONS_PREFIX PREF_GCZEAL,
- nullptr)) ||
-#endif
#define WORKER_SIMPLE_PREF(name, getter, NAME) \
NS_FAILED(Preferences::RegisterCallbackAndCall( \
@@ -2227,12 +2175,6 @@ RuntimeService::Cleanup()
#undef WORKER_SIMPLE_PREF
#undef WORKER_PREF
-#ifdef JS_GC_ZEAL
- NS_FAILED(Preferences::UnregisterCallback(
- LoadGCZealOptions,
- PREF_JS_OPTIONS_PREFIX PREF_GCZEAL,
- nullptr)) ||
-#endif
NS_FAILED(Preferences::UnregisterCallback(
LoadJSGCMemoryOptions,
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX,
@@ -2644,15 +2586,6 @@ RuntimeService::UpdateAllWorkerMemoryParameter(JSGCParamKey aKey,
BROADCAST_ALL_WORKERS(UpdateJSWorkerMemoryParameter, aKey, aValue);
}
-#ifdef JS_GC_ZEAL
-void
-RuntimeService::UpdateAllWorkerGCZeal()
-{
- BROADCAST_ALL_WORKERS(UpdateGCZeal, sDefaultJSSettings.gcZeal,
- sDefaultJSSettings.gcZealFrequency);
-}
-#endif
-
void
RuntimeService::GarbageCollectAllWorkers(bool aShrinking)
{
diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h
index 2e5cc1dad..2ab8cbabe 100644
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -215,19 +215,6 @@ public:
void
UpdateAllWorkerMemoryParameter(JSGCParamKey aKey, uint32_t aValue);
-#ifdef JS_GC_ZEAL
- static void
- SetDefaultGCZeal(uint8_t aGCZeal, uint32_t aFrequency)
- {
- AssertIsOnMainThread();
- sDefaultJSSettings.gcZeal = aGCZeal;
- sDefaultJSSettings.gcZealFrequency = aFrequency;
- }
-
- void
- UpdateAllWorkerGCZeal();
-#endif
-
void
GarbageCollectAllWorkers(bool aShrinking);
diff --git a/dom/workers/WorkerPrefs.h b/dom/workers/WorkerPrefs.h
index c9b605a84..9a1be4801 100644
--- a/dom/workers/WorkerPrefs.h
+++ b/dom/workers/WorkerPrefs.h
@@ -44,6 +44,3 @@ WORKER_PREF("intl.accept_languages", PrefLanguagesChanged)
WORKER_PREF("general.appname.override", AppNameOverrideChanged)
WORKER_PREF("general.appversion.override", AppVersionOverrideChanged)
WORKER_PREF("general.platform.override", PlatformOverrideChanged)
-#ifdef JS_GC_ZEAL
-WORKER_PREF("dom.workers.options.gcZeal", LoadGCZealOptions)
-#endif
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 1df4e5551..c2ab4aca3 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1391,30 +1391,6 @@ private:
}
};
-#ifdef JS_GC_ZEAL
-class UpdateGCZealRunnable final : public WorkerControlRunnable
-{
- uint8_t mGCZeal;
- uint32_t mFrequency;
-
-public:
- UpdateGCZealRunnable(WorkerPrivate* aWorkerPrivate,
- uint8_t aGCZeal,
- uint32_t aFrequency)
- : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount),
- mGCZeal(aGCZeal), mFrequency(aFrequency)
- { }
-
-private:
- virtual bool
- WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
- {
- aWorkerPrivate->UpdateGCZealInternal(aCx, mGCZeal, mFrequency);
- return true;
- }
-};
-#endif
-
class GarbageCollectRunnable final : public WorkerControlRunnable
{
bool mShrinking;
@@ -3148,27 +3124,6 @@ WorkerPrivateParent<Derived>::UpdateJSWorkerMemoryParameter(JSGCParamKey aKey,
}
}
-#ifdef JS_GC_ZEAL
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::UpdateGCZeal(uint8_t aGCZeal, uint32_t aFrequency)
-{
- AssertIsOnParentThread();
-
- {
- MutexAutoLock lock(mMutex);
- mJSSettings.gcZeal = aGCZeal;
- mJSSettings.gcZealFrequency = aFrequency;
- }
-
- RefPtr<UpdateGCZealRunnable> runnable =
- new UpdateGCZealRunnable(ParentAsWorkerPrivate(), aGCZeal, aFrequency);
- if (!runnable->Dispatch()) {
- NS_WARNING("Failed to update worker gczeal!");
- }
-}
-#endif
-
template <class Derived>
void
WorkerPrivateParent<Derived>::GarbageCollect(bool aShrinking)
@@ -6323,21 +6278,6 @@ WorkerPrivate::UpdateJSWorkerMemoryParameterInternal(JSContext* aCx,
}
}
-#ifdef JS_GC_ZEAL
-void
-WorkerPrivate::UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal,
- uint32_t aFrequency)
-{
- AssertIsOnWorkerThread();
-
- JS_SetGCZeal(aCx, aGCZeal, aFrequency);
-
- for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
- mChildWorkers[index]->UpdateGCZeal(aGCZeal, aFrequency);
- }
-}
-#endif
-
void
WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
bool aCollectChildren)
diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
index ad906b054..8008f30e5 100644
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -386,11 +386,6 @@ public:
void
UpdateJSWorkerMemoryParameter(JSGCParamKey key, uint32_t value);
-#ifdef JS_GC_ZEAL
- void
- UpdateGCZeal(uint8_t aGCZeal, uint32_t aFrequency);
-#endif
-
void
GarbageCollect(bool aShrinking);
diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h
index 89e2ccfca..ad083d3b8 100644
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -143,15 +143,7 @@ struct JSSettings
JSGCSettingsArray gcSettings;
JS::ContextOptions contextOptions;
-#ifdef JS_GC_ZEAL
- uint8_t gcZeal;
- uint32_t gcZealFrequency;
-#endif
-
JSSettings()
-#ifdef JS_GC_ZEAL
- : gcZeal(0), gcZealFrequency(0)
-#endif
{
for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
new (gcSettings + index) JSGCSetting();
diff --git a/editor/composer/nsEditorSpellCheck.cpp b/editor/composer/nsEditorSpellCheck.cpp
index 7cae48c1f..790480034 100644
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -594,45 +594,24 @@ nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary)
// Ignore pending dictionary fetchers by increasing this number.
mDictionaryFetcherGroup++;
- uint32_t flags = 0;
- mEditor->GetFlags(&flags);
- if (!(flags & nsIPlaintextEditor::eEditorMailMask)) {
- if (!aDictionary.IsEmpty() && (mPreferredLang.IsEmpty() ||
- !mPreferredLang.Equals(aDictionary,
- nsCaseInsensitiveStringComparator()))) {
- // When user sets dictionary manually, we store this value associated
- // with editor url, if it doesn't match the document language exactly.
- // For example on "en" sites, we need to store "en-GB", otherwise
- // the language might jump back to en-US although the user explicitly
- // chose otherwise.
- StoreCurrentDictionary(mEditor, aDictionary);
-#ifdef DEBUG_DICT
- printf("***** Writing content preferences for |%s|\n",
- NS_ConvertUTF16toUTF8(aDictionary).get());
-#endif
- } else {
- // If user sets a dictionary matching the language defined by
- // document, we consider content pref has been canceled, and we clear it.
- ClearCurrentDictionary(mEditor);
-#ifdef DEBUG_DICT
- printf("***** Clearing content preferences for |%s|\n",
- NS_ConvertUTF16toUTF8(aDictionary).get());
-#endif
- }
-
- // Also store it in as a preference, so we can use it as a fallback.
- // We don't want this for mail composer because it uses
- // "spellchecker.dictionary" as a preference.
- Preferences::SetString("spellchecker.dictionary", aDictionary);
-#ifdef DEBUG_DICT
- printf("***** Storing spellchecker.dictionary |%s|\n",
- NS_ConvertUTF16toUTF8(aDictionary).get());
-#endif
+ if (mPreferredLang.IsEmpty() ||
+ !mPreferredLang.Equals(aDictionary, nsCaseInsensitiveStringComparator())) {
+ // When user sets dictionary manually, we store this value associated
+ // with editor url, if it doesn't match the document language exactly.
+ // For example on "en" sites, we need to store "en-GB", otherwise
+ // the language might jump back to en-US although the user explicitly
+ // chose otherwise.
+ StoreCurrentDictionary(mEditor, aDictionary);
+ } else {
+ // If user sets a dictionary matching the language defined by
+ // document, we consider content pref has been canceled, and we clear it.
+ ClearCurrentDictionary(mEditor);
}
}
return mSpellChecker->SetCurrentDictionary(aDictionary);
}
+
NS_IMETHODIMP
nsEditorSpellCheck::UninitSpellChecker()
{
@@ -771,23 +750,16 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
/*
* We try to derive the dictionary to use based on the following priorities:
- * 1) Content preference, so the language the user set for the site before.
- * (Introduced in bug 678842 and corrected in bug 717433.)
- * 2) Language set by the website, or any other dictionary that partly
- * matches that. (Introduced in bug 338427.)
- * Eg. if the website is "en-GB", a user who only has "en-US" will get
- * that. If the website is generic "en", the user will get one of the
- * "en-*" installed, (almost) at random.
- * However, we prefer what is stored in "spellchecker.dictionary",
- * so if the user chose "en-AU" before, they will get "en-AU" on a plain
- * "en" site. (Introduced in bug 682564.)
- * 3) The value of "spellchecker.dictionary" which reflects a previous
- * language choice of the user (on another site).
- * (This was the original behaviour before the aforementioned bugs
- * landed).
- * 4) The user's locale.
- * 5) Use the current dictionary that is currently set.
- * 6) The content of the "LANG" environment variable (if set).
+ * 1) Content preference: the language the user set for the site before.
+ * 2) The value of "spellchecker.dictionary.override" which reflects a
+ * global choice of language explicitly set by the user.
+ * 3) Language set by the website, or any other dictionary that partly matches that.
+ * Eg. if the website is "en-GB", a user who only has "en-US" will get that.
+ * If the website is generic "en", the user will get one of the "en-*" installed,
+ * pretty much at random.
+ * 4) The user's locale
+ * 5) Leave the current dictionary set.
+ * 6) The content of the "LANG" environment variable (if set)
* 7) The first spell check dictionary installed.
*/
@@ -795,131 +767,100 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
// https://html.spec.whatwg.org/#attr-lang
// This is used in SetCurrentDictionary.
mPreferredLang.Assign(aFetcher->mRootContentLang);
-#ifdef DEBUG_DICT
- printf("***** mPreferredLang (element) |%s|\n",
- NS_ConvertUTF16toUTF8(mPreferredLang).get());
-#endif
// If no luck, try the "Content-Language" header.
if (mPreferredLang.IsEmpty()) {
mPreferredLang.Assign(aFetcher->mRootDocContentLang);
-#ifdef DEBUG_DICT
- printf("***** mPreferredLang (content-language) |%s|\n",
- NS_ConvertUTF16toUTF8(mPreferredLang).get());
-#endif
}
-
- // Auxiliary status.
- nsresult rv2;
-
- // We obtain a list of available dictionaries.
- nsTArray<nsString> dictList;
- rv2 = mSpellChecker->GetDictionaryList(&dictList);
- NS_ENSURE_SUCCESS(rv2, rv2);
-
+
// Priority 1:
+ // Get language from content prefs, if set.
// If we successfully fetched a dictionary from content prefs, do not go
// further. Use this exact dictionary.
- // Don't use content preferences for editor with eEditorMailMask flag.
nsAutoString dictName;
- uint32_t flags;
- mEditor->GetFlags(&flags);
- if (!(flags & nsIPlaintextEditor::eEditorMailMask)) {
- dictName.Assign(aFetcher->mDictionary);
- if (!dictName.IsEmpty()) {
- if (NS_SUCCEEDED(TryDictionary(dictName, dictList, DICT_NORMAL_COMPARE))) {
-#ifdef DEBUG_DICT
- printf("***** Assigned from content preferences |%s|\n",
- NS_ConvertUTF16toUTF8(dictName).get());
-#endif
-
- // We take an early exit here, so let's not forget to clear the word
- // list.
- DeleteSuggestedWordList();
- return NS_OK;
- }
- // May be dictionary was uninstalled ?
- // Clear the content preference and continue.
- ClearCurrentDictionary(mEditor);
+ dictName.Assign(aFetcher->mDictionary);
+ if (!dictName.IsEmpty()) {
+ if (NS_SUCCEEDED(SetCurrentDictionary(dictName))) {
+ // We take an early exit here, so clear the suggested word list.
+ DeleteSuggestedWordList();
+ return NS_OK;
}
+ // Maybe the dictionary was uninstalled ?
+ // Clear the content preference and continue.
+ ClearCurrentDictionary(mEditor);
}
-
+
// Priority 2:
- // After checking the content preferences, we use the language of the element
- // or document.
- dictName.Assign(mPreferredLang);
-#ifdef DEBUG_DICT
- printf("***** Assigned from element/doc |%s|\n",
- NS_ConvertUTF16toUTF8(dictName).get());
-#endif
-
- // Get the preference value.
+ // Get global preferred language from preferences, if set.
nsAutoString preferredDict;
- preferredDict = Preferences::GetLocalizedString("spellchecker.dictionary");
+ preferredDict = Preferences::GetLocalizedString("spellchecker.dictionary.override");
+ if (!preferredDict.IsEmpty()) {
+ dictName.Assign(preferredDict);
+ }
- // The following will be driven by this status. Once we were able to set a
+ // Priority 3:
+ // Get language from element/doc, if set.
+ if (dictName.IsEmpty() && !mPreferredLang.IsEmpty()) {
+ dictName.Assign(mPreferredLang);
+ }
+
+ // Auxiliary status value
+ nsresult rv2;
+
+ // Obtain a list of available dictionaries to check against.
+ nsTArray<nsString> dictList;
+ rv2 = mSpellChecker->GetDictionaryList(&dictList);
+ NS_ENSURE_SUCCESS(rv2, rv2);
+ int32_t i, dictCount = dictList.Length();
+
+ // The following will be driven by this status. Once we are able to set a
// dictionary successfully, we're done. So we start with a "failed" status.
- nsresult rv = NS_ERROR_NOT_AVAILABLE;
-
+ nsresult rv = NS_ERROR_FAILURE;
+
if (!dictName.IsEmpty()) {
- // RFC 5646 explicitly states that matches should be case-insensitive.
- rv = TryDictionary (dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE);
-
- if (NS_FAILED(rv)) {
-#ifdef DEBUG_DICT
- printf("***** Setting of |%s| failed (or it wasn't available)\n",
- NS_ConvertUTF16toUTF8(dictName).get());
-#endif
+ for (i = 0; i < dictCount; i++) {
+ nsAutoString dictStr(dictList.ElementAt(i));
+ if (dictName.Equals(dictStr, nsCaseInsensitiveStringComparator())) {
+ // First let's correct any problems due to non-matching case.
+ // This applies to both a user-set override and document language.
+ // RFC 5646 explicitly states that matches should be case-insensitive.
+ dictName.Assign(dictStr);
+ // Try to set it. Doing this inside this loop avoids trying to set a
+ // dictionary that isn't available.
+ rv = SetCurrentDictionary(dictName);
+ break;
+ }
+ }
+ if (NS_FAILED(rv)) {
// Required dictionary was not available. Try to get a dictionary
- // matching at least language part of dictName.
+ // matching at least the language part of dictName:
nsAutoString langCode;
int32_t dashIdx = dictName.FindChar('-');
- if (dashIdx != -1) {
+ if (dashIdx != -1) {
langCode.Assign(Substring(dictName, 0, dashIdx));
} else {
langCode.Assign(dictName);
}
- // Try dictionary.spellchecker preference, if it starts with langCode,
- // so we don't just get any random dictionary matching the language.
- if (!preferredDict.IsEmpty() &&
- nsStyleUtil::DashMatchCompare(preferredDict, langCode, nsDefaultStringComparator())) {
-#ifdef DEBUG_DICT
- printf("***** Trying preference value |%s| since it matches language code\n",
- NS_ConvertUTF16toUTF8(preferredDict).get());
-#endif
- rv = TryDictionary (preferredDict, dictList,
- DICT_COMPARE_CASE_INSENSITIVE);
- }
+ nsDefaultStringComparator comparator;
- if (NS_FAILED(rv)) {
- // Use any dictionary with the required language.
-#ifdef DEBUG_DICT
- printf("***** Trying to find match for language code |%s|\n",
- NS_ConvertUTF16toUTF8(langCode).get());
-#endif
- rv = TryDictionary (langCode, dictList, DICT_COMPARE_DASHMATCH);
+ // Loop over available dictionaries; if we find one with the required
+ // language, use it.
+ for (i = 0; i < dictCount; i++) {
+ nsAutoString dictStr(dictList.ElementAt(i));
+ if (nsStyleUtil::DashMatchCompare(dictStr, langCode, comparator) &&
+ NS_SUCCEEDED(rv = SetCurrentDictionary(dictStr))) {
+ break;
+ }
}
}
}
-
- // Priority 3:
- // If the document didn't supply a dictionary or the setting failed,
- // try the user preference next.
- if (NS_FAILED(rv)) {
- if (!preferredDict.IsEmpty()) {
-#ifdef DEBUG_DICT
- printf("***** Trying preference value |%s|\n",
- NS_ConvertUTF16toUTF8(preferredDict).get());
-#endif
- rv = TryDictionary (preferredDict, dictList, DICT_NORMAL_COMPARE);
- }
- }
-
+
// Priority 4:
- // As next fallback, try the current locale.
- if (NS_FAILED(rv)) {
+ // Content prefs, override and document didn't give us a valid dictionary
+ // name, so we just get the current locale and try to use that.
+ if (NS_FAILED (rv)) {
nsCOMPtr<nsIXULChromeRegistry> packageRegistry =
mozilla::services::GetXULChromeRegistryService();
@@ -929,69 +870,57 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
false, utf8DictName);
dictName.Assign(EmptyString());
AppendUTF8toUTF16(utf8DictName, dictName);
-#ifdef DEBUG_DICT
- printf("***** Trying locale |%s|\n",
- NS_ConvertUTF16toUTF8(dictName).get());
-#endif
- rv = TryDictionary (dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE);
+ // Try to set it, if it's in the list.
+ for (i = 0; i < dictCount; i++) {
+ nsAutoString dictStr(dictList.ElementAt(i));
+ if (dictStr.Equals(dictName)) {
+ rv = SetCurrentDictionary(dictName);
+ break;
+ }
+ }
}
}
-
+
if (NS_FAILED(rv)) {
- // Still no success.
+ // Still no success. Further fallback attempts required.
- // Priority 5:
- // If we have a current dictionary, don't try anything else.
+ // Priority 5:
+ // If we have a current dictionary, don't try anything else.
nsAutoString currentDictionary;
rv2 = GetCurrentDictionary(currentDictionary);
-#ifdef DEBUG_DICT
- if (NS_SUCCEEDED(rv2)) {
- printf("***** Retrieved current dict |%s|\n",
- NS_ConvertUTF16toUTF8(currentDictionary).get());
- }
-#endif
-
+
if (NS_FAILED(rv2) || currentDictionary.IsEmpty()) {
+ // We don't have a current dictionary.
// Priority 6:
// Try to get current dictionary from environment variable LANG.
- // LANG = language[_territory][.charset]
+ // LANG = language[_territory][.codeset]
char* env_lang = getenv("LANG");
- if (env_lang) {
+ if (env_lang != nullptr) {
nsString lang = NS_ConvertUTF8toUTF16(env_lang);
+
// Strip trailing charset, if there is any.
int32_t dot_pos = lang.FindChar('.');
if (dot_pos != -1) {
lang = Substring(lang, 0, dot_pos);
}
-
+
+ // Convert underscore to dash.
int32_t underScore = lang.FindChar('_');
if (underScore != -1) {
lang.Replace(underScore, 1, '-');
-#ifdef DEBUG_DICT
- printf("***** Trying LANG from environment |%s|\n",
- NS_ConvertUTF16toUTF8(lang).get());
-#endif
- nsAutoString lang2;
- lang2.Assign(lang);
- rv = TryDictionary(lang2, dictList, DICT_COMPARE_CASE_INSENSITIVE);
+ // Only attempt to set if a _territory is present.
+ rv = SetCurrentDictionary(lang);
}
}
-
+
// Priority 7:
- // If it does not work, pick the first one.
- if (NS_FAILED(rv) && !dictList.IsEmpty()) {
- nsAutoString firstInList;
- firstInList.Assign(dictList[0]);
- rv = TryDictionary(firstInList, dictList, DICT_NORMAL_COMPARE);
-#ifdef DEBUG_DICT
- printf("***** Trying first of list |%s|\n",
- NS_ConvertUTF16toUTF8(dictList[0]).get());
- if (NS_SUCCEEDED(rv)) {
- printf ("***** Setting worked.\n");
+ // If LANG does not work either, pick the first one.
+ if (NS_FAILED(rv)) {
+ if (dictList.Length() > 0) {
+ rv = SetCurrentDictionary(dictList[0]);
}
-#endif
}
- }
+ }
}
// If an error was thrown while setting the dictionary, just
@@ -999,6 +928,7 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
// up. The user can manually reset the language to their choice on
// the dialog if it is wrong.
+ // Dictionary has changed, so delete the suggested word list.
DeleteSuggestedWordList();
return NS_OK;
diff --git a/gfx/graphite2/ChangeLog b/gfx/graphite2/ChangeLog
index 2d5a0c113..026feda56 100644
--- a/gfx/graphite2/ChangeLog
+++ b/gfx/graphite2/ChangeLog
@@ -1,3 +1,34 @@
+1.3.10
+ . Address floating point build parameters to give consistent positioning results across platforms
+ . Various bug fixes
+
+1.3.9
+ . Add Collision COLL_ISSPACE to allow for visible spaces in collision avoidance
+ . Add segment and pass direction information to tracing output
+ . Bug fix rule length testing in 32-bit
+ . Increase slanted margin distances for collision avoidance
+ . Change kerning algorithm to simple outline expansion. Seems to make no visible difference.
+ . Add trace2svg to test tools
+
+1.3.8
+ . Various bug fixes arising from fuzzing
+ . Fix regression that stopped piglatin from working
+ . Make collision avoidance kerning give more regular results
+ . Minor modification to clustering algorithm to handle variable width chars
+
+1.3.7
+ . Bug fixes
+ . Start to deprecate SegCache. This will be going away in a later release.
+
+1.3.6
+ . Bug fixes
+
+1.3.5
+ . Bug fixes
+ . Security bug fix
+ . Fix ARM misalignment problem
+ . Track latest cmake
+
1.3.4
. Transition from Mercurial to Git
. Bug fixes
diff --git a/gfx/graphite2/include/graphite2/XmlLog.h b/gfx/graphite2/include/graphite2/XmlLog.h
deleted file mode 100644
index 554132756..000000000
--- a/gfx/graphite2/include/graphite2/XmlLog.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2010, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
- Alternatively, the contents of this file may be used under the terms
- of the Mozilla Public License (http://mozilla.org/MPL) or the GNU
- General Public License, as published by the Free Software Foundation,
- either version 2 of the License or (at your option) any later version.
-*/
-#pragma once
-
-#include <graphite2/Types.h>
-#include <stdio.h>
-
-typedef enum {
- GRLOG_NONE = 0x0,
- GRLOG_FACE = 0x01,
- GRLOG_SEGMENT = 0x02,
- GRLOG_PASS = 0x04,
- GRLOG_CACHE = 0x08,
-
- GRLOG_OPCODE = 0x80,
- GRLOG_ALL = 0xFF
-} GrLogMask;
-
-// If startGraphiteLogging returns true, logging is enabled and the FILE handle
-// will be closed by graphite when stopGraphiteLogging is called.
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-GR2_API bool graphite_start_logging(FILE * logFile, GrLogMask mask); //may not do anthing if disabled in the implementation of the engine.
-GR2_API void graphite_stop_logging();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/gfx/graphite2/src/Bidi.cpp b/gfx/graphite2/src/Bidi.cpp
deleted file mode 100644
index 48ec2ebfc..000000000
--- a/gfx/graphite2/src/Bidi.cpp
+++ /dev/null
@@ -1,826 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2011, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-#include "inc/Main.h"
-#include "inc/Slot.h"
-#include "inc/Segment.h"
-#include "inc/Bidi.h"
-
-using namespace graphite2;
-
-enum DirCode { // Hungarian: dirc
- Unk = -1,
- N = 0, // other neutrals (default) - ON
- L = 1, // left-to-right, strong - L
- R = 2, // right-to-left, strong - R
- AL = 3, // Arabic letter, right-to-left, strong, AR
- EN = 4, // European number, left-to-right, weak - EN
- EUS = 5, // European separator, left-to-right, weak - ES
- ET = 6, // European number terminator, left-to-right, weak - ET
- AN = 7, // Arabic number, left-to-right, weak - AN
- CUS = 8, // Common number separator, left-to-right, weak - CS
- WS = 9, // white space, neutral - WS
- BN = 10, // boundary neutral - BN
-
- LRO = 11, // LTR override
- RLO = 12, // RTL override
- LRE = 13, // LTR embedding
- RLE = 14, // RTL embedding
- PDF = 15, // pop directional format
- NSM = 16, // non-space mark
- LRI = 17, // LRI isolate
- RLI = 18, // RLI isolate
- FSI = 19, // FSI isolate
- PDI = 20, // pop isolate
- OPP = 21, // opening paired parenthesis
- CPP = 22, // closing paired parenthesis
-
- ON = N
-};
-
-enum DirMask {
- WSflag = int8(1 << 7), // keep track of WS for eos handling
- WSMask = int8(~(1 << 7))
-};
-
-inline uint8 BaseClass(Slot *s) { return s->getBidiClass() & WSMask; }
-
-unsigned int bidi_class_map[] = { 0, 1, 2, 5, 4, 8, 9, 3, 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0 };
-// Algorithms based on Unicode reference standard code. Thanks Asmus Freitag.
-
-void resolveWeak(Slot *start, int sos, int eos);
-void resolveNeutrals(Slot *s, int baseLevel, int sos, int eos);
-void processParens(Slot *s, Segment *seg, uint8 aMirror, int level, BracketPairStack &stack);
-
-inline int calc_base_level(Slot *s)
-{
- int count = 0;
- for ( ; s; s = s->next())
- {
- int cls = s->getBidiClass();
- if (count)
- {
- switch(cls)
- {
- case LRI :
- case RLI :
- case FSI :
- ++count;
- break;
- case PDI :
- --count;
- }
- }
- else
- {
- switch(cls)
- {
- case L :
- return 0;
- case R :
- case AL :
- return 1;
- case LRI :
- case RLI :
- case FSI :
- ++count;
- }
- }
- }
- return 0;
-}
-
-// inline or not?
-void do_resolves(Slot *start, int level, int sos, int eos, int &bmask, Segment *seg, uint8 aMirror, BracketPairStack &stack)
-{
- if (bmask & 0x1F1178)
- resolveWeak(start, sos, eos);
- if (bmask & 0x200000)
- processParens(start, seg, aMirror, level, stack);
- if (bmask & 0x7E0361)
- resolveNeutrals(start, level, sos, eos);
- bmask = 0;
-}
-
-enum maxs
-{
- MAX_LEVEL = 125,
-};
-
-// returns where we are up to in processing
-Slot *process_bidi(Slot *start, int level, int prelevel, int &nextLevel, int dirover, int isol, int &cisol, int &isolerr, int &embederr, int init, Segment *seg, uint8 aMirror, BracketPairStack &bstack)
-{
- int bmask = 0;
- Slot *s = start;
- Slot *slast = start;
- Slot *scurr = 0;
- Slot *stemp;
- int lnextLevel = nextLevel;
- int newLevel;
- int empty = 1;
- for ( ; s; s = s ? s->next() : s)
- {
- int cls = s->getBidiClass();
- bmask |= (1 << cls);
- s->setBidiLevel(level);
- // we keep s->prev() pointing backwards for PDI repeating
-
- switch (cls)
- {
- case BN :
- if (slast == s) slast = s->next(); // ignore if at front of text
- continue;
- case LRE :
- case LRO :
- case RLE :
- case RLO :
- switch (cls)
- {
- case LRE :
- case LRO :
- newLevel = level + (level & 1 ? 1 : 2);
- break;
- case RLE :
- case RLO :
- newLevel = level + (level & 1 ? 2 : 1);
- break;
- }
- s->setBidiClass(BN);
- if (isolerr || newLevel > MAX_LEVEL || embederr)
- {
- if (!isolerr) ++embederr;
- break;
- }
- stemp = scurr;
- if (scurr)
- scurr->prev(0); // don't include control in string
- lnextLevel = newLevel;
- scurr = s;
- s->setBidiLevel(newLevel); // to make it vanish
- // recurse for the new subsequence. A sequence only contains text at the same level
- s = process_bidi(s->next(), newLevel, level, lnextLevel, cls < LRE, 0, cisol, isolerr, embederr, 0, seg, aMirror, bstack);
- // s points at PDF or end of sequence
- // try to keep extending the run and not process it until we have to
- if (lnextLevel != level || !s) // if the subsequence really had something in it, or we are at the end of the run
- {
- if (slast != scurr) // process the run now, don't try to extend it
- {
- // process text preceeding embedding
- do_resolves(slast, level, (prelevel > level ? prelevel : level) & 1, lnextLevel & 1, bmask, seg, aMirror, bstack);
- empty = 0;
- nextLevel = level;
- }
- else if (lnextLevel != level) // the subsequence had something
- {
- empty = 0; // so we aren't empty either
- nextLevel = lnextLevel; // but since we really are empty, pass back our level from the subsequence
- }
- if (s) // if still more to process
- {
- prelevel = lnextLevel; // future text starts out with sos of the higher subsequence
- lnextLevel = level; // and eos is our level
- }
- slast = s ? s->next() : s;
- }
- else if (stemp)
- stemp->prev(s);
- break;
-
- case PDF :
- s->setBidiClass(BN);
- s->prev(0); // unstitch us since we skip final stitching code when we return
- if (isol || isolerr || init) // boundary error conditions
- break;
- if (embederr)
- {
- --embederr;
- break;
- }
- if (slast != s)
- {
- scurr->prev(0); // if slast, then scurr. Terminate before here
- do_resolves(slast, level, level & 1, level & 1, bmask, seg, aMirror, bstack);
- empty = 0;
- }
- if (empty)
- {
- nextLevel = prelevel; // no contents? set our level to that of parent
- s->setBidiLevel(prelevel);
- }
- return s;
-
- case FSI :
- case LRI :
- case RLI :
- switch (cls)
- {
- case FSI :
- if (calc_base_level(s->next()))
- newLevel = level + (level & 1 ? 2 : 1);
- else
- newLevel = level + (level & 1 ? 1 : 2);
- break;
- case LRI :
- newLevel = level + (level & 1 ? 1 : 2);
- break;
- case RLI :
- newLevel = level + (level & 1 ? 2 : 1);
- break;
- }
- if (newLevel > MAX_LEVEL || isolerr)
- {
- ++isolerr;
- s->setBidiClass(ON | WSflag);
- break;
- }
- ++cisol;
- if (scurr) scurr->prev(s);
- scurr = s; // include FSI
- lnextLevel = newLevel;
- // recurse for the new sub sequence
- s = process_bidi(s->next(), newLevel, newLevel, lnextLevel, 0, 1, cisol, isolerr, embederr, 0, seg, aMirror, bstack);
- // s points at PDI
- if (s)
- {
- bmask |= 1 << BaseClass(s); // include the PDI in the mask
- s->setBidiLevel(level); // reset its level to our level
- }
- lnextLevel = level;
- break;
-
- case PDI :
- if (isolerr)
- {
- --isolerr;
- s->setBidiClass(ON | WSflag);
- break;
- }
- if (init || !cisol)
- {
- s->setBidiClass(ON | WSflag);
- break;
- }
- embederr = 0;
- if (!isol) // we are in an embedded subsequence, we have to return through all those
- {
- if (empty) // if empty, reset the level to tell embedded parent
- nextLevel = prelevel;
- return s->prev(); // keep working up the stack pointing at this PDI until we get to an isolate entry
- }
- else // we are terminating an isolate sequence
- {
- if (slast != s) // process any remaining content in this subseqence
- {
- scurr->prev(0);
- do_resolves(slast, level, prelevel & 1, level & 1, bmask, seg, aMirror, bstack);
- }
- --cisol; // pop the isol sequence from the stack
- return s;
- }
-
- default :
- if (dirover)
- s->setBidiClass((level & 1 ? R : L) | (WSflag * (cls == WS)));
- }
- if (s) s->prev(0); // unstitch us
- if (scurr) // stitch in text for processing
- scurr->prev(s);
- scurr = s; // add us to text to process
- }
- if (slast != s)
- {
- do_resolves(slast, level, (level > prelevel ? level : prelevel) & 1, lnextLevel & 1, bmask, seg, aMirror, bstack);
- empty = 0;
- }
- if (empty || isol)
- nextLevel = prelevel;
- return s;
-}
-
-// === RESOLVE WEAK TYPES ================================================
-
-enum bidi_state // possible states
-{
- xa, // arabic letter
- xr, // right leter
- xl, // left letter
-
- ao, // arabic lett. foll by ON
- ro, // right lett. foll by ON
- lo, // left lett. foll by ON
-
- rt, // ET following R
- lt, // ET following L
-
- cn, // EN, AN following AL
- ra, // arabic number foll R
- re, // european number foll R
- la, // arabic number foll L
- le, // european number foll L
-
- ac, // CS following cn
- rc, // CS following ra
- rs, // CS,ES following re
- lc, // CS following la
- ls, // CS,ES following le
-
- ret, // ET following re
- let, // ET following le
-} ;
-
-const bidi_state stateWeak[][10] =
-{
- // N, L, R, AN, EN, AL,NSM, CS, ES, ET,
-{ /*xa*/ ao, xl, xr, cn, cn, xa, xa, ao, ao, ao, /* arabic letter */ },
-{ /*xr*/ ro, xl, xr, ra, re, xa, xr, ro, ro, rt, /* right letter */ },
-{ /*xl*/ lo, xl, xr, la, le, xa, xl, lo, lo, lt, /* left letter */ },
-
-{ /*ao*/ ao, xl, xr, cn, cn, xa, ao, ao, ao, ao, /* arabic lett. foll by ON*/ },
-{ /*ro*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* right lett. foll by ON */ },
-{ /*lo*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* left lett. foll by ON */ },
-
-{ /*rt*/ ro, xl, xr, ra, re, xa, rt, ro, ro, rt, /* ET following R */ },
-{ /*lt*/ lo, xl, xr, la, le, xa, lt, lo, lo, lt, /* ET following L */ },
-
-{ /*cn*/ ao, xl, xr, cn, cn, xa, cn, ac, ao, ao, /* EN, AN following AL */ },
-{ /*ra*/ ro, xl, xr, ra, re, xa, ra, rc, ro, rt, /* arabic number foll R */ },
-{ /*re*/ ro, xl, xr, ra, re, xa, re, rs, rs,ret, /* european number foll R */ },
-{ /*la*/ lo, xl, xr, la, le, xa, la, lc, lo, lt, /* arabic number foll L */ },
-{ /*le*/ lo, xl, xr, la, le, xa, le, ls, ls,let, /* european number foll L */ },
-
-{ /*ac*/ ao, xl, xr, cn, cn, xa, ao, ao, ao, ao, /* CS following cn */ },
-{ /*rc*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* CS following ra */ },
-{ /*rs*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* CS,ES following re */ },
-{ /*lc*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* CS following la */ },
-{ /*ls*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* CS,ES following le */ },
-
-{ /*ret*/ ro, xl, xr, ra, re, xa,ret, ro, ro,ret, /* ET following re */ },
-{ /*let*/ lo, xl, xr, la, le, xa,let, lo, lo,let, /* ET following le */ },
-
-
-};
-
-enum bidi_action // possible actions
-{
- // primitives
- IX = 0x100, // increment
- XX = 0xF, // no-op
-
- // actions
- xxx = (XX << 4) + XX, // no-op
- xIx = IX + xxx, // increment run
- xxN = (XX << 4) + ON, // set current to N
- xxE = (XX << 4) + EN, // set current to EN
- xxA = (XX << 4) + AN, // set current to AN
- xxR = (XX << 4) + R, // set current to R
- xxL = (XX << 4) + L, // set current to L
- Nxx = (ON << 4) + 0xF, // set run to neutral
- Axx = (AN << 4) + 0xF, // set run to AN
- ExE = (EN << 4) + EN, // set run to EN, set current to EN
- NIx = (ON << 4) + 0xF + IX, // set run to N, increment
- NxN = (ON << 4) + ON, // set run to N, set current to N
- NxR = (ON << 4) + R, // set run to N, set current to R
- NxE = (ON << 4) + EN, // set run to N, set current to EN
-
- AxA = (AN << 4) + AN, // set run to AN, set current to AN
- NxL = (ON << 4) + L, // set run to N, set current to L
- LxL = (L << 4) + L, // set run to L, set current to L
-};
-
-
-const bidi_action actionWeak[][10] =
-{
- // N,.. L, R, AN, EN, AL, NSM, CS,..ES, ET,
-{ /*xa*/ xxx, xxx, xxx, xxx, xxA, xxR, xxR, xxN, xxN, xxN, /* arabic letter */ },
-{ /*xr*/ xxx, xxx, xxx, xxx, xxE, xxR, xxR, xxN, xxN, xIx, /* right leter */ },
-{ /*xl*/ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xIx, /* left letter */ },
-
-{ /*ao*/ xxx, xxx, xxx, xxx, xxA, xxR, xxN, xxN, xxN, xxN, /* arabic lett. foll by ON */ },
-{ /*ro*/ xxx, xxx, xxx, xxx, xxE, xxR, xxN, xxN, xxN, xIx, /* right lett. foll by ON */ },
-{ /*lo*/ xxx, xxx, xxx, xxx, xxL, xxR, xxN, xxN, xxN, xIx, /* left lett. foll by ON */ },
-
-{ /*rt*/ Nxx, Nxx, Nxx, Nxx, ExE, NxR, xIx, NxN, NxN, xIx, /* ET following R */ },
-{ /*lt*/ Nxx, Nxx, Nxx, Nxx, LxL, NxR, xIx, NxN, NxN, xIx, /* ET following L */ },
-
-{ /*cn*/ xxx, xxx, xxx, xxx, xxA, xxR, xxA, xIx, xxN, xxN, /* EN, AN following AL */ },
-{ /*ra*/ xxx, xxx, xxx, xxx, xxE, xxR, xxA, xIx, xxN, xIx, /* arabic number foll R */ },
-{ /*re*/ xxx, xxx, xxx, xxx, xxE, xxR, xxE, xIx, xIx, xxE, /* european number foll R */ },
-{ /*la*/ xxx, xxx, xxx, xxx, xxL, xxR, xxA, xIx, xxN, xIx, /* arabic number foll L */ },
-{ /*le*/ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xIx, xIx, xxL, /* european number foll L */ },
-
-{ /*ac*/ Nxx, Nxx, Nxx, Axx, AxA, NxR, NxN, NxN, NxN, NxN, /* CS following cn */ },
-{ /*rc*/ Nxx, Nxx, Nxx, Axx, NxE, NxR, NxN, NxN, NxN, NIx, /* CS following ra */ },
-{ /*rs*/ Nxx, Nxx, Nxx, Nxx, ExE, NxR, NxN, NxN, NxN, NIx, /* CS,ES following re */ },
-{ /*lc*/ Nxx, Nxx, Nxx, Axx, NxL, NxR, NxN, NxN, NxN, NIx, /* CS following la */ },
-{ /*ls*/ Nxx, Nxx, Nxx, Nxx, LxL, NxR, NxN, NxN, NxN, NIx, /* CS,ES following le */ },
-
-{ /*ret*/xxx, xxx, xxx, xxx, xxE, xxR, xxE, xxN, xxN, xxE, /* ET following re */ },
-{ /*let*/xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xxL, /* ET following le */ },
-};
-
-inline uint8 GetDeferredType(bidi_action a) { return (a >> 4) & 0xF; }
-inline uint8 GetResolvedType(bidi_action a) { return a & 0xF; }
-inline DirCode EmbeddingDirection(int l) { return l & 1 ? R : L; }
-
-// Neutrals
-enum neutral_action
-{
- // action to resolve previous input
- nL = L, // resolve EN to L
- En = 3 << 4, // resolve neutrals run to embedding level direction
- Rn = R << 4, // resolve neutrals run to strong right
- Ln = L << 4, // resolved neutrals run to strong left
- In = (1<<8), // increment count of deferred neutrals
- LnL = (1<<4)+L, // set run and EN to L
-};
-
-// ->prev() here means ->next()
-void SetDeferredRunClass(Slot *s, Slot *sRun, int nval)
-{
- if (!sRun || s == sRun) return;
- for (Slot *p = sRun; p != s; p = p->prev())
- if (p->getBidiClass() == WS) p->setBidiClass(nval | WSflag);
- else if (BaseClass(p) != BN) p->setBidiClass(nval | (p->getBidiClass() & WSflag));
-}
-
-void SetThisDeferredRunClass(Slot *s, Slot *sRun, int nval)
-{
- if (!sRun) return;
- for (Slot *p = sRun, *e = s->prev(); p != e; p = p->prev())
- if (p->getBidiClass() == WS) p->setBidiClass(nval | WSflag);
- else if (BaseClass(p) != BN) p->setBidiClass(nval | (p->getBidiClass() & WSflag));
-}
-
-void resolveWeak(Slot *start, int sos, int eos)
-{
- int state = (sos & 1) ? xr : xl;
- int cls;
- Slot *s = start;
- Slot *sRun = NULL;
- Slot *sLast = s;
-
- for ( ; s; s = s->prev())
- {
- sLast = s;
- cls = BaseClass(s);
- switch (cls)
- {
- case BN :
- if (s == start) start = s->prev(); // skip initial BNs for NSM resolving
- continue;
- case LRI :
- case RLI :
- case FSI :
- case PDI :
- {
- Slot *snext = s->prev();
- if (snext && snext->getBidiClass() == NSM)
- snext->setBidiClass(ON);
- s->setBidiClass(ON | WSflag);
- }
- break;
-
- case NSM :
- if (s == start)
- {
- cls = EmbeddingDirection(sos);
- s->setBidiClass(cls);
- }
- break;
- }
-
- bidi_action action = actionWeak[state][bidi_class_map[cls]];
- int clsRun = GetDeferredType(action);
- if (clsRun != XX)
- {
- SetDeferredRunClass(s, sRun, clsRun);
- sRun = NULL;
- }
- int clsNew = GetResolvedType(action);
- if (clsNew != XX)
- s->setBidiClass(clsNew);
- if (!sRun && (IX & action))
- sRun = s;
- state = stateWeak[state][bidi_class_map[cls]];
- }
-
- cls = EmbeddingDirection(eos);
- int clsRun = GetDeferredType(actionWeak[state][bidi_class_map[cls]]);
- if (clsRun != XX)
- SetThisDeferredRunClass(sLast, sRun, clsRun);
-}
-
-void processParens(Slot *s, Segment *seg, uint8 aMirror, int level, BracketPairStack &stack)
-{
- uint8 mask = 0;
- int8 lastDir = -1;
- BracketPair *p;
- for ( ; s; s = s->prev()) // walk the sequence
- {
- uint16 ogid = seg->glyphAttr(s->gid(), aMirror) || s->gid();
- int cls = BaseClass(s);
-
- switch(cls)
- {
- case OPP :
- stack.orin(mask);
- stack.push(ogid, s, lastDir, lastDir != CPP);
- mask = 0;
- lastDir = OPP;
- break;
- case CPP :
- stack.orin(mask);
- p = stack.scan(s->gid());
- if (!p) break;
- mask = 0;
- stack.close(p, s);
- lastDir = CPP;
- break;
- case L :
- lastDir = L;
- mask |= 1;
- break;
- case R :
- case AL :
- case AN :
- case EN :
- lastDir = R;
- mask |= 2;
- }
- }
- if (stack.size())
- {
- for (p = stack.start(); p; p =p->next()) // walk the stack
- {
- if (p->close() && p->mask())
- {
- int dir = (level & 1) + 1;
- if (p->mask() & dir)
- { }
- else if (p->mask() & (1 << (~level & 1))) // if inside has strong other embedding
- {
- int ldir = p->before();
- if ((p->before() == OPP || p->before() == CPP) && p->prev())
- {
- for (BracketPair *q = p->prev(); q; q = q->prev())
- {
- ldir = q->open()->getBidiClass();
- if (ldir < 3) break;
- ldir = q->before();
- if (ldir < 3) break;
- }
- if (ldir > 2) ldir = 0;
- }
- if (ldir > 0 && (ldir - 1) != (level & 1)) // is dir given opp. to level dir (ldir == R or L)
- dir = (~level & 1) + 1;
- }
- p->open()->setBidiClass(dir);
- p->close()->setBidiClass(dir);
- }
- }
- stack.clear();
- }
-}
-
-int GetDeferredNeutrals(int action, int level)
-{
- action = (action >> 4) & 0xF;
- if (action == (En >> 4))
- return EmbeddingDirection(level);
- else
- return action;
-}
-
-int GetResolvedNeutrals(int action)
-{
- return action & 0xF;
-}
-
-// state values
-enum neutral_state
-{
- // new temporary class
- r, // R and characters resolved to R
- l, // L and characters resolved to L
- rn, // N preceded by right
- ln, // N preceded by left
- a, // AN preceded by left (the abbrev 'la' is used up above)
- na, // N preceeded by a
-} ;
-
-const uint8 neutral_class_map[] = { 0, 1, 2, 0, 4, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-const int actionNeutrals[][5] =
-{
-// cls= N, L, R, AN, EN, state =
-{ In, 0, 0, 0, 0, }, // r right
-{ In, 0, 0, 0, L, }, // l left
-
-{ In, En, Rn, Rn, Rn, }, // rn N preceded by right
-{ In, Ln, En, En, LnL, }, // ln N preceded by left
-
-{ In, 0, 0, 0, L, }, // a AN preceded by left
-{ In, En, Rn, Rn, En, }, // na N preceded by a
-} ;
-
-const int stateNeutrals[][5] =
-{
-// cls= N, L, R, AN, EN state =
-{ rn, l, r, r, r, }, // r right
-{ ln, l, r, a, l, }, // l left
-
-{ rn, l, r, r, r, }, // rn N preceded by right
-{ ln, l, r, a, l, }, // ln N preceded by left
-
-{ na, l, r, a, l, }, // a AN preceded by left
-{ na, l, r, a, l, }, // na N preceded by la
-} ;
-
-void resolveNeutrals(Slot *s, int baseLevel, int sos, int eos)
-{
- int state = (sos & 1) ? r : l;
- int cls;
- Slot *sRun = NULL;
- Slot *sLast = s;
- int level = baseLevel;
-
- for ( ; s; s = s->prev())
- {
- sLast = s;
- cls = BaseClass(s);
- switch (cls)
- {
- case BN :
- continue;
- case LRI :
- case RLI :
- case FSI :
- s->setBidiClass(BN | WSflag);
- continue;
-
- default :
- int action = actionNeutrals[state][neutral_class_map[cls]];
- int clsRun = GetDeferredNeutrals(action, level);
- if (clsRun != N)
- {
- SetDeferredRunClass(s, sRun, clsRun);
- sRun = NULL;
- }
- int clsNew = GetResolvedNeutrals(action);
- if (clsNew != N)
- s->setBidiClass(clsNew);
- if (!sRun && (action & In))
- sRun = s;
- state = stateNeutrals[state][neutral_class_map[cls]];
- }
- }
- cls = EmbeddingDirection(eos);
- int clsRun = GetDeferredNeutrals(actionNeutrals[state][neutral_class_map[cls]], level);
- if (clsRun != N)
- SetThisDeferredRunClass(sLast, sRun, clsRun);
-}
-
-const int addLevel[][4] =
-{
- // cls = L, R, AN, EN level =
-/* even */ { 0, 1, 2, 2, }, // EVEN
-/* odd */ { 1, 0, 1, 1, }, // ODD
-
-};
-
-void resolveImplicit(Slot *s, Segment *seg, uint8 aMirror)
-{
- bool rtl = seg->dir() & 1;
- int level = rtl;
- Slot *slast = 0;
- for ( ; s; s = s->next())
- {
- int cls = BaseClass(s);
- s->prev(slast); // restitch the prev() side of the doubly linked list
- slast = s;
- if (cls == AN)
- cls = AL; // use AL value as the index for AN, no property change
- if (cls < 5 && cls > 0)
- {
- level = s->getBidiLevel();
- level += addLevel[level & 1][cls - 1];
- s->setBidiLevel(level);
- }
- if (aMirror)
- {
- int hasChar = seg->glyphAttr(s->gid(), aMirror + 1);
- if ( ((level & 1) && (!(seg->dir() & 4) || !hasChar))
- || ((rtl ^ (level & 1)) && (seg->dir() & 4) && hasChar) )
- {
- unsigned short g = seg->glyphAttr(s->gid(), aMirror);
- if (g) s->setGlyph(seg, g);
- }
- }
- }
-}
-
-void resolveWhitespace(int baseLevel, Slot *s)
-{
- for ( ; s; s = s->prev())
- {
- int8 cls = s->getBidiClass();
- if (cls == WS || (cls & WSflag))
- s->setBidiLevel(baseLevel);
- else if (cls != BN)
- break;
- }
-}
-
-
-/*
-Stitch two spans together to make another span (with ends tied together).
-If the level is odd then swap the order of the two spans
-*/
-inline
-Slot * join(int level, Slot * a, Slot * b)
-{
- if (!a) return b;
- if (level & 1) { Slot * const t = a; a = b; b = t; }
- Slot * const t = b->prev();
- a->prev()->next(b); b->prev(a->prev()); // splice middle
- t->next(a); a->prev(t); // splice ends
- return a;
-}
-
-/*
-Given the first slot in a run of slots with the same bidi level, turn the run
-into it's own little doubly linked list ring (a span) with the two ends joined together.
-If the run is rtl then reverse its direction.
-Returns the first slot after the span
-*/
-Slot * span(Slot * & cs, const bool rtl)
-{
- Slot * r = cs, * re = cs; cs = cs->next();
- if (rtl)
- {
- Slot * t = r->next(); r->next(r->prev()); r->prev(t);
- for (int l = r->getBidiLevel(); cs && (l == cs->getBidiLevel() || cs->getBidiClass() == BN); cs = cs->prev())
- {
- re = cs;
- t = cs->next(); cs->next(cs->prev()); cs->prev(t);
- }
- r->next(re);
- re->prev(r);
- r = re;
- }
- else
- {
- for (int l = r->getBidiLevel(); cs && (l == cs->getBidiLevel() || cs->getBidiClass() == BN); cs = cs->next())
- re = cs;
- r->prev(re);
- re->next(r);
- }
- if (cs) cs->prev(0);
- return r;
-}
-
-inline int getlevel(const Slot *cs, const int level)
-{
- while (cs && cs->getBidiClass() == BN)
- { cs = cs->next(); }
- if (cs)
- return cs->getBidiLevel();
- else
- return level;
-}
-
-Slot *resolveOrder(Slot * & cs, const bool reordered, const int level)
-{
- Slot * r = 0;
- int ls;
- while (cs && level <= (ls = getlevel(cs, level) - reordered))
- {
- r = join(level, r, level < ls
- ? resolveOrder(/* updates */cs, reordered, level+1) // find span of heighest level
- : span(/* updates */cs, level & 1));
- }
- return r;
-}
diff --git a/gfx/graphite2/src/GlyphFaceCache.cpp b/gfx/graphite2/src/GlyphFaceCache.cpp
deleted file mode 100644
index 9abb1aa9d..000000000
--- a/gfx/graphite2/src/GlyphFaceCache.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2010, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-#include "inc/GlyphFaceCache.h"
-#include "graphite2/Font.h"
-#include "inc/Face.h" //for the tags
-#include "inc/Endian.h"
-
-using namespace graphite2;
-
-/*virtual*/ bool GlyphFaceCacheHeader::initialize(const Face & face, const bool dumb_font) //return result indicates success. Do not use if failed.
-{
- if ((m_pLoca = face.getTable(Tag::loca, &m_lLoca)) == NULL) return false;
- if ((m_pHead = face.getTable(Tag::head)) == NULL) return false;
- if ((m_pGlyf = face.getTable(Tag::glyf, &m_lGlyf)) == NULL) return false;
- if ((m_pHmtx = face.getTable(Tag::hmtx, &m_lHmtx)) == NULL) return false;
- if ((m_pHHea = face.getTable(Tag::hhea)) == NULL) return false;
-
- const void* pMaxp = face.getTable(Tag::maxp);
- if (pMaxp == NULL) return false;
- m_nGlyphs = m_nGlyphsWithGraphics = (unsigned short)TtfUtil::GlyphCount(pMaxp);
- if (TtfUtil::LocaLookup(m_nGlyphs-1, m_pLoca, m_lLoca, m_pHead) == size_t(-1))
- return false; // This will fail if m_nGlyphs is wildly out of range.
-
- if (!dumb_font)
- {
- if ((m_pGlat = face.getTable(Tag::Glat, &m_lGlat)) == NULL) return false;
- m_fGlat = be::peek<uint32>(m_pGlat);
- size_t lGloc;
- if ((m_pGloc = face.getTable(Tag::Gloc, &lGloc)) == NULL) return false;
- if (lGloc < 6) return false;
- int version = be::read<uint32>(m_pGloc);
- if (version != 0x00010000) return false;
-
- const uint16 locFlags = be::read<uint16>(m_pGloc);
- m_numAttrs = be::read<uint16>(m_pGloc);
- if (m_numAttrs > 0x1000) return false; // is this hard limit appropriate?
-
- if (locFlags & 1)
- {
- m_locFlagsUse32Bit = true;
- m_nGlyphsWithAttributes = (unsigned short)((lGloc - 12) / 4);
- }
- else
- {
- m_locFlagsUse32Bit = false;
- m_nGlyphsWithAttributes = (unsigned short)((lGloc - 10) / 2);
- }
-
- if (m_nGlyphsWithAttributes > m_nGlyphs)
- m_nGlyphs = m_nGlyphsWithAttributes;
- }
-
- return true;
-}
-
-GlyphFaceCache* GlyphFaceCache::makeCache(const GlyphFaceCacheHeader& hdr)
-{
- return new (hdr) GlyphFaceCache(hdr);
-}
-
-GlyphFaceCache::GlyphFaceCache(const GlyphFaceCacheHeader& hdr)
-: GlyphFaceCacheHeader(hdr)
-{
- unsigned int nGlyphs = numGlyphs();
-
- for (unsigned int i = 0; i < nGlyphs; i++)
- {
- *glyphPtrDirect(i) = NULL;
- }
-}
-
-GlyphFaceCache::~GlyphFaceCache()
-{
- unsigned int nGlyphs = numGlyphs();
- int deltaPointers = (*glyphPtrDirect(nGlyphs-1u) - *glyphPtrDirect(0u));
- if ((nGlyphs > 0u) && (deltaPointers == static_cast<int>(nGlyphs - 1)))
- {
- for (unsigned int i=0 ; i<nGlyphs; ++i)
- {
- GlyphFace *p = *glyphPtrDirect(i);
- assert (p);
- p->~GlyphFace();
- }
- free (*glyphPtrDirect(0));
- }
- else
- {
- for (unsigned int i=0 ; i<nGlyphs; ++i)
- {
- GlyphFace *p = *glyphPtrDirect(i);
- if (p)
- {
- p->~GlyphFace();
- free(p);
- }
- }
- }
-}
-
-void GlyphFaceCache::loadAllGlyphs()
-{
- unsigned int nGlyphs = numGlyphs();
-// size_t sparse_size = 0;
- GlyphFace * glyphs = gralloc<GlyphFace>(nGlyphs);
- for (unsigned short glyphid = 0; glyphid < nGlyphs; glyphid++)
- {
- GlyphFace **p = glyphPtrDirect(glyphid);
- *p = &(glyphs[glyphid]);
- new(*p) GlyphFace(*this, glyphid);
-// sparse_size += (*p)->m_attrs._sizeof();
- }
-// const size_t flat_size = nGlyphs*(sizeof(uint16*) + sizeof(uint16)*numAttrs());
-// assert(sparse_size <= flat_size);
-}
-
-/*virtual*/ const GlyphFace *GlyphFaceCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
-{
- GlyphFace **p = glyphPtrDirect(glyphid);
- if (*p)
- return *p;
-
- *p = (GlyphFace*)malloc(sizeof(GlyphFace));
- new(*p) GlyphFace(*this, glyphid);
- return *p;
-}
diff --git a/gfx/graphite2/src/Rule.cpp b/gfx/graphite2/src/Rule.cpp
deleted file mode 100644
index 34c8ae169..000000000
--- a/gfx/graphite2/src/Rule.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2011, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-
-#include "inc/Rule.h"
-#include "inc/Segment.h"
-
-using namespace graphite2;
diff --git a/gfx/graphite2/src/XmlTraceLog.cpp b/gfx/graphite2/src/XmlTraceLog.cpp
deleted file mode 100644
index f34d15018..000000000
--- a/gfx/graphite2/src/XmlTraceLog.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2010, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-
-#include <cstring>
-#include <cstdarg>
-#include "Main.h"
-#include "XmlTraceLog.h"
-
-
-using namespace graphite2;
-
-#ifndef DISABLE_TRACING
-
-/*static*/ XmlTraceLog XmlTraceLog::sm_NullLog(NULL, NULL, GRLOG_NONE);
-XmlTraceLog * XmlTraceLog::sLog = &sm_NullLog;
-
-XmlTraceLog::XmlTraceLog(FILE * file, const char * ns, GrLogMask logMask)
- : m_file(file), m_depth(0), m_mask(logMask)
-{
- if (!m_file) return;
- int deep = 0;
-#ifdef ENABLE_DEEP_TRACING
- deep = 1;
-#endif
- fprintf(m_file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%s xmlns=\"%s\" mask=\"%x\" deep=\"%d\">",
- xmlTraceLogElements[ElementTopLevel].mName, ns, logMask, deep);
- m_elementStack[m_depth++] = ElementTopLevel;
- m_elementEmpty = true;
- m_inElement = false;
- m_lastNodeText = false;
-}
-
-XmlTraceLog::~XmlTraceLog()
-{
- if (m_file && m_file != stdout && m_file != stderr)
- {
- assert(m_depth == 1);
- while (m_depth > 0)
- {
- closeElement(m_elementStack[m_depth-1]);
- }
- fclose(m_file);
- m_file = NULL;
- }
-}
-
-void XmlTraceLog::addSingleElement(XmlTraceLogElement eId, const int value)
-{
- if (!m_file) return;
- if (m_inElement)
- {
- if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
- fprintf(m_file, ">");
- }
- if (xmlTraceLogElements[eId].mFlags & m_mask)
- {
- if (!m_lastNodeText)
- {
- fprintf(m_file, "\n");
- for (size_t i = 0; i < m_depth; i++)
- {
- fprintf(m_file, " ");
- }
- }
- fprintf(m_file, "<%s val=\"%d\"/>", xmlTraceLogElements[eId].mName, value);
- }
- m_inElement = false;
- m_lastNodeText = false;
-}
-
-void XmlTraceLog::writeElementArray(XmlTraceLogElement eId, XmlTraceLogAttribute aId, int16 values [], size_t length)
-{
- if (!m_file) return;
- if (xmlTraceLogElements[eId].mFlags & m_mask)
- {
- if(m_inElement && xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
- {
- fprintf(m_file, ">");
- m_inElement = false;
- }
- // line break after 5 columns
- for (size_t i = 0; i < length; i++)
- {
- if (i % 5 == 0)
- {
- fprintf(m_file, "\n");
- for (size_t j = 0; j < m_depth; j++)
- {
- fprintf(m_file, " ");
- }
- }
- fprintf(m_file, "<%s index=\"%d\" %s=\"%d\"/>", xmlTraceLogElements[eId].mName, int(i),
- xmlTraceLogAttributes[aId], (int)values[i]);
- }
- }
-}
-
-void XmlTraceLog::writeText(const char * utf8)
-{
- if (!m_file) return;
- if (m_inElement)
- {
- if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
- {
- fprintf(m_file, ">");
- }
- m_inElement = false;
- }
- if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
- {
- escapeIfNeeded(utf8);
- }
- m_lastNodeText = true;
-}
-
-void XmlTraceLog::writeUnicode(const uint32 code)
-{
- if (!m_file) return;
- if (m_inElement)
- {
- if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
- {
- fprintf(m_file, ">");
- }
- m_inElement = false;
- }
- if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
- {
- fprintf(m_file, "&#x%02x;", code);
- }
- m_lastNodeText = true;
-}
-
-void XmlTraceLog::escapeIfNeeded(const char * data)
-{
- size_t length = strlen(data);
- for (size_t i = 0; i < length; i++)
- {
- switch (data[i])
- {
- case '<':
- fprintf(m_file, "&lt;");
- break;
- case '>':
- fprintf(m_file, "&gt;");
- break;
- case '&':
- fprintf(m_file, "&amp;");
- break;
- case '"':
- fprintf(m_file, "&#34;");
- break;
- default:
- fprintf(m_file, "%c", data[i]);
- }
- }
-}
-
-static const int MAX_MSG_LEN = 1024;
-
-void XmlTraceLog::error(const char * msg, ...)
-{
- if (!m_file) return;
- openElement(ElementError);
- va_list args;
- va_start(args, msg);
- char buffer[MAX_MSG_LEN];
-#ifndef NDEBUG
- int len =
-#endif
- vsnprintf(buffer, MAX_MSG_LEN, msg, args);
- assert(len + 1 < MAX_MSG_LEN);
- writeText(buffer);
- va_end(args);
- closeElement(ElementError);
-}
-
-void XmlTraceLog::warning(const char * msg, ...)
-{
- if (!m_file) return;
- openElement(ElementWarning);
- va_list args;
- va_start(args, msg);
- char buffer[MAX_MSG_LEN];
-#ifndef NDEBUG
- int len =
-#endif
- vsnprintf(buffer, MAX_MSG_LEN, msg, args);
- assert(len + 1 < MAX_MSG_LEN);
- writeText(buffer);
- va_end(args);
- closeElement(ElementWarning);
-}
-
-#endif //!DISABLE_TRACING
diff --git a/gfx/graphite2/src/XmlTraceLogTags.cpp b/gfx/graphite2/src/XmlTraceLogTags.cpp
deleted file mode 100644
index b6ec970ac..000000000
--- a/gfx/graphite2/src/XmlTraceLogTags.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2010, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-#include "Main.h"
-#include "XmlTraceLogTags.h"
-
-
-using namespace graphite2;
-
-#ifndef DISABLE_TRACING
-
-
-// start this at same line number as in XmlTraceLogTags.h
-const XmlTraceLogTag graphite2::xmlTraceLogElements[NumElements] = {
- XmlTraceLogTag("Graphite2Log", GRLOG_ALL),
- XmlTraceLogTag("Face", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("Glyphs", GRLOG_FACE),
- XmlTraceLogTag("GlyphFace", GRLOG_FACE),
- XmlTraceLogTag("Attr", GRLOG_FACE),
- XmlTraceLogTag("Silf", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("SilfSub", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("Pass", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("Pseudo", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("ClassMap", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("LookupClass", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("Lookup", GRLOG_FACE | GRLOG_PASS),
- XmlTraceLogTag("Range", GRLOG_PASS),
- XmlTraceLogTag("RuleMap", GRLOG_PASS),
- XmlTraceLogTag("Rule", GRLOG_PASS),
- XmlTraceLogTag("StartState", GRLOG_PASS),
- XmlTraceLogTag("StateTransitions", GRLOG_PASS),
- XmlTraceLogTag("TR", GRLOG_PASS),
- XmlTraceLogTag("TD", GRLOG_PASS),
- XmlTraceLogTag("Constraint", GRLOG_PASS),
- XmlTraceLogTag("Constraints", GRLOG_PASS),
- XmlTraceLogTag("Actions", GRLOG_PASS),
- XmlTraceLogTag("Action", GRLOG_PASS),
- XmlTraceLogTag("Features", GRLOG_PASS),
- XmlTraceLogTag("Feature", GRLOG_PASS),
- XmlTraceLogTag("FeatureSetting", GRLOG_PASS),
- XmlTraceLogTag("Segment", GRLOG_SEGMENT),
- XmlTraceLogTag("Slot", GRLOG_SEGMENT),
- XmlTraceLogTag("Text", GRLOG_SEGMENT),
- XmlTraceLogTag("OpCode", GRLOG_OPCODE),
- XmlTraceLogTag("TestRule", GRLOG_OPCODE),
- XmlTraceLogTag("DoRule", GRLOG_OPCODE),
- XmlTraceLogTag("RunPass", GRLOG_OPCODE),
- XmlTraceLogTag("Params", GRLOG_OPCODE),
- XmlTraceLogTag("Push", GRLOG_OPCODE),
- XmlTraceLogTag("SubSeg", GRLOG_SEGMENT),
- XmlTraceLogTag("SegCache", GRLOG_CACHE),
- XmlTraceLogTag("SegCacheEntry", GRLOG_CACHE),
- XmlTraceLogTag("Glyph", GRLOG_CACHE),
- XmlTraceLogTag("PassResult", GRLOG_OPCODE),
-
- XmlTraceLogTag("Error", GRLOG_ALL),
- XmlTraceLogTag("Warning", GRLOG_ALL)
- // Nothing corresponds to NumElements
-};
-
-
-
-// start this at same line number as in XmlTraceLogTags.h
-const char * graphite2::xmlTraceLogAttributes[NumAttributes] = {
- "index",
- "version",
- "major",
- "minor",
- "num",
- "glyphId",
- "advance",
- "advanceX",
- "advanceY",
- "attrId",
- "attrVal",
- "compilerMajor",
- "compilerMinor",
- "numPasses",//AttrNumPasses,
- "subPass",//AttrSubPass,
- "posPass",//AttrPosPass,
- "justPass",//AttrJustPass,
- "bidiPass",//AttrBidiPass,
- "preContext",//AttrPreContext,
- "postContext",//AttrPostContext,
- "pseudoGlyph",//AttrPseudoGlyph,
- "breakWeight",//AttrBreakWeight,
- "directionality",//AttrDirectionality,
- "numJustLevels",//AttrNumJustLevels,
- "numLigCompAttr",//AttrLigComp,
- "numUserDefinedAttr",//AttrUserDefn,
- "maxNumLigComp",//AttrNumLigComp,
- "numCriticalFeatures",//AttrNumCritFeatures,
- "numScripts",//AttrNumScripts
- "lineBreakglyph",//,AttrLBGlyph,
- "numPseudo",
- "numClasses",
- "numLinear",
- "passId",//AttrPassId,
- "flags",//AttrFlags,
- "maxRuleLoop",//AttrMaxRuleLoop,
- "maxRuleContext",//AttrMaxRuleContext,
- "maxBackup",//AttrMaxBackup,
- "numRules",//AttrNumRules,
- "numRows",//AttrNumRows,
- "numTransitionStates",//AttrNumTransition,
- "numSuccessStates",//AttrNumSuccess,
- "numColumns",//AttrNumColumns,
- "numRanges",//AttrNumRanges,
- "minPrecontext",//AttrMinPrecontext,
- "maxPrecontext",//AttrMaxPrecontext,
- "firstId",
- "lastId",
- "colId",
- "successId",
- "ruleId",
- "contextLength",
- "state",
- "value",
- "sortKey",
- "precontext",
- "action",
- "actionCode",
- "arg1",
- "arg2",
- "arg3",
- "arg4",
- "arg5",
- "arg6",
- "arg7",
- "arg8",
- "label",
- "length",
- "x",
- "y",
- "before",
- "after",
- "encoding",
- "name",
- "result",
- "default",
- "accessCount",
- "lastAccess",
- "misses"
-};
-
-#endif
diff --git a/gfx/graphite2/src/inc/Bidi.h b/gfx/graphite2/src/inc/Bidi.h
deleted file mode 100644
index 9593c7e14..000000000
--- a/gfx/graphite2/src/inc/Bidi.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2013, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-#pragma once
-
-namespace graphite2
-{
-
-class BracketPair
-{
-public:
- BracketPair(uint16 g, Slot *s, uint8 b, BracketPair *p, BracketPair *l) : _open(s), _close(0), _parent(p), _next(0), _prev(l), _gid(g), _mask(0), _before(b) {};
- uint16 gid() const { return _gid; }
- Slot *open() const { return _open; }
- Slot *close() const { return _close; }
- uint8 mask() const { return _mask; }
- int8 before() const { return _before; }
- BracketPair *parent() const { return _parent; }
- void close(Slot *s) { _close = s; }
- BracketPair *next() const { return _next; }
- BracketPair *prev() const { return _prev; }
- void next(BracketPair *n) { _next = n; }
- void orin(uint8 m) { _mask |= m; }
-private:
- Slot * _open; // Slot of opening paren
- Slot * _close; // Slot of closing paren
- BracketPair * _parent; // pair this pair is in or NULL
- BracketPair * _next; // next pair along the string
- BracketPair * _prev; // pair that closed last before we opened
- uint16 _gid; // gid of closing paren
- uint8 _mask; // bitmap (2 bits) of directions within the pair
- int8 _before; // most recent strong type (L, R, OPP, CPP)
-};
-
-class BracketPairStack
-{
-public:
- BracketPairStack(int s) : _stack(grzeroalloc<BracketPair>(s)), _ip(_stack - 1), _top(0), _last(0), _lastclose(0), _size(s) {}
- ~BracketPairStack() { free(_stack); }
-
-public:
- BracketPair *scan(uint16 gid);
- void close(BracketPair *tos, Slot *s);
- BracketPair *push(uint16 gid, Slot *pos, uint8 before, int prevopen);
- void orin(uint8 mask);
- void clear() { _ip = _stack - 1; _top = 0; _last = 0; _lastclose = 0; }
- int size() const { return _size; }
- BracketPair *start() const { return _stack; }
-
- CLASS_NEW_DELETE
-
-private:
-
- BracketPair *_stack; // start of storage
- BracketPair *_ip; // where to add the next pair
- BracketPair *_top; // current parent
- BracketPair *_last; // end of next() chain
- BracketPair *_lastclose; // last pair to close
- int _size; // capacity
-};
-
-inline BracketPair *BracketPairStack::scan(uint16 gid)
-{
- BracketPair *res = _top;
- while (res >= _stack)
- {
- if (res->gid() == gid)
- return res;
- res = res->parent();
- }
- return 0;
-}
-
-inline void BracketPairStack::close(BracketPair *tos, Slot *s)
-{
- for ( ; _last && _last != tos && !_last->close(); _last = _last->parent())
- { }
- tos->close(s);
- _last->next(NULL);
- _lastclose = tos;
- _top = tos->parent();
-}
-
-inline BracketPair *BracketPairStack::push(uint16 gid, Slot *pos, uint8 before, int prevopen)
-{
- if (++_ip - _stack < _size && _stack)
- {
- ::new (_ip) BracketPair(gid, pos, before, _top, prevopen ? _last : _lastclose);
- if (_last) _last->next(_ip);
- _last = _ip;
- }
- _top = _ip;
- return _ip;
-}
-
-inline void BracketPairStack::orin(uint8 mask)
-{
- BracketPair *t = _top;
- for ( ; t; t = t->parent())
- t->orin(mask);
-}
-
-}
diff --git a/gfx/graphite2/src/inc/GlyphFaceCache.h b/gfx/graphite2/src/inc/GlyphFaceCache.h
deleted file mode 100644
index 4afdfbe01..000000000
--- a/gfx/graphite2/src/inc/GlyphFaceCache.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2010, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-#pragma once
-
-#include "inc/GlyphFace.h"
-#include "graphite2/Font.h"
-
-namespace graphite2 {
-
-class Segment;
-class Face;
-class FeatureVal;
-
-
-class GlyphFaceCacheHeader
-{
-public:
- bool initialize(const Face & face, const bool dumb_font); //return result indicates success. Do not use if failed.
- unsigned short numGlyphs() const { return m_nGlyphs; }
- unsigned short numAttrs() const { return m_numAttrs; }
-
-private:
-friend class Face;
-friend class GlyphFace;
- const byte* m_pHead,
- * m_pHHea,
- * m_pHmtx,
- * m_pGlat,
- * m_pGloc,
- * m_pGlyf,
- * m_pLoca;
- size_t m_lHmtx,
- m_lGlat,
- m_lGlyf,
- m_lLoca;
-
- uint32 m_fGlat;
- unsigned short m_numAttrs, // number of glyph attributes per glyph
- m_nGlyphsWithGraphics, //i.e. boundary box and advance
- m_nGlyphsWithAttributes,
- m_nGlyphs; // number of glyphs in the font. Max of the above 2.
- bool m_locFlagsUse32Bit;
-};
-
-class GlyphFaceCache : public GlyphFaceCacheHeader
-{
-public:
- static GlyphFaceCache* makeCache(const GlyphFaceCacheHeader& hdr /*, EGlyphCacheStrategy requested */);
-
- GlyphFaceCache(const GlyphFaceCacheHeader& hdr);
- ~GlyphFaceCache();
-
- const GlyphFace *glyphSafe(unsigned short glyphid) const { return glyphid<numGlyphs()?glyph(glyphid):NULL; }
- uint16 glyphAttr(uint16 gid, uint8 gattr) const { if (gattr>=numAttrs()) return 0; const GlyphFace*p=glyphSafe(gid); return p?p->getAttr(gattr):0; }
-
- void * operator new (size_t s, const GlyphFaceCacheHeader& hdr)
- {
- return malloc(s + sizeof(GlyphFace*)*hdr.numGlyphs());
- }
- // delete in case an exception is thrown in constructor
- void operator delete(void* p, const GlyphFaceCacheHeader& ) throw()
- {
- free(p);
- }
-
- const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid
- void loadAllGlyphs();
-
- CLASS_NEW_DELETE
-
-private:
- GlyphFace **glyphPtrDirect(unsigned short glyphid) const { return (GlyphFace **)((const char*)(this)+sizeof(GlyphFaceCache)+sizeof(GlyphFace*)*glyphid);}
-
-private: //defensive
- GlyphFaceCache(const GlyphFaceCache&);
- GlyphFaceCache& operator=(const GlyphFaceCache&);
-};
-
-} // namespace graphite2
diff --git a/gfx/graphite2/src/inc/Shrinker.h b/gfx/graphite2/src/inc/Shrinker.h
deleted file mode 100644
index e4db2f135..000000000
--- a/gfx/graphite2/src/inc/Shrinker.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (c) 2012, Siyuan Fu <fusiyuan2010@gmail.com>
- Copyright (c) 2015, SIL International
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#pragma once
-
-#include <cassert>
-#include <cstddef>
-#include <cstring>
-
-#include <iterator>
-
-//the code from LZ4
-#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
-# define expect(expr,value) (__builtin_expect ((expr),(value)) )
-#else
-# define expect(expr,value) (expr)
-#endif
-#define likely(expr) expect((expr) != 0, 1)
-#define unlikely(expr) expect((expr) != 0, 0)
-////////////////////
-
-
-namespace
-{
-
-#if defined(_MSC_VER)
-typedef unsigned __int8 u8;
-typedef unsigned __int16 u16;
-typedef unsigned __int32 u32;
-typedef unsigned __int64 u64;
-#else
-#include <stdint.h>
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-#endif
-
-ptrdiff_t const MINMATCH = 4;
-
-template<int S>
-inline
-void unaligned_copy(void * d, void const * s) {
- ::memcpy(d, s, S);
-}
-
-inline
-u8 * memcpy_nooverlap(u8 * d, u8 const * s, size_t n) {
- size_t const WS = sizeof(unsigned long);
- u8 const * e = s + n;
- do
- {
- unaligned_copy<WS>(d, s);
- d += WS;
- s += WS;
- }
- while (s < e);
- d-=(s-e);
-
- return d;
-}
-
-
-inline
-u8 * memcpy_nooverlap_surpass(u8 * d, u8 const * s, size_t n) {
- size_t const WS = sizeof(unsigned long);
- size_t wn = n/WS;
- while (wn--)
- {
- unaligned_copy<WS>(d, s);
- d += WS;
- s += WS;
- }
- n &= WS-1;
- while (n--) {*d++ = *s++; }
-
- return d;
-}
-
-
-inline
-u8 * memcpy_(u8 * d, u8 const * s, size_t n) {
- if (likely(d>s+sizeof(unsigned long)))
- return memcpy_nooverlap(d,s,n);
- else while (n--) *d++ = *s++;
- return d;
-}
-
-} // end of anonymous namespace
-
-
diff --git a/gfx/graphite2/src/moz.build b/gfx/graphite2/src/moz.build
index d918f8ee9..c95c2089d 100644
--- a/gfx/graphite2/src/moz.build
+++ b/gfx/graphite2/src/moz.build
@@ -1,4 +1,4 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -23,7 +23,6 @@ else:
# This should contain all of the _SOURCES from files.mk, except *_machine.cpp
UNIFIED_SOURCES += [
- 'Bidi.cpp',
'CachedFace.cpp',
'CmapCache.cpp',
'Code.cpp',
diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h
index e0eb70de3..71485ff22 100644
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -444,6 +444,7 @@ private:
DECL_GFX_PREF(Once, "image.mem.surfacecache.size_factor", ImageMemSurfaceCacheSizeFactor, uint32_t, 64);
DECL_GFX_PREF(Live, "image.mozsamplesize.enabled", ImageMozSampleSizeEnabled, bool, false);
DECL_GFX_PREF(Once, "image.multithreaded_decoding.limit", ImageMTDecodingLimit, int32_t, -1);
+ DECL_GFX_PREF(Live, "image.webp.enabled", ImageWebPEnabled, bool, true);
DECL_GFX_PREF(Once, "layers.acceleration.disabled", LayersAccelerationDisabledDoNotUseDirectly, bool, false);
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps", LayersDrawFPS, bool, false);
diff --git a/image/DecoderFactory.cpp b/image/DecoderFactory.cpp
index 1c51d2fbc..2085fb7c4 100644
--- a/image/DecoderFactory.cpp
+++ b/image/DecoderFactory.cpp
@@ -5,6 +5,7 @@
#include "DecoderFactory.h"
+#include "gfxPrefs.h"
#include "nsMimeTypes.h"
#include "mozilla/RefPtr.h"
@@ -17,6 +18,7 @@
#include "nsBMPDecoder.h"
#include "nsICODecoder.h"
#include "nsIconDecoder.h"
+#include "nsWebPDecoder.h"
namespace mozilla {
@@ -65,8 +67,12 @@ DecoderFactory::GetDecoderType(const char* aMimeType)
// Icon
} else if (!strcmp(aMimeType, IMAGE_ICON_MS)) {
type = DecoderType::ICON;
- }
+ // WebP
+ } else if (!strcmp(aMimeType, IMAGE_WEBP) &&
+ gfxPrefs::ImageWebPEnabled()) {
+ type = DecoderType::WEBP;
+ }
return type;
}
@@ -100,6 +106,9 @@ DecoderFactory::GetDecoder(DecoderType aType,
case DecoderType::ICON:
decoder = new nsIconDecoder(aImage);
break;
+ case DecoderType::WEBP:
+ decoder = new nsWebPDecoder(aImage);
+ break;
default:
MOZ_ASSERT_UNREACHABLE("Unknown decoder type");
}
@@ -171,7 +180,8 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
return nullptr;
}
- MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG,
+ MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG ||
+ aType == DecoderType::WEBP,
"Calling CreateAnimationDecoder for non-animating DecoderType");
// Create an anonymous decoder. Interaction with the SurfaceCache and the
diff --git a/image/DecoderFactory.h b/image/DecoderFactory.h
index 107ebede6..f8cf64cc6 100644
--- a/image/DecoderFactory.h
+++ b/image/DecoderFactory.h
@@ -36,6 +36,7 @@ enum class DecoderType
BMP,
ICO,
ICON,
+ WEBP,
UNKNOWN
};
diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp
index 6e3928362..fd970e179 100644
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -931,12 +931,21 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams, BackendTy
RefPtr<gfxDrawable> svgDrawable =
new gfxCallbackDrawable(cb, aParams.size);
+ // We take an early exit without using the surface cache if
+ // x or y > maxDimension, because for vector images this can cause bad perf
+ // issues if large sizes are scaled repeatedly (a rather common scenario)
+ // that can quickly exhaust the cache.
+ int32_t maxDimension = 3000;
+
bool bypassCache = bool(aParams.flags & FLAG_BYPASS_SURFACE_CACHE) ||
// Refuse to cache animated images:
// XXX(seth): We may remove this restriction in bug 922893.
mHaveAnimations ||
// The image is too big to fit in the cache:
- !SurfaceCache::CanHold(aParams.size);
+ !SurfaceCache::CanHold(aParams.size) ||
+ // Image x or y is larger than our cache cap:
+ aParams.size.width > maxDimension ||
+ aParams.size.height > maxDimension;
if (bypassCache) {
return Show(svgDrawable, aParams);
}
diff --git a/image/build/nsImageModule.cpp b/image/build/nsImageModule.cpp
index 48d246cd3..9d52c07b6 100644
--- a/image/build/nsImageModule.cpp
+++ b/image/build/nsImageModule.cpp
@@ -82,6 +82,7 @@ static const mozilla::Module::CategoryEntry kImageCategories[] = {
{ "Gecko-Content-Viewers", IMAGE_PNG, "@mozilla.org/content/document-loader-factory;1" },
{ "Gecko-Content-Viewers", IMAGE_APNG, "@mozilla.org/content/document-loader-factory;1" },
{ "Gecko-Content-Viewers", IMAGE_X_PNG, "@mozilla.org/content/document-loader-factory;1" },
+ { "Gecko-Content-Viewers", IMAGE_WEBP, "@mozilla.org/content/document-loader-factory;1" },
{ "content-sniffing-services", "@mozilla.org/image/loader;1", "@mozilla.org/image/loader;1" },
{ nullptr }
};
diff --git a/image/decoders/moz.build b/image/decoders/moz.build
index 775c3eaa5..30c026f99 100644
--- a/image/decoders/moz.build
+++ b/image/decoders/moz.build
@@ -28,6 +28,7 @@ UNIFIED_SOURCES += [
'nsIconDecoder.cpp',
'nsJPEGDecoder.cpp',
'nsPNGDecoder.cpp',
+ 'nsWebPDecoder.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
diff --git a/image/decoders/nsWebPDecoder.cpp b/image/decoders/nsWebPDecoder.cpp
new file mode 100644
index 000000000..5da696347
--- /dev/null
+++ b/image/decoders/nsWebPDecoder.cpp
@@ -0,0 +1,467 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h" // Must appear first
+#include "nsWebPDecoder.h"
+
+#include "RasterImage.h"
+#include "SurfacePipeFactory.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace image {
+
+static LazyLogModule sWebPLog("WebPDecoder");
+
+nsWebPDecoder::nsWebPDecoder(RasterImage* aImage)
+ : Decoder(aImage)
+ , mLexer(Transition::ToUnbuffered(State::FINISHED_WEBP_DATA,
+ State::WEBP_DATA,
+ SIZE_MAX),
+ Transition::TerminateSuccess())
+ , mDecoder(nullptr)
+ , mBlend(BlendMethod::OVER)
+ , mDisposal(DisposalMethod::KEEP)
+ , mTimeout(FrameTimeout::Forever())
+ , mFormat(SurfaceFormat::B8G8R8X8)
+ , mLastRow(0)
+ , mCurrentFrame(0)
+{
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::nsWebPDecoder", this));
+}
+
+nsWebPDecoder::~nsWebPDecoder()
+{
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::~nsWebPDecoder", this));
+ WebPIDelete(mDecoder);
+}
+
+LexerResult
+nsWebPDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
+{
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::WEBP_DATA:
+ if (!HasSize()) {
+ return ReadHeader(aData, aLength);
+ }
+ return ReadPayload(aData, aLength);
+ case State::FINISHED_WEBP_DATA:
+ return FinishedData();
+ }
+ MOZ_CRASH("Unknown State");
+ });
+}
+
+nsresult
+nsWebPDecoder::CreateFrame(const nsIntRect& aFrameRect)
+{
+ MOZ_ASSERT(HasSize());
+ MOZ_ASSERT(!mDecoder);
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- frame %u, %d x %d\n",
+ this, mCurrentFrame, aFrameRect.width, aFrameRect.height));
+
+ // If this is our first frame in an animation and it doesn't cover the
+ // full frame, then we are transparent even if there is no alpha
+ if (mCurrentFrame == 0 && !aFrameRect.IsEqualEdges(FullFrame())) {
+ MOZ_ASSERT(HasAnimation());
+ PostHasTransparency();
+ }
+
+ WebPInitDecBuffer(&mBuffer);
+ mBuffer.colorspace = MODE_RGBA;
+
+ mDecoder = WebPINewDecoder(&mBuffer);
+ if (!mDecoder) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- create decoder error\n",
+ this));
+ return NS_ERROR_FAILURE;
+ }
+
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(this,
+ mCurrentFrame, Size(), OutputSize(), aFrameRect,
+ mFormat, SurfacePipeFlags());
+ if (!pipe) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- no pipe\n", this));
+ return NS_ERROR_FAILURE;
+ }
+
+ mPipe = Move(*pipe);
+ return NS_OK;
+}
+
+void
+nsWebPDecoder::EndFrame()
+{
+ MOZ_ASSERT(HasSize());
+ MOZ_ASSERT(mDecoder);
+
+ auto opacity = mFormat == SurfaceFormat::B8G8R8A8
+ ? Opacity::SOME_TRANSPARENCY : Opacity::FULLY_OPAQUE;
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::EndFrame -- frame %u, opacity %d, "
+ "disposal %d, timeout %d, blend %d\n",
+ this, mCurrentFrame, (int)opacity, (int)mDisposal,
+ mTimeout.AsEncodedValueDeprecated(), (int)mBlend));
+
+ PostFrameStop(opacity, mDisposal, mTimeout, mBlend);
+ WebPIDelete(mDecoder);
+ mDecoder = nullptr;
+ mLastRow = 0;
+ ++mCurrentFrame;
+}
+
+nsresult
+nsWebPDecoder::GetDataBuffer(const uint8_t*& aData, size_t& aLength)
+{
+ if (!mData.empty() && mData.begin() != aData) {
+ if (!mData.append(aData, aLength)) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::GetDataBuffer -- oom, append %zu on %zu\n",
+ this, aLength, mData.length()));
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ aData = mData.begin();
+ aLength = mData.length();
+ }
+ return NS_OK;
+}
+
+nsresult
+nsWebPDecoder::SaveDataBuffer(const uint8_t* aData, size_t aLength)
+{
+ if (mData.empty() && !mData.append(aData, aLength)) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::SaveDataBuffer -- oom, append %zu on %zu\n",
+ this, aLength, mData.length()));
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ return NS_OK;
+}
+
+LexerTransition<nsWebPDecoder::State>
+nsWebPDecoder::ReadHeader(const char* aData, size_t aLength)
+{
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- %zu bytes\n", this, aLength));
+
+ // XXX(aosmond): In an ideal world, we could request the lexer to do this
+ // buffering for us (and in turn the underlying SourceBuffer). That way we
+ // could avoid extra copies during the decode and just do
+ // SourceBuffer::Compact on each iteration. For a typical WebP image we
+ // can hope that we will get the full header in the first packet, but
+ // for animated images we will end up buffering the whole stream if it
+ // not already fully received and contiguous.
+ auto data = (const uint8_t*)aData;
+ size_t length = aLength;
+ if (NS_FAILED(GetDataBuffer(data, length))) {
+ return Transition::TerminateFailure();
+ }
+
+ WebPBitstreamFeatures features;
+ VP8StatusCode status = WebPGetFeatures(data, length, &features);
+ switch (status) {
+ case VP8_STATUS_OK:
+ break;
+ case VP8_STATUS_NOT_ENOUGH_DATA:
+ if (NS_FAILED(SaveDataBuffer(data, length))) {
+ return Transition::TerminateFailure();
+ }
+ return Transition::ContinueUnbuffered(State::WEBP_DATA);
+ default:
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- parse error %d\n",
+ this, status));
+ return Transition::TerminateFailure();
+ }
+
+ if (features.has_animation) {
+ // A metadata decode expects to get the correct first frame timeout which
+ // sadly is not provided by the normal WebP header parsing.
+ WebPDemuxState state;
+ WebPData fragment;
+ fragment.bytes = data;
+ fragment.size = length;
+ WebPDemuxer* demuxer = WebPDemuxPartial(&fragment, &state);
+ if (!demuxer || state == WEBP_DEMUX_PARSE_ERROR) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- demux parse error\n", this));
+ WebPDemuxDelete(demuxer);
+ return Transition::TerminateFailure();
+ }
+
+ WebPIterator iter;
+ if (!WebPDemuxGetFrame(demuxer, 1, &iter)) {
+ WebPDemuxDelete(demuxer);
+ if (state == WEBP_DEMUX_DONE) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- demux parse error\n",
+ this));
+ return Transition::TerminateFailure();
+ }
+ if (NS_FAILED(SaveDataBuffer(data, length))) {
+ return Transition::TerminateFailure();
+ }
+ return Transition::ContinueUnbuffered(State::WEBP_DATA);
+ }
+
+ PostIsAnimated(FrameTimeout::FromRawMilliseconds(iter.duration));
+ WebPDemuxReleaseIterator(&iter);
+ WebPDemuxDelete(demuxer);
+ }
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- %d x %d, alpha %d, "
+ "animation %d, format %d, metadata decode %d, first frame decode %d\n",
+ this, features.width, features.height, features.has_alpha,
+ features.has_animation, features.format, IsMetadataDecode(),
+ IsFirstFrameDecode()));
+
+ PostSize(features.width, features.height);
+ if (features.has_alpha) {
+ mFormat = SurfaceFormat::B8G8R8A8;
+ PostHasTransparency();
+ }
+
+ if (IsMetadataDecode()) {
+ return Transition::TerminateSuccess();
+ }
+
+ auto transition = ReadPayload((const char*)data, length);
+ if (!features.has_animation) {
+ mData.clearAndFree();
+ }
+ return transition;
+}
+
+LexerTransition<nsWebPDecoder::State>
+nsWebPDecoder::ReadPayload(const char* aData, size_t aLength)
+{
+ auto data = (const uint8_t*)aData;
+ if (!HasAnimation()) {
+ auto rv = ReadSingle(data, aLength, true, FullFrame());
+ if (rv.NextStateIsTerminal() &&
+ rv.NextStateAsTerminal() == TerminalState::SUCCESS) {
+ PostDecodeDone();
+ }
+ return rv;
+ }
+ return ReadMultiple(data, aLength);
+}
+
+LexerTransition<nsWebPDecoder::State>
+nsWebPDecoder::ReadSingle(const uint8_t* aData, size_t aLength, bool aAppend, const IntRect& aFrameRect)
+{
+ MOZ_ASSERT(!IsMetadataDecode());
+ MOZ_ASSERT(aData);
+ MOZ_ASSERT(aLength > 0);
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- %zu bytes\n", this, aLength));
+
+ if (!mDecoder && NS_FAILED(CreateFrame(aFrameRect))) {
+ return Transition::TerminateFailure();
+ }
+
+ // XXX(aosmond): The demux API can be used for single images according to the
+ // documentation. If WebPIAppend is not any more efficient in its buffering
+ // than what we do for animated images, we should just combine the use cases.
+ bool complete;
+ VP8StatusCode status;
+ if (aAppend) {
+ status = WebPIAppend(mDecoder, aData, aLength);
+ } else {
+ status = WebPIUpdate(mDecoder, aData, aLength);
+ }
+ switch (status) {
+ case VP8_STATUS_OK:
+ complete = true;
+ break;
+ case VP8_STATUS_SUSPENDED:
+ complete = false;
+ break;
+ default:
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- append error %d\n",
+ this, status));
+ return Transition::TerminateFailure();
+ }
+
+ int lastRow = -1;
+ int width = 0;
+ int height = 0;
+ int stride = 0;
+ const uint8_t* rowStart = WebPIDecGetRGB(mDecoder, &lastRow, &width, &height, &stride);
+ if (!rowStart || lastRow == -1) {
+ return Transition::ContinueUnbuffered(State::WEBP_DATA);
+ }
+
+ if (width <= 0 || height <= 0 || stride <= 0) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- bad (w,h,s) = (%d, %d, %d)\n",
+ this, width, height, stride));
+ return Transition::TerminateFailure();
+ }
+
+ for (int row = mLastRow; row < lastRow; row++) {
+ const uint8_t* src = rowStart + row * stride;
+ auto result = mPipe.WritePixelsToRow<uint32_t>([&]() -> NextPixel<uint32_t> {
+ MOZ_ASSERT(mFormat == SurfaceFormat::B8G8R8A8 || src[3] == 0xFF);
+ const uint32_t pixel = gfxPackedPixel(src[3], src[0], src[1], src[2]);
+ src += 4;
+ return AsVariant(pixel);
+ });
+ MOZ_ASSERT(result != WriteState::FAILURE);
+ MOZ_ASSERT_IF(result == WriteState::FINISHED, complete && row == lastRow - 1);
+
+ if (result == WriteState::FAILURE) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- write pixels error\n",
+ this));
+ return Transition::TerminateFailure();
+ }
+ }
+
+ if (mLastRow != lastRow) {
+ mLastRow = lastRow;
+
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (invalidRect) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+ }
+
+ if (!complete) {
+ return Transition::ContinueUnbuffered(State::WEBP_DATA);
+ }
+
+ EndFrame();
+ return Transition::TerminateSuccess();
+}
+
+LexerTransition<nsWebPDecoder::State>
+nsWebPDecoder::ReadMultiple(const uint8_t* aData, size_t aLength)
+{
+ MOZ_ASSERT(!IsMetadataDecode());
+ MOZ_ASSERT(aData);
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadMultiple -- %zu bytes\n", this, aLength));
+
+ auto data = aData;
+ size_t length = aLength;
+ if (NS_FAILED(GetDataBuffer(data, length))) {
+ return Transition::TerminateFailure();
+ }
+
+ WebPDemuxState state;
+ WebPData fragment;
+ fragment.bytes = data;
+ fragment.size = length;
+ WebPDemuxer* demuxer = WebPDemuxPartial(&fragment, &state);
+ if (!demuxer) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadMultiple -- create demuxer error\n",
+ this));
+ return Transition::TerminateFailure();
+ }
+
+ if (state == WEBP_DEMUX_PARSE_ERROR) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadMultiple -- demuxer parse error\n",
+ this));
+ WebPDemuxDelete(demuxer);
+ return Transition::TerminateFailure();
+ }
+
+ bool complete = false;
+ WebPIterator iter;
+ auto rv = Transition::ContinueUnbuffered(State::WEBP_DATA);
+ if (WebPDemuxGetFrame(demuxer, mCurrentFrame + 1, &iter)) {
+ switch (iter.blend_method) {
+ case WEBP_MUX_BLEND:
+ mBlend = BlendMethod::OVER;
+ break;
+ case WEBP_MUX_NO_BLEND:
+ mBlend = BlendMethod::SOURCE;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unhandled blend method");
+ break;
+ }
+
+ switch (iter.dispose_method) {
+ case WEBP_MUX_DISPOSE_NONE:
+ mDisposal = DisposalMethod::KEEP;
+ break;
+ case WEBP_MUX_DISPOSE_BACKGROUND:
+ mDisposal = DisposalMethod::CLEAR;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unhandled dispose method");
+ break;
+ }
+
+ mFormat = iter.has_alpha ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8;
+ mTimeout = FrameTimeout::FromRawMilliseconds(iter.duration);
+ nsIntRect frameRect(iter.x_offset, iter.y_offset, iter.width, iter.height);
+
+ rv = ReadSingle(iter.fragment.bytes, iter.fragment.size, false, frameRect);
+ complete = state == WEBP_DEMUX_DONE && !WebPDemuxNextFrame(&iter);
+ WebPDemuxReleaseIterator(&iter);
+ }
+
+ if (rv.NextStateIsTerminal()) {
+ if (rv.NextStateAsTerminal() == TerminalState::SUCCESS) {
+ // If we extracted one frame, and it is not the last, we need to yield to
+ // the lexer to allow the upper layers to acknowledge the frame.
+ if (!complete && !IsFirstFrameDecode()) {
+ // The resume point is determined by whether or not we had to buffer.
+ // If we have yet to buffer, we want to resume at the same point,
+ // otherwise our internal buffer has everything we need and we want
+ // to resume having consumed all of the current fragment.
+ rv = Transition::ContinueUnbufferedAfterYield(State::WEBP_DATA,
+ mData.empty() ? 0 : aLength);
+ } else {
+ uint32_t loopCount = WebPDemuxGetI(demuxer, WEBP_FF_LOOP_COUNT);
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadMultiple -- loop count %u\n",
+ this, loopCount));
+ PostDecodeDone(loopCount - 1);
+ }
+ }
+ } else if (NS_FAILED(SaveDataBuffer(data, length))) {
+ rv = Transition::TerminateFailure();
+ }
+
+ WebPDemuxDelete(demuxer);
+ return rv;
+}
+
+LexerTransition<nsWebPDecoder::State>
+nsWebPDecoder::FinishedData()
+{
+ // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read
+ // all that data something is really wrong.
+ MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
+ return Transition::TerminateFailure();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsWebPDecoder.h b/image/decoders/nsWebPDecoder.h
new file mode 100644
index 000000000..5b3951cfc
--- /dev/null
+++ b/image/decoders/nsWebPDecoder.h
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsWebPDecoder_h
+#define mozilla_image_decoders_nsWebPDecoder_h
+
+#include "Decoder.h"
+#include "webp/demux.h"
+#include "StreamingLexer.h"
+#include "SurfacePipe.h"
+
+namespace mozilla {
+namespace image {
+class RasterImage;
+
+class nsWebPDecoder : public Decoder
+{
+public:
+ virtual ~nsWebPDecoder();
+
+protected:
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+
+private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsWebPDecoder(RasterImage* aImage);
+
+ enum class State
+ {
+ WEBP_DATA,
+ FINISHED_WEBP_DATA
+ };
+
+ LexerTransition<State> ReadHeader(const char* aData, size_t aLength);
+ LexerTransition<State> ReadPayload(const char* aData, size_t aLength);
+ LexerTransition<State> FinishedData();
+
+ nsresult CreateFrame(const nsIntRect& aFrameRect);
+ void EndFrame();
+
+ nsresult GetDataBuffer(const uint8_t*& aData, size_t& aLength);
+ nsresult SaveDataBuffer(const uint8_t* aData, size_t aLength);
+
+ LexerTransition<State> ReadSingle(const uint8_t* aData, size_t aLength,
+ bool aAppend, const IntRect& aFrameRect);
+
+ LexerTransition<State> ReadMultiple(const uint8_t* aData, size_t aLength);
+
+ StreamingLexer<State> mLexer;
+
+ /// The SurfacePipe used to write to the output surface.
+ SurfacePipe mPipe;
+
+ /// The buffer used to accumulate data until the complete WebP header is received.
+ Vector<uint8_t> mData;
+
+ /// The libwebp output buffer descriptor pointing to the decoded data.
+ WebPDecBuffer mBuffer;
+
+ /// The libwebp incremental decoder descriptor, wraps mBuffer.
+ WebPIDecoder* mDecoder;
+
+ /// Blend method for the current frame.
+ BlendMethod mBlend;
+
+ /// Disposal method for the current frame.
+ DisposalMethod mDisposal;
+
+ /// Frame timeout for the current frame;
+ FrameTimeout mTimeout;
+
+ /// Surface format for the current frame.
+ gfx::SurfaceFormat mFormat;
+
+ /// The last row of decoded pixels written to mPipe.
+ int mLastRow;
+
+ /// Number of decoded frames.
+ uint32_t mCurrentFrame;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsWebPDecoder_h
diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp
index 3545c5be2..5e5ee7829 100644
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -2558,6 +2558,11 @@ imgLoader::GetMimeTypeFromContent(const char* aContents,
!memcmp(aContents, "\000\000\002\000", 4))) {
aContentType.AssignLiteral(IMAGE_ICO);
+ // WebPs always begin with RIFF, a 32-bit length, and WEBP.
+ } else if (aLength >= 12 && !memcmp(aContents, "RIFF", 4) &&
+ !memcmp(aContents + 8, "WEBP", 4)) {
+ aContentType.AssignLiteral(IMAGE_WEBP);
+
} else {
/* none of the above? I give up */
return NS_ERROR_NOT_AVAILABLE;
diff --git a/image/test/gtest/TestLoader.cpp b/image/test/gtest/TestLoader.cpp
new file mode 100644
index 000000000..5551f3f05
--- /dev/null
+++ b/image/test/gtest/TestLoader.cpp
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "imgLoader.h"
+#include "nsMimeTypes.h"
+#include "nsString.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+static void
+CheckMimeType(const char* aContents, size_t aLength, const char* aExpected)
+{
+ nsAutoCString detected;
+ nsresult rv = imgLoader::GetMimeTypeFromContent(aContents, aLength, detected);
+ if (aExpected) {
+ ASSERT_TRUE(NS_SUCCEEDED(rv));
+ EXPECT_TRUE(detected.EqualsASCII(aExpected));
+ } else {
+ ASSERT_TRUE(NS_FAILED(rv));
+ EXPECT_TRUE(detected.IsEmpty());
+ }
+}
+
+class ImageLoader : public ::testing::Test
+{
+protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageLoader, DetectGIF)
+{
+ const char buffer[] = "GIF87a";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_GIF);
+}
+
+TEST_F(ImageLoader, DetectPNG)
+{
+ const char buffer[] = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_PNG);
+}
+
+TEST_F(ImageLoader, DetectJPEG)
+{
+ const char buffer[] = "\xFF\xD8\xFF";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_JPEG);
+}
+
+TEST_F(ImageLoader, DetectART)
+{
+ const char buffer[] = "\x4A\x47\xFF\xFF\x00";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_ART);
+}
+
+TEST_F(ImageLoader, DetectBMP)
+{
+ const char buffer[] = "BM";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_BMP);
+}
+
+TEST_F(ImageLoader, DetectICO)
+{
+ const char buffer[] = "\x00\x00\x01\x00";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_ICO);
+}
+
+TEST_F(ImageLoader, DetectWebP)
+{
+ const char buffer[] = "RIFF\xFF\xFF\xFF\xFFWEBPVP8L";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_WEBP);
+}
+
+TEST_F(ImageLoader, DetectNone)
+{
+ const char buffer[] = "abcdefghijklmnop";
+ CheckMimeType(buffer, sizeof(buffer), nullptr);
+}
+
diff --git a/image/test/gtest/moz.build b/image/test/gtest/moz.build
index 5cf6d5116..3548eaecc 100644
--- a/image/test/gtest/moz.build
+++ b/image/test/gtest/moz.build
@@ -13,6 +13,7 @@ UNIFIED_SOURCES = [
'TestDecoders.cpp',
'TestDecodeToSurface.cpp',
'TestDeinterlacingFilter.cpp',
+ 'TestLoader.cpp',
'TestMetadata.cpp',
'TestRemoveFrameRectFilter.cpp',
'TestSourceBuffer.cpp',
diff --git a/ipc/testshell/XPCShellEnvironment.cpp b/ipc/testshell/XPCShellEnvironment.cpp
index a6979ccae..455a14610 100644
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -231,21 +231,6 @@ GC(JSContext *cx,
return true;
}
-#ifdef JS_GC_ZEAL
-static bool
-GCZeal(JSContext *cx, unsigned argc, JS::Value *vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- uint32_t zeal;
- if (!ToUint32(cx, args.get(0), &zeal))
- return false;
-
- JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ);
- return true;
-}
-#endif
-
const JSFunctionSpec gGlobalFunctions[] =
{
JS_FS("print", Print, 0,0),
@@ -255,9 +240,6 @@ const JSFunctionSpec gGlobalFunctions[] =
JS_FS("dumpXPC", DumpXPC, 1,0),
JS_FS("dump", Dump, 1,0),
JS_FS("gc", GC, 0,0),
- #ifdef JS_GC_ZEAL
- JS_FS("gczeal", GCZeal, 1,0),
- #endif
JS_FS_END
};
diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp
index 5bc69a346..acf449b7e 100644
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -188,14 +188,6 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
if (!JS_SetProperty(cx, info, "tsan", value))
return false;
-#ifdef JS_GC_ZEAL
- value = BooleanValue(true);
-#else
- value = BooleanValue(false);
-#endif
- if (!JS_SetProperty(cx, info, "has-gczeal", value))
- return false;
-
#ifdef JS_MORE_DETERMINISTIC
value = BooleanValue(true);
#else
@@ -731,171 +723,6 @@ GCPreserveCode(JSContext* cx, unsigned argc, Value* vp)
return true;
}
-#ifdef JS_GC_ZEAL
-static bool
-GCZeal(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- if (args.length() > 2) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Too many arguments");
- return false;
- }
-
- uint32_t zeal;
- if (!ToUint32(cx, args.get(0), &zeal))
- return false;
-
- if (zeal > uint32_t(gc::ZealMode::Limit)) {
- JS_ReportErrorASCII(cx, "gczeal argument out of range");
- return false;
- }
-
- uint32_t frequency = JS_DEFAULT_ZEAL_FREQ;
- if (args.length() >= 2) {
- if (!ToUint32(cx, args.get(1), &frequency))
- return false;
- }
-
- JS_SetGCZeal(cx, (uint8_t)zeal, frequency);
- args.rval().setUndefined();
- return true;
-}
-
-static bool
-ScheduleGC(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- if (args.length() > 1) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Too many arguments");
- return false;
- }
-
- if (args.length() == 0) {
- /* Fetch next zeal trigger only. */
- } else if (args[0].isInt32()) {
- /* Schedule a GC to happen after |arg| allocations. */
- JS_ScheduleGC(cx, args[0].toInt32());
- } else if (args[0].isObject()) {
- /* Ensure that |zone| is collected during the next GC. */
- Zone* zone = UncheckedUnwrap(&args[0].toObject())->zone();
- PrepareZoneForGC(zone);
- } else if (args[0].isString()) {
- /* This allows us to schedule the atoms zone for GC. */
- Zone* zone = args[0].toString()->zoneFromAnyThread();
- if (!CurrentThreadCanAccessZone(zone)) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Specified zone not accessible for GC");
- return false;
- }
- PrepareZoneForGC(zone);
- } else {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Bad argument - expecting integer, object or string");
- return false;
- }
-
- uint32_t zealBits;
- uint32_t freq;
- uint32_t next;
- JS_GetGCZealBits(cx, &zealBits, &freq, &next);
- args.rval().setInt32(next);
- return true;
-}
-
-static bool
-SelectForGC(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- /*
- * The selectedForMarking set is intended to be manually marked at slice
- * start to detect missing pre-barriers. It is invalid for nursery things
- * to be in the set, so evict the nursery before adding items.
- */
- JSRuntime* rt = cx->runtime();
- rt->gc.evictNursery();
-
- for (unsigned i = 0; i < args.length(); i++) {
- if (args[i].isObject()) {
- if (!rt->gc.selectForMarking(&args[i].toObject()))
- return false;
- }
- }
-
- args.rval().setUndefined();
- return true;
-}
-
-static bool
-VerifyPreBarriers(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- if (args.length() > 0) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Too many arguments");
- return false;
- }
-
- gc::VerifyBarriers(cx->runtime(), gc::PreBarrierVerifier);
- args.rval().setUndefined();
- return true;
-}
-
-static bool
-VerifyPostBarriers(JSContext* cx, unsigned argc, Value* vp)
-{
- // This is a no-op since the post barrier verifier was removed.
- CallArgs args = CallArgsFromVp(argc, vp);
- if (args.length()) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Too many arguments");
- return false;
- }
- args.rval().setUndefined();
- return true;
-}
-
-static bool
-GCState(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- if (args.length() != 0) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Too many arguments");
- return false;
- }
-
- const char* state = StateName(cx->runtime()->gc.state());
- JSString* str = JS_NewStringCopyZ(cx, state);
- if (!str)
- return false;
- args.rval().setString(str);
- return true;
-}
-
-static bool
-DeterministicGC(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- if (args.length() != 1) {
- RootedObject callee(cx, &args.callee());
- ReportUsageErrorASCII(cx, callee, "Wrong number of arguments");
- return false;
- }
-
- cx->runtime()->gc.setDeterministic(ToBoolean(args[0]));
- args.rval().setUndefined();
- return true;
-}
-#endif /* JS_GC_ZEAL */
-
static bool
StartGC(JSContext* cx, unsigned argc, Value* vp)
{
@@ -1437,8 +1264,6 @@ OOMTest(JSContext* cx, unsigned argc, Value* vp)
MOZ_ASSERT(!cx->isExceptionPending());
rt->hadOutOfMemory = false;
- JS_SetGCZeal(cx, 0, JS_DEFAULT_ZEAL_FREQ);
-
for (unsigned thread = threadStart; thread < threadEnd; thread++) {
if (verbose)
fprintf(stderr, "thread %d\n", thread);
@@ -4387,39 +4212,6 @@ JS_FN_HELP("rejectPromise", RejectPromise, 2, 0,
"gcPreserveCode()",
" Preserve JIT code during garbage collections."),
-#ifdef JS_GC_ZEAL
- JS_FN_HELP("gczeal", GCZeal, 2, 0,
-"gczeal(level, [N])",
-gc::ZealModeHelpText),
-
- JS_FN_HELP("schedulegc", ScheduleGC, 1, 0,
-"schedulegc([num | obj | string])",
-" If num is given, schedule a GC after num allocations.\n"
-" If obj is given, schedule a GC of obj's zone.\n"
-" If string is given, schedule a GC of the string's zone if possible.\n"
-" Returns the number of allocations before the next trigger."),
-
- JS_FN_HELP("selectforgc", SelectForGC, 0, 0,
-"selectforgc(obj1, obj2, ...)",
-" Schedule the given objects to be marked in the next GC slice."),
-
- JS_FN_HELP("verifyprebarriers", VerifyPreBarriers, 0, 0,
-"verifyprebarriers()",
-" Start or end a run of the pre-write barrier verifier."),
-
- JS_FN_HELP("verifypostbarriers", VerifyPostBarriers, 0, 0,
-"verifypostbarriers()",
-" Does nothing (the post-write barrier verifier has been remove)."),
-
- JS_FN_HELP("gcstate", GCState, 0, 0,
-"gcstate()",
-" Report the global GC state."),
-
- JS_FN_HELP("deterministicgc", DeterministicGC, 1, 0,
-"deterministicgc(true|false)",
-" If true, only allow determinstic GCs to run."),
-#endif
-
JS_FN_HELP("startgc", StartGC, 1, 0,
"startgc([n [, 'shrinking']])",
" Start an incremental GC and run a slice that processes about n objects.\n"
diff --git a/js/src/devtools/automation/variants/compacting b/js/src/devtools/automation/variants/compacting
index cd1891bfe..2ffade6ac 100644
--- a/js/src/devtools/automation/variants/compacting
+++ b/js/src/devtools/automation/variants/compacting
@@ -3,7 +3,6 @@
"optimize": true,
"debug": true,
"env": {
- "JS_GC_ZEAL": "Compact",
"JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt",
"JSTESTS_EXTRA_ARGS": "--exclude-file={DIR}/cgc-jstests-slow.txt"
},
diff --git a/js/src/devtools/automation/variants/rootanalysis b/js/src/devtools/automation/variants/rootanalysis
index c5ed4dfcd..508e1e2db 100644
--- a/js/src/devtools/automation/variants/rootanalysis
+++ b/js/src/devtools/automation/variants/rootanalysis
@@ -3,7 +3,6 @@
"optimize": true,
"debug": true,
"env": {
- "JS_GC_ZEAL": "GenerationalGC",
"JSTESTS_EXTRA_ARGS": "--jitflags=debug"
}
}
diff --git a/js/src/gc/Allocator.cpp b/js/src/gc/Allocator.cpp
index f7dc50d02..3994d5a5b 100644
--- a/js/src/gc/Allocator.cpp
+++ b/js/src/gc/Allocator.cpp
@@ -190,7 +190,7 @@ GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind)
return false;
}
-#if defined(JS_GC_ZEAL) || defined(DEBUG)
+#if defined(DEBUG)
MOZ_ASSERT_IF(cx->compartment()->isAtomsCompartment(),
kind == AllocKind::ATOM ||
kind == AllocKind::FAT_INLINE_ATOM ||
@@ -223,11 +223,6 @@ GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind)
bool
GCRuntime::gcIfNeededPerAllocation(JSContext* cx)
{
-#ifdef JS_GC_ZEAL
- if (needZealousGC())
- runDebugGC();
-#endif
-
// Invoking the interrupt callback can fail and we can't usefully
// handle that here. Just check in case we need to collect instead.
if (rt->hasPendingInterrupt())
diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h
index 722539e1c..4919b87a5 100644
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.h
@@ -61,51 +61,6 @@ class MOZ_RAII AutoPrepareForTracing
AbortReason
IsIncrementalGCUnsafe(JSRuntime* rt);
-#ifdef JS_GC_ZEAL
-
-class MOZ_RAII AutoStopVerifyingBarriers
-{
- GCRuntime* gc;
- bool restartPreVerifier;
-
- public:
- AutoStopVerifyingBarriers(JSRuntime* rt, bool isShutdown)
- : gc(&rt->gc)
- {
- if (gc->isVerifyPreBarriersEnabled()) {
- gc->endVerifyPreBarriers();
- restartPreVerifier = !isShutdown;
- } else {
- restartPreVerifier = false;
- }
- }
-
- ~AutoStopVerifyingBarriers() {
- // Nasty special case: verification runs a minor GC, which *may* nest
- // inside of an outer minor GC. This is not allowed by the
- // gc::Statistics phase tree. So we pause the "real" GC, if in fact one
- // is in progress.
- gcstats::Phase outer = gc->stats.currentPhase();
- if (outer != gcstats::PHASE_NONE)
- gc->stats.endPhase(outer);
- MOZ_ASSERT((gc->stats.currentPhase() == gcstats::PHASE_NONE) ||
- (gc->stats.currentPhase() == gcstats::PHASE_GC_BEGIN) ||
- (gc->stats.currentPhase() == gcstats::PHASE_GC_END));
-
- if (restartPreVerifier)
- gc->startVerifyPreBarriers();
-
- if (outer != gcstats::PHASE_NONE)
- gc->stats.beginPhase(outer);
- }
-};
-#else
-struct MOZ_RAII AutoStopVerifyingBarriers
-{
- AutoStopVerifyingBarriers(JSRuntime*, bool) {}
-};
-#endif /* JS_GC_ZEAL */
-
#ifdef JSGC_HASH_TABLE_CHECKS
void CheckHashTablesAfterMovingGC(JSRuntime* rt);
void CheckHeapAfterGC(JSRuntime* rt);
diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h
index 8c9322849..19737c9ee 100644
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -600,11 +600,6 @@ class GCRuntime
void finishRoots();
void finish();
- inline bool hasZealMode(ZealMode mode);
- inline void clearZealMode(ZealMode mode);
- inline bool upcomingZealousGC();
- inline bool needZealousGC();
-
MOZ_MUST_USE bool addRoot(Value* vp, const char* name);
void removeRoot(Value* vp);
void setMarkStackLimit(size_t limit, AutoLockGC& lock);
@@ -638,7 +633,6 @@ class GCRuntime
MOZ_RELEASE_ASSERT(triggerGC(JS::gcreason::ALLOC_TRIGGER));
}
- void runDebugGC();
inline void poke();
enum TraceOrMarkRuntime {
@@ -653,19 +647,6 @@ class GCRuntime
void onOutOfMallocMemory();
void onOutOfMallocMemory(const AutoLockGC& lock);
-#ifdef JS_GC_ZEAL
- const void* addressOfZealModeBits() { return &zealModeBits; }
- void getZealBits(uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled);
- void setZeal(uint8_t zeal, uint32_t frequency);
- bool parseAndSetZeal(const char* str);
- void setNextScheduled(uint32_t count);
- void verifyPreBarriers();
- void maybeVerifyPreBarriers(bool always);
- bool selectForMarking(JSObject* object);
- void clearSelectedForMarking();
- void setDeterministic(bool enable);
-#endif
-
size_t maxMallocBytesAllocated() { return maxMallocBytes; }
uint64_t nextCellUniqueId() {
@@ -851,15 +832,6 @@ class GCRuntime
AutoMaybeStartBackgroundAllocation& maybeStartBGAlloc);
void recycleChunk(Chunk* chunk, const AutoLockGC& lock);
-#ifdef JS_GC_ZEAL
- void startVerifyPreBarriers();
- void endVerifyPreBarriers();
- void finishVerifier();
- bool isVerifyPreBarriersEnabled() const { return !!verifyPreData; }
-#else
- bool isVerifyPreBarriersEnabled() const { return false; }
-#endif
-
// Free certain LifoAlloc blocks when it is safe to do so.
void freeUnusedLifoBlocksAfterSweeping(LifoAlloc* lifo);
void freeAllLifoBlocksAfterSweeping(LifoAlloc* lifo);
@@ -948,7 +920,6 @@ class GCRuntime
void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason,
AutoLockForExclusiveAccess& lock);
- void pushZealSelectedObjects();
void purgeRuntime(AutoLockForExclusiveAccess& lock);
MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, AutoLockForExclusiveAccess& lock);
bool shouldPreserveJITCode(JSCompartment* comp, int64_t currentTime,
@@ -1004,10 +975,6 @@ class GCRuntime
void releaseRelocatedArenasWithoutUnlocking(Arena* arenaList, const AutoLockGC& lock);
void finishCollection(JS::gcreason::Reason reason);
- void computeNonIncrementalMarkingForValidation(AutoLockForExclusiveAccess& lock);
- void validateIncrementalMarking();
- void finishMarkingValidation();
-
#ifdef DEBUG
void checkForCompartmentMismatches();
#endif
@@ -1219,10 +1186,6 @@ class GCRuntime
ZoneList zonesToMaybeCompact;
Arena* relocatedArenasToRelease;
-#ifdef JS_GC_ZEAL
- MarkingValidator* markingValidator;
-#endif
-
/*
* Indicates that a GC slice has taken place in the middle of an animation
* frame, rather than at the beginning. In this case, the next slice will be
@@ -1274,40 +1237,6 @@ class GCRuntime
bool poked;
- /*
- * These options control the zealousness of the GC. At every allocation,
- * nextScheduled is decremented. When it reaches zero we do a full GC.
- *
- * At this point, if zeal_ is one of the types that trigger periodic
- * collection, then nextScheduled is reset to the value of zealFrequency.
- * Otherwise, no additional GCs take place.
- *
- * You can control these values in several ways:
- * - Set the JS_GC_ZEAL environment variable
- * - Call gczeal() or schedulegc() from inside shell-executed JS code
- * (see the help for details)
- *
- * If gcZeal_ == 1 then we perform GCs in select places (during MaybeGC and
- * whenever a GC poke happens). This option is mainly useful to embedders.
- *
- * We use zeal_ == 4 to enable write barrier verification. See the comment
- * in jsgc.cpp for more information about this.
- *
- * zeal_ values from 8 to 10 periodically run different types of
- * incremental GC.
- *
- * zeal_ value 14 performs periodic shrinking collections.
- */
-#ifdef JS_GC_ZEAL
- uint32_t zealModeBits;
- int zealFrequency;
- int nextScheduled;
- bool deterministicOnly;
- int incrementalLimit;
-
- Vector<JSObject*, 0, SystemAllocPolicy> selectedForMarking;
-#endif
-
bool fullCompartmentChecks;
Callback<JSGCCallback> gcCallback;
@@ -1415,51 +1344,6 @@ class MOZ_RAII AutoMaybeStartBackgroundAllocation
}
};
-#ifdef JS_GC_ZEAL
-
-inline bool
-GCRuntime::hasZealMode(ZealMode mode)
-{
- static_assert(size_t(ZealMode::Limit) < sizeof(zealModeBits) * 8,
- "Zeal modes must fit in zealModeBits");
- return zealModeBits & (1 << uint32_t(mode));
-}
-
-inline void
-GCRuntime::clearZealMode(ZealMode mode)
-{
- zealModeBits &= ~(1 << uint32_t(mode));
- MOZ_ASSERT(!hasZealMode(mode));
-}
-
-inline bool
-GCRuntime::upcomingZealousGC() {
- return nextScheduled == 1;
-}
-
-inline bool
-GCRuntime::needZealousGC() {
- if (nextScheduled > 0 && --nextScheduled == 0) {
- if (hasZealMode(ZealMode::Alloc) ||
- hasZealMode(ZealMode::GenerationalGC) ||
- hasZealMode(ZealMode::IncrementalRootsThenFinish) ||
- hasZealMode(ZealMode::IncrementalMarkAllThenFinish) ||
- hasZealMode(ZealMode::IncrementalMultipleSlices) ||
- hasZealMode(ZealMode::Compact))
- {
- nextScheduled = zealFrequency;
- }
- return true;
- }
- return false;
-}
-#else
-inline bool GCRuntime::hasZealMode(ZealMode mode) { return false; }
-inline void GCRuntime::clearZealMode(ZealMode mode) { }
-inline bool GCRuntime::upcomingZealousGC() { return false; }
-inline bool GCRuntime::needZealousGC() { return false; }
-#endif
-
} /* namespace gc */
} /* namespace js */
diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h
index 2a9390e91..697803380 100644
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -1322,22 +1322,6 @@ TenuredCell::writeBarrierPre(TenuredCell* thing)
if (!thing)
return;
-#ifdef JS_GC_ZEAL
- // When verifying pre barriers we need to switch on all barriers, even
- // those on the Atoms Zone. Normally, we never enter a parse task when
- // collecting in the atoms zone, so will filter out atoms below.
- // Unfortuantely, If we try that when verifying pre-barriers, we'd never be
- // able to handle OMT parse tasks at all as we switch on the verifier any
- // time we're not doing GC. This would cause us to deadlock, as OMT parsing
- // is meant to resume after GC work completes. Instead we filter out any
- // OMT barriers that reach us and assert that they would normally not be
- // possible.
- if (!CurrentThreadCanAccessRuntime(thing->runtimeFromAnyThread())) {
- AssertSafeToSkipBarrier(thing);
- return;
- }
-#endif
-
JS::shadow::Zone* shadowZone = thing->shadowZoneFromAnyThread();
if (shadowZone->needsIncrementalBarrier()) {
MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone));
diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp
index 2c402fe0b..bce2b74aa 100644
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -74,14 +74,6 @@ struct js::Nursery::SweepAction
#endif
};
-#ifdef JS_GC_ZEAL
-struct js::Nursery::Canary
-{
- uintptr_t magicValue;
- Canary* next;
-};
-#endif
-
inline void
js::Nursery::NurseryChunk::poisonAndInit(JSRuntime* rt, uint8_t poison)
{
@@ -124,9 +116,6 @@ js::Nursery::Nursery(JSRuntime* rt)
, minorGcCount_(0)
, freeMallocedBuffersTask(nullptr)
, sweepActions_(nullptr)
-#ifdef JS_GC_ZEAL
- , lastCanary_(nullptr)
-#endif
{}
bool
@@ -199,7 +188,6 @@ void
js::Nursery::enable()
{
MOZ_ASSERT(isEmpty());
- MOZ_ASSERT(!runtime()->gc.isVerifyPreBarriersEnabled());
if (isEnabled())
return;
@@ -209,10 +197,6 @@ js::Nursery::enable()
setCurrentChunk(0);
setStartPosition();
-#ifdef JS_GC_ZEAL
- if (runtime()->hasZealMode(ZealMode::GenerationalGC))
- enterZealMode();
-#endif
MOZ_ALWAYS_TRUE(runtime()->gc.storeBuffer.enable());
return;
@@ -235,31 +219,11 @@ js::Nursery::isEmpty() const
MOZ_ASSERT(runtime_);
if (!isEnabled())
return true;
-
- if (!runtime_->hasZealMode(ZealMode::GenerationalGC)) {
- MOZ_ASSERT(currentStartChunk_ == 0);
- MOZ_ASSERT(currentStartPosition_ == chunk(0).start());
- }
+ MOZ_ASSERT(currentStartChunk_ == 0);
+ MOZ_ASSERT(currentStartPosition_ == chunk(0).start());
return position() == currentStartPosition_;
}
-#ifdef JS_GC_ZEAL
-void
-js::Nursery::enterZealMode() {
- if (isEnabled())
- updateNumChunks(maxNurseryChunks_);
-}
-
-void
-js::Nursery::leaveZealMode() {
- if (isEnabled()) {
- MOZ_ASSERT(isEmpty());
- setCurrentChunk(0);
- setStartPosition();
- }
-}
-#endif // JS_GC_ZEAL
-
JSObject*
js::Nursery::allocateObject(JSContext* cx, size_t size, size_t numDynamic, const js::Class* clasp)
{
@@ -305,12 +269,6 @@ js::Nursery::allocate(size_t size)
MOZ_ASSERT(position() % gc::CellSize == 0);
MOZ_ASSERT(size % gc::CellSize == 0);
-#ifdef JS_GC_ZEAL
- static const size_t CanarySize = (sizeof(Nursery::Canary) + CellSize - 1) & ~CellMask;
- if (runtime()->gc.hasZealMode(ZealMode::CheckNursery))
- size += CanarySize;
-#endif
-
if (currentEnd() < position() + size) {
if (currentChunk_ + 1 == numChunks())
return nullptr;
@@ -322,19 +280,6 @@ js::Nursery::allocate(size_t size)
JS_EXTRA_POISON(thing, JS_ALLOCATED_NURSERY_PATTERN, size);
-#ifdef JS_GC_ZEAL
- if (runtime()->gc.hasZealMode(ZealMode::CheckNursery)) {
- auto canary = reinterpret_cast<Canary*>(position() - CanarySize);
- canary->magicValue = CanaryMagicValue;
- canary->next = nullptr;
- if (lastCanary_) {
- MOZ_ASSERT(!lastCanary_->next);
- lastCanary_->next = canary;
- }
- lastCanary_ = canary;
- }
-#endif
-
MemProfiler::SampleNursery(reinterpret_cast<void*>(thing), size);
return thing;
}
@@ -561,14 +506,6 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason)
rt->gc.incMinorGcNumber();
-#ifdef JS_GC_ZEAL
- if (rt->gc.hasZealMode(ZealMode::CheckNursery)) {
- for (auto canary = lastCanary_; canary; canary = canary->next)
- MOZ_ASSERT(canary->magicValue == CanaryMagicValue);
- }
- lastCanary_ = nullptr;
-#endif
-
rt->gc.stats.beginNurseryCollection(reason);
TraceMinorGCStart();
@@ -659,7 +596,6 @@ js::Nursery::doCollection(JSRuntime* rt, JS::gcreason::Reason reason,
{
AutoTraceSession session(rt, JS::HeapState::MinorCollecting);
AutoSetThreadIsPerformingGC performingGC;
- AutoStopVerifyingBarriers av(rt, false);
AutoDisableProxyCheck disableStrictProxyChecking(rt);
mozilla::DebugOnly<AutoEnterOOMUnsafeRegion> oomUnsafeRegion;
@@ -752,10 +688,6 @@ js::Nursery::doCollection(JSRuntime* rt, JS::gcreason::Reason reason,
// Make sure hashtables have been updated after the collection.
maybeStartProfile(ProfileKey::CheckHashTables);
-#ifdef JS_GC_ZEAL
- if (rt->hasZealMode(ZealMode::CheckHashTablesOnMinorGC))
- CheckHashTablesAfterMovingGC(rt);
-#endif
maybeEndProfile(ProfileKey::CheckHashTables);
// Calculate and return the promotion rate.
@@ -828,17 +760,6 @@ js::Nursery::sweep()
runSweepActions();
sweepDictionaryModeObjects();
-#ifdef JS_GC_ZEAL
- /* Poison the nursery contents so touching a freed object will crash. */
- for (unsigned i = 0; i < numChunks(); i++)
- chunk(i).poisonAndInit(runtime(), JS_SWEPT_NURSERY_PATTERN);
-
- if (runtime()->hasZealMode(ZealMode::GenerationalGC)) {
- /* Only reset the alloc point when we are close to the end. */
- if (currentChunk_ + 1 == numChunks())
- setCurrentChunk(0);
- } else
-#endif
{
#ifdef JS_CRASH_DIAGNOSTICS
for (unsigned i = 0; i < numChunks(); ++i)
@@ -916,20 +837,12 @@ js::Nursery::growAllocableSpace()
void
js::Nursery::shrinkAllocableSpace()
{
-#ifdef JS_GC_ZEAL
- if (runtime()->hasZealMode(ZealMode::GenerationalGC))
- return;
-#endif
updateNumChunks(Max(numChunks() - 1, 1u));
}
void
js::Nursery::minimizeAllocableSpace()
{
-#ifdef JS_GC_ZEAL
- if (runtime()->hasZealMode(ZealMode::GenerationalGC))
- return;
-#endif
updateNumChunks(1);
}
diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h
index 69fb66b7a..0d215d997 100644
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -58,8 +58,6 @@ class NativeObject;
class Nursery;
class HeapSlot;
-void SetGCZeal(JSRuntime*, uint8_t, uint32_t);
-
namespace gc {
class AutoMaybeStartBackgroundAllocation;
struct Cell;
@@ -252,11 +250,6 @@ class Nursery
(numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize;
}
-#ifdef JS_GC_ZEAL
- void enterZealMode();
- void leaveZealMode();
-#endif
-
/* Print total profile times on shutdown. */
void printTotalProfileTimes();
@@ -374,11 +367,6 @@ class Nursery
using NativeObjectVector = Vector<NativeObject*, 0, SystemAllocPolicy>;
NativeObjectVector dictionaryModeObjects_;
-#ifdef JS_GC_ZEAL
- struct Canary;
- Canary* lastCanary_;
-#endif
-
NurseryChunk* allocChunk();
NurseryChunk& chunk(unsigned index) const {
diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp
index dd4031606..3ebbbb4f6 100644
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -26,420 +26,6 @@
using namespace js;
using namespace js::gc;
-#ifdef JS_GC_ZEAL
-
-/*
- * Write barrier verification
- *
- * The next few functions are for write barrier verification.
- *
- * The VerifyBarriers function is a shorthand. It checks if a verification phase
- * is currently running. If not, it starts one. Otherwise, it ends the current
- * phase and starts a new one.
- *
- * The user can adjust the frequency of verifications, which causes
- * VerifyBarriers to be a no-op all but one out of N calls. However, if the
- * |always| parameter is true, it starts a new phase no matter what.
- *
- * Pre-Barrier Verifier:
- * When StartVerifyBarriers is called, a snapshot is taken of all objects in
- * the GC heap and saved in an explicit graph data structure. Later,
- * EndVerifyBarriers traverses the heap again. Any pointer values that were in
- * the snapshot and are no longer found must be marked; otherwise an assertion
- * triggers. Note that we must not GC in between starting and finishing a
- * verification phase.
- */
-
-struct EdgeValue
-{
- void* thing;
- JS::TraceKind kind;
- const char* label;
-};
-
-struct VerifyNode
-{
- void* thing;
- JS::TraceKind kind;
- uint32_t count;
- EdgeValue edges[1];
-};
-
-typedef HashMap<void*, VerifyNode*, DefaultHasher<void*>, SystemAllocPolicy> NodeMap;
-
-/*
- * The verifier data structures are simple. The entire graph is stored in a
- * single block of memory. At the beginning is a VerifyNode for the root
- * node. It is followed by a sequence of EdgeValues--the exact number is given
- * in the node. After the edges come more nodes and their edges.
- *
- * The edgeptr and term fields are used to allocate out of the block of memory
- * for the graph. If we run out of memory (i.e., if edgeptr goes beyond term),
- * we just abandon the verification.
- *
- * The nodemap field is a hashtable that maps from the address of the GC thing
- * to the VerifyNode that represents it.
- */
-class js::VerifyPreTracer final : public JS::CallbackTracer
-{
- JS::AutoDisableGenerationalGC noggc;
-
- void onChild(const JS::GCCellPtr& thing) override;
-
- public:
- /* The gcNumber when the verification began. */
- uint64_t number;
-
- /* This counts up to gcZealFrequency to decide whether to verify. */
- int count;
-
- /* This graph represents the initial GC "snapshot". */
- VerifyNode* curnode;
- VerifyNode* root;
- char* edgeptr;
- char* term;
- NodeMap nodemap;
-
- explicit VerifyPreTracer(JSRuntime* rt)
- : JS::CallbackTracer(rt), noggc(rt), number(rt->gc.gcNumber()), count(0), curnode(nullptr),
- root(nullptr), edgeptr(nullptr), term(nullptr)
- {}
-
- ~VerifyPreTracer() {
- js_free(root);
- }
-};
-
-/*
- * This function builds up the heap snapshot by adding edges to the current
- * node.
- */
-void
-VerifyPreTracer::onChild(const JS::GCCellPtr& thing)
-{
- MOZ_ASSERT(!IsInsideNursery(thing.asCell()));
-
- // Skip things in other runtimes.
- if (thing.asCell()->asTenured().runtimeFromAnyThread() != runtime())
- return;
-
- edgeptr += sizeof(EdgeValue);
- if (edgeptr >= term) {
- edgeptr = term;
- return;
- }
-
- VerifyNode* node = curnode;
- uint32_t i = node->count;
-
- node->edges[i].thing = thing.asCell();
- node->edges[i].kind = thing.kind();
- node->edges[i].label = contextName();
- node->count++;
-}
-
-static VerifyNode*
-MakeNode(VerifyPreTracer* trc, void* thing, JS::TraceKind kind)
-{
- NodeMap::AddPtr p = trc->nodemap.lookupForAdd(thing);
- if (!p) {
- VerifyNode* node = (VerifyNode*)trc->edgeptr;
- trc->edgeptr += sizeof(VerifyNode) - sizeof(EdgeValue);
- if (trc->edgeptr >= trc->term) {
- trc->edgeptr = trc->term;
- return nullptr;
- }
-
- node->thing = thing;
- node->count = 0;
- node->kind = kind;
- if (!trc->nodemap.add(p, thing, node)) {
- trc->edgeptr = trc->term;
- return nullptr;
- }
-
- return node;
- }
- return nullptr;
-}
-
-static VerifyNode*
-NextNode(VerifyNode* node)
-{
- if (node->count == 0)
- return (VerifyNode*)((char*)node + sizeof(VerifyNode) - sizeof(EdgeValue));
- else
- return (VerifyNode*)((char*)node + sizeof(VerifyNode) +
- sizeof(EdgeValue)*(node->count - 1));
-}
-
-void
-gc::GCRuntime::startVerifyPreBarriers()
-{
- if (verifyPreData || isIncrementalGCInProgress())
- return;
-
- if (IsIncrementalGCUnsafe(rt) != AbortReason::None)
- return;
-
- number++;
-
- VerifyPreTracer* trc = js_new<VerifyPreTracer>(rt);
- if (!trc)
- return;
-
- AutoPrepareForTracing prep(rt->contextFromMainThread(), WithAtoms);
-
- for (auto chunk = allNonEmptyChunks(); !chunk.done(); chunk.next())
- chunk->bitmap.clear();
-
- gcstats::AutoPhase ap(stats, gcstats::PHASE_TRACE_HEAP);
-
- const size_t size = 64 * 1024 * 1024;
- trc->root = (VerifyNode*)js_malloc(size);
- if (!trc->root)
- goto oom;
- trc->edgeptr = (char*)trc->root;
- trc->term = trc->edgeptr + size;
-
- if (!trc->nodemap.init())
- goto oom;
-
- /* Create the root node. */
- trc->curnode = MakeNode(trc, nullptr, JS::TraceKind(0));
-
- incrementalState = State::MarkRoots;
-
- /* Make all the roots be edges emanating from the root node. */
- traceRuntime(trc, prep.session().lock);
-
- VerifyNode* node;
- node = trc->curnode;
- if (trc->edgeptr == trc->term)
- goto oom;
-
- /* For each edge, make a node for it if one doesn't already exist. */
- while ((char*)node < trc->edgeptr) {
- for (uint32_t i = 0; i < node->count; i++) {
- EdgeValue& e = node->edges[i];
- VerifyNode* child = MakeNode(trc, e.thing, e.kind);
- if (child) {
- trc->curnode = child;
- js::TraceChildren(trc, e.thing, e.kind);
- }
- if (trc->edgeptr == trc->term)
- goto oom;
- }
-
- node = NextNode(node);
- }
-
- verifyPreData = trc;
- incrementalState = State::Mark;
- marker.start();
-
- for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
- PurgeJITCaches(zone);
- if (!zone->usedByExclusiveThread) {
- zone->setNeedsIncrementalBarrier(true, Zone::UpdateJit);
- zone->arenas.purge();
- }
- }
-
- return;
-
-oom:
- incrementalState = State::NotActive;
- js_delete(trc);
- verifyPreData = nullptr;
-}
-
-static bool
-IsMarkedOrAllocated(TenuredCell* cell)
-{
- return cell->isMarked() || cell->arena()->allocatedDuringIncremental;
-}
-
-struct CheckEdgeTracer : public JS::CallbackTracer {
- VerifyNode* node;
- explicit CheckEdgeTracer(JSRuntime* rt) : JS::CallbackTracer(rt), node(nullptr) {}
- void onChild(const JS::GCCellPtr& thing) override;
-};
-
-static const uint32_t MAX_VERIFIER_EDGES = 1000;
-
-/*
- * This function is called by EndVerifyBarriers for every heap edge. If the edge
- * already existed in the original snapshot, we "cancel it out" by overwriting
- * it with nullptr. EndVerifyBarriers later asserts that the remaining
- * non-nullptr edges (i.e., the ones from the original snapshot that must have
- * been modified) must point to marked objects.
- */
-void
-CheckEdgeTracer::onChild(const JS::GCCellPtr& thing)
-{
- // Skip things in other runtimes.
- if (thing.asCell()->asTenured().runtimeFromAnyThread() != runtime())
- return;
-
- /* Avoid n^2 behavior. */
- if (node->count > MAX_VERIFIER_EDGES)
- return;
-
- for (uint32_t i = 0; i < node->count; i++) {
- if (node->edges[i].thing == thing.asCell()) {
- MOZ_ASSERT(node->edges[i].kind == thing.kind());
- node->edges[i].thing = nullptr;
- return;
- }
- }
-}
-
-void
-js::gc::AssertSafeToSkipBarrier(TenuredCell* thing)
-{
- Zone* zone = thing->zoneFromAnyThread();
- MOZ_ASSERT(!zone->needsIncrementalBarrier() || zone->isAtomsZone());
-}
-
-static bool
-IsMarkedOrAllocated(const EdgeValue& edge)
-{
- if (!edge.thing || IsMarkedOrAllocated(TenuredCell::fromPointer(edge.thing)))
- return true;
-
- // Permanent atoms and well-known symbols aren't marked during graph traversal.
- if (edge.kind == JS::TraceKind::String && static_cast<JSString*>(edge.thing)->isPermanentAtom())
- return true;
- if (edge.kind == JS::TraceKind::Symbol && static_cast<JS::Symbol*>(edge.thing)->isWellKnownSymbol())
- return true;
-
- return false;
-}
-
-void
-gc::GCRuntime::endVerifyPreBarriers()
-{
- VerifyPreTracer* trc = verifyPreData;
-
- if (!trc)
- return;
-
- MOZ_ASSERT(!JS::IsGenerationalGCEnabled(rt));
-
- AutoPrepareForTracing prep(rt->contextFromMainThread(), SkipAtoms);
-
- bool compartmentCreated = false;
-
- /* We need to disable barriers before tracing, which may invoke barriers. */
- for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
- if (!zone->needsIncrementalBarrier())
- compartmentCreated = true;
-
- zone->setNeedsIncrementalBarrier(false, Zone::UpdateJit);
- PurgeJITCaches(zone);
- }
-
- /*
- * We need to bump gcNumber so that the methodjit knows that jitcode has
- * been discarded.
- */
- MOZ_ASSERT(trc->number == number);
- number++;
-
- verifyPreData = nullptr;
- incrementalState = State::NotActive;
-
- if (!compartmentCreated && IsIncrementalGCUnsafe(rt) == AbortReason::None) {
- CheckEdgeTracer cetrc(rt);
-
- /* Start after the roots. */
- VerifyNode* node = NextNode(trc->root);
- while ((char*)node < trc->edgeptr) {
- cetrc.node = node;
- js::TraceChildren(&cetrc, node->thing, node->kind);
-
- if (node->count <= MAX_VERIFIER_EDGES) {
- for (uint32_t i = 0; i < node->count; i++) {
- EdgeValue& edge = node->edges[i];
- if (!IsMarkedOrAllocated(edge)) {
- char msgbuf[1024];
- SprintfLiteral(msgbuf,
- "[barrier verifier] Unmarked edge: %s %p '%s' edge to %s %p",
- JS::GCTraceKindToAscii(node->kind), node->thing,
- edge.label,
- JS::GCTraceKindToAscii(edge.kind), edge.thing);
- MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__);
- MOZ_CRASH();
- }
- }
- }
-
- node = NextNode(node);
- }
- }
-
- marker.reset();
- marker.stop();
-
- js_delete(trc);
-}
-
-/*** Barrier Verifier Scheduling ***/
-
-void
-gc::GCRuntime::verifyPreBarriers()
-{
- if (verifyPreData)
- endVerifyPreBarriers();
- else
- startVerifyPreBarriers();
-}
-
-void
-gc::VerifyBarriers(JSRuntime* rt, VerifierType type)
-{
- if (type == PreBarrierVerifier)
- rt->gc.verifyPreBarriers();
-}
-
-void
-gc::GCRuntime::maybeVerifyPreBarriers(bool always)
-{
- if (!hasZealMode(ZealMode::VerifierPre))
- return;
-
- if (rt->mainThread.suppressGC)
- return;
-
- if (verifyPreData) {
- if (++verifyPreData->count < zealFrequency && !always)
- return;
-
- endVerifyPreBarriers();
- }
-
- startVerifyPreBarriers();
-}
-
-void
-js::gc::MaybeVerifyBarriers(JSContext* cx, bool always)
-{
- GCRuntime* gc = &cx->runtime()->gc;
- gc->maybeVerifyPreBarriers(always);
-}
-
-void
-js::gc::GCRuntime::finishVerifier()
-{
- if (verifyPreData) {
- js_delete(verifyPreData);
- verifyPreData = nullptr;
- }
-}
-
-#endif /* JS_GC_ZEAL */
-
#ifdef JSGC_HASH_TABLE_CHECKS
class CheckHeapTracer : public JS::CallbackTracer
diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h
index a3a6dc07f..50d06319d 100644
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -253,12 +253,6 @@ struct Zone : public JS::shadow::Zone,
// possibly at other times too.
uint64_t gcNumber();
- bool compileBarriers() const { return compileBarriers(needsIncrementalBarrier()); }
- bool compileBarriers(bool needsIncrementalBarrier) const {
- return needsIncrementalBarrier ||
- runtimeFromMainThread()->hasZealMode(js::gc::ZealMode::VerifierPre);
- }
-
enum ShouldUpdateJit { DontUpdateJit, UpdateJit };
void setNeedsIncrementalBarrier(bool needs, ShouldUpdateJit updateJit);
const bool* addressOfNeedsIncrementalBarrier() const { return &needsIncrementalBarrier_; }
diff --git a/js/src/gdb/progressbar.py b/js/src/gdb/progressbar.py
index d96a67c96..faf571ffb 100644
--- a/js/src/gdb/progressbar.py
+++ b/js/src/gdb/progressbar.py
@@ -12,7 +12,7 @@ class ProgressBar(object):
self.limit = limit
self.label_width = label_width
self.cur = 0
- self.t0 = datetime.datetime.now()
+ self.t0 = datetime.datetime.utcnow()
self.fullwidth = None
self.barlen = 64 - self.label_width
@@ -23,7 +23,7 @@ class ProgressBar(object):
pct = int(100.0 * self.cur / self.limit)
barlen = int(1.0 * self.barlen * self.cur / self.limit) - 1
bar = '='*barlen + '>'
- dt = datetime.datetime.now() - self.t0
+ dt = datetime.datetime.utcnow() - self.t0
dt = dt.seconds + dt.microseconds * 1e-6
line = self.fmt%(self.label[:self.label_width], pct, bar, dt)
self.fullwidth = len(line)
diff --git a/js/src/jit-test/tests/ion/bug730152.js b/js/src/jit-test/tests/ion/bug730152.js
deleted file mode 100644
index fe4ecfe14..000000000
--- a/js/src/jit-test/tests/ion/bug730152.js
+++ /dev/null
@@ -1,4 +0,0 @@
-if (typeof verifybarriers !== "undefined") {
- for (var i = 0; i < 30; i++) {}
- for (i in Function("gc(verifybarriers()); yield")()) {}
-}
diff --git a/js/src/jit-test/tests/ion/bug732758.js b/js/src/jit-test/tests/ion/bug732758.js
index 91da521c7..8196c3e03 100644
--- a/js/src/jit-test/tests/ion/bug732758.js
+++ b/js/src/jit-test/tests/ion/bug732758.js
@@ -38,5 +38,4 @@ tryItOut("{t:g}");
tryItOut("r");
tryItOut("p");
tryItOut("gc()");
-tryItOut("verifybarriers()");
tryItOut("/**/yield");
diff --git a/js/src/jit/CompileWrappers.h b/js/src/jit/CompileWrappers.h
index bbec9ffa3..ccded4f13 100644
--- a/js/src/jit/CompileWrappers.h
+++ b/js/src/jit/CompileWrappers.h
@@ -51,10 +51,6 @@ class CompileRuntime
// &runtime()->activation_
const void* addressOfActivation();
-#ifdef JS_GC_ZEAL
- const void* addressOfGCZealModeBits();
-#endif
-
const void* addressOfInterruptUint32();
// We have to bake JSContext* into JIT code, but this pointer shouldn't be
diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp
index 628b31fae..4edbc3c83 100644
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -135,7 +135,6 @@ CheckOverRecursed(JSContext* cx)
#else
JS_CHECK_RECURSION(cx, return false);
#endif
- gc::MaybeVerifyBarriers(cx);
return cx->runtime()->handleInterrupt(cx);
}
@@ -180,7 +179,6 @@ CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame,
JS_CHECK_RECURSION_WITH_SP(cx, checkSp, return false);
#endif
- gc::MaybeVerifyBarriers(cx);
return cx->runtime()->handleInterrupt(cx);
}
@@ -465,8 +463,6 @@ SetProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValu
bool
InterruptCheck(JSContext* cx)
{
- gc::MaybeVerifyBarriers(cx);
-
{
JSRuntime* rt = cx->runtime();
JitRuntime::AutoPreventBackedgePatching apbp(rt);
@@ -627,11 +623,7 @@ PostWriteElementBarrier(JSRuntime* rt, JSObject* obj, int32_t index)
if (obj->is<NativeObject>() &&
!obj->as<NativeObject>().isInWholeCellBuffer() &&
uint32_t(index) < obj->as<NativeObject>().getDenseInitializedLength() &&
- (obj->as<NativeObject>().getDenseInitializedLength() > MAX_WHOLE_CELL_BUFFER_SIZE
-#ifdef JS_GC_ZEAL
- || rt->hasZealMode(gc::ZealMode::ElementsBarrier)
-#endif
- ))
+ (obj->as<NativeObject>().getDenseInitializedLength() > MAX_WHOLE_CELL_BUFFER_SIZE))
{
rt->gc.storeBuffer.putSlot(&obj->as<NativeObject>(), HeapSlot::Element, index, 1);
return;
diff --git a/js/src/js-config.h.in b/js/src/js-config.h.in
index f2ce93e12..779446fd7 100644
--- a/js/src/js-config.h.in
+++ b/js/src/js-config.h.in
@@ -38,10 +38,6 @@
/* Define to 1 if SpiderMonkey should include ctypes support. */
#undef JS_HAS_CTYPES
-/* Define to 1 if SpiderMonkey should support the ability to perform
- entirely too much GC. */
-#undef JS_GC_ZEAL
-
/* Define to 1 if SpiderMonkey should use small chunks. */
#undef JS_GC_SMALL_CHUNK_SIZE
diff --git a/js/src/jsapi-tests/testGCFinalizeCallback.cpp b/js/src/jsapi-tests/testGCFinalizeCallback.cpp
index 48003ab0c..a8f7ba7f8 100644
--- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp
+++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp
@@ -94,36 +94,6 @@ BEGIN_TEST(testGCFinalizeCallback)
CHECK(checkFinalizeStatus());
CHECK(checkFinalizeIsZoneGC(true));
-#ifdef JS_GC_ZEAL
-
- /* Full GC with reset due to new zone, becoming zone GC. */
-
- FinalizeCalls = 0;
- JS_SetGCZeal(cx, 9, 1000000);
- JS::PrepareForFullGC(cx);
- js::SliceBudget budget(js::WorkBudget(1));
- cx->gc.startDebugGC(GC_NORMAL, budget);
- CHECK(cx->gc.state() == js::gc::State::Mark);
- CHECK(cx->gc.isFullGc());
-
- JS::RootedObject global4(cx, createTestGlobal());
- budget = js::SliceBudget(js::WorkBudget(1));
- cx->gc.debugGCSlice(budget);
- while (cx->gc.isIncrementalGCInProgress())
- cx->gc.debugGCSlice(budget);
- CHECK(!cx->gc.isIncrementalGCInProgress());
- CHECK(!cx->gc.isFullGc());
- CHECK(checkMultipleGroups());
- CHECK(checkFinalizeStatus());
-
- for (unsigned i = 0; i < FinalizeCalls - 1; ++i)
- CHECK(!IsZoneGCBuffer[i]);
- CHECK(IsZoneGCBuffer[FinalizeCalls - 1]);
-
- JS_SetGCZeal(cx, 0, 0);
-
-#endif
-
/*
* Make some use of the globals here to ensure the compiler doesn't optimize
* them away in release builds, causing the zones to be collected and
diff --git a/js/src/jsapi-tests/testGCHeapPostBarriers.cpp b/js/src/jsapi-tests/testGCHeapPostBarriers.cpp
index 74512a53f..00d47f111 100644
--- a/js/src/jsapi-tests/testGCHeapPostBarriers.cpp
+++ b/js/src/jsapi-tests/testGCHeapPostBarriers.cpp
@@ -40,10 +40,6 @@ JSFunction* CreateGCThing(JSContext* cx)
BEGIN_TEST(testGCHeapPostBarriers)
{
-#ifdef JS_GC_ZEAL
- AutoLeaveZeal nozeal(cx);
-#endif /* JS_GC_ZEAL */
-
/* Sanity check - objects start in the nursery and then become tenured. */
JS_GC(cx);
JS::RootedObject obj(cx, CreateGCThing<JSObject>(cx));
diff --git a/js/src/jsapi-tests/testGCMarking.cpp b/js/src/jsapi-tests/testGCMarking.cpp
index 684397392..b475c2d69 100644
--- a/js/src/jsapi-tests/testGCMarking.cpp
+++ b/js/src/jsapi-tests/testGCMarking.cpp
@@ -101,10 +101,6 @@ class CCWTestTracer : public JS::CallbackTracer {
BEGIN_TEST(testTracingIncomingCCWs)
{
-#ifdef JS_GC_ZEAL
- // Disable zeal modes because this test needs to control exactly when the GC happens.
- JS_SetGCZeal(cx, 0, 100);
-#endif
JS_GC(cx);
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
@@ -146,10 +142,6 @@ countWrappers(JSCompartment* comp)
BEGIN_TEST(testDeadNurseryCCW)
{
-#ifdef JS_GC_ZEAL
- // Disable zeal modes because this test needs to control exactly when the GC happens.
- JS_SetGCZeal(cx, 0, 100);
-#endif
JS_GC(cx);
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
@@ -177,10 +169,6 @@ END_TEST(testDeadNurseryCCW)
BEGIN_TEST(testLiveNurseryCCW)
{
-#ifdef JS_GC_ZEAL
- // Disable zeal modes because this test needs to control exactly when the GC happens.
- JS_SetGCZeal(cx, 0, 100);
-#endif
JS_GC(cx);
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
@@ -208,10 +196,6 @@ END_TEST(testLiveNurseryCCW)
BEGIN_TEST(testLiveNurseryWrapperCCW)
{
-#ifdef JS_GC_ZEAL
- // Disable zeal modes because this test needs to control exactly when the GC happens.
- JS_SetGCZeal(cx, 0, 100);
-#endif
JS_GC(cx);
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
@@ -244,10 +228,6 @@ END_TEST(testLiveNurseryWrapperCCW)
BEGIN_TEST(testLiveNurseryWrappeeCCW)
{
-#ifdef JS_GC_ZEAL
- // Disable zeal modes because this test needs to control exactly when the GC happens.
- JS_SetGCZeal(cx, 0, 100);
-#endif
JS_GC(cx);
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
@@ -280,11 +260,6 @@ BEGIN_TEST(testIncrementalRoots)
{
JSRuntime* rt = cx->runtime();
-#ifdef JS_GC_ZEAL
- // Disable zeal modes because this test needs to control exactly when the GC happens.
- JS_SetGCZeal(cx, 0, 100);
-#endif
-
// Construct a big object graph to mark. In JS, the resulting object graph
// is equivalent to:
//
diff --git a/js/src/jsapi-tests/testGCUniqueId.cpp b/js/src/jsapi-tests/testGCUniqueId.cpp
index 71d66b722..d03d51b04 100644
--- a/js/src/jsapi-tests/testGCUniqueId.cpp
+++ b/js/src/jsapi-tests/testGCUniqueId.cpp
@@ -23,10 +23,6 @@ MinimizeHeap(JSContext* cx)
BEGIN_TEST(testGCUID)
{
-#ifdef JS_GC_ZEAL
- AutoLeaveZeal nozeal(cx);
-#endif /* JS_GC_ZEAL */
-
uint64_t uid = 0;
uint64_t tmp = 0;
diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h
index 9955621ef..7f7309c16 100644
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -418,39 +418,4 @@ class TestJSPrincipals : public JSPrincipals
}
};
-#ifdef JS_GC_ZEAL
-/*
- * Temporarily disable the GC zeal setting. This is only useful in tests that
- * need very explicit GC behavior and should not be used elsewhere.
- */
-class AutoLeaveZeal
-{
- JSContext* cx_;
- uint32_t zealBits_;
- uint32_t frequency_;
-
- public:
- explicit AutoLeaveZeal(JSContext* cx) : cx_(cx) {
- uint32_t dummy;
- JS_GetGCZealBits(cx_, &zealBits_, &frequency_, &dummy);
- JS_SetGCZeal(cx_, 0, 0);
- JS::PrepareForFullGC(cx_);
- JS::GCForReason(cx_, GC_SHRINK, JS::gcreason::DEBUG_GC);
- }
- ~AutoLeaveZeal() {
- for (size_t i = 0; i < sizeof(zealBits_) * 8; i++) {
- if (zealBits_ & (1 << i))
- JS_SetGCZeal(cx_, i, frequency_);
- }
-
-#ifdef DEBUG
- uint32_t zealBitsAfter, frequencyAfter, dummy;
- JS_GetGCZealBits(cx_, &zealBitsAfter, &frequencyAfter, &dummy);
- MOZ_ASSERT(zealBitsAfter == zealBits_);
- MOZ_ASSERT(frequencyAfter == frequency_);
-#endif
- }
-};
-#endif /* JS_GC_ZEAL */
-
#endif /* jsapi_tests_tests_h */
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index a99d08951..ee9c61059 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1410,6 +1410,17 @@ JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value)
MOZ_ALWAYS_TRUE(cx->gc.setParameter(key, value, lock));
}
+JS_PUBLIC_API(void)
+JS_SetGGCMode(JSContext* cx, bool enabled)
+{
+ // Control GGC
+ if (enabled && !cx->gc.isGenerationalGCEnabled()) {
+ cx->gc.enableGenerationalGC();
+ } else if (!enabled && cx->gc.isGenerationalGCEnabled()) {
+ cx->gc.disableGenerationalGC();
+ }
+}
+
JS_PUBLIC_API(uint32_t)
JS_GetGCParameter(JSContext* cx, JSGCParamKey key)
{
@@ -6252,26 +6263,6 @@ JS_AbortIfWrongThread(JSContext* cx)
MOZ_CRASH();
}
-#ifdef JS_GC_ZEAL
-JS_PUBLIC_API(void)
-JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled)
-{
- cx->runtime()->gc.getZealBits(zealBits, frequency, nextScheduled);
-}
-
-JS_PUBLIC_API(void)
-JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency)
-{
- cx->gc.setZeal(zeal, frequency);
-}
-
-JS_PUBLIC_API(void)
-JS_ScheduleGC(JSContext* cx, uint32_t count)
-{
- cx->runtime()->gc.setNextScheduled(count);
-}
-#endif
-
JS_PUBLIC_API(void)
JS_SetParallelParsingEnabled(JSContext* cx, bool enabled)
{
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 46aa15947..9ad3e757f 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1768,6 +1768,9 @@ typedef enum JSGCParamKey {
extern JS_PUBLIC_API(void)
JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
+extern JS_PUBLIC_API(void)
+JS_SetGGCMode(JSContext* cx, bool enabled);
+
extern JS_PUBLIC_API(uint32_t)
JS_GetGCParameter(JSContext* cx, JSGCParamKey key);
@@ -5758,19 +5761,6 @@ JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallAr
/************************************************************************/
-#ifdef JS_GC_ZEAL
-#define JS_DEFAULT_ZEAL_FREQ 100
-
-extern JS_PUBLIC_API(void)
-JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled);
-
-extern JS_PUBLIC_API(void)
-JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency);
-
-extern JS_PUBLIC_API(void)
-JS_ScheduleGC(JSContext* cx, uint32_t count);
-#endif
-
extern JS_PUBLIC_API(void)
JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index 42d10283c..45301dac8 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -844,9 +844,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
arenasAllocatedDuringSweep(nullptr),
startedCompacting(false),
relocatedArenasToRelease(nullptr),
-#ifdef JS_GC_ZEAL
- markingValidator(nullptr),
-#endif
interFrameGC(false),
defaultTimeBudget_(SliceBudget::UnlimitedTimeBudget),
incrementalAllowed(true),
@@ -856,13 +853,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
manipulatingDeadZones(false),
objectsMarkedInDeadZones(0),
poked(false),
-#ifdef JS_GC_ZEAL
- zealModeBits(0),
- zealFrequency(0),
- nextScheduled(0),
- deterministicOnly(false),
- incrementalLimit(0),
-#endif
fullCompartmentChecks(false),
mallocBytesUntilGC(0),
mallocGCTriggered(false),
@@ -881,147 +871,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
setGCMode(JSGC_MODE_GLOBAL);
}
-#ifdef JS_GC_ZEAL
-
-void
-GCRuntime::getZealBits(uint32_t* zealBits, uint32_t* frequency, uint32_t* scheduled)
-{
- *zealBits = zealModeBits;
- *frequency = zealFrequency;
- *scheduled = nextScheduled;
-}
-
-const char* gc::ZealModeHelpText =
- " Specifies how zealous the garbage collector should be. Some of these modes can\n"
- " be set simultaneously, by passing multiple level options, e.g. \"2;4\" will activate\n"
- " both modes 2 and 4. Modes can be specified by name or number.\n"
- " \n"
- " Values:\n"
- " 0: (None) Normal amount of collection (resets all modes)\n"
- " 1: (Poke) Collect when roots are added or removed\n"
- " 2: (Alloc) Collect when every N allocations (default: 100)\n"
- " 3: (FrameGC) Collect when the window paints (browser only)\n"
- " 4: (VerifierPre) Verify pre write barriers between instructions\n"
- " 5: (FrameVerifierPre) Verify pre write barriers between paints\n"
- " 6: (StackRooting) Verify stack rooting\n"
- " 7: (GenerationalGC) Collect the nursery every N nursery allocations\n"
- " 8: (IncrementalRootsThenFinish) Incremental GC in two slices: 1) mark roots 2) finish collection\n"
- " 9: (IncrementalMarkAllThenFinish) Incremental GC in two slices: 1) mark all 2) new marking and finish\n"
- " 10: (IncrementalMultipleSlices) Incremental GC in multiple slices\n"
- " 11: (IncrementalMarkingValidator) Verify incremental marking\n"
- " 12: (ElementsBarrier) Always use the individual element post-write barrier, regardless of elements size\n"
- " 13: (CheckHashTablesOnMinorGC) Check internal hashtables on minor GC\n"
- " 14: (Compact) Perform a shrinking collection every N allocations\n"
- " 15: (CheckHeapAfterGC) Walk the heap to check its integrity after every GC\n"
- " 16: (CheckNursery) Check nursery integrity on minor GC\n";
-
-void
-GCRuntime::setZeal(uint8_t zeal, uint32_t frequency)
-{
- MOZ_ASSERT(zeal <= unsigned(ZealMode::Limit));
-
- if (verifyPreData)
- VerifyBarriers(rt, PreBarrierVerifier);
-
- if (zeal == 0 && hasZealMode(ZealMode::GenerationalGC)) {
- evictNursery(JS::gcreason::DEBUG_GC);
- nursery.leaveZealMode();
- }
-
- ZealMode zealMode = ZealMode(zeal);
- if (zealMode == ZealMode::GenerationalGC)
- nursery.enterZealMode();
-
- // Zeal modes 8-10 are mutually exclusive. If we're setting one of those,
- // we first reset all of them.
- if (zealMode >= ZealMode::IncrementalRootsThenFinish &&
- zealMode <= ZealMode::IncrementalMultipleSlices)
- {
- clearZealMode(ZealMode::IncrementalRootsThenFinish);
- clearZealMode(ZealMode::IncrementalMarkAllThenFinish);
- clearZealMode(ZealMode::IncrementalMultipleSlices);
- }
-
- bool schedule = zealMode >= ZealMode::Alloc;
- if (zeal != 0)
- zealModeBits |= 1 << unsigned(zeal);
- else
- zealModeBits = 0;
- zealFrequency = frequency;
- nextScheduled = schedule ? frequency : 0;
-}
-
-void
-GCRuntime::setNextScheduled(uint32_t count)
-{
- nextScheduled = count;
-}
-
-bool
-GCRuntime::parseAndSetZeal(const char* str)
-{
- int frequency = -1;
- bool foundFrequency = false;
- mozilla::Vector<int, 0, SystemAllocPolicy> zeals;
-
- static const struct {
- const char* const zealMode;
- size_t length;
- uint32_t zeal;
- } zealModes[] = {
-#define ZEAL_MODE(name, value) {#name, sizeof(#name) - 1, value},
- JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE)
-#undef ZEAL_MODE
- {"None", 4, 0}
- };
-
- do {
- int zeal = -1;
-
- const char* p = nullptr;
- if (isdigit(str[0])) {
- zeal = atoi(str);
-
- size_t offset = strspn(str, "0123456789");
- p = str + offset;
- } else {
- for (auto z : zealModes) {
- if (!strncmp(str, z.zealMode, z.length)) {
- zeal = z.zeal;
- p = str + z.length;
- break;
- }
- }
- }
- if (p) {
- if (!*p || *p == ';') {
- frequency = JS_DEFAULT_ZEAL_FREQ;
- } else if (*p == ',') {
- frequency = atoi(p + 1);
- foundFrequency = true;
- }
- }
-
- if (zeal < 0 || zeal > int(ZealMode::Limit) || frequency <= 0) {
- fprintf(stderr, "Format: JS_GC_ZEAL=level(;level)*[,N]\n");
- fputs(ZealModeHelpText, stderr);
- return false;
- }
-
- if (!zeals.emplaceBack(zeal)) {
- return false;
- }
- } while (!foundFrequency &&
- (str = strchr(str, ';')) != nullptr &&
- str++);
-
- for (auto z : zeals)
- setZeal(z, frequency);
- return true;
-}
-
-#endif
-
/*
* Lifetime in number of major GCs for type sets attached to scripts containing
* observed types.
@@ -1063,12 +912,6 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
}
}
-#ifdef JS_GC_ZEAL
- const char* zealSpec = getenv("JS_GC_ZEAL");
- if (zealSpec && zealSpec[0] && !parseAndSetZeal(zealSpec))
- return false;
-#endif
-
if (!InitTrace(*this))
return false;
@@ -1094,11 +937,6 @@ GCRuntime::finish()
allocTask.cancel(GCParallelTask::CancelAndWait);
decommitTask.cancel(GCParallelTask::CancelAndWait);
-#ifdef JS_GC_ZEAL
- /* Free memory associated with GC verification. */
- finishVerifier();
-#endif
-
/* Delete all remaining zones. */
if (rt->gcInitialized) {
AutoSetThreadIsSweeping threadIsSweeping;
@@ -1315,7 +1153,6 @@ GCRuntime::setMarkStackLimit(size_t limit, AutoLockGC& lock)
{
MOZ_ASSERT(!rt->isHeapBusy());
AutoUnlockGC unlock(lock);
- AutoStopVerifyingBarriers pauseVerification(rt, false);
marker.setMaxCapacity(limit);
}
@@ -2635,7 +2472,7 @@ GCRuntime::releaseRelocatedArenasWithoutUnlocking(Arena* arenaList, const AutoLo
// Mark arena as empty
arena->setAsFullyUnused();
-#if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL)
+#if defined(JS_CRASH_DIAGNOSTICS)
JS_POISON(reinterpret_cast<void*>(arena->thingsStart()),
JS_MOVED_TENURED_PATTERN, arena->getThingsSpan());
#endif
@@ -3048,13 +2885,6 @@ GCRuntime::triggerZoneGC(Zone* zone, JS::gcreason::Reason reason)
if (rt->isHeapCollecting())
return false;
-#ifdef JS_GC_ZEAL
- if (hasZealMode(ZealMode::Alloc)) {
- MOZ_RELEASE_ASSERT(triggerGC(reason));
- return true;
- }
-#endif
-
if (zone->isAtomsZone()) {
/* We can't do a zone GC of the atoms compartment. */
if (rt->keepAtoms()) {
@@ -3077,14 +2907,6 @@ GCRuntime::maybeGC(Zone* zone)
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
-#ifdef JS_GC_ZEAL
- if (hasZealMode(ZealMode::Alloc) || hasZealMode(ZealMode::Poke)) {
- JS::PrepareForFullGC(rt->contextFromMainThread());
- gc(GC_NORMAL, JS::gcreason::DEBUG_GC);
- return;
- }
-#endif
-
if (gcIfRequested())
return;
@@ -3418,11 +3240,6 @@ GCRuntime::shouldReleaseObservedTypes()
{
bool releaseTypes = false;
-#ifdef JS_GC_ZEAL
- if (zealModeBits != 0)
- releaseTypes = true;
-#endif
-
/* We may miss the exact target GC due to resets. */
if (majorGCNumber >= jitReleaseNumber)
releaseTypes = true;
@@ -4068,292 +3885,6 @@ GCRuntime::markAllGrayReferences(gcstats::Phase phase)
markGrayReferences<GCZonesIter, GCCompartmentsIter>(phase);
}
-#ifdef JS_GC_ZEAL
-
-struct GCChunkHasher {
- typedef gc::Chunk* Lookup;
-
- /*
- * Strip zeros for better distribution after multiplying by the golden
- * ratio.
- */
- static HashNumber hash(gc::Chunk* chunk) {
- MOZ_ASSERT(!(uintptr_t(chunk) & gc::ChunkMask));
- return HashNumber(uintptr_t(chunk) >> gc::ChunkShift);
- }
-
- static bool match(gc::Chunk* k, gc::Chunk* l) {
- MOZ_ASSERT(!(uintptr_t(k) & gc::ChunkMask));
- MOZ_ASSERT(!(uintptr_t(l) & gc::ChunkMask));
- return k == l;
- }
-};
-
-class js::gc::MarkingValidator
-{
- public:
- explicit MarkingValidator(GCRuntime* gc);
- ~MarkingValidator();
- void nonIncrementalMark(AutoLockForExclusiveAccess& lock);
- void validate();
-
- private:
- GCRuntime* gc;
- bool initialized;
-
- typedef HashMap<Chunk*, ChunkBitmap*, GCChunkHasher, SystemAllocPolicy> BitmapMap;
- BitmapMap map;
-};
-
-js::gc::MarkingValidator::MarkingValidator(GCRuntime* gc)
- : gc(gc),
- initialized(false)
-{}
-
-js::gc::MarkingValidator::~MarkingValidator()
-{
- if (!map.initialized())
- return;
-
- for (BitmapMap::Range r(map.all()); !r.empty(); r.popFront())
- js_delete(r.front().value());
-}
-
-void
-js::gc::MarkingValidator::nonIncrementalMark(AutoLockForExclusiveAccess& lock)
-{
- /*
- * Perform a non-incremental mark for all collecting zones and record
- * the results for later comparison.
- *
- * Currently this does not validate gray marking.
- */
-
- if (!map.init())
- return;
-
- JSRuntime* runtime = gc->rt;
- GCMarker* gcmarker = &gc->marker;
-
- gc->waitBackgroundSweepEnd();
-
- /* Save existing mark bits. */
- for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) {
- ChunkBitmap* bitmap = &chunk->bitmap;
- ChunkBitmap* entry = js_new<ChunkBitmap>();
- if (!entry)
- return;
-
- memcpy((void*)entry->bitmap, (void*)bitmap->bitmap, sizeof(bitmap->bitmap));
- if (!map.putNew(chunk, entry))
- return;
- }
-
- /*
- * Temporarily clear the weakmaps' mark flags for the compartments we are
- * collecting.
- */
-
- WeakMapSet markedWeakMaps;
- if (!markedWeakMaps.init())
- return;
-
- /*
- * For saving, smush all of the keys into one big table and split them back
- * up into per-zone tables when restoring.
- */
- gc::WeakKeyTable savedWeakKeys(SystemAllocPolicy(), runtime->randomHashCodeScrambler());
- if (!savedWeakKeys.init())
- return;
-
- for (GCZonesIter zone(runtime); !zone.done(); zone.next()) {
- if (!WeakMapBase::saveZoneMarkedWeakMaps(zone, markedWeakMaps))
- return;
-
- AutoEnterOOMUnsafeRegion oomUnsafe;
- for (gc::WeakKeyTable::Range r = zone->gcWeakKeys.all(); !r.empty(); r.popFront()) {
- if (!savedWeakKeys.put(Move(r.front().key), Move(r.front().value)))
- oomUnsafe.crash("saving weak keys table for validator");
- }
-
- if (!zone->gcWeakKeys.clear())
- oomUnsafe.crash("clearing weak keys table for validator");
- }
-
- /*
- * After this point, the function should run to completion, so we shouldn't
- * do anything fallible.
- */
- initialized = true;
-
- /* Re-do all the marking, but non-incrementally. */
- js::gc::State state = gc->incrementalState;
- gc->incrementalState = State::MarkRoots;
-
- {
- gcstats::AutoPhase ap(gc->stats, gcstats::PHASE_MARK);
-
- {
- gcstats::AutoPhase ap(gc->stats, gcstats::PHASE_UNMARK);
-
- for (GCZonesIter zone(runtime); !zone.done(); zone.next())
- WeakMapBase::unmarkZone(zone);
-
- MOZ_ASSERT(gcmarker->isDrained());
- gcmarker->reset();
-
- for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next())
- chunk->bitmap.clear();
- }
-
- gc->traceRuntimeForMajorGC(gcmarker, lock);
-
- gc->incrementalState = State::Mark;
- auto unlimited = SliceBudget::unlimited();
- MOZ_RELEASE_ASSERT(gc->marker.drainMarkStack(unlimited));
- }
-
- gc->incrementalState = State::Sweep;
- {
- gcstats::AutoPhase ap1(gc->stats, gcstats::PHASE_SWEEP);
- gcstats::AutoPhase ap2(gc->stats, gcstats::PHASE_SWEEP_MARK);
-
- gc->markAllWeakReferences(gcstats::PHASE_SWEEP_MARK_WEAK);
-
- /* Update zone state for gray marking. */
- for (GCZonesIter zone(runtime); !zone.done(); zone.next()) {
- MOZ_ASSERT(zone->isGCMarkingBlack());
- zone->setGCState(Zone::MarkGray);
- }
- gc->marker.setMarkColorGray();
-
- gc->markAllGrayReferences(gcstats::PHASE_SWEEP_MARK_GRAY);
- gc->markAllWeakReferences(gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
-
- /* Restore zone state. */
- for (GCZonesIter zone(runtime); !zone.done(); zone.next()) {
- MOZ_ASSERT(zone->isGCMarkingGray());
- zone->setGCState(Zone::Mark);
- }
- MOZ_ASSERT(gc->marker.isDrained());
- gc->marker.setMarkColorBlack();
- }
-
- /* Take a copy of the non-incremental mark state and restore the original. */
- for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) {
- ChunkBitmap* bitmap = &chunk->bitmap;
- ChunkBitmap* entry = map.lookup(chunk)->value();
- Swap(*entry, *bitmap);
- }
-
- for (GCZonesIter zone(runtime); !zone.done(); zone.next()) {
- WeakMapBase::unmarkZone(zone);
- AutoEnterOOMUnsafeRegion oomUnsafe;
- if (!zone->gcWeakKeys.clear())
- oomUnsafe.crash("clearing weak keys table for validator");
- }
-
- WeakMapBase::restoreMarkedWeakMaps(markedWeakMaps);
-
- for (gc::WeakKeyTable::Range r = savedWeakKeys.all(); !r.empty(); r.popFront()) {
- AutoEnterOOMUnsafeRegion oomUnsafe;
- Zone* zone = gc::TenuredCell::fromPointer(r.front().key.asCell())->zone();
- if (!zone->gcWeakKeys.put(Move(r.front().key), Move(r.front().value)))
- oomUnsafe.crash("restoring weak keys table for validator");
- }
-
- gc->incrementalState = state;
-}
-
-void
-js::gc::MarkingValidator::validate()
-{
- /*
- * Validates the incremental marking for a single compartment by comparing
- * the mark bits to those previously recorded for a non-incremental mark.
- */
-
- if (!initialized)
- return;
-
- gc->waitBackgroundSweepEnd();
-
- for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) {
- BitmapMap::Ptr ptr = map.lookup(chunk);
- if (!ptr)
- continue; /* Allocated after we did the non-incremental mark. */
-
- ChunkBitmap* bitmap = ptr->value();
- ChunkBitmap* incBitmap = &chunk->bitmap;
-
- for (size_t i = 0; i < ArenasPerChunk; i++) {
- if (chunk->decommittedArenas.get(i))
- continue;
- Arena* arena = &chunk->arenas[i];
- if (!arena->allocated())
- continue;
- if (!arena->zone->isGCSweeping())
- continue;
- if (arena->allocatedDuringIncremental)
- continue;
-
- AllocKind kind = arena->getAllocKind();
- uintptr_t thing = arena->thingsStart();
- uintptr_t end = arena->thingsEnd();
- while (thing < end) {
- Cell* cell = (Cell*)thing;
-
- /*
- * If a non-incremental GC wouldn't have collected a cell, then
- * an incremental GC won't collect it.
- */
- MOZ_ASSERT_IF(bitmap->isMarked(cell, BLACK), incBitmap->isMarked(cell, BLACK));
-
- /*
- * If the cycle collector isn't allowed to collect an object
- * after a non-incremental GC has run, then it isn't allowed to
- * collected it after an incremental GC.
- */
- MOZ_ASSERT_IF(!bitmap->isMarked(cell, GRAY), !incBitmap->isMarked(cell, GRAY));
-
- thing += Arena::thingSize(kind);
- }
- }
- }
-}
-
-#endif // JS_GC_ZEAL
-
-void
-GCRuntime::computeNonIncrementalMarkingForValidation(AutoLockForExclusiveAccess& lock)
-{
-#ifdef JS_GC_ZEAL
- MOZ_ASSERT(!markingValidator);
- if (isIncremental && hasZealMode(ZealMode::IncrementalMarkingValidator))
- markingValidator = js_new<MarkingValidator>(this);
- if (markingValidator)
- markingValidator->nonIncrementalMark(lock);
-#endif
-}
-
-void
-GCRuntime::validateIncrementalMarking()
-{
-#ifdef JS_GC_ZEAL
- if (markingValidator)
- markingValidator->validate();
-#endif
-}
-
-void
-GCRuntime::finishMarkingValidation()
-{
-#ifdef JS_GC_ZEAL
- js_delete(markingValidator);
- markingValidator = nullptr;
-#endif
-}
-
static void
DropStringWrappers(JSRuntime* rt)
{
@@ -4988,8 +4519,6 @@ GCRuntime::beginSweepingZoneGroup(AutoLockForExclusiveAccess& lock)
#endif
}
- validateIncrementalMarking();
-
FreeOp fop(rt);
SweepAtomsTask sweepAtomsTask(rt);
SweepCCWrappersTask sweepCCWrappersTask(rt);
@@ -5215,8 +4744,6 @@ GCRuntime::beginSweepPhase(bool destroyingRuntime, AutoLockForExclusiveAccess& l
releaseHeldRelocatedArenas();
- computeNonIncrementalMarkingForValidation(lock);
-
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP);
sweepOnBackgroundThread =
@@ -5462,8 +4989,6 @@ GCRuntime::endSweepPhase(bool destroyingRuntime, AutoLockForExclusiveAccess& loc
rt->setGCGrayBitsValid(true);
}
- finishMarkingValidation();
-
#ifdef DEBUG
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
for (auto i : AllAllocKinds()) {
@@ -5782,16 +5307,6 @@ AutoGCSlice::~AutoGCSlice()
}
}
-void
-GCRuntime::pushZealSelectedObjects()
-{
-#ifdef JS_GC_ZEAL
- /* Push selected objects onto the mark stack and clear the list. */
- for (JSObject** obj = selectedForMarking.begin(); obj != selectedForMarking.end(); obj++)
- TraceManuallyBarrieredEdge(&marker, obj, "selected obj");
-#endif
-}
-
static bool
IsShutdownGC(JS::gcreason::Reason reason)
{
@@ -5817,31 +5332,9 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
gc::State initialState = incrementalState;
- bool useZeal = false;
-#ifdef JS_GC_ZEAL
- if (reason == JS::gcreason::DEBUG_GC && !budget.isUnlimited()) {
- /*
- * Do the incremental collection type specified by zeal mode if the
- * collection was triggered by runDebugGC() and incremental GC has not
- * been cancelled by resetIncrementalGC().
- */
- useZeal = true;
- }
-#endif
-
MOZ_ASSERT_IF(isIncrementalGCInProgress(), isIncremental);
isIncremental = !budget.isUnlimited();
- if (useZeal && (hasZealMode(ZealMode::IncrementalRootsThenFinish) ||
- hasZealMode(ZealMode::IncrementalMarkAllThenFinish)))
- {
- /*
- * Yields between slices occurs at predetermined points in these modes;
- * the budget is not used.
- */
- budget.makeUnlimited();
- }
-
switch (incrementalState) {
case State::NotActive:
initialReason = reason;
@@ -5859,14 +5352,8 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
return;
}
- if (!destroyingRuntime)
- pushZealSelectedObjects();
-
incrementalState = State::Mark;
- if (isIncremental && useZeal && hasZealMode(ZealMode::IncrementalRootsThenFinish))
- break;
-
MOZ_FALLTHROUGH;
case State::Mark:
@@ -5895,10 +5382,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
* We will need to mark anything new on the stack when we resume, so
* we stay in Mark state.
*/
- if (!lastMarkSlice && isIncremental &&
- ((initialState == State::Mark &&
- !(useZeal && hasZealMode(ZealMode::IncrementalRootsThenFinish))) ||
- (useZeal && hasZealMode(ZealMode::IncrementalMarkAllThenFinish))))
+ if (!lastMarkSlice && isIncremental && initialState == State::Mark)
{
lastMarkSlice = true;
break;
@@ -5914,13 +5398,6 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
if (budget.isOverBudget())
break;
- /*
- * Always yield here when running in incremental multi-slice zeal
- * mode, so RunDebugGC can reset the slice buget.
- */
- if (isIncremental && useZeal && hasZealMode(ZealMode::IncrementalMultipleSlices))
- break;
-
MOZ_FALLTHROUGH;
case State::Sweep:
@@ -6202,11 +5679,6 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
chunkAllocationSinceLastGC = false;
-#ifdef JS_GC_ZEAL
- /* Keeping these around after a GC is dangerous. */
- clearSelectedForMarking();
-#endif
-
/* Clear gcMallocBytes for all zones. */
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
zone->resetGCMallocBytes();
@@ -6218,23 +5690,6 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
return false;
}
-#ifdef JS_GC_ZEAL
-static bool
-IsDeterministicGCReason(JS::gcreason::Reason reason)
-{
- if (reason > JS::gcreason::DEBUG_GC &&
- reason != JS::gcreason::CC_FORCED && reason != JS::gcreason::SHUTDOWN_CC)
- {
- return false;
- }
-
- if (reason == JS::gcreason::EAGER_ALLOC_TRIGGER)
- return false;
-
- return true;
-}
-#endif
-
gcstats::ZoneGCStats
GCRuntime::scanZonesBeforeGC()
{
@@ -6300,11 +5755,6 @@ GCRuntime::checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason)
if (rt->isBeingDestroyed() && !IsShutdownGC(reason))
return false;
-#ifdef JS_GC_ZEAL
- if (deterministicOnly && !IsDeterministicGCReason(reason))
- return false;
-#endif
-
return true;
}
@@ -6319,7 +5769,6 @@ GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::R
return;
AutoTraceLog logGC(TraceLoggerForMainThread(rt), TraceLogger_GC);
- AutoStopVerifyingBarriers av(rt, IsShutdownGC(reason));
AutoEnqueuePendingParseTasksAfterGC aept(*this);
AutoScheduleZonesForGC asz(rt);
@@ -6360,13 +5809,6 @@ GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::R
if (reason == JS::gcreason::COMPARTMENT_REVIVED)
maybeDoCycleCollection();
-
-#ifdef JS_GC_ZEAL
- if (rt->hasZealMode(ZealMode::CheckHeapAfterGC)) {
- gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_TRACE_HEAP);
- CheckHeapAfterGC(rt);
- }
-#endif
}
js::AutoEnqueuePendingParseTasksAfterGC::~AutoEnqueuePendingParseTasksAfterGC()
@@ -6442,7 +5884,6 @@ GCRuntime::abortGC()
checkCanCallAPI();
MOZ_ASSERT(!rt->mainThread.suppressGC);
- AutoStopVerifyingBarriers av(rt, false);
AutoEnqueuePendingParseTasksAfterGC aept(*this);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind,
@@ -6460,17 +5901,6 @@ GCRuntime::notifyDidPaint()
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
-#ifdef JS_GC_ZEAL
- if (hasZealMode(ZealMode::FrameVerifierPre))
- verifyPreBarriers();
-
- if (hasZealMode(ZealMode::FrameGC)) {
- JS::PrepareForFullGC(rt->contextFromMainThread());
- gc(GC_NORMAL, JS::gcreason::REFRESH_FRAME);
- return;
- }
-#endif
-
if (isIncrementalGCInProgress() && !interFrameGC && tunables.areRefreshFrameSlicesEnabled()) {
JS::PrepareForIncrementalGC(rt->contextFromMainThread());
gcSlice(JS::gcreason::REFRESH_FRAME);
@@ -6566,11 +5996,6 @@ GCRuntime::minorGC(JS::gcreason::Reason reason, gcstats::Phase phase)
blocksToFreeAfterMinorGC.freeAll();
-#ifdef JS_GC_ZEAL
- if (rt->hasZealMode(ZealMode::CheckHeapAfterGC))
- CheckHeapAfterGC(rt);
-#endif
-
{
AutoLockGC lock(rt);
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
@@ -6754,92 +6179,12 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
}
void
-GCRuntime::runDebugGC()
-{
-#ifdef JS_GC_ZEAL
- if (rt->mainThread.suppressGC)
- return;
-
- if (hasZealMode(ZealMode::GenerationalGC))
- return minorGC(JS::gcreason::DEBUG_GC);
-
- PrepareForDebugGC(rt);
-
- auto budget = SliceBudget::unlimited();
- if (hasZealMode(ZealMode::IncrementalRootsThenFinish) ||
- hasZealMode(ZealMode::IncrementalMarkAllThenFinish) ||
- hasZealMode(ZealMode::IncrementalMultipleSlices))
- {
- js::gc::State initialState = incrementalState;
- if (hasZealMode(ZealMode::IncrementalMultipleSlices)) {
- /*
- * Start with a small slice limit and double it every slice. This
- * ensure that we get multiple slices, and collection runs to
- * completion.
- */
- if (!isIncrementalGCInProgress())
- incrementalLimit = zealFrequency / 2;
- else
- incrementalLimit *= 2;
- budget = SliceBudget(WorkBudget(incrementalLimit));
- } else {
- // This triggers incremental GC but is actually ignored by IncrementalMarkSlice.
- budget = SliceBudget(WorkBudget(1));
- }
-
- if (!isIncrementalGCInProgress())
- invocationKind = GC_SHRINK;
- collect(false, budget, JS::gcreason::DEBUG_GC);
-
- /*
- * For multi-slice zeal, reset the slice size when we get to the sweep
- * or compact phases.
- */
- if (hasZealMode(ZealMode::IncrementalMultipleSlices)) {
- if ((initialState == State::Mark && incrementalState == State::Sweep) ||
- (initialState == State::Sweep && incrementalState == State::Compact))
- {
- incrementalLimit = zealFrequency / 2;
- }
- }
- } else if (hasZealMode(ZealMode::Compact)) {
- gc(GC_SHRINK, JS::gcreason::DEBUG_GC);
- } else {
- gc(GC_NORMAL, JS::gcreason::DEBUG_GC);
- }
-
-#endif
-}
-
-void
GCRuntime::setFullCompartmentChecks(bool enabled)
{
MOZ_ASSERT(!rt->isHeapMajorCollecting());
fullCompartmentChecks = enabled;
}
-#ifdef JS_GC_ZEAL
-bool
-GCRuntime::selectForMarking(JSObject* object)
-{
- MOZ_ASSERT(!rt->isHeapMajorCollecting());
- return selectedForMarking.append(object);
-}
-
-void
-GCRuntime::clearSelectedForMarking()
-{
- selectedForMarking.clearAndFree();
-}
-
-void
-GCRuntime::setDeterministic(bool enabled)
-{
- MOZ_ASSERT(!rt->isHeapMajorCollecting());
- deterministicOnly = enabled;
-}
-#endif
-
#ifdef DEBUG
/* Should only be called manually under gdb */
@@ -7337,7 +6682,7 @@ JS::IsIncrementalGCEnabled(JSContext* cx)
JS_PUBLIC_API(bool)
JS::IsIncrementalGCInProgress(JSContext* cx)
{
- return cx->gc.isIncrementalGCInProgress() && !cx->gc.isVerifyPreBarriersEnabled();
+ return cx->gc.isIncrementalGCInProgress();
}
JS_PUBLIC_API(bool)
diff --git a/js/src/jsgc.h b/js/src/jsgc.h
index 79ac9596c..7ad176d84 100644
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -1264,31 +1264,6 @@ enum VerifierType {
PreBarrierVerifier
};
-#ifdef JS_GC_ZEAL
-
-extern const char* ZealModeHelpText;
-
-/* Check that write barriers have been used correctly. See jsgc.cpp. */
-void
-VerifyBarriers(JSRuntime* rt, VerifierType type);
-
-void
-MaybeVerifyBarriers(JSContext* cx, bool always = false);
-
-#else
-
-static inline void
-VerifyBarriers(JSRuntime* rt, VerifierType type)
-{
-}
-
-static inline void
-MaybeVerifyBarriers(JSContext* cx, bool always = false)
-{
-}
-
-#endif
-
/*
* Instances of this class set the |JSRuntime::suppressGC| flag for the duration
* that they are live. Use of this class is highly discouraged. Please carefully
diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h
index 9cebb03a4..c6988d7af 100644
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -42,12 +42,6 @@ inline void
GCRuntime::poke()
{
poked = true;
-
-#ifdef JS_GC_ZEAL
- /* Schedule a GC to happen "soon" after a GC poke. */
- if (hasZealMode(ZealMode::Poke))
- nextScheduled = 1;
-#endif
}
class ArenaIter
diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h
index 309b9d746..20ea1ef8b 100644
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -22,7 +22,7 @@
#include "js/TraceKind.h"
#include "js/TypeDecls.h"
-#if defined(JS_GC_ZEAL) || defined(DEBUG)
+#if defined(DEBUG)
# define JSGC_HASH_TABLE_CHECKS
#endif
diff --git a/js/src/jsutil.h b/js/src/jsutil.h
index 790b97ddc..8ef4cac90 100644
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -368,7 +368,7 @@ Poison(void* ptr, uint8_t value, size_t num)
#endif
/* Enable poisoning in crash-diagnostics and zeal builds. */
-#if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL)
+#if defined(JS_CRASH_DIAGNOSTICS)
# define JS_POISON(p, val, size) Poison(p, val, size)
#else
# define JS_POISON(p, val, size) ((void) 0)
diff --git a/js/src/old-configure.in b/js/src/old-configure.in
index 1c5c9e214..e4589b951 100644
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -1806,17 +1806,6 @@ if test -n "$MOZ_DEBUG"; then
fi
dnl ========================================================
-dnl Zealous JavaScript GC
-dnl ========================================================
-MOZ_ARG_ENABLE_BOOL(gczeal,
-[ --enable-gczeal Enable zealous GCing],
- JS_GC_ZEAL=1,
- JS_GC_ZEAL= )
-if test -n "$JS_GC_ZEAL" -o -n "$MOZ_DEBUG"; then
- AC_DEFINE(JS_GC_ZEAL)
-fi
-
-dnl ========================================================
dnl Enable breakpoint for artificial OOMs
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(oom-breakpoint,
diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
index 00a4a503c..88d482a23 100644
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -323,10 +323,6 @@ static bool enableNativeRegExp = false;
static bool enableUnboxedArrays = false;
static bool enableSharedMemory = SHARED_MEMORY_DEFAULT;
static bool enableWasmAlwaysBaseline = false;
-#ifdef JS_GC_ZEAL
-static uint32_t gZealBits = 0;
-static uint32_t gZealFrequency = 0;
-#endif
static bool printTiming = false;
static const char* jsCacheDir = nullptr;
static const char* jsCacheAsmJSPath = nullptr;
@@ -7517,16 +7513,6 @@ SetContextOptions(JSContext* cx, const OptionParser& op)
dumpEntrainedVariables = op.getBoolOption("dump-entrained-variables");
#endif
-#ifdef JS_GC_ZEAL
- const char* zealStr = op.getStringOption("gc-zeal");
- if (zealStr) {
- if (!cx->gc.parseAndSetZeal(zealStr))
- return false;
- uint32_t nextScheduled;
- cx->gc.getZealBits(&gZealBits, &gZealFrequency, &nextScheduled);
- }
-#endif
-
return true;
}
@@ -7544,16 +7530,6 @@ SetWorkerContextOptions(JSContext* cx)
cx->setOffthreadIonCompilationEnabled(offthreadCompilation);
cx->profilingScripts = enableCodeCoverage || enableDisassemblyDumps;
-#ifdef JS_GC_ZEAL
- if (gZealBits && gZealFrequency) {
-#define ZEAL_MODE(_, value) \
- if (gZealBits & (1 << value)) \
- cx->gc.setZeal(value, gZealFrequency);
- JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE)
-#undef ZEAL_MODE
- }
-#endif
-
JS_SetNativeStackQuota(cx, gMaxStackSize);
}
@@ -7838,9 +7814,6 @@ main(int argc, char** argv, char** envp)
"NUMBER of instructions.", -1)
#endif
|| !op.addIntOption('\0', "nursery-size", "SIZE-MB", "Set the maximum nursery size in MB", 16)
-#ifdef JS_GC_ZEAL
- || !op.addStringOption('z', "gc-zeal", "LEVEL(;LEVEL)*[,N]", gc::ZealModeHelpText)
-#endif
|| !op.addStringOption('\0', "module-load-path", "DIR", "Set directory to load modules from")
)
{
diff --git a/js/src/tests/lib/progressbar.py b/js/src/tests/lib/progressbar.py
index 29361660d..da578783d 100644
--- a/js/src/tests/lib/progressbar.py
+++ b/js/src/tests/lib/progressbar.py
@@ -28,7 +28,7 @@ class ProgressBar(object):
# field in the counters map.
self.limit = limit # int: The value of 'current' equal to 100%.
self.limit_digits = int(math.ceil(math.log10(self.limit))) # int: max digits in limit
- self.t0 = datetime.now() # datetime: The start time.
+ self.t0 = datetime.utcnow() # datetime: The start time.
# Compute the width of the counters and build the format string.
self.counters_width = 1 # [
@@ -68,7 +68,7 @@ class ProgressBar(object):
sys.stdout.write(bar + '|')
# Update the bar.
- dt = datetime.now() - self.t0
+ dt = datetime.utcnow() - self.t0
dt = dt.seconds + dt.microseconds * 1e-6
sys.stdout.write('{:6.1f}s'.format(dt))
Terminal.clear_right()
diff --git a/js/src/tests/lib/tasks_unix.py b/js/src/tests/lib/tasks_unix.py
index 655033522..487c749ee 100644
--- a/js/src/tests/lib/tasks_unix.py
+++ b/js/src/tests/lib/tasks_unix.py
@@ -14,7 +14,7 @@ class Task(object):
self.pid = pid
self.stdout = stdout
self.stderr = stderr
- self.start = datetime.now()
+ self.start = datetime.utcnow()
self.out = []
self.err = []
@@ -59,7 +59,7 @@ def get_max_wait(tasks, timeout):
# If a timeout is supplied, we need to wake up for the first task to
# timeout if that is sooner.
if timeout:
- now = datetime.now()
+ now = datetime.utcnow()
timeout_delta = timedelta(seconds=timeout)
for task in tasks:
remaining = task.start + timeout_delta - now
@@ -136,7 +136,7 @@ def timed_out(task, timeout):
timed_out always returns False).
"""
if timeout:
- now = datetime.now()
+ now = datetime.utcnow()
return (now - task.start) > timedelta(seconds=timeout)
return False
@@ -175,7 +175,7 @@ def reap_zombies(tasks, timeout):
''.join(ended.out),
''.join(ended.err),
returncode,
- (datetime.now() - ended.start).total_seconds(),
+ (datetime.utcnow() - ended.start).total_seconds(),
timed_out(ended, timeout)))
return tasks, finished
diff --git a/js/src/tests/lib/tasks_win.py b/js/src/tests/lib/tasks_win.py
index 7a4540c60..a99640abb 100644
--- a/js/src/tests/lib/tasks_win.py
+++ b/js/src/tests/lib/tasks_win.py
@@ -36,7 +36,7 @@ def _do_work(qTasks, qResults, qWatch, prefix, run_skipped, timeout, show_cmd):
cmd = test.get_command(prefix)
if show_cmd:
print(escape_cmdline(cmd))
- tStart = datetime.now()
+ tStart = datetime.utcnow()
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
@@ -49,7 +49,7 @@ def _do_work(qTasks, qResults, qWatch, prefix, run_skipped, timeout, show_cmd):
qWatch.put(TaskFinishedMarker)
# Create a result record and forward to result processing.
- dt = datetime.now() - tStart
+ dt = datetime.utcnow() - tStart
result = TestOutput(test, cmd, out, err, proc.returncode, dt.total_seconds(),
dt > timedelta(seconds=timeout))
qResults.put(result)
diff --git a/js/src/tests/shell.js b/js/src/tests/shell.js
index 36dbc79da..c7a57953e 100644
--- a/js/src/tests/shell.js
+++ b/js/src/tests/shell.js
@@ -32,8 +32,6 @@
// Certain cached functionality only exists (and is only needed) when
// running in the browser. Segregate that caching here.
- var SpecialPowersSetGCZeal =
- global.SpecialPowers ? global.SpecialPowers.setGCZeal : undefined;
}
var runningInShell = typeof window === "undefined";
@@ -205,19 +203,6 @@
global.quit = quit;
}
- var gczeal = global.gczeal;
- if (typeof gczeal !== "function") {
- if (typeof SpecialPowersSetGCZeal === "function") {
- gczeal = function gczeal(z) {
- SpecialPowersSetGCZeal(z);
- };
- } else {
- gczeal = function() {}; // no-op if not available
- }
-
- global.gczeal = gczeal;
- }
-
/******************************************************
* TEST METADATA EXPORTS (these are of dubious value) *
******************************************************/
diff --git a/js/src/vm/Caches-inl.h b/js/src/vm/Caches-inl.h
index 4eb8ecaa6..56e69a0d9 100644
--- a/js/src/vm/Caches-inl.h
+++ b/js/src/vm/Caches-inl.h
@@ -57,9 +57,6 @@ NewObjectCache::newObjectFromHit(JSContext* cx, EntryIndex entryIndex, gc::Initi
if (group->shouldPreTenure())
heap = gc::TenuredHeap;
- if (cx->runtime()->gc.upcomingZealousGC())
- return nullptr;
-
NativeObject* obj = static_cast<NativeObject*>(Allocate<JSObject, NoGC>(cx, entry->kind, 0,
heap, group->clasp()));
if (!obj)
diff --git a/js/src/vm/EnvironmentObject.h b/js/src/vm/EnvironmentObject.h
index 6bdaac89e..d457ca839 100644
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -930,9 +930,6 @@ class DebugEnvironments
void mark(JSTracer* trc);
void sweep(JSRuntime* rt);
void finish();
-#ifdef JS_GC_ZEAL
- void checkHashTablesAfterMovingGC(JSRuntime* rt);
-#endif
// If a live frame has a synthesized entry in missingEnvs, make sure it's not
// collected.
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index 3ca379d01..fbf526ae5 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1647,7 +1647,6 @@ Interpret(JSContext* cx, RunState& state)
#define ADVANCE_AND_DISPATCH(N) \
JS_BEGIN_MACRO \
REGS.pc += (N); \
- SANITY_CHECKS(); \
DISPATCH_TO(*REGS.pc | activation.opMask()); \
JS_END_MACRO
@@ -1727,12 +1726,6 @@ Interpret(JSContext* cx, RunState& state)
activation.enableInterruptsUnconditionally(); \
JS_END_MACRO
-#define SANITY_CHECKS() \
- JS_BEGIN_MACRO \
- js::gc::MaybeVerifyBarriers(cx); \
- JS_END_MACRO
-
- gc::MaybeVerifyBarriers(cx, true);
MOZ_ASSERT(!cx->zone()->types.activeAnalysis);
InterpreterFrame* entryFrame = state.pushInterpreterFrame(cx);
@@ -1863,7 +1856,6 @@ CASE(EnableInterruptsPseudoOpcode)
activation.clearInterruptsMask();
/* Commence executing the actual opcode. */
- SANITY_CHECKS();
DISPATCH_TO(op);
}
@@ -4184,8 +4176,6 @@ DEFAULT()
REGS.fp()->epilogue(cx, REGS.pc);
}
- gc::MaybeVerifyBarriers(cx, true);
-
TraceLogStopEvent(logger, TraceLogger_Engine);
TraceLogStopEvent(logger, scriptEvent);
diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp
index 646d48299..0d6a3922c 100644
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -868,8 +868,7 @@ bool
JSRuntime::activeGCInAtomsZone()
{
Zone* zone = atomsCompartment_->zone();
- return (zone->needsIncrementalBarrier() && !gc.isVerifyPreBarriersEnabled()) ||
- zone->wasGCStarted();
+ return zone->needsIncrementalBarrier() || zone->wasGCStarted();
}
void
diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h
index 4f7755b9d..734543c4e 100644
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -866,8 +866,6 @@ struct JSRuntime : public JS::shadow::Runtime,
/* Garbage collector state has been successfully initialized. */
bool gcInitialized;
- bool hasZealMode(js::gc::ZealMode mode) { return gc.hasZealMode(mode); }
-
void lockGC() {
gc.lockGC();
}
diff --git a/js/xpconnect/idl/xpccomponents.idl b/js/xpconnect/idl/xpccomponents.idl
index 711ea4c64..611091c4b 100644
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -123,7 +123,7 @@ interface ScheduledGCCallback : nsISupports
/**
* interface of Components.utils
*/
-[scriptable, uuid(86003fe3-ee9a-4620-91dc-eef8b1e58815)]
+[scriptable, uuid(a6e66965-4b9a-4846-8985-985e71aaf549)]
interface nsIXPCComponents_Utils : nsISupports
{
@@ -530,9 +530,6 @@ interface nsIXPCComponents_Utils : nsISupports
attribute boolean ion;
[implicit_jscontext]
- void setGCZeal(in long zeal);
-
- [implicit_jscontext]
void nukeSandbox(in jsval obj);
/*
diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
index ca78234c9..dbb63092e 100644
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3005,15 +3005,6 @@ GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Ion, ion, setIon)
#undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER
NS_IMETHODIMP
-nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx)
-{
-#ifdef JS_GC_ZEAL
- JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
-#endif
- return NS_OK;
-}
-
-NS_IMETHODIMP
nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext* cx)
{
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::JS);
diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp
index 6981b525c..defd1b785 100644
--- a/js/xpconnect/src/XPCJSContext.cpp
+++ b/js/xpconnect/src/XPCJSContext.cpp
@@ -1473,16 +1473,6 @@ ReloadPrefsCallback(const char* pref, void* data)
sExtraWarningsForSystemJS = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict.debug");
#endif
-#ifdef JS_GC_ZEAL
- int32_t zeal = Preferences::GetInt(JS_OPTIONS_DOT_STR "gczeal", -1);
- int32_t zeal_frequency =
- Preferences::GetInt(JS_OPTIONS_DOT_STR "gczeal.frequency",
- JS_DEFAULT_ZEAL_FREQ);
- if (zeal >= 0) {
- JS_SetGCZeal(cx, (uint8_t)zeal, zeal_frequency);
- }
-#endif // JS_GC_ZEAL
-
JS::ContextOptionsRef(cx).setBaseline(useBaseline)
.setIon(useIon)
.setAsmJS(useAsmJS)
diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp
index d86b5c5d3..d9629bfed 100644
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -440,21 +440,6 @@ GC(JSContext* cx, unsigned argc, Value* vp)
return true;
}
-#ifdef JS_GC_ZEAL
-static bool
-GCZeal(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
- uint32_t zeal;
- if (!ToUint32(cx, args.get(0), &zeal))
- return false;
-
- JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ);
- args.rval().setUndefined();
- return true;
-}
-#endif
-
static bool
SendCommand(JSContext* cx, unsigned argc, Value* vp)
{
@@ -652,9 +637,6 @@ static const JSFunctionSpec glob_functions[] = {
JS_FS("dumpXPC", DumpXPC, 1,0),
JS_FS("dump", Dump, 1,0),
JS_FS("gc", GC, 0,0),
-#ifdef JS_GC_ZEAL
- JS_FS("gczeal", GCZeal, 1,0),
-#endif
JS_FS("options", Options, 0,0),
JS_FS("sendCommand", SendCommand, 1,0),
JS_FS("atob", xpc::Atob, 1,0),
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 1c6d97395..054632ad7 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2268,14 +2268,8 @@ ComputeRadialGradientLine(nsPresContext* aPresContext,
*aLineEnd = *aLineStart + gfxPoint(radiusX*cos(-angle), radiusY*sin(-angle));
}
-
-static float Interpolate(float aF1, float aF2, float aFrac)
-{
- return aF1 + aFrac * (aF2 - aF1);
-}
-
// Returns aFrac*aC2 + (1 - aFrac)*C1. The interpolation is done
-// in unpremultiplied space, which is what SVG gradients and cairo
+// in RGBA color space, which is what SVG gradients and cairo
// gradients expect.
static Color
InterpolateColor(const Color& aC1, const Color& aC2, float aFrac)
@@ -2435,79 +2429,6 @@ static void ResolveMidpoints(nsTArray<ColorStop>& stops)
}
}
-static Color
-Premultiply(const Color& aColor)
-{
- gfx::Float a = aColor.a;
- return Color(aColor.r * a, aColor.g * a, aColor.b * a, a);
-}
-
-static Color
-Unpremultiply(const Color& aColor)
-{
- gfx::Float a = aColor.a;
- return (a > 0.f)
- ? Color(aColor.r / a, aColor.g / a, aColor.b / a, a)
- : aColor;
-}
-
-static Color
-TransparentColor(Color aColor) {
- aColor.a = 0;
- return aColor;
-}
-
-// Adjusts and adds color stops in such a way that drawing the gradient with
-// unpremultiplied interpolation looks nearly the same as if it were drawn with
-// premultiplied interpolation.
-static const float kAlphaIncrementPerGradientStep = 0.1f;
-static void
-ResolvePremultipliedAlpha(nsTArray<ColorStop>& aStops)
-{
- for (size_t x = 1; x < aStops.Length(); x++) {
- const ColorStop leftStop = aStops[x - 1];
- const ColorStop rightStop = aStops[x];
-
- // if the left and right stop have the same alpha value, we don't need
- // to do anything
- if (leftStop.mColor.a == rightStop.mColor.a) {
- continue;
- }
-
- // Is the stop on the left 100% transparent? If so, have it adopt the color
- // of the right stop
- if (leftStop.mColor.a == 0) {
- aStops[x - 1].mColor = TransparentColor(rightStop.mColor);
- continue;
- }
-
- // Is the stop on the right completely transparent?
- // If so, duplicate it and assign it the color on the left.
- if (rightStop.mColor.a == 0) {
- ColorStop newStop = rightStop;
- newStop.mColor = TransparentColor(leftStop.mColor);
- aStops.InsertElementAt(x, newStop);
- x++;
- continue;
- }
-
- // Now handle cases where one or both of the stops are partially transparent.
- if (leftStop.mColor.a != 1.0f || rightStop.mColor.a != 1.0f) {
- Color premulLeftColor = Premultiply(leftStop.mColor);
- Color premulRightColor = Premultiply(rightStop.mColor);
- // Calculate how many extra steps. We do a step per 10% transparency.
- size_t stepCount = NSToIntFloor(fabsf(leftStop.mColor.a - rightStop.mColor.a) / kAlphaIncrementPerGradientStep);
- for (size_t y = 1; y < stepCount; y++) {
- float frac = static_cast<float>(y) / stepCount;
- ColorStop newStop(Interpolate(leftStop.mPosition, rightStop.mPosition, frac), false,
- Unpremultiply(InterpolateColor(premulLeftColor, premulRightColor, frac)));
- aStops.InsertElementAt(x, newStop);
- x++;
- }
- }
- }
-}
-
static ColorStop
InterpolateColorStop(const ColorStop& aFirst, const ColorStop& aSecond,
double aPosition, const Color& aDefault)
@@ -2522,9 +2443,9 @@ InterpolateColorStop(const ColorStop& aFirst, const ColorStop& aSecond,
}
return ColorStop(aPosition, false,
- Unpremultiply(InterpolateColor(Premultiply(aFirst.mColor),
- Premultiply(aSecond.mColor),
- (aPosition - aFirst.mPosition) / delta)));
+ InterpolateColor(aFirst.mColor,
+ aSecond.mColor,
+ (aPosition - aFirst.mPosition) / delta));
}
// Clamp and extend the given ColorStop array in-place to fit exactly into the
@@ -2749,6 +2670,44 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
lineLength = rectLen;
}
+ // Special case for 'transparent'
+ for (uint32_t i = 0; i < stops.Length(); ++i) {
+ Color color = stops[i].mColor;
+ if (color.r == 0 && color.g == 0 && color.b == 0 && color.a == 0) {
+ // We have (0,0,0,0) as a color stop - this means 'transparent'.
+ // In this case for the usually intended effect, we change the color
+ // of the transparent stop to the color of the adjacent stop with
+ // 0 opacity. If we are not on either edge, we add a stop on both
+ // sides of the transparent point with the adjacent color value.
+ // i.e.: c1 -> c1 (alpha 0) | c2 (alpha 0) -> c2
+ // XXX: We should probably track the use of the transparent keyword
+ // down from the CSS parsing level to here with a flag in mStops, if
+ // rgba(0,0,0,0) ever is an intended thing (very much a corner case).
+ if (i > 0) {
+ // Change stop color to adjacent-previous (color->T)
+ color = stops[i - 1].mColor;
+ color.a = 0;
+ stops[i].mColor = color;
+ if (i < stops.Length() - 1) {
+ // We're in the middle somewhere: insert stop adjacent-next (T->color)
+ Color color2 = stops[i + 1].mColor;
+ color2.a = 0;
+ if (color != color2) {
+ // Only insert an extra stop if c1 is different than c2 in c1->T->c2
+ // Note: A transparent stop is never considered an interpolation hint
+ stops.InsertElementAt(i + 1, ColorStop(stops[i].mPosition, false, color2));
+ i++;
+ }
+ }
+ } else if (i < stops.Length() - 1) {
+ // Change stop color to adjacent-next (T->color)
+ color = stops[i + 1].mColor;
+ color.a = 0;
+ stops[i].mColor = color;
+ }
+ }
+ }
+
// Eliminate negative-position stops if the gradient is radial.
double firstStop = stops[0].mPosition;
if (aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR && firstStop < 0.0) {
@@ -2924,7 +2883,6 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
}
ResolveMidpoints(stops);
- ResolvePremultipliedAlpha(stops);
bool isRepeat = aGradient->mRepeating || forceRepeatToCoverTiles;
diff --git a/layout/reftests/css-gradients/linear-premul-ref.html b/layout/reftests/css-gradients/linear-premul-ref.html
deleted file mode 100644
index bf0b12c33..000000000
--- a/layout/reftests/css-gradients/linear-premul-ref.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: linear-gradient(to right, rgba(255, 0, 0, .9) 0% , rgba(255, 0, 0, 0) 50%, rgba(0, 0, 255, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/linear-premul.html b/layout/reftests/css-gradients/linear-premul.html
deleted file mode 100644
index 20c7c276a..000000000
--- a/layout/reftests/css-gradients/linear-premul.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: linear-gradient(to right, rgba(255, 0, 0, .9) 0% , rgba(0, 255, 0, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/radial-premul-ref.html b/layout/reftests/css-gradients/radial-premul-ref.html
deleted file mode 100644
index 1424f4373..000000000
--- a/layout/reftests/css-gradients/radial-premul-ref.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: radial-gradient(rgba(255, 0, 0, .9) 0% , rgba(255, 0, 0, 0) 50%, rgba(0, 0, 255, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/radial-premul.html b/layout/reftests/css-gradients/radial-premul.html
deleted file mode 100644
index 33b89c72b..000000000
--- a/layout/reftests/css-gradients/radial-premul.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: radial-gradient(rgba(255, 0, 0, .9) 0% , rgba(0, 255, 0, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/reftest.list b/layout/reftests/css-gradients/reftest.list
index a93070752..729bc6058 100644
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -16,7 +16,6 @@ fuzzy-if(!contentSameGfxBackendAsCanvas,4,92400) fuzzy-if(azureSkiaGL||skiaConte
== linear-diagonal-4a.html linear-diagonal-4-ref.html
== linear-diagonal-4b.html linear-diagonal-4-ref.html
== linear-diagonal-4c.html linear-diagonal-4-ref.html
-== linear-premul.html linear-premul-ref.html
# these tests uses a similar gradient over different bounds. It's perfectly
# reasonable to expect implementations to give slightly different results
@@ -92,7 +91,6 @@ fuzzy-if(Android,4,248) == radial-zero-length-1g.html radial-zero-length-1-ref.h
fuzzy-if(Android,4,248) == radial-zero-length-1h.html radial-zero-length-1-ref.html
fuzzy-if(Android,4,248) == radial-zero-length-1i.html radial-zero-length-1-ref.html
fuzzy-if(Android,4,248) == radial-zero-length-1j.html radial-zero-length-1-ref.html
-== radial-premul.html radial-premul-ref.html
== repeated-final-stop-1.html repeated-final-stop-1-ref.html
== repeating-linear-1a.html repeating-linear-1-ref.html
== repeating-linear-1b.html repeating-linear-1-ref.html
diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h
index 657ef663e..eaf8d966b 100644
--- a/layout/style/nsCSSPseudoElements.h
+++ b/layout/style/nsCSSPseudoElements.h
@@ -111,8 +111,7 @@ private:
// which is a general gcc bug that we seem to have hit only on Android/x86.
#if defined(ANDROID) && defined(__i386__) && defined(__GNUC__) && \
!defined(__clang__)
-#if (MOZ_GCC_VERSION_AT_LEAST(4,8,0) && MOZ_GCC_VERSION_AT_MOST(4,8,4)) || \
- (MOZ_GCC_VERSION_AT_LEAST(4,9,0) && MOZ_GCC_VERSION_AT_MOST(4,9,2))
+#if (MOZ_GCC_VERSION_AT_LEAST(4,9,0) && MOZ_GCC_VERSION_AT_MOST(4,9,2))
__attribute__((noinline))
#endif
#endif
diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp
index 683f10bc7..aeadccbc5 100644
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -979,21 +979,43 @@ nsSVGOuterSVGAnonChildFrame::GetType() const
}
bool
-nsSVGOuterSVGAnonChildFrame::HasChildrenOnlyTransform(gfx::Matrix *aTransform) const
+nsSVGOuterSVGAnonChildFrame::IsSVGTransformed(Matrix* aOwnTransform,
+ Matrix* aFromParentTransform) const
{
- // We must claim our nsSVGOuterSVGFrame's children-only transforms as our own
- // so that the children we are used to wrap are transformed properly.
+ // Our elements 'transform' attribute is applied to our nsSVGOuterSVGFrame
+ // parent, and the element's children-only transforms are applied to us, the
+ // anonymous child frame. Since we are the child frame, we apply the
+ // children-only transforms as if they are our own transform.
- SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
+ SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
+
+ if (!content->HasChildrenOnlyTransform()) {
+ return false;
+ }
+
+ // Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
+ gfxMatrix ownMatrix =
+ content->PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace);
- bool hasTransform = content->HasChildrenOnlyTransform();
+ if (ownMatrix.IsIdentity()) {
+ return false;
+ }
+
+ if (aOwnTransform) {
+ if (ownMatrix.HasNonTranslation()) {
+ // Note: viewBox, currentScale and currentTranslate should only
+ // produce a rectilinear transform.
+ // The nsDisplayTransform code will apply this transform to our frame,
+ // including to our frame position. We don't want our frame position to
+ // be scaled though, so we need to correct for that in the transform.
+ CSSPoint pos = CSSPixel::FromAppUnits(GetPosition());
+ CSSPoint scaledPos = CSSPoint(ownMatrix._11 * pos.x, ownMatrix._22 * pos.y);
+ CSSPoint deltaPos = scaledPos - pos;
+ ownMatrix *= gfxMatrix::Translation(-deltaPos.x, -deltaPos.y);
+ }
- if (hasTransform && aTransform) {
- // Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
- gfxMatrix identity;
- *aTransform = gfx::ToMatrix(
- content->PrependLocalTransformsTo(identity, eChildToUserSpace));
+ *aOwnTransform = gfx::ToMatrix(ownMatrix);
}
- return hasTransform;
+ return true;
}
diff --git a/layout/svg/nsSVGOuterSVGFrame.h b/layout/svg/nsSVGOuterSVGFrame.h
index a08593678..6d29234ac 100644
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -263,6 +263,9 @@ public:
*/
virtual nsIAtom* GetType() const override;
+ bool IsSVGTransformed(Matrix *aOwnTransform,
+ Matrix *aFromParentTransform) const override;
+
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override {
// GetCanvasTM returns the transform from an SVG frame to the frame's
@@ -270,8 +273,6 @@ public:
// set on us for any CSS border or padding on our nsSVGOuterSVGFrame.
return static_cast<nsSVGOuterSVGFrame*>(GetParent())->GetCanvasTM();
}
-
- virtual bool HasChildrenOnlyTransform(Matrix *aTransform) const override;
};
#endif
diff --git a/media/libwebp/AUTHORS b/media/libwebp/AUTHORS
new file mode 100644
index 000000000..b6e9cfb89
--- /dev/null
+++ b/media/libwebp/AUTHORS
@@ -0,0 +1,38 @@
+Contributors:
+- Charles Munger (clm at google dot com)
+- Christian Duvivier (cduvivier at google dot com)
+- Djordje Pesut (djordje dot pesut at imgtec dot com)
+- Hui Su (huisu at google dot com)
+- James Zern (jzern at google dot com)
+- Jan Engelhardt (jengelh at medozas dot de)
+- Jehan (jehan at girinstud dot io)
+- Johann (johann dot koenig at duck dot com)
+- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
+- Jyrki Alakuijala (jyrki at google dot com)
+- Lode Vandevenne (lode at google dot com)
+- Lou Quillio (louquillio at google dot com)
+- Mans Rullgard (mans at mansr dot com)
+- Marcin Kowalczyk (qrczak at google dot com)
+- Martin Olsson (mnemo at minimum dot se)
+- Mikołaj Zalewski (mikolajz at google dot com)
+- Mislav Bradac (mislavm at google dot com)
+- Nico Weber (thakis at chromium dot org)
+- Noel Chromium (noel at chromium dot org)
+- Owen Rodley (orodley at google dot com)
+- Parag Salasakar (img dot mips1 at gmail dot com)
+- Pascal Massimino (pascal dot massimino at gmail dot com)
+- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
+- Pierre Joye (pierre dot php at gmail dot com)
+- Sam Clegg (sbc at chromium dot org)
+- Scott Hancher (seh at google dot com)
+- Scott LaVarnway (slavarnway at google dot com)
+- Scott Talbot (s at chikachow dot org)
+- Slobodan Prijic (slobodan dot prijic at imgtec dot com)
+- Somnath Banerjee (somnath dot banerjee at gmail dot com)
+- Sriraman Tallam (tmsriram at google dot com)
+- Tamar Levy (tamar dot levy at intel dot com)
+- Timothy Gu (timothygu99 at gmail dot com)
+- Urvang Joshi (urvang at google dot com)
+- Vikas Arora (vikasa at google dot com)
+- Vincent Rabaud (vrabaud at google dot com)
+- Yang Zhang (yang dot zhang at arm dot com)
diff --git a/media/libwebp/COPYING b/media/libwebp/COPYING
new file mode 100644
index 000000000..7a6f99547
--- /dev/null
+++ b/media/libwebp/COPYING
@@ -0,0 +1,30 @@
+Copyright (c) 2010, Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Google nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/media/libwebp/MOZCHANGES b/media/libwebp/MOZCHANGES
new file mode 100644
index 000000000..68937eea6
--- /dev/null
+++ b/media/libwebp/MOZCHANGES
@@ -0,0 +1,3 @@
+Changes made to pristine libwebp source by mozilla.org developers.
+
+2017/01/27 -- Synced with libwebp-0.6.0 (bug #1294490).
diff --git a/media/libwebp/NEWS b/media/libwebp/NEWS
new file mode 100644
index 000000000..3bf4bd052
--- /dev/null
+++ b/media/libwebp/NEWS
@@ -0,0 +1,176 @@
+- 1/26/2017: version 0.6.0
+ * lossless performance and compression improvements
+ * miscellaneous performance improvements (SSE2, NEON, MSA)
+ * webpmux gained a -duration option allowing for frame timing modification
+ * new img2webp utility allowing a sequence of images to be converted to
+ animated webp
+ * API changes:
+ - libwebp:
+ WebPPictureSharpARGBToYUVA
+ WebPPlaneDistortion
+ - libwebpmux / gif2webp:
+ WebPAnimEncoderOptions: kmax <= 0 now disables keyframes, kmax == 1
+ forces all keyframes. See mux.h and the gif2webp
+ manpage for details.
+
+- 12/13/2016: version 0.5.2
+ This is a binary compatible release.
+ This release covers CVE-2016-8888 and CVE-2016-9085.
+ * further security related hardening in the tools; fixes to
+ gif2webp/AnimEncoder (issues #310, #314, #316, #322), cwebp/libwebp (issue
+ #312)
+ * full libwebp (encoder & decoder) iOS framework; libwebpdecoder
+ WebP.framework renamed to WebPDecoder.framework (issue #307)
+ * CMake support for Android Studio (2.2)
+ * miscellaneous build related fixes (issue #306, #313)
+ * miscellaneous documentation improvements (issue #225)
+ * minor lossy encoder fixes and improvements
+
+- 6/14/2016: version 0.5.1
+ This is a binary compatible release.
+ * miscellaneous bug fixes (issues #280, #289)
+ * reverted alpha plane encoding with color cache for compatibility with
+ libwebp 0.4.0->0.4.3 (issues #291, #298)
+ * lossless encoding performance improvements
+ * memory reduction in both lossless encoding and decoding
+ * force mux output to be in the extended format (VP8X) when undefined chunks
+ are present (issue #294)
+ * gradle, cmake build support
+ * workaround for compiler bug causing 64-bit decode failures on android
+ devices using clang-3.8 in the r11c NDK
+ * various WebPAnimEncoder improvements
+
+- 12/17/2015: version 0.5.0
+ * miscellaneous bug & build fixes (issues #234, #258, #274, #275, #278)
+ * encoder & decoder speed-ups on x86/ARM/MIPS for lossy & lossless
+ - note! YUV->RGB conversion was sped-up, but the results will be slightly
+ different from previous releases
+ * various lossless encoder improvements
+ * gif2webp improvements, -min_size option added
+ * tools fully support input from stdin and output to stdout (issue #168)
+ * New WebPAnimEncoder API for creating animations
+ * New WebPAnimDecoder API for decoding animations
+ * other API changes:
+ - libwebp:
+ WebPPictureSmartARGBToYUVA() (-pre 4 in cwebp)
+ WebPConfig::exact (-exact in cwebp; -alpha_cleanup is now the default)
+ WebPConfig::near_lossless (-near_lossless in cwebp)
+ WebPFree() (free'ing webp allocated memory in other languages)
+ WebPConfigLosslessPreset()
+ WebPMemoryWriterClear()
+ - libwebpdemux: removed experimental fragment related fields and functions
+ - libwebpmux: WebPMuxSetCanvasSize()
+ * new libwebpextras library with some uncommon import functions:
+ WebPImportGray/WebPImportRGB565/WebPImportRGB4444
+
+- 10/15/15: version 0.4.4
+ This is a binary compatible release.
+ * rescaling out-of-bounds read fix (issue #254)
+ * various build fixes and improvements (issues #253, #259, #262, #267, #268)
+ * container documentation update
+ * gif2webp transparency fix (issue #245)
+
+- 3/3/15: version 0.4.3
+ This is a binary compatible release.
+ * Android / gcc / iOS / MSVS build fixes and improvements
+ * lossless decode fix (issue #239 -- since 0.4.0)
+ * documentation / vwebp updates for animation
+ * multi-threading fix (issue #234)
+
+- 10/13/14: version 0.4.2
+ This is a binary compatible release.
+ * Android / gcc build fixes
+ * (Windows) fix reading from stdin and writing to stdout
+ * gif2webp: miscellaneous fixes
+ * fix 'alpha-leak' with lossy compression (issue #220)
+ * the lossless bitstream spec has been amended to reflect the current code
+
+- 7/24/14: version 0.4.1
+ This is a binary compatible release.
+ * AArch64 (arm64) & MIPS support/optimizations
+ * NEON assembly additions:
+ - ~25% faster lossy decode / encode (-m 4)
+ - ~10% faster lossless decode
+ - ~5-10% faster lossless encode (-m 3/4)
+ * dwebp/vwebp can read from stdin
+ * cwebp/gif2webp can write to stdout
+ * cwebp can read webp files; useful if storing sources as webp lossless
+
+- 12/19/13: version 0.4.0
+ * improved gif2webp tool
+ * numerous fixes, compression improvement and speed-up
+ * dither option added to decoder (dwebp -dither 50 ...)
+ * improved multi-threaded modes (-mt option)
+ * improved filtering strength determination
+ * New function: WebPMuxGetCanvasSize
+ * BMP and TIFF format output added to 'dwebp'
+ * Significant memory reduction for decoding lossy images with alpha.
+ * Intertwined decoding of RGB and alpha for a shorter
+ time-to-first-decoded-pixel.
+ * WebPIterator has a new member 'has_alpha' denoting whether the frame
+ contains transparency.
+ * Container spec amended with new 'blending method' for animation.
+
+- 6/13/13: version 0.3.1
+ This is a binary compatible release.
+ * Add incremental decoding support for images containing ALPH and ICCP chunks.
+ * Python bindings via swig for the simple encode/decode interfaces similar to
+ Java.
+
+- 3/20/13: version 0.3.0
+ This is a binary compatible release.
+ * WebPINewRGB/WebPINewYUVA accept being passed a NULL output buffer
+ and will perform auto-allocation.
+ * default filter option is now '-strong -f 60'
+ * encoding speed-up for lossy methods 3 to 6
+ * alpha encoding can be done in parallel to lossy using 'cwebp -mt ...'
+ * color profile, metadata (XMP/EXIF) and animation support finalized in the
+ container.
+ * various NEON assembly additions
+ Tool updates / additions:
+ * gif2webp added
+ * vwebp given color profile & animation support
+ * cwebp can preserve color profile / metadata with '-metadata'
+
+- 10/30/12: version 0.2.1
+ * Various security related fixes
+ * cwebp.exe: fix import errors on Windows XP
+ * enable DLL builds for mingw targets
+
+- 8/3/12: version 0.2.0
+ * Add support for ARGB -> YUVA conversion for lossless decoder
+ New functions: WebPINewYUVA, WebPIDecGetYUVA
+ * Add stats for lossless and alpha encoding
+ * Security related hardening: allocation and size checks
+ * Add PAM output support to dwebp
+
+- 7/19/12: version 0.1.99
+ * This is a pre-release of 0.2.0, not an rc to allow for further
+ incompatible changes based on user feedback.
+ * Alpha channel encode/decode support.
+ * Lossless encoder/decoder.
+ * Add TIFF input support to cwebp.
+ Incompatible changes:
+ * The encode ABI has been modified to support alpha encoding.
+ * Deprecated function WebPINew() has been removed.
+ * Decode function signatures have changed to consistently use size_t over
+ int/uint32_t.
+ * decode_vp8.h is no longer installed system-wide.
+ * cwebp will encode the alpha channel if present.
+
+- 9/19/11: version 0.1.3
+ * Advanced decoding APIs.
+ * On-the-fly cropping and rescaling of images.
+ * SSE2 instructions for decoding performance optimizations on x86 based
+ platforms.
+ * Support Multi-threaded decoding.
+ * 40% improvement in Decoding performance.
+ * Add support for RGB565, RGBA4444 & ARGB image colorspace.
+ * Better handling of large picture encoding.
+
+- 3/25/11: version 0.1.2
+ * Incremental decoding: picture can be decoded byte-by-byte if needs be.
+ * lot of bug-fixes, consolidation and stabilization
+
+- 2/23/11: initial release of version 0.1, with the new encoder
+- 9/30/10: initial release version with only the lightweight decoder
diff --git a/media/libwebp/PATENTS b/media/libwebp/PATENTS
new file mode 100644
index 000000000..caedf607e
--- /dev/null
+++ b/media/libwebp/PATENTS
@@ -0,0 +1,23 @@
+Additional IP Rights Grant (Patents)
+------------------------------------
+
+"These implementations" means the copyrightable works that implement the WebM
+codecs distributed by Google as part of the WebM Project.
+
+Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent license to
+make, have made, use, offer to sell, sell, import, transfer, and otherwise
+run, modify and propagate the contents of these implementations of WebM, where
+such license applies only to those patent claims, both currently owned by
+Google and acquired in the future, licensable by Google that are necessarily
+infringed by these implementations of WebM. This grant does not include claims
+that would be infringed only as a consequence of further modification of these
+implementations. If you or your agent or exclusive licensee institute or order
+or agree to the institution of patent litigation or any other patent
+enforcement activity against any entity (including a cross-claim or
+counterclaim in a lawsuit) alleging that any of these implementations of WebM
+or any code incorporated within any of these implementations of WebM
+constitute direct or contributory patent infringement, or inducement of
+patent infringement, then any patent rights granted to you under this License
+for these implementations of WebM shall terminate as of the date such
+litigation is filed.
diff --git a/media/libwebp/README b/media/libwebp/README
new file mode 100644
index 000000000..4c15c4ad8
--- /dev/null
+++ b/media/libwebp/README
@@ -0,0 +1,750 @@
+ __ __ ____ ____ ____
+ / \\/ \/ _ \/ _ )/ _ \
+ \ / __/ _ \ __/
+ \__\__/\____/\_____/__/ ____ ___
+ / _/ / \ \ / _ \/ _/
+ / \_/ / / \ \ __/ \__
+ \____/____/\_____/_____/____/v0.6.0
+
+Description:
+============
+
+WebP codec: library to encode and decode images in WebP format. This package
+contains the library that can be used in other programs to add WebP support,
+as well as the command line tools 'cwebp' and 'dwebp'.
+
+See http://developers.google.com/speed/webp
+
+The latest source tree is available at
+https://chromium.googlesource.com/webm/libwebp
+
+It is released under the same license as the WebM project.
+See http://www.webmproject.org/license/software/ or the
+"COPYING" file for details. An additional intellectual
+property rights grant can be found in the file PATENTS.
+
+Building:
+=========
+
+Windows build:
+--------------
+
+By running:
+
+ nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
+
+the directory output\release-static\(x64|x86)\bin will contain the tools
+cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will
+contain the libwebp static library.
+The target architecture (x86/x64) is detected by Makefile.vc from the Visual
+Studio compiler (cl.exe) available in the system path.
+
+Unix build using makefile.unix:
+-------------------------------
+
+On platforms with GNU tools installed (gcc and make), running
+
+ make -f makefile.unix
+
+will build the binaries examples/cwebp and examples/dwebp, along
+with the static library src/libwebp.a. No system-wide installation
+is supplied, as this is a simple alternative to the full installation
+system based on the autoconf tools (see below).
+Please refer to makefile.unix for additional details and customizations.
+
+Using autoconf tools:
+---------------------
+Prerequisites:
+A compiler (e.g., gcc), make, autoconf, automake, libtool.
+On a Debian-like system the following should install everything you need for a
+minimal build:
+$ sudo apt-get install gcc make autoconf automake libtool
+
+When building from git sources, you will need to run autogen.sh to generate the
+configure script.
+
+./configure
+make
+make install
+
+should be all you need to have the following files
+
+/usr/local/include/webp/decode.h
+/usr/local/include/webp/encode.h
+/usr/local/include/webp/types.h
+/usr/local/lib/libwebp.*
+/usr/local/bin/cwebp
+/usr/local/bin/dwebp
+
+installed.
+
+Note: A decode-only library, libwebpdecoder, is available using the
+'--enable-libwebpdecoder' flag. The encode library is built separately and can
+be installed independently using a minor modification in the corresponding
+Makefile.am configure files (see comments there). See './configure --help' for
+more options.
+
+Building for MIPS Linux:
+------------------------
+MIPS Linux toolchain stable available releases can be found at:
+https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
+
+# Add toolchain to PATH
+export PATH=$PATH:/path/to/toolchain/bin
+
+# 32-bit build for mips32r5 (p5600)
+HOST=mips-mti-linux-gnu
+MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
+ -msched-weight -mload-store-pairs -fPIE"
+MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
+
+# 64-bit build for mips64r6 (i6400)
+HOST=mips-img-linux-gnu
+MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
+ -msched-weight -mload-store-pairs -fPIE"
+MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
+
+./configure --host=${HOST} --build=`config.guess` \
+ CC="${HOST}-gcc -EL" \
+ CFLAGS="$MIPS_CFLAGS" \
+ LDFLAGS="$MIPS_LDFLAGS"
+make
+make install
+
+CMake:
+------
+The support for CMake is minimal: it only helps you compile libwebp, cwebp and
+dwebp.
+
+Prerequisites:
+A compiler (e.g., gcc with autotools) and CMake.
+On a Debian-like system the following should install everything you need for a
+minimal build:
+$ sudo apt-get install build-essential cmake
+
+When building from git sources, you will need to run cmake to generate the
+configure script.
+
+mkdir build && cd build && cmake ../
+make
+make install
+
+If you also want cwebp or dwebp, you will need to enable them through CMake:
+
+cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
+
+or through your favorite interface (like ccmake or cmake-qt-gui).
+
+Gradle:
+-------
+The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
+dwebp and webpmux_example.
+
+Prerequisites:
+A compiler (e.g., gcc with autotools) and gradle.
+On a Debian-like system the following should install everything you need for a
+minimal build:
+$ sudo apt-get install build-essential gradle
+
+When building from git sources, you will need to run the Gradle wrapper with the
+appropriate target, e.g. :
+
+./gradlew buildAllExecutables
+
+SWIG bindings:
+--------------
+
+To generate language bindings from swig/libwebp.swig at least swig-1.3
+(http://www.swig.org) is required.
+
+Currently the following functions are mapped:
+Decode:
+ WebPGetDecoderVersion
+ WebPGetInfo
+ WebPDecodeRGBA
+ WebPDecodeARGB
+ WebPDecodeBGRA
+ WebPDecodeBGR
+ WebPDecodeRGB
+
+Encode:
+ WebPGetEncoderVersion
+ WebPEncodeRGBA
+ WebPEncodeBGRA
+ WebPEncodeRGB
+ WebPEncodeBGR
+ WebPEncodeLosslessRGBA
+ WebPEncodeLosslessBGRA
+ WebPEncodeLosslessRGB
+ WebPEncodeLosslessBGR
+
+See swig/README for more detailed build instructions.
+
+Java bindings:
+
+To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent)
+is necessary for enum support. The output is intended to be a shared object /
+DLL that can be loaded via System.loadLibrary("webp_jni").
+
+Python bindings:
+
+To build the swig-generated Python extension code at least Python 2.6 is
+required. Python < 2.6 may build with some minor changes to libwebp.swig or the
+generated code, but is untested.
+
+Encoding tool:
+==============
+
+The examples/ directory contains tools for encoding (cwebp) and
+decoding (dwebp) images.
+
+The easiest use should look like:
+ cwebp input.png -q 80 -o output.webp
+which will convert the input file to a WebP file using a quality factor of 80
+on a 0->100 scale (0 being the lowest quality, 100 being the best. Default
+value is 75).
+You might want to try the -lossless flag too, which will compress the source
+(in RGBA format) without any loss. The -q quality parameter will in this case
+control the amount of processing time spent trying to make the output file as
+small as possible.
+
+A longer list of options is available using the -longhelp command line flag:
+
+> cwebp -longhelp
+Usage:
+ cwebp [-preset <...>] [options] in_file [-o out_file]
+
+If input size (-s) for an image is not specified, it is
+assumed to be a PNG, JPEG, TIFF or WebP file.
+
+Options:
+ -h / -help ............. short help
+ -H / -longhelp ......... long help
+ -q <float> ............. quality factor (0:small..100:big), default=75
+ -alpha_q <int> ......... transparency-compression quality (0..100),
+ default=100
+ -preset <string> ....... preset setting, one of:
+ default, photo, picture,
+ drawing, icon, text
+ -preset must come first, as it overwrites other parameters
+ -z <int> ............... activates lossless preset with given
+ level in [0:fast, ..., 9:slowest]
+
+ -m <int> ............... compression method (0=fast, 6=slowest), default=4
+ -segments <int> ........ number of segments to use (1..4), default=4
+ -size <int> ............ target size (in bytes)
+ -psnr <float> .......... target PSNR (in dB. typically: 42)
+
+ -s <int> <int> ......... input size (width x height) for YUV
+ -sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
+ -f <int> ............... filter strength (0=off..100), default=60
+ -sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
+ -strong ................ use strong filter instead of simple (default)
+ -nostrong .............. use simple filter instead of strong
+ -sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
+ -partition_limit <int> . limit quality to fit the 512k limit on
+ the first partition (0=no degradation ... 100=full)
+ -pass <int> ............ analysis pass number (1..10)
+ -crop <x> <y> <w> <h> .. crop picture with the given rectangle
+ -resize <w> <h> ........ resize picture (after any cropping)
+ -mt .................... use multi-threading if available
+ -low_memory ............ reduce memory usage (slower encoding)
+ -map <int> ............. print map of extra info
+ -print_psnr ............ prints averaged PSNR distortion
+ -print_ssim ............ prints averaged SSIM distortion
+ -print_lsim ............ prints local-similarity distortion
+ -d <file.pgm> .......... dump the compressed output (PGM file)
+ -alpha_method <int> .... transparency-compression method (0..1), default=1
+ -alpha_filter <string> . predictive filtering for alpha plane,
+ one of: none, fast (default) or best
+ -exact ................. preserve RGB values in transparent area, default=off
+ -blend_alpha <hex> ..... blend colors against background color
+ expressed as RGB values written in
+ hexadecimal, e.g. 0xc0e0d0 for red=0xc0
+ green=0xe0 and blue=0xd0
+ -noalpha ............... discard any transparency information
+ -lossless .............. encode image losslessly, default=off
+ -near_lossless <int> ... use near-lossless image
+ preprocessing (0..100=off), default=100
+ -hint <string> ......... specify image characteristics hint,
+ one of: photo, picture or graph
+
+ -metadata <string> ..... comma separated list of metadata to
+ copy from the input to the output if present.
+ Valid values: all, none (default), exif, icc, xmp
+
+ -short ................. condense printed message
+ -quiet ................. don't print anything
+ -version ............... print version number and exit
+ -noasm ................. disable all assembly optimizations
+ -v ..................... verbose, e.g. print encoding/decoding times
+ -progress .............. report encoding progress
+
+Experimental Options:
+ -jpeg_like ............. roughly match expected JPEG size
+ -af .................... auto-adjust filter strength
+ -pre <int> ............. pre-processing filter
+
+The main options you might want to try in order to further tune the
+visual quality are:
+ -preset
+ -sns
+ -f
+ -m
+
+Namely:
+ * 'preset' will set up a default encoding configuration targeting a
+ particular type of input. It should appear first in the list of options,
+ so that subsequent options can take effect on top of this preset.
+ Default value is 'default'.
+ * 'sns' will progressively turn on (when going from 0 to 100) some additional
+ visual optimizations (like: segmentation map re-enforcement). This option
+ will balance the bit allocation differently. It tries to take bits from the
+ "easy" parts of the picture and use them in the "difficult" ones instead.
+ Usually, raising the sns value (at fixed -q value) leads to larger files,
+ but with better quality.
+ Typical value is around '75'.
+ * 'f' option directly links to the filtering strength used by the codec's
+ in-loop processing. The higher the value, the smoother the
+ highly-compressed area will look. This is particularly useful when aiming
+ at very small files. Typical values are around 20-30. Note that using the
+ option -strong/-nostrong will change the type of filtering. Use "-f 0" to
+ turn filtering off.
+ * 'm' controls the trade-off between encoding speed and quality. Default is 4.
+ You can try -m 5 or -m 6 to explore more (time-consuming) encoding
+ possibilities. A lower value will result in faster encoding at the expense
+ of quality.
+
+Decoding tool:
+==============
+
+There is a decoding sample in examples/dwebp.c which will take
+a .webp file and decode it to a PNG image file (amongst other formats).
+This is simply to demonstrate the use of the API. You can verify the
+file test.webp decodes to exactly the same as test_ref.ppm by using:
+
+ cd examples
+ ./dwebp test.webp -ppm -o test.ppm
+ diff test.ppm test_ref.ppm
+
+The full list of options is available using -h:
+
+> dwebp -h
+Usage: dwebp in_file [options] [-o out_file]
+
+Decodes the WebP image file to PNG format [Default]
+Use following options to convert into alternate image formats:
+ -pam ......... save the raw RGBA samples as a color PAM
+ -ppm ......... save the raw RGB samples as a color PPM
+ -bmp ......... save as uncompressed BMP format
+ -tiff ........ save as uncompressed TIFF format
+ -pgm ......... save the raw YUV samples as a grayscale PGM
+ file with IMC4 layout
+ -yuv ......... save the raw YUV samples in flat layout
+
+ Other options are:
+ -version ..... print version number and exit
+ -nofancy ..... don't use the fancy YUV420 upscaler
+ -nofilter .... disable in-loop filtering
+ -nodither .... disable dithering
+ -dither <d> .. dithering strength (in 0..100)
+ -alpha_dither use alpha-plane dithering if needed
+ -mt .......... use multi-threading
+ -crop <x> <y> <w> <h> ... crop output with the given rectangle
+ -resize <w> <h> ......... scale the output (*after* any cropping)
+ -flip ........ flip the output vertically
+ -alpha ....... only save the alpha plane
+ -incremental . use incremental decoding (useful for tests)
+ -h ........... this help message
+ -v ........... verbose (e.g. print encoding/decoding times)
+ -quiet ....... quiet mode, don't print anything
+ -noasm ....... disable all assembly optimizations
+
+Visualization tool:
+===================
+
+There's a little self-serve visualization tool called 'vwebp' under the
+examples/ directory. It uses OpenGL to open a simple drawing window and show
+a decoded WebP file. It's not yet integrated in the automake build system, but
+you can try to manually compile it using the recommendations below.
+
+Usage: vwebp in_file [options]
+
+Decodes the WebP image file and visualize it using OpenGL
+Options are:
+ -version ..... print version number and exit
+ -noicc ....... don't use the icc profile if present
+ -nofancy ..... don't use the fancy YUV420 upscaler
+ -nofilter .... disable in-loop filtering
+ -dither <int> dithering strength (0..100), default=50
+ -noalphadither disable alpha plane dithering
+ -mt .......... use multi-threading
+ -info ........ print info
+ -h ........... this help message
+
+Keyboard shortcuts:
+ 'c' ................ toggle use of color profile
+ 'i' ................ overlay file information
+ 'd' ................ disable blending & disposal (debug)
+ 'q' / 'Q' / ESC .... quit
+
+Building:
+---------
+
+Prerequisites:
+1) OpenGL & OpenGL Utility Toolkit (GLUT)
+ Linux:
+ $ sudo apt-get install freeglut3-dev mesa-common-dev
+ Mac + XCode:
+ - These libraries should be available in the OpenGL / GLUT frameworks.
+ Windows:
+ http://freeglut.sourceforge.net/index.php#download
+
+2) (Optional) qcms (Quick Color Management System)
+ i. Download qcms from Mozilla / Chromium:
+ http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
+ http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
+ ii. Build and archive the source files as libqcms.a / qcms.lib
+ iii. Update makefile.unix / Makefile.vc
+ a) Define WEBP_HAVE_QCMS
+ b) Update include / library paths to reference the qcms directory.
+
+Build using makefile.unix / Makefile.vc:
+$ make -f makefile.unix examples/vwebp
+> nmake /f Makefile.vc CFG=release-static \
+ ../obj/x64/release-static/bin/vwebp.exe
+
+Animation creation tool:
+========================
+The utility 'img2webp' can turn a sequence of input images (PNG, JPEG, ...)
+into an animated WebP file. It offers fine control over duration, encoding
+modes, etc.
+
+Usage:
+
+ img2webp [file-level options] [image files...] [per-frame options...]
+
+File-level options (only used at the start of compression):
+ -min_size ............ minimize size
+ -loop <int> .......... loop count (default: 0, = infinite loop)
+ -kmax <int> .......... maximum number of frame between key-frames
+ (0=only keyframes)
+ -kmin <int> .......... minimum number of frame between key-frames
+ (0=disable key-frames altogether)
+ -mixed ............... use mixed lossy/lossless automatic mode
+ -v ................... verbose mode
+ -h ................... this help
+
+Per-frame options (only used for subsequent images input):
+ -d <int> ............. frame duration in ms (default: 100)
+ -lossless ........... use lossless mode (default)
+ -lossy ... ........... use lossy mode
+ -q <float> ........... quality
+ -m <int> ............. method to use
+
+example: img2webp -loop 2 in0.png -lossy in1.jpg
+ -d 80 in2.tiff -o out.webp
+
+Animated GIF conversion:
+========================
+Animated GIF files can be converted to WebP files with animation using the
+gif2webp utility available under examples/. The files can then be viewed using
+vwebp.
+
+Usage:
+ gif2webp [options] gif_file -o webp_file
+Options:
+ -h / -help ............. this help
+ -lossy ................. encode image using lossy compression
+ -mixed ................. for each frame in the image, pick lossy
+ or lossless compression heuristically
+ -q <float> ............. quality factor (0:small..100:big)
+ -m <int> ............... compression method (0=fast, 6=slowest)
+ -min_size .............. minimize output size (default:off)
+ lossless compression by default; can be
+ combined with -q, -m, -lossy or -mixed
+ options
+ -kmin <int> ............ min distance between key frames
+ -kmax <int> ............ max distance between key frames
+ -f <int> ............... filter strength (0=off..100)
+ -metadata <string> ..... comma separated list of metadata to
+ copy from the input to the output if present
+ Valid values: all, none, icc, xmp (default)
+ -mt .................... use multi-threading if available
+
+ -version ............... print version number and exit
+ -v ..................... verbose
+ -quiet ................. don't print anything
+
+Building:
+---------
+With the libgif development files installed, gif2webp can be built using
+makefile.unix:
+$ make -f makefile.unix examples/gif2webp
+
+or using autoconf:
+$ ./configure --enable-everything
+$ make
+
+Comparison of animated images:
+==============================
+Test utility anim_diff under examples/ can be used to compare two animated
+images (each can be GIF or WebP).
+
+Usage: anim_diff <image1> <image2> [options]
+
+Options:
+ -dump_frames <folder> dump decoded frames in PAM format
+ -min_psnr <float> ... minimum per-frame PSNR
+ -raw_comparison ..... if this flag is not used, RGB is
+ premultiplied before comparison
+
+Building:
+---------
+With the libgif development files and a C++ compiler installed, anim_diff can
+be built using makefile.unix:
+$ make -f makefile.unix examples/anim_diff
+
+or using autoconf:
+$ ./configure --enable-everything
+$ make
+
+Encoding API:
+=============
+
+The main encoding functions are available in the header src/webp/encode.h
+The ready-to-use ones are:
+size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+
+They will convert raw RGB samples to a WebP data. The only control supplied
+is the quality factor.
+
+There are some variants for using the lossless format:
+
+size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
+ int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
+ int stride, uint8_t** output);
+size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
+ int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
+ int stride, uint8_t** output);
+
+Of course in this case, no quality factor is needed since the compression
+occurs without loss of the input values, at the expense of larger output sizes.
+
+Advanced encoding API:
+----------------------
+
+A more advanced API is based on the WebPConfig and WebPPicture structures.
+
+WebPConfig contains the encoding settings and is not tied to a particular
+picture.
+WebPPicture contains input data, on which some WebPConfig will be used for
+compression.
+The encoding flow looks like:
+
+-------------------------------------- BEGIN PSEUDO EXAMPLE
+
+#include <webp/encode.h>
+
+ // Setup a config, starting form a preset and tuning some additional
+ // parameters
+ WebPConfig config;
+ if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
+ return 0; // version error
+ }
+ // ... additional tuning
+ config.sns_strength = 90;
+ config.filter_sharpness = 6;
+ config_error = WebPValidateConfig(&config); // not mandatory, but useful
+
+ // Setup the input data
+ WebPPicture pic;
+ if (!WebPPictureInit(&pic)) {
+ return 0; // version error
+ }
+ pic.width = width;
+ pic.height = height;
+ // allocated picture of dimension width x height
+ if (!WebPPictureAllocate(&pic)) {
+ return 0; // memory error
+ }
+ // at this point, 'pic' has been initialized as a container,
+ // and can receive the Y/U/V samples.
+ // Alternatively, one could use ready-made import functions like
+ // WebPPictureImportRGB(), which will take care of memory allocation.
+ // In any case, past this point, one will have to call
+ // WebPPictureFree(&pic) to reclaim memory.
+
+ // Set up a byte-output write method. WebPMemoryWriter, for instance.
+ WebPMemoryWriter wrt;
+ WebPMemoryWriterInit(&wrt); // initialize 'wrt'
+
+ pic.writer = MyFileWriter;
+ pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
+
+ // Compress!
+ int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
+ WebPPictureFree(&pic); // must be called independently of the 'ok' result.
+
+ // output data should have been handled by the writer at that point.
+ // -> compressed data is the memory buffer described by wrt.mem / wrt.size
+
+ // deallocate the memory used by compressed data
+ WebPMemoryWriterClear(&wrt);
+
+-------------------------------------- END PSEUDO EXAMPLE
+
+Decoding API:
+=============
+
+This is mainly just one function to call:
+
+#include "webp/decode.h"
+uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+Please have a look at the file src/webp/decode.h for the details.
+There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with
+decoding to raw Y'CbCr samples. One can also decode the image directly into a
+pre-allocated buffer.
+
+To detect a WebP file and gather the picture's dimensions, the function:
+ int WebPGetInfo(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+is supplied. No decoding is involved when using it.
+
+Incremental decoding API:
+=========================
+
+In the case when data is being progressively transmitted, pictures can still
+be incrementally decoded using a slightly more complicated API. Decoder state
+is stored into an instance of the WebPIDecoder object. This object can be
+created with the purpose of decoding either RGB or Y'CbCr samples.
+For instance:
+
+ WebPDecBuffer buffer;
+ WebPInitDecBuffer(&buffer);
+ buffer.colorspace = MODE_BGR;
+ ...
+ WebPIDecoder* idec = WebPINewDecoder(&buffer);
+
+As data is made progressively available, this incremental-decoder object
+can be used to decode the picture further. There are two (mutually exclusive)
+ways to pass freshly arrived data:
+
+either by appending the fresh bytes:
+
+ WebPIAppend(idec, fresh_data, size_of_fresh_data);
+
+or by just mentioning the new size of the transmitted data:
+
+ WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
+
+Note that 'buffer' can be modified between each call to WebPIUpdate, in
+particular when the buffer is resized to accommodate larger data.
+
+These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
+decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
+status is an error condition.
+
+The 'idec' object must always be released (even upon an error condition) by
+calling: WebPDelete(idec).
+
+To retrieve partially decoded picture samples, one must use the corresponding
+method: WebPIDecGetRGB or WebPIDecGetYUVA.
+It will return the last displayable pixel row.
+
+Lastly, note that decoding can also be performed into a pre-allocated pixel
+buffer. This buffer must be passed when creating a WebPIDecoder, calling
+WebPINewRGB() or WebPINewYUVA().
+
+Please have a look at the src/webp/decode.h header for further details.
+
+Advanced Decoding API:
+======================
+
+WebP decoding supports an advanced API which provides on-the-fly cropping and
+rescaling, something of great usefulness on memory-constrained environments like
+mobile phones. Basically, the memory usage will scale with the output's size,
+not the input's, when one only needs a quick preview or a zoomed in portion of
+an otherwise too-large picture. Some CPU can be saved too, incidentally.
+
+-------------------------------------- BEGIN PSEUDO EXAMPLE
+ // A) Init a configuration object
+ WebPDecoderConfig config;
+ CHECK(WebPInitDecoderConfig(&config));
+
+ // B) optional: retrieve the bitstream's features.
+ CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
+
+ // C) Adjust 'config' options, if needed
+ config.options.no_fancy_upsampling = 1;
+ config.options.use_scaling = 1;
+ config.options.scaled_width = scaledWidth();
+ config.options.scaled_height = scaledHeight();
+ // etc.
+
+ // D) Specify 'config' output options for specifying output colorspace.
+ // Optionally the external image decode buffer can also be specified.
+ config.output.colorspace = MODE_BGRA;
+ // Optionally, the config.output can be pointed to an external buffer as
+ // well for decoding the image. This externally supplied memory buffer
+ // should be big enough to store the decoded picture.
+ config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
+ config.output.u.RGBA.stride = scanline_stride;
+ config.output.u.RGBA.size = total_size_of_the_memory_buffer;
+ config.output.is_external_memory = 1;
+
+ // E) Decode the WebP image. There are two variants w.r.t decoding image.
+ // The first one (E.1) decodes the full image and the second one (E.2) is
+ // used to incrementally decode the image using small input buffers.
+ // Any one of these steps can be used to decode the WebP image.
+
+ // E.1) Decode full image.
+ CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+ // E.2) Decode image incrementally.
+ WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
+ CHECK(idec != NULL);
+ while (bytes_remaining > 0) {
+ VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
+ if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
+ bytes_remaining -= bytes_read;
+ } else {
+ break;
+ }
+ }
+ WebPIDelete(idec);
+
+ // F) Decoded image is now in config.output (and config.output.u.RGBA).
+ // It can be saved, displayed or otherwise processed.
+
+ // G) Reclaim memory allocated in config's object. It's safe to call
+ // this function even if the memory is external and wasn't allocated
+ // by WebPDecode().
+ WebPFreeDecBuffer(&config.output);
+
+-------------------------------------- END PSEUDO EXAMPLE
+
+Bugs:
+=====
+
+Please report all bugs to the issue tracker:
+ https://bugs.chromium.org/p/webp
+Patches welcome! See this page to get started:
+ http://www.webmproject.org/code/contribute/submitting-patches/
+
+Discuss:
+========
+
+Email: webp-discuss@webmproject.org
+Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/media/libwebp/README.mux b/media/libwebp/README.mux
new file mode 100644
index 000000000..04fedd163
--- /dev/null
+++ b/media/libwebp/README.mux
@@ -0,0 +1,223 @@
+ __ __ ____ ____ ____ __ __ _ __ __
+ / \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
+ \ / __/ _ \ __/ / / (_/ /__
+ \__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.0
+
+
+Description:
+============
+
+WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and
+manipulation of an extended format WebP file, which can have features like
+color profile, metadata and animation. Reference command-line tools 'webpmux'
+and 'vwebp' as well as the WebP container specification
+'doc/webp-container-spec.txt' are also provided in this package.
+
+WebP Mux tool:
+==============
+
+The examples/ directory contains a tool (webpmux) for manipulating WebP
+files. The webpmux tool can be used to create an extended format WebP file and
+also to extract or strip relevant data from such a file.
+
+A list of options is available using the -help command line flag:
+
+> webpmux -help
+Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
+ webpmux -set SET_OPTIONS INPUT -o OUTPUT
+ webpmux -duration DURATION_OPTIONS [-duration ...]
+ INPUT -o OUTPUT
+ webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
+ webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
+ [-bgcolor BACKGROUND_COLOR] -o OUTPUT
+ webpmux -info INPUT
+ webpmux [-h|-help]
+ webpmux -version
+
+GET_OPTIONS:
+ Extract relevant data:
+ icc get ICC profile
+ exif get EXIF metadata
+ xmp get XMP metadata
+ frame n get nth frame
+
+SET_OPTIONS:
+ Set color profile/metadata:
+ icc file.icc set ICC profile
+ exif file.exif set EXIF metadata
+ xmp file.xmp set XMP metadata
+ where: 'file.icc' contains the ICC profile to be set,
+ 'file.exif' contains the EXIF metadata to be set
+ 'file.xmp' contains the XMP metadata to be set
+
+DURATION_OPTIONS:
+ Set duration of selected frames:
+ duration set duration for each frames
+ duration,frame set duration of a particular frame
+ duration,start,end set duration of frames in the
+ interval [start,end])
+ where: 'duration' is the duration in milliseconds
+ 'start' is the start frame index
+ 'end' is the inclusive end frame index
+ The special 'end' value '0' means: last frame.
+
+STRIP_OPTIONS:
+ Strip color profile/metadata:
+ icc strip ICC profile
+ exif strip EXIF metadata
+ xmp strip XMP metadata
+
+FRAME_OPTIONS(i):
+ Create animation:
+ file_i +di+[xi+yi[+mi[bi]]]
+ where: 'file_i' is the i'th animation frame (WebP format),
+ 'di' is the pause duration before next frame,
+ 'xi','yi' specify the image offset for this frame,
+ 'mi' is the dispose method for this frame (0 or 1),
+ 'bi' is the blending method for this frame (+b or -b)
+
+LOOP_COUNT:
+ Number of times to repeat the animation.
+ Valid range is 0 to 65535 [Default: 0 (infinite)].
+
+BACKGROUND_COLOR:
+ Background color of the canvas.
+ A,R,G,B
+ where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
+ the Alpha, Red, Green and Blue component values respectively
+ [Default: 255,255,255,255]
+
+INPUT & OUTPUT are in WebP format.
+
+Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
+valid.
+
+Visualization tool:
+===================
+
+The examples/ directory also contains a tool (vwebp) for viewing WebP files.
+It decodes the image and visualizes it using OpenGL. See the libwebp README
+for details on building and running this program.
+
+Mux API:
+========
+The Mux API contains methods for adding data to and reading data from WebP
+files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
+Other features may be added in subsequent releases.
+
+Example#1 (pseudo code): Creating a WebPMux object with image data, color
+profile and XMP metadata.
+
+ int copy_data = 0;
+ WebPMux* mux = WebPMuxNew();
+ // ... (Prepare image data).
+ WebPMuxSetImage(mux, &image, copy_data);
+ // ... (Prepare ICC profile data).
+ WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+ // ... (Prepare XMP metadata).
+ WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
+ // Get data from mux in WebP RIFF format.
+ WebPMuxAssemble(mux, &output_data);
+ WebPMuxDelete(mux);
+ // ... (Consume output_data; e.g. write output_data.bytes to file).
+ WebPDataClear(&output_data);
+
+
+Example#2 (pseudo code): Get image and color profile data from a WebP file.
+
+ int copy_data = 0;
+ // ... (Read data from file).
+ WebPMux* mux = WebPMuxCreate(&data, copy_data);
+ WebPMuxGetFrame(mux, 1, &image);
+ // ... (Consume image; e.g. call WebPDecode() to decode the data).
+ WebPMuxGetChunk(mux, "ICCP", &icc_profile);
+ // ... (Consume icc_profile).
+ WebPMuxDelete(mux);
+ free(data);
+
+
+For a detailed Mux API reference, please refer to the header file
+(src/webp/mux.h).
+
+Demux API:
+==========
+The Demux API enables extraction of images and extended format data from
+WebP files. This API currently supports reading of XMP/EXIF metadata, ICC
+profile and animated images. Other features may be added in subsequent
+releases.
+
+Code example: Demuxing WebP data to extract all the frames, ICC profile
+and EXIF/XMP metadata.
+
+ WebPDemuxer* demux = WebPDemux(&webp_data);
+ uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+ uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+ // ... (Get information about the features present in the WebP file).
+ uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+
+ // ... (Iterate over all frames).
+ WebPIterator iter;
+ if (WebPDemuxGetFrame(demux, 1, &iter)) {
+ do {
+ // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
+ // ... and get other frame properties like width, height, offsets etc.
+ // ... see 'struct WebPIterator' below for more info).
+ } while (WebPDemuxNextFrame(&iter));
+ WebPDemuxReleaseIterator(&iter);
+ }
+
+ // ... (Extract metadata).
+ WebPChunkIterator chunk_iter;
+ if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
+ // ... (Consume the ICC profile in 'chunk_iter.chunk').
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
+ // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
+ // ... (Consume the XMP metadata in 'chunk_iter.chunk').
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ WebPDemuxDelete(demux);
+
+
+For a detailed Demux API reference, please refer to the header file
+(src/webp/demux.h).
+
+AnimEncoder API:
+================
+The AnimEncoder API can be used to create animated WebP images.
+
+Code example:
+
+ WebPAnimEncoderOptions enc_options;
+ WebPAnimEncoderOptionsInit(&enc_options);
+ // ... (Tune 'enc_options' as needed).
+ WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
+ while(<there are more frames>) {
+ WebPConfig config;
+ WebPConfigInit(&config);
+ // ... (Tune 'config' as needed).
+ WebPAnimEncoderAdd(enc, frame, duration, &config);
+ }
+ WebPAnimEncoderAssemble(enc, webp_data);
+ WebPAnimEncoderDelete(enc);
+ // ... (Write the 'webp_data' to a file, or re-mux it further).
+
+
+For a detailed AnimEncoder API reference, please refer to the header file
+(src/webp/mux.h).
+
+
+Bugs:
+=====
+
+Please report all bugs to the issue tracker:
+ https://bugs.chromium.org/p/webp
+Patches welcome! See this page to get started:
+ http://www.webmproject.org/code/contribute/submitting-patches/
+
+Discuss:
+========
+
+Email: webp-discuss@webmproject.org
+Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
diff --git a/media/libwebp/dec/alpha_dec.c b/media/libwebp/dec/alpha_dec.c
new file mode 100644
index 000000000..83ffd4b60
--- /dev/null
+++ b/media/libwebp/dec/alpha_dec.c
@@ -0,0 +1,232 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha-plane decompression.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <stdlib.h>
+#include "./alphai_dec.h"
+#include "./vp8i_dec.h"
+#include "./vp8li_dec.h"
+#include "../dsp/dsp.h"
+#include "../utils/quant_levels_dec_utils.h"
+#include "../utils/utils.h"
+#include "../webp/format_constants.h"
+
+//------------------------------------------------------------------------------
+// ALPHDecoder object.
+
+// Allocates a new alpha decoder instance.
+static ALPHDecoder* ALPHNew(void) {
+ ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
+ return dec;
+}
+
+// Clears and deallocates an alpha decoder instance.
+static void ALPHDelete(ALPHDecoder* const dec) {
+ if (dec != NULL) {
+ VP8LDelete(dec->vp8l_dec_);
+ dec->vp8l_dec_ = NULL;
+ WebPSafeFree(dec);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Decoding.
+
+// Initialize alpha decoding by parsing the alpha header and decoding the image
+// header for alpha data stored using lossless compression.
+// Returns false in case of error in alpha header (data too short, invalid
+// compression method or filter, error in lossless header data etc).
+static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
+ size_t data_size, const VP8Io* const src_io,
+ uint8_t* output) {
+ int ok = 0;
+ const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN;
+ const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
+ int rsrv;
+ VP8Io* const io = &dec->io_;
+
+ assert(data != NULL && output != NULL && src_io != NULL);
+
+ VP8FiltersInit();
+ dec->output_ = output;
+ dec->width_ = src_io->width;
+ dec->height_ = src_io->height;
+ assert(dec->width_ > 0 && dec->height_ > 0);
+
+ if (data_size <= ALPHA_HEADER_LEN) {
+ return 0;
+ }
+
+ dec->method_ = (data[0] >> 0) & 0x03;
+ dec->filter_ = (WEBP_FILTER_TYPE)((data[0] >> 2) & 0x03);
+ dec->pre_processing_ = (data[0] >> 4) & 0x03;
+ rsrv = (data[0] >> 6) & 0x03;
+ if (dec->method_ < ALPHA_NO_COMPRESSION ||
+ dec->method_ > ALPHA_LOSSLESS_COMPRESSION ||
+ dec->filter_ >= WEBP_FILTER_LAST ||
+ dec->pre_processing_ > ALPHA_PREPROCESSED_LEVELS ||
+ rsrv != 0) {
+ return 0;
+ }
+
+ // Copy the necessary parameters from src_io to io
+ VP8InitIo(io);
+ WebPInitCustomIo(NULL, io);
+ io->opaque = dec;
+ io->width = src_io->width;
+ io->height = src_io->height;
+
+ io->use_cropping = src_io->use_cropping;
+ io->crop_left = src_io->crop_left;
+ io->crop_right = src_io->crop_right;
+ io->crop_top = src_io->crop_top;
+ io->crop_bottom = src_io->crop_bottom;
+ // No need to copy the scaling parameters.
+
+ if (dec->method_ == ALPHA_NO_COMPRESSION) {
+ const size_t alpha_decoded_size = dec->width_ * dec->height_;
+ ok = (alpha_data_size >= alpha_decoded_size);
+ } else {
+ assert(dec->method_ == ALPHA_LOSSLESS_COMPRESSION);
+ ok = VP8LDecodeAlphaHeader(dec, alpha_data, alpha_data_size);
+ }
+
+ return ok;
+}
+
+// Decodes, unfilters and dequantizes *at least* 'num_rows' rows of alpha
+// starting from row number 'row'. It assumes that rows up to (row - 1) have
+// already been decoded.
+// Returns false in case of bitstream error.
+static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
+ ALPHDecoder* const alph_dec = dec->alph_dec_;
+ const int width = alph_dec->width_;
+ const int height = alph_dec->io_.crop_bottom;
+ if (alph_dec->method_ == ALPHA_NO_COMPRESSION) {
+ int y;
+ const uint8_t* prev_line = dec->alpha_prev_line_;
+ const uint8_t* deltas = dec->alpha_data_ + ALPHA_HEADER_LEN + row * width;
+ uint8_t* dst = dec->alpha_plane_ + row * width;
+ assert(deltas <= &dec->alpha_data_[dec->alpha_data_size_]);
+ if (alph_dec->filter_ != WEBP_FILTER_NONE) {
+ assert(WebPUnfilters[alph_dec->filter_] != NULL);
+ for (y = 0; y < num_rows; ++y) {
+ WebPUnfilters[alph_dec->filter_](prev_line, deltas, dst, width);
+ prev_line = dst;
+ dst += width;
+ deltas += width;
+ }
+ } else {
+ for (y = 0; y < num_rows; ++y) {
+ memcpy(dst, deltas, width * sizeof(*dst));
+ prev_line = dst;
+ dst += width;
+ deltas += width;
+ }
+ }
+ dec->alpha_prev_line_ = prev_line;
+ } else { // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION
+ assert(alph_dec->vp8l_dec_ != NULL);
+ if (!VP8LDecodeAlphaImageStream(alph_dec, row + num_rows)) {
+ return 0;
+ }
+ }
+
+ if (row + num_rows >= height) {
+ dec->is_alpha_decoded_ = 1;
+ }
+ return 1;
+}
+
+static int AllocateAlphaPlane(VP8Decoder* const dec, const VP8Io* const io) {
+ const int stride = io->width;
+ const int height = io->crop_bottom;
+ const uint64_t alpha_size = (uint64_t)stride * height;
+ assert(dec->alpha_plane_mem_ == NULL);
+ dec->alpha_plane_mem_ =
+ (uint8_t*)WebPSafeMalloc(alpha_size, sizeof(*dec->alpha_plane_));
+ if (dec->alpha_plane_mem_ == NULL) {
+ return 0;
+ }
+ dec->alpha_plane_ = dec->alpha_plane_mem_;
+ dec->alpha_prev_line_ = NULL;
+ return 1;
+}
+
+void WebPDeallocateAlphaMemory(VP8Decoder* const dec) {
+ assert(dec != NULL);
+ WebPSafeFree(dec->alpha_plane_mem_);
+ dec->alpha_plane_mem_ = NULL;
+ dec->alpha_plane_ = NULL;
+ ALPHDelete(dec->alph_dec_);
+ dec->alph_dec_ = NULL;
+}
+
+//------------------------------------------------------------------------------
+// Main entry point.
+
+const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
+ const VP8Io* const io,
+ int row, int num_rows) {
+ const int width = io->width;
+ const int height = io->crop_bottom;
+
+ assert(dec != NULL && io != NULL);
+
+ if (row < 0 || num_rows <= 0 || row + num_rows > height) {
+ return NULL; // sanity check.
+ }
+
+ if (!dec->is_alpha_decoded_) {
+ if (dec->alph_dec_ == NULL) { // Initialize decoder.
+ dec->alph_dec_ = ALPHNew();
+ if (dec->alph_dec_ == NULL) return NULL;
+ if (!AllocateAlphaPlane(dec, io)) goto Error;
+ if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_,
+ io, dec->alpha_plane_)) {
+ goto Error;
+ }
+ // if we allowed use of alpha dithering, check whether it's needed at all
+ if (dec->alph_dec_->pre_processing_ != ALPHA_PREPROCESSED_LEVELS) {
+ dec->alpha_dithering_ = 0; // disable dithering
+ } else {
+ num_rows = height - row; // decode everything in one pass
+ }
+ }
+
+ assert(dec->alph_dec_ != NULL);
+ assert(row + num_rows <= height);
+ if (!ALPHDecode(dec, row, num_rows)) goto Error;
+
+ if (dec->is_alpha_decoded_) { // finished?
+ ALPHDelete(dec->alph_dec_);
+ dec->alph_dec_ = NULL;
+ if (dec->alpha_dithering_ > 0) {
+ uint8_t* const alpha = dec->alpha_plane_ + io->crop_top * width
+ + io->crop_left;
+ if (!WebPDequantizeLevels(alpha,
+ io->crop_right - io->crop_left,
+ io->crop_bottom - io->crop_top,
+ width, dec->alpha_dithering_)) {
+ goto Error;
+ }
+ }
+ }
+ }
+
+ // Return a pointer to the current decoded row.
+ return dec->alpha_plane_ + row * width;
+
+ Error:
+ WebPDeallocateAlphaMemory(dec);
+ return NULL;
+}
diff --git a/media/libwebp/dec/alphai_dec.h b/media/libwebp/dec/alphai_dec.h
new file mode 100644
index 000000000..561e8151e
--- /dev/null
+++ b/media/libwebp/dec/alphai_dec.h
@@ -0,0 +1,54 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha decoder: internal header.
+//
+// Author: Urvang (urvang@google.com)
+
+#ifndef WEBP_DEC_ALPHAI_H_
+#define WEBP_DEC_ALPHAI_H_
+
+#include "./webpi_dec.h"
+#include "../utils/filters_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct VP8LDecoder; // Defined in dec/vp8li.h.
+
+typedef struct ALPHDecoder ALPHDecoder;
+struct ALPHDecoder {
+ int width_;
+ int height_;
+ int method_;
+ WEBP_FILTER_TYPE filter_;
+ int pre_processing_;
+ struct VP8LDecoder* vp8l_dec_;
+ VP8Io io_;
+ int use_8b_decode_; // Although alpha channel requires only 1 byte per
+ // pixel, sometimes VP8LDecoder may need to allocate
+ // 4 bytes per pixel internally during decode.
+ uint8_t* output_;
+ const uint8_t* prev_line_; // last output row (or NULL)
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+// Deallocate memory associated to dec->alpha_plane_ decoding
+void WebPDeallocateAlphaMemory(VP8Decoder* const dec);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_DEC_ALPHAI_H_ */
diff --git a/media/libwebp/dec/buffer_dec.c b/media/libwebp/dec/buffer_dec.c
new file mode 100644
index 000000000..c685fd564
--- /dev/null
+++ b/media/libwebp/dec/buffer_dec.c
@@ -0,0 +1,300 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Everything about WebPDecBuffer
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <stdlib.h>
+
+#include "./vp8i_dec.h"
+#include "./webpi_dec.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// WebPDecBuffer
+
+// Number of bytes per pixel for the different color-spaces.
+static const int kModeBpp[MODE_LAST] = {
+ 3, 4, 3, 4, 4, 2, 2,
+ 4, 4, 4, 2, // pre-multiplied modes
+ 1, 1 };
+
+// Check that webp_csp_mode is within the bounds of WEBP_CSP_MODE.
+// Convert to an integer to handle both the unsigned/signed enum cases
+// without the need for casting to remove type limit warnings.
+static int IsValidColorspace(int webp_csp_mode) {
+ return (webp_csp_mode >= MODE_RGB && webp_csp_mode < MODE_LAST);
+}
+
+// strictly speaking, the very last (or first, if flipped) row
+// doesn't require padding.
+#define MIN_BUFFER_SIZE(WIDTH, HEIGHT, STRIDE) \
+ (uint64_t)(STRIDE) * ((HEIGHT) - 1) + (WIDTH)
+
+static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
+ int ok = 1;
+ const WEBP_CSP_MODE mode = buffer->colorspace;
+ const int width = buffer->width;
+ const int height = buffer->height;
+ if (!IsValidColorspace(mode)) {
+ ok = 0;
+ } else if (!WebPIsRGBMode(mode)) { // YUV checks
+ const WebPYUVABuffer* const buf = &buffer->u.YUVA;
+ const int uv_width = (width + 1) / 2;
+ const int uv_height = (height + 1) / 2;
+ const int y_stride = abs(buf->y_stride);
+ const int u_stride = abs(buf->u_stride);
+ const int v_stride = abs(buf->v_stride);
+ const int a_stride = abs(buf->a_stride);
+ const uint64_t y_size = MIN_BUFFER_SIZE(width, height, y_stride);
+ const uint64_t u_size = MIN_BUFFER_SIZE(uv_width, uv_height, u_stride);
+ const uint64_t v_size = MIN_BUFFER_SIZE(uv_width, uv_height, v_stride);
+ const uint64_t a_size = MIN_BUFFER_SIZE(width, height, a_stride);
+ ok &= (y_size <= buf->y_size);
+ ok &= (u_size <= buf->u_size);
+ ok &= (v_size <= buf->v_size);
+ ok &= (y_stride >= width);
+ ok &= (u_stride >= uv_width);
+ ok &= (v_stride >= uv_width);
+ ok &= (buf->y != NULL);
+ ok &= (buf->u != NULL);
+ ok &= (buf->v != NULL);
+ if (mode == MODE_YUVA) {
+ ok &= (a_stride >= width);
+ ok &= (a_size <= buf->a_size);
+ ok &= (buf->a != NULL);
+ }
+ } else { // RGB checks
+ const WebPRGBABuffer* const buf = &buffer->u.RGBA;
+ const int stride = abs(buf->stride);
+ const uint64_t size = MIN_BUFFER_SIZE(width, height, stride);
+ ok &= (size <= buf->size);
+ ok &= (stride >= width * kModeBpp[mode]);
+ ok &= (buf->rgba != NULL);
+ }
+ return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM;
+}
+#undef MIN_BUFFER_SIZE
+
+static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
+ const int w = buffer->width;
+ const int h = buffer->height;
+ const WEBP_CSP_MODE mode = buffer->colorspace;
+
+ if (w <= 0 || h <= 0 || !IsValidColorspace(mode)) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+
+ if (buffer->is_external_memory <= 0 && buffer->private_memory == NULL) {
+ uint8_t* output;
+ int uv_stride = 0, a_stride = 0;
+ uint64_t uv_size = 0, a_size = 0, total_size;
+ // We need memory and it hasn't been allocated yet.
+ // => initialize output buffer, now that dimensions are known.
+ const int stride = w * kModeBpp[mode];
+ const uint64_t size = (uint64_t)stride * h;
+
+ if (!WebPIsRGBMode(mode)) {
+ uv_stride = (w + 1) / 2;
+ uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
+ if (mode == MODE_YUVA) {
+ a_stride = w;
+ a_size = (uint64_t)a_stride * h;
+ }
+ }
+ total_size = size + 2 * uv_size + a_size;
+
+ // Security/sanity checks
+ output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
+ if (output == NULL) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ buffer->private_memory = output;
+
+ if (!WebPIsRGBMode(mode)) { // YUVA initialization
+ WebPYUVABuffer* const buf = &buffer->u.YUVA;
+ buf->y = output;
+ buf->y_stride = stride;
+ buf->y_size = (size_t)size;
+ buf->u = output + size;
+ buf->u_stride = uv_stride;
+ buf->u_size = (size_t)uv_size;
+ buf->v = output + size + uv_size;
+ buf->v_stride = uv_stride;
+ buf->v_size = (size_t)uv_size;
+ if (mode == MODE_YUVA) {
+ buf->a = output + size + 2 * uv_size;
+ }
+ buf->a_size = (size_t)a_size;
+ buf->a_stride = a_stride;
+ } else { // RGBA initialization
+ WebPRGBABuffer* const buf = &buffer->u.RGBA;
+ buf->rgba = output;
+ buf->stride = stride;
+ buf->size = (size_t)size;
+ }
+ }
+ return CheckDecBuffer(buffer);
+}
+
+VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
+ if (buffer == NULL) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ if (WebPIsRGBMode(buffer->colorspace)) {
+ WebPRGBABuffer* const buf = &buffer->u.RGBA;
+ buf->rgba += (buffer->height - 1) * buf->stride;
+ buf->stride = -buf->stride;
+ } else {
+ WebPYUVABuffer* const buf = &buffer->u.YUVA;
+ const int H = buffer->height;
+ buf->y += (H - 1) * buf->y_stride;
+ buf->y_stride = -buf->y_stride;
+ buf->u += ((H - 1) >> 1) * buf->u_stride;
+ buf->u_stride = -buf->u_stride;
+ buf->v += ((H - 1) >> 1) * buf->v_stride;
+ buf->v_stride = -buf->v_stride;
+ if (buf->a != NULL) {
+ buf->a += (H - 1) * buf->a_stride;
+ buf->a_stride = -buf->a_stride;
+ }
+ }
+ return VP8_STATUS_OK;
+}
+
+VP8StatusCode WebPAllocateDecBuffer(int w, int h,
+ const WebPDecoderOptions* const options,
+ WebPDecBuffer* const out) {
+ VP8StatusCode status;
+ if (out == NULL || w <= 0 || h <= 0) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ if (options != NULL) { // First, apply options if there is any.
+ if (options->use_cropping) {
+ const int cw = options->crop_width;
+ const int ch = options->crop_height;
+ const int x = options->crop_left & ~1;
+ const int y = options->crop_top & ~1;
+ if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
+ return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
+ }
+ w = cw;
+ h = ch;
+ }
+ if (options->use_scaling) {
+ int scaled_width = options->scaled_width;
+ int scaled_height = options->scaled_height;
+ if (!WebPRescalerGetScaledDimensions(
+ w, h, &scaled_width, &scaled_height)) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ w = scaled_width;
+ h = scaled_height;
+ }
+ }
+ out->width = w;
+ out->height = h;
+
+ // Then, allocate buffer for real.
+ status = AllocateBuffer(out);
+ if (status != VP8_STATUS_OK) return status;
+
+ // Use the stride trick if vertical flip is needed.
+ if (options != NULL && options->flip) {
+ status = WebPFlipBuffer(out);
+ }
+ return status;
+}
+
+//------------------------------------------------------------------------------
+// constructors / destructors
+
+int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) {
+ if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+ return 0; // version mismatch
+ }
+ if (buffer == NULL) return 0;
+ memset(buffer, 0, sizeof(*buffer));
+ return 1;
+}
+
+void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
+ if (buffer != NULL) {
+ if (buffer->is_external_memory <= 0) {
+ WebPSafeFree(buffer->private_memory);
+ }
+ buffer->private_memory = NULL;
+ }
+}
+
+void WebPCopyDecBuffer(const WebPDecBuffer* const src,
+ WebPDecBuffer* const dst) {
+ if (src != NULL && dst != NULL) {
+ *dst = *src;
+ if (src->private_memory != NULL) {
+ dst->is_external_memory = 1; // dst buffer doesn't own the memory.
+ dst->private_memory = NULL;
+ }
+ }
+}
+
+// Copy and transfer ownership from src to dst (beware of parameter order!)
+void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst) {
+ if (src != NULL && dst != NULL) {
+ *dst = *src;
+ if (src->private_memory != NULL) {
+ src->is_external_memory = 1; // src relinquishes ownership
+ src->private_memory = NULL;
+ }
+ }
+}
+
+VP8StatusCode WebPCopyDecBufferPixels(const WebPDecBuffer* const src_buf,
+ WebPDecBuffer* const dst_buf) {
+ assert(src_buf != NULL && dst_buf != NULL);
+ assert(src_buf->colorspace == dst_buf->colorspace);
+
+ dst_buf->width = src_buf->width;
+ dst_buf->height = src_buf->height;
+ if (CheckDecBuffer(dst_buf) != VP8_STATUS_OK) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ if (WebPIsRGBMode(src_buf->colorspace)) {
+ const WebPRGBABuffer* const src = &src_buf->u.RGBA;
+ const WebPRGBABuffer* const dst = &dst_buf->u.RGBA;
+ WebPCopyPlane(src->rgba, src->stride, dst->rgba, dst->stride,
+ src_buf->width * kModeBpp[src_buf->colorspace],
+ src_buf->height);
+ } else {
+ const WebPYUVABuffer* const src = &src_buf->u.YUVA;
+ const WebPYUVABuffer* const dst = &dst_buf->u.YUVA;
+ WebPCopyPlane(src->y, src->y_stride, dst->y, dst->y_stride,
+ src_buf->width, src_buf->height);
+ WebPCopyPlane(src->u, src->u_stride, dst->u, dst->u_stride,
+ (src_buf->width + 1) / 2, (src_buf->height + 1) / 2);
+ WebPCopyPlane(src->v, src->v_stride, dst->v, dst->v_stride,
+ (src_buf->width + 1) / 2, (src_buf->height + 1) / 2);
+ if (WebPIsAlphaMode(src_buf->colorspace)) {
+ WebPCopyPlane(src->a, src->a_stride, dst->a, dst->a_stride,
+ src_buf->width, src_buf->height);
+ }
+ }
+ return VP8_STATUS_OK;
+}
+
+int WebPAvoidSlowMemory(const WebPDecBuffer* const output,
+ const WebPBitstreamFeatures* const features) {
+ assert(output != NULL);
+ return (output->is_external_memory >= 2) &&
+ WebPIsPremultipliedMode(output->colorspace) &&
+ (features != NULL && features->has_alpha);
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dec/common_dec.h b/media/libwebp/dec/common_dec.h
new file mode 100644
index 000000000..6961e2247
--- /dev/null
+++ b/media/libwebp/dec/common_dec.h
@@ -0,0 +1,54 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Definitions and macros common to encoding and decoding
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_DEC_COMMON_H_
+#define WEBP_DEC_COMMON_H_
+
+// intra prediction modes
+enum { B_DC_PRED = 0, // 4x4 modes
+ B_TM_PRED = 1,
+ B_VE_PRED = 2,
+ B_HE_PRED = 3,
+ B_RD_PRED = 4,
+ B_VR_PRED = 5,
+ B_LD_PRED = 6,
+ B_VL_PRED = 7,
+ B_HD_PRED = 8,
+ B_HU_PRED = 9,
+ NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED, // = 10
+
+ // Luma16 or UV modes
+ DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
+ H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED,
+ B_PRED = NUM_BMODES, // refined I4x4 mode
+ NUM_PRED_MODES = 4,
+
+ // special modes
+ B_DC_PRED_NOTOP = 4,
+ B_DC_PRED_NOLEFT = 5,
+ B_DC_PRED_NOTOPLEFT = 6,
+ NUM_B_DC_MODES = 7 };
+
+enum { MB_FEATURE_TREE_PROBS = 3,
+ NUM_MB_SEGMENTS = 4,
+ NUM_REF_LF_DELTAS = 4,
+ NUM_MODE_LF_DELTAS = 4, // I4x4, ZERO, *, SPLIT
+ MAX_NUM_PARTITIONS = 8,
+ // Probabilities
+ NUM_TYPES = 4, // 0: i16-AC, 1: i16-DC, 2:chroma-AC, 3:i4-AC
+ NUM_BANDS = 8,
+ NUM_CTX = 3,
+ NUM_PROBAS = 11
+ };
+
+#endif // WEBP_DEC_COMMON_H_
diff --git a/media/libwebp/dec/frame_dec.c b/media/libwebp/dec/frame_dec.c
new file mode 100644
index 000000000..f91e27f7c
--- /dev/null
+++ b/media/libwebp/dec/frame_dec.c
@@ -0,0 +1,812 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Frame-reconstruction function. Memory allocation.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <stdlib.h>
+#include "./vp8i_dec.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Main reconstruction function.
+
+static const int kScan[16] = {
+ 0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS,
+ 0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * BPS,
+ 0 + 8 * BPS, 4 + 8 * BPS, 8 + 8 * BPS, 12 + 8 * BPS,
+ 0 + 12 * BPS, 4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS
+};
+
+static int CheckMode(int mb_x, int mb_y, int mode) {
+ if (mode == B_DC_PRED) {
+ if (mb_x == 0) {
+ return (mb_y == 0) ? B_DC_PRED_NOTOPLEFT : B_DC_PRED_NOLEFT;
+ } else {
+ return (mb_y == 0) ? B_DC_PRED_NOTOP : B_DC_PRED;
+ }
+ }
+ return mode;
+}
+
+static void Copy32b(uint8_t* const dst, const uint8_t* const src) {
+ memcpy(dst, src, 4);
+}
+
+static WEBP_INLINE void DoTransform(uint32_t bits, const int16_t* const src,
+ uint8_t* const dst) {
+ switch (bits >> 30) {
+ case 3:
+ VP8Transform(src, dst, 0);
+ break;
+ case 2:
+ VP8TransformAC3(src, dst);
+ break;
+ case 1:
+ VP8TransformDC(src, dst);
+ break;
+ default:
+ break;
+ }
+}
+
+static void DoUVTransform(uint32_t bits, const int16_t* const src,
+ uint8_t* const dst) {
+ if (bits & 0xff) { // any non-zero coeff at all?
+ if (bits & 0xaa) { // any non-zero AC coefficient?
+ VP8TransformUV(src, dst); // note we don't use the AC3 variant for U/V
+ } else {
+ VP8TransformDCUV(src, dst);
+ }
+ }
+}
+
+static void ReconstructRow(const VP8Decoder* const dec,
+ const VP8ThreadContext* ctx) {
+ int j;
+ int mb_x;
+ const int mb_y = ctx->mb_y_;
+ const int cache_id = ctx->id_;
+ uint8_t* const y_dst = dec->yuv_b_ + Y_OFF;
+ uint8_t* const u_dst = dec->yuv_b_ + U_OFF;
+ uint8_t* const v_dst = dec->yuv_b_ + V_OFF;
+
+ // Initialize left-most block.
+ for (j = 0; j < 16; ++j) {
+ y_dst[j * BPS - 1] = 129;
+ }
+ for (j = 0; j < 8; ++j) {
+ u_dst[j * BPS - 1] = 129;
+ v_dst[j * BPS - 1] = 129;
+ }
+
+ // Init top-left sample on left column too.
+ if (mb_y > 0) {
+ y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129;
+ } else {
+ // we only need to do this init once at block (0,0).
+ // Afterward, it remains valid for the whole topmost row.
+ memset(y_dst - BPS - 1, 127, 16 + 4 + 1);
+ memset(u_dst - BPS - 1, 127, 8 + 1);
+ memset(v_dst - BPS - 1, 127, 8 + 1);
+ }
+
+ // Reconstruct one row.
+ for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) {
+ const VP8MBData* const block = ctx->mb_data_ + mb_x;
+
+ // Rotate in the left samples from previously decoded block. We move four
+ // pixels at a time for alignment reason, and because of in-loop filter.
+ if (mb_x > 0) {
+ for (j = -1; j < 16; ++j) {
+ Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]);
+ }
+ for (j = -1; j < 8; ++j) {
+ Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]);
+ Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]);
+ }
+ }
+ {
+ // bring top samples into the cache
+ VP8TopSamples* const top_yuv = dec->yuv_t_ + mb_x;
+ const int16_t* const coeffs = block->coeffs_;
+ uint32_t bits = block->non_zero_y_;
+ int n;
+
+ if (mb_y > 0) {
+ memcpy(y_dst - BPS, top_yuv[0].y, 16);
+ memcpy(u_dst - BPS, top_yuv[0].u, 8);
+ memcpy(v_dst - BPS, top_yuv[0].v, 8);
+ }
+
+ // predict and add residuals
+ if (block->is_i4x4_) { // 4x4
+ uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16);
+
+ if (mb_y > 0) {
+ if (mb_x >= dec->mb_w_ - 1) { // on rightmost border
+ memset(top_right, top_yuv[0].y[15], sizeof(*top_right));
+ } else {
+ memcpy(top_right, top_yuv[1].y, sizeof(*top_right));
+ }
+ }
+ // replicate the top-right pixels below
+ top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0];
+
+ // predict and add residuals for all 4x4 blocks in turn.
+ for (n = 0; n < 16; ++n, bits <<= 2) {
+ uint8_t* const dst = y_dst + kScan[n];
+ VP8PredLuma4[block->imodes_[n]](dst);
+ DoTransform(bits, coeffs + n * 16, dst);
+ }
+ } else { // 16x16
+ const int pred_func = CheckMode(mb_x, mb_y, block->imodes_[0]);
+ VP8PredLuma16[pred_func](y_dst);
+ if (bits != 0) {
+ for (n = 0; n < 16; ++n, bits <<= 2) {
+ DoTransform(bits, coeffs + n * 16, y_dst + kScan[n]);
+ }
+ }
+ }
+ {
+ // Chroma
+ const uint32_t bits_uv = block->non_zero_uv_;
+ const int pred_func = CheckMode(mb_x, mb_y, block->uvmode_);
+ VP8PredChroma8[pred_func](u_dst);
+ VP8PredChroma8[pred_func](v_dst);
+ DoUVTransform(bits_uv >> 0, coeffs + 16 * 16, u_dst);
+ DoUVTransform(bits_uv >> 8, coeffs + 20 * 16, v_dst);
+ }
+
+ // stash away top samples for next block
+ if (mb_y < dec->mb_h_ - 1) {
+ memcpy(top_yuv[0].y, y_dst + 15 * BPS, 16);
+ memcpy(top_yuv[0].u, u_dst + 7 * BPS, 8);
+ memcpy(top_yuv[0].v, v_dst + 7 * BPS, 8);
+ }
+ }
+ // Transfer reconstructed samples from yuv_b_ cache to final destination.
+ {
+ const int y_offset = cache_id * 16 * dec->cache_y_stride_;
+ const int uv_offset = cache_id * 8 * dec->cache_uv_stride_;
+ uint8_t* const y_out = dec->cache_y_ + mb_x * 16 + y_offset;
+ uint8_t* const u_out = dec->cache_u_ + mb_x * 8 + uv_offset;
+ uint8_t* const v_out = dec->cache_v_ + mb_x * 8 + uv_offset;
+ for (j = 0; j < 16; ++j) {
+ memcpy(y_out + j * dec->cache_y_stride_, y_dst + j * BPS, 16);
+ }
+ for (j = 0; j < 8; ++j) {
+ memcpy(u_out + j * dec->cache_uv_stride_, u_dst + j * BPS, 8);
+ memcpy(v_out + j * dec->cache_uv_stride_, v_dst + j * BPS, 8);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Filtering
+
+// kFilterExtraRows[] = How many extra lines are needed on the MB boundary
+// for caching, given a filtering level.
+// Simple filter: up to 2 luma samples are read and 1 is written.
+// Complex filter: up to 4 luma samples are read and 3 are written. Same for
+// U/V, so it's 8 samples total (because of the 2x upsampling).
+static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 };
+
+static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) {
+ const VP8ThreadContext* const ctx = &dec->thread_ctx_;
+ const int cache_id = ctx->id_;
+ const int y_bps = dec->cache_y_stride_;
+ const VP8FInfo* const f_info = ctx->f_info_ + mb_x;
+ uint8_t* const y_dst = dec->cache_y_ + cache_id * 16 * y_bps + mb_x * 16;
+ const int ilevel = f_info->f_ilevel_;
+ const int limit = f_info->f_limit_;
+ if (limit == 0) {
+ return;
+ }
+ assert(limit >= 3);
+ if (dec->filter_type_ == 1) { // simple
+ if (mb_x > 0) {
+ VP8SimpleHFilter16(y_dst, y_bps, limit + 4);
+ }
+ if (f_info->f_inner_) {
+ VP8SimpleHFilter16i(y_dst, y_bps, limit);
+ }
+ if (mb_y > 0) {
+ VP8SimpleVFilter16(y_dst, y_bps, limit + 4);
+ }
+ if (f_info->f_inner_) {
+ VP8SimpleVFilter16i(y_dst, y_bps, limit);
+ }
+ } else { // complex
+ const int uv_bps = dec->cache_uv_stride_;
+ uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8;
+ uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8;
+ const int hev_thresh = f_info->hev_thresh_;
+ if (mb_x > 0) {
+ VP8HFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
+ VP8HFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
+ }
+ if (f_info->f_inner_) {
+ VP8HFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh);
+ VP8HFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh);
+ }
+ if (mb_y > 0) {
+ VP8VFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
+ VP8VFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
+ }
+ if (f_info->f_inner_) {
+ VP8VFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh);
+ VP8VFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh);
+ }
+ }
+}
+
+// Filter the decoded macroblock row (if needed)
+static void FilterRow(const VP8Decoder* const dec) {
+ int mb_x;
+ const int mb_y = dec->thread_ctx_.mb_y_;
+ assert(dec->thread_ctx_.filter_row_);
+ for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) {
+ DoFilter(dec, mb_x, mb_y);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Precompute the filtering strength for each segment and each i4x4/i16x16 mode.
+
+static void PrecomputeFilterStrengths(VP8Decoder* const dec) {
+ if (dec->filter_type_ > 0) {
+ int s;
+ const VP8FilterHeader* const hdr = &dec->filter_hdr_;
+ for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+ int i4x4;
+ // First, compute the initial level
+ int base_level;
+ if (dec->segment_hdr_.use_segment_) {
+ base_level = dec->segment_hdr_.filter_strength_[s];
+ if (!dec->segment_hdr_.absolute_delta_) {
+ base_level += hdr->level_;
+ }
+ } else {
+ base_level = hdr->level_;
+ }
+ for (i4x4 = 0; i4x4 <= 1; ++i4x4) {
+ VP8FInfo* const info = &dec->fstrengths_[s][i4x4];
+ int level = base_level;
+ if (hdr->use_lf_delta_) {
+ level += hdr->ref_lf_delta_[0];
+ if (i4x4) {
+ level += hdr->mode_lf_delta_[0];
+ }
+ }
+ level = (level < 0) ? 0 : (level > 63) ? 63 : level;
+ if (level > 0) {
+ int ilevel = level;
+ if (hdr->sharpness_ > 0) {
+ if (hdr->sharpness_ > 4) {
+ ilevel >>= 2;
+ } else {
+ ilevel >>= 1;
+ }
+ if (ilevel > 9 - hdr->sharpness_) {
+ ilevel = 9 - hdr->sharpness_;
+ }
+ }
+ if (ilevel < 1) ilevel = 1;
+ info->f_ilevel_ = ilevel;
+ info->f_limit_ = 2 * level + ilevel;
+ info->hev_thresh_ = (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
+ } else {
+ info->f_limit_ = 0; // no filtering
+ }
+ info->f_inner_ = i4x4;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Dithering
+
+// minimal amp that will provide a non-zero dithering effect
+#define MIN_DITHER_AMP 4
+
+#define DITHER_AMP_TAB_SIZE 12
+static const int kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = {
+ // roughly, it's dqm->uv_mat_[1]
+ 8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1
+};
+
+void VP8InitDithering(const WebPDecoderOptions* const options,
+ VP8Decoder* const dec) {
+ assert(dec != NULL);
+ if (options != NULL) {
+ const int d = options->dithering_strength;
+ const int max_amp = (1 << VP8_RANDOM_DITHER_FIX) - 1;
+ const int f = (d < 0) ? 0 : (d > 100) ? max_amp : (d * max_amp / 100);
+ if (f > 0) {
+ int s;
+ int all_amp = 0;
+ for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+ VP8QuantMatrix* const dqm = &dec->dqm_[s];
+ if (dqm->uv_quant_ < DITHER_AMP_TAB_SIZE) {
+ // TODO(skal): should we specially dither more for uv_quant_ < 0?
+ const int idx = (dqm->uv_quant_ < 0) ? 0 : dqm->uv_quant_;
+ dqm->dither_ = (f * kQuantToDitherAmp[idx]) >> 3;
+ }
+ all_amp |= dqm->dither_;
+ }
+ if (all_amp != 0) {
+ VP8InitRandom(&dec->dithering_rg_, 1.0f);
+ dec->dither_ = 1;
+ }
+ }
+ // potentially allow alpha dithering
+ dec->alpha_dithering_ = options->alpha_dithering_strength;
+ if (dec->alpha_dithering_ > 100) {
+ dec->alpha_dithering_ = 100;
+ } else if (dec->alpha_dithering_ < 0) {
+ dec->alpha_dithering_ = 0;
+ }
+ }
+}
+
+// Convert to range: [-2,2] for dither=50, [-4,4] for dither=100
+static void Dither8x8(VP8Random* const rg, uint8_t* dst, int bps, int amp) {
+ uint8_t dither[64];
+ int i;
+ for (i = 0; i < 8 * 8; ++i) {
+ dither[i] = VP8RandomBits2(rg, VP8_DITHER_AMP_BITS + 1, amp);
+ }
+ VP8DitherCombine8x8(dither, dst, bps);
+}
+
+static void DitherRow(VP8Decoder* const dec) {
+ int mb_x;
+ assert(dec->dither_);
+ for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) {
+ const VP8ThreadContext* const ctx = &dec->thread_ctx_;
+ const VP8MBData* const data = ctx->mb_data_ + mb_x;
+ const int cache_id = ctx->id_;
+ const int uv_bps = dec->cache_uv_stride_;
+ if (data->dither_ >= MIN_DITHER_AMP) {
+ uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8;
+ uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8;
+ Dither8x8(&dec->dithering_rg_, u_dst, uv_bps, data->dither_);
+ Dither8x8(&dec->dithering_rg_, v_dst, uv_bps, data->dither_);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// This function is called after a row of macroblocks is finished decoding.
+// It also takes into account the following restrictions:
+// * In case of in-loop filtering, we must hold off sending some of the bottom
+// pixels as they are yet unfiltered. They will be when the next macroblock
+// row is decoded. Meanwhile, we must preserve them by rotating them in the
+// cache area. This doesn't hold for the very bottom row of the uncropped
+// picture of course.
+// * we must clip the remaining pixels against the cropping area. The VP8Io
+// struct must have the following fields set correctly before calling put():
+
+#define MACROBLOCK_VPOS(mb_y) ((mb_y) * 16) // vertical position of a MB
+
+// Finalize and transmit a complete row. Return false in case of user-abort.
+static int FinishRow(VP8Decoder* const dec, VP8Io* const io) {
+ int ok = 1;
+ const VP8ThreadContext* const ctx = &dec->thread_ctx_;
+ const int cache_id = ctx->id_;
+ const int extra_y_rows = kFilterExtraRows[dec->filter_type_];
+ const int ysize = extra_y_rows * dec->cache_y_stride_;
+ const int uvsize = (extra_y_rows / 2) * dec->cache_uv_stride_;
+ const int y_offset = cache_id * 16 * dec->cache_y_stride_;
+ const int uv_offset = cache_id * 8 * dec->cache_uv_stride_;
+ uint8_t* const ydst = dec->cache_y_ - ysize + y_offset;
+ uint8_t* const udst = dec->cache_u_ - uvsize + uv_offset;
+ uint8_t* const vdst = dec->cache_v_ - uvsize + uv_offset;
+ const int mb_y = ctx->mb_y_;
+ const int is_first_row = (mb_y == 0);
+ const int is_last_row = (mb_y >= dec->br_mb_y_ - 1);
+
+ if (dec->mt_method_ == 2) {
+ ReconstructRow(dec, ctx);
+ }
+
+ if (ctx->filter_row_) {
+ FilterRow(dec);
+ }
+
+ if (dec->dither_) {
+ DitherRow(dec);
+ }
+
+ if (io->put != NULL) {
+ int y_start = MACROBLOCK_VPOS(mb_y);
+ int y_end = MACROBLOCK_VPOS(mb_y + 1);
+ if (!is_first_row) {
+ y_start -= extra_y_rows;
+ io->y = ydst;
+ io->u = udst;
+ io->v = vdst;
+ } else {
+ io->y = dec->cache_y_ + y_offset;
+ io->u = dec->cache_u_ + uv_offset;
+ io->v = dec->cache_v_ + uv_offset;
+ }
+
+ if (!is_last_row) {
+ y_end -= extra_y_rows;
+ }
+ if (y_end > io->crop_bottom) {
+ y_end = io->crop_bottom; // make sure we don't overflow on last row.
+ }
+ io->a = NULL;
+ if (dec->alpha_data_ != NULL && y_start < y_end) {
+ // TODO(skal): testing presence of alpha with dec->alpha_data_ is not a
+ // good idea.
+ io->a = VP8DecompressAlphaRows(dec, io, y_start, y_end - y_start);
+ if (io->a == NULL) {
+ return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+ "Could not decode alpha data.");
+ }
+ }
+ if (y_start < io->crop_top) {
+ const int delta_y = io->crop_top - y_start;
+ y_start = io->crop_top;
+ assert(!(delta_y & 1));
+ io->y += dec->cache_y_stride_ * delta_y;
+ io->u += dec->cache_uv_stride_ * (delta_y >> 1);
+ io->v += dec->cache_uv_stride_ * (delta_y >> 1);
+ if (io->a != NULL) {
+ io->a += io->width * delta_y;
+ }
+ }
+ if (y_start < y_end) {
+ io->y += io->crop_left;
+ io->u += io->crop_left >> 1;
+ io->v += io->crop_left >> 1;
+ if (io->a != NULL) {
+ io->a += io->crop_left;
+ }
+ io->mb_y = y_start - io->crop_top;
+ io->mb_w = io->crop_right - io->crop_left;
+ io->mb_h = y_end - y_start;
+ ok = io->put(io);
+ }
+ }
+ // rotate top samples if needed
+ if (cache_id + 1 == dec->num_caches_) {
+ if (!is_last_row) {
+ memcpy(dec->cache_y_ - ysize, ydst + 16 * dec->cache_y_stride_, ysize);
+ memcpy(dec->cache_u_ - uvsize, udst + 8 * dec->cache_uv_stride_, uvsize);
+ memcpy(dec->cache_v_ - uvsize, vdst + 8 * dec->cache_uv_stride_, uvsize);
+ }
+ }
+
+ return ok;
+}
+
+#undef MACROBLOCK_VPOS
+
+//------------------------------------------------------------------------------
+
+int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io) {
+ int ok = 1;
+ VP8ThreadContext* const ctx = &dec->thread_ctx_;
+ const int filter_row =
+ (dec->filter_type_ > 0) &&
+ (dec->mb_y_ >= dec->tl_mb_y_) && (dec->mb_y_ <= dec->br_mb_y_);
+ if (dec->mt_method_ == 0) {
+ // ctx->id_ and ctx->f_info_ are already set
+ ctx->mb_y_ = dec->mb_y_;
+ ctx->filter_row_ = filter_row;
+ ReconstructRow(dec, ctx);
+ ok = FinishRow(dec, io);
+ } else {
+ WebPWorker* const worker = &dec->worker_;
+ // Finish previous job *before* updating context
+ ok &= WebPGetWorkerInterface()->Sync(worker);
+ assert(worker->status_ == OK);
+ if (ok) { // spawn a new deblocking/output job
+ ctx->io_ = *io;
+ ctx->id_ = dec->cache_id_;
+ ctx->mb_y_ = dec->mb_y_;
+ ctx->filter_row_ = filter_row;
+ if (dec->mt_method_ == 2) { // swap macroblock data
+ VP8MBData* const tmp = ctx->mb_data_;
+ ctx->mb_data_ = dec->mb_data_;
+ dec->mb_data_ = tmp;
+ } else {
+ // perform reconstruction directly in main thread
+ ReconstructRow(dec, ctx);
+ }
+ if (filter_row) { // swap filter info
+ VP8FInfo* const tmp = ctx->f_info_;
+ ctx->f_info_ = dec->f_info_;
+ dec->f_info_ = tmp;
+ }
+ // (reconstruct)+filter in parallel
+ WebPGetWorkerInterface()->Launch(worker);
+ if (++dec->cache_id_ == dec->num_caches_) {
+ dec->cache_id_ = 0;
+ }
+ }
+ }
+ return ok;
+}
+
+//------------------------------------------------------------------------------
+// Finish setting up the decoding parameter once user's setup() is called.
+
+VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
+ // Call setup() first. This may trigger additional decoding features on 'io'.
+ // Note: Afterward, we must call teardown() no matter what.
+ if (io->setup != NULL && !io->setup(io)) {
+ VP8SetError(dec, VP8_STATUS_USER_ABORT, "Frame setup failed");
+ return dec->status_;
+ }
+
+ // Disable filtering per user request
+ if (io->bypass_filtering) {
+ dec->filter_type_ = 0;
+ }
+ // TODO(skal): filter type / strength / sharpness forcing
+
+ // Define the area where we can skip in-loop filtering, in case of cropping.
+ //
+ // 'Simple' filter reads two luma samples outside of the macroblock
+ // and filters one. It doesn't filter the chroma samples. Hence, we can
+ // avoid doing the in-loop filtering before crop_top/crop_left position.
+ // For the 'Complex' filter, 3 samples are read and up to 3 are filtered.
+ // Means: there's a dependency chain that goes all the way up to the
+ // top-left corner of the picture (MB #0). We must filter all the previous
+ // macroblocks.
+ // TODO(skal): add an 'approximate_decoding' option, that won't produce
+ // a 1:1 bit-exactness for complex filtering?
+ {
+ const int extra_pixels = kFilterExtraRows[dec->filter_type_];
+ if (dec->filter_type_ == 2) {
+ // For complex filter, we need to preserve the dependency chain.
+ dec->tl_mb_x_ = 0;
+ dec->tl_mb_y_ = 0;
+ } else {
+ // For simple filter, we can filter only the cropped region.
+ // We include 'extra_pixels' on the other side of the boundary, since
+ // vertical or horizontal filtering of the previous macroblock can
+ // modify some abutting pixels.
+ dec->tl_mb_x_ = (io->crop_left - extra_pixels) >> 4;
+ dec->tl_mb_y_ = (io->crop_top - extra_pixels) >> 4;
+ if (dec->tl_mb_x_ < 0) dec->tl_mb_x_ = 0;
+ if (dec->tl_mb_y_ < 0) dec->tl_mb_y_ = 0;
+ }
+ // We need some 'extra' pixels on the right/bottom.
+ dec->br_mb_y_ = (io->crop_bottom + 15 + extra_pixels) >> 4;
+ dec->br_mb_x_ = (io->crop_right + 15 + extra_pixels) >> 4;
+ if (dec->br_mb_x_ > dec->mb_w_) {
+ dec->br_mb_x_ = dec->mb_w_;
+ }
+ if (dec->br_mb_y_ > dec->mb_h_) {
+ dec->br_mb_y_ = dec->mb_h_;
+ }
+ }
+ PrecomputeFilterStrengths(dec);
+ return VP8_STATUS_OK;
+}
+
+int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io) {
+ int ok = 1;
+ if (dec->mt_method_ > 0) {
+ ok = WebPGetWorkerInterface()->Sync(&dec->worker_);
+ }
+
+ if (io->teardown != NULL) {
+ io->teardown(io);
+ }
+ return ok;
+}
+
+//------------------------------------------------------------------------------
+// For multi-threaded decoding we need to use 3 rows of 16 pixels as delay line.
+//
+// Reason is: the deblocking filter cannot deblock the bottom horizontal edges
+// immediately, and needs to wait for first few rows of the next macroblock to
+// be decoded. Hence, deblocking is lagging behind by 4 or 8 pixels (depending
+// on strength).
+// With two threads, the vertical positions of the rows being decoded are:
+// Decode: [ 0..15][16..31][32..47][48..63][64..79][...
+// Deblock: [ 0..11][12..27][28..43][44..59][...
+// If we use two threads and two caches of 16 pixels, the sequence would be:
+// Decode: [ 0..15][16..31][ 0..15!!][16..31][ 0..15][...
+// Deblock: [ 0..11][12..27!!][-4..11][12..27][...
+// The problem occurs during row [12..15!!] that both the decoding and
+// deblocking threads are writing simultaneously.
+// With 3 cache lines, one get a safe write pattern:
+// Decode: [ 0..15][16..31][32..47][ 0..15][16..31][32..47][0..
+// Deblock: [ 0..11][12..27][28..43][-4..11][12..27][28...
+// Note that multi-threaded output _without_ deblocking can make use of two
+// cache lines of 16 pixels only, since there's no lagging behind. The decoding
+// and output process have non-concurrent writing:
+// Decode: [ 0..15][16..31][ 0..15][16..31][...
+// io->put: [ 0..15][16..31][ 0..15][...
+
+#define MT_CACHE_LINES 3
+#define ST_CACHE_LINES 1 // 1 cache row only for single-threaded case
+
+// Initialize multi/single-thread worker
+static int InitThreadContext(VP8Decoder* const dec) {
+ dec->cache_id_ = 0;
+ if (dec->mt_method_ > 0) {
+ WebPWorker* const worker = &dec->worker_;
+ if (!WebPGetWorkerInterface()->Reset(worker)) {
+ return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
+ "thread initialization failed.");
+ }
+ worker->data1 = dec;
+ worker->data2 = (void*)&dec->thread_ctx_.io_;
+ worker->hook = (WebPWorkerHook)FinishRow;
+ dec->num_caches_ =
+ (dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
+ } else {
+ dec->num_caches_ = ST_CACHE_LINES;
+ }
+ return 1;
+}
+
+int VP8GetThreadMethod(const WebPDecoderOptions* const options,
+ const WebPHeaderStructure* const headers,
+ int width, int height) {
+ if (options == NULL || options->use_threads == 0) {
+ return 0;
+ }
+ (void)headers;
+ (void)width;
+ (void)height;
+ assert(headers == NULL || !headers->is_lossless);
+#if defined(WEBP_USE_THREAD)
+ if (width < MIN_WIDTH_FOR_THREADS) return 0;
+ // TODO(skal): tune the heuristic further
+#if 0
+ if (height < 2 * width) return 2;
+#endif
+ return 2;
+#else // !WEBP_USE_THREAD
+ return 0;
+#endif
+}
+
+#undef MT_CACHE_LINES
+#undef ST_CACHE_LINES
+
+//------------------------------------------------------------------------------
+// Memory setup
+
+static int AllocateMemory(VP8Decoder* const dec) {
+ const int num_caches = dec->num_caches_;
+ const int mb_w = dec->mb_w_;
+ // Note: we use 'size_t' when there's no overflow risk, uint64_t otherwise.
+ const size_t intra_pred_mode_size = 4 * mb_w * sizeof(uint8_t);
+ const size_t top_size = sizeof(VP8TopSamples) * mb_w;
+ const size_t mb_info_size = (mb_w + 1) * sizeof(VP8MB);
+ const size_t f_info_size =
+ (dec->filter_type_ > 0) ?
+ mb_w * (dec->mt_method_ > 0 ? 2 : 1) * sizeof(VP8FInfo)
+ : 0;
+ const size_t yuv_size = YUV_SIZE * sizeof(*dec->yuv_b_);
+ const size_t mb_data_size =
+ (dec->mt_method_ == 2 ? 2 : 1) * mb_w * sizeof(*dec->mb_data_);
+ const size_t cache_height = (16 * num_caches
+ + kFilterExtraRows[dec->filter_type_]) * 3 / 2;
+ const size_t cache_size = top_size * cache_height;
+ // alpha_size is the only one that scales as width x height.
+ const uint64_t alpha_size = (dec->alpha_data_ != NULL) ?
+ (uint64_t)dec->pic_hdr_.width_ * dec->pic_hdr_.height_ : 0ULL;
+ const uint64_t needed = (uint64_t)intra_pred_mode_size
+ + top_size + mb_info_size + f_info_size
+ + yuv_size + mb_data_size
+ + cache_size + alpha_size + WEBP_ALIGN_CST;
+ uint8_t* mem;
+
+ if (needed != (size_t)needed) return 0; // check for overflow
+ if (needed > dec->mem_size_) {
+ WebPSafeFree(dec->mem_);
+ dec->mem_size_ = 0;
+ dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t));
+ if (dec->mem_ == NULL) {
+ return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
+ "no memory during frame initialization.");
+ }
+ // down-cast is ok, thanks to WebPSafeMalloc() above.
+ dec->mem_size_ = (size_t)needed;
+ }
+
+ mem = (uint8_t*)dec->mem_;
+ dec->intra_t_ = (uint8_t*)mem;
+ mem += intra_pred_mode_size;
+
+ dec->yuv_t_ = (VP8TopSamples*)mem;
+ mem += top_size;
+
+ dec->mb_info_ = ((VP8MB*)mem) + 1;
+ mem += mb_info_size;
+
+ dec->f_info_ = f_info_size ? (VP8FInfo*)mem : NULL;
+ mem += f_info_size;
+ dec->thread_ctx_.id_ = 0;
+ dec->thread_ctx_.f_info_ = dec->f_info_;
+ if (dec->mt_method_ > 0) {
+ // secondary cache line. The deblocking process need to make use of the
+ // filtering strength from previous macroblock row, while the new ones
+ // are being decoded in parallel. We'll just swap the pointers.
+ dec->thread_ctx_.f_info_ += mb_w;
+ }
+
+ mem = (uint8_t*)WEBP_ALIGN(mem);
+ assert((yuv_size & WEBP_ALIGN_CST) == 0);
+ dec->yuv_b_ = (uint8_t*)mem;
+ mem += yuv_size;
+
+ dec->mb_data_ = (VP8MBData*)mem;
+ dec->thread_ctx_.mb_data_ = (VP8MBData*)mem;
+ if (dec->mt_method_ == 2) {
+ dec->thread_ctx_.mb_data_ += mb_w;
+ }
+ mem += mb_data_size;
+
+ dec->cache_y_stride_ = 16 * mb_w;
+ dec->cache_uv_stride_ = 8 * mb_w;
+ {
+ const int extra_rows = kFilterExtraRows[dec->filter_type_];
+ const int extra_y = extra_rows * dec->cache_y_stride_;
+ const int extra_uv = (extra_rows / 2) * dec->cache_uv_stride_;
+ dec->cache_y_ = ((uint8_t*)mem) + extra_y;
+ dec->cache_u_ = dec->cache_y_
+ + 16 * num_caches * dec->cache_y_stride_ + extra_uv;
+ dec->cache_v_ = dec->cache_u_
+ + 8 * num_caches * dec->cache_uv_stride_ + extra_uv;
+ dec->cache_id_ = 0;
+ }
+ mem += cache_size;
+
+ // alpha plane
+ dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
+ mem += alpha_size;
+ assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
+
+ // note: left/top-info is initialized once for all.
+ memset(dec->mb_info_ - 1, 0, mb_info_size);
+ VP8InitScanline(dec); // initialize left too.
+
+ // initialize top
+ memset(dec->intra_t_, B_DC_PRED, intra_pred_mode_size);
+
+ return 1;
+}
+
+static void InitIo(VP8Decoder* const dec, VP8Io* io) {
+ // prepare 'io'
+ io->mb_y = 0;
+ io->y = dec->cache_y_;
+ io->u = dec->cache_u_;
+ io->v = dec->cache_v_;
+ io->y_stride = dec->cache_y_stride_;
+ io->uv_stride = dec->cache_uv_stride_;
+ io->a = NULL;
+}
+
+int VP8InitFrame(VP8Decoder* const dec, VP8Io* const io) {
+ if (!InitThreadContext(dec)) return 0; // call first. Sets dec->num_caches_.
+ if (!AllocateMemory(dec)) return 0;
+ InitIo(dec, io);
+ VP8DspInit(); // Init critical function pointers and look-up tables.
+ return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dec/idec_dec.c b/media/libwebp/dec/idec_dec.c
new file mode 100644
index 000000000..78fb2e718
--- /dev/null
+++ b/media/libwebp/dec/idec_dec.c
@@ -0,0 +1,892 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Incremental decoding
+//
+// Author: somnath@google.com (Somnath Banerjee)
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "./alphai_dec.h"
+#include "./webpi_dec.h"
+#include "./vp8i_dec.h"
+#include "../utils/utils.h"
+
+// In append mode, buffer allocations increase as multiples of this value.
+// Needs to be a power of 2.
+#define CHUNK_SIZE 4096
+#define MAX_MB_SIZE 4096
+
+//------------------------------------------------------------------------------
+// Data structures for memory and states
+
+// Decoding states. State normally flows as:
+// WEBP_HEADER->VP8_HEADER->VP8_PARTS0->VP8_DATA->DONE for a lossy image, and
+// WEBP_HEADER->VP8L_HEADER->VP8L_DATA->DONE for a lossless image.
+// If there is any error the decoder goes into state ERROR.
+typedef enum {
+ STATE_WEBP_HEADER, // All the data before that of the VP8/VP8L chunk.
+ STATE_VP8_HEADER, // The VP8 Frame header (within the VP8 chunk).
+ STATE_VP8_PARTS0,
+ STATE_VP8_DATA,
+ STATE_VP8L_HEADER,
+ STATE_VP8L_DATA,
+ STATE_DONE,
+ STATE_ERROR
+} DecState;
+
+// Operating state for the MemBuffer
+typedef enum {
+ MEM_MODE_NONE = 0,
+ MEM_MODE_APPEND,
+ MEM_MODE_MAP
+} MemBufferMode;
+
+// storage for partition #0 and partial data (in a rolling fashion)
+typedef struct {
+ MemBufferMode mode_; // Operation mode
+ size_t start_; // start location of the data to be decoded
+ size_t end_; // end location
+ size_t buf_size_; // size of the allocated buffer
+ uint8_t* buf_; // We don't own this buffer in case WebPIUpdate()
+
+ size_t part0_size_; // size of partition #0
+ const uint8_t* part0_buf_; // buffer to store partition #0
+} MemBuffer;
+
+struct WebPIDecoder {
+ DecState state_; // current decoding state
+ WebPDecParams params_; // Params to store output info
+ int is_lossless_; // for down-casting 'dec_'.
+ void* dec_; // either a VP8Decoder or a VP8LDecoder instance
+ VP8Io io_;
+
+ MemBuffer mem_; // input memory buffer.
+ WebPDecBuffer output_; // output buffer (when no external one is supplied,
+ // or if the external one has slow-memory)
+ WebPDecBuffer* final_output_; // Slow-memory output to copy to eventually.
+ size_t chunk_size_; // Compressed VP8/VP8L size extracted from Header.
+
+ int last_mb_y_; // last row reached for intra-mode decoding
+};
+
+// MB context to restore in case VP8DecodeMB() fails
+typedef struct {
+ VP8MB left_;
+ VP8MB info_;
+ VP8BitReader token_br_;
+} MBContext;
+
+//------------------------------------------------------------------------------
+// MemBuffer: incoming data handling
+
+static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) {
+ return (mem->end_ - mem->start_);
+}
+
+// Check if we need to preserve the compressed alpha data, as it may not have
+// been decoded yet.
+static int NeedCompressedAlpha(const WebPIDecoder* const idec) {
+ if (idec->state_ == STATE_WEBP_HEADER) {
+ // We haven't parsed the headers yet, so we don't know whether the image is
+ // lossy or lossless. This also means that we haven't parsed the ALPH chunk.
+ return 0;
+ }
+ if (idec->is_lossless_) {
+ return 0; // ALPH chunk is not present for lossless images.
+ } else {
+ const VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+ assert(dec != NULL); // Must be true as idec->state_ != STATE_WEBP_HEADER.
+ return (dec->alpha_data_ != NULL) && !dec->is_alpha_decoded_;
+ }
+}
+
+static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
+ MemBuffer* const mem = &idec->mem_;
+ const uint8_t* const new_base = mem->buf_ + mem->start_;
+ // note: for VP8, setting up idec->io_ is only really needed at the beginning
+ // of the decoding, till partition #0 is complete.
+ idec->io_.data = new_base;
+ idec->io_.data_size = MemDataSize(mem);
+
+ if (idec->dec_ != NULL) {
+ if (!idec->is_lossless_) {
+ VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+ const uint32_t last_part = dec->num_parts_minus_one_;
+ if (offset != 0) {
+ uint32_t p;
+ for (p = 0; p <= last_part; ++p) {
+ VP8RemapBitReader(dec->parts_ + p, offset);
+ }
+ // Remap partition #0 data pointer to new offset, but only in MAP
+ // mode (in APPEND mode, partition #0 is copied into a fixed memory).
+ if (mem->mode_ == MEM_MODE_MAP) {
+ VP8RemapBitReader(&dec->br_, offset);
+ }
+ }
+ {
+ const uint8_t* const last_start = dec->parts_[last_part].buf_;
+ VP8BitReaderSetBuffer(&dec->parts_[last_part], last_start,
+ mem->buf_ + mem->end_ - last_start);
+ }
+ if (NeedCompressedAlpha(idec)) {
+ ALPHDecoder* const alph_dec = dec->alph_dec_;
+ dec->alpha_data_ += offset;
+ if (alph_dec != NULL) {
+ if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
+ VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
+ assert(alph_vp8l_dec != NULL);
+ assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
+ VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
+ dec->alpha_data_ + ALPHA_HEADER_LEN,
+ dec->alpha_data_size_ - ALPHA_HEADER_LEN);
+ } else { // alph_dec->method_ == ALPHA_NO_COMPRESSION
+ // Nothing special to do in this case.
+ }
+ }
+ }
+ } else { // Resize lossless bitreader
+ VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
+ VP8LBitReaderSetBuffer(&dec->br_, new_base, MemDataSize(mem));
+ }
+ }
+}
+
+// Appends data to the end of MemBuffer->buf_. It expands the allocated memory
+// size if required and also updates VP8BitReader's if new memory is allocated.
+static int AppendToMemBuffer(WebPIDecoder* const idec,
+ const uint8_t* const data, size_t data_size) {
+ VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+ MemBuffer* const mem = &idec->mem_;
+ const int need_compressed_alpha = NeedCompressedAlpha(idec);
+ const uint8_t* const old_start = mem->buf_ + mem->start_;
+ const uint8_t* const old_base =
+ need_compressed_alpha ? dec->alpha_data_ : old_start;
+ assert(mem->mode_ == MEM_MODE_APPEND);
+ if (data_size > MAX_CHUNK_PAYLOAD) {
+ // security safeguard: trying to allocate more than what the format
+ // allows for a chunk should be considered a smoke smell.
+ return 0;
+ }
+
+ if (mem->end_ + data_size > mem->buf_size_) { // Need some free memory
+ const size_t new_mem_start = old_start - old_base;
+ const size_t current_size = MemDataSize(mem) + new_mem_start;
+ const uint64_t new_size = (uint64_t)current_size + data_size;
+ const uint64_t extra_size = (new_size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
+ uint8_t* const new_buf =
+ (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
+ if (new_buf == NULL) return 0;
+ memcpy(new_buf, old_base, current_size);
+ WebPSafeFree(mem->buf_);
+ mem->buf_ = new_buf;
+ mem->buf_size_ = (size_t)extra_size;
+ mem->start_ = new_mem_start;
+ mem->end_ = current_size;
+ }
+
+ memcpy(mem->buf_ + mem->end_, data, data_size);
+ mem->end_ += data_size;
+ assert(mem->end_ <= mem->buf_size_);
+
+ DoRemap(idec, mem->buf_ + mem->start_ - old_start);
+ return 1;
+}
+
+static int RemapMemBuffer(WebPIDecoder* const idec,
+ const uint8_t* const data, size_t data_size) {
+ MemBuffer* const mem = &idec->mem_;
+ const uint8_t* const old_buf = mem->buf_;
+ const uint8_t* const old_start = old_buf + mem->start_;
+ assert(mem->mode_ == MEM_MODE_MAP);
+
+ if (data_size < mem->buf_size_) return 0; // can't remap to a shorter buffer!
+
+ mem->buf_ = (uint8_t*)data;
+ mem->end_ = mem->buf_size_ = data_size;
+
+ DoRemap(idec, mem->buf_ + mem->start_ - old_start);
+ return 1;
+}
+
+static void InitMemBuffer(MemBuffer* const mem) {
+ mem->mode_ = MEM_MODE_NONE;
+ mem->buf_ = NULL;
+ mem->buf_size_ = 0;
+ mem->part0_buf_ = NULL;
+ mem->part0_size_ = 0;
+}
+
+static void ClearMemBuffer(MemBuffer* const mem) {
+ assert(mem);
+ if (mem->mode_ == MEM_MODE_APPEND) {
+ WebPSafeFree(mem->buf_);
+ WebPSafeFree((void*)mem->part0_buf_);
+ }
+}
+
+static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) {
+ if (mem->mode_ == MEM_MODE_NONE) {
+ mem->mode_ = expected; // switch to the expected mode
+ } else if (mem->mode_ != expected) {
+ return 0; // we mixed the modes => error
+ }
+ assert(mem->mode_ == expected); // mode is ok
+ return 1;
+}
+
+// To be called last.
+static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
+ const WebPDecoderOptions* const options = idec->params_.options;
+ WebPDecBuffer* const output = idec->params_.output;
+
+ idec->state_ = STATE_DONE;
+ if (options != NULL && options->flip) {
+ const VP8StatusCode status = WebPFlipBuffer(output);
+ if (status != VP8_STATUS_OK) return status;
+ }
+ if (idec->final_output_ != NULL) {
+ WebPCopyDecBufferPixels(output, idec->final_output_); // do the slow-copy
+ WebPFreeDecBuffer(&idec->output_);
+ *output = *idec->final_output_;
+ idec->final_output_ = NULL;
+ }
+ return VP8_STATUS_OK;
+}
+
+//------------------------------------------------------------------------------
+// Macroblock-decoding contexts
+
+static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br,
+ MBContext* const context) {
+ context->left_ = dec->mb_info_[-1];
+ context->info_ = dec->mb_info_[dec->mb_x_];
+ context->token_br_ = *token_br;
+}
+
+static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
+ VP8BitReader* const token_br) {
+ dec->mb_info_[-1] = context->left_;
+ dec->mb_info_[dec->mb_x_] = context->info_;
+ *token_br = context->token_br_;
+}
+
+//------------------------------------------------------------------------------
+
+static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
+ if (idec->state_ == STATE_VP8_DATA) {
+ VP8Io* const io = &idec->io_;
+ if (io->teardown != NULL) {
+ io->teardown(io);
+ }
+ }
+ idec->state_ = STATE_ERROR;
+ return error;
+}
+
+static void ChangeState(WebPIDecoder* const idec, DecState new_state,
+ size_t consumed_bytes) {
+ MemBuffer* const mem = &idec->mem_;
+ idec->state_ = new_state;
+ mem->start_ += consumed_bytes;
+ assert(mem->start_ <= mem->end_);
+ idec->io_.data = mem->buf_ + mem->start_;
+ idec->io_.data_size = MemDataSize(mem);
+}
+
+// Headers
+static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) {
+ MemBuffer* const mem = &idec->mem_;
+ const uint8_t* data = mem->buf_ + mem->start_;
+ size_t curr_size = MemDataSize(mem);
+ VP8StatusCode status;
+ WebPHeaderStructure headers;
+
+ headers.data = data;
+ headers.data_size = curr_size;
+ headers.have_all_data = 0;
+ status = WebPParseHeaders(&headers);
+ if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
+ return VP8_STATUS_SUSPENDED; // We haven't found a VP8 chunk yet.
+ } else if (status != VP8_STATUS_OK) {
+ return IDecError(idec, status);
+ }
+
+ idec->chunk_size_ = headers.compressed_size;
+ idec->is_lossless_ = headers.is_lossless;
+ if (!idec->is_lossless_) {
+ VP8Decoder* const dec = VP8New();
+ if (dec == NULL) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ idec->dec_ = dec;
+ dec->alpha_data_ = headers.alpha_data;
+ dec->alpha_data_size_ = headers.alpha_data_size;
+ ChangeState(idec, STATE_VP8_HEADER, headers.offset);
+ } else {
+ VP8LDecoder* const dec = VP8LNew();
+ if (dec == NULL) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ idec->dec_ = dec;
+ ChangeState(idec, STATE_VP8L_HEADER, headers.offset);
+ }
+ return VP8_STATUS_OK;
+}
+
+static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) {
+ const uint8_t* data = idec->mem_.buf_ + idec->mem_.start_;
+ const size_t curr_size = MemDataSize(&idec->mem_);
+ int width, height;
+ uint32_t bits;
+
+ if (curr_size < VP8_FRAME_HEADER_SIZE) {
+ // Not enough data bytes to extract VP8 Frame Header.
+ return VP8_STATUS_SUSPENDED;
+ }
+ if (!VP8GetInfo(data, curr_size, idec->chunk_size_, &width, &height)) {
+ return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+ }
+
+ bits = data[0] | (data[1] << 8) | (data[2] << 16);
+ idec->mem_.part0_size_ = (bits >> 5) + VP8_FRAME_HEADER_SIZE;
+
+ idec->io_.data = data;
+ idec->io_.data_size = curr_size;
+ idec->state_ = STATE_VP8_PARTS0;
+ return VP8_STATUS_OK;
+}
+
+// Partition #0
+static VP8StatusCode CopyParts0Data(WebPIDecoder* const idec) {
+ VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+ VP8BitReader* const br = &dec->br_;
+ const size_t part_size = br->buf_end_ - br->buf_;
+ MemBuffer* const mem = &idec->mem_;
+ assert(!idec->is_lossless_);
+ assert(mem->part0_buf_ == NULL);
+ // the following is a format limitation, no need for runtime check:
+ assert(part_size <= mem->part0_size_);
+ if (part_size == 0) { // can't have zero-size partition #0
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ if (mem->mode_ == MEM_MODE_APPEND) {
+ // We copy and grab ownership of the partition #0 data.
+ uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, part_size);
+ if (part0_buf == NULL) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ memcpy(part0_buf, br->buf_, part_size);
+ mem->part0_buf_ = part0_buf;
+ VP8BitReaderSetBuffer(br, part0_buf, part_size);
+ } else {
+ // Else: just keep pointers to the partition #0's data in dec_->br_.
+ }
+ mem->start_ += part_size;
+ return VP8_STATUS_OK;
+}
+
+static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
+ VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+ VP8Io* const io = &idec->io_;
+ const WebPDecParams* const params = &idec->params_;
+ WebPDecBuffer* const output = params->output;
+
+ // Wait till we have enough data for the whole partition #0
+ if (MemDataSize(&idec->mem_) < idec->mem_.part0_size_) {
+ return VP8_STATUS_SUSPENDED;
+ }
+
+ if (!VP8GetHeaders(dec, io)) {
+ const VP8StatusCode status = dec->status_;
+ if (status == VP8_STATUS_SUSPENDED ||
+ status == VP8_STATUS_NOT_ENOUGH_DATA) {
+ // treating NOT_ENOUGH_DATA as SUSPENDED state
+ return VP8_STATUS_SUSPENDED;
+ }
+ return IDecError(idec, status);
+ }
+
+ // Allocate/Verify output buffer now
+ dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
+ output);
+ if (dec->status_ != VP8_STATUS_OK) {
+ return IDecError(idec, dec->status_);
+ }
+ // This change must be done before calling VP8InitFrame()
+ dec->mt_method_ = VP8GetThreadMethod(params->options, NULL,
+ io->width, io->height);
+ VP8InitDithering(params->options, dec);
+
+ dec->status_ = CopyParts0Data(idec);
+ if (dec->status_ != VP8_STATUS_OK) {
+ return IDecError(idec, dec->status_);
+ }
+
+ // Finish setting up the decoding parameters. Will call io->setup().
+ if (VP8EnterCritical(dec, io) != VP8_STATUS_OK) {
+ return IDecError(idec, dec->status_);
+ }
+
+ // Note: past this point, teardown() must always be called
+ // in case of error.
+ idec->state_ = STATE_VP8_DATA;
+ // Allocate memory and prepare everything.
+ if (!VP8InitFrame(dec, io)) {
+ return IDecError(idec, dec->status_);
+ }
+ return VP8_STATUS_OK;
+}
+
+// Remaining partitions
+static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
+ VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
+ VP8Io* const io = &idec->io_;
+
+ assert(dec->ready_);
+ for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
+ if (idec->last_mb_y_ != dec->mb_y_) {
+ if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
+ // note: normally, error shouldn't occur since we already have the whole
+ // partition0 available here in DecodeRemaining(). Reaching EOF while
+ // reading intra modes really means a BITSTREAM_ERROR.
+ return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+ }
+ idec->last_mb_y_ = dec->mb_y_;
+ }
+ for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
+ VP8BitReader* const token_br =
+ &dec->parts_[dec->mb_y_ & dec->num_parts_minus_one_];
+ MBContext context;
+ SaveContext(dec, token_br, &context);
+ if (!VP8DecodeMB(dec, token_br)) {
+ // We shouldn't fail when MAX_MB data was available
+ if (dec->num_parts_minus_one_ == 0 &&
+ MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
+ return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
+ }
+ RestoreContext(&context, dec, token_br);
+ return VP8_STATUS_SUSPENDED;
+ }
+ // Release buffer only if there is only one partition
+ if (dec->num_parts_minus_one_ == 0) {
+ idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_;
+ assert(idec->mem_.start_ <= idec->mem_.end_);
+ }
+ }
+ VP8InitScanline(dec); // Prepare for next scanline
+
+ // Reconstruct, filter and emit the row.
+ if (!VP8ProcessRow(dec, io)) {
+ return IDecError(idec, VP8_STATUS_USER_ABORT);
+ }
+ }
+ // Synchronize the thread and check for errors.
+ if (!VP8ExitCritical(dec, io)) {
+ return IDecError(idec, VP8_STATUS_USER_ABORT);
+ }
+ dec->ready_ = 0;
+ return FinishDecoding(idec);
+}
+
+static VP8StatusCode ErrorStatusLossless(WebPIDecoder* const idec,
+ VP8StatusCode status) {
+ if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) {
+ return VP8_STATUS_SUSPENDED;
+ }
+ return IDecError(idec, status);
+}
+
+static VP8StatusCode DecodeVP8LHeader(WebPIDecoder* const idec) {
+ VP8Io* const io = &idec->io_;
+ VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
+ const WebPDecParams* const params = &idec->params_;
+ WebPDecBuffer* const output = params->output;
+ size_t curr_size = MemDataSize(&idec->mem_);
+ assert(idec->is_lossless_);
+
+ // Wait until there's enough data for decoding header.
+ if (curr_size < (idec->chunk_size_ >> 3)) {
+ dec->status_ = VP8_STATUS_SUSPENDED;
+ return ErrorStatusLossless(idec, dec->status_);
+ }
+
+ if (!VP8LDecodeHeader(dec, io)) {
+ if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR &&
+ curr_size < idec->chunk_size_) {
+ dec->status_ = VP8_STATUS_SUSPENDED;
+ }
+ return ErrorStatusLossless(idec, dec->status_);
+ }
+ // Allocate/verify output buffer now.
+ dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
+ output);
+ if (dec->status_ != VP8_STATUS_OK) {
+ return IDecError(idec, dec->status_);
+ }
+
+ idec->state_ = STATE_VP8L_DATA;
+ return VP8_STATUS_OK;
+}
+
+static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) {
+ VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
+ const size_t curr_size = MemDataSize(&idec->mem_);
+ assert(idec->is_lossless_);
+
+ // Switch to incremental decoding if we don't have all the bytes available.
+ dec->incremental_ = (curr_size < idec->chunk_size_);
+
+ if (!VP8LDecodeImage(dec)) {
+ return ErrorStatusLossless(idec, dec->status_);
+ }
+ assert(dec->status_ == VP8_STATUS_OK || dec->status_ == VP8_STATUS_SUSPENDED);
+ return (dec->status_ == VP8_STATUS_SUSPENDED) ? dec->status_
+ : FinishDecoding(idec);
+}
+
+ // Main decoding loop
+static VP8StatusCode IDecode(WebPIDecoder* idec) {
+ VP8StatusCode status = VP8_STATUS_SUSPENDED;
+
+ if (idec->state_ == STATE_WEBP_HEADER) {
+ status = DecodeWebPHeaders(idec);
+ } else {
+ if (idec->dec_ == NULL) {
+ return VP8_STATUS_SUSPENDED; // can't continue if we have no decoder.
+ }
+ }
+ if (idec->state_ == STATE_VP8_HEADER) {
+ status = DecodeVP8FrameHeader(idec);
+ }
+ if (idec->state_ == STATE_VP8_PARTS0) {
+ status = DecodePartition0(idec);
+ }
+ if (idec->state_ == STATE_VP8_DATA) {
+ status = DecodeRemaining(idec);
+ }
+ if (idec->state_ == STATE_VP8L_HEADER) {
+ status = DecodeVP8LHeader(idec);
+ }
+ if (idec->state_ == STATE_VP8L_DATA) {
+ status = DecodeVP8LData(idec);
+ }
+ return status;
+}
+
+//------------------------------------------------------------------------------
+// Internal constructor
+
+static WebPIDecoder* NewDecoder(WebPDecBuffer* const output_buffer,
+ const WebPBitstreamFeatures* const features) {
+ WebPIDecoder* idec = (WebPIDecoder*)WebPSafeCalloc(1ULL, sizeof(*idec));
+ if (idec == NULL) {
+ return NULL;
+ }
+
+ idec->state_ = STATE_WEBP_HEADER;
+ idec->chunk_size_ = 0;
+
+ idec->last_mb_y_ = -1;
+
+ InitMemBuffer(&idec->mem_);
+ WebPInitDecBuffer(&idec->output_);
+ VP8InitIo(&idec->io_);
+
+ WebPResetDecParams(&idec->params_);
+ if (output_buffer == NULL || WebPAvoidSlowMemory(output_buffer, features)) {
+ idec->params_.output = &idec->output_;
+ idec->final_output_ = output_buffer;
+ if (output_buffer != NULL) {
+ idec->params_.output->colorspace = output_buffer->colorspace;
+ }
+ } else {
+ idec->params_.output = output_buffer;
+ idec->final_output_ = NULL;
+ }
+ WebPInitCustomIo(&idec->params_, &idec->io_); // Plug the I/O functions.
+
+ return idec;
+}
+
+//------------------------------------------------------------------------------
+// Public functions
+
+WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
+ return NewDecoder(output_buffer, NULL);
+}
+
+WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
+ WebPDecoderConfig* config) {
+ WebPIDecoder* idec;
+ WebPBitstreamFeatures tmp_features;
+ WebPBitstreamFeatures* const features =
+ (config == NULL) ? &tmp_features : &config->input;
+ memset(&tmp_features, 0, sizeof(tmp_features));
+
+ // Parse the bitstream's features, if requested:
+ if (data != NULL && data_size > 0) {
+ if (WebPGetFeatures(data, data_size, features) != VP8_STATUS_OK) {
+ return NULL;
+ }
+ }
+
+ // Create an instance of the incremental decoder
+ idec = (config != NULL) ? NewDecoder(&config->output, features)
+ : NewDecoder(NULL, features);
+ if (idec == NULL) {
+ return NULL;
+ }
+ // Finish initialization
+ if (config != NULL) {
+ idec->params_.options = &config->options;
+ }
+ return idec;
+}
+
+void WebPIDelete(WebPIDecoder* idec) {
+ if (idec == NULL) return;
+ if (idec->dec_ != NULL) {
+ if (!idec->is_lossless_) {
+ if (idec->state_ == STATE_VP8_DATA) {
+ // Synchronize the thread, clean-up and check for errors.
+ VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
+ }
+ VP8Delete((VP8Decoder*)idec->dec_);
+ } else {
+ VP8LDelete((VP8LDecoder*)idec->dec_);
+ }
+ }
+ ClearMemBuffer(&idec->mem_);
+ WebPFreeDecBuffer(&idec->output_);
+ WebPSafeFree(idec);
+}
+
+//------------------------------------------------------------------------------
+// Wrapper toward WebPINewDecoder
+
+WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer,
+ size_t output_buffer_size, int output_stride) {
+ const int is_external_memory = (output_buffer != NULL) ? 1 : 0;
+ WebPIDecoder* idec;
+
+ if (mode >= MODE_YUV) return NULL;
+ if (is_external_memory == 0) { // Overwrite parameters to sane values.
+ output_buffer_size = 0;
+ output_stride = 0;
+ } else { // A buffer was passed. Validate the other params.
+ if (output_stride == 0 || output_buffer_size == 0) {
+ return NULL; // invalid parameter.
+ }
+ }
+ idec = WebPINewDecoder(NULL);
+ if (idec == NULL) return NULL;
+ idec->output_.colorspace = mode;
+ idec->output_.is_external_memory = is_external_memory;
+ idec->output_.u.RGBA.rgba = output_buffer;
+ idec->output_.u.RGBA.stride = output_stride;
+ idec->output_.u.RGBA.size = output_buffer_size;
+ return idec;
+}
+
+WebPIDecoder* WebPINewYUVA(uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride,
+ uint8_t* a, size_t a_size, int a_stride) {
+ const int is_external_memory = (luma != NULL) ? 1 : 0;
+ WebPIDecoder* idec;
+ WEBP_CSP_MODE colorspace;
+
+ if (is_external_memory == 0) { // Overwrite parameters to sane values.
+ luma_size = u_size = v_size = a_size = 0;
+ luma_stride = u_stride = v_stride = a_stride = 0;
+ u = v = a = NULL;
+ colorspace = MODE_YUVA;
+ } else { // A luma buffer was passed. Validate the other parameters.
+ if (u == NULL || v == NULL) return NULL;
+ if (luma_size == 0 || u_size == 0 || v_size == 0) return NULL;
+ if (luma_stride == 0 || u_stride == 0 || v_stride == 0) return NULL;
+ if (a != NULL) {
+ if (a_size == 0 || a_stride == 0) return NULL;
+ }
+ colorspace = (a == NULL) ? MODE_YUV : MODE_YUVA;
+ }
+
+ idec = WebPINewDecoder(NULL);
+ if (idec == NULL) return NULL;
+
+ idec->output_.colorspace = colorspace;
+ idec->output_.is_external_memory = is_external_memory;
+ idec->output_.u.YUVA.y = luma;
+ idec->output_.u.YUVA.y_stride = luma_stride;
+ idec->output_.u.YUVA.y_size = luma_size;
+ idec->output_.u.YUVA.u = u;
+ idec->output_.u.YUVA.u_stride = u_stride;
+ idec->output_.u.YUVA.u_size = u_size;
+ idec->output_.u.YUVA.v = v;
+ idec->output_.u.YUVA.v_stride = v_stride;
+ idec->output_.u.YUVA.v_size = v_size;
+ idec->output_.u.YUVA.a = a;
+ idec->output_.u.YUVA.a_stride = a_stride;
+ idec->output_.u.YUVA.a_size = a_size;
+ return idec;
+}
+
+WebPIDecoder* WebPINewYUV(uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride) {
+ return WebPINewYUVA(luma, luma_size, luma_stride,
+ u, u_size, u_stride,
+ v, v_size, v_stride,
+ NULL, 0, 0);
+}
+
+//------------------------------------------------------------------------------
+
+static VP8StatusCode IDecCheckStatus(const WebPIDecoder* const idec) {
+ assert(idec);
+ if (idec->state_ == STATE_ERROR) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ if (idec->state_ == STATE_DONE) {
+ return VP8_STATUS_OK;
+ }
+ return VP8_STATUS_SUSPENDED;
+}
+
+VP8StatusCode WebPIAppend(WebPIDecoder* idec,
+ const uint8_t* data, size_t data_size) {
+ VP8StatusCode status;
+ if (idec == NULL || data == NULL) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ status = IDecCheckStatus(idec);
+ if (status != VP8_STATUS_SUSPENDED) {
+ return status;
+ }
+ // Check mixed calls between RemapMemBuffer and AppendToMemBuffer.
+ if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_APPEND)) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ // Append data to memory buffer
+ if (!AppendToMemBuffer(idec, data, data_size)) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ return IDecode(idec);
+}
+
+VP8StatusCode WebPIUpdate(WebPIDecoder* idec,
+ const uint8_t* data, size_t data_size) {
+ VP8StatusCode status;
+ if (idec == NULL || data == NULL) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ status = IDecCheckStatus(idec);
+ if (status != VP8_STATUS_SUSPENDED) {
+ return status;
+ }
+ // Check mixed calls between RemapMemBuffer and AppendToMemBuffer.
+ if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_MAP)) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ // Make the memory buffer point to the new buffer
+ if (!RemapMemBuffer(idec, data, data_size)) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ return IDecode(idec);
+}
+
+//------------------------------------------------------------------------------
+
+static const WebPDecBuffer* GetOutputBuffer(const WebPIDecoder* const idec) {
+ if (idec == NULL || idec->dec_ == NULL) {
+ return NULL;
+ }
+ if (idec->state_ <= STATE_VP8_PARTS0) {
+ return NULL;
+ }
+ if (idec->final_output_ != NULL) {
+ return NULL; // not yet slow-copied
+ }
+ return idec->params_.output;
+}
+
+const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec,
+ int* left, int* top,
+ int* width, int* height) {
+ const WebPDecBuffer* const src = GetOutputBuffer(idec);
+ if (left != NULL) *left = 0;
+ if (top != NULL) *top = 0;
+ if (src != NULL) {
+ if (width != NULL) *width = src->width;
+ if (height != NULL) *height = idec->params_.last_y;
+ } else {
+ if (width != NULL) *width = 0;
+ if (height != NULL) *height = 0;
+ }
+ return src;
+}
+
+uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
+ int* width, int* height, int* stride) {
+ const WebPDecBuffer* const src = GetOutputBuffer(idec);
+ if (src == NULL) return NULL;
+ if (src->colorspace >= MODE_YUV) {
+ return NULL;
+ }
+
+ if (last_y != NULL) *last_y = idec->params_.last_y;
+ if (width != NULL) *width = src->width;
+ if (height != NULL) *height = src->height;
+ if (stride != NULL) *stride = src->u.RGBA.stride;
+
+ return src->u.RGBA.rgba;
+}
+
+uint8_t* WebPIDecGetYUVA(const WebPIDecoder* idec, int* last_y,
+ uint8_t** u, uint8_t** v, uint8_t** a,
+ int* width, int* height,
+ int* stride, int* uv_stride, int* a_stride) {
+ const WebPDecBuffer* const src = GetOutputBuffer(idec);
+ if (src == NULL) return NULL;
+ if (src->colorspace < MODE_YUV) {
+ return NULL;
+ }
+
+ if (last_y != NULL) *last_y = idec->params_.last_y;
+ if (u != NULL) *u = src->u.YUVA.u;
+ if (v != NULL) *v = src->u.YUVA.v;
+ if (a != NULL) *a = src->u.YUVA.a;
+ if (width != NULL) *width = src->width;
+ if (height != NULL) *height = src->height;
+ if (stride != NULL) *stride = src->u.YUVA.y_stride;
+ if (uv_stride != NULL) *uv_stride = src->u.YUVA.u_stride;
+ if (a_stride != NULL) *a_stride = src->u.YUVA.a_stride;
+
+ return src->u.YUVA.y;
+}
+
+int WebPISetIOHooks(WebPIDecoder* const idec,
+ VP8IoPutHook put,
+ VP8IoSetupHook setup,
+ VP8IoTeardownHook teardown,
+ void* user_data) {
+ if (idec == NULL || idec->state_ > STATE_WEBP_HEADER) {
+ return 0;
+ }
+
+ idec->io_.put = put;
+ idec->io_.setup = setup;
+ idec->io_.teardown = teardown;
+ idec->io_.opaque = user_data;
+
+ return 1;
+}
diff --git a/media/libwebp/dec/io_dec.c b/media/libwebp/dec/io_dec.c
new file mode 100644
index 000000000..8bfab8695
--- /dev/null
+++ b/media/libwebp/dec/io_dec.c
@@ -0,0 +1,645 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// functions for sample output.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include "../dec/vp8i_dec.h"
+#include "./webpi_dec.h"
+#include "../dsp/dsp.h"
+#include "../dsp/yuv.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Main YUV<->RGB conversion functions
+
+static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
+ WebPDecBuffer* output = p->output;
+ const WebPYUVABuffer* const buf = &output->u.YUVA;
+ uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
+ uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
+ uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
+ const int mb_w = io->mb_w;
+ const int mb_h = io->mb_h;
+ const int uv_w = (mb_w + 1) / 2;
+ const int uv_h = (mb_h + 1) / 2;
+ int j;
+ for (j = 0; j < mb_h; ++j) {
+ memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
+ }
+ for (j = 0; j < uv_h; ++j) {
+ memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
+ memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
+ }
+ return io->mb_h;
+}
+
+// Point-sampling U/V sampler.
+static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
+ WebPDecBuffer* const output = p->output;
+ WebPRGBABuffer* const buf = &output->u.RGBA;
+ uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
+ WebPSamplerProcessPlane(io->y, io->y_stride,
+ io->u, io->v, io->uv_stride,
+ dst, buf->stride, io->mb_w, io->mb_h,
+ WebPSamplers[output->colorspace]);
+ return io->mb_h;
+}
+
+//------------------------------------------------------------------------------
+// Fancy upsampling
+
+#ifdef FANCY_UPSAMPLING
+static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
+ int num_lines_out = io->mb_h; // a priori guess
+ const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+ uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
+ WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
+ const uint8_t* cur_y = io->y;
+ const uint8_t* cur_u = io->u;
+ const uint8_t* cur_v = io->v;
+ const uint8_t* top_u = p->tmp_u;
+ const uint8_t* top_v = p->tmp_v;
+ int y = io->mb_y;
+ const int y_end = io->mb_y + io->mb_h;
+ const int mb_w = io->mb_w;
+ const int uv_w = (mb_w + 1) / 2;
+
+ if (y == 0) {
+ // First line is special cased. We mirror the u/v samples at boundary.
+ upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, mb_w);
+ } else {
+ // We can finish the left-over line from previous call.
+ upsample(p->tmp_y, cur_y, top_u, top_v, cur_u, cur_v,
+ dst - buf->stride, dst, mb_w);
+ ++num_lines_out;
+ }
+ // Loop over each output pairs of row.
+ for (; y + 2 < y_end; y += 2) {
+ top_u = cur_u;
+ top_v = cur_v;
+ cur_u += io->uv_stride;
+ cur_v += io->uv_stride;
+ dst += 2 * buf->stride;
+ cur_y += 2 * io->y_stride;
+ upsample(cur_y - io->y_stride, cur_y,
+ top_u, top_v, cur_u, cur_v,
+ dst - buf->stride, dst, mb_w);
+ }
+ // move to last row
+ cur_y += io->y_stride;
+ if (io->crop_top + y_end < io->crop_bottom) {
+ // Save the unfinished samples for next call (as we're not done yet).
+ memcpy(p->tmp_y, cur_y, mb_w * sizeof(*p->tmp_y));
+ memcpy(p->tmp_u, cur_u, uv_w * sizeof(*p->tmp_u));
+ memcpy(p->tmp_v, cur_v, uv_w * sizeof(*p->tmp_v));
+ // The fancy upsampler leaves a row unfinished behind
+ // (except for the very last row)
+ num_lines_out--;
+ } else {
+ // Process the very last row of even-sized picture
+ if (!(y_end & 1)) {
+ upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v,
+ dst + buf->stride, NULL, mb_w);
+ }
+ }
+ return num_lines_out;
+}
+
+#endif /* FANCY_UPSAMPLING */
+
+//------------------------------------------------------------------------------
+
+static void FillAlphaPlane(uint8_t* dst, int w, int h, int stride) {
+ int j;
+ for (j = 0; j < h; ++j) {
+ memset(dst, 0xff, w * sizeof(*dst));
+ dst += stride;
+ }
+}
+
+static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
+ int expected_num_lines_out) {
+ const uint8_t* alpha = io->a;
+ const WebPYUVABuffer* const buf = &p->output->u.YUVA;
+ const int mb_w = io->mb_w;
+ const int mb_h = io->mb_h;
+ uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
+ int j;
+ (void)expected_num_lines_out;
+ assert(expected_num_lines_out == mb_h);
+ if (alpha != NULL) {
+ for (j = 0; j < mb_h; ++j) {
+ memcpy(dst, alpha, mb_w * sizeof(*dst));
+ alpha += io->width;
+ dst += buf->a_stride;
+ }
+ } else if (buf->a != NULL) {
+ // the user requested alpha, but there is none, set it to opaque.
+ FillAlphaPlane(dst, mb_w, mb_h, buf->a_stride);
+ }
+ return 0;
+}
+
+static int GetAlphaSourceRow(const VP8Io* const io,
+ const uint8_t** alpha, int* const num_rows) {
+ int start_y = io->mb_y;
+ *num_rows = io->mb_h;
+
+ // Compensate for the 1-line delay of the fancy upscaler.
+ // This is similar to EmitFancyRGB().
+ if (io->fancy_upsampling) {
+ if (start_y == 0) {
+ // We don't process the last row yet. It'll be done during the next call.
+ --*num_rows;
+ } else {
+ --start_y;
+ // Fortunately, *alpha data is persistent, so we can go back
+ // one row and finish alpha blending, now that the fancy upscaler
+ // completed the YUV->RGB interpolation.
+ *alpha -= io->width;
+ }
+ if (io->crop_top + io->mb_y + io->mb_h == io->crop_bottom) {
+ // If it's the very last call, we process all the remaining rows!
+ *num_rows = io->crop_bottom - io->crop_top - start_y;
+ }
+ }
+ return start_y;
+}
+
+static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
+ int expected_num_lines_out) {
+ const uint8_t* alpha = io->a;
+ if (alpha != NULL) {
+ const int mb_w = io->mb_w;
+ const WEBP_CSP_MODE colorspace = p->output->colorspace;
+ const int alpha_first =
+ (colorspace == MODE_ARGB || colorspace == MODE_Argb);
+ const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+ int num_rows;
+ const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
+ uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
+ uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
+ const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
+ num_rows, dst, buf->stride);
+ (void)expected_num_lines_out;
+ assert(expected_num_lines_out == num_rows);
+ // has_alpha is true if there's non-trivial alpha to premultiply with.
+ if (has_alpha && WebPIsPremultipliedMode(colorspace)) {
+ WebPApplyAlphaMultiply(base_rgba, alpha_first,
+ mb_w, num_rows, buf->stride);
+ }
+ }
+ return 0;
+}
+
+static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
+ int expected_num_lines_out) {
+ const uint8_t* alpha = io->a;
+ if (alpha != NULL) {
+ const int mb_w = io->mb_w;
+ const WEBP_CSP_MODE colorspace = p->output->colorspace;
+ const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+ int num_rows;
+ const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
+ uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
+#ifdef WEBP_SWAP_16BIT_CSP
+ uint8_t* alpha_dst = base_rgba;
+#else
+ uint8_t* alpha_dst = base_rgba + 1;
+#endif
+ uint32_t alpha_mask = 0x0f;
+ int i, j;
+ for (j = 0; j < num_rows; ++j) {
+ for (i = 0; i < mb_w; ++i) {
+ // Fill in the alpha value (converted to 4 bits).
+ const uint32_t alpha_value = alpha[i] >> 4;
+ alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value;
+ alpha_mask &= alpha_value;
+ }
+ alpha += io->width;
+ alpha_dst += buf->stride;
+ }
+ (void)expected_num_lines_out;
+ assert(expected_num_lines_out == num_rows);
+ if (alpha_mask != 0x0f && WebPIsPremultipliedMode(colorspace)) {
+ WebPApplyAlphaMultiply4444(base_rgba, mb_w, num_rows, buf->stride);
+ }
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// YUV rescaling (no final RGB conversion needed)
+
+static int Rescale(const uint8_t* src, int src_stride,
+ int new_lines, WebPRescaler* const wrk) {
+ int num_lines_out = 0;
+ while (new_lines > 0) { // import new contributions of source rows.
+ const int lines_in = WebPRescalerImport(wrk, new_lines, src, src_stride);
+ src += lines_in * src_stride;
+ new_lines -= lines_in;
+ num_lines_out += WebPRescalerExport(wrk); // emit output row(s)
+ }
+ return num_lines_out;
+}
+
+static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
+ const int mb_h = io->mb_h;
+ const int uv_mb_h = (mb_h + 1) >> 1;
+ WebPRescaler* const scaler = p->scaler_y;
+ int num_lines_out = 0;
+ if (WebPIsAlphaMode(p->output->colorspace) && io->a != NULL) {
+ // Before rescaling, we premultiply the luma directly into the io->y
+ // internal buffer. This is OK since these samples are not used for
+ // intra-prediction (the top samples are saved in cache_y_/u_/v_).
+ // But we need to cast the const away, though.
+ WebPMultRows((uint8_t*)io->y, io->y_stride,
+ io->a, io->width, io->mb_w, mb_h, 0);
+ }
+ num_lines_out = Rescale(io->y, io->y_stride, mb_h, scaler);
+ Rescale(io->u, io->uv_stride, uv_mb_h, p->scaler_u);
+ Rescale(io->v, io->uv_stride, uv_mb_h, p->scaler_v);
+ return num_lines_out;
+}
+
+static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
+ int expected_num_lines_out) {
+ const WebPYUVABuffer* const buf = &p->output->u.YUVA;
+ uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
+ if (io->a != NULL) {
+ uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
+ const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
+ assert(expected_num_lines_out == num_lines_out);
+ if (num_lines_out > 0) { // unmultiply the Y
+ WebPMultRows(dst_y, buf->y_stride, dst_a, buf->a_stride,
+ p->scaler_a->dst_width, num_lines_out, 1);
+ }
+ } else if (buf->a != NULL) {
+ // the user requested alpha, but there is none, set it to opaque.
+ assert(p->last_y + expected_num_lines_out <= io->scaled_height);
+ FillAlphaPlane(dst_a, io->scaled_width, expected_num_lines_out,
+ buf->a_stride);
+ }
+ return 0;
+}
+
+static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
+ const int has_alpha = WebPIsAlphaMode(p->output->colorspace);
+ const WebPYUVABuffer* const buf = &p->output->u.YUVA;
+ const int out_width = io->scaled_width;
+ const int out_height = io->scaled_height;
+ const int uv_out_width = (out_width + 1) >> 1;
+ const int uv_out_height = (out_height + 1) >> 1;
+ const int uv_in_width = (io->mb_w + 1) >> 1;
+ const int uv_in_height = (io->mb_h + 1) >> 1;
+ const size_t work_size = 2 * out_width; // scratch memory for luma rescaler
+ const size_t uv_work_size = 2 * uv_out_width; // and for each u/v ones
+ size_t tmp_size, rescaler_size;
+ rescaler_t* work;
+ WebPRescaler* scalers;
+ const int num_rescalers = has_alpha ? 4 : 3;
+
+ tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work);
+ if (has_alpha) {
+ tmp_size += work_size * sizeof(*work);
+ }
+ rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
+
+ p->memory = WebPSafeMalloc(1ULL, tmp_size + rescaler_size);
+ if (p->memory == NULL) {
+ return 0; // memory error
+ }
+ work = (rescaler_t*)p->memory;
+
+ scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + tmp_size);
+ p->scaler_y = &scalers[0];
+ p->scaler_u = &scalers[1];
+ p->scaler_v = &scalers[2];
+ p->scaler_a = has_alpha ? &scalers[3] : NULL;
+
+ WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
+ buf->y, out_width, out_height, buf->y_stride, 1,
+ work);
+ WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
+ buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
+ work + work_size);
+ WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
+ buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
+ work + work_size + uv_work_size);
+ p->emit = EmitRescaledYUV;
+
+ if (has_alpha) {
+ WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
+ buf->a, out_width, out_height, buf->a_stride, 1,
+ work + work_size + 2 * uv_work_size);
+ p->emit_alpha = EmitRescaledAlphaYUV;
+ WebPInitAlphaProcessing();
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// RGBA rescaling
+
+static int ExportRGB(WebPDecParams* const p, int y_pos) {
+ const WebPYUV444Converter convert =
+ WebPYUV444Converters[p->output->colorspace];
+ const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+ uint8_t* dst = buf->rgba + y_pos * buf->stride;
+ int num_lines_out = 0;
+ // For RGB rescaling, because of the YUV420, current scan position
+ // U/V can be +1/-1 line from the Y one. Hence the double test.
+ while (WebPRescalerHasPendingOutput(p->scaler_y) &&
+ WebPRescalerHasPendingOutput(p->scaler_u)) {
+ assert(y_pos + num_lines_out < p->output->height);
+ assert(p->scaler_u->y_accum == p->scaler_v->y_accum);
+ WebPRescalerExportRow(p->scaler_y);
+ WebPRescalerExportRow(p->scaler_u);
+ WebPRescalerExportRow(p->scaler_v);
+ convert(p->scaler_y->dst, p->scaler_u->dst, p->scaler_v->dst,
+ dst, p->scaler_y->dst_width);
+ dst += buf->stride;
+ ++num_lines_out;
+ }
+ return num_lines_out;
+}
+
+static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
+ const int mb_h = io->mb_h;
+ const int uv_mb_h = (mb_h + 1) >> 1;
+ int j = 0, uv_j = 0;
+ int num_lines_out = 0;
+ while (j < mb_h) {
+ const int y_lines_in =
+ WebPRescalerImport(p->scaler_y, mb_h - j,
+ io->y + j * io->y_stride, io->y_stride);
+ j += y_lines_in;
+ if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
+ const int u_lines_in =
+ WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
+ io->u + uv_j * io->uv_stride, io->uv_stride);
+ const int v_lines_in =
+ WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
+ io->v + uv_j * io->uv_stride, io->uv_stride);
+ (void)v_lines_in; // remove a gcc warning
+ assert(u_lines_in == v_lines_in);
+ uv_j += u_lines_in;
+ }
+ num_lines_out += ExportRGB(p, p->last_y + num_lines_out);
+ }
+ return num_lines_out;
+}
+
+static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
+ const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+ uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
+ const WEBP_CSP_MODE colorspace = p->output->colorspace;
+ const int alpha_first =
+ (colorspace == MODE_ARGB || colorspace == MODE_Argb);
+ uint8_t* dst = base_rgba + (alpha_first ? 0 : 3);
+ int num_lines_out = 0;
+ const int is_premult_alpha = WebPIsPremultipliedMode(colorspace);
+ uint32_t non_opaque = 0;
+ const int width = p->scaler_a->dst_width;
+
+ while (WebPRescalerHasPendingOutput(p->scaler_a) &&
+ num_lines_out < max_lines_out) {
+ assert(y_pos + num_lines_out < p->output->height);
+ WebPRescalerExportRow(p->scaler_a);
+ non_opaque |= WebPDispatchAlpha(p->scaler_a->dst, 0, width, 1, dst, 0);
+ dst += buf->stride;
+ ++num_lines_out;
+ }
+ if (is_premult_alpha && non_opaque) {
+ WebPApplyAlphaMultiply(base_rgba, alpha_first,
+ width, num_lines_out, buf->stride);
+ }
+ return num_lines_out;
+}
+
+static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
+ int max_lines_out) {
+ const WebPRGBABuffer* const buf = &p->output->u.RGBA;
+ uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
+#ifdef WEBP_SWAP_16BIT_CSP
+ uint8_t* alpha_dst = base_rgba;
+#else
+ uint8_t* alpha_dst = base_rgba + 1;
+#endif
+ int num_lines_out = 0;
+ const WEBP_CSP_MODE colorspace = p->output->colorspace;
+ const int width = p->scaler_a->dst_width;
+ const int is_premult_alpha = WebPIsPremultipliedMode(colorspace);
+ uint32_t alpha_mask = 0x0f;
+
+ while (WebPRescalerHasPendingOutput(p->scaler_a) &&
+ num_lines_out < max_lines_out) {
+ int i;
+ assert(y_pos + num_lines_out < p->output->height);
+ WebPRescalerExportRow(p->scaler_a);
+ for (i = 0; i < width; ++i) {
+ // Fill in the alpha value (converted to 4 bits).
+ const uint32_t alpha_value = p->scaler_a->dst[i] >> 4;
+ alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value;
+ alpha_mask &= alpha_value;
+ }
+ alpha_dst += buf->stride;
+ ++num_lines_out;
+ }
+ if (is_premult_alpha && alpha_mask != 0x0f) {
+ WebPApplyAlphaMultiply4444(base_rgba, width, num_lines_out, buf->stride);
+ }
+ return num_lines_out;
+}
+
+static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
+ int expected_num_out_lines) {
+ if (io->a != NULL) {
+ WebPRescaler* const scaler = p->scaler_a;
+ int lines_left = expected_num_out_lines;
+ const int y_end = p->last_y + lines_left;
+ while (lines_left > 0) {
+ const int row_offset = scaler->src_y - io->mb_y;
+ WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
+ io->a + row_offset * io->width, io->width);
+ lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
+ }
+ }
+ return 0;
+}
+
+static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
+ const int has_alpha = WebPIsAlphaMode(p->output->colorspace);
+ const int out_width = io->scaled_width;
+ const int out_height = io->scaled_height;
+ const int uv_in_width = (io->mb_w + 1) >> 1;
+ const int uv_in_height = (io->mb_h + 1) >> 1;
+ const size_t work_size = 2 * out_width; // scratch memory for one rescaler
+ rescaler_t* work; // rescalers work area
+ uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion
+ size_t tmp_size1, tmp_size2, total_size, rescaler_size;
+ WebPRescaler* scalers;
+ const int num_rescalers = has_alpha ? 4 : 3;
+
+ tmp_size1 = 3 * work_size;
+ tmp_size2 = 3 * out_width;
+ if (has_alpha) {
+ tmp_size1 += work_size;
+ tmp_size2 += out_width;
+ }
+ total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
+ rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
+
+ p->memory = WebPSafeMalloc(1ULL, total_size + rescaler_size);
+ if (p->memory == NULL) {
+ return 0; // memory error
+ }
+ work = (rescaler_t*)p->memory;
+ tmp = (uint8_t*)(work + tmp_size1);
+
+ scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + total_size);
+ p->scaler_y = &scalers[0];
+ p->scaler_u = &scalers[1];
+ p->scaler_v = &scalers[2];
+ p->scaler_a = has_alpha ? &scalers[3] : NULL;
+
+ WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
+ tmp + 0 * out_width, out_width, out_height, 0, 1,
+ work + 0 * work_size);
+ WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
+ tmp + 1 * out_width, out_width, out_height, 0, 1,
+ work + 1 * work_size);
+ WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
+ tmp + 2 * out_width, out_width, out_height, 0, 1,
+ work + 2 * work_size);
+ p->emit = EmitRescaledRGB;
+ WebPInitYUV444Converters();
+
+ if (has_alpha) {
+ WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
+ tmp + 3 * out_width, out_width, out_height, 0, 1,
+ work + 3 * work_size);
+ p->emit_alpha = EmitRescaledAlphaRGB;
+ if (p->output->colorspace == MODE_RGBA_4444 ||
+ p->output->colorspace == MODE_rgbA_4444) {
+ p->emit_alpha_row = ExportAlphaRGBA4444;
+ } else {
+ p->emit_alpha_row = ExportAlpha;
+ }
+ WebPInitAlphaProcessing();
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// Default custom functions
+
+static int CustomSetup(VP8Io* io) {
+ WebPDecParams* const p = (WebPDecParams*)io->opaque;
+ const WEBP_CSP_MODE colorspace = p->output->colorspace;
+ const int is_rgb = WebPIsRGBMode(colorspace);
+ const int is_alpha = WebPIsAlphaMode(colorspace);
+
+ p->memory = NULL;
+ p->emit = NULL;
+ p->emit_alpha = NULL;
+ p->emit_alpha_row = NULL;
+ if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) {
+ return 0;
+ }
+ if (is_alpha && WebPIsPremultipliedMode(colorspace)) {
+ WebPInitUpsamplers();
+ }
+ if (io->use_scaling) {
+ const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
+ if (!ok) {
+ return 0; // memory error
+ }
+ } else {
+ if (is_rgb) {
+ WebPInitSamplers();
+ p->emit = EmitSampledRGB; // default
+ if (io->fancy_upsampling) {
+#ifdef FANCY_UPSAMPLING
+ const int uv_width = (io->mb_w + 1) >> 1;
+ p->memory = WebPSafeMalloc(1ULL, (size_t)(io->mb_w + 2 * uv_width));
+ if (p->memory == NULL) {
+ return 0; // memory error.
+ }
+ p->tmp_y = (uint8_t*)p->memory;
+ p->tmp_u = p->tmp_y + io->mb_w;
+ p->tmp_v = p->tmp_u + uv_width;
+ p->emit = EmitFancyRGB;
+ WebPInitUpsamplers();
+#endif
+ }
+ } else {
+ p->emit = EmitYUV;
+ }
+ if (is_alpha) { // need transparency output
+ p->emit_alpha =
+ (colorspace == MODE_RGBA_4444 || colorspace == MODE_rgbA_4444) ?
+ EmitAlphaRGBA4444
+ : is_rgb ? EmitAlphaRGB
+ : EmitAlphaYUV;
+ if (is_rgb) {
+ WebPInitAlphaProcessing();
+ }
+ }
+ }
+
+ if (is_rgb) {
+ VP8YUVInit();
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+
+static int CustomPut(const VP8Io* io) {
+ WebPDecParams* const p = (WebPDecParams*)io->opaque;
+ const int mb_w = io->mb_w;
+ const int mb_h = io->mb_h;
+ int num_lines_out;
+ assert(!(io->mb_y & 1));
+
+ if (mb_w <= 0 || mb_h <= 0) {
+ return 0;
+ }
+ num_lines_out = p->emit(io, p);
+ if (p->emit_alpha != NULL) {
+ p->emit_alpha(io, p, num_lines_out);
+ }
+ p->last_y += num_lines_out;
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+
+static void CustomTeardown(const VP8Io* io) {
+ WebPDecParams* const p = (WebPDecParams*)io->opaque;
+ WebPSafeFree(p->memory);
+ p->memory = NULL;
+}
+
+//------------------------------------------------------------------------------
+// Main entry point
+
+void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io) {
+ io->put = CustomPut;
+ io->setup = CustomSetup;
+ io->teardown = CustomTeardown;
+ io->opaque = params;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dec/moz.build b/media/libwebp/dec/moz.build
new file mode 100644
index 000000000..d988ae658
--- /dev/null
+++ b/media/libwebp/dec/moz.build
@@ -0,0 +1,26 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files('**'):
+ BUG_COMPONENT = ('Core', 'ImageLib')
+
+SOURCES += [
+ 'alpha_dec.c',
+ 'buffer_dec.c',
+ 'frame_dec.c',
+ 'idec_dec.c',
+ 'io_dec.c',
+ 'quant_dec.c',
+ 'tree_dec.c',
+ 'vp8_dec.c',
+ 'vp8l_dec.c',
+ 'webp_dec.c',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
diff --git a/media/libwebp/dec/quant_dec.c b/media/libwebp/dec/quant_dec.c
new file mode 100644
index 000000000..14e319894
--- /dev/null
+++ b/media/libwebp/dec/quant_dec.c
@@ -0,0 +1,110 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Quantizer initialization
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./vp8i_dec.h"
+
+static WEBP_INLINE int clip(int v, int M) {
+ return v < 0 ? 0 : v > M ? M : v;
+}
+
+// Paragraph 14.1
+static const uint8_t kDcTable[128] = {
+ 4, 5, 6, 7, 8, 9, 10, 10,
+ 11, 12, 13, 14, 15, 16, 17, 17,
+ 18, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 25, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89,
+ 91, 93, 95, 96, 98, 100, 101, 102,
+ 104, 106, 108, 110, 112, 114, 116, 118,
+ 122, 124, 126, 128, 130, 132, 134, 136,
+ 138, 140, 143, 145, 148, 151, 154, 157
+};
+
+static const uint16_t kAcTable[128] = {
+ 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 60,
+ 62, 64, 66, 68, 70, 72, 74, 76,
+ 78, 80, 82, 84, 86, 88, 90, 92,
+ 94, 96, 98, 100, 102, 104, 106, 108,
+ 110, 112, 114, 116, 119, 122, 125, 128,
+ 131, 134, 137, 140, 143, 146, 149, 152,
+ 155, 158, 161, 164, 167, 170, 173, 177,
+ 181, 185, 189, 193, 197, 201, 205, 209,
+ 213, 217, 221, 225, 229, 234, 239, 245,
+ 249, 254, 259, 264, 269, 274, 279, 284
+};
+
+//------------------------------------------------------------------------------
+// Paragraph 9.6
+
+void VP8ParseQuant(VP8Decoder* const dec) {
+ VP8BitReader* const br = &dec->br_;
+ const int base_q0 = VP8GetValue(br, 7);
+ const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+ const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+ const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+ const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+ const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
+
+ const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
+ int i;
+
+ for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
+ int q;
+ if (hdr->use_segment_) {
+ q = hdr->quantizer_[i];
+ if (!hdr->absolute_delta_) {
+ q += base_q0;
+ }
+ } else {
+ if (i > 0) {
+ dec->dqm_[i] = dec->dqm_[0];
+ continue;
+ } else {
+ q = base_q0;
+ }
+ }
+ {
+ VP8QuantMatrix* const m = &dec->dqm_[i];
+ m->y1_mat_[0] = kDcTable[clip(q + dqy1_dc, 127)];
+ m->y1_mat_[1] = kAcTable[clip(q + 0, 127)];
+
+ m->y2_mat_[0] = kDcTable[clip(q + dqy2_dc, 127)] * 2;
+ // For all x in [0..284], x*155/100 is bitwise equal to (x*101581) >> 16.
+ // The smallest precision for that is '(x*6349) >> 12' but 16 is a good
+ // word size.
+ m->y2_mat_[1] = (kAcTable[clip(q + dqy2_ac, 127)] * 101581) >> 16;
+ if (m->y2_mat_[1] < 8) m->y2_mat_[1] = 8;
+
+ m->uv_mat_[0] = kDcTable[clip(q + dquv_dc, 117)];
+ m->uv_mat_[1] = kAcTable[clip(q + dquv_ac, 127)];
+
+ m->uv_quant_ = q + dquv_ac; // for dithering strength evaluation
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/media/libwebp/dec/tree_dec.c b/media/libwebp/dec/tree_dec.c
new file mode 100644
index 000000000..9e805f60f
--- /dev/null
+++ b/media/libwebp/dec/tree_dec.c
@@ -0,0 +1,528 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Coding trees and probas
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./vp8i_dec.h"
+#include "../utils/bit_reader_inl_utils.h"
+
+#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
+// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
+#define USE_GENERIC_TREE
+#endif
+
+#ifdef USE_GENERIC_TREE
+static const int8_t kYModesIntra4[18] = {
+ -B_DC_PRED, 1,
+ -B_TM_PRED, 2,
+ -B_VE_PRED, 3,
+ 4, 6,
+ -B_HE_PRED, 5,
+ -B_RD_PRED, -B_VR_PRED,
+ -B_LD_PRED, 7,
+ -B_VL_PRED, 8,
+ -B_HD_PRED, -B_HU_PRED
+};
+#endif
+
+//------------------------------------------------------------------------------
+// Default probabilities
+
+// Paragraph 13.5
+static const uint8_t
+ CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
+ { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+ },
+ { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
+ { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
+ { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 }
+ },
+ { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
+ { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
+ { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 },
+ },
+ { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
+ { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
+ { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 },
+ },
+ { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
+ { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
+ { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 }
+ },
+ { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
+ { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
+ { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 }
+ },
+ { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
+ { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
+ { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 }
+ },
+ { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+ }
+ },
+ { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 },
+ { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 },
+ { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 }
+ },
+ { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
+ { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
+ { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 }
+ },
+ { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
+ { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
+ { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 }
+ },
+ { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
+ { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
+ { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 }
+ },
+ { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
+ { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
+ { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 }
+ },
+ { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
+ { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
+ { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 }
+ },
+ { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
+ { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
+ { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 }
+ },
+ { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
+ { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+ { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 }
+ }
+ },
+ { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
+ { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
+ { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 }
+ },
+ { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
+ { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
+ { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 }
+ },
+ { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
+ { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
+ { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 }
+ },
+ { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
+ { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
+ { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 }
+ },
+ { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+ { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
+ { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+ },
+ { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+ },
+ { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
+ { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
+ { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+ },
+ { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+ }
+ },
+ { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
+ { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
+ { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 }
+ },
+ { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
+ { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
+ { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 }
+ },
+ { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
+ { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
+ { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 }
+ },
+ { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
+ { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
+ { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 }
+ },
+ { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
+ { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
+ { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 }
+ },
+ { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
+ { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
+ { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 }
+ },
+ { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
+ { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
+ { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 }
+ },
+ { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+ { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+ }
+ }
+};
+
+// Paragraph 11.5
+static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = {
+ { { 231, 120, 48, 89, 115, 113, 120, 152, 112 },
+ { 152, 179, 64, 126, 170, 118, 46, 70, 95 },
+ { 175, 69, 143, 80, 85, 82, 72, 155, 103 },
+ { 56, 58, 10, 171, 218, 189, 17, 13, 152 },
+ { 114, 26, 17, 163, 44, 195, 21, 10, 173 },
+ { 121, 24, 80, 195, 26, 62, 44, 64, 85 },
+ { 144, 71, 10, 38, 171, 213, 144, 34, 26 },
+ { 170, 46, 55, 19, 136, 160, 33, 206, 71 },
+ { 63, 20, 8, 114, 114, 208, 12, 9, 226 },
+ { 81, 40, 11, 96, 182, 84, 29, 16, 36 } },
+ { { 134, 183, 89, 137, 98, 101, 106, 165, 148 },
+ { 72, 187, 100, 130, 157, 111, 32, 75, 80 },
+ { 66, 102, 167, 99, 74, 62, 40, 234, 128 },
+ { 41, 53, 9, 178, 241, 141, 26, 8, 107 },
+ { 74, 43, 26, 146, 73, 166, 49, 23, 157 },
+ { 65, 38, 105, 160, 51, 52, 31, 115, 128 },
+ { 104, 79, 12, 27, 217, 255, 87, 17, 7 },
+ { 87, 68, 71, 44, 114, 51, 15, 186, 23 },
+ { 47, 41, 14, 110, 182, 183, 21, 17, 194 },
+ { 66, 45, 25, 102, 197, 189, 23, 18, 22 } },
+ { { 88, 88, 147, 150, 42, 46, 45, 196, 205 },
+ { 43, 97, 183, 117, 85, 38, 35, 179, 61 },
+ { 39, 53, 200, 87, 26, 21, 43, 232, 171 },
+ { 56, 34, 51, 104, 114, 102, 29, 93, 77 },
+ { 39, 28, 85, 171, 58, 165, 90, 98, 64 },
+ { 34, 22, 116, 206, 23, 34, 43, 166, 73 },
+ { 107, 54, 32, 26, 51, 1, 81, 43, 31 },
+ { 68, 25, 106, 22, 64, 171, 36, 225, 114 },
+ { 34, 19, 21, 102, 132, 188, 16, 76, 124 },
+ { 62, 18, 78, 95, 85, 57, 50, 48, 51 } },
+ { { 193, 101, 35, 159, 215, 111, 89, 46, 111 },
+ { 60, 148, 31, 172, 219, 228, 21, 18, 111 },
+ { 112, 113, 77, 85, 179, 255, 38, 120, 114 },
+ { 40, 42, 1, 196, 245, 209, 10, 25, 109 },
+ { 88, 43, 29, 140, 166, 213, 37, 43, 154 },
+ { 61, 63, 30, 155, 67, 45, 68, 1, 209 },
+ { 100, 80, 8, 43, 154, 1, 51, 26, 71 },
+ { 142, 78, 78, 16, 255, 128, 34, 197, 171 },
+ { 41, 40, 5, 102, 211, 183, 4, 1, 221 },
+ { 51, 50, 17, 168, 209, 192, 23, 25, 82 } },
+ { { 138, 31, 36, 171, 27, 166, 38, 44, 229 },
+ { 67, 87, 58, 169, 82, 115, 26, 59, 179 },
+ { 63, 59, 90, 180, 59, 166, 93, 73, 154 },
+ { 40, 40, 21, 116, 143, 209, 34, 39, 175 },
+ { 47, 15, 16, 183, 34, 223, 49, 45, 183 },
+ { 46, 17, 33, 183, 6, 98, 15, 32, 183 },
+ { 57, 46, 22, 24, 128, 1, 54, 17, 37 },
+ { 65, 32, 73, 115, 28, 128, 23, 128, 205 },
+ { 40, 3, 9, 115, 51, 192, 18, 6, 223 },
+ { 87, 37, 9, 115, 59, 77, 64, 21, 47 } },
+ { { 104, 55, 44, 218, 9, 54, 53, 130, 226 },
+ { 64, 90, 70, 205, 40, 41, 23, 26, 57 },
+ { 54, 57, 112, 184, 5, 41, 38, 166, 213 },
+ { 30, 34, 26, 133, 152, 116, 10, 32, 134 },
+ { 39, 19, 53, 221, 26, 114, 32, 73, 255 },
+ { 31, 9, 65, 234, 2, 15, 1, 118, 73 },
+ { 75, 32, 12, 51, 192, 255, 160, 43, 51 },
+ { 88, 31, 35, 67, 102, 85, 55, 186, 85 },
+ { 56, 21, 23, 111, 59, 205, 45, 37, 192 },
+ { 55, 38, 70, 124, 73, 102, 1, 34, 98 } },
+ { { 125, 98, 42, 88, 104, 85, 117, 175, 82 },
+ { 95, 84, 53, 89, 128, 100, 113, 101, 45 },
+ { 75, 79, 123, 47, 51, 128, 81, 171, 1 },
+ { 57, 17, 5, 71, 102, 57, 53, 41, 49 },
+ { 38, 33, 13, 121, 57, 73, 26, 1, 85 },
+ { 41, 10, 67, 138, 77, 110, 90, 47, 114 },
+ { 115, 21, 2, 10, 102, 255, 166, 23, 6 },
+ { 101, 29, 16, 10, 85, 128, 101, 196, 26 },
+ { 57, 18, 10, 102, 102, 213, 34, 20, 43 },
+ { 117, 20, 15, 36, 163, 128, 68, 1, 26 } },
+ { { 102, 61, 71, 37, 34, 53, 31, 243, 192 },
+ { 69, 60, 71, 38, 73, 119, 28, 222, 37 },
+ { 68, 45, 128, 34, 1, 47, 11, 245, 171 },
+ { 62, 17, 19, 70, 146, 85, 55, 62, 70 },
+ { 37, 43, 37, 154, 100, 163, 85, 160, 1 },
+ { 63, 9, 92, 136, 28, 64, 32, 201, 85 },
+ { 75, 15, 9, 9, 64, 255, 184, 119, 16 },
+ { 86, 6, 28, 5, 64, 255, 25, 248, 1 },
+ { 56, 8, 17, 132, 137, 255, 55, 116, 128 },
+ { 58, 15, 20, 82, 135, 57, 26, 121, 40 } },
+ { { 164, 50, 31, 137, 154, 133, 25, 35, 218 },
+ { 51, 103, 44, 131, 131, 123, 31, 6, 158 },
+ { 86, 40, 64, 135, 148, 224, 45, 183, 128 },
+ { 22, 26, 17, 131, 240, 154, 14, 1, 209 },
+ { 45, 16, 21, 91, 64, 222, 7, 1, 197 },
+ { 56, 21, 39, 155, 60, 138, 23, 102, 213 },
+ { 83, 12, 13, 54, 192, 255, 68, 47, 28 },
+ { 85, 26, 85, 85, 128, 128, 32, 146, 171 },
+ { 18, 11, 7, 63, 144, 171, 4, 4, 246 },
+ { 35, 27, 10, 146, 174, 171, 12, 26, 128 } },
+ { { 190, 80, 35, 99, 180, 80, 126, 54, 45 },
+ { 85, 126, 47, 87, 176, 51, 41, 20, 32 },
+ { 101, 75, 128, 139, 118, 146, 116, 128, 85 },
+ { 56, 41, 15, 176, 236, 85, 37, 9, 62 },
+ { 71, 30, 17, 119, 118, 255, 17, 18, 138 },
+ { 101, 38, 60, 138, 55, 70, 43, 26, 142 },
+ { 146, 36, 19, 30, 171, 255, 97, 27, 20 },
+ { 138, 45, 61, 62, 219, 1, 81, 188, 64 },
+ { 32, 41, 20, 117, 151, 142, 20, 21, 163 },
+ { 112, 19, 12, 61, 195, 128, 48, 4, 24 } }
+};
+
+void VP8ResetProba(VP8Proba* const proba) {
+ memset(proba->segments_, 255u, sizeof(proba->segments_));
+ // proba->bands_[][] is initialized later
+}
+
+static void ParseIntraMode(VP8BitReader* const br,
+ VP8Decoder* const dec, int mb_x) {
+ uint8_t* const top = dec->intra_t_ + 4 * mb_x;
+ uint8_t* const left = dec->intra_l_;
+ VP8MBData* const block = dec->mb_data_ + mb_x;
+
+ // Note: we don't save segment map (yet), as we don't expect
+ // to decode more than 1 keyframe.
+ if (dec->segment_hdr_.update_map_) {
+ // Hardcoded tree parsing
+ block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0])
+ ? VP8GetBit(br, dec->proba_.segments_[1])
+ : 2 + VP8GetBit(br, dec->proba_.segments_[2]);
+ } else {
+ block->segment_ = 0; // default for intra
+ }
+ if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_);
+
+ block->is_i4x4_ = !VP8GetBit(br, 145); // decide for B_PRED first
+ if (!block->is_i4x4_) {
+ // Hardcoded 16x16 intra-mode decision tree.
+ const int ymode =
+ VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED)
+ : (VP8GetBit(br, 163) ? V_PRED : DC_PRED);
+ block->imodes_[0] = ymode;
+ memset(top, ymode, 4 * sizeof(*top));
+ memset(left, ymode, 4 * sizeof(*left));
+ } else {
+ uint8_t* modes = block->imodes_;
+ int y;
+ for (y = 0; y < 4; ++y) {
+ int ymode = left[y];
+ int x;
+ for (x = 0; x < 4; ++x) {
+ const uint8_t* const prob = kBModesProba[top[x]][ymode];
+#ifdef USE_GENERIC_TREE
+ // Generic tree-parsing
+ int i = kYModesIntra4[VP8GetBit(br, prob[0])];
+ while (i > 0) {
+ i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])];
+ }
+ ymode = -i;
+#else
+ // Hardcoded tree parsing
+ ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED :
+ !VP8GetBit(br, prob[1]) ? B_TM_PRED :
+ !VP8GetBit(br, prob[2]) ? B_VE_PRED :
+ !VP8GetBit(br, prob[3]) ?
+ (!VP8GetBit(br, prob[4]) ? B_HE_PRED :
+ (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) :
+ (!VP8GetBit(br, prob[6]) ? B_LD_PRED :
+ (!VP8GetBit(br, prob[7]) ? B_VL_PRED :
+ (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
+#endif // USE_GENERIC_TREE
+ top[x] = ymode;
+ }
+ memcpy(modes, top, 4 * sizeof(*top));
+ modes += 4;
+ left[y] = ymode;
+ }
+ }
+ // Hardcoded UVMode decision tree
+ block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED
+ : !VP8GetBit(br, 114) ? V_PRED
+ : VP8GetBit(br, 183) ? TM_PRED : H_PRED;
+}
+
+int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) {
+ int mb_x;
+ for (mb_x = 0; mb_x < dec->mb_w_; ++mb_x) {
+ ParseIntraMode(br, dec, mb_x);
+ }
+ return !dec->br_.eof_;
+}
+
+//------------------------------------------------------------------------------
+// Paragraph 13
+
+static const uint8_t
+ CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
+ { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
+ { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ }
+ },
+ { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
+ { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }
+ },
+ { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ }
+ },
+ { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
+ { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }
+ },
+ { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ }
+ },
+ { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
+ { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ },
+ { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+ }
+ }
+};
+
+// Paragraph 9.9
+
+static const int kBands[16 + 1] = {
+ 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
+ 0 // extra entry as sentinel
+};
+
+void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
+ VP8Proba* const proba = &dec->proba_;
+ int t, b, c, p;
+ for (t = 0; t < NUM_TYPES; ++t) {
+ for (b = 0; b < NUM_BANDS; ++b) {
+ for (c = 0; c < NUM_CTX; ++c) {
+ for (p = 0; p < NUM_PROBAS; ++p) {
+ const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ?
+ VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p];
+ proba->bands_[t][b].probas_[c][p] = v;
+ }
+ }
+ }
+ for (b = 0; b < 16 + 1; ++b) {
+ proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]];
+ }
+ }
+ dec->use_skip_proba_ = VP8Get(br);
+ if (dec->use_skip_proba_) {
+ dec->skip_p_ = VP8GetValue(br, 8);
+ }
+}
+
diff --git a/media/libwebp/dec/vp8_dec.c b/media/libwebp/dec/vp8_dec.c
new file mode 100644
index 000000000..fad8d9cf3
--- /dev/null
+++ b/media/libwebp/dec/vp8_dec.c
@@ -0,0 +1,721 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// main entry for the decoder
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <stdlib.h>
+
+#include "./alphai_dec.h"
+#include "./vp8i_dec.h"
+#include "./vp8li_dec.h"
+#include "./webpi_dec.h"
+#include "../utils/bit_reader_inl_utils.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+
+int WebPGetDecoderVersion(void) {
+ return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION;
+}
+
+//------------------------------------------------------------------------------
+// Signature and pointer-to-function for GetCoeffs() variants below.
+
+typedef int (*GetCoeffsFunc)(VP8BitReader* const br,
+ const VP8BandProbas* const prob[],
+ int ctx, const quant_t dq, int n, int16_t* out);
+static volatile GetCoeffsFunc GetCoeffs = NULL;
+
+static void InitGetCoeffs(void);
+
+//------------------------------------------------------------------------------
+// VP8Decoder
+
+static void SetOk(VP8Decoder* const dec) {
+ dec->status_ = VP8_STATUS_OK;
+ dec->error_msg_ = "OK";
+}
+
+int VP8InitIoInternal(VP8Io* const io, int version) {
+ if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+ return 0; // mismatch error
+ }
+ if (io != NULL) {
+ memset(io, 0, sizeof(*io));
+ }
+ return 1;
+}
+
+VP8Decoder* VP8New(void) {
+ VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
+ if (dec != NULL) {
+ SetOk(dec);
+ WebPGetWorkerInterface()->Init(&dec->worker_);
+ dec->ready_ = 0;
+ dec->num_parts_minus_one_ = 0;
+ InitGetCoeffs();
+ }
+ return dec;
+}
+
+VP8StatusCode VP8Status(VP8Decoder* const dec) {
+ if (!dec) return VP8_STATUS_INVALID_PARAM;
+ return dec->status_;
+}
+
+const char* VP8StatusMessage(VP8Decoder* const dec) {
+ if (dec == NULL) return "no object";
+ if (!dec->error_msg_) return "OK";
+ return dec->error_msg_;
+}
+
+void VP8Delete(VP8Decoder* const dec) {
+ if (dec != NULL) {
+ VP8Clear(dec);
+ WebPSafeFree(dec);
+ }
+}
+
+int VP8SetError(VP8Decoder* const dec,
+ VP8StatusCode error, const char* const msg) {
+ // The oldest error reported takes precedence over the new one.
+ if (dec->status_ == VP8_STATUS_OK) {
+ dec->status_ = error;
+ dec->error_msg_ = msg;
+ dec->ready_ = 0;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+
+int VP8CheckSignature(const uint8_t* const data, size_t data_size) {
+ return (data_size >= 3 &&
+ data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a);
+}
+
+int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
+ int* const width, int* const height) {
+ if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) {
+ return 0; // not enough data
+ }
+ // check signature
+ if (!VP8CheckSignature(data + 3, data_size - 3)) {
+ return 0; // Wrong signature.
+ } else {
+ const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16);
+ const int key_frame = !(bits & 1);
+ const int w = ((data[7] << 8) | data[6]) & 0x3fff;
+ const int h = ((data[9] << 8) | data[8]) & 0x3fff;
+
+ if (!key_frame) { // Not a keyframe.
+ return 0;
+ }
+
+ if (((bits >> 1) & 7) > 3) {
+ return 0; // unknown profile
+ }
+ if (!((bits >> 4) & 1)) {
+ return 0; // first frame is invisible!
+ }
+ if (((bits >> 5)) >= chunk_size) { // partition_length
+ return 0; // inconsistent size information.
+ }
+ if (w == 0 || h == 0) {
+ return 0; // We don't support both width and height to be zero.
+ }
+
+ if (width) {
+ *width = w;
+ }
+ if (height) {
+ *height = h;
+ }
+
+ return 1;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Header parsing
+
+static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
+ assert(hdr != NULL);
+ hdr->use_segment_ = 0;
+ hdr->update_map_ = 0;
+ hdr->absolute_delta_ = 1;
+ memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_));
+ memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_));
+}
+
+// Paragraph 9.3
+static int ParseSegmentHeader(VP8BitReader* br,
+ VP8SegmentHeader* hdr, VP8Proba* proba) {
+ assert(br != NULL);
+ assert(hdr != NULL);
+ hdr->use_segment_ = VP8Get(br);
+ if (hdr->use_segment_) {
+ hdr->update_map_ = VP8Get(br);
+ if (VP8Get(br)) { // update data
+ int s;
+ hdr->absolute_delta_ = VP8Get(br);
+ for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+ hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
+ }
+ for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
+ hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
+ }
+ }
+ if (hdr->update_map_) {
+ int s;
+ for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
+ proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u;
+ }
+ }
+ } else {
+ hdr->update_map_ = 0;
+ }
+ return !br->eof_;
+}
+
+// Paragraph 9.5
+// This function returns VP8_STATUS_SUSPENDED if we don't have all the
+// necessary data in 'buf'.
+// This case is not necessarily an error (for incremental decoding).
+// Still, no bitreader is ever initialized to make it possible to read
+// unavailable memory.
+// If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA
+// is returned, and this is an unrecoverable error.
+// If the partitions were positioned ok, VP8_STATUS_OK is returned.
+static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
+ const uint8_t* buf, size_t size) {
+ VP8BitReader* const br = &dec->br_;
+ const uint8_t* sz = buf;
+ const uint8_t* buf_end = buf + size;
+ const uint8_t* part_start;
+ size_t size_left = size;
+ size_t last_part;
+ size_t p;
+
+ dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1;
+ last_part = dec->num_parts_minus_one_;
+ if (size < 3 * last_part) {
+ // we can't even read the sizes with sz[]! That's a failure.
+ return VP8_STATUS_NOT_ENOUGH_DATA;
+ }
+ part_start = buf + last_part * 3;
+ size_left -= last_part * 3;
+ for (p = 0; p < last_part; ++p) {
+ size_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16);
+ if (psize > size_left) psize = size_left;
+ VP8InitBitReader(dec->parts_ + p, part_start, psize);
+ part_start += psize;
+ size_left -= psize;
+ sz += 3;
+ }
+ VP8InitBitReader(dec->parts_ + last_part, part_start, size_left);
+ return (part_start < buf_end) ? VP8_STATUS_OK :
+ VP8_STATUS_SUSPENDED; // Init is ok, but there's not enough data
+}
+
+// Paragraph 9.4
+static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
+ VP8FilterHeader* const hdr = &dec->filter_hdr_;
+ hdr->simple_ = VP8Get(br);
+ hdr->level_ = VP8GetValue(br, 6);
+ hdr->sharpness_ = VP8GetValue(br, 3);
+ hdr->use_lf_delta_ = VP8Get(br);
+ if (hdr->use_lf_delta_) {
+ if (VP8Get(br)) { // update lf-delta?
+ int i;
+ for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
+ if (VP8Get(br)) {
+ hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6);
+ }
+ }
+ for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
+ if (VP8Get(br)) {
+ hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6);
+ }
+ }
+ }
+ }
+ dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2;
+ return !br->eof_;
+}
+
+// Topmost call
+int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
+ const uint8_t* buf;
+ size_t buf_size;
+ VP8FrameHeader* frm_hdr;
+ VP8PictureHeader* pic_hdr;
+ VP8BitReader* br;
+ VP8StatusCode status;
+
+ if (dec == NULL) {
+ return 0;
+ }
+ SetOk(dec);
+ if (io == NULL) {
+ return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
+ "null VP8Io passed to VP8GetHeaders()");
+ }
+ buf = io->data;
+ buf_size = io->data_size;
+ if (buf_size < 4) {
+ return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+ "Truncated header.");
+ }
+
+ // Paragraph 9.1
+ {
+ const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
+ frm_hdr = &dec->frm_hdr_;
+ frm_hdr->key_frame_ = !(bits & 1);
+ frm_hdr->profile_ = (bits >> 1) & 7;
+ frm_hdr->show_ = (bits >> 4) & 1;
+ frm_hdr->partition_length_ = (bits >> 5);
+ if (frm_hdr->profile_ > 3) {
+ return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+ "Incorrect keyframe parameters.");
+ }
+ if (!frm_hdr->show_) {
+ return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
+ "Frame not displayable.");
+ }
+ buf += 3;
+ buf_size -= 3;
+ }
+
+ pic_hdr = &dec->pic_hdr_;
+ if (frm_hdr->key_frame_) {
+ // Paragraph 9.2
+ if (buf_size < 7) {
+ return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+ "cannot parse picture header");
+ }
+ if (!VP8CheckSignature(buf, buf_size)) {
+ return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+ "Bad code word");
+ }
+ pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff;
+ pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2
+ pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff;
+ pic_hdr->yscale_ = buf[6] >> 6;
+ buf += 7;
+ buf_size -= 7;
+
+ dec->mb_w_ = (pic_hdr->width_ + 15) >> 4;
+ dec->mb_h_ = (pic_hdr->height_ + 15) >> 4;
+
+ // Setup default output area (can be later modified during io->setup())
+ io->width = pic_hdr->width_;
+ io->height = pic_hdr->height_;
+ // IMPORTANT! use some sane dimensions in crop_* and scaled_* fields.
+ // So they can be used interchangeably without always testing for
+ // 'use_cropping'.
+ io->use_cropping = 0;
+ io->crop_top = 0;
+ io->crop_left = 0;
+ io->crop_right = io->width;
+ io->crop_bottom = io->height;
+ io->use_scaling = 0;
+ io->scaled_width = io->width;
+ io->scaled_height = io->height;
+
+ io->mb_w = io->width; // sanity check
+ io->mb_h = io->height; // ditto
+
+ VP8ResetProba(&dec->proba_);
+ ResetSegmentHeader(&dec->segment_hdr_);
+ }
+
+ // Check if we have all the partition #0 available, and initialize dec->br_
+ // to read this partition (and this partition only).
+ if (frm_hdr->partition_length_ > buf_size) {
+ return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+ "bad partition length");
+ }
+
+ br = &dec->br_;
+ VP8InitBitReader(br, buf, frm_hdr->partition_length_);
+ buf += frm_hdr->partition_length_;
+ buf_size -= frm_hdr->partition_length_;
+
+ if (frm_hdr->key_frame_) {
+ pic_hdr->colorspace_ = VP8Get(br);
+ pic_hdr->clamp_type_ = VP8Get(br);
+ }
+ if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
+ return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+ "cannot parse segment header");
+ }
+ // Filter specs
+ if (!ParseFilterHeader(br, dec)) {
+ return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+ "cannot parse filter header");
+ }
+ status = ParsePartitions(dec, buf, buf_size);
+ if (status != VP8_STATUS_OK) {
+ return VP8SetError(dec, status, "cannot parse partitions");
+ }
+
+ // quantizer change
+ VP8ParseQuant(dec);
+
+ // Frame buffer marking
+ if (!frm_hdr->key_frame_) {
+ return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
+ "Not a key frame.");
+ }
+
+ VP8Get(br); // ignore the value of update_proba_
+
+ VP8ParseProba(br, dec);
+
+ // sanitized state
+ dec->ready_ = 1;
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// Residual decoding (Paragraph 13.2 / 13.3)
+
+static const uint8_t kCat3[] = { 173, 148, 140, 0 };
+static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 };
+static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 };
+static const uint8_t kCat6[] =
+ { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 };
+static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 };
+static const uint8_t kZigzag[16] = {
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
+static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
+ int v;
+ if (!VP8GetBit(br, p[3])) {
+ if (!VP8GetBit(br, p[4])) {
+ v = 2;
+ } else {
+ v = 3 + VP8GetBit(br, p[5]);
+ }
+ } else {
+ if (!VP8GetBit(br, p[6])) {
+ if (!VP8GetBit(br, p[7])) {
+ v = 5 + VP8GetBit(br, 159);
+ } else {
+ v = 7 + 2 * VP8GetBit(br, 165);
+ v += VP8GetBit(br, 145);
+ }
+ } else {
+ const uint8_t* tab;
+ const int bit1 = VP8GetBit(br, p[8]);
+ const int bit0 = VP8GetBit(br, p[9 + bit1]);
+ const int cat = 2 * bit1 + bit0;
+ v = 0;
+ for (tab = kCat3456[cat]; *tab; ++tab) {
+ v += v + VP8GetBit(br, *tab);
+ }
+ v += 3 + (8 << cat);
+ }
+ }
+ return v;
+}
+
+// Returns the position of the last non-zero coeff plus one
+static int GetCoeffsFast(VP8BitReader* const br,
+ const VP8BandProbas* const prob[],
+ int ctx, const quant_t dq, int n, int16_t* out) {
+ const uint8_t* p = prob[n]->probas_[ctx];
+ for (; n < 16; ++n) {
+ if (!VP8GetBit(br, p[0])) {
+ return n; // previous coeff was last non-zero coeff
+ }
+ while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs
+ p = prob[++n]->probas_[0];
+ if (n == 16) return 16;
+ }
+ { // non zero coeff
+ const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
+ int v;
+ if (!VP8GetBit(br, p[2])) {
+ v = 1;
+ p = p_ctx[1];
+ } else {
+ v = GetLargeValue(br, p);
+ p = p_ctx[2];
+ }
+ out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
+ }
+ }
+ return 16;
+}
+
+// This version of GetCoeffs() uses VP8GetBitAlt() which is an alternate version
+// of VP8GetBitAlt() targeting specific platforms.
+static int GetCoeffsAlt(VP8BitReader* const br,
+ const VP8BandProbas* const prob[],
+ int ctx, const quant_t dq, int n, int16_t* out) {
+ const uint8_t* p = prob[n]->probas_[ctx];
+ for (; n < 16; ++n) {
+ if (!VP8GetBitAlt(br, p[0])) {
+ return n; // previous coeff was last non-zero coeff
+ }
+ while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs
+ p = prob[++n]->probas_[0];
+ if (n == 16) return 16;
+ }
+ { // non zero coeff
+ const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
+ int v;
+ if (!VP8GetBitAlt(br, p[2])) {
+ v = 1;
+ p = p_ctx[1];
+ } else {
+ v = GetLargeValue(br, p);
+ p = p_ctx[2];
+ }
+ out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
+ }
+ }
+ return 16;
+}
+
+WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) {
+ if (GetCoeffs == NULL) {
+ if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
+ GetCoeffs = GetCoeffsAlt;
+ } else {
+ GetCoeffs = GetCoeffsFast;
+ }
+ }
+}
+
+static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) {
+ nz_coeffs <<= 2;
+ nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz;
+ return nz_coeffs;
+}
+
+static int ParseResiduals(VP8Decoder* const dec,
+ VP8MB* const mb, VP8BitReader* const token_br) {
+ const VP8BandProbas* (* const bands)[16 + 1] = dec->proba_.bands_ptr_;
+ const VP8BandProbas* const * ac_proba;
+ VP8MBData* const block = dec->mb_data_ + dec->mb_x_;
+ const VP8QuantMatrix* const q = &dec->dqm_[block->segment_];
+ int16_t* dst = block->coeffs_;
+ VP8MB* const left_mb = dec->mb_info_ - 1;
+ uint8_t tnz, lnz;
+ uint32_t non_zero_y = 0;
+ uint32_t non_zero_uv = 0;
+ int x, y, ch;
+ uint32_t out_t_nz, out_l_nz;
+ int first;
+
+ memset(dst, 0, 384 * sizeof(*dst));
+ if (!block->is_i4x4_) { // parse DC
+ int16_t dc[16] = { 0 };
+ const int ctx = mb->nz_dc_ + left_mb->nz_dc_;
+ const int nz = GetCoeffs(token_br, bands[1], ctx, q->y2_mat_, 0, dc);
+ mb->nz_dc_ = left_mb->nz_dc_ = (nz > 0);
+ if (nz > 1) { // more than just the DC -> perform the full transform
+ VP8TransformWHT(dc, dst);
+ } else { // only DC is non-zero -> inlined simplified transform
+ int i;
+ const int dc0 = (dc[0] + 3) >> 3;
+ for (i = 0; i < 16 * 16; i += 16) dst[i] = dc0;
+ }
+ first = 1;
+ ac_proba = bands[0];
+ } else {
+ first = 0;
+ ac_proba = bands[3];
+ }
+
+ tnz = mb->nz_ & 0x0f;
+ lnz = left_mb->nz_ & 0x0f;
+ for (y = 0; y < 4; ++y) {
+ int l = lnz & 1;
+ uint32_t nz_coeffs = 0;
+ for (x = 0; x < 4; ++x) {
+ const int ctx = l + (tnz & 1);
+ const int nz = GetCoeffs(token_br, ac_proba, ctx, q->y1_mat_, first, dst);
+ l = (nz > first);
+ tnz = (tnz >> 1) | (l << 7);
+ nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0);
+ dst += 16;
+ }
+ tnz >>= 4;
+ lnz = (lnz >> 1) | (l << 7);
+ non_zero_y = (non_zero_y << 8) | nz_coeffs;
+ }
+ out_t_nz = tnz;
+ out_l_nz = lnz >> 4;
+
+ for (ch = 0; ch < 4; ch += 2) {
+ uint32_t nz_coeffs = 0;
+ tnz = mb->nz_ >> (4 + ch);
+ lnz = left_mb->nz_ >> (4 + ch);
+ for (y = 0; y < 2; ++y) {
+ int l = lnz & 1;
+ for (x = 0; x < 2; ++x) {
+ const int ctx = l + (tnz & 1);
+ const int nz = GetCoeffs(token_br, bands[2], ctx, q->uv_mat_, 0, dst);
+ l = (nz > 0);
+ tnz = (tnz >> 1) | (l << 3);
+ nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0);
+ dst += 16;
+ }
+ tnz >>= 2;
+ lnz = (lnz >> 1) | (l << 5);
+ }
+ // Note: we don't really need the per-4x4 details for U/V blocks.
+ non_zero_uv |= nz_coeffs << (4 * ch);
+ out_t_nz |= (tnz << 4) << ch;
+ out_l_nz |= (lnz & 0xf0) << ch;
+ }
+ mb->nz_ = out_t_nz;
+ left_mb->nz_ = out_l_nz;
+
+ block->non_zero_y_ = non_zero_y;
+ block->non_zero_uv_ = non_zero_uv;
+
+ // We look at the mode-code of each block and check if some blocks have less
+ // than three non-zero coeffs (code < 2). This is to avoid dithering flat and
+ // empty blocks.
+ block->dither_ = (non_zero_uv & 0xaaaa) ? 0 : q->dither_;
+
+ return !(non_zero_y | non_zero_uv); // will be used for further optimization
+}
+
+//------------------------------------------------------------------------------
+// Main loop
+
+int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) {
+ VP8MB* const left = dec->mb_info_ - 1;
+ VP8MB* const mb = dec->mb_info_ + dec->mb_x_;
+ VP8MBData* const block = dec->mb_data_ + dec->mb_x_;
+ int skip = dec->use_skip_proba_ ? block->skip_ : 0;
+
+ if (!skip) {
+ skip = ParseResiduals(dec, mb, token_br);
+ } else {
+ left->nz_ = mb->nz_ = 0;
+ if (!block->is_i4x4_) {
+ left->nz_dc_ = mb->nz_dc_ = 0;
+ }
+ block->non_zero_y_ = 0;
+ block->non_zero_uv_ = 0;
+ block->dither_ = 0;
+ }
+
+ if (dec->filter_type_ > 0) { // store filter info
+ VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_;
+ *finfo = dec->fstrengths_[block->segment_][block->is_i4x4_];
+ finfo->f_inner_ |= !skip;
+ }
+
+ return !token_br->eof_;
+}
+
+void VP8InitScanline(VP8Decoder* const dec) {
+ VP8MB* const left = dec->mb_info_ - 1;
+ left->nz_ = 0;
+ left->nz_dc_ = 0;
+ memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_));
+ dec->mb_x_ = 0;
+}
+
+static int ParseFrame(VP8Decoder* const dec, VP8Io* io) {
+ for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) {
+ // Parse bitstream for this row.
+ VP8BitReader* const token_br =
+ &dec->parts_[dec->mb_y_ & dec->num_parts_minus_one_];
+ if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
+ return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+ "Premature end-of-partition0 encountered.");
+ }
+ for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
+ if (!VP8DecodeMB(dec, token_br)) {
+ return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
+ "Premature end-of-file encountered.");
+ }
+ }
+ VP8InitScanline(dec); // Prepare for next scanline
+
+ // Reconstruct, filter and emit the row.
+ if (!VP8ProcessRow(dec, io)) {
+ return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted.");
+ }
+ }
+ if (dec->mt_method_ > 0) {
+ if (!WebPGetWorkerInterface()->Sync(&dec->worker_)) return 0;
+ }
+
+ return 1;
+}
+
+// Main entry point
+int VP8Decode(VP8Decoder* const dec, VP8Io* const io) {
+ int ok = 0;
+ if (dec == NULL) {
+ return 0;
+ }
+ if (io == NULL) {
+ return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
+ "NULL VP8Io parameter in VP8Decode().");
+ }
+
+ if (!dec->ready_) {
+ if (!VP8GetHeaders(dec, io)) {
+ return 0;
+ }
+ }
+ assert(dec->ready_);
+
+ // Finish setting up the decoding parameter. Will call io->setup().
+ ok = (VP8EnterCritical(dec, io) == VP8_STATUS_OK);
+ if (ok) { // good to go.
+ // Will allocate memory and prepare everything.
+ if (ok) ok = VP8InitFrame(dec, io);
+
+ // Main decoding loop
+ if (ok) ok = ParseFrame(dec, io);
+
+ // Exit.
+ ok &= VP8ExitCritical(dec, io);
+ }
+
+ if (!ok) {
+ VP8Clear(dec);
+ return 0;
+ }
+
+ dec->ready_ = 0;
+ return ok;
+}
+
+void VP8Clear(VP8Decoder* const dec) {
+ if (dec == NULL) {
+ return;
+ }
+ WebPGetWorkerInterface()->End(&dec->worker_);
+ WebPDeallocateAlphaMemory(dec);
+ WebPSafeFree(dec->mem_);
+ dec->mem_ = NULL;
+ dec->mem_size_ = 0;
+ memset(&dec->br_, 0, sizeof(dec->br_));
+ dec->ready_ = 0;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dec/vp8_dec.h b/media/libwebp/dec/vp8_dec.h
new file mode 100644
index 000000000..b9337bbec
--- /dev/null
+++ b/media/libwebp/dec/vp8_dec.h
@@ -0,0 +1,185 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Low-level API for VP8 decoder
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_DECODE_VP8_H_
+#define WEBP_WEBP_DECODE_VP8_H_
+
+#include "../webp/decode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Lower-level API
+//
+// These functions provide fine-grained control of the decoding process.
+// The call flow should resemble:
+//
+// VP8Io io;
+// VP8InitIo(&io);
+// io.data = data;
+// io.data_size = size;
+// /* customize io's functions (setup()/put()/teardown()) if needed. */
+//
+// VP8Decoder* dec = VP8New();
+// bool ok = VP8Decode(dec);
+// if (!ok) printf("Error: %s\n", VP8StatusMessage(dec));
+// VP8Delete(dec);
+// return ok;
+
+// Input / Output
+typedef struct VP8Io VP8Io;
+typedef int (*VP8IoPutHook)(const VP8Io* io);
+typedef int (*VP8IoSetupHook)(VP8Io* io);
+typedef void (*VP8IoTeardownHook)(const VP8Io* io);
+
+struct VP8Io {
+ // set by VP8GetHeaders()
+ int width, height; // picture dimensions, in pixels (invariable).
+ // These are the original, uncropped dimensions.
+ // The actual area passed to put() is stored
+ // in mb_w / mb_h fields.
+
+ // set before calling put()
+ int mb_y; // position of the current rows (in pixels)
+ int mb_w; // number of columns in the sample
+ int mb_h; // number of rows in the sample
+ const uint8_t* y, *u, *v; // rows to copy (in yuv420 format)
+ int y_stride; // row stride for luma
+ int uv_stride; // row stride for chroma
+
+ void* opaque; // user data
+
+ // called when fresh samples are available. Currently, samples are in
+ // YUV420 format, and can be up to width x 24 in size (depending on the
+ // in-loop filtering level, e.g.). Should return false in case of error
+ // or abort request. The actual size of the area to update is mb_w x mb_h
+ // in size, taking cropping into account.
+ VP8IoPutHook put;
+
+ // called just before starting to decode the blocks.
+ // Must return false in case of setup error, true otherwise. If false is
+ // returned, teardown() will NOT be called. But if the setup succeeded
+ // and true is returned, then teardown() will always be called afterward.
+ VP8IoSetupHook setup;
+
+ // Called just after block decoding is finished (or when an error occurred
+ // during put()). Is NOT called if setup() failed.
+ VP8IoTeardownHook teardown;
+
+ // this is a recommendation for the user-side yuv->rgb converter. This flag
+ // is set when calling setup() hook and can be overwritten by it. It then
+ // can be taken into consideration during the put() method.
+ int fancy_upsampling;
+
+ // Input buffer.
+ size_t data_size;
+ const uint8_t* data;
+
+ // If true, in-loop filtering will not be performed even if present in the
+ // bitstream. Switching off filtering may speed up decoding at the expense
+ // of more visible blocking. Note that output will also be non-compliant
+ // with the VP8 specifications.
+ int bypass_filtering;
+
+ // Cropping parameters.
+ int use_cropping;
+ int crop_left, crop_right, crop_top, crop_bottom;
+
+ // Scaling parameters.
+ int use_scaling;
+ int scaled_width, scaled_height;
+
+ // If non NULL, pointer to the alpha data (if present) corresponding to the
+ // start of the current row (That is: it is pre-offset by mb_y and takes
+ // cropping into account).
+ const uint8_t* a;
+};
+
+// Internal, version-checked, entry point
+int VP8InitIoInternal(VP8Io* const, int);
+
+// Set the custom IO function pointers and user-data. The setter for IO hooks
+// should be called before initiating incremental decoding. Returns true if
+// WebPIDecoder object is successfully modified, false otherwise.
+int WebPISetIOHooks(WebPIDecoder* const idec,
+ VP8IoPutHook put,
+ VP8IoSetupHook setup,
+ VP8IoTeardownHook teardown,
+ void* user_data);
+
+// Main decoding object. This is an opaque structure.
+typedef struct VP8Decoder VP8Decoder;
+
+// Create a new decoder object.
+VP8Decoder* VP8New(void);
+
+// Must be called to make sure 'io' is initialized properly.
+// Returns false in case of version mismatch. Upon such failure, no other
+// decoding function should be called (VP8Decode, VP8GetHeaders, ...)
+static WEBP_INLINE int VP8InitIo(VP8Io* const io) {
+ return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION);
+}
+
+// Decode the VP8 frame header. Returns true if ok.
+// Note: 'io->data' must be pointing to the start of the VP8 frame header.
+int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
+
+// Decode a picture. Will call VP8GetHeaders() if it wasn't done already.
+// Returns false in case of error.
+int VP8Decode(VP8Decoder* const dec, VP8Io* const io);
+
+// Return current status of the decoder:
+VP8StatusCode VP8Status(VP8Decoder* const dec);
+
+// return readable string corresponding to the last status.
+const char* VP8StatusMessage(VP8Decoder* const dec);
+
+// Resets the decoder in its initial state, reclaiming memory.
+// Not a mandatory call between calls to VP8Decode().
+void VP8Clear(VP8Decoder* const dec);
+
+// Destroy the decoder object.
+void VP8Delete(VP8Decoder* const dec);
+
+//------------------------------------------------------------------------------
+// Miscellaneous VP8/VP8L bitstream probing functions.
+
+// Returns true if the next 3 bytes in data contain the VP8 signature.
+WEBP_EXTERN(int) VP8CheckSignature(const uint8_t* const data, size_t data_size);
+
+// Validates the VP8 data-header and retrieves basic header information viz
+// width and height. Returns 0 in case of formatting error. *width/*height
+// can be passed NULL.
+WEBP_EXTERN(int) VP8GetInfo(
+ const uint8_t* data,
+ size_t data_size, // data available so far
+ size_t chunk_size, // total data size expected in the chunk
+ int* const width, int* const height);
+
+// Returns true if the next byte(s) in data is a VP8L signature.
+WEBP_EXTERN(int) VP8LCheckSignature(const uint8_t* const data, size_t size);
+
+// Validates the VP8L data-header and retrieves basic header information viz
+// width, height and alpha. Returns 0 in case of formatting error.
+// width/height/has_alpha can be passed NULL.
+WEBP_EXTERN(int) VP8LGetInfo(
+ const uint8_t* data, size_t data_size, // data available so far
+ int* const width, int* const height, int* const has_alpha);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_DECODE_VP8_H_ */
diff --git a/media/libwebp/dec/vp8i_dec.h b/media/libwebp/dec/vp8i_dec.h
new file mode 100644
index 000000000..555853e8f
--- /dev/null
+++ b/media/libwebp/dec/vp8i_dec.h
@@ -0,0 +1,320 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// VP8 decoder: internal header.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_DEC_VP8I_H_
+#define WEBP_DEC_VP8I_H_
+
+#include <string.h> // for memcpy()
+#include "./common_dec.h"
+#include "./vp8li_dec.h"
+#include "../utils/bit_reader_utils.h"
+#include "../utils/random_utils.h"
+#include "../utils/thread_utils.h"
+#include "../dsp/dsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Various defines and enums
+
+// version numbers
+#define DEC_MAJ_VERSION 0
+#define DEC_MIN_VERSION 6
+#define DEC_REV_VERSION 0
+
+// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
+// Constraints are: We need to store one 16x16 block of luma samples (y),
+// and two 8x8 chroma blocks (u/v). These are better be 16-bytes aligned,
+// in order to be SIMD-friendly. We also need to store the top, left and
+// top-left samples (from previously decoded blocks), along with four
+// extra top-right samples for luma (intra4x4 prediction only).
+// One possible layout is, using 32 * (17 + 9) bytes:
+//
+// .+------ <- only 1 pixel high
+// .|yyyyt.
+// .|yyyyt.
+// .|yyyyt.
+// .|yyyy..
+// .+--.+-- <- only 1 pixel high
+// .|uu.|vv
+// .|uu.|vv
+//
+// Every character is a 4x4 block, with legend:
+// '.' = unused
+// 'y' = y-samples 'u' = u-samples 'v' = u-samples
+// '|' = left sample, '-' = top sample, '+' = top-left sample
+// 't' = extra top-right sample for 4x4 modes
+#define YUV_SIZE (BPS * 17 + BPS * 9)
+#define Y_SIZE (BPS * 17)
+#define Y_OFF (BPS * 1 + 8)
+#define U_OFF (Y_OFF + BPS * 16 + BPS)
+#define V_OFF (U_OFF + 16)
+
+// minimal width under which lossy multi-threading is always disabled
+#define MIN_WIDTH_FOR_THREADS 512
+
+//------------------------------------------------------------------------------
+// Headers
+
+typedef struct {
+ uint8_t key_frame_;
+ uint8_t profile_;
+ uint8_t show_;
+ uint32_t partition_length_;
+} VP8FrameHeader;
+
+typedef struct {
+ uint16_t width_;
+ uint16_t height_;
+ uint8_t xscale_;
+ uint8_t yscale_;
+ uint8_t colorspace_; // 0 = YCbCr
+ uint8_t clamp_type_;
+} VP8PictureHeader;
+
+// segment features
+typedef struct {
+ int use_segment_;
+ int update_map_; // whether to update the segment map or not
+ int absolute_delta_; // absolute or delta values for quantizer and filter
+ int8_t quantizer_[NUM_MB_SEGMENTS]; // quantization changes
+ int8_t filter_strength_[NUM_MB_SEGMENTS]; // filter strength for segments
+} VP8SegmentHeader;
+
+// probas associated to one of the contexts
+typedef uint8_t VP8ProbaArray[NUM_PROBAS];
+
+typedef struct { // all the probas associated to one band
+ VP8ProbaArray probas_[NUM_CTX];
+} VP8BandProbas;
+
+// Struct collecting all frame-persistent probabilities.
+typedef struct {
+ uint8_t segments_[MB_FEATURE_TREE_PROBS];
+ // Type: 0:Intra16-AC 1:Intra16-DC 2:Chroma 3:Intra4
+ VP8BandProbas bands_[NUM_TYPES][NUM_BANDS];
+ const VP8BandProbas* bands_ptr_[NUM_TYPES][16 + 1];
+} VP8Proba;
+
+// Filter parameters
+typedef struct {
+ int simple_; // 0=complex, 1=simple
+ int level_; // [0..63]
+ int sharpness_; // [0..7]
+ int use_lf_delta_;
+ int ref_lf_delta_[NUM_REF_LF_DELTAS];
+ int mode_lf_delta_[NUM_MODE_LF_DELTAS];
+} VP8FilterHeader;
+
+//------------------------------------------------------------------------------
+// Informations about the macroblocks.
+
+typedef struct { // filter specs
+ uint8_t f_limit_; // filter limit in [3..189], or 0 if no filtering
+ uint8_t f_ilevel_; // inner limit in [1..63]
+ uint8_t f_inner_; // do inner filtering?
+ uint8_t hev_thresh_; // high edge variance threshold in [0..2]
+} VP8FInfo;
+
+typedef struct { // Top/Left Contexts used for syntax-parsing
+ uint8_t nz_; // non-zero AC/DC coeffs (4bit for luma + 4bit for chroma)
+ uint8_t nz_dc_; // non-zero DC coeff (1bit)
+} VP8MB;
+
+// Dequantization matrices
+typedef int quant_t[2]; // [DC / AC]. Can be 'uint16_t[2]' too (~slower).
+typedef struct {
+ quant_t y1_mat_, y2_mat_, uv_mat_;
+
+ int uv_quant_; // U/V quantizer value
+ int dither_; // dithering amplitude (0 = off, max=255)
+} VP8QuantMatrix;
+
+// Data needed to reconstruct a macroblock
+typedef struct {
+ int16_t coeffs_[384]; // 384 coeffs = (16+4+4) * 4*4
+ uint8_t is_i4x4_; // true if intra4x4
+ uint8_t imodes_[16]; // one 16x16 mode (#0) or sixteen 4x4 modes
+ uint8_t uvmode_; // chroma prediction mode
+ // bit-wise info about the content of each sub-4x4 blocks (in decoding order).
+ // Each of the 4x4 blocks for y/u/v is associated with a 2b code according to:
+ // code=0 -> no coefficient
+ // code=1 -> only DC
+ // code=2 -> first three coefficients are non-zero
+ // code=3 -> more than three coefficients are non-zero
+ // This allows to call specialized transform functions.
+ uint32_t non_zero_y_;
+ uint32_t non_zero_uv_;
+ uint8_t dither_; // local dithering strength (deduced from non_zero_*)
+ uint8_t skip_;
+ uint8_t segment_;
+} VP8MBData;
+
+// Persistent information needed by the parallel processing
+typedef struct {
+ int id_; // cache row to process (in [0..2])
+ int mb_y_; // macroblock position of the row
+ int filter_row_; // true if row-filtering is needed
+ VP8FInfo* f_info_; // filter strengths (swapped with dec->f_info_)
+ VP8MBData* mb_data_; // reconstruction data (swapped with dec->mb_data_)
+ VP8Io io_; // copy of the VP8Io to pass to put()
+} VP8ThreadContext;
+
+// Saved top samples, per macroblock. Fits into a cache-line.
+typedef struct {
+ uint8_t y[16], u[8], v[8];
+} VP8TopSamples;
+
+//------------------------------------------------------------------------------
+// VP8Decoder: the main opaque structure handed over to user
+
+struct VP8Decoder {
+ VP8StatusCode status_;
+ int ready_; // true if ready to decode a picture with VP8Decode()
+ const char* error_msg_; // set when status_ is not OK.
+
+ // Main data source
+ VP8BitReader br_;
+
+ // headers
+ VP8FrameHeader frm_hdr_;
+ VP8PictureHeader pic_hdr_;
+ VP8FilterHeader filter_hdr_;
+ VP8SegmentHeader segment_hdr_;
+
+ // Worker
+ WebPWorker worker_;
+ int mt_method_; // multi-thread method: 0=off, 1=[parse+recon][filter]
+ // 2=[parse][recon+filter]
+ int cache_id_; // current cache row
+ int num_caches_; // number of cached rows of 16 pixels (1, 2 or 3)
+ VP8ThreadContext thread_ctx_; // Thread context
+
+ // dimension, in macroblock units.
+ int mb_w_, mb_h_;
+
+ // Macroblock to process/filter, depending on cropping and filter_type.
+ int tl_mb_x_, tl_mb_y_; // top-left MB that must be in-loop filtered
+ int br_mb_x_, br_mb_y_; // last bottom-right MB that must be decoded
+
+ // number of partitions minus one.
+ uint32_t num_parts_minus_one_;
+ // per-partition boolean decoders.
+ VP8BitReader parts_[MAX_NUM_PARTITIONS];
+
+ // Dithering strength, deduced from decoding options
+ int dither_; // whether to use dithering or not
+ VP8Random dithering_rg_; // random generator for dithering
+
+ // dequantization (one set of DC/AC dequant factor per segment)
+ VP8QuantMatrix dqm_[NUM_MB_SEGMENTS];
+
+ // probabilities
+ VP8Proba proba_;
+ int use_skip_proba_;
+ uint8_t skip_p_;
+
+ // Boundary data cache and persistent buffers.
+ uint8_t* intra_t_; // top intra modes values: 4 * mb_w_
+ uint8_t intra_l_[4]; // left intra modes values
+
+ VP8TopSamples* yuv_t_; // top y/u/v samples
+
+ VP8MB* mb_info_; // contextual macroblock info (mb_w_ + 1)
+ VP8FInfo* f_info_; // filter strength info
+ uint8_t* yuv_b_; // main block for Y/U/V (size = YUV_SIZE)
+
+ uint8_t* cache_y_; // macroblock row for storing unfiltered samples
+ uint8_t* cache_u_;
+ uint8_t* cache_v_;
+ int cache_y_stride_;
+ int cache_uv_stride_;
+
+ // main memory chunk for the above data. Persistent.
+ void* mem_;
+ size_t mem_size_;
+
+ // Per macroblock non-persistent infos.
+ int mb_x_, mb_y_; // current position, in macroblock units
+ VP8MBData* mb_data_; // parsed reconstruction data
+
+ // Filtering side-info
+ int filter_type_; // 0=off, 1=simple, 2=complex
+ VP8FInfo fstrengths_[NUM_MB_SEGMENTS][2]; // precalculated per-segment/type
+
+ // Alpha
+ struct ALPHDecoder* alph_dec_; // alpha-plane decoder object
+ const uint8_t* alpha_data_; // compressed alpha data (if present)
+ size_t alpha_data_size_;
+ int is_alpha_decoded_; // true if alpha_data_ is decoded in alpha_plane_
+ uint8_t* alpha_plane_mem_; // memory allocated for alpha_plane_
+ uint8_t* alpha_plane_; // output. Persistent, contains the whole data.
+ const uint8_t* alpha_prev_line_; // last decoded alpha row (or NULL)
+ int alpha_dithering_; // derived from decoding options (0=off, 100=full)
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+// in vp8.c
+int VP8SetError(VP8Decoder* const dec,
+ VP8StatusCode error, const char* const msg);
+
+// in tree.c
+void VP8ResetProba(VP8Proba* const proba);
+void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec);
+// parses one row of intra mode data in partition 0, returns !eof
+int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec);
+
+// in quant.c
+void VP8ParseQuant(VP8Decoder* const dec);
+
+// in frame.c
+int VP8InitFrame(VP8Decoder* const dec, VP8Io* const io);
+// Call io->setup() and finish setting up scan parameters.
+// After this call returns, one must always call VP8ExitCritical() with the
+// same parameters. Both functions should be used in pair. Returns VP8_STATUS_OK
+// if ok, otherwise sets and returns the error status on *dec.
+VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io);
+// Must always be called in pair with VP8EnterCritical().
+// Returns false in case of error.
+int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io);
+// Return the multi-threading method to use (0=off), depending
+// on options and bitstream size. Only for lossy decoding.
+int VP8GetThreadMethod(const WebPDecoderOptions* const options,
+ const WebPHeaderStructure* const headers,
+ int width, int height);
+// Initialize dithering post-process if needed.
+void VP8InitDithering(const WebPDecoderOptions* const options,
+ VP8Decoder* const dec);
+// Process the last decoded row (filtering + output).
+int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io);
+// To be called at the start of a new scanline, to initialize predictors.
+void VP8InitScanline(VP8Decoder* const dec);
+// Decode one macroblock. Returns false if there is not enough data.
+int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br);
+
+// in alpha.c
+const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
+ const VP8Io* const io,
+ int row, int num_rows);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_DEC_VP8I_H_ */
diff --git a/media/libwebp/dec/vp8l_dec.c b/media/libwebp/dec/vp8l_dec.c
new file mode 100644
index 000000000..ef359a91f
--- /dev/null
+++ b/media/libwebp/dec/vp8l_dec.c
@@ -0,0 +1,1671 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// main entry for the decoder
+//
+// Authors: Vikas Arora (vikaas.arora@gmail.com)
+// Jyrki Alakuijala (jyrki@google.com)
+
+#include <stdlib.h>
+
+#include "./alphai_dec.h"
+#include "./vp8li_dec.h"
+#include "../dsp/dsp.h"
+#include "../dsp/lossless.h"
+#include "../dsp/lossless_common.h"
+#include "../dsp/yuv.h"
+#include "../utils/endian_inl_utils.h"
+#include "../utils/huffman_utils.h"
+#include "../utils/utils.h"
+
+#define NUM_ARGB_CACHE_ROWS 16
+
+static const int kCodeLengthLiterals = 16;
+static const int kCodeLengthRepeatCode = 16;
+static const int kCodeLengthExtraBits[3] = { 2, 3, 7 };
+static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
+
+// -----------------------------------------------------------------------------
+// Five Huffman codes are used at each meta code:
+// 1. green + length prefix codes + color cache codes,
+// 2. alpha,
+// 3. red,
+// 4. blue, and,
+// 5. distance prefix codes.
+typedef enum {
+ GREEN = 0,
+ RED = 1,
+ BLUE = 2,
+ ALPHA = 3,
+ DIST = 4
+} HuffIndex;
+
+static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = {
+ NUM_LITERAL_CODES + NUM_LENGTH_CODES,
+ NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
+ NUM_DISTANCE_CODES
+};
+
+static const uint8_t kLiteralMap[HUFFMAN_CODES_PER_META_CODE] = {
+ 0, 1, 1, 1, 0
+};
+
+#define NUM_CODE_LENGTH_CODES 19
+static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = {
+ 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+#define CODE_TO_PLANE_CODES 120
+static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
+ 0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a,
+ 0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a,
+ 0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b,
+ 0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03,
+ 0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c,
+ 0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e,
+ 0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b,
+ 0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f,
+ 0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b,
+ 0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41,
+ 0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f,
+ 0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70
+};
+
+// Memory needed for lookup tables of one Huffman tree group. Red, blue, alpha
+// and distance alphabets are constant (256 for red, blue and alpha, 40 for
+// distance) and lookup table sizes for them in worst case are 630 and 410
+// respectively. Size of green alphabet depends on color cache size and is equal
+// to 256 (green component values) + 24 (length prefix values)
+// + color_cache_size (between 0 and 2048).
+// All values computed for 8-bit first level lookup with Mark Adler's tool:
+// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
+#define FIXED_TABLE_SIZE (630 * 3 + 410)
+static const int kTableSize[12] = {
+ FIXED_TABLE_SIZE + 654,
+ FIXED_TABLE_SIZE + 656,
+ FIXED_TABLE_SIZE + 658,
+ FIXED_TABLE_SIZE + 662,
+ FIXED_TABLE_SIZE + 670,
+ FIXED_TABLE_SIZE + 686,
+ FIXED_TABLE_SIZE + 718,
+ FIXED_TABLE_SIZE + 782,
+ FIXED_TABLE_SIZE + 912,
+ FIXED_TABLE_SIZE + 1168,
+ FIXED_TABLE_SIZE + 1680,
+ FIXED_TABLE_SIZE + 2704
+};
+
+static int DecodeImageStream(int xsize, int ysize,
+ int is_level0,
+ VP8LDecoder* const dec,
+ uint32_t** const decoded_data);
+
+//------------------------------------------------------------------------------
+
+int VP8LCheckSignature(const uint8_t* const data, size_t size) {
+ return (size >= VP8L_FRAME_HEADER_SIZE &&
+ data[0] == VP8L_MAGIC_BYTE &&
+ (data[4] >> 5) == 0); // version
+}
+
+static int ReadImageInfo(VP8LBitReader* const br,
+ int* const width, int* const height,
+ int* const has_alpha) {
+ if (VP8LReadBits(br, 8) != VP8L_MAGIC_BYTE) return 0;
+ *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
+ *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
+ *has_alpha = VP8LReadBits(br, 1);
+ if (VP8LReadBits(br, VP8L_VERSION_BITS) != 0) return 0;
+ return !br->eos_;
+}
+
+int VP8LGetInfo(const uint8_t* data, size_t data_size,
+ int* const width, int* const height, int* const has_alpha) {
+ if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) {
+ return 0; // not enough data
+ } else if (!VP8LCheckSignature(data, data_size)) {
+ return 0; // bad signature
+ } else {
+ int w, h, a;
+ VP8LBitReader br;
+ VP8LInitBitReader(&br, data, data_size);
+ if (!ReadImageInfo(&br, &w, &h, &a)) {
+ return 0;
+ }
+ if (width != NULL) *width = w;
+ if (height != NULL) *height = h;
+ if (has_alpha != NULL) *has_alpha = a;
+ return 1;
+ }
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int GetCopyDistance(int distance_symbol,
+ VP8LBitReader* const br) {
+ int extra_bits, offset;
+ if (distance_symbol < 4) {
+ return distance_symbol + 1;
+ }
+ extra_bits = (distance_symbol - 2) >> 1;
+ offset = (2 + (distance_symbol & 1)) << extra_bits;
+ return offset + VP8LReadBits(br, extra_bits) + 1;
+}
+
+static WEBP_INLINE int GetCopyLength(int length_symbol,
+ VP8LBitReader* const br) {
+ // Length and distance prefixes are encoded the same way.
+ return GetCopyDistance(length_symbol, br);
+}
+
+static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
+ if (plane_code > CODE_TO_PLANE_CODES) {
+ return plane_code - CODE_TO_PLANE_CODES;
+ } else {
+ const int dist_code = kCodeToPlane[plane_code - 1];
+ const int yoffset = dist_code >> 4;
+ const int xoffset = 8 - (dist_code & 0xf);
+ const int dist = yoffset * xsize + xoffset;
+ return (dist >= 1) ? dist : 1; // dist<1 can happen if xsize is very small
+ }
+}
+
+//------------------------------------------------------------------------------
+// Decodes the next Huffman code from bit-stream.
+// FillBitWindow(br) needs to be called at minimum every second call
+// to ReadSymbol, in order to pre-fetch enough bits.
+static WEBP_INLINE int ReadSymbol(const HuffmanCode* table,
+ VP8LBitReader* const br) {
+ int nbits;
+ uint32_t val = VP8LPrefetchBits(br);
+ table += val & HUFFMAN_TABLE_MASK;
+ nbits = table->bits - HUFFMAN_TABLE_BITS;
+ if (nbits > 0) {
+ VP8LSetBitPos(br, br->bit_pos_ + HUFFMAN_TABLE_BITS);
+ val = VP8LPrefetchBits(br);
+ table += table->value;
+ table += val & ((1 << nbits) - 1);
+ }
+ VP8LSetBitPos(br, br->bit_pos_ + table->bits);
+ return table->value;
+}
+
+// Reads packed symbol depending on GREEN channel
+#define BITS_SPECIAL_MARKER 0x100 // something large enough (and a bit-mask)
+#define PACKED_NON_LITERAL_CODE 0 // must be < NUM_LITERAL_CODES
+static WEBP_INLINE int ReadPackedSymbols(const HTreeGroup* group,
+ VP8LBitReader* const br,
+ uint32_t* const dst) {
+ const uint32_t val = VP8LPrefetchBits(br) & (HUFFMAN_PACKED_TABLE_SIZE - 1);
+ const HuffmanCode32 code = group->packed_table[val];
+ assert(group->use_packed_table);
+ if (code.bits < BITS_SPECIAL_MARKER) {
+ VP8LSetBitPos(br, br->bit_pos_ + code.bits);
+ *dst = code.value;
+ return PACKED_NON_LITERAL_CODE;
+ } else {
+ VP8LSetBitPos(br, br->bit_pos_ + code.bits - BITS_SPECIAL_MARKER);
+ assert(code.value >= NUM_LITERAL_CODES);
+ return code.value;
+ }
+}
+
+static int AccumulateHCode(HuffmanCode hcode, int shift,
+ HuffmanCode32* const huff) {
+ huff->bits += hcode.bits;
+ huff->value |= (uint32_t)hcode.value << shift;
+ assert(huff->bits <= HUFFMAN_TABLE_BITS);
+ return hcode.bits;
+}
+
+static void BuildPackedTable(HTreeGroup* const htree_group) {
+ uint32_t code;
+ for (code = 0; code < HUFFMAN_PACKED_TABLE_SIZE; ++code) {
+ uint32_t bits = code;
+ HuffmanCode32* const huff = &htree_group->packed_table[bits];
+ HuffmanCode hcode = htree_group->htrees[GREEN][bits];
+ if (hcode.value >= NUM_LITERAL_CODES) {
+ huff->bits = hcode.bits + BITS_SPECIAL_MARKER;
+ huff->value = hcode.value;
+ } else {
+ huff->bits = 0;
+ huff->value = 0;
+ bits >>= AccumulateHCode(hcode, 8, huff);
+ bits >>= AccumulateHCode(htree_group->htrees[RED][bits], 16, huff);
+ bits >>= AccumulateHCode(htree_group->htrees[BLUE][bits], 0, huff);
+ bits >>= AccumulateHCode(htree_group->htrees[ALPHA][bits], 24, huff);
+ (void)bits;
+ }
+ }
+}
+
+static int ReadHuffmanCodeLengths(
+ VP8LDecoder* const dec, const int* const code_length_code_lengths,
+ int num_symbols, int* const code_lengths) {
+ int ok = 0;
+ VP8LBitReader* const br = &dec->br_;
+ int symbol;
+ int max_symbol;
+ int prev_code_len = DEFAULT_CODE_LENGTH;
+ HuffmanCode table[1 << LENGTHS_TABLE_BITS];
+
+ if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
+ code_length_code_lengths,
+ NUM_CODE_LENGTH_CODES)) {
+ goto End;
+ }
+
+ if (VP8LReadBits(br, 1)) { // use length
+ const int length_nbits = 2 + 2 * VP8LReadBits(br, 3);
+ max_symbol = 2 + VP8LReadBits(br, length_nbits);
+ if (max_symbol > num_symbols) {
+ goto End;
+ }
+ } else {
+ max_symbol = num_symbols;
+ }
+
+ symbol = 0;
+ while (symbol < num_symbols) {
+ const HuffmanCode* p;
+ int code_len;
+ if (max_symbol-- == 0) break;
+ VP8LFillBitWindow(br);
+ p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+ VP8LSetBitPos(br, br->bit_pos_ + p->bits);
+ code_len = p->value;
+ if (code_len < kCodeLengthLiterals) {
+ code_lengths[symbol++] = code_len;
+ if (code_len != 0) prev_code_len = code_len;
+ } else {
+ const int use_prev = (code_len == kCodeLengthRepeatCode);
+ const int slot = code_len - kCodeLengthLiterals;
+ const int extra_bits = kCodeLengthExtraBits[slot];
+ const int repeat_offset = kCodeLengthRepeatOffsets[slot];
+ int repeat = VP8LReadBits(br, extra_bits) + repeat_offset;
+ if (symbol + repeat > num_symbols) {
+ goto End;
+ } else {
+ const int length = use_prev ? prev_code_len : 0;
+ while (repeat-- > 0) code_lengths[symbol++] = length;
+ }
+ }
+ }
+ ok = 1;
+
+ End:
+ if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ return ok;
+}
+
+// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
+// tree.
+static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
+ int* const code_lengths, HuffmanCode* const table) {
+ int ok = 0;
+ int size = 0;
+ VP8LBitReader* const br = &dec->br_;
+ const int simple_code = VP8LReadBits(br, 1);
+
+ memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths));
+
+ if (simple_code) { // Read symbols, codes & code lengths directly.
+ const int num_symbols = VP8LReadBits(br, 1) + 1;
+ const int first_symbol_len_code = VP8LReadBits(br, 1);
+ // The first code is either 1 bit or 8 bit code.
+ int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
+ code_lengths[symbol] = 1;
+ // The second code (if present), is always 8 bit long.
+ if (num_symbols == 2) {
+ symbol = VP8LReadBits(br, 8);
+ code_lengths[symbol] = 1;
+ }
+ ok = 1;
+ } else { // Decode Huffman-coded code lengths.
+ int i;
+ int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
+ const int num_codes = VP8LReadBits(br, 4) + 4;
+ if (num_codes > NUM_CODE_LENGTH_CODES) {
+ dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ return 0;
+ }
+
+ for (i = 0; i < num_codes; ++i) {
+ code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3);
+ }
+ ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size,
+ code_lengths);
+ }
+
+ ok = ok && !br->eos_;
+ if (ok) {
+ size = VP8LBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
+ code_lengths, alphabet_size);
+ }
+ if (!ok || size == 0) {
+ dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ return 0;
+ }
+ return size;
+}
+
+static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+ int color_cache_bits, int allow_recursion) {
+ int i, j;
+ VP8LBitReader* const br = &dec->br_;
+ VP8LMetadata* const hdr = &dec->hdr_;
+ uint32_t* huffman_image = NULL;
+ HTreeGroup* htree_groups = NULL;
+ HuffmanCode* huffman_tables = NULL;
+ HuffmanCode* next = NULL;
+ int num_htree_groups = 1;
+ int max_alphabet_size = 0;
+ int* code_lengths = NULL;
+ const int table_size = kTableSize[color_cache_bits];
+
+ if (allow_recursion && VP8LReadBits(br, 1)) {
+ // use meta Huffman codes.
+ const int huffman_precision = VP8LReadBits(br, 3) + 2;
+ const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision);
+ const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision);
+ const int huffman_pixs = huffman_xsize * huffman_ysize;
+ if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec,
+ &huffman_image)) {
+ goto Error;
+ }
+ hdr->huffman_subsample_bits_ = huffman_precision;
+ for (i = 0; i < huffman_pixs; ++i) {
+ // The huffman data is stored in red and green bytes.
+ const int group = (huffman_image[i] >> 8) & 0xffff;
+ huffman_image[i] = group;
+ if (group >= num_htree_groups) {
+ num_htree_groups = group + 1;
+ }
+ }
+ }
+
+ if (br->eos_) goto Error;
+
+ // Find maximum alphabet size for the htree group.
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+ int alphabet_size = kAlphabetSize[j];
+ if (j == 0 && color_cache_bits > 0) {
+ alphabet_size += 1 << color_cache_bits;
+ }
+ if (max_alphabet_size < alphabet_size) {
+ max_alphabet_size = alphabet_size;
+ }
+ }
+
+ huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
+ sizeof(*huffman_tables));
+ htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
+ code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
+ sizeof(*code_lengths));
+
+ if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ goto Error;
+ }
+
+ next = huffman_tables;
+ for (i = 0; i < num_htree_groups; ++i) {
+ HTreeGroup* const htree_group = &htree_groups[i];
+ HuffmanCode** const htrees = htree_group->htrees;
+ int size;
+ int total_size = 0;
+ int is_trivial_literal = 1;
+ int max_bits = 0;
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+ int alphabet_size = kAlphabetSize[j];
+ htrees[j] = next;
+ if (j == 0 && color_cache_bits > 0) {
+ alphabet_size += 1 << color_cache_bits;
+ }
+ size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next);
+ if (size == 0) {
+ goto Error;
+ }
+ if (is_trivial_literal && kLiteralMap[j] == 1) {
+ is_trivial_literal = (next->bits == 0);
+ }
+ total_size += next->bits;
+ next += size;
+ if (j <= ALPHA) {
+ int local_max_bits = code_lengths[0];
+ int k;
+ for (k = 1; k < alphabet_size; ++k) {
+ if (code_lengths[k] > local_max_bits) {
+ local_max_bits = code_lengths[k];
+ }
+ }
+ max_bits += local_max_bits;
+ }
+ }
+ htree_group->is_trivial_literal = is_trivial_literal;
+ htree_group->is_trivial_code = 0;
+ if (is_trivial_literal) {
+ const int red = htrees[RED][0].value;
+ const int blue = htrees[BLUE][0].value;
+ const int alpha = htrees[ALPHA][0].value;
+ htree_group->literal_arb =
+ ((uint32_t)alpha << 24) | (red << 16) | blue;
+ if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
+ htree_group->is_trivial_code = 1;
+ htree_group->literal_arb |= htrees[GREEN][0].value << 8;
+ }
+ }
+ htree_group->use_packed_table = !htree_group->is_trivial_code &&
+ (max_bits < HUFFMAN_PACKED_BITS);
+ if (htree_group->use_packed_table) BuildPackedTable(htree_group);
+ }
+ WebPSafeFree(code_lengths);
+
+ // All OK. Finalize pointers and return.
+ hdr->huffman_image_ = huffman_image;
+ hdr->num_htree_groups_ = num_htree_groups;
+ hdr->htree_groups_ = htree_groups;
+ hdr->huffman_tables_ = huffman_tables;
+ return 1;
+
+ Error:
+ WebPSafeFree(code_lengths);
+ WebPSafeFree(huffman_image);
+ WebPSafeFree(huffman_tables);
+ VP8LHtreeGroupsFree(htree_groups);
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// Scaling.
+
+static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
+ const int num_channels = 4;
+ const int in_width = io->mb_w;
+ const int out_width = io->scaled_width;
+ const int in_height = io->mb_h;
+ const int out_height = io->scaled_height;
+ const uint64_t work_size = 2 * num_channels * (uint64_t)out_width;
+ rescaler_t* work; // Rescaler work area.
+ const uint64_t scaled_data_size = (uint64_t)out_width;
+ uint32_t* scaled_data; // Temporary storage for scaled BGRA data.
+ const uint64_t memory_size = sizeof(*dec->rescaler) +
+ work_size * sizeof(*work) +
+ scaled_data_size * sizeof(*scaled_data);
+ uint8_t* memory = (uint8_t*)WebPSafeMalloc(memory_size, sizeof(*memory));
+ if (memory == NULL) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ return 0;
+ }
+ assert(dec->rescaler_memory == NULL);
+ dec->rescaler_memory = memory;
+
+ dec->rescaler = (WebPRescaler*)memory;
+ memory += sizeof(*dec->rescaler);
+ work = (rescaler_t*)memory;
+ memory += work_size * sizeof(*work);
+ scaled_data = (uint32_t*)memory;
+
+ WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
+ out_width, out_height, 0, num_channels, work);
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// Export to ARGB
+
+// We have special "export" function since we need to convert from BGRA
+static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
+ int rgba_stride, uint8_t* const rgba) {
+ uint32_t* const src = (uint32_t*)rescaler->dst;
+ const int dst_width = rescaler->dst_width;
+ int num_lines_out = 0;
+ while (WebPRescalerHasPendingOutput(rescaler)) {
+ uint8_t* const dst = rgba + num_lines_out * rgba_stride;
+ WebPRescalerExportRow(rescaler);
+ WebPMultARGBRow(src, dst_width, 1);
+ VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
+ ++num_lines_out;
+ }
+ return num_lines_out;
+}
+
+// Emit scaled rows.
+static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
+ uint8_t* in, int in_stride, int mb_h,
+ uint8_t* const out, int out_stride) {
+ const WEBP_CSP_MODE colorspace = dec->output_->colorspace;
+ int num_lines_in = 0;
+ int num_lines_out = 0;
+ while (num_lines_in < mb_h) {
+ uint8_t* const row_in = in + num_lines_in * in_stride;
+ uint8_t* const row_out = out + num_lines_out * out_stride;
+ const int lines_left = mb_h - num_lines_in;
+ const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
+ int lines_imported;
+ assert(needed_lines > 0 && needed_lines <= lines_left);
+ WebPMultARGBRows(row_in, in_stride,
+ dec->rescaler->src_width, needed_lines, 0);
+ lines_imported =
+ WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride);
+ assert(lines_imported == needed_lines);
+ num_lines_in += lines_imported;
+ num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out);
+ }
+ return num_lines_out;
+}
+
+// Emit rows without any scaling.
+static int EmitRows(WEBP_CSP_MODE colorspace,
+ const uint8_t* row_in, int in_stride,
+ int mb_w, int mb_h,
+ uint8_t* const out, int out_stride) {
+ int lines = mb_h;
+ uint8_t* row_out = out;
+ while (lines-- > 0) {
+ VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out);
+ row_in += in_stride;
+ row_out += out_stride;
+ }
+ return mb_h; // Num rows out == num rows in.
+}
+
+//------------------------------------------------------------------------------
+// Export to YUVA
+
+static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos,
+ const WebPDecBuffer* const output) {
+ const WebPYUVABuffer* const buf = &output->u.YUVA;
+
+ // first, the luma plane
+ WebPConvertARGBToY(src, buf->y + y_pos * buf->y_stride, width);
+
+ // then U/V planes
+ {
+ uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride;
+ uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride;
+ // even lines: store values
+ // odd lines: average with previous values
+ WebPConvertARGBToUV(src, u, v, width, !(y_pos & 1));
+ }
+ // Lastly, store alpha if needed.
+ if (buf->a != NULL) {
+ uint8_t* const a = buf->a + y_pos * buf->a_stride;
+#if defined(WORDS_BIGENDIAN)
+ WebPExtractAlpha((uint8_t*)src + 0, 0, width, 1, a, 0);
+#else
+ WebPExtractAlpha((uint8_t*)src + 3, 0, width, 1, a, 0);
+#endif
+ }
+}
+
+static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) {
+ WebPRescaler* const rescaler = dec->rescaler;
+ uint32_t* const src = (uint32_t*)rescaler->dst;
+ const int dst_width = rescaler->dst_width;
+ int num_lines_out = 0;
+ while (WebPRescalerHasPendingOutput(rescaler)) {
+ WebPRescalerExportRow(rescaler);
+ WebPMultARGBRow(src, dst_width, 1);
+ ConvertToYUVA(src, dst_width, y_pos, dec->output_);
+ ++y_pos;
+ ++num_lines_out;
+ }
+ return num_lines_out;
+}
+
+static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec,
+ uint8_t* in, int in_stride, int mb_h) {
+ int num_lines_in = 0;
+ int y_pos = dec->last_out_row_;
+ while (num_lines_in < mb_h) {
+ const int lines_left = mb_h - num_lines_in;
+ const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
+ int lines_imported;
+ WebPMultARGBRows(in, in_stride, dec->rescaler->src_width, needed_lines, 0);
+ lines_imported =
+ WebPRescalerImport(dec->rescaler, lines_left, in, in_stride);
+ assert(lines_imported == needed_lines);
+ num_lines_in += lines_imported;
+ in += needed_lines * in_stride;
+ y_pos += ExportYUVA(dec, y_pos);
+ }
+ return y_pos;
+}
+
+static int EmitRowsYUVA(const VP8LDecoder* const dec,
+ const uint8_t* in, int in_stride,
+ int mb_w, int num_rows) {
+ int y_pos = dec->last_out_row_;
+ while (num_rows-- > 0) {
+ ConvertToYUVA((const uint32_t*)in, mb_w, y_pos, dec->output_);
+ in += in_stride;
+ ++y_pos;
+ }
+ return y_pos;
+}
+
+//------------------------------------------------------------------------------
+// Cropping.
+
+// Sets io->mb_y, io->mb_h & io->mb_w according to start row, end row and
+// crop options. Also updates the input data pointer, so that it points to the
+// start of the cropped window. Note that pixels are in ARGB format even if
+// 'in_data' is uint8_t*.
+// Returns true if the crop window is not empty.
+static int SetCropWindow(VP8Io* const io, int y_start, int y_end,
+ uint8_t** const in_data, int pixel_stride) {
+ assert(y_start < y_end);
+ assert(io->crop_left < io->crop_right);
+ if (y_end > io->crop_bottom) {
+ y_end = io->crop_bottom; // make sure we don't overflow on last row.
+ }
+ if (y_start < io->crop_top) {
+ const int delta = io->crop_top - y_start;
+ y_start = io->crop_top;
+ *in_data += delta * pixel_stride;
+ }
+ if (y_start >= y_end) return 0; // Crop window is empty.
+
+ *in_data += io->crop_left * sizeof(uint32_t);
+
+ io->mb_y = y_start - io->crop_top;
+ io->mb_w = io->crop_right - io->crop_left;
+ io->mb_h = y_end - y_start;
+ return 1; // Non-empty crop window.
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int GetMetaIndex(
+ const uint32_t* const image, int xsize, int bits, int x, int y) {
+ if (bits == 0) return 0;
+ return image[xsize * (y >> bits) + (x >> bits)];
+}
+
+static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr,
+ int x, int y) {
+ const int meta_index = GetMetaIndex(hdr->huffman_image_, hdr->huffman_xsize_,
+ hdr->huffman_subsample_bits_, x, y);
+ assert(meta_index < hdr->num_htree_groups_);
+ return hdr->htree_groups_ + meta_index;
+}
+
+//------------------------------------------------------------------------------
+// Main loop, with custom row-processing function
+
+typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row);
+
+static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows,
+ const uint32_t* const rows) {
+ int n = dec->next_transform_;
+ const int cache_pixs = dec->width_ * num_rows;
+ const int start_row = dec->last_row_;
+ const int end_row = start_row + num_rows;
+ const uint32_t* rows_in = rows;
+ uint32_t* const rows_out = dec->argb_cache_;
+
+ // Inverse transforms.
+ while (n-- > 0) {
+ VP8LTransform* const transform = &dec->transforms_[n];
+ VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out);
+ rows_in = rows_out;
+ }
+ if (rows_in != rows_out) {
+ // No transform called, hence just copy.
+ memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
+ }
+}
+
+// Processes (transforms, scales & color-converts) the rows decoded after the
+// last call.
+static void ProcessRows(VP8LDecoder* const dec, int row) {
+ const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_;
+ const int num_rows = row - dec->last_row_;
+
+ assert(row <= dec->io_->crop_bottom);
+ // We can't process more than NUM_ARGB_CACHE_ROWS at a time (that's the size
+ // of argb_cache_), but we currently don't need more than that.
+ assert(num_rows <= NUM_ARGB_CACHE_ROWS);
+ if (num_rows > 0) { // Emit output.
+ VP8Io* const io = dec->io_;
+ uint8_t* rows_data = (uint8_t*)dec->argb_cache_;
+ const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA
+
+ ApplyInverseTransforms(dec, num_rows, rows);
+ if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) {
+ // Nothing to output (this time).
+ } else {
+ const WebPDecBuffer* const output = dec->output_;
+ if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
+ const WebPRGBABuffer* const buf = &output->u.RGBA;
+ uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
+ const int num_rows_out = io->use_scaling ?
+ EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
+ rgba, buf->stride) :
+ EmitRows(output->colorspace, rows_data, in_stride,
+ io->mb_w, io->mb_h, rgba, buf->stride);
+ // Update 'last_out_row_'.
+ dec->last_out_row_ += num_rows_out;
+ } else { // convert to YUVA
+ dec->last_out_row_ = io->use_scaling ?
+ EmitRescaledRowsYUVA(dec, rows_data, in_stride, io->mb_h) :
+ EmitRowsYUVA(dec, rows_data, in_stride, io->mb_w, io->mb_h);
+ }
+ assert(dec->last_out_row_ <= output->height);
+ }
+ }
+
+ // Update 'last_row_'.
+ dec->last_row_ = row;
+ assert(dec->last_row_ <= dec->height_);
+}
+
+// Row-processing for the special case when alpha data contains only one
+// transform (color indexing), and trivial non-green literals.
+static int Is8bOptimizable(const VP8LMetadata* const hdr) {
+ int i;
+ if (hdr->color_cache_size_ > 0) return 0;
+ // When the Huffman tree contains only one symbol, we can skip the
+ // call to ReadSymbol() for red/blue/alpha channels.
+ for (i = 0; i < hdr->num_htree_groups_; ++i) {
+ HuffmanCode** const htrees = hdr->htree_groups_[i].htrees;
+ if (htrees[RED][0].bits > 0) return 0;
+ if (htrees[BLUE][0].bits > 0) return 0;
+ if (htrees[ALPHA][0].bits > 0) return 0;
+ }
+ return 1;
+}
+
+static void AlphaApplyFilter(ALPHDecoder* const alph_dec,
+ int first_row, int last_row,
+ uint8_t* out, int stride) {
+ if (alph_dec->filter_ != WEBP_FILTER_NONE) {
+ int y;
+ const uint8_t* prev_line = alph_dec->prev_line_;
+ assert(WebPUnfilters[alph_dec->filter_] != NULL);
+ for (y = first_row; y < last_row; ++y) {
+ WebPUnfilters[alph_dec->filter_](prev_line, out, out, stride);
+ prev_line = out;
+ out += stride;
+ }
+ alph_dec->prev_line_ = prev_line;
+ }
+}
+
+static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int last_row) {
+ // For vertical and gradient filtering, we need to decode the part above the
+ // crop_top row, in order to have the correct spatial predictors.
+ ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io_->opaque;
+ const int top_row =
+ (alph_dec->filter_ == WEBP_FILTER_NONE ||
+ alph_dec->filter_ == WEBP_FILTER_HORIZONTAL) ? dec->io_->crop_top
+ : dec->last_row_;
+ const int first_row = (dec->last_row_ < top_row) ? top_row : dec->last_row_;
+ assert(last_row <= dec->io_->crop_bottom);
+ if (last_row > first_row) {
+ // Special method for paletted alpha data. We only process the cropped area.
+ const int width = dec->io_->width;
+ uint8_t* out = alph_dec->output_ + width * first_row;
+ const uint8_t* const in =
+ (uint8_t*)dec->pixels_ + dec->width_ * first_row;
+ VP8LTransform* const transform = &dec->transforms_[0];
+ assert(dec->next_transform_ == 1);
+ assert(transform->type_ == COLOR_INDEXING_TRANSFORM);
+ VP8LColorIndexInverseTransformAlpha(transform, first_row, last_row,
+ in, out);
+ AlphaApplyFilter(alph_dec, first_row, last_row, out, width);
+ }
+ dec->last_row_ = dec->last_out_row_ = last_row;
+}
+
+//------------------------------------------------------------------------------
+// Helper functions for fast pattern copy (8b and 32b)
+
+// cyclic rotation of pattern word
+static WEBP_INLINE uint32_t Rotate8b(uint32_t V) {
+#if defined(WORDS_BIGENDIAN)
+ return ((V & 0xff000000u) >> 24) | (V << 8);
+#else
+ return ((V & 0xffu) << 24) | (V >> 8);
+#endif
+}
+
+// copy 1, 2 or 4-bytes pattern
+static WEBP_INLINE void CopySmallPattern8b(const uint8_t* src, uint8_t* dst,
+ int length, uint32_t pattern) {
+ int i;
+ // align 'dst' to 4-bytes boundary. Adjust the pattern along the way.
+ while ((uintptr_t)dst & 3) {
+ *dst++ = *src++;
+ pattern = Rotate8b(pattern);
+ --length;
+ }
+ // Copy the pattern 4 bytes at a time.
+ for (i = 0; i < (length >> 2); ++i) {
+ ((uint32_t*)dst)[i] = pattern;
+ }
+ // Finish with left-overs. 'pattern' is still correctly positioned,
+ // so no Rotate8b() call is needed.
+ for (i <<= 2; i < length; ++i) {
+ dst[i] = src[i];
+ }
+}
+
+static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
+ const uint8_t* src = dst - dist;
+ if (length >= 8) {
+ uint32_t pattern = 0;
+ switch (dist) {
+ case 1:
+ pattern = src[0];
+#if defined(__arm__) || defined(_M_ARM) // arm doesn't like multiply that much
+ pattern |= pattern << 8;
+ pattern |= pattern << 16;
+#elif defined(WEBP_USE_MIPS_DSP_R2)
+ __asm__ volatile ("replv.qb %0, %0" : "+r"(pattern));
+#else
+ pattern = 0x01010101u * pattern;
+#endif
+ break;
+ case 2:
+ memcpy(&pattern, src, sizeof(uint16_t));
+#if defined(__arm__) || defined(_M_ARM)
+ pattern |= pattern << 16;
+#elif defined(WEBP_USE_MIPS_DSP_R2)
+ __asm__ volatile ("replv.ph %0, %0" : "+r"(pattern));
+#else
+ pattern = 0x00010001u * pattern;
+#endif
+ break;
+ case 4:
+ memcpy(&pattern, src, sizeof(uint32_t));
+ break;
+ default:
+ goto Copy;
+ break;
+ }
+ CopySmallPattern8b(src, dst, length, pattern);
+ return;
+ }
+ Copy:
+ if (dist >= length) { // no overlap -> use memcpy()
+ memcpy(dst, src, length * sizeof(*dst));
+ } else {
+ int i;
+ for (i = 0; i < length; ++i) dst[i] = src[i];
+ }
+}
+
+// copy pattern of 1 or 2 uint32_t's
+static WEBP_INLINE void CopySmallPattern32b(const uint32_t* src,
+ uint32_t* dst,
+ int length, uint64_t pattern) {
+ int i;
+ if ((uintptr_t)dst & 4) { // Align 'dst' to 8-bytes boundary.
+ *dst++ = *src++;
+ pattern = (pattern >> 32) | (pattern << 32);
+ --length;
+ }
+ assert(0 == ((uintptr_t)dst & 7));
+ for (i = 0; i < (length >> 1); ++i) {
+ ((uint64_t*)dst)[i] = pattern; // Copy the pattern 8 bytes at a time.
+ }
+ if (length & 1) { // Finish with left-over.
+ dst[i << 1] = src[i << 1];
+ }
+}
+
+static WEBP_INLINE void CopyBlock32b(uint32_t* const dst,
+ int dist, int length) {
+ const uint32_t* const src = dst - dist;
+ if (dist <= 2 && length >= 4 && ((uintptr_t)dst & 3) == 0) {
+ uint64_t pattern;
+ if (dist == 1) {
+ pattern = (uint64_t)src[0];
+ pattern |= pattern << 32;
+ } else {
+ memcpy(&pattern, src, sizeof(pattern));
+ }
+ CopySmallPattern32b(src, dst, length, pattern);
+ } else if (dist >= length) { // no overlap
+ memcpy(dst, src, length * sizeof(*dst));
+ } else {
+ int i;
+ for (i = 0; i < length; ++i) dst[i] = src[i];
+ }
+}
+
+//------------------------------------------------------------------------------
+
+static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
+ int width, int height, int last_row) {
+ int ok = 1;
+ int row = dec->last_pixel_ / width;
+ int col = dec->last_pixel_ % width;
+ VP8LBitReader* const br = &dec->br_;
+ VP8LMetadata* const hdr = &dec->hdr_;
+ int pos = dec->last_pixel_; // current position
+ const int end = width * height; // End of data
+ const int last = width * last_row; // Last pixel to decode
+ const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
+ const int mask = hdr->huffman_mask_;
+ const HTreeGroup* htree_group =
+ (pos < last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
+ assert(pos <= end);
+ assert(last_row <= height);
+ assert(Is8bOptimizable(hdr));
+
+ while (!br->eos_ && pos < last) {
+ int code;
+ // Only update when changing tile.
+ if ((col & mask) == 0) {
+ htree_group = GetHtreeGroupForPos(hdr, col, row);
+ }
+ assert(htree_group != NULL);
+ VP8LFillBitWindow(br);
+ code = ReadSymbol(htree_group->htrees[GREEN], br);
+ if (code < NUM_LITERAL_CODES) { // Literal
+ data[pos] = code;
+ ++pos;
+ ++col;
+ if (col >= width) {
+ col = 0;
+ ++row;
+ if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
+ ExtractPalettedAlphaRows(dec, row);
+ }
+ }
+ } else if (code < len_code_limit) { // Backward reference
+ int dist_code, dist;
+ const int length_sym = code - NUM_LITERAL_CODES;
+ const int length = GetCopyLength(length_sym, br);
+ const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
+ VP8LFillBitWindow(br);
+ dist_code = GetCopyDistance(dist_symbol, br);
+ dist = PlaneCodeToDistance(width, dist_code);
+ if (pos >= dist && end - pos >= length) {
+ CopyBlock8b(data + pos, dist, length);
+ } else {
+ ok = 0;
+ goto End;
+ }
+ pos += length;
+ col += length;
+ while (col >= width) {
+ col -= width;
+ ++row;
+ if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
+ ExtractPalettedAlphaRows(dec, row);
+ }
+ }
+ if (pos < last && (col & mask)) {
+ htree_group = GetHtreeGroupForPos(hdr, col, row);
+ }
+ } else { // Not reached
+ ok = 0;
+ goto End;
+ }
+ assert(br->eos_ == VP8LIsEndOfStream(br));
+ }
+ // Process the remaining rows corresponding to last row-block.
+ ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
+
+ End:
+ if (!ok || (br->eos_ && pos < end)) {
+ ok = 0;
+ dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
+ : VP8_STATUS_BITSTREAM_ERROR;
+ } else {
+ dec->last_pixel_ = pos;
+ }
+ return ok;
+}
+
+static void SaveState(VP8LDecoder* const dec, int last_pixel) {
+ assert(dec->incremental_);
+ dec->saved_br_ = dec->br_;
+ dec->saved_last_pixel_ = last_pixel;
+ if (dec->hdr_.color_cache_size_ > 0) {
+ VP8LColorCacheCopy(&dec->hdr_.color_cache_, &dec->hdr_.saved_color_cache_);
+ }
+}
+
+static void RestoreState(VP8LDecoder* const dec) {
+ assert(dec->br_.eos_);
+ dec->status_ = VP8_STATUS_SUSPENDED;
+ dec->br_ = dec->saved_br_;
+ dec->last_pixel_ = dec->saved_last_pixel_;
+ if (dec->hdr_.color_cache_size_ > 0) {
+ VP8LColorCacheCopy(&dec->hdr_.saved_color_cache_, &dec->hdr_.color_cache_);
+ }
+}
+
+#define SYNC_EVERY_N_ROWS 8 // minimum number of rows between check-points
+static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
+ int width, int height, int last_row,
+ ProcessRowsFunc process_func) {
+ int row = dec->last_pixel_ / width;
+ int col = dec->last_pixel_ % width;
+ VP8LBitReader* const br = &dec->br_;
+ VP8LMetadata* const hdr = &dec->hdr_;
+ uint32_t* src = data + dec->last_pixel_;
+ uint32_t* last_cached = src;
+ uint32_t* const src_end = data + width * height; // End of data
+ uint32_t* const src_last = data + width * last_row; // Last pixel to decode
+ const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
+ const int color_cache_limit = len_code_limit + hdr->color_cache_size_;
+ int next_sync_row = dec->incremental_ ? row : 1 << 24;
+ VP8LColorCache* const color_cache =
+ (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
+ const int mask = hdr->huffman_mask_;
+ const HTreeGroup* htree_group =
+ (src < src_last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
+ assert(dec->last_row_ < last_row);
+ assert(src_last <= src_end);
+
+ while (src < src_last) {
+ int code;
+ if (row >= next_sync_row) {
+ SaveState(dec, (int)(src - data));
+ next_sync_row = row + SYNC_EVERY_N_ROWS;
+ }
+ // Only update when changing tile. Note we could use this test:
+ // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed
+ // but that's actually slower and needs storing the previous col/row.
+ if ((col & mask) == 0) {
+ htree_group = GetHtreeGroupForPos(hdr, col, row);
+ }
+ assert(htree_group != NULL);
+ if (htree_group->is_trivial_code) {
+ *src = htree_group->literal_arb;
+ goto AdvanceByOne;
+ }
+ VP8LFillBitWindow(br);
+ if (htree_group->use_packed_table) {
+ code = ReadPackedSymbols(htree_group, br, src);
+ if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne;
+ } else {
+ code = ReadSymbol(htree_group->htrees[GREEN], br);
+ }
+ if (br->eos_) break; // early out
+ if (code < NUM_LITERAL_CODES) { // Literal
+ if (htree_group->is_trivial_literal) {
+ *src = htree_group->literal_arb | (code << 8);
+ } else {
+ int red, blue, alpha;
+ red = ReadSymbol(htree_group->htrees[RED], br);
+ VP8LFillBitWindow(br);
+ blue = ReadSymbol(htree_group->htrees[BLUE], br);
+ alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
+ if (br->eos_) break;
+ *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
+ }
+ AdvanceByOne:
+ ++src;
+ ++col;
+ if (col >= width) {
+ col = 0;
+ ++row;
+ if (process_func != NULL) {
+ if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
+ process_func(dec, row);
+ }
+ }
+ if (color_cache != NULL) {
+ while (last_cached < src) {
+ VP8LColorCacheInsert(color_cache, *last_cached++);
+ }
+ }
+ }
+ } else if (code < len_code_limit) { // Backward reference
+ int dist_code, dist;
+ const int length_sym = code - NUM_LITERAL_CODES;
+ const int length = GetCopyLength(length_sym, br);
+ const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
+ VP8LFillBitWindow(br);
+ dist_code = GetCopyDistance(dist_symbol, br);
+ dist = PlaneCodeToDistance(width, dist_code);
+ if (br->eos_) break;
+ if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
+ goto Error;
+ } else {
+ CopyBlock32b(src, dist, length);
+ }
+ src += length;
+ col += length;
+ while (col >= width) {
+ col -= width;
+ ++row;
+ if (process_func != NULL) {
+ if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
+ process_func(dec, row);
+ }
+ }
+ }
+ // Because of the check done above (before 'src' was incremented by
+ // 'length'), the following holds true.
+ assert(src <= src_end);
+ if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row);
+ if (color_cache != NULL) {
+ while (last_cached < src) {
+ VP8LColorCacheInsert(color_cache, *last_cached++);
+ }
+ }
+ } else if (code < color_cache_limit) { // Color cache
+ const int key = code - len_code_limit;
+ assert(color_cache != NULL);
+ while (last_cached < src) {
+ VP8LColorCacheInsert(color_cache, *last_cached++);
+ }
+ *src = VP8LColorCacheLookup(color_cache, key);
+ goto AdvanceByOne;
+ } else { // Not reached
+ goto Error;
+ }
+ assert(br->eos_ == VP8LIsEndOfStream(br));
+ }
+
+ if (dec->incremental_ && br->eos_ && src < src_end) {
+ RestoreState(dec);
+ } else if (!br->eos_) {
+ // Process the remaining rows corresponding to last row-block.
+ if (process_func != NULL) {
+ process_func(dec, row > last_row ? last_row : row);
+ }
+ dec->status_ = VP8_STATUS_OK;
+ dec->last_pixel_ = (int)(src - data); // end-of-scan marker
+ } else {
+ // if not incremental, and we are past the end of buffer (eos_=1), then this
+ // is a real bitstream error.
+ goto Error;
+ }
+ return 1;
+
+ Error:
+ dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LTransform
+
+static void ClearTransform(VP8LTransform* const transform) {
+ WebPSafeFree(transform->data_);
+ transform->data_ = NULL;
+}
+
+// For security reason, we need to remap the color map to span
+// the total possible bundled values, and not just the num_colors.
+static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
+ int i;
+ const int final_num_colors = 1 << (8 >> transform->bits_);
+ uint32_t* const new_color_map =
+ (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors,
+ sizeof(*new_color_map));
+ if (new_color_map == NULL) {
+ return 0;
+ } else {
+ uint8_t* const data = (uint8_t*)transform->data_;
+ uint8_t* const new_data = (uint8_t*)new_color_map;
+ new_color_map[0] = transform->data_[0];
+ for (i = 4; i < 4 * num_colors; ++i) {
+ // Equivalent to AddPixelEq(), on a byte-basis.
+ new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
+ }
+ for (; i < 4 * final_num_colors; ++i) {
+ new_data[i] = 0; // black tail.
+ }
+ WebPSafeFree(transform->data_);
+ transform->data_ = new_color_map;
+ }
+ return 1;
+}
+
+static int ReadTransform(int* const xsize, int const* ysize,
+ VP8LDecoder* const dec) {
+ int ok = 1;
+ VP8LBitReader* const br = &dec->br_;
+ VP8LTransform* transform = &dec->transforms_[dec->next_transform_];
+ const VP8LImageTransformType type =
+ (VP8LImageTransformType)VP8LReadBits(br, 2);
+
+ // Each transform type can only be present once in the stream.
+ if (dec->transforms_seen_ & (1U << type)) {
+ return 0; // Already there, let's not accept the second same transform.
+ }
+ dec->transforms_seen_ |= (1U << type);
+
+ transform->type_ = type;
+ transform->xsize_ = *xsize;
+ transform->ysize_ = *ysize;
+ transform->data_ = NULL;
+ ++dec->next_transform_;
+ assert(dec->next_transform_ <= NUM_TRANSFORMS);
+
+ switch (type) {
+ case PREDICTOR_TRANSFORM:
+ case CROSS_COLOR_TRANSFORM:
+ transform->bits_ = VP8LReadBits(br, 3) + 2;
+ ok = DecodeImageStream(VP8LSubSampleSize(transform->xsize_,
+ transform->bits_),
+ VP8LSubSampleSize(transform->ysize_,
+ transform->bits_),
+ 0, dec, &transform->data_);
+ break;
+ case COLOR_INDEXING_TRANSFORM: {
+ const int num_colors = VP8LReadBits(br, 8) + 1;
+ const int bits = (num_colors > 16) ? 0
+ : (num_colors > 4) ? 1
+ : (num_colors > 2) ? 2
+ : 3;
+ *xsize = VP8LSubSampleSize(transform->xsize_, bits);
+ transform->bits_ = bits;
+ ok = DecodeImageStream(num_colors, 1, 0, dec, &transform->data_);
+ ok = ok && ExpandColorMap(num_colors, transform);
+ break;
+ }
+ case SUBTRACT_GREEN:
+ break;
+ default:
+ assert(0); // can't happen
+ break;
+ }
+
+ return ok;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LMetadata
+
+static void InitMetadata(VP8LMetadata* const hdr) {
+ assert(hdr != NULL);
+ memset(hdr, 0, sizeof(*hdr));
+}
+
+static void ClearMetadata(VP8LMetadata* const hdr) {
+ assert(hdr != NULL);
+
+ WebPSafeFree(hdr->huffman_image_);
+ WebPSafeFree(hdr->huffman_tables_);
+ VP8LHtreeGroupsFree(hdr->htree_groups_);
+ VP8LColorCacheClear(&hdr->color_cache_);
+ VP8LColorCacheClear(&hdr->saved_color_cache_);
+ InitMetadata(hdr);
+}
+
+// -----------------------------------------------------------------------------
+// VP8LDecoder
+
+VP8LDecoder* VP8LNew(void) {
+ VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
+ if (dec == NULL) return NULL;
+ dec->status_ = VP8_STATUS_OK;
+ dec->state_ = READ_DIM;
+
+ VP8LDspInit(); // Init critical function pointers.
+
+ return dec;
+}
+
+void VP8LClear(VP8LDecoder* const dec) {
+ int i;
+ if (dec == NULL) return;
+ ClearMetadata(&dec->hdr_);
+
+ WebPSafeFree(dec->pixels_);
+ dec->pixels_ = NULL;
+ for (i = 0; i < dec->next_transform_; ++i) {
+ ClearTransform(&dec->transforms_[i]);
+ }
+ dec->next_transform_ = 0;
+ dec->transforms_seen_ = 0;
+
+ WebPSafeFree(dec->rescaler_memory);
+ dec->rescaler_memory = NULL;
+
+ dec->output_ = NULL; // leave no trace behind
+}
+
+void VP8LDelete(VP8LDecoder* const dec) {
+ if (dec != NULL) {
+ VP8LClear(dec);
+ WebPSafeFree(dec);
+ }
+}
+
+static void UpdateDecoder(VP8LDecoder* const dec, int width, int height) {
+ VP8LMetadata* const hdr = &dec->hdr_;
+ const int num_bits = hdr->huffman_subsample_bits_;
+ dec->width_ = width;
+ dec->height_ = height;
+
+ hdr->huffman_xsize_ = VP8LSubSampleSize(width, num_bits);
+ hdr->huffman_mask_ = (num_bits == 0) ? ~0 : (1 << num_bits) - 1;
+}
+
+static int DecodeImageStream(int xsize, int ysize,
+ int is_level0,
+ VP8LDecoder* const dec,
+ uint32_t** const decoded_data) {
+ int ok = 1;
+ int transform_xsize = xsize;
+ int transform_ysize = ysize;
+ VP8LBitReader* const br = &dec->br_;
+ VP8LMetadata* const hdr = &dec->hdr_;
+ uint32_t* data = NULL;
+ int color_cache_bits = 0;
+
+ // Read the transforms (may recurse).
+ if (is_level0) {
+ while (ok && VP8LReadBits(br, 1)) {
+ ok = ReadTransform(&transform_xsize, &transform_ysize, dec);
+ }
+ }
+
+ // Color cache
+ if (ok && VP8LReadBits(br, 1)) {
+ color_cache_bits = VP8LReadBits(br, 4);
+ ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS);
+ if (!ok) {
+ dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ goto End;
+ }
+ }
+
+ // Read the Huffman codes (may recurse).
+ ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize,
+ color_cache_bits, is_level0);
+ if (!ok) {
+ dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ goto End;
+ }
+
+ // Finish setting up the color-cache
+ if (color_cache_bits > 0) {
+ hdr->color_cache_size_ = 1 << color_cache_bits;
+ if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ ok = 0;
+ goto End;
+ }
+ } else {
+ hdr->color_cache_size_ = 0;
+ }
+ UpdateDecoder(dec, transform_xsize, transform_ysize);
+
+ if (is_level0) { // level 0 complete
+ dec->state_ = READ_HDR;
+ goto End;
+ }
+
+ {
+ const uint64_t total_size = (uint64_t)transform_xsize * transform_ysize;
+ data = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*data));
+ if (data == NULL) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ ok = 0;
+ goto End;
+ }
+ }
+
+ // Use the Huffman trees to decode the LZ77 encoded data.
+ ok = DecodeImageData(dec, data, transform_xsize, transform_ysize,
+ transform_ysize, NULL);
+ ok = ok && !br->eos_;
+
+ End:
+ if (!ok) {
+ WebPSafeFree(data);
+ ClearMetadata(hdr);
+ } else {
+ if (decoded_data != NULL) {
+ *decoded_data = data;
+ } else {
+ // We allocate image data in this function only for transforms. At level 0
+ // (that is: not the transforms), we shouldn't have allocated anything.
+ assert(data == NULL);
+ assert(is_level0);
+ }
+ dec->last_pixel_ = 0; // Reset for future DECODE_DATA_FUNC() calls.
+ if (!is_level0) ClearMetadata(hdr); // Clean up temporary data behind.
+ }
+ return ok;
+}
+
+//------------------------------------------------------------------------------
+// Allocate internal buffers dec->pixels_ and dec->argb_cache_.
+static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
+ const uint64_t num_pixels = (uint64_t)dec->width_ * dec->height_;
+ // Scratch buffer corresponding to top-prediction row for transforming the
+ // first row in the row-blocks. Not needed for paletted alpha.
+ const uint64_t cache_top_pixels = (uint16_t)final_width;
+ // Scratch buffer for temporary BGRA storage. Not needed for paletted alpha.
+ const uint64_t cache_pixels = (uint64_t)final_width * NUM_ARGB_CACHE_ROWS;
+ const uint64_t total_num_pixels =
+ num_pixels + cache_top_pixels + cache_pixels;
+
+ assert(dec->width_ <= final_width);
+ dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
+ if (dec->pixels_ == NULL) {
+ dec->argb_cache_ = NULL; // for sanity check
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ return 0;
+ }
+ dec->argb_cache_ = dec->pixels_ + num_pixels + cache_top_pixels;
+ return 1;
+}
+
+static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
+ const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_;
+ dec->argb_cache_ = NULL; // for sanity check
+ dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
+ if (dec->pixels_ == NULL) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ return 0;
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+
+// Special row-processing that only stores the alpha data.
+static void ExtractAlphaRows(VP8LDecoder* const dec, int last_row) {
+ int cur_row = dec->last_row_;
+ int num_rows = last_row - cur_row;
+ const uint32_t* in = dec->pixels_ + dec->width_ * cur_row;
+
+ assert(last_row <= dec->io_->crop_bottom);
+ while (num_rows > 0) {
+ const int num_rows_to_process =
+ (num_rows > NUM_ARGB_CACHE_ROWS) ? NUM_ARGB_CACHE_ROWS : num_rows;
+ // Extract alpha (which is stored in the green plane).
+ ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io_->opaque;
+ uint8_t* const output = alph_dec->output_;
+ const int width = dec->io_->width; // the final width (!= dec->width_)
+ const int cache_pixs = width * num_rows_to_process;
+ uint8_t* const dst = output + width * cur_row;
+ const uint32_t* const src = dec->argb_cache_;
+ ApplyInverseTransforms(dec, num_rows_to_process, in);
+ WebPExtractGreen(src, dst, cache_pixs);
+ AlphaApplyFilter(alph_dec,
+ cur_row, cur_row + num_rows_to_process, dst, width);
+ num_rows -= num_rows_to_process;
+ in += num_rows_to_process * dec->width_;
+ cur_row += num_rows_to_process;
+ }
+ assert(cur_row == last_row);
+ dec->last_row_ = dec->last_out_row_ = last_row;
+}
+
+int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
+ const uint8_t* const data, size_t data_size) {
+ int ok = 0;
+ VP8LDecoder* dec = VP8LNew();
+
+ if (dec == NULL) return 0;
+
+ assert(alph_dec != NULL);
+ alph_dec->vp8l_dec_ = dec;
+
+ dec->width_ = alph_dec->width_;
+ dec->height_ = alph_dec->height_;
+ dec->io_ = &alph_dec->io_;
+ dec->io_->opaque = alph_dec;
+ dec->io_->width = alph_dec->width_;
+ dec->io_->height = alph_dec->height_;
+
+ dec->status_ = VP8_STATUS_OK;
+ VP8LInitBitReader(&dec->br_, data, data_size);
+
+ if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) {
+ goto Err;
+ }
+
+ // Special case: if alpha data uses only the color indexing transform and
+ // doesn't use color cache (a frequent case), we will use DecodeAlphaData()
+ // method that only needs allocation of 1 byte per pixel (alpha channel).
+ if (dec->next_transform_ == 1 &&
+ dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM &&
+ Is8bOptimizable(&dec->hdr_)) {
+ alph_dec->use_8b_decode_ = 1;
+ ok = AllocateInternalBuffers8b(dec);
+ } else {
+ // Allocate internal buffers (note that dec->width_ may have changed here).
+ alph_dec->use_8b_decode_ = 0;
+ ok = AllocateInternalBuffers32b(dec, alph_dec->width_);
+ }
+
+ if (!ok) goto Err;
+
+ return 1;
+
+ Err:
+ VP8LDelete(alph_dec->vp8l_dec_);
+ alph_dec->vp8l_dec_ = NULL;
+ return 0;
+}
+
+int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) {
+ VP8LDecoder* const dec = alph_dec->vp8l_dec_;
+ assert(dec != NULL);
+ assert(last_row <= dec->height_);
+
+ if (dec->last_row_ >= last_row) {
+ return 1; // done
+ }
+
+ if (!alph_dec->use_8b_decode_) WebPInitAlphaProcessing();
+
+ // Decode (with special row processing).
+ return alph_dec->use_8b_decode_ ?
+ DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_,
+ last_row) :
+ DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
+ last_row, ExtractAlphaRows);
+}
+
+//------------------------------------------------------------------------------
+
+int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
+ int width, height, has_alpha;
+
+ if (dec == NULL) return 0;
+ if (io == NULL) {
+ dec->status_ = VP8_STATUS_INVALID_PARAM;
+ return 0;
+ }
+
+ dec->io_ = io;
+ dec->status_ = VP8_STATUS_OK;
+ VP8LInitBitReader(&dec->br_, io->data, io->data_size);
+ if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) {
+ dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ goto Error;
+ }
+ dec->state_ = READ_DIM;
+ io->width = width;
+ io->height = height;
+
+ if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error;
+ return 1;
+
+ Error:
+ VP8LClear(dec);
+ assert(dec->status_ != VP8_STATUS_OK);
+ return 0;
+}
+
+int VP8LDecodeImage(VP8LDecoder* const dec) {
+ VP8Io* io = NULL;
+ WebPDecParams* params = NULL;
+
+ // Sanity checks.
+ if (dec == NULL) return 0;
+
+ assert(dec->hdr_.huffman_tables_ != NULL);
+ assert(dec->hdr_.htree_groups_ != NULL);
+ assert(dec->hdr_.num_htree_groups_ > 0);
+
+ io = dec->io_;
+ assert(io != NULL);
+ params = (WebPDecParams*)io->opaque;
+ assert(params != NULL);
+
+ // Initialization.
+ if (dec->state_ != READ_DATA) {
+ dec->output_ = params->output;
+ assert(dec->output_ != NULL);
+
+ if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) {
+ dec->status_ = VP8_STATUS_INVALID_PARAM;
+ goto Err;
+ }
+
+ if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
+
+ if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
+
+ if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) {
+ // need the alpha-multiply functions for premultiplied output or rescaling
+ WebPInitAlphaProcessing();
+ }
+ if (!WebPIsRGBMode(dec->output_->colorspace)) {
+ WebPInitConvertARGBToYUV();
+ if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing();
+ }
+ if (dec->incremental_) {
+ if (dec->hdr_.color_cache_size_ > 0 &&
+ dec->hdr_.saved_color_cache_.colors_ == NULL) {
+ if (!VP8LColorCacheInit(&dec->hdr_.saved_color_cache_,
+ dec->hdr_.color_cache_.hash_bits_)) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ goto Err;
+ }
+ }
+ }
+ dec->state_ = READ_DATA;
+ }
+
+ // Decode.
+ if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
+ io->crop_bottom, ProcessRows)) {
+ goto Err;
+ }
+
+ params->last_y = dec->last_out_row_;
+ return 1;
+
+ Err:
+ VP8LClear(dec);
+ assert(dec->status_ != VP8_STATUS_OK);
+ return 0;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dec/vp8li_dec.h b/media/libwebp/dec/vp8li_dec.h
new file mode 100644
index 000000000..097a9d058
--- /dev/null
+++ b/media/libwebp/dec/vp8li_dec.h
@@ -0,0 +1,135 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Lossless decoder: internal header.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+// Vikas Arora(vikaas.arora@gmail.com)
+
+#ifndef WEBP_DEC_VP8LI_H_
+#define WEBP_DEC_VP8LI_H_
+
+#include <string.h> // for memcpy()
+#include "./webpi_dec.h"
+#include "../utils/bit_reader_utils.h"
+#include "../utils/color_cache_utils.h"
+#include "../utils/huffman_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ READ_DATA = 0,
+ READ_HDR = 1,
+ READ_DIM = 2
+} VP8LDecodeState;
+
+typedef struct VP8LTransform VP8LTransform;
+struct VP8LTransform {
+ VP8LImageTransformType type_; // transform type.
+ int bits_; // subsampling bits defining transform window.
+ int xsize_; // transform window X index.
+ int ysize_; // transform window Y index.
+ uint32_t *data_; // transform data.
+};
+
+typedef struct {
+ int color_cache_size_;
+ VP8LColorCache color_cache_;
+ VP8LColorCache saved_color_cache_; // for incremental
+
+ int huffman_mask_;
+ int huffman_subsample_bits_;
+ int huffman_xsize_;
+ uint32_t *huffman_image_;
+ int num_htree_groups_;
+ HTreeGroup *htree_groups_;
+ HuffmanCode *huffman_tables_;
+} VP8LMetadata;
+
+typedef struct VP8LDecoder VP8LDecoder;
+struct VP8LDecoder {
+ VP8StatusCode status_;
+ VP8LDecodeState state_;
+ VP8Io *io_;
+
+ const WebPDecBuffer *output_; // shortcut to io->opaque->output
+
+ uint32_t *pixels_; // Internal data: either uint8_t* for alpha
+ // or uint32_t* for BGRA.
+ uint32_t *argb_cache_; // Scratch buffer for temporary BGRA storage.
+
+ VP8LBitReader br_;
+ int incremental_; // if true, incremental decoding is expected
+ VP8LBitReader saved_br_; // note: could be local variables too
+ int saved_last_pixel_;
+
+ int width_;
+ int height_;
+ int last_row_; // last input row decoded so far.
+ int last_pixel_; // last pixel decoded so far. However, it may
+ // not be transformed, scaled and
+ // color-converted yet.
+ int last_out_row_; // last row output so far.
+
+ VP8LMetadata hdr_;
+
+ int next_transform_;
+ VP8LTransform transforms_[NUM_TRANSFORMS];
+ // or'd bitset storing the transforms types.
+ uint32_t transforms_seen_;
+
+ uint8_t *rescaler_memory; // Working memory for rescaling work.
+ WebPRescaler *rescaler; // Common rescaler for all channels.
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+struct ALPHDecoder; // Defined in dec/alphai.h.
+
+// in vp8l.c
+
+// Decodes image header for alpha data stored using lossless compression.
+// Returns false in case of error.
+int VP8LDecodeAlphaHeader(struct ALPHDecoder* const alph_dec,
+ const uint8_t* const data, size_t data_size);
+
+// Decodes *at least* 'last_row' rows of alpha. If some of the initial rows are
+// already decoded in previous call(s), it will resume decoding from where it
+// was paused.
+// Returns false in case of bitstream error.
+int VP8LDecodeAlphaImageStream(struct ALPHDecoder* const alph_dec,
+ int last_row);
+
+// Allocates and initialize a new lossless decoder instance.
+VP8LDecoder* VP8LNew(void);
+
+// Decodes the image header. Returns false in case of error.
+int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io);
+
+// Decodes an image. It's required to decode the lossless header before calling
+// this function. Returns false in case of error, with updated dec->status_.
+int VP8LDecodeImage(VP8LDecoder* const dec);
+
+// Resets the decoder in its initial state, reclaiming memory.
+// Preserves the dec->status_ value.
+void VP8LClear(VP8LDecoder* const dec);
+
+// Clears and deallocate a lossless decoder instance.
+void VP8LDelete(VP8LDecoder* const dec);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_DEC_VP8LI_H_ */
diff --git a/media/libwebp/dec/webp_dec.c b/media/libwebp/dec/webp_dec.c
new file mode 100644
index 000000000..a8e9c2c51
--- /dev/null
+++ b/media/libwebp/dec/webp_dec.c
@@ -0,0 +1,843 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Main decoding functions for WEBP images.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <stdlib.h>
+
+#include "./vp8i_dec.h"
+#include "./vp8li_dec.h"
+#include "./webpi_dec.h"
+#include "../utils/utils.h"
+#include "../webp/mux_types.h" // ALPHA_FLAG
+
+//------------------------------------------------------------------------------
+// RIFF layout is:
+// Offset tag
+// 0...3 "RIFF" 4-byte tag
+// 4...7 size of image data (including metadata) starting at offset 8
+// 8...11 "WEBP" our form-type signature
+// The RIFF container (12 bytes) is followed by appropriate chunks:
+// 12..15 "VP8 ": 4-bytes tags, signaling the use of VP8 video format
+// 16..19 size of the raw VP8 image data, starting at offset 20
+// 20.... the VP8 bytes
+// Or,
+// 12..15 "VP8L": 4-bytes tags, signaling the use of VP8L lossless format
+// 16..19 size of the raw VP8L image data, starting at offset 20
+// 20.... the VP8L bytes
+// Or,
+// 12..15 "VP8X": 4-bytes tags, describing the extended-VP8 chunk.
+// 16..19 size of the VP8X chunk starting at offset 20.
+// 20..23 VP8X flags bit-map corresponding to the chunk-types present.
+// 24..26 Width of the Canvas Image.
+// 27..29 Height of the Canvas Image.
+// There can be extra chunks after the "VP8X" chunk (ICCP, ANMF, VP8, VP8L,
+// XMP, EXIF ...)
+// All sizes are in little-endian order.
+// Note: chunk data size must be padded to multiple of 2 when written.
+
+// Validates the RIFF container (if detected) and skips over it.
+// If a RIFF container is detected, returns:
+// VP8_STATUS_BITSTREAM_ERROR for invalid header,
+// VP8_STATUS_NOT_ENOUGH_DATA for truncated data if have_all_data is true,
+// and VP8_STATUS_OK otherwise.
+// In case there are not enough bytes (partial RIFF container), return 0 for
+// *riff_size. Else return the RIFF size extracted from the header.
+static VP8StatusCode ParseRIFF(const uint8_t** const data,
+ size_t* const data_size, int have_all_data,
+ size_t* const riff_size) {
+ assert(data != NULL);
+ assert(data_size != NULL);
+ assert(riff_size != NULL);
+
+ *riff_size = 0; // Default: no RIFF present.
+ if (*data_size >= RIFF_HEADER_SIZE && !memcmp(*data, "RIFF", TAG_SIZE)) {
+ if (memcmp(*data + 8, "WEBP", TAG_SIZE)) {
+ return VP8_STATUS_BITSTREAM_ERROR; // Wrong image file signature.
+ } else {
+ const uint32_t size = GetLE32(*data + TAG_SIZE);
+ // Check that we have at least one chunk (i.e "WEBP" + "VP8?nnnn").
+ if (size < TAG_SIZE + CHUNK_HEADER_SIZE) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ if (size > MAX_CHUNK_PAYLOAD) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ if (have_all_data && (size > *data_size - CHUNK_HEADER_SIZE)) {
+ return VP8_STATUS_NOT_ENOUGH_DATA; // Truncated bitstream.
+ }
+ // We have a RIFF container. Skip it.
+ *riff_size = size;
+ *data += RIFF_HEADER_SIZE;
+ *data_size -= RIFF_HEADER_SIZE;
+ }
+ }
+ return VP8_STATUS_OK;
+}
+
+// Validates the VP8X header and skips over it.
+// Returns VP8_STATUS_BITSTREAM_ERROR for invalid VP8X header,
+// VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
+// VP8_STATUS_OK otherwise.
+// If a VP8X chunk is found, found_vp8x is set to true and *width_ptr,
+// *height_ptr and *flags_ptr are set to the corresponding values extracted
+// from the VP8X chunk.
+static VP8StatusCode ParseVP8X(const uint8_t** const data,
+ size_t* const data_size,
+ int* const found_vp8x,
+ int* const width_ptr, int* const height_ptr,
+ uint32_t* const flags_ptr) {
+ const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
+ assert(data != NULL);
+ assert(data_size != NULL);
+ assert(found_vp8x != NULL);
+
+ *found_vp8x = 0;
+
+ if (*data_size < CHUNK_HEADER_SIZE) {
+ return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data.
+ }
+
+ if (!memcmp(*data, "VP8X", TAG_SIZE)) {
+ int width, height;
+ uint32_t flags;
+ const uint32_t chunk_size = GetLE32(*data + TAG_SIZE);
+ if (chunk_size != VP8X_CHUNK_SIZE) {
+ return VP8_STATUS_BITSTREAM_ERROR; // Wrong chunk size.
+ }
+
+ // Verify if enough data is available to validate the VP8X chunk.
+ if (*data_size < vp8x_size) {
+ return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data.
+ }
+ flags = GetLE32(*data + 8);
+ width = 1 + GetLE24(*data + 12);
+ height = 1 + GetLE24(*data + 15);
+ if (width * (uint64_t)height >= MAX_IMAGE_AREA) {
+ return VP8_STATUS_BITSTREAM_ERROR; // image is too large
+ }
+
+ if (flags_ptr != NULL) *flags_ptr = flags;
+ if (width_ptr != NULL) *width_ptr = width;
+ if (height_ptr != NULL) *height_ptr = height;
+ // Skip over VP8X header bytes.
+ *data += vp8x_size;
+ *data_size -= vp8x_size;
+ *found_vp8x = 1;
+ }
+ return VP8_STATUS_OK;
+}
+
+// Skips to the next VP8/VP8L chunk header in the data given the size of the
+// RIFF chunk 'riff_size'.
+// Returns VP8_STATUS_BITSTREAM_ERROR if any invalid chunk size is encountered,
+// VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
+// VP8_STATUS_OK otherwise.
+// If an alpha chunk is found, *alpha_data and *alpha_size are set
+// appropriately.
+static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
+ size_t* const data_size,
+ size_t const riff_size,
+ const uint8_t** const alpha_data,
+ size_t* const alpha_size) {
+ const uint8_t* buf;
+ size_t buf_size;
+ uint32_t total_size = TAG_SIZE + // "WEBP".
+ CHUNK_HEADER_SIZE + // "VP8Xnnnn".
+ VP8X_CHUNK_SIZE; // data.
+ assert(data != NULL);
+ assert(data_size != NULL);
+ buf = *data;
+ buf_size = *data_size;
+
+ assert(alpha_data != NULL);
+ assert(alpha_size != NULL);
+ *alpha_data = NULL;
+ *alpha_size = 0;
+
+ while (1) {
+ uint32_t chunk_size;
+ uint32_t disk_chunk_size; // chunk_size with padding
+
+ *data = buf;
+ *data_size = buf_size;
+
+ if (buf_size < CHUNK_HEADER_SIZE) { // Insufficient data.
+ return VP8_STATUS_NOT_ENOUGH_DATA;
+ }
+
+ chunk_size = GetLE32(buf + TAG_SIZE);
+ if (chunk_size > MAX_CHUNK_PAYLOAD) {
+ return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
+ }
+ // For odd-sized chunk-payload, there's one byte padding at the end.
+ disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
+ total_size += disk_chunk_size;
+
+ // Check that total bytes skipped so far does not exceed riff_size.
+ if (riff_size > 0 && (total_size > riff_size)) {
+ return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
+ }
+
+ // Start of a (possibly incomplete) VP8/VP8L chunk implies that we have
+ // parsed all the optional chunks.
+ // Note: This check must occur before the check 'buf_size < disk_chunk_size'
+ // below to allow incomplete VP8/VP8L chunks.
+ if (!memcmp(buf, "VP8 ", TAG_SIZE) ||
+ !memcmp(buf, "VP8L", TAG_SIZE)) {
+ return VP8_STATUS_OK;
+ }
+
+ if (buf_size < disk_chunk_size) { // Insufficient data.
+ return VP8_STATUS_NOT_ENOUGH_DATA;
+ }
+
+ if (!memcmp(buf, "ALPH", TAG_SIZE)) { // A valid ALPH header.
+ *alpha_data = buf + CHUNK_HEADER_SIZE;
+ *alpha_size = chunk_size;
+ }
+
+ // We have a full and valid chunk; skip it.
+ buf += disk_chunk_size;
+ buf_size -= disk_chunk_size;
+ }
+}
+
+// Validates the VP8/VP8L Header ("VP8 nnnn" or "VP8L nnnn") and skips over it.
+// Returns VP8_STATUS_BITSTREAM_ERROR for invalid (chunk larger than
+// riff_size) VP8/VP8L header,
+// VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
+// VP8_STATUS_OK otherwise.
+// If a VP8/VP8L chunk is found, *chunk_size is set to the total number of bytes
+// extracted from the VP8/VP8L chunk header.
+// The flag '*is_lossless' is set to 1 in case of VP8L chunk / raw VP8L data.
+static VP8StatusCode ParseVP8Header(const uint8_t** const data_ptr,
+ size_t* const data_size, int have_all_data,
+ size_t riff_size, size_t* const chunk_size,
+ int* const is_lossless) {
+ const uint8_t* const data = *data_ptr;
+ const int is_vp8 = !memcmp(data, "VP8 ", TAG_SIZE);
+ const int is_vp8l = !memcmp(data, "VP8L", TAG_SIZE);
+ const uint32_t minimal_size =
+ TAG_SIZE + CHUNK_HEADER_SIZE; // "WEBP" + "VP8 nnnn" OR
+ // "WEBP" + "VP8Lnnnn"
+ assert(data != NULL);
+ assert(data_size != NULL);
+ assert(chunk_size != NULL);
+ assert(is_lossless != NULL);
+
+ if (*data_size < CHUNK_HEADER_SIZE) {
+ return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data.
+ }
+
+ if (is_vp8 || is_vp8l) {
+ // Bitstream contains VP8/VP8L header.
+ const uint32_t size = GetLE32(data + TAG_SIZE);
+ if ((riff_size >= minimal_size) && (size > riff_size - minimal_size)) {
+ return VP8_STATUS_BITSTREAM_ERROR; // Inconsistent size information.
+ }
+ if (have_all_data && (size > *data_size - CHUNK_HEADER_SIZE)) {
+ return VP8_STATUS_NOT_ENOUGH_DATA; // Truncated bitstream.
+ }
+ // Skip over CHUNK_HEADER_SIZE bytes from VP8/VP8L Header.
+ *chunk_size = size;
+ *data_ptr += CHUNK_HEADER_SIZE;
+ *data_size -= CHUNK_HEADER_SIZE;
+ *is_lossless = is_vp8l;
+ } else {
+ // Raw VP8/VP8L bitstream (no header).
+ *is_lossless = VP8LCheckSignature(data, *data_size);
+ *chunk_size = *data_size;
+ }
+
+ return VP8_STATUS_OK;
+}
+
+//------------------------------------------------------------------------------
+
+// Fetch '*width', '*height', '*has_alpha' and fill out 'headers' based on
+// 'data'. All the output parameters may be NULL. If 'headers' is NULL only the
+// minimal amount will be read to fetch the remaining parameters.
+// If 'headers' is non-NULL this function will attempt to locate both alpha
+// data (with or without a VP8X chunk) and the bitstream chunk (VP8/VP8L).
+// Note: The following chunk sequences (before the raw VP8/VP8L data) are
+// considered valid by this function:
+// RIFF + VP8(L)
+// RIFF + VP8X + (optional chunks) + VP8(L)
+// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
+// VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
+static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
+ size_t data_size,
+ int* const width,
+ int* const height,
+ int* const has_alpha,
+ int* const has_animation,
+ int* const format,
+ WebPHeaderStructure* const headers) {
+ int canvas_width = 0;
+ int canvas_height = 0;
+ int image_width = 0;
+ int image_height = 0;
+ int found_riff = 0;
+ int found_vp8x = 0;
+ int animation_present = 0;
+ const int have_all_data = (headers != NULL) ? headers->have_all_data : 0;
+
+ VP8StatusCode status;
+ WebPHeaderStructure hdrs;
+
+ if (data == NULL || data_size < RIFF_HEADER_SIZE) {
+ return VP8_STATUS_NOT_ENOUGH_DATA;
+ }
+ memset(&hdrs, 0, sizeof(hdrs));
+ hdrs.data = data;
+ hdrs.data_size = data_size;
+
+ // Skip over RIFF header.
+ status = ParseRIFF(&data, &data_size, have_all_data, &hdrs.riff_size);
+ if (status != VP8_STATUS_OK) {
+ return status; // Wrong RIFF header / insufficient data.
+ }
+ found_riff = (hdrs.riff_size > 0);
+
+ // Skip over VP8X.
+ {
+ uint32_t flags = 0;
+ status = ParseVP8X(&data, &data_size, &found_vp8x,
+ &canvas_width, &canvas_height, &flags);
+ if (status != VP8_STATUS_OK) {
+ return status; // Wrong VP8X / insufficient data.
+ }
+ animation_present = !!(flags & ANIMATION_FLAG);
+ if (!found_riff && found_vp8x) {
+ // Note: This restriction may be removed in the future, if it becomes
+ // necessary to send VP8X chunk to the decoder.
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG);
+ if (has_animation != NULL) *has_animation = animation_present;
+ if (format != NULL) *format = 0; // default = undefined
+
+ image_width = canvas_width;
+ image_height = canvas_height;
+ if (found_vp8x && animation_present && headers == NULL) {
+ status = VP8_STATUS_OK;
+ goto ReturnWidthHeight; // Just return features from VP8X header.
+ }
+ }
+
+ if (data_size < TAG_SIZE) {
+ status = VP8_STATUS_NOT_ENOUGH_DATA;
+ goto ReturnWidthHeight;
+ }
+
+ // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH".
+ if ((found_riff && found_vp8x) ||
+ (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) {
+ status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size,
+ &hdrs.alpha_data, &hdrs.alpha_data_size);
+ if (status != VP8_STATUS_OK) {
+ goto ReturnWidthHeight; // Invalid chunk size / insufficient data.
+ }
+ }
+
+ // Skip over VP8/VP8L header.
+ status = ParseVP8Header(&data, &data_size, have_all_data, hdrs.riff_size,
+ &hdrs.compressed_size, &hdrs.is_lossless);
+ if (status != VP8_STATUS_OK) {
+ goto ReturnWidthHeight; // Wrong VP8/VP8L chunk-header / insufficient data.
+ }
+ if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+
+ if (format != NULL && !animation_present) {
+ *format = hdrs.is_lossless ? 2 : 1;
+ }
+
+ if (!hdrs.is_lossless) {
+ if (data_size < VP8_FRAME_HEADER_SIZE) {
+ status = VP8_STATUS_NOT_ENOUGH_DATA;
+ goto ReturnWidthHeight;
+ }
+ // Validates raw VP8 data.
+ if (!VP8GetInfo(data, data_size, (uint32_t)hdrs.compressed_size,
+ &image_width, &image_height)) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ } else {
+ if (data_size < VP8L_FRAME_HEADER_SIZE) {
+ status = VP8_STATUS_NOT_ENOUGH_DATA;
+ goto ReturnWidthHeight;
+ }
+ // Validates raw VP8L data.
+ if (!VP8LGetInfo(data, data_size, &image_width, &image_height, has_alpha)) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ }
+ // Validates image size coherency.
+ if (found_vp8x) {
+ if (canvas_width != image_width || canvas_height != image_height) {
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
+ }
+ if (headers != NULL) {
+ *headers = hdrs;
+ headers->offset = data - headers->data;
+ assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD);
+ assert(headers->offset == headers->data_size - data_size);
+ }
+ ReturnWidthHeight:
+ if (status == VP8_STATUS_OK ||
+ (status == VP8_STATUS_NOT_ENOUGH_DATA && found_vp8x && headers == NULL)) {
+ if (has_alpha != NULL) {
+ // If the data did not contain a VP8X/VP8L chunk the only definitive way
+ // to set this is by looking for alpha data (from an ALPH chunk).
+ *has_alpha |= (hdrs.alpha_data != NULL);
+ }
+ if (width != NULL) *width = image_width;
+ if (height != NULL) *height = image_height;
+ return VP8_STATUS_OK;
+ } else {
+ return status;
+ }
+}
+
+VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
+ // status is marked volatile as a workaround for a clang-3.8 (aarch64) bug
+ volatile VP8StatusCode status;
+ int has_animation = 0;
+ assert(headers != NULL);
+ // fill out headers, ignore width/height/has_alpha.
+ status = ParseHeadersInternal(headers->data, headers->data_size,
+ NULL, NULL, NULL, &has_animation,
+ NULL, headers);
+ if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
+ // TODO(jzern): full support of animation frames will require API additions.
+ if (has_animation) {
+ status = VP8_STATUS_UNSUPPORTED_FEATURE;
+ }
+ }
+ return status;
+}
+
+//------------------------------------------------------------------------------
+// WebPDecParams
+
+void WebPResetDecParams(WebPDecParams* const params) {
+ if (params != NULL) {
+ memset(params, 0, sizeof(*params));
+ }
+}
+
+//------------------------------------------------------------------------------
+// "Into" decoding variants
+
+// Main flow
+static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
+ WebPDecParams* const params) {
+ VP8StatusCode status;
+ VP8Io io;
+ WebPHeaderStructure headers;
+
+ headers.data = data;
+ headers.data_size = data_size;
+ headers.have_all_data = 1;
+ status = WebPParseHeaders(&headers); // Process Pre-VP8 chunks.
+ if (status != VP8_STATUS_OK) {
+ return status;
+ }
+
+ assert(params != NULL);
+ VP8InitIo(&io);
+ io.data = headers.data + headers.offset;
+ io.data_size = headers.data_size - headers.offset;
+ WebPInitCustomIo(params, &io); // Plug the I/O functions.
+
+ if (!headers.is_lossless) {
+ VP8Decoder* const dec = VP8New();
+ if (dec == NULL) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ dec->alpha_data_ = headers.alpha_data;
+ dec->alpha_data_size_ = headers.alpha_data_size;
+
+ // Decode bitstream header, update io->width/io->height.
+ if (!VP8GetHeaders(dec, &io)) {
+ status = dec->status_; // An error occurred. Grab error status.
+ } else {
+ // Allocate/check output buffers.
+ status = WebPAllocateDecBuffer(io.width, io.height, params->options,
+ params->output);
+ if (status == VP8_STATUS_OK) { // Decode
+ // This change must be done before calling VP8Decode()
+ dec->mt_method_ = VP8GetThreadMethod(params->options, &headers,
+ io.width, io.height);
+ VP8InitDithering(params->options, dec);
+ if (!VP8Decode(dec, &io)) {
+ status = dec->status_;
+ }
+ }
+ }
+ VP8Delete(dec);
+ } else {
+ VP8LDecoder* const dec = VP8LNew();
+ if (dec == NULL) {
+ return VP8_STATUS_OUT_OF_MEMORY;
+ }
+ if (!VP8LDecodeHeader(dec, &io)) {
+ status = dec->status_; // An error occurred. Grab error status.
+ } else {
+ // Allocate/check output buffers.
+ status = WebPAllocateDecBuffer(io.width, io.height, params->options,
+ params->output);
+ if (status == VP8_STATUS_OK) { // Decode
+ if (!VP8LDecodeImage(dec)) {
+ status = dec->status_;
+ }
+ }
+ }
+ VP8LDelete(dec);
+ }
+
+ if (status != VP8_STATUS_OK) {
+ WebPFreeDecBuffer(params->output);
+ } else {
+ if (params->options != NULL && params->options->flip) {
+ // This restores the original stride values if options->flip was used
+ // during the call to WebPAllocateDecBuffer above.
+ status = WebPFlipBuffer(params->output);
+ }
+ }
+ return status;
+}
+
+// Helpers
+static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace,
+ const uint8_t* const data,
+ size_t data_size,
+ uint8_t* const rgba,
+ int stride, size_t size) {
+ WebPDecParams params;
+ WebPDecBuffer buf;
+ if (rgba == NULL) {
+ return NULL;
+ }
+ WebPInitDecBuffer(&buf);
+ WebPResetDecParams(&params);
+ params.output = &buf;
+ buf.colorspace = colorspace;
+ buf.u.RGBA.rgba = rgba;
+ buf.u.RGBA.stride = stride;
+ buf.u.RGBA.size = size;
+ buf.is_external_memory = 1;
+ if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
+ return NULL;
+ }
+ return rgba;
+}
+
+uint8_t* WebPDecodeRGBInto(const uint8_t* data, size_t data_size,
+ uint8_t* output, size_t size, int stride) {
+ return DecodeIntoRGBABuffer(MODE_RGB, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeRGBAInto(const uint8_t* data, size_t data_size,
+ uint8_t* output, size_t size, int stride) {
+ return DecodeIntoRGBABuffer(MODE_RGBA, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeARGBInto(const uint8_t* data, size_t data_size,
+ uint8_t* output, size_t size, int stride) {
+ return DecodeIntoRGBABuffer(MODE_ARGB, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeBGRInto(const uint8_t* data, size_t data_size,
+ uint8_t* output, size_t size, int stride) {
+ return DecodeIntoRGBABuffer(MODE_BGR, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeBGRAInto(const uint8_t* data, size_t data_size,
+ uint8_t* output, size_t size, int stride) {
+ return DecodeIntoRGBABuffer(MODE_BGRA, data, data_size, output, stride, size);
+}
+
+uint8_t* WebPDecodeYUVInto(const uint8_t* data, size_t data_size,
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride) {
+ WebPDecParams params;
+ WebPDecBuffer output;
+ if (luma == NULL) return NULL;
+ WebPInitDecBuffer(&output);
+ WebPResetDecParams(&params);
+ params.output = &output;
+ output.colorspace = MODE_YUV;
+ output.u.YUVA.y = luma;
+ output.u.YUVA.y_stride = luma_stride;
+ output.u.YUVA.y_size = luma_size;
+ output.u.YUVA.u = u;
+ output.u.YUVA.u_stride = u_stride;
+ output.u.YUVA.u_size = u_size;
+ output.u.YUVA.v = v;
+ output.u.YUVA.v_stride = v_stride;
+ output.u.YUVA.v_size = v_size;
+ output.is_external_memory = 1;
+ if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
+ return NULL;
+ }
+ return luma;
+}
+
+//------------------------------------------------------------------------------
+
+static uint8_t* Decode(WEBP_CSP_MODE mode, const uint8_t* const data,
+ size_t data_size, int* const width, int* const height,
+ WebPDecBuffer* const keep_info) {
+ WebPDecParams params;
+ WebPDecBuffer output;
+
+ WebPInitDecBuffer(&output);
+ WebPResetDecParams(&params);
+ params.output = &output;
+ output.colorspace = mode;
+
+ // Retrieve (and report back) the required dimensions from bitstream.
+ if (!WebPGetInfo(data, data_size, &output.width, &output.height)) {
+ return NULL;
+ }
+ if (width != NULL) *width = output.width;
+ if (height != NULL) *height = output.height;
+
+ // Decode
+ if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
+ return NULL;
+ }
+ if (keep_info != NULL) { // keep track of the side-info
+ WebPCopyDecBuffer(&output, keep_info);
+ }
+ // return decoded samples (don't clear 'output'!)
+ return WebPIsRGBMode(mode) ? output.u.RGBA.rgba : output.u.YUVA.y;
+}
+
+uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
+ int* width, int* height) {
+ return Decode(MODE_RGB, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
+ int* width, int* height) {
+ return Decode(MODE_RGBA, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
+ int* width, int* height) {
+ return Decode(MODE_ARGB, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
+ int* width, int* height) {
+ return Decode(MODE_BGR, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
+ int* width, int* height) {
+ return Decode(MODE_BGRA, data, data_size, width, height, NULL);
+}
+
+uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
+ int* width, int* height, uint8_t** u, uint8_t** v,
+ int* stride, int* uv_stride) {
+ WebPDecBuffer output; // only to preserve the side-infos
+ uint8_t* const out = Decode(MODE_YUV, data, data_size,
+ width, height, &output);
+
+ if (out != NULL) {
+ const WebPYUVABuffer* const buf = &output.u.YUVA;
+ *u = buf->u;
+ *v = buf->v;
+ *stride = buf->y_stride;
+ *uv_stride = buf->u_stride;
+ assert(buf->u_stride == buf->v_stride);
+ }
+ return out;
+}
+
+static void DefaultFeatures(WebPBitstreamFeatures* const features) {
+ assert(features != NULL);
+ memset(features, 0, sizeof(*features));
+}
+
+static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size,
+ WebPBitstreamFeatures* const features) {
+ if (features == NULL || data == NULL) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ DefaultFeatures(features);
+
+ // Only parse enough of the data to retrieve the features.
+ return ParseHeadersInternal(data, data_size,
+ &features->width, &features->height,
+ &features->has_alpha, &features->has_animation,
+ &features->format, NULL);
+}
+
+//------------------------------------------------------------------------------
+// WebPGetInfo()
+
+int WebPGetInfo(const uint8_t* data, size_t data_size,
+ int* width, int* height) {
+ WebPBitstreamFeatures features;
+
+ if (GetFeatures(data, data_size, &features) != VP8_STATUS_OK) {
+ return 0;
+ }
+
+ if (width != NULL) {
+ *width = features.width;
+ }
+ if (height != NULL) {
+ *height = features.height;
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// Advance decoding API
+
+int WebPInitDecoderConfigInternal(WebPDecoderConfig* config,
+ int version) {
+ if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+ return 0; // version mismatch
+ }
+ if (config == NULL) {
+ return 0;
+ }
+ memset(config, 0, sizeof(*config));
+ DefaultFeatures(&config->input);
+ WebPInitDecBuffer(&config->output);
+ return 1;
+}
+
+VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
+ WebPBitstreamFeatures* features,
+ int version) {
+ if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
+ return VP8_STATUS_INVALID_PARAM; // version mismatch
+ }
+ if (features == NULL) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+ return GetFeatures(data, data_size, features);
+}
+
+VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
+ WebPDecoderConfig* config) {
+ WebPDecParams params;
+ VP8StatusCode status;
+
+ if (config == NULL) {
+ return VP8_STATUS_INVALID_PARAM;
+ }
+
+ status = GetFeatures(data, data_size, &config->input);
+ if (status != VP8_STATUS_OK) {
+ if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
+ return VP8_STATUS_BITSTREAM_ERROR; // Not-enough-data treated as error.
+ }
+ return status;
+ }
+
+ WebPResetDecParams(&params);
+ params.options = &config->options;
+ params.output = &config->output;
+ if (WebPAvoidSlowMemory(params.output, &config->input)) {
+ // decoding to slow memory: use a temporary in-mem buffer to decode into.
+ WebPDecBuffer in_mem_buffer;
+ WebPInitDecBuffer(&in_mem_buffer);
+ in_mem_buffer.colorspace = config->output.colorspace;
+ in_mem_buffer.width = config->input.width;
+ in_mem_buffer.height = config->input.height;
+ params.output = &in_mem_buffer;
+ status = DecodeInto(data, data_size, &params);
+ if (status == VP8_STATUS_OK) { // do the slow-copy
+ status = WebPCopyDecBufferPixels(&in_mem_buffer, &config->output);
+ }
+ WebPFreeDecBuffer(&in_mem_buffer);
+ } else {
+ status = DecodeInto(data, data_size, &params);
+ }
+
+ return status;
+}
+
+//------------------------------------------------------------------------------
+// Cropping and rescaling.
+
+int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
+ VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
+ const int W = io->width;
+ const int H = io->height;
+ int x = 0, y = 0, w = W, h = H;
+
+ // Cropping
+ io->use_cropping = (options != NULL) && (options->use_cropping > 0);
+ if (io->use_cropping) {
+ w = options->crop_width;
+ h = options->crop_height;
+ x = options->crop_left;
+ y = options->crop_top;
+ if (!WebPIsRGBMode(src_colorspace)) { // only snap for YUV420
+ x &= ~1;
+ y &= ~1;
+ }
+ if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
+ return 0; // out of frame boundary error
+ }
+ }
+ io->crop_left = x;
+ io->crop_top = y;
+ io->crop_right = x + w;
+ io->crop_bottom = y + h;
+ io->mb_w = w;
+ io->mb_h = h;
+
+ // Scaling
+ io->use_scaling = (options != NULL) && (options->use_scaling > 0);
+ if (io->use_scaling) {
+ int scaled_width = options->scaled_width;
+ int scaled_height = options->scaled_height;
+ if (!WebPRescalerGetScaledDimensions(w, h, &scaled_width, &scaled_height)) {
+ return 0;
+ }
+ io->scaled_width = scaled_width;
+ io->scaled_height = scaled_height;
+ }
+
+ // Filter
+ io->bypass_filtering = (options != NULL) && options->bypass_filtering;
+
+ // Fancy upsampler
+#ifdef FANCY_UPSAMPLING
+ io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling);
+#endif
+
+ if (io->use_scaling) {
+ // disable filter (only for large downscaling ratio).
+ io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
+ (io->scaled_height < H * 3 / 4);
+ io->fancy_upsampling = 0;
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dec/webpi_dec.h b/media/libwebp/dec/webpi_dec.h
new file mode 100644
index 000000000..696abc195
--- /dev/null
+++ b/media/libwebp/dec/webpi_dec.h
@@ -0,0 +1,133 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Internal header: WebP decoding parameters and custom IO on buffer
+//
+// Author: somnath@google.com (Somnath Banerjee)
+
+#ifndef WEBP_DEC_WEBPI_H_
+#define WEBP_DEC_WEBPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../utils/rescaler_utils.h"
+#include "./vp8_dec.h"
+
+//------------------------------------------------------------------------------
+// WebPDecParams: Decoding output parameters. Transient internal object.
+
+typedef struct WebPDecParams WebPDecParams;
+typedef int (*OutputFunc)(const VP8Io* const io, WebPDecParams* const p);
+typedef int (*OutputAlphaFunc)(const VP8Io* const io, WebPDecParams* const p,
+ int expected_num_out_lines);
+typedef int (*OutputRowFunc)(WebPDecParams* const p, int y_pos,
+ int max_out_lines);
+
+struct WebPDecParams {
+ WebPDecBuffer* output; // output buffer.
+ uint8_t* tmp_y, *tmp_u, *tmp_v; // cache for the fancy upsampler
+ // or used for tmp rescaling
+
+ int last_y; // coordinate of the line that was last output
+ const WebPDecoderOptions* options; // if not NULL, use alt decoding features
+
+ WebPRescaler* scaler_y, *scaler_u, *scaler_v, *scaler_a; // rescalers
+ void* memory; // overall scratch memory for the output work.
+
+ OutputFunc emit; // output RGB or YUV samples
+ OutputAlphaFunc emit_alpha; // output alpha channel
+ OutputRowFunc emit_alpha_row; // output one line of rescaled alpha values
+};
+
+// Should be called first, before any use of the WebPDecParams object.
+void WebPResetDecParams(WebPDecParams* const params);
+
+//------------------------------------------------------------------------------
+// Header parsing helpers
+
+// Structure storing a description of the RIFF headers.
+typedef struct {
+ const uint8_t* data; // input buffer
+ size_t data_size; // input buffer size
+ int have_all_data; // true if all data is known to be available
+ size_t offset; // offset to main data chunk (VP8 or VP8L)
+ const uint8_t* alpha_data; // points to alpha chunk (if present)
+ size_t alpha_data_size; // alpha chunk size
+ size_t compressed_size; // VP8/VP8L compressed data size
+ size_t riff_size; // size of the riff payload (or 0 if absent)
+ int is_lossless; // true if a VP8L chunk is present
+} WebPHeaderStructure;
+
+// Skips over all valid chunks prior to the first VP8/VP8L frame header.
+// Returns: VP8_STATUS_OK, VP8_STATUS_BITSTREAM_ERROR (invalid header/chunk),
+// VP8_STATUS_NOT_ENOUGH_DATA (partial input) or VP8_STATUS_UNSUPPORTED_FEATURE
+// in the case of non-decodable features (animation for instance).
+// In 'headers', compressed_size, offset, alpha_data, alpha_size, and lossless
+// fields are updated appropriately upon success.
+VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers);
+
+//------------------------------------------------------------------------------
+// Misc utils
+
+// Initializes VP8Io with custom setup, io and teardown functions. The default
+// hooks will use the supplied 'params' as io->opaque handle.
+void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
+
+// Setup crop_xxx fields, mb_w and mb_h in io. 'src_colorspace' refers
+// to the *compressed* format, not the output one.
+int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
+ VP8Io* const io, WEBP_CSP_MODE src_colorspace);
+
+//------------------------------------------------------------------------------
+// Internal functions regarding WebPDecBuffer memory (in buffer.c).
+// Don't really need to be externally visible for now.
+
+// Prepare 'buffer' with the requested initial dimensions width/height.
+// If no external storage is supplied, initializes buffer by allocating output
+// memory and setting up the stride information. Validate the parameters. Return
+// an error code in case of problem (no memory, or invalid stride / size /
+// dimension / etc.). If *options is not NULL, also verify that the options'
+// parameters are valid and apply them to the width/height dimensions of the
+// output buffer. This takes cropping / scaling / rotation into account.
+// Also incorporates the options->flip flag to flip the buffer parameters if
+// needed.
+VP8StatusCode WebPAllocateDecBuffer(int width, int height,
+ const WebPDecoderOptions* const options,
+ WebPDecBuffer* const buffer);
+
+// Flip buffer vertically by negating the various strides.
+VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer);
+
+// Copy 'src' into 'dst' buffer, making sure 'dst' is not marked as owner of the
+// memory (still held by 'src'). No pixels are copied.
+void WebPCopyDecBuffer(const WebPDecBuffer* const src,
+ WebPDecBuffer* const dst);
+
+// Copy and transfer ownership from src to dst (beware of parameter order!)
+void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst);
+
+// Copy pixels from 'src' into a *preallocated* 'dst' buffer. Returns
+// VP8_STATUS_INVALID_PARAM if the 'dst' is not set up correctly for the copy.
+VP8StatusCode WebPCopyDecBufferPixels(const WebPDecBuffer* const src,
+ WebPDecBuffer* const dst);
+
+// Returns true if decoding will be slow with the current configuration
+// and bitstream features.
+int WebPAvoidSlowMemory(const WebPDecBuffer* const output,
+ const WebPBitstreamFeatures* const features);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_DEC_WEBPI_H_ */
diff --git a/media/libwebp/demux/demux.c b/media/libwebp/demux/demux.c
new file mode 100644
index 000000000..100eab8c0
--- /dev/null
+++ b/media/libwebp/demux/demux.c
@@ -0,0 +1,965 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebP container demux.
+//
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../utils/utils.h"
+#include "../webp/decode.h" // WebPGetFeatures
+#include "../webp/demux.h"
+#include "../webp/format_constants.h"
+
+#define DMUX_MAJ_VERSION 0
+#define DMUX_MIN_VERSION 3
+#define DMUX_REV_VERSION 2
+
+typedef struct {
+ size_t start_; // start location of the data
+ size_t end_; // end location
+ size_t riff_end_; // riff chunk end location, can be > end_.
+ size_t buf_size_; // size of the buffer
+ const uint8_t* buf_;
+} MemBuffer;
+
+typedef struct {
+ size_t offset_;
+ size_t size_;
+} ChunkData;
+
+typedef struct Frame {
+ int x_offset_, y_offset_;
+ int width_, height_;
+ int has_alpha_;
+ int duration_;
+ WebPMuxAnimDispose dispose_method_;
+ WebPMuxAnimBlend blend_method_;
+ int frame_num_;
+ int complete_; // img_components_ contains a full image.
+ ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH
+ struct Frame* next_;
+} Frame;
+
+typedef struct Chunk {
+ ChunkData data_;
+ struct Chunk* next_;
+} Chunk;
+
+struct WebPDemuxer {
+ MemBuffer mem_;
+ WebPDemuxState state_;
+ int is_ext_format_;
+ uint32_t feature_flags_;
+ int canvas_width_, canvas_height_;
+ int loop_count_;
+ uint32_t bgcolor_;
+ int num_frames_;
+ Frame* frames_;
+ Frame** frames_tail_;
+ Chunk* chunks_; // non-image chunks
+ Chunk** chunks_tail_;
+};
+
+typedef enum {
+ PARSE_OK,
+ PARSE_NEED_MORE_DATA,
+ PARSE_ERROR
+} ParseStatus;
+
+typedef struct ChunkParser {
+ uint8_t id[4];
+ ParseStatus (*parse)(WebPDemuxer* const dmux);
+ int (*valid)(const WebPDemuxer* const dmux);
+} ChunkParser;
+
+static ParseStatus ParseSingleImage(WebPDemuxer* const dmux);
+static ParseStatus ParseVP8X(WebPDemuxer* const dmux);
+static int IsValidSimpleFormat(const WebPDemuxer* const dmux);
+static int IsValidExtendedFormat(const WebPDemuxer* const dmux);
+
+static const ChunkParser kMasterChunks[] = {
+ { { 'V', 'P', '8', ' ' }, ParseSingleImage, IsValidSimpleFormat },
+ { { 'V', 'P', '8', 'L' }, ParseSingleImage, IsValidSimpleFormat },
+ { { 'V', 'P', '8', 'X' }, ParseVP8X, IsValidExtendedFormat },
+ { { '0', '0', '0', '0' }, NULL, NULL },
+};
+
+//------------------------------------------------------------------------------
+
+int WebPGetDemuxVersion(void) {
+ return (DMUX_MAJ_VERSION << 16) | (DMUX_MIN_VERSION << 8) | DMUX_REV_VERSION;
+}
+
+// -----------------------------------------------------------------------------
+// MemBuffer
+
+static int RemapMemBuffer(MemBuffer* const mem,
+ const uint8_t* data, size_t size) {
+ if (size < mem->buf_size_) return 0; // can't remap to a shorter buffer!
+
+ mem->buf_ = data;
+ mem->end_ = mem->buf_size_ = size;
+ return 1;
+}
+
+static int InitMemBuffer(MemBuffer* const mem,
+ const uint8_t* data, size_t size) {
+ memset(mem, 0, sizeof(*mem));
+ return RemapMemBuffer(mem, data, size);
+}
+
+// Return the remaining data size available in 'mem'.
+static WEBP_INLINE size_t MemDataSize(const MemBuffer* const mem) {
+ return (mem->end_ - mem->start_);
+}
+
+// Return true if 'size' exceeds the end of the RIFF chunk.
+static WEBP_INLINE int SizeIsInvalid(const MemBuffer* const mem, size_t size) {
+ return (size > mem->riff_end_ - mem->start_);
+}
+
+static WEBP_INLINE void Skip(MemBuffer* const mem, size_t size) {
+ mem->start_ += size;
+}
+
+static WEBP_INLINE void Rewind(MemBuffer* const mem, size_t size) {
+ mem->start_ -= size;
+}
+
+static WEBP_INLINE const uint8_t* GetBuffer(MemBuffer* const mem) {
+ return mem->buf_ + mem->start_;
+}
+
+// Read from 'mem' and skip the read bytes.
+static WEBP_INLINE uint8_t ReadByte(MemBuffer* const mem) {
+ const uint8_t byte = mem->buf_[mem->start_];
+ Skip(mem, 1);
+ return byte;
+}
+
+static WEBP_INLINE int ReadLE16s(MemBuffer* const mem) {
+ const uint8_t* const data = mem->buf_ + mem->start_;
+ const int val = GetLE16(data);
+ Skip(mem, 2);
+ return val;
+}
+
+static WEBP_INLINE int ReadLE24s(MemBuffer* const mem) {
+ const uint8_t* const data = mem->buf_ + mem->start_;
+ const int val = GetLE24(data);
+ Skip(mem, 3);
+ return val;
+}
+
+static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) {
+ const uint8_t* const data = mem->buf_ + mem->start_;
+ const uint32_t val = GetLE32(data);
+ Skip(mem, 4);
+ return val;
+}
+
+// -----------------------------------------------------------------------------
+// Secondary chunk parsing
+
+static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) {
+ *dmux->chunks_tail_ = chunk;
+ chunk->next_ = NULL;
+ dmux->chunks_tail_ = &chunk->next_;
+}
+
+// Add a frame to the end of the list, ensuring the last frame is complete.
+// Returns true on success, false otherwise.
+static int AddFrame(WebPDemuxer* const dmux, Frame* const frame) {
+ const Frame* const last_frame = *dmux->frames_tail_;
+ if (last_frame != NULL && !last_frame->complete_) return 0;
+
+ *dmux->frames_tail_ = frame;
+ frame->next_ = NULL;
+ dmux->frames_tail_ = &frame->next_;
+ return 1;
+}
+
+static void SetFrameInfo(size_t start_offset, size_t size,
+ int frame_num, int complete,
+ const WebPBitstreamFeatures* const features,
+ Frame* const frame) {
+ frame->img_components_[0].offset_ = start_offset;
+ frame->img_components_[0].size_ = size;
+ frame->width_ = features->width;
+ frame->height_ = features->height;
+ frame->has_alpha_ |= features->has_alpha;
+ frame->frame_num_ = frame_num;
+ frame->complete_ = complete;
+}
+
+// Store image bearing chunks to 'frame'.
+static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
+ MemBuffer* const mem, Frame* const frame) {
+ int alpha_chunks = 0;
+ int image_chunks = 0;
+ int done = (MemDataSize(mem) < min_size);
+ ParseStatus status = PARSE_OK;
+
+ if (done) return PARSE_NEED_MORE_DATA;
+
+ do {
+ const size_t chunk_start_offset = mem->start_;
+ const uint32_t fourcc = ReadLE32(mem);
+ const uint32_t payload_size = ReadLE32(mem);
+ const uint32_t payload_size_padded = payload_size + (payload_size & 1);
+ const size_t payload_available = (payload_size_padded > MemDataSize(mem))
+ ? MemDataSize(mem) : payload_size_padded;
+ const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available;
+
+ if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+ if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
+ if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
+
+ switch (fourcc) {
+ case MKFOURCC('A', 'L', 'P', 'H'):
+ if (alpha_chunks == 0) {
+ ++alpha_chunks;
+ frame->img_components_[1].offset_ = chunk_start_offset;
+ frame->img_components_[1].size_ = chunk_size;
+ frame->has_alpha_ = 1;
+ frame->frame_num_ = frame_num;
+ Skip(mem, payload_available);
+ } else {
+ goto Done;
+ }
+ break;
+ case MKFOURCC('V', 'P', '8', 'L'):
+ if (alpha_chunks > 0) return PARSE_ERROR; // VP8L has its own alpha
+ // fall through
+ case MKFOURCC('V', 'P', '8', ' '):
+ if (image_chunks == 0) {
+ // Extract the bitstream features, tolerating failures when the data
+ // is incomplete.
+ WebPBitstreamFeatures features;
+ const VP8StatusCode vp8_status =
+ WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size,
+ &features);
+ if (status == PARSE_NEED_MORE_DATA &&
+ vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) {
+ return PARSE_NEED_MORE_DATA;
+ } else if (vp8_status != VP8_STATUS_OK) {
+ // We have enough data, and yet WebPGetFeatures() failed.
+ return PARSE_ERROR;
+ }
+ ++image_chunks;
+ SetFrameInfo(chunk_start_offset, chunk_size, frame_num,
+ status == PARSE_OK, &features, frame);
+ Skip(mem, payload_available);
+ } else {
+ goto Done;
+ }
+ break;
+ Done:
+ default:
+ // Restore fourcc/size when moving up one level in parsing.
+ Rewind(mem, CHUNK_HEADER_SIZE);
+ done = 1;
+ break;
+ }
+
+ if (mem->start_ == mem->riff_end_) {
+ done = 1;
+ } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) {
+ status = PARSE_NEED_MORE_DATA;
+ }
+ } while (!done && status == PARSE_OK);
+
+ return status;
+}
+
+// Creates a new Frame if 'actual_size' is within bounds and 'mem' contains
+// enough data ('min_size') to parse the payload.
+// Returns PARSE_OK on success with *frame pointing to the new Frame.
+// Returns PARSE_NEED_MORE_DATA with insufficient data, PARSE_ERROR otherwise.
+static ParseStatus NewFrame(const MemBuffer* const mem,
+ uint32_t min_size, uint32_t actual_size,
+ Frame** frame) {
+ if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
+ if (actual_size < min_size) return PARSE_ERROR;
+ if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
+
+ *frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(**frame));
+ return (*frame == NULL) ? PARSE_ERROR : PARSE_OK;
+}
+
+// Parse a 'ANMF' chunk and any image bearing chunks that immediately follow.
+// 'frame_chunk_size' is the previously validated, padded chunk size.
+static ParseStatus ParseAnimationFrame(
+ WebPDemuxer* const dmux, uint32_t frame_chunk_size) {
+ const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
+ const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE;
+ int added_frame = 0;
+ int bits;
+ MemBuffer* const mem = &dmux->mem_;
+ Frame* frame;
+ ParseStatus status =
+ NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
+ if (status != PARSE_OK) return status;
+
+ frame->x_offset_ = 2 * ReadLE24s(mem);
+ frame->y_offset_ = 2 * ReadLE24s(mem);
+ frame->width_ = 1 + ReadLE24s(mem);
+ frame->height_ = 1 + ReadLE24s(mem);
+ frame->duration_ = ReadLE24s(mem);
+ bits = ReadByte(mem);
+ frame->dispose_method_ =
+ (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE;
+ frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND;
+ if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) {
+ WebPSafeFree(frame);
+ return PARSE_ERROR;
+ }
+
+ // Store a frame only if the animation flag is set there is some data for
+ // this frame is available.
+ status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
+ if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
+ added_frame = AddFrame(dmux, frame);
+ if (added_frame) {
+ ++dmux->num_frames_;
+ } else {
+ status = PARSE_ERROR;
+ }
+ }
+
+ if (!added_frame) WebPSafeFree(frame);
+ return status;
+}
+
+// General chunk storage, starting with the header at 'start_offset', allowing
+// the user to request the payload via a fourcc string. 'size' includes the
+// header and the unpadded payload size.
+// Returns true on success, false otherwise.
+static int StoreChunk(WebPDemuxer* const dmux,
+ size_t start_offset, uint32_t size) {
+ Chunk* const chunk = (Chunk*)WebPSafeCalloc(1ULL, sizeof(*chunk));
+ if (chunk == NULL) return 0;
+
+ chunk->data_.offset_ = start_offset;
+ chunk->data_.size_ = size;
+ AddChunk(dmux, chunk);
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+// Primary chunk parsing
+
+static ParseStatus ReadHeader(MemBuffer* const mem) {
+ const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE;
+ uint32_t riff_size;
+
+ // Basic file level validation.
+ if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
+ if (memcmp(GetBuffer(mem), "RIFF", CHUNK_SIZE_BYTES) ||
+ memcmp(GetBuffer(mem) + CHUNK_HEADER_SIZE, "WEBP", CHUNK_SIZE_BYTES)) {
+ return PARSE_ERROR;
+ }
+
+ riff_size = GetLE32(GetBuffer(mem) + TAG_SIZE);
+ if (riff_size < CHUNK_HEADER_SIZE) return PARSE_ERROR;
+ if (riff_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+
+ // There's no point in reading past the end of the RIFF chunk
+ mem->riff_end_ = riff_size + CHUNK_HEADER_SIZE;
+ if (mem->buf_size_ > mem->riff_end_) {
+ mem->buf_size_ = mem->end_ = mem->riff_end_;
+ }
+
+ Skip(mem, RIFF_HEADER_SIZE);
+ return PARSE_OK;
+}
+
+static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
+ const size_t min_size = CHUNK_HEADER_SIZE;
+ MemBuffer* const mem = &dmux->mem_;
+ Frame* frame;
+ ParseStatus status;
+ int image_added = 0;
+
+ if (dmux->frames_ != NULL) return PARSE_ERROR;
+ if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
+ if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
+
+ frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
+ if (frame == NULL) return PARSE_ERROR;
+
+ // For the single image case we allow parsing of a partial frame, but we need
+ // at least CHUNK_HEADER_SIZE for parsing.
+ status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame);
+ if (status != PARSE_ERROR) {
+ const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
+ // Clear any alpha when the alpha flag is missing.
+ if (!has_alpha && frame->img_components_[1].size_ > 0) {
+ frame->img_components_[1].offset_ = 0;
+ frame->img_components_[1].size_ = 0;
+ frame->has_alpha_ = 0;
+ }
+
+ // Use the frame width/height as the canvas values for non-vp8x files.
+ // Also, set ALPHA_FLAG if this is a lossless image with alpha.
+ if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) {
+ dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
+ dmux->canvas_width_ = frame->width_;
+ dmux->canvas_height_ = frame->height_;
+ dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0;
+ }
+ if (!AddFrame(dmux, frame)) {
+ status = PARSE_ERROR; // last frame was left incomplete
+ } else {
+ image_added = 1;
+ dmux->num_frames_ = 1;
+ }
+ }
+
+ if (!image_added) WebPSafeFree(frame);
+ return status;
+}
+
+static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) {
+ const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
+ MemBuffer* const mem = &dmux->mem_;
+ int anim_chunks = 0;
+ ParseStatus status = PARSE_OK;
+
+ do {
+ int store_chunk = 1;
+ const size_t chunk_start_offset = mem->start_;
+ const uint32_t fourcc = ReadLE32(mem);
+ const uint32_t chunk_size = ReadLE32(mem);
+ const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
+
+ if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+ if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
+
+ switch (fourcc) {
+ case MKFOURCC('V', 'P', '8', 'X'): {
+ return PARSE_ERROR;
+ }
+ case MKFOURCC('A', 'L', 'P', 'H'):
+ case MKFOURCC('V', 'P', '8', ' '):
+ case MKFOURCC('V', 'P', '8', 'L'): {
+ // check that this isn't an animation (all frames should be in an ANMF).
+ if (anim_chunks > 0 || is_animation) return PARSE_ERROR;
+
+ Rewind(mem, CHUNK_HEADER_SIZE);
+ status = ParseSingleImage(dmux);
+ break;
+ }
+ case MKFOURCC('A', 'N', 'I', 'M'): {
+ if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR;
+
+ if (MemDataSize(mem) < chunk_size_padded) {
+ status = PARSE_NEED_MORE_DATA;
+ } else if (anim_chunks == 0) {
+ ++anim_chunks;
+ dmux->bgcolor_ = ReadLE32(mem);
+ dmux->loop_count_ = ReadLE16s(mem);
+ Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE);
+ } else {
+ store_chunk = 0;
+ goto Skip;
+ }
+ break;
+ }
+ case MKFOURCC('A', 'N', 'M', 'F'): {
+ if (anim_chunks == 0) return PARSE_ERROR; // 'ANIM' precedes frames.
+ status = ParseAnimationFrame(dmux, chunk_size_padded);
+ break;
+ }
+ case MKFOURCC('I', 'C', 'C', 'P'): {
+ store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
+ goto Skip;
+ }
+ case MKFOURCC('E', 'X', 'I', 'F'): {
+ store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG);
+ goto Skip;
+ }
+ case MKFOURCC('X', 'M', 'P', ' '): {
+ store_chunk = !!(dmux->feature_flags_ & XMP_FLAG);
+ goto Skip;
+ }
+ Skip:
+ default: {
+ if (chunk_size_padded <= MemDataSize(mem)) {
+ if (store_chunk) {
+ // Store only the chunk header and unpadded size as only the payload
+ // will be returned to the user.
+ if (!StoreChunk(dmux, chunk_start_offset,
+ CHUNK_HEADER_SIZE + chunk_size)) {
+ return PARSE_ERROR;
+ }
+ }
+ Skip(mem, chunk_size_padded);
+ } else {
+ status = PARSE_NEED_MORE_DATA;
+ }
+ }
+ }
+
+ if (mem->start_ == mem->riff_end_) {
+ break;
+ } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) {
+ status = PARSE_NEED_MORE_DATA;
+ }
+ } while (status == PARSE_OK);
+
+ return status;
+}
+
+static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
+ MemBuffer* const mem = &dmux->mem_;
+ uint32_t vp8x_size;
+
+ if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
+
+ dmux->is_ext_format_ = 1;
+ Skip(mem, TAG_SIZE); // VP8X
+ vp8x_size = ReadLE32(mem);
+ if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
+ if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR;
+ vp8x_size += vp8x_size & 1;
+ if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR;
+ if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA;
+
+ dmux->feature_flags_ = ReadByte(mem);
+ Skip(mem, 3); // Reserved.
+ dmux->canvas_width_ = 1 + ReadLE24s(mem);
+ dmux->canvas_height_ = 1 + ReadLE24s(mem);
+ if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) {
+ return PARSE_ERROR; // image final dimension is too large
+ }
+ Skip(mem, vp8x_size - VP8X_CHUNK_SIZE); // skip any trailing data.
+ dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
+
+ if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR;
+ if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
+
+ return ParseVP8XChunks(dmux);
+}
+
+// -----------------------------------------------------------------------------
+// Format validation
+
+static int IsValidSimpleFormat(const WebPDemuxer* const dmux) {
+ const Frame* const frame = dmux->frames_;
+ if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1;
+
+ if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0;
+ if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0;
+
+ if (frame->width_ <= 0 || frame->height_ <= 0) return 0;
+ return 1;
+}
+
+// If 'exact' is true, check that the image resolution matches the canvas.
+// If 'exact' is false, check that the x/y offsets do not exceed the canvas.
+static int CheckFrameBounds(const Frame* const frame, int exact,
+ int canvas_width, int canvas_height) {
+ if (exact) {
+ if (frame->x_offset_ != 0 || frame->y_offset_ != 0) {
+ return 0;
+ }
+ if (frame->width_ != canvas_width || frame->height_ != canvas_height) {
+ return 0;
+ }
+ } else {
+ if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0;
+ if (frame->width_ + frame->x_offset_ > canvas_width) return 0;
+ if (frame->height_ + frame->y_offset_ > canvas_height) return 0;
+ }
+ return 1;
+}
+
+static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
+ const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG);
+ const Frame* f = dmux->frames_;
+
+ if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1;
+
+ if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0;
+ if (dmux->loop_count_ < 0) return 0;
+ if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0;
+ if (dmux->feature_flags_ & ~ALL_VALID_FLAGS) return 0; // invalid bitstream
+
+ while (f != NULL) {
+ const int cur_frame_set = f->frame_num_;
+ int frame_count = 0;
+
+ // Check frame properties.
+ for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
+ const ChunkData* const image = f->img_components_;
+ const ChunkData* const alpha = f->img_components_ + 1;
+
+ if (!is_animation && f->frame_num_ > 1) return 0;
+
+ if (f->complete_) {
+ if (alpha->size_ == 0 && image->size_ == 0) return 0;
+ // Ensure alpha precedes image bitstream.
+ if (alpha->size_ > 0 && alpha->offset_ > image->offset_) {
+ return 0;
+ }
+
+ if (f->width_ <= 0 || f->height_ <= 0) return 0;
+ } else {
+ // There shouldn't be a partial frame in a complete file.
+ if (dmux->state_ == WEBP_DEMUX_DONE) return 0;
+
+ // Ensure alpha precedes image bitstream.
+ if (alpha->size_ > 0 && image->size_ > 0 &&
+ alpha->offset_ > image->offset_) {
+ return 0;
+ }
+ // There shouldn't be any frames after an incomplete one.
+ if (f->next_ != NULL) return 0;
+ }
+
+ if (f->width_ > 0 && f->height_ > 0 &&
+ !CheckFrameBounds(f, !is_animation,
+ dmux->canvas_width_, dmux->canvas_height_)) {
+ return 0;
+ }
+
+ ++frame_count;
+ }
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+// WebPDemuxer object
+
+static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) {
+ dmux->state_ = WEBP_DEMUX_PARSING_HEADER;
+ dmux->loop_count_ = 1;
+ dmux->bgcolor_ = 0xFFFFFFFF; // White background by default.
+ dmux->canvas_width_ = -1;
+ dmux->canvas_height_ = -1;
+ dmux->frames_tail_ = &dmux->frames_;
+ dmux->chunks_tail_ = &dmux->chunks_;
+ dmux->mem_ = *mem;
+}
+
+static ParseStatus CreateRawImageDemuxer(MemBuffer* const mem,
+ WebPDemuxer** demuxer) {
+ WebPBitstreamFeatures features;
+ const VP8StatusCode status =
+ WebPGetFeatures(mem->buf_, mem->buf_size_, &features);
+ *demuxer = NULL;
+ if (status != VP8_STATUS_OK) {
+ return (status == VP8_STATUS_NOT_ENOUGH_DATA) ? PARSE_NEED_MORE_DATA
+ : PARSE_ERROR;
+ }
+
+ {
+ WebPDemuxer* const dmux = (WebPDemuxer*)WebPSafeCalloc(1ULL, sizeof(*dmux));
+ Frame* const frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
+ if (dmux == NULL || frame == NULL) goto Error;
+ InitDemux(dmux, mem);
+ SetFrameInfo(0, mem->buf_size_, 1 /*frame_num*/, 1 /*complete*/, &features,
+ frame);
+ if (!AddFrame(dmux, frame)) goto Error;
+ dmux->state_ = WEBP_DEMUX_DONE;
+ dmux->canvas_width_ = frame->width_;
+ dmux->canvas_height_ = frame->height_;
+ dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0;
+ dmux->num_frames_ = 1;
+ assert(IsValidSimpleFormat(dmux));
+ *demuxer = dmux;
+ return PARSE_OK;
+
+ Error:
+ WebPSafeFree(dmux);
+ WebPSafeFree(frame);
+ return PARSE_ERROR;
+ }
+}
+
+WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial,
+ WebPDemuxState* state, int version) {
+ const ChunkParser* parser;
+ int partial;
+ ParseStatus status = PARSE_ERROR;
+ MemBuffer mem;
+ WebPDemuxer* dmux;
+
+ if (state != NULL) *state = WEBP_DEMUX_PARSE_ERROR;
+
+ if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DEMUX_ABI_VERSION)) return NULL;
+ if (data == NULL || data->bytes == NULL || data->size == 0) return NULL;
+
+ if (!InitMemBuffer(&mem, data->bytes, data->size)) return NULL;
+ status = ReadHeader(&mem);
+ if (status != PARSE_OK) {
+ // If parsing of the webp file header fails attempt to handle a raw
+ // VP8/VP8L frame. Note 'allow_partial' is ignored in this case.
+ if (status == PARSE_ERROR) {
+ status = CreateRawImageDemuxer(&mem, &dmux);
+ if (status == PARSE_OK) {
+ if (state != NULL) *state = WEBP_DEMUX_DONE;
+ return dmux;
+ }
+ }
+ if (state != NULL) {
+ *state = (status == PARSE_NEED_MORE_DATA) ? WEBP_DEMUX_PARSING_HEADER
+ : WEBP_DEMUX_PARSE_ERROR;
+ }
+ return NULL;
+ }
+
+ partial = (mem.buf_size_ < mem.riff_end_);
+ if (!allow_partial && partial) return NULL;
+
+ dmux = (WebPDemuxer*)WebPSafeCalloc(1ULL, sizeof(*dmux));
+ if (dmux == NULL) return NULL;
+ InitDemux(dmux, &mem);
+
+ status = PARSE_ERROR;
+ for (parser = kMasterChunks; parser->parse != NULL; ++parser) {
+ if (!memcmp(parser->id, GetBuffer(&dmux->mem_), TAG_SIZE)) {
+ status = parser->parse(dmux);
+ if (status == PARSE_OK) dmux->state_ = WEBP_DEMUX_DONE;
+ if (status == PARSE_NEED_MORE_DATA && !partial) status = PARSE_ERROR;
+ if (status != PARSE_ERROR && !parser->valid(dmux)) status = PARSE_ERROR;
+ if (status == PARSE_ERROR) dmux->state_ = WEBP_DEMUX_PARSE_ERROR;
+ break;
+ }
+ }
+ if (state != NULL) *state = dmux->state_;
+
+ if (status == PARSE_ERROR) {
+ WebPDemuxDelete(dmux);
+ return NULL;
+ }
+ return dmux;
+}
+
+void WebPDemuxDelete(WebPDemuxer* dmux) {
+ Chunk* c;
+ Frame* f;
+ if (dmux == NULL) return;
+
+ for (f = dmux->frames_; f != NULL;) {
+ Frame* const cur_frame = f;
+ f = f->next_;
+ WebPSafeFree(cur_frame);
+ }
+ for (c = dmux->chunks_; c != NULL;) {
+ Chunk* const cur_chunk = c;
+ c = c->next_;
+ WebPSafeFree(cur_chunk);
+ }
+ WebPSafeFree(dmux);
+}
+
+// -----------------------------------------------------------------------------
+
+uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) {
+ if (dmux == NULL) return 0;
+
+ switch (feature) {
+ case WEBP_FF_FORMAT_FLAGS: return dmux->feature_flags_;
+ case WEBP_FF_CANVAS_WIDTH: return (uint32_t)dmux->canvas_width_;
+ case WEBP_FF_CANVAS_HEIGHT: return (uint32_t)dmux->canvas_height_;
+ case WEBP_FF_LOOP_COUNT: return (uint32_t)dmux->loop_count_;
+ case WEBP_FF_BACKGROUND_COLOR: return dmux->bgcolor_;
+ case WEBP_FF_FRAME_COUNT: return (uint32_t)dmux->num_frames_;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// Frame iteration
+
+static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
+ const Frame* f;
+ for (f = dmux->frames_; f != NULL; f = f->next_) {
+ if (frame_num == f->frame_num_) break;
+ }
+ return f;
+}
+
+static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
+ const Frame* const frame,
+ size_t* const data_size) {
+ *data_size = 0;
+ if (frame != NULL) {
+ const ChunkData* const image = frame->img_components_;
+ const ChunkData* const alpha = frame->img_components_ + 1;
+ size_t start_offset = image->offset_;
+ *data_size = image->size_;
+
+ // if alpha exists it precedes image, update the size allowing for
+ // intervening chunks.
+ if (alpha->size_ > 0) {
+ const size_t inter_size = (image->offset_ > 0)
+ ? image->offset_ - (alpha->offset_ + alpha->size_)
+ : 0;
+ start_offset = alpha->offset_;
+ *data_size += alpha->size_ + inter_size;
+ }
+ return mem_buf + start_offset;
+ }
+ return NULL;
+}
+
+// Create a whole 'frame' from VP8 (+ alpha) or lossless.
+static int SynthesizeFrame(const WebPDemuxer* const dmux,
+ const Frame* const frame,
+ WebPIterator* const iter) {
+ const uint8_t* const mem_buf = dmux->mem_.buf_;
+ size_t payload_size = 0;
+ const uint8_t* const payload = GetFramePayload(mem_buf, frame, &payload_size);
+ if (payload == NULL) return 0;
+ assert(frame != NULL);
+
+ iter->frame_num = frame->frame_num_;
+ iter->num_frames = dmux->num_frames_;
+ iter->x_offset = frame->x_offset_;
+ iter->y_offset = frame->y_offset_;
+ iter->width = frame->width_;
+ iter->height = frame->height_;
+ iter->has_alpha = frame->has_alpha_;
+ iter->duration = frame->duration_;
+ iter->dispose_method = frame->dispose_method_;
+ iter->blend_method = frame->blend_method_;
+ iter->complete = frame->complete_;
+ iter->fragment.bytes = payload;
+ iter->fragment.size = payload_size;
+ return 1;
+}
+
+static int SetFrame(int frame_num, WebPIterator* const iter) {
+ const Frame* frame;
+ const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
+ if (dmux == NULL || frame_num < 0) return 0;
+ if (frame_num > dmux->num_frames_) return 0;
+ if (frame_num == 0) frame_num = dmux->num_frames_;
+
+ frame = GetFrame(dmux, frame_num);
+ if (frame == NULL) return 0;
+
+ return SynthesizeFrame(dmux, frame, iter);
+}
+
+int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) {
+ if (iter == NULL) return 0;
+
+ memset(iter, 0, sizeof(*iter));
+ iter->private_ = (void*)dmux;
+ return SetFrame(frame, iter);
+}
+
+int WebPDemuxNextFrame(WebPIterator* iter) {
+ if (iter == NULL) return 0;
+ return SetFrame(iter->frame_num + 1, iter);
+}
+
+int WebPDemuxPrevFrame(WebPIterator* iter) {
+ if (iter == NULL) return 0;
+ if (iter->frame_num <= 1) return 0;
+ return SetFrame(iter->frame_num - 1, iter);
+}
+
+void WebPDemuxReleaseIterator(WebPIterator* iter) {
+ (void)iter;
+}
+
+// -----------------------------------------------------------------------------
+// Chunk iteration
+
+static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) {
+ const uint8_t* const mem_buf = dmux->mem_.buf_;
+ const Chunk* c;
+ int count = 0;
+ for (c = dmux->chunks_; c != NULL; c = c->next_) {
+ const uint8_t* const header = mem_buf + c->data_.offset_;
+ if (!memcmp(header, fourcc, TAG_SIZE)) ++count;
+ }
+ return count;
+}
+
+static const Chunk* GetChunk(const WebPDemuxer* const dmux,
+ const char fourcc[4], int chunk_num) {
+ const uint8_t* const mem_buf = dmux->mem_.buf_;
+ const Chunk* c;
+ int count = 0;
+ for (c = dmux->chunks_; c != NULL; c = c->next_) {
+ const uint8_t* const header = mem_buf + c->data_.offset_;
+ if (!memcmp(header, fourcc, TAG_SIZE)) ++count;
+ if (count == chunk_num) break;
+ }
+ return c;
+}
+
+static int SetChunk(const char fourcc[4], int chunk_num,
+ WebPChunkIterator* const iter) {
+ const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
+ int count;
+
+ if (dmux == NULL || fourcc == NULL || chunk_num < 0) return 0;
+ count = ChunkCount(dmux, fourcc);
+ if (count == 0) return 0;
+ if (chunk_num == 0) chunk_num = count;
+
+ if (chunk_num <= count) {
+ const uint8_t* const mem_buf = dmux->mem_.buf_;
+ const Chunk* const chunk = GetChunk(dmux, fourcc, chunk_num);
+ iter->chunk.bytes = mem_buf + chunk->data_.offset_ + CHUNK_HEADER_SIZE;
+ iter->chunk.size = chunk->data_.size_ - CHUNK_HEADER_SIZE;
+ iter->num_chunks = count;
+ iter->chunk_num = chunk_num;
+ return 1;
+ }
+ return 0;
+}
+
+int WebPDemuxGetChunk(const WebPDemuxer* dmux,
+ const char fourcc[4], int chunk_num,
+ WebPChunkIterator* iter) {
+ if (iter == NULL) return 0;
+
+ memset(iter, 0, sizeof(*iter));
+ iter->private_ = (void*)dmux;
+ return SetChunk(fourcc, chunk_num, iter);
+}
+
+int WebPDemuxNextChunk(WebPChunkIterator* iter) {
+ if (iter != NULL) {
+ const char* const fourcc =
+ (const char*)iter->chunk.bytes - CHUNK_HEADER_SIZE;
+ return SetChunk(fourcc, iter->chunk_num + 1, iter);
+ }
+ return 0;
+}
+
+int WebPDemuxPrevChunk(WebPChunkIterator* iter) {
+ if (iter != NULL && iter->chunk_num > 1) {
+ const char* const fourcc =
+ (const char*)iter->chunk.bytes - CHUNK_HEADER_SIZE;
+ return SetChunk(fourcc, iter->chunk_num - 1, iter);
+ }
+ return 0;
+}
+
+void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) {
+ (void)iter;
+}
+
diff --git a/media/libwebp/demux/moz.build b/media/libwebp/demux/moz.build
new file mode 100644
index 000000000..3024a71c3
--- /dev/null
+++ b/media/libwebp/demux/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files('**'):
+ BUG_COMPONENT = ('Core', 'ImageLib')
+
+SOURCES += [
+ 'demux.c',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
diff --git a/media/libwebp/dsp/alpha_processing.c b/media/libwebp/dsp/alpha_processing.c
new file mode 100644
index 000000000..4b60e092b
--- /dev/null
+++ b/media/libwebp/dsp/alpha_processing.c
@@ -0,0 +1,397 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for processing transparent channel.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <assert.h>
+#include "./dsp.h"
+
+// Tables can be faster on some platform but incur some extra binary size (~2k).
+// #define USE_TABLES_FOR_ALPHA_MULT
+
+// -----------------------------------------------------------------------------
+
+#define MFIX 24 // 24bit fixed-point arithmetic
+#define HALF ((1u << MFIX) >> 1)
+#define KINV_255 ((1u << MFIX) / 255u)
+
+static uint32_t Mult(uint8_t x, uint32_t mult) {
+ const uint32_t v = (x * mult + HALF) >> MFIX;
+ assert(v <= 255); // <- 24bit precision is enough to ensure that.
+ return v;
+}
+
+#ifdef USE_TABLES_FOR_ALPHA_MULT
+
+static const uint32_t kMultTables[2][256] = {
+ { // (255u << MFIX) / alpha
+ 0x00000000, 0xff000000, 0x7f800000, 0x55000000, 0x3fc00000, 0x33000000,
+ 0x2a800000, 0x246db6db, 0x1fe00000, 0x1c555555, 0x19800000, 0x172e8ba2,
+ 0x15400000, 0x139d89d8, 0x1236db6d, 0x11000000, 0x0ff00000, 0x0f000000,
+ 0x0e2aaaaa, 0x0d6bca1a, 0x0cc00000, 0x0c249249, 0x0b9745d1, 0x0b1642c8,
+ 0x0aa00000, 0x0a333333, 0x09cec4ec, 0x0971c71c, 0x091b6db6, 0x08cb08d3,
+ 0x08800000, 0x0839ce73, 0x07f80000, 0x07ba2e8b, 0x07800000, 0x07492492,
+ 0x07155555, 0x06e45306, 0x06b5e50d, 0x0689d89d, 0x06600000, 0x063831f3,
+ 0x06124924, 0x05ee23b8, 0x05cba2e8, 0x05aaaaaa, 0x058b2164, 0x056cefa8,
+ 0x05500000, 0x05343eb1, 0x05199999, 0x05000000, 0x04e76276, 0x04cfb2b7,
+ 0x04b8e38e, 0x04a2e8ba, 0x048db6db, 0x0479435e, 0x04658469, 0x045270d0,
+ 0x04400000, 0x042e29f7, 0x041ce739, 0x040c30c3, 0x03fc0000, 0x03ec4ec4,
+ 0x03dd1745, 0x03ce540f, 0x03c00000, 0x03b21642, 0x03a49249, 0x03976fc6,
+ 0x038aaaaa, 0x037e3f1f, 0x03722983, 0x03666666, 0x035af286, 0x034fcace,
+ 0x0344ec4e, 0x033a5440, 0x03300000, 0x0325ed09, 0x031c18f9, 0x0312818a,
+ 0x03092492, 0x03000000, 0x02f711dc, 0x02ee5846, 0x02e5d174, 0x02dd7baf,
+ 0x02d55555, 0x02cd5cd5, 0x02c590b2, 0x02bdef7b, 0x02b677d4, 0x02af286b,
+ 0x02a80000, 0x02a0fd5c, 0x029a1f58, 0x029364d9, 0x028ccccc, 0x0286562d,
+ 0x02800000, 0x0279c952, 0x0273b13b, 0x026db6db, 0x0267d95b, 0x026217ec,
+ 0x025c71c7, 0x0256e62a, 0x0251745d, 0x024c1bac, 0x0246db6d, 0x0241b2f9,
+ 0x023ca1af, 0x0237a6f4, 0x0232c234, 0x022df2df, 0x02293868, 0x02249249,
+ 0x02200000, 0x021b810e, 0x021714fb, 0x0212bb51, 0x020e739c, 0x020a3d70,
+ 0x02061861, 0x02020408, 0x01fe0000, 0x01fa0be8, 0x01f62762, 0x01f25213,
+ 0x01ee8ba2, 0x01ead3ba, 0x01e72a07, 0x01e38e38, 0x01e00000, 0x01dc7f10,
+ 0x01d90b21, 0x01d5a3e9, 0x01d24924, 0x01cefa8d, 0x01cbb7e3, 0x01c880e5,
+ 0x01c55555, 0x01c234f7, 0x01bf1f8f, 0x01bc14e5, 0x01b914c1, 0x01b61eed,
+ 0x01b33333, 0x01b05160, 0x01ad7943, 0x01aaaaaa, 0x01a7e567, 0x01a5294a,
+ 0x01a27627, 0x019fcbd2, 0x019d2a20, 0x019a90e7, 0x01980000, 0x01957741,
+ 0x0192f684, 0x01907da4, 0x018e0c7c, 0x018ba2e8, 0x018940c5, 0x0186e5f0,
+ 0x01849249, 0x018245ae, 0x01800000, 0x017dc11f, 0x017b88ee, 0x0179574e,
+ 0x01772c23, 0x01750750, 0x0172e8ba, 0x0170d045, 0x016ebdd7, 0x016cb157,
+ 0x016aaaaa, 0x0168a9b9, 0x0166ae6a, 0x0164b8a7, 0x0162c859, 0x0160dd67,
+ 0x015ef7bd, 0x015d1745, 0x015b3bea, 0x01596596, 0x01579435, 0x0155c7b4,
+ 0x01540000, 0x01523d03, 0x01507eae, 0x014ec4ec, 0x014d0fac, 0x014b5edc,
+ 0x0149b26c, 0x01480a4a, 0x01466666, 0x0144c6af, 0x01432b16, 0x0141938b,
+ 0x01400000, 0x013e7063, 0x013ce4a9, 0x013b5cc0, 0x0139d89d, 0x01385830,
+ 0x0136db6d, 0x01356246, 0x0133ecad, 0x01327a97, 0x01310bf6, 0x012fa0be,
+ 0x012e38e3, 0x012cd459, 0x012b7315, 0x012a150a, 0x0128ba2e, 0x01276276,
+ 0x01260dd6, 0x0124bc44, 0x01236db6, 0x01222222, 0x0120d97c, 0x011f93bc,
+ 0x011e50d7, 0x011d10c4, 0x011bd37a, 0x011a98ef, 0x0119611a, 0x01182bf2,
+ 0x0116f96f, 0x0115c988, 0x01149c34, 0x0113716a, 0x01124924, 0x01112358,
+ 0x01100000, 0x010edf12, 0x010dc087, 0x010ca458, 0x010b8a7d, 0x010a72f0,
+ 0x01095da8, 0x01084a9f, 0x010739ce, 0x01062b2e, 0x01051eb8, 0x01041465,
+ 0x01030c30, 0x01020612, 0x01010204, 0x01000000 },
+ { // alpha * KINV_255
+ 0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505,
+ 0x00060606, 0x00070707, 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b,
+ 0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, 0x00101010, 0x00111111,
+ 0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717,
+ 0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d,
+ 0x001e1e1e, 0x001f1f1f, 0x00202020, 0x00212121, 0x00222222, 0x00232323,
+ 0x00242424, 0x00252525, 0x00262626, 0x00272727, 0x00282828, 0x00292929,
+ 0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f,
+ 0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535,
+ 0x00363636, 0x00373737, 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b,
+ 0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, 0x00404040, 0x00414141,
+ 0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747,
+ 0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d,
+ 0x004e4e4e, 0x004f4f4f, 0x00505050, 0x00515151, 0x00525252, 0x00535353,
+ 0x00545454, 0x00555555, 0x00565656, 0x00575757, 0x00585858, 0x00595959,
+ 0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f,
+ 0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565,
+ 0x00666666, 0x00676767, 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b,
+ 0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, 0x00707070, 0x00717171,
+ 0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777,
+ 0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d,
+ 0x007e7e7e, 0x007f7f7f, 0x00808080, 0x00818181, 0x00828282, 0x00838383,
+ 0x00848484, 0x00858585, 0x00868686, 0x00878787, 0x00888888, 0x00898989,
+ 0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f,
+ 0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595,
+ 0x00969696, 0x00979797, 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b,
+ 0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, 0x00a0a0a0, 0x00a1a1a1,
+ 0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7,
+ 0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad,
+ 0x00aeaeae, 0x00afafaf, 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3,
+ 0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, 0x00b8b8b8, 0x00b9b9b9,
+ 0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf,
+ 0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5,
+ 0x00c6c6c6, 0x00c7c7c7, 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb,
+ 0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, 0x00d0d0d0, 0x00d1d1d1,
+ 0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7,
+ 0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd,
+ 0x00dedede, 0x00dfdfdf, 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3,
+ 0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, 0x00e8e8e8, 0x00e9e9e9,
+ 0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef,
+ 0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5,
+ 0x00f6f6f6, 0x00f7f7f7, 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb,
+ 0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff }
+};
+
+static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
+ return kMultTables[!inverse][a];
+}
+
+#else
+
+static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
+ return inverse ? (255u << MFIX) / a : a * KINV_255;
+}
+
+#endif // USE_TABLES_FOR_ALPHA_MULT
+
+void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse) {
+ int x;
+ for (x = 0; x < width; ++x) {
+ const uint32_t argb = ptr[x];
+ if (argb < 0xff000000u) { // alpha < 255
+ if (argb <= 0x00ffffffu) { // alpha == 0
+ ptr[x] = 0;
+ } else {
+ const uint32_t alpha = (argb >> 24) & 0xff;
+ const uint32_t scale = GetScale(alpha, inverse);
+ uint32_t out = argb & 0xff000000u;
+ out |= Mult(argb >> 0, scale) << 0;
+ out |= Mult(argb >> 8, scale) << 8;
+ out |= Mult(argb >> 16, scale) << 16;
+ ptr[x] = out;
+ }
+ }
+ }
+}
+
+void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
+ int width, int inverse) {
+ int x;
+ for (x = 0; x < width; ++x) {
+ const uint32_t a = alpha[x];
+ if (a != 255) {
+ if (a == 0) {
+ ptr[x] = 0;
+ } else {
+ const uint32_t scale = GetScale(a, inverse);
+ ptr[x] = Mult(ptr[x], scale);
+ }
+ }
+ }
+}
+
+#undef KINV_255
+#undef HALF
+#undef MFIX
+
+void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
+void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
+ int width, int inverse);
+
+//------------------------------------------------------------------------------
+// Generic per-plane calls
+
+void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
+ int inverse) {
+ int n;
+ for (n = 0; n < num_rows; ++n) {
+ WebPMultARGBRow((uint32_t*)ptr, width, inverse);
+ ptr += stride;
+ }
+}
+
+void WebPMultRows(uint8_t* ptr, int stride,
+ const uint8_t* alpha, int alpha_stride,
+ int width, int num_rows, int inverse) {
+ int n;
+ for (n = 0; n < num_rows; ++n) {
+ WebPMultRow(ptr, alpha, width, inverse);
+ ptr += stride;
+ alpha += alpha_stride;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Premultiplied modes
+
+// non dithered-modes
+
+// (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.)
+// for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5),
+// one can use instead: (x * a * 65793 + (1 << 23)) >> 24
+#if 1 // (int)(x * a / 255.)
+#define MULTIPLIER(a) ((a) * 32897U)
+#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
+#else // (int)(x * a / 255. + .5)
+#define MULTIPLIER(a) ((a) * 65793U)
+#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24)
+#endif
+
+static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
+ int w, int h, int stride) {
+ while (h-- > 0) {
+ uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
+ const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
+ int i;
+ for (i = 0; i < w; ++i) {
+ const uint32_t a = alpha[4 * i];
+ if (a != 0xff) {
+ const uint32_t mult = MULTIPLIER(a);
+ rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
+ rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
+ rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
+ }
+ }
+ rgba += stride;
+ }
+}
+#undef MULTIPLIER
+#undef PREMULTIPLY
+
+// rgbA4444
+
+#define MULTIPLIER(a) ((a) * 0x1111) // 0x1111 ~= (1 << 16) / 15
+
+static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
+ return (x & 0xf0) | (x >> 4);
+}
+
+static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
+ return (x & 0x0f) | (x << 4);
+}
+
+static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
+ return (x * m) >> 16;
+}
+
+static WEBP_INLINE void ApplyAlphaMultiply4444(uint8_t* rgba4444,
+ int w, int h, int stride,
+ int rg_byte_pos /* 0 or 1 */) {
+ while (h-- > 0) {
+ int i;
+ for (i = 0; i < w; ++i) {
+ const uint32_t rg = rgba4444[2 * i + rg_byte_pos];
+ const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)];
+ const uint8_t a = ba & 0x0f;
+ const uint32_t mult = MULTIPLIER(a);
+ const uint8_t r = multiply(dither_hi(rg), mult);
+ const uint8_t g = multiply(dither_lo(rg), mult);
+ const uint8_t b = multiply(dither_hi(ba), mult);
+ rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f);
+ rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a;
+ }
+ rgba4444 += stride;
+ }
+}
+#undef MULTIPLIER
+
+static void ApplyAlphaMultiply_16b(uint8_t* rgba4444,
+ int w, int h, int stride) {
+#ifdef WEBP_SWAP_16BIT_CSP
+ ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1);
+#else
+ ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0);
+#endif
+}
+
+static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
+ int width, int height,
+ uint8_t* dst, int dst_stride) {
+ uint32_t alpha_mask = 0xff;
+ int i, j;
+
+ for (j = 0; j < height; ++j) {
+ for (i = 0; i < width; ++i) {
+ const uint32_t alpha_value = alpha[i];
+ dst[4 * i] = alpha_value;
+ alpha_mask &= alpha_value;
+ }
+ alpha += alpha_stride;
+ dst += dst_stride;
+ }
+
+ return (alpha_mask != 0xff);
+}
+
+static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
+ int width, int height,
+ uint32_t* dst, int dst_stride) {
+ int i, j;
+ for (j = 0; j < height; ++j) {
+ for (i = 0; i < width; ++i) {
+ dst[i] = alpha[i] << 8; // leave A/R/B channels zero'd.
+ }
+ alpha += alpha_stride;
+ dst += dst_stride;
+ }
+}
+
+static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
+ int width, int height,
+ uint8_t* alpha, int alpha_stride) {
+ uint8_t alpha_mask = 0xff;
+ int i, j;
+
+ for (j = 0; j < height; ++j) {
+ for (i = 0; i < width; ++i) {
+ const uint8_t alpha_value = argb[4 * i];
+ alpha[i] = alpha_value;
+ alpha_mask &= alpha_value;
+ }
+ argb += argb_stride;
+ alpha += alpha_stride;
+ }
+ return (alpha_mask == 0xff);
+}
+
+static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
+ int i;
+ for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
+}
+
+void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
+void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
+int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
+void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
+int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
+void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
+
+//------------------------------------------------------------------------------
+// Init function
+
+extern void WebPInitAlphaProcessingMIPSdspR2(void);
+extern void WebPInitAlphaProcessingSSE2(void);
+extern void WebPInitAlphaProcessingSSE41(void);
+extern void WebPInitAlphaProcessingNEON(void);
+
+static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
+ (VP8CPUInfo)&alpha_processing_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
+ if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ WebPMultARGBRow = WebPMultARGBRowC;
+ WebPMultRow = WebPMultRowC;
+ WebPApplyAlphaMultiply = ApplyAlphaMultiply;
+ WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b;
+
+ WebPDispatchAlpha = DispatchAlpha_C;
+ WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C;
+ WebPExtractAlpha = ExtractAlpha_C;
+ WebPExtractGreen = ExtractGreen_C;
+
+ // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ WebPInitAlphaProcessingSSE2();
+#if defined(WEBP_USE_SSE41)
+ if (VP8GetCPUInfo(kSSE4_1)) {
+ WebPInitAlphaProcessingSSE41();
+ }
+#endif
+ }
+#endif
+#if defined(WEBP_USE_NEON)
+ if (VP8GetCPUInfo(kNEON)) {
+ WebPInitAlphaProcessingNEON();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ WebPInitAlphaProcessingMIPSdspR2();
+ }
+#endif
+ }
+ alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/media/libwebp/dsp/alpha_processing_sse2.c b/media/libwebp/dsp/alpha_processing_sse2.c
new file mode 100644
index 000000000..83dc559fa
--- /dev/null
+++ b/media/libwebp/dsp/alpha_processing_sse2.c
@@ -0,0 +1,285 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for processing transparent channel.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <emmintrin.h>
+
+//------------------------------------------------------------------------------
+
+static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
+ int width, int height,
+ uint8_t* dst, int dst_stride) {
+ // alpha_and stores an 'and' operation of all the alpha[] values. The final
+ // value is not 0xff if any of the alpha[] is not equal to 0xff.
+ uint32_t alpha_and = 0xff;
+ int i, j;
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u); // to preserve RGB
+ const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+ __m128i all_alphas = all_0xff;
+
+ // We must be able to access 3 extra bytes after the last written byte
+ // 'dst[4 * width - 4]', because we don't know if alpha is the first or the
+ // last byte of the quadruplet.
+ const int limit = (width - 1) & ~7;
+
+ for (j = 0; j < height; ++j) {
+ __m128i* out = (__m128i*)dst;
+ for (i = 0; i < limit; i += 8) {
+ // load 8 alpha bytes
+ const __m128i a0 = _mm_loadl_epi64((const __m128i*)&alpha[i]);
+ const __m128i a1 = _mm_unpacklo_epi8(a0, zero);
+ const __m128i a2_lo = _mm_unpacklo_epi16(a1, zero);
+ const __m128i a2_hi = _mm_unpackhi_epi16(a1, zero);
+ // load 8 dst pixels (32 bytes)
+ const __m128i b0_lo = _mm_loadu_si128(out + 0);
+ const __m128i b0_hi = _mm_loadu_si128(out + 1);
+ // mask dst alpha values
+ const __m128i b1_lo = _mm_and_si128(b0_lo, rgb_mask);
+ const __m128i b1_hi = _mm_and_si128(b0_hi, rgb_mask);
+ // combine
+ const __m128i b2_lo = _mm_or_si128(b1_lo, a2_lo);
+ const __m128i b2_hi = _mm_or_si128(b1_hi, a2_hi);
+ // store
+ _mm_storeu_si128(out + 0, b2_lo);
+ _mm_storeu_si128(out + 1, b2_hi);
+ // accumulate eight alpha 'and' in parallel
+ all_alphas = _mm_and_si128(all_alphas, a0);
+ out += 2;
+ }
+ for (; i < width; ++i) {
+ const uint32_t alpha_value = alpha[i];
+ dst[4 * i] = alpha_value;
+ alpha_and &= alpha_value;
+ }
+ alpha += alpha_stride;
+ dst += dst_stride;
+ }
+ // Combine the eight alpha 'and' into a 8-bit mask.
+ alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff));
+ return (alpha_and != 0xff);
+}
+
+static void DispatchAlphaToGreen(const uint8_t* alpha, int alpha_stride,
+ int width, int height,
+ uint32_t* dst, int dst_stride) {
+ int i, j;
+ const __m128i zero = _mm_setzero_si128();
+ const int limit = width & ~15;
+ for (j = 0; j < height; ++j) {
+ for (i = 0; i < limit; i += 16) { // process 16 alpha bytes
+ const __m128i a0 = _mm_loadu_si128((const __m128i*)&alpha[i]);
+ const __m128i a1 = _mm_unpacklo_epi8(zero, a0); // note the 'zero' first!
+ const __m128i b1 = _mm_unpackhi_epi8(zero, a0);
+ const __m128i a2_lo = _mm_unpacklo_epi16(a1, zero);
+ const __m128i b2_lo = _mm_unpacklo_epi16(b1, zero);
+ const __m128i a2_hi = _mm_unpackhi_epi16(a1, zero);
+ const __m128i b2_hi = _mm_unpackhi_epi16(b1, zero);
+ _mm_storeu_si128((__m128i*)&dst[i + 0], a2_lo);
+ _mm_storeu_si128((__m128i*)&dst[i + 4], a2_hi);
+ _mm_storeu_si128((__m128i*)&dst[i + 8], b2_lo);
+ _mm_storeu_si128((__m128i*)&dst[i + 12], b2_hi);
+ }
+ for (; i < width; ++i) dst[i] = alpha[i] << 8;
+ alpha += alpha_stride;
+ dst += dst_stride;
+ }
+}
+
+static int ExtractAlpha(const uint8_t* argb, int argb_stride,
+ int width, int height,
+ uint8_t* alpha, int alpha_stride) {
+ // alpha_and stores an 'and' operation of all the alpha[] values. The final
+ // value is not 0xff if any of the alpha[] is not equal to 0xff.
+ uint32_t alpha_and = 0xff;
+ int i, j;
+ const __m128i a_mask = _mm_set1_epi32(0xffu); // to preserve alpha
+ const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+ __m128i all_alphas = all_0xff;
+
+ // We must be able to access 3 extra bytes after the last written byte
+ // 'src[4 * width - 4]', because we don't know if alpha is the first or the
+ // last byte of the quadruplet.
+ const int limit = (width - 1) & ~7;
+
+ for (j = 0; j < height; ++j) {
+ const __m128i* src = (const __m128i*)argb;
+ for (i = 0; i < limit; i += 8) {
+ // load 32 argb bytes
+ const __m128i a0 = _mm_loadu_si128(src + 0);
+ const __m128i a1 = _mm_loadu_si128(src + 1);
+ const __m128i b0 = _mm_and_si128(a0, a_mask);
+ const __m128i b1 = _mm_and_si128(a1, a_mask);
+ const __m128i c0 = _mm_packs_epi32(b0, b1);
+ const __m128i d0 = _mm_packus_epi16(c0, c0);
+ // store
+ _mm_storel_epi64((__m128i*)&alpha[i], d0);
+ // accumulate eight alpha 'and' in parallel
+ all_alphas = _mm_and_si128(all_alphas, d0);
+ src += 2;
+ }
+ for (; i < width; ++i) {
+ const uint32_t alpha_value = argb[4 * i];
+ alpha[i] = alpha_value;
+ alpha_and &= alpha_value;
+ }
+ argb += argb_stride;
+ alpha += alpha_stride;
+ }
+ // Combine the eight alpha 'and' into a 8-bit mask.
+ alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff));
+ return (alpha_and == 0xff);
+}
+
+//------------------------------------------------------------------------------
+// Non-dither premultiplied modes
+
+#define MULTIPLIER(a) ((a) * 0x8081)
+#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
+
+// We can't use a 'const int' for the SHUFFLE value, because it has to be an
+// immediate in the _mm_shufflexx_epi16() instruction. We really need a macro.
+// We use: v / 255 = (v * 0x8081) >> 23, where v = alpha * {r,g,b} is a 16bit
+// value.
+#define APPLY_ALPHA(RGBX, SHUFFLE) do { \
+ const __m128i argb0 = _mm_loadu_si128((const __m128i*)&(RGBX)); \
+ const __m128i argb1_lo = _mm_unpacklo_epi8(argb0, zero); \
+ const __m128i argb1_hi = _mm_unpackhi_epi8(argb0, zero); \
+ const __m128i alpha0_lo = _mm_or_si128(argb1_lo, kMask); \
+ const __m128i alpha0_hi = _mm_or_si128(argb1_hi, kMask); \
+ const __m128i alpha1_lo = _mm_shufflelo_epi16(alpha0_lo, SHUFFLE); \
+ const __m128i alpha1_hi = _mm_shufflelo_epi16(alpha0_hi, SHUFFLE); \
+ const __m128i alpha2_lo = _mm_shufflehi_epi16(alpha1_lo, SHUFFLE); \
+ const __m128i alpha2_hi = _mm_shufflehi_epi16(alpha1_hi, SHUFFLE); \
+ /* alpha2 = [ff a0 a0 a0][ff a1 a1 a1] */ \
+ const __m128i A0_lo = _mm_mullo_epi16(alpha2_lo, argb1_lo); \
+ const __m128i A0_hi = _mm_mullo_epi16(alpha2_hi, argb1_hi); \
+ const __m128i A1_lo = _mm_mulhi_epu16(A0_lo, kMult); \
+ const __m128i A1_hi = _mm_mulhi_epu16(A0_hi, kMult); \
+ const __m128i A2_lo = _mm_srli_epi16(A1_lo, 7); \
+ const __m128i A2_hi = _mm_srli_epi16(A1_hi, 7); \
+ const __m128i A3 = _mm_packus_epi16(A2_lo, A2_hi); \
+ _mm_storeu_si128((__m128i*)&(RGBX), A3); \
+} while (0)
+
+static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
+ int w, int h, int stride) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i kMult = _mm_set1_epi16(0x8081u);
+ const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0);
+ const int kSpan = 4;
+ while (h-- > 0) {
+ uint32_t* const rgbx = (uint32_t*)rgba;
+ int i;
+ if (!alpha_first) {
+ for (i = 0; i + kSpan <= w; i += kSpan) {
+ APPLY_ALPHA(rgbx[i], _MM_SHUFFLE(2, 3, 3, 3));
+ }
+ } else {
+ for (i = 0; i + kSpan <= w; i += kSpan) {
+ APPLY_ALPHA(rgbx[i], _MM_SHUFFLE(0, 0, 0, 1));
+ }
+ }
+ // Finish with left-overs.
+ for (; i < w; ++i) {
+ uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
+ const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
+ const uint32_t a = alpha[4 * i];
+ if (a != 0xff) {
+ const uint32_t mult = MULTIPLIER(a);
+ rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
+ rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
+ rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
+ }
+ }
+ rgba += stride;
+ }
+}
+#undef MULTIPLIER
+#undef PREMULTIPLY
+
+// -----------------------------------------------------------------------------
+// Apply alpha value to rows
+
+static void MultARGBRow_SSE2(uint32_t* const ptr, int width, int inverse) {
+ int x = 0;
+ if (!inverse) {
+ const int kSpan = 2;
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i k128 = _mm_set1_epi16(128);
+ const __m128i kMult = _mm_set1_epi16(0x0101);
+ const __m128i kMask = _mm_set_epi16(0, 0xff, 0, 0, 0, 0xff, 0, 0);
+ for (x = 0; x + kSpan <= width; x += kSpan) {
+ // To compute 'result = (int)(a * x / 255. + .5)', we use:
+ // tmp = a * v + 128, result = (tmp * 0x0101u) >> 16
+ const __m128i A0 = _mm_loadl_epi64((const __m128i*)&ptr[x]);
+ const __m128i A1 = _mm_unpacklo_epi8(A0, zero);
+ const __m128i A2 = _mm_or_si128(A1, kMask);
+ const __m128i A3 = _mm_shufflelo_epi16(A2, _MM_SHUFFLE(2, 3, 3, 3));
+ const __m128i A4 = _mm_shufflehi_epi16(A3, _MM_SHUFFLE(2, 3, 3, 3));
+ // here, A4 = [ff a0 a0 a0][ff a1 a1 a1]
+ const __m128i A5 = _mm_mullo_epi16(A4, A1);
+ const __m128i A6 = _mm_add_epi16(A5, k128);
+ const __m128i A7 = _mm_mulhi_epu16(A6, kMult);
+ const __m128i A10 = _mm_packus_epi16(A7, zero);
+ _mm_storel_epi64((__m128i*)&ptr[x], A10);
+ }
+ }
+ width -= x;
+ if (width > 0) WebPMultARGBRowC(ptr + x, width, inverse);
+}
+
+static void MultRow_SSE2(uint8_t* const ptr, const uint8_t* const alpha,
+ int width, int inverse) {
+ int x = 0;
+ if (!inverse) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i k128 = _mm_set1_epi16(128);
+ const __m128i kMult = _mm_set1_epi16(0x0101);
+ for (x = 0; x + 8 <= width; x += 8) {
+ const __m128i v0 = _mm_loadl_epi64((__m128i*)&ptr[x]);
+ const __m128i a0 = _mm_loadl_epi64((const __m128i*)&alpha[x]);
+ const __m128i v1 = _mm_unpacklo_epi8(v0, zero);
+ const __m128i a1 = _mm_unpacklo_epi8(a0, zero);
+ const __m128i v2 = _mm_mullo_epi16(v1, a1);
+ const __m128i v3 = _mm_add_epi16(v2, k128);
+ const __m128i v4 = _mm_mulhi_epu16(v3, kMult);
+ const __m128i v5 = _mm_packus_epi16(v4, zero);
+ _mm_storel_epi64((__m128i*)&ptr[x], v5);
+ }
+ }
+ width -= x;
+ if (width > 0) WebPMultRowC(ptr + x, alpha + x, width, inverse);
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void WebPInitAlphaProcessingSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
+ WebPMultARGBRow = MultARGBRow_SSE2;
+ WebPMultRow = MultRow_SSE2;
+ WebPApplyAlphaMultiply = ApplyAlphaMultiply_SSE2;
+ WebPDispatchAlpha = DispatchAlpha;
+ WebPDispatchAlphaToGreen = DispatchAlphaToGreen;
+ WebPExtractAlpha = ExtractAlpha;
+}
+
+#else // !WEBP_USE_SSE2
+
+WEBP_DSP_INIT_STUB(WebPInitAlphaProcessingSSE2)
+
+#endif // WEBP_USE_SSE2
diff --git a/media/libwebp/dsp/alpha_processing_sse41.c b/media/libwebp/dsp/alpha_processing_sse41.c
new file mode 100644
index 000000000..986fde94e
--- /dev/null
+++ b/media/libwebp/dsp/alpha_processing_sse41.c
@@ -0,0 +1,92 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for processing transparent channel, SSE4.1 variant.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE41)
+
+#include <smmintrin.h>
+
+//------------------------------------------------------------------------------
+
+static int ExtractAlpha(const uint8_t* argb, int argb_stride,
+ int width, int height,
+ uint8_t* alpha, int alpha_stride) {
+ // alpha_and stores an 'and' operation of all the alpha[] values. The final
+ // value is not 0xff if any of the alpha[] is not equal to 0xff.
+ uint32_t alpha_and = 0xff;
+ int i, j;
+ const __m128i all_0xff = _mm_set1_epi32(~0u);
+ __m128i all_alphas = all_0xff;
+
+ // We must be able to access 3 extra bytes after the last written byte
+ // 'src[4 * width - 4]', because we don't know if alpha is the first or the
+ // last byte of the quadruplet.
+ const int limit = (width - 1) & ~15;
+ const __m128i kCstAlpha0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 12, 8, 4, 0);
+ const __m128i kCstAlpha1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1,
+ 12, 8, 4, 0, -1, -1, -1, -1);
+ const __m128i kCstAlpha2 = _mm_set_epi8(-1, -1, -1, -1, 12, 8, 4, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1);
+ const __m128i kCstAlpha3 = _mm_set_epi8(12, 8, 4, 0, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1);
+ for (j = 0; j < height; ++j) {
+ const __m128i* src = (const __m128i*)argb;
+ for (i = 0; i < limit; i += 16) {
+ // load 64 argb bytes
+ const __m128i a0 = _mm_loadu_si128(src + 0);
+ const __m128i a1 = _mm_loadu_si128(src + 1);
+ const __m128i a2 = _mm_loadu_si128(src + 2);
+ const __m128i a3 = _mm_loadu_si128(src + 3);
+ const __m128i b0 = _mm_shuffle_epi8(a0, kCstAlpha0);
+ const __m128i b1 = _mm_shuffle_epi8(a1, kCstAlpha1);
+ const __m128i b2 = _mm_shuffle_epi8(a2, kCstAlpha2);
+ const __m128i b3 = _mm_shuffle_epi8(a3, kCstAlpha3);
+ const __m128i c0 = _mm_or_si128(b0, b1);
+ const __m128i c1 = _mm_or_si128(b2, b3);
+ const __m128i d0 = _mm_or_si128(c0, c1);
+ // store
+ _mm_storeu_si128((__m128i*)&alpha[i], d0);
+ // accumulate sixteen alpha 'and' in parallel
+ all_alphas = _mm_and_si128(all_alphas, d0);
+ src += 4;
+ }
+ for (; i < width; ++i) {
+ const uint32_t alpha_value = argb[4 * i];
+ alpha[i] = alpha_value;
+ alpha_and &= alpha_value;
+ }
+ argb += argb_stride;
+ alpha += alpha_stride;
+ }
+ // Combine the sixteen alpha 'and' into an 8-bit mask.
+ alpha_and |= 0xff00u; // pretend the upper bits [8..15] were tested ok.
+ alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff));
+ return (alpha_and == 0xffffu);
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void WebPInitAlphaProcessingSSE41(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE41(void) {
+ WebPExtractAlpha = ExtractAlpha;
+}
+
+#else // !WEBP_USE_SSE41
+
+WEBP_DSP_INIT_STUB(WebPInitAlphaProcessingSSE41)
+
+#endif // WEBP_USE_SSE41
diff --git a/media/libwebp/dsp/common_sse2.h b/media/libwebp/dsp/common_sse2.h
new file mode 100644
index 000000000..995d7cf4e
--- /dev/null
+++ b/media/libwebp/dsp/common_sse2.h
@@ -0,0 +1,194 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 code common to several files.
+//
+// Author: Vincent Rabaud (vrabaud@google.com)
+
+#ifndef WEBP_DSP_COMMON_SSE2_H_
+#define WEBP_DSP_COMMON_SSE2_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(WEBP_USE_SSE2)
+
+#include <emmintrin.h>
+
+//------------------------------------------------------------------------------
+// Quite useful macro for debugging. Left here for convenience.
+
+#if 0
+#include <stdio.h>
+static WEBP_INLINE void PrintReg(const __m128i r, const char* const name,
+ int size) {
+ int n;
+ union {
+ __m128i r;
+ uint8_t i8[16];
+ uint16_t i16[8];
+ uint32_t i32[4];
+ uint64_t i64[2];
+ } tmp;
+ tmp.r = r;
+ fprintf(stderr, "%s\t: ", name);
+ if (size == 8) {
+ for (n = 0; n < 16; ++n) fprintf(stderr, "%.2x ", tmp.i8[n]);
+ } else if (size == 16) {
+ for (n = 0; n < 8; ++n) fprintf(stderr, "%.4x ", tmp.i16[n]);
+ } else if (size == 32) {
+ for (n = 0; n < 4; ++n) fprintf(stderr, "%.8x ", tmp.i32[n]);
+ } else {
+ for (n = 0; n < 2; ++n) fprintf(stderr, "%.16lx ", tmp.i64[n]);
+ }
+ fprintf(stderr, "\n");
+}
+#endif
+
+//------------------------------------------------------------------------------
+// Math functions.
+
+// Return the sum of all the 8b in the register.
+static WEBP_INLINE int VP8HorizontalAdd8b(const __m128i* const a) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i sad8x2 = _mm_sad_epu8(*a, zero);
+ // sum the two sads: sad8x2[0:1] + sad8x2[8:9]
+ const __m128i sum = _mm_add_epi32(sad8x2, _mm_shuffle_epi32(sad8x2, 2));
+ return _mm_cvtsi128_si32(sum);
+}
+
+// Transpose two 4x4 16b matrices horizontally stored in registers.
+static WEBP_INLINE void VP8Transpose_2_4x4_16b(
+ const __m128i* const in0, const __m128i* const in1,
+ const __m128i* const in2, const __m128i* const in3, __m128i* const out0,
+ __m128i* const out1, __m128i* const out2, __m128i* const out3) {
+ // Transpose the two 4x4.
+ // a00 a01 a02 a03 b00 b01 b02 b03
+ // a10 a11 a12 a13 b10 b11 b12 b13
+ // a20 a21 a22 a23 b20 b21 b22 b23
+ // a30 a31 a32 a33 b30 b31 b32 b33
+ const __m128i transpose0_0 = _mm_unpacklo_epi16(*in0, *in1);
+ const __m128i transpose0_1 = _mm_unpacklo_epi16(*in2, *in3);
+ const __m128i transpose0_2 = _mm_unpackhi_epi16(*in0, *in1);
+ const __m128i transpose0_3 = _mm_unpackhi_epi16(*in2, *in3);
+ // a00 a10 a01 a11 a02 a12 a03 a13
+ // a20 a30 a21 a31 a22 a32 a23 a33
+ // b00 b10 b01 b11 b02 b12 b03 b13
+ // b20 b30 b21 b31 b22 b32 b23 b33
+ const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
+ const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
+ const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
+ const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
+ // a00 a10 a20 a30 a01 a11 a21 a31
+ // b00 b10 b20 b30 b01 b11 b21 b31
+ // a02 a12 a22 a32 a03 a13 a23 a33
+ // b02 b12 a22 b32 b03 b13 b23 b33
+ *out0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
+ *out1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
+ *out2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
+ *out3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
+ // a00 a10 a20 a30 b00 b10 b20 b30
+ // a01 a11 a21 a31 b01 b11 b21 b31
+ // a02 a12 a22 a32 b02 b12 b22 b32
+ // a03 a13 a23 a33 b03 b13 b23 b33
+}
+
+//------------------------------------------------------------------------------
+// Channel mixing.
+
+// Function used several times in VP8PlanarTo24b.
+// It samples the in buffer as follows: one every two unsigned char is stored
+// at the beginning of the buffer, while the other half is stored at the end.
+#define VP8PlanarTo24bHelper(IN, OUT) \
+ do { \
+ const __m128i v_mask = _mm_set1_epi16(0x00ff); \
+ /* Take one every two upper 8b values.*/ \
+ (OUT##0) = _mm_packus_epi16(_mm_and_si128((IN##0), v_mask), \
+ _mm_and_si128((IN##1), v_mask)); \
+ (OUT##1) = _mm_packus_epi16(_mm_and_si128((IN##2), v_mask), \
+ _mm_and_si128((IN##3), v_mask)); \
+ (OUT##2) = _mm_packus_epi16(_mm_and_si128((IN##4), v_mask), \
+ _mm_and_si128((IN##5), v_mask)); \
+ /* Take one every two lower 8b values.*/ \
+ (OUT##3) = _mm_packus_epi16(_mm_srli_epi16((IN##0), 8), \
+ _mm_srli_epi16((IN##1), 8)); \
+ (OUT##4) = _mm_packus_epi16(_mm_srli_epi16((IN##2), 8), \
+ _mm_srli_epi16((IN##3), 8)); \
+ (OUT##5) = _mm_packus_epi16(_mm_srli_epi16((IN##4), 8), \
+ _mm_srli_epi16((IN##5), 8)); \
+ } while (0)
+
+// Pack the planar buffers
+// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
+// triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ...
+static WEBP_INLINE void VP8PlanarTo24b(__m128i* const in0, __m128i* const in1,
+ __m128i* const in2, __m128i* const in3,
+ __m128i* const in4, __m128i* const in5) {
+ // The input is 6 registers of sixteen 8b but for the sake of explanation,
+ // let's take 6 registers of four 8b values.
+ // To pack, we will keep taking one every two 8b integer and move it
+ // around as follows:
+ // Input:
+ // r0r1r2r3 | r4r5r6r7 | g0g1g2g3 | g4g5g6g7 | b0b1b2b3 | b4b5b6b7
+ // Split the 6 registers in two sets of 3 registers: the first set as the even
+ // 8b bytes, the second the odd ones:
+ // r0r2r4r6 | g0g2g4g6 | b0b2b4b6 | r1r3r5r7 | g1g3g5g7 | b1b3b5b7
+ // Repeat the same permutations twice more:
+ // r0r4g0g4 | b0b4r1r5 | g1g5b1b5 | r2r6g2g6 | b2b6r3r7 | g3g7b3b7
+ // r0g0b0r1 | g1b1r2g2 | b2r3g3b3 | r4g4b4r5 | g5b5r6g6 | b6r7g7b7
+ __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
+ VP8PlanarTo24bHelper(*in, tmp);
+ VP8PlanarTo24bHelper(tmp, *in);
+ VP8PlanarTo24bHelper(*in, tmp);
+ // We need to do it two more times than the example as we have sixteen bytes.
+ {
+ __m128i out0, out1, out2, out3, out4, out5;
+ VP8PlanarTo24bHelper(tmp, out);
+ VP8PlanarTo24bHelper(out, *in);
+ }
+}
+
+#undef VP8PlanarTo24bHelper
+
+// Convert four packed four-channel buffers like argbargbargbargb... into the
+// split channels aaaaa ... rrrr ... gggg .... bbbbb ......
+static WEBP_INLINE void VP8L32bToPlanar(__m128i* const in0,
+ __m128i* const in1,
+ __m128i* const in2,
+ __m128i* const in3) {
+ // Column-wise transpose.
+ const __m128i A0 = _mm_unpacklo_epi8(*in0, *in1);
+ const __m128i A1 = _mm_unpackhi_epi8(*in0, *in1);
+ const __m128i A2 = _mm_unpacklo_epi8(*in2, *in3);
+ const __m128i A3 = _mm_unpackhi_epi8(*in2, *in3);
+ const __m128i B0 = _mm_unpacklo_epi8(A0, A1);
+ const __m128i B1 = _mm_unpackhi_epi8(A0, A1);
+ const __m128i B2 = _mm_unpacklo_epi8(A2, A3);
+ const __m128i B3 = _mm_unpackhi_epi8(A2, A3);
+ // C0 = g7 g6 ... g1 g0 | b7 b6 ... b1 b0
+ // C1 = a7 a6 ... a1 a0 | r7 r6 ... r1 r0
+ const __m128i C0 = _mm_unpacklo_epi8(B0, B1);
+ const __m128i C1 = _mm_unpackhi_epi8(B0, B1);
+ const __m128i C2 = _mm_unpacklo_epi8(B2, B3);
+ const __m128i C3 = _mm_unpackhi_epi8(B2, B3);
+ // Gather the channels.
+ *in0 = _mm_unpackhi_epi64(C1, C3);
+ *in1 = _mm_unpacklo_epi64(C1, C3);
+ *in2 = _mm_unpackhi_epi64(C0, C2);
+ *in3 = _mm_unpacklo_epi64(C0, C2);
+}
+
+#endif // WEBP_USE_SSE2
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WEBP_DSP_COMMON_SSE2_H_
diff --git a/media/libwebp/dsp/dec.c b/media/libwebp/dsp/dec.c
new file mode 100644
index 000000000..007e985d8
--- /dev/null
+++ b/media/libwebp/dsp/dec.c
@@ -0,0 +1,795 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical decoding functions, default plain-C implementations.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+#include "../dec/vp8i_dec.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE uint8_t clip_8b(int v) {
+ return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
+}
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+#define STORE(x, y, v) \
+ dst[x + y * BPS] = clip_8b(dst[x + y * BPS] + ((v) >> 3))
+
+#define STORE2(y, dc, d, c) do { \
+ const int DC = (dc); \
+ STORE(0, y, DC + (d)); \
+ STORE(1, y, DC + (c)); \
+ STORE(2, y, DC - (c)); \
+ STORE(3, y, DC - (d)); \
+} while (0)
+
+#define MUL1(a) ((((a) * 20091) >> 16) + (a))
+#define MUL2(a) (((a) * 35468) >> 16)
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+ int C[4 * 4], *tmp;
+ int i;
+ tmp = C;
+ for (i = 0; i < 4; ++i) { // vertical pass
+ const int a = in[0] + in[8]; // [-4096, 4094]
+ const int b = in[0] - in[8]; // [-4095, 4095]
+ const int c = MUL2(in[4]) - MUL1(in[12]); // [-3783, 3783]
+ const int d = MUL1(in[4]) + MUL2(in[12]); // [-3785, 3781]
+ tmp[0] = a + d; // [-7881, 7875]
+ tmp[1] = b + c; // [-7878, 7878]
+ tmp[2] = b - c; // [-7878, 7878]
+ tmp[3] = a - d; // [-7877, 7879]
+ tmp += 4;
+ in++;
+ }
+ // Each pass is expanding the dynamic range by ~3.85 (upper bound).
+ // The exact value is (2. + (20091 + 35468) / 65536).
+ // After the second pass, maximum interval is [-3794, 3794], assuming
+ // an input in [-2048, 2047] interval. We then need to add a dst value
+ // in the [0, 255] range.
+ // In the worst case scenario, the input to clip_8b() can be as large as
+ // [-60713, 60968].
+ tmp = C;
+ for (i = 0; i < 4; ++i) { // horizontal pass
+ const int dc = tmp[0] + 4;
+ const int a = dc + tmp[8];
+ const int b = dc - tmp[8];
+ const int c = MUL2(tmp[4]) - MUL1(tmp[12]);
+ const int d = MUL1(tmp[4]) + MUL2(tmp[12]);
+ STORE(0, 0, a + d);
+ STORE(1, 0, b + c);
+ STORE(2, 0, b - c);
+ STORE(3, 0, a - d);
+ tmp++;
+ dst += BPS;
+ }
+}
+
+// Simplified transform when only in[0], in[1] and in[4] are non-zero
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+ const int a = in[0] + 4;
+ const int c4 = MUL2(in[4]);
+ const int d4 = MUL1(in[4]);
+ const int c1 = MUL2(in[1]);
+ const int d1 = MUL1(in[1]);
+ STORE2(0, a + d4, d1, c1);
+ STORE2(1, a + c4, d1, c1);
+ STORE2(2, a - c4, d1, c1);
+ STORE2(3, a - d4, d1, c1);
+}
+#undef MUL1
+#undef MUL2
+#undef STORE2
+
+static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
+ TransformOne(in, dst);
+ if (do_two) {
+ TransformOne(in + 16, dst + 4);
+ }
+}
+
+static void TransformUV(const int16_t* in, uint8_t* dst) {
+ VP8Transform(in + 0 * 16, dst, 1);
+ VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
+}
+
+static void TransformDC(const int16_t* in, uint8_t* dst) {
+ const int DC = in[0] + 4;
+ int i, j;
+ for (j = 0; j < 4; ++j) {
+ for (i = 0; i < 4; ++i) {
+ STORE(i, j, DC);
+ }
+ }
+}
+
+static void TransformDCUV(const int16_t* in, uint8_t* dst) {
+ if (in[0 * 16]) VP8TransformDC(in + 0 * 16, dst);
+ if (in[1 * 16]) VP8TransformDC(in + 1 * 16, dst + 4);
+ if (in[2 * 16]) VP8TransformDC(in + 2 * 16, dst + 4 * BPS);
+ if (in[3 * 16]) VP8TransformDC(in + 3 * 16, dst + 4 * BPS + 4);
+}
+
+#undef STORE
+
+//------------------------------------------------------------------------------
+// Paragraph 14.3
+
+static void TransformWHT(const int16_t* in, int16_t* out) {
+ int tmp[16];
+ int i;
+ for (i = 0; i < 4; ++i) {
+ const int a0 = in[0 + i] + in[12 + i];
+ const int a1 = in[4 + i] + in[ 8 + i];
+ const int a2 = in[4 + i] - in[ 8 + i];
+ const int a3 = in[0 + i] - in[12 + i];
+ tmp[0 + i] = a0 + a1;
+ tmp[8 + i] = a0 - a1;
+ tmp[4 + i] = a3 + a2;
+ tmp[12 + i] = a3 - a2;
+ }
+ for (i = 0; i < 4; ++i) {
+ const int dc = tmp[0 + i * 4] + 3; // w/ rounder
+ const int a0 = dc + tmp[3 + i * 4];
+ const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4];
+ const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4];
+ const int a3 = dc - tmp[3 + i * 4];
+ out[ 0] = (a0 + a1) >> 3;
+ out[16] = (a3 + a2) >> 3;
+ out[32] = (a0 - a1) >> 3;
+ out[48] = (a3 - a2) >> 3;
+ out += 64;
+ }
+}
+
+void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
+
+//------------------------------------------------------------------------------
+// Intra predictions
+
+#define DST(x, y) dst[(x) + (y) * BPS]
+
+static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
+ const uint8_t* top = dst - BPS;
+ const uint8_t* const clip0 = VP8kclip1 - top[-1];
+ int y;
+ for (y = 0; y < size; ++y) {
+ const uint8_t* const clip = clip0 + dst[-1];
+ int x;
+ for (x = 0; x < size; ++x) {
+ dst[x] = clip[top[x]];
+ }
+ dst += BPS;
+ }
+}
+static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
+static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
+static void TM16(uint8_t* dst) { TrueMotion(dst, 16); }
+
+//------------------------------------------------------------------------------
+// 16x16
+
+static void VE16(uint8_t* dst) { // vertical
+ int j;
+ for (j = 0; j < 16; ++j) {
+ memcpy(dst + j * BPS, dst - BPS, 16);
+ }
+}
+
+static void HE16(uint8_t* dst) { // horizontal
+ int j;
+ for (j = 16; j > 0; --j) {
+ memset(dst, dst[-1], 16);
+ dst += BPS;
+ }
+}
+
+static WEBP_INLINE void Put16(int v, uint8_t* dst) {
+ int j;
+ for (j = 0; j < 16; ++j) {
+ memset(dst + j * BPS, v, 16);
+ }
+}
+
+static void DC16(uint8_t* dst) { // DC
+ int DC = 16;
+ int j;
+ for (j = 0; j < 16; ++j) {
+ DC += dst[-1 + j * BPS] + dst[j - BPS];
+ }
+ Put16(DC >> 5, dst);
+}
+
+static void DC16NoTop(uint8_t* dst) { // DC with top samples not available
+ int DC = 8;
+ int j;
+ for (j = 0; j < 16; ++j) {
+ DC += dst[-1 + j * BPS];
+ }
+ Put16(DC >> 4, dst);
+}
+
+static void DC16NoLeft(uint8_t* dst) { // DC with left samples not available
+ int DC = 8;
+ int i;
+ for (i = 0; i < 16; ++i) {
+ DC += dst[i - BPS];
+ }
+ Put16(DC >> 4, dst);
+}
+
+static void DC16NoTopLeft(uint8_t* dst) { // DC with no top and left samples
+ Put16(0x80, dst);
+}
+
+VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
+
+//------------------------------------------------------------------------------
+// 4x4
+
+#define AVG3(a, b, c) ((uint8_t)(((a) + 2 * (b) + (c) + 2) >> 2))
+#define AVG2(a, b) (((a) + (b) + 1) >> 1)
+
+static void VE4(uint8_t* dst) { // vertical
+ const uint8_t* top = dst - BPS;
+ const uint8_t vals[4] = {
+ AVG3(top[-1], top[0], top[1]),
+ AVG3(top[ 0], top[1], top[2]),
+ AVG3(top[ 1], top[2], top[3]),
+ AVG3(top[ 2], top[3], top[4])
+ };
+ int i;
+ for (i = 0; i < 4; ++i) {
+ memcpy(dst + i * BPS, vals, sizeof(vals));
+ }
+}
+
+static void HE4(uint8_t* dst) { // horizontal
+ const int A = dst[-1 - BPS];
+ const int B = dst[-1];
+ const int C = dst[-1 + BPS];
+ const int D = dst[-1 + 2 * BPS];
+ const int E = dst[-1 + 3 * BPS];
+ WebPUint32ToMem(dst + 0 * BPS, 0x01010101U * AVG3(A, B, C));
+ WebPUint32ToMem(dst + 1 * BPS, 0x01010101U * AVG3(B, C, D));
+ WebPUint32ToMem(dst + 2 * BPS, 0x01010101U * AVG3(C, D, E));
+ WebPUint32ToMem(dst + 3 * BPS, 0x01010101U * AVG3(D, E, E));
+}
+
+static void DC4(uint8_t* dst) { // DC
+ uint32_t dc = 4;
+ int i;
+ for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
+ dc >>= 3;
+ for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4);
+}
+
+static void RD4(uint8_t* dst) { // Down-right
+ const int I = dst[-1 + 0 * BPS];
+ const int J = dst[-1 + 1 * BPS];
+ const int K = dst[-1 + 2 * BPS];
+ const int L = dst[-1 + 3 * BPS];
+ const int X = dst[-1 - BPS];
+ const int A = dst[0 - BPS];
+ const int B = dst[1 - BPS];
+ const int C = dst[2 - BPS];
+ const int D = dst[3 - BPS];
+ DST(0, 3) = AVG3(J, K, L);
+ DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
+ DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
+ DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
+ DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
+ DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
+ DST(3, 0) = AVG3(D, C, B);
+}
+
+static void LD4(uint8_t* dst) { // Down-Left
+ const int A = dst[0 - BPS];
+ const int B = dst[1 - BPS];
+ const int C = dst[2 - BPS];
+ const int D = dst[3 - BPS];
+ const int E = dst[4 - BPS];
+ const int F = dst[5 - BPS];
+ const int G = dst[6 - BPS];
+ const int H = dst[7 - BPS];
+ DST(0, 0) = AVG3(A, B, C);
+ DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
+ DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
+ DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
+ DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
+ DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
+ DST(3, 3) = AVG3(G, H, H);
+}
+
+static void VR4(uint8_t* dst) { // Vertical-Right
+ const int I = dst[-1 + 0 * BPS];
+ const int J = dst[-1 + 1 * BPS];
+ const int K = dst[-1 + 2 * BPS];
+ const int X = dst[-1 - BPS];
+ const int A = dst[0 - BPS];
+ const int B = dst[1 - BPS];
+ const int C = dst[2 - BPS];
+ const int D = dst[3 - BPS];
+ DST(0, 0) = DST(1, 2) = AVG2(X, A);
+ DST(1, 0) = DST(2, 2) = AVG2(A, B);
+ DST(2, 0) = DST(3, 2) = AVG2(B, C);
+ DST(3, 0) = AVG2(C, D);
+
+ DST(0, 3) = AVG3(K, J, I);
+ DST(0, 2) = AVG3(J, I, X);
+ DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
+ DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
+ DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
+ DST(3, 1) = AVG3(B, C, D);
+}
+
+static void VL4(uint8_t* dst) { // Vertical-Left
+ const int A = dst[0 - BPS];
+ const int B = dst[1 - BPS];
+ const int C = dst[2 - BPS];
+ const int D = dst[3 - BPS];
+ const int E = dst[4 - BPS];
+ const int F = dst[5 - BPS];
+ const int G = dst[6 - BPS];
+ const int H = dst[7 - BPS];
+ DST(0, 0) = AVG2(A, B);
+ DST(1, 0) = DST(0, 2) = AVG2(B, C);
+ DST(2, 0) = DST(1, 2) = AVG2(C, D);
+ DST(3, 0) = DST(2, 2) = AVG2(D, E);
+
+ DST(0, 1) = AVG3(A, B, C);
+ DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
+ DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
+ DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
+ DST(3, 2) = AVG3(E, F, G);
+ DST(3, 3) = AVG3(F, G, H);
+}
+
+static void HU4(uint8_t* dst) { // Horizontal-Up
+ const int I = dst[-1 + 0 * BPS];
+ const int J = dst[-1 + 1 * BPS];
+ const int K = dst[-1 + 2 * BPS];
+ const int L = dst[-1 + 3 * BPS];
+ DST(0, 0) = AVG2(I, J);
+ DST(2, 0) = DST(0, 1) = AVG2(J, K);
+ DST(2, 1) = DST(0, 2) = AVG2(K, L);
+ DST(1, 0) = AVG3(I, J, K);
+ DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
+ DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
+ DST(3, 2) = DST(2, 2) =
+ DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
+}
+
+static void HD4(uint8_t* dst) { // Horizontal-Down
+ const int I = dst[-1 + 0 * BPS];
+ const int J = dst[-1 + 1 * BPS];
+ const int K = dst[-1 + 2 * BPS];
+ const int L = dst[-1 + 3 * BPS];
+ const int X = dst[-1 - BPS];
+ const int A = dst[0 - BPS];
+ const int B = dst[1 - BPS];
+ const int C = dst[2 - BPS];
+
+ DST(0, 0) = DST(2, 1) = AVG2(I, X);
+ DST(0, 1) = DST(2, 2) = AVG2(J, I);
+ DST(0, 2) = DST(2, 3) = AVG2(K, J);
+ DST(0, 3) = AVG2(L, K);
+
+ DST(3, 0) = AVG3(A, B, C);
+ DST(2, 0) = AVG3(X, A, B);
+ DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
+ DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
+ DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
+ DST(1, 3) = AVG3(L, K, J);
+}
+
+#undef DST
+#undef AVG3
+#undef AVG2
+
+VP8PredFunc VP8PredLuma4[NUM_BMODES];
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static void VE8uv(uint8_t* dst) { // vertical
+ int j;
+ for (j = 0; j < 8; ++j) {
+ memcpy(dst + j * BPS, dst - BPS, 8);
+ }
+}
+
+static void HE8uv(uint8_t* dst) { // horizontal
+ int j;
+ for (j = 0; j < 8; ++j) {
+ memset(dst, dst[-1], 8);
+ dst += BPS;
+ }
+}
+
+// helper for chroma-DC predictions
+static WEBP_INLINE void Put8x8uv(uint8_t value, uint8_t* dst) {
+ int j;
+ for (j = 0; j < 8; ++j) {
+ memset(dst + j * BPS, value, 8);
+ }
+}
+
+static void DC8uv(uint8_t* dst) { // DC
+ int dc0 = 8;
+ int i;
+ for (i = 0; i < 8; ++i) {
+ dc0 += dst[i - BPS] + dst[-1 + i * BPS];
+ }
+ Put8x8uv(dc0 >> 4, dst);
+}
+
+static void DC8uvNoLeft(uint8_t* dst) { // DC with no left samples
+ int dc0 = 4;
+ int i;
+ for (i = 0; i < 8; ++i) {
+ dc0 += dst[i - BPS];
+ }
+ Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTop(uint8_t* dst) { // DC with no top samples
+ int dc0 = 4;
+ int i;
+ for (i = 0; i < 8; ++i) {
+ dc0 += dst[-1 + i * BPS];
+ }
+ Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTopLeft(uint8_t* dst) { // DC with nothing
+ Put8x8uv(0x80, dst);
+}
+
+VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
+
+//------------------------------------------------------------------------------
+// Edge filtering functions
+
+// 4 pixels in, 2 pixels out
+static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
+ const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
+ const int a = 3 * (q0 - p0) + VP8ksclip1[p1 - q1]; // in [-893,892]
+ const int a1 = VP8ksclip2[(a + 4) >> 3]; // in [-16,15]
+ const int a2 = VP8ksclip2[(a + 3) >> 3];
+ p[-step] = VP8kclip1[p0 + a2];
+ p[ 0] = VP8kclip1[q0 - a1];
+}
+
+// 4 pixels in, 4 pixels out
+static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
+ const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
+ const int a = 3 * (q0 - p0);
+ const int a1 = VP8ksclip2[(a + 4) >> 3];
+ const int a2 = VP8ksclip2[(a + 3) >> 3];
+ const int a3 = (a1 + 1) >> 1;
+ p[-2*step] = VP8kclip1[p1 + a3];
+ p[- step] = VP8kclip1[p0 + a2];
+ p[ 0] = VP8kclip1[q0 - a1];
+ p[ step] = VP8kclip1[q1 - a3];
+}
+
+// 6 pixels in, 6 pixels out
+static WEBP_INLINE void do_filter6(uint8_t* p, int step) {
+ const int p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
+ const int q0 = p[0], q1 = p[step], q2 = p[2*step];
+ const int a = VP8ksclip1[3 * (q0 - p0) + VP8ksclip1[p1 - q1]];
+ // a is in [-128,127], a1 in [-27,27], a2 in [-18,18] and a3 in [-9,9]
+ const int a1 = (27 * a + 63) >> 7; // eq. to ((3 * a + 7) * 9) >> 7
+ const int a2 = (18 * a + 63) >> 7; // eq. to ((2 * a + 7) * 9) >> 7
+ const int a3 = (9 * a + 63) >> 7; // eq. to ((1 * a + 7) * 9) >> 7
+ p[-3*step] = VP8kclip1[p2 + a3];
+ p[-2*step] = VP8kclip1[p1 + a2];
+ p[- step] = VP8kclip1[p0 + a1];
+ p[ 0] = VP8kclip1[q0 - a1];
+ p[ step] = VP8kclip1[q1 - a2];
+ p[ 2*step] = VP8kclip1[q2 - a3];
+}
+
+static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
+ const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
+ return (VP8kabs0[p1 - p0] > thresh) || (VP8kabs0[q1 - q0] > thresh);
+}
+
+static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int t) {
+ const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
+ return ((4 * VP8kabs0[p0 - q0] + VP8kabs0[p1 - q1]) <= t);
+}
+
+static WEBP_INLINE int needs_filter2(const uint8_t* p,
+ int step, int t, int it) {
+ const int p3 = p[-4 * step], p2 = p[-3 * step], p1 = p[-2 * step];
+ const int p0 = p[-step], q0 = p[0];
+ const int q1 = p[step], q2 = p[2 * step], q3 = p[3 * step];
+ if ((4 * VP8kabs0[p0 - q0] + VP8kabs0[p1 - q1]) > t) return 0;
+ return VP8kabs0[p3 - p2] <= it && VP8kabs0[p2 - p1] <= it &&
+ VP8kabs0[p1 - p0] <= it && VP8kabs0[q3 - q2] <= it &&
+ VP8kabs0[q2 - q1] <= it && VP8kabs0[q1 - q0] <= it;
+}
+
+//------------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+ int i;
+ const int thresh2 = 2 * thresh + 1;
+ for (i = 0; i < 16; ++i) {
+ if (needs_filter(p + i, stride, thresh2)) {
+ do_filter2(p + i, stride);
+ }
+ }
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+ int i;
+ const int thresh2 = 2 * thresh + 1;
+ for (i = 0; i < 16; ++i) {
+ if (needs_filter(p + i * stride, 1, thresh2)) {
+ do_filter2(p + i * stride, 1);
+ }
+ }
+}
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+ int k;
+ for (k = 3; k > 0; --k) {
+ p += 4 * stride;
+ SimpleVFilter16(p, stride, thresh);
+ }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+ int k;
+ for (k = 3; k > 0; --k) {
+ p += 4;
+ SimpleHFilter16(p, stride, thresh);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Complex In-loop filtering (Paragraph 15.3)
+
+static WEBP_INLINE void FilterLoop26(uint8_t* p,
+ int hstride, int vstride, int size,
+ int thresh, int ithresh, int hev_thresh) {
+ const int thresh2 = 2 * thresh + 1;
+ while (size-- > 0) {
+ if (needs_filter2(p, hstride, thresh2, ithresh)) {
+ if (hev(p, hstride, hev_thresh)) {
+ do_filter2(p, hstride);
+ } else {
+ do_filter6(p, hstride);
+ }
+ }
+ p += vstride;
+ }
+}
+
+static WEBP_INLINE void FilterLoop24(uint8_t* p,
+ int hstride, int vstride, int size,
+ int thresh, int ithresh, int hev_thresh) {
+ const int thresh2 = 2 * thresh + 1;
+ while (size-- > 0) {
+ if (needs_filter2(p, hstride, thresh2, ithresh)) {
+ if (hev(p, hstride, hev_thresh)) {
+ do_filter2(p, hstride);
+ } else {
+ do_filter4(p, hstride);
+ }
+ }
+ p += vstride;
+ }
+}
+
+// on macroblock edges
+static void VFilter16(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter16(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ int k;
+ for (k = 3; k > 0; --k) {
+ p += 4 * stride;
+ FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
+ }
+}
+
+static void HFilter16i(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ int k;
+ for (k = 3; k > 0; --k) {
+ p += 4;
+ FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
+ }
+}
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
+ FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
+ FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+ FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+ FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
+}
+
+//------------------------------------------------------------------------------
+
+static void DitherCombine8x8(const uint8_t* dither, uint8_t* dst,
+ int dst_stride) {
+ int i, j;
+ for (j = 0; j < 8; ++j) {
+ for (i = 0; i < 8; ++i) {
+ const int delta0 = dither[i] - VP8_DITHER_AMP_CENTER;
+ const int delta1 =
+ (delta0 + VP8_DITHER_DESCALE_ROUNDER) >> VP8_DITHER_DESCALE;
+ dst[i] = clip_8b((int)dst[i] + delta1);
+ }
+ dst += dst_stride;
+ dither += 8;
+ }
+}
+
+//------------------------------------------------------------------------------
+
+VP8DecIdct2 VP8Transform;
+VP8DecIdct VP8TransformAC3;
+VP8DecIdct VP8TransformUV;
+VP8DecIdct VP8TransformDC;
+VP8DecIdct VP8TransformDCUV;
+
+VP8LumaFilterFunc VP8VFilter16;
+VP8LumaFilterFunc VP8HFilter16;
+VP8ChromaFilterFunc VP8VFilter8;
+VP8ChromaFilterFunc VP8HFilter8;
+VP8LumaFilterFunc VP8VFilter16i;
+VP8LumaFilterFunc VP8HFilter16i;
+VP8ChromaFilterFunc VP8VFilter8i;
+VP8ChromaFilterFunc VP8HFilter8i;
+VP8SimpleFilterFunc VP8SimpleVFilter16;
+VP8SimpleFilterFunc VP8SimpleHFilter16;
+VP8SimpleFilterFunc VP8SimpleVFilter16i;
+VP8SimpleFilterFunc VP8SimpleHFilter16i;
+
+void (*VP8DitherCombine8x8)(const uint8_t* dither, uint8_t* dst,
+ int dst_stride);
+
+extern void VP8DspInitSSE2(void);
+extern void VP8DspInitSSE41(void);
+extern void VP8DspInitNEON(void);
+extern void VP8DspInitMIPS32(void);
+extern void VP8DspInitMIPSdspR2(void);
+extern void VP8DspInitMSA(void);
+
+static volatile VP8CPUInfo dec_last_cpuinfo_used =
+ (VP8CPUInfo)&dec_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
+ if (dec_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ VP8InitClipTables();
+
+ VP8TransformWHT = TransformWHT;
+ VP8Transform = TransformTwo;
+ VP8TransformUV = TransformUV;
+ VP8TransformDC = TransformDC;
+ VP8TransformDCUV = TransformDCUV;
+ VP8TransformAC3 = TransformAC3;
+
+ VP8VFilter16 = VFilter16;
+ VP8HFilter16 = HFilter16;
+ VP8VFilter8 = VFilter8;
+ VP8HFilter8 = HFilter8;
+ VP8VFilter16i = VFilter16i;
+ VP8HFilter16i = HFilter16i;
+ VP8VFilter8i = VFilter8i;
+ VP8HFilter8i = HFilter8i;
+ VP8SimpleVFilter16 = SimpleVFilter16;
+ VP8SimpleHFilter16 = SimpleHFilter16;
+ VP8SimpleVFilter16i = SimpleVFilter16i;
+ VP8SimpleHFilter16i = SimpleHFilter16i;
+
+ VP8PredLuma4[0] = DC4;
+ VP8PredLuma4[1] = TM4;
+ VP8PredLuma4[2] = VE4;
+ VP8PredLuma4[3] = HE4;
+ VP8PredLuma4[4] = RD4;
+ VP8PredLuma4[5] = VR4;
+ VP8PredLuma4[6] = LD4;
+ VP8PredLuma4[7] = VL4;
+ VP8PredLuma4[8] = HD4;
+ VP8PredLuma4[9] = HU4;
+
+ VP8PredLuma16[0] = DC16;
+ VP8PredLuma16[1] = TM16;
+ VP8PredLuma16[2] = VE16;
+ VP8PredLuma16[3] = HE16;
+ VP8PredLuma16[4] = DC16NoTop;
+ VP8PredLuma16[5] = DC16NoLeft;
+ VP8PredLuma16[6] = DC16NoTopLeft;
+
+ VP8PredChroma8[0] = DC8uv;
+ VP8PredChroma8[1] = TM8uv;
+ VP8PredChroma8[2] = VE8uv;
+ VP8PredChroma8[3] = HE8uv;
+ VP8PredChroma8[4] = DC8uvNoTop;
+ VP8PredChroma8[5] = DC8uvNoLeft;
+ VP8PredChroma8[6] = DC8uvNoTopLeft;
+
+ VP8DitherCombine8x8 = DitherCombine8x8;
+
+ // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ VP8DspInitSSE2();
+#if defined(WEBP_USE_SSE41)
+ if (VP8GetCPUInfo(kSSE4_1)) {
+ VP8DspInitSSE41();
+ }
+#endif
+ }
+#endif
+#if defined(WEBP_USE_NEON)
+ if (VP8GetCPUInfo(kNEON)) {
+ VP8DspInitNEON();
+ }
+#endif
+#if defined(WEBP_USE_MIPS32)
+ if (VP8GetCPUInfo(kMIPS32)) {
+ VP8DspInitMIPS32();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ VP8DspInitMIPSdspR2();
+ }
+#endif
+#if defined(WEBP_USE_MSA)
+ if (VP8GetCPUInfo(kMSA)) {
+ VP8DspInitMSA();
+ }
+#endif
+ }
+ dec_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/media/libwebp/dsp/dec_clip_tables.c b/media/libwebp/dsp/dec_clip_tables.c
new file mode 100644
index 000000000..74ba34c0b
--- /dev/null
+++ b/media/libwebp/dsp/dec_clip_tables.c
@@ -0,0 +1,366 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Clipping tables for filtering
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#define USE_STATIC_TABLES // undefine to have run-time table initialization
+
+#ifdef USE_STATIC_TABLES
+
+static const uint8_t abs0[255 + 255 + 1] = {
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4,
+ 0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
+ 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xdf, 0xde, 0xdd, 0xdc,
+ 0xdb, 0xda, 0xd9, 0xd8, 0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
+ 0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, 0xc7, 0xc6, 0xc5, 0xc4,
+ 0xc3, 0xc2, 0xc1, 0xc0, 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
+ 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0, 0xaf, 0xae, 0xad, 0xac,
+ 0xab, 0xaa, 0xa9, 0xa8, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
+ 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94,
+ 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
+ 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x7f, 0x7e, 0x7d, 0x7c,
+ 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
+ 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64,
+ 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
+ 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x4e, 0x4d, 0x4c,
+ 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
+ 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34,
+ 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
+ 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c,
+ 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04,
+ 0x03, 0x02, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+ 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c,
+ 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
+ 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
+ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
+ 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
+ 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
+ 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc,
+ 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+ 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
+ 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec,
+ 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static const uint8_t sclip1[1020 + 1020 + 1] = {
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
+ 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,
+ 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb,
+ 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
+ 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
+ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
+};
+
+static const uint8_t sclip2[112 + 112 + 1] = {
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
+ 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f
+};
+
+static const uint8_t clip1[255 + 511 + 1] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+ 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c,
+ 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
+ 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
+ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
+ 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4,
+ 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
+ 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc,
+ 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+ 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
+ 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec,
+ 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+#else
+
+// uninitialized tables
+static uint8_t abs0[255 + 255 + 1];
+static int8_t sclip1[1020 + 1020 + 1];
+static int8_t sclip2[112 + 112 + 1];
+static uint8_t clip1[255 + 511 + 1];
+
+// We declare this variable 'volatile' to prevent instruction reordering
+// and make sure it's set to true _last_ (so as to be thread-safe)
+static volatile int tables_ok = 0;
+
+#endif
+
+const int8_t* const VP8ksclip1 = (const int8_t*)&sclip1[1020];
+const int8_t* const VP8ksclip2 = (const int8_t*)&sclip2[112];
+const uint8_t* const VP8kclip1 = &clip1[255];
+const uint8_t* const VP8kabs0 = &abs0[255];
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8InitClipTables(void) {
+#if !defined(USE_STATIC_TABLES)
+ int i;
+ if (!tables_ok) {
+ for (i = -255; i <= 255; ++i) {
+ abs0[255 + i] = (i < 0) ? -i : i;
+ }
+ for (i = -1020; i <= 1020; ++i) {
+ sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i;
+ }
+ for (i = -112; i <= 112; ++i) {
+ sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i;
+ }
+ for (i = -255; i <= 255 + 255; ++i) {
+ clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
+ }
+ tables_ok = 1;
+ }
+#endif // USE_STATIC_TABLES
+}
diff --git a/media/libwebp/dsp/dec_neon.c b/media/libwebp/dsp/dec_neon.c
new file mode 100644
index 000000000..34796cf4a
--- /dev/null
+++ b/media/libwebp/dsp/dec_neon.c
@@ -0,0 +1,1639 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// ARM NEON version of dsp functions and loop filtering.
+//
+// Authors: Somnath Banerjee (somnath@google.com)
+// Johann Koenig (johannkoenig@google.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include "./neon.h"
+#include "../dec/vp8i_dec.h"
+
+//------------------------------------------------------------------------------
+// NxM Loading functions
+
+// Load/Store vertical edge
+#define LOAD8x4(c1, c2, c3, c4, b1, b2, stride) \
+ "vld4.8 {" #c1 "[0]," #c2 "[0]," #c3 "[0]," #c4 "[0]}," #b1 "," #stride "\n" \
+ "vld4.8 {" #c1 "[1]," #c2 "[1]," #c3 "[1]," #c4 "[1]}," #b2 "," #stride "\n" \
+ "vld4.8 {" #c1 "[2]," #c2 "[2]," #c3 "[2]," #c4 "[2]}," #b1 "," #stride "\n" \
+ "vld4.8 {" #c1 "[3]," #c2 "[3]," #c3 "[3]," #c4 "[3]}," #b2 "," #stride "\n" \
+ "vld4.8 {" #c1 "[4]," #c2 "[4]," #c3 "[4]," #c4 "[4]}," #b1 "," #stride "\n" \
+ "vld4.8 {" #c1 "[5]," #c2 "[5]," #c3 "[5]," #c4 "[5]}," #b2 "," #stride "\n" \
+ "vld4.8 {" #c1 "[6]," #c2 "[6]," #c3 "[6]," #c4 "[6]}," #b1 "," #stride "\n" \
+ "vld4.8 {" #c1 "[7]," #c2 "[7]," #c3 "[7]," #c4 "[7]}," #b2 "," #stride "\n"
+
+#define STORE8x2(c1, c2, p, stride) \
+ "vst2.8 {" #c1 "[0], " #c2 "[0]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[1], " #c2 "[1]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[2], " #c2 "[2]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[3], " #c2 "[3]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[4], " #c2 "[4]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[5], " #c2 "[5]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[6], " #c2 "[6]}," #p "," #stride " \n" \
+ "vst2.8 {" #c1 "[7], " #c2 "[7]}," #p "," #stride " \n"
+
+#if !defined(WORK_AROUND_GCC)
+
+// This intrinsics version makes gcc-4.6.3 crash during Load4x??() compilation
+// (register alloc, probably). The variants somewhat mitigate the problem, but
+// not quite. HFilter16i() remains problematic.
+static WEBP_INLINE uint8x8x4_t Load4x8(const uint8_t* const src, int stride) {
+ const uint8x8_t zero = vdup_n_u8(0);
+ uint8x8x4_t out;
+ INIT_VECTOR4(out, zero, zero, zero, zero);
+ out = vld4_lane_u8(src + 0 * stride, out, 0);
+ out = vld4_lane_u8(src + 1 * stride, out, 1);
+ out = vld4_lane_u8(src + 2 * stride, out, 2);
+ out = vld4_lane_u8(src + 3 * stride, out, 3);
+ out = vld4_lane_u8(src + 4 * stride, out, 4);
+ out = vld4_lane_u8(src + 5 * stride, out, 5);
+ out = vld4_lane_u8(src + 6 * stride, out, 6);
+ out = vld4_lane_u8(src + 7 * stride, out, 7);
+ return out;
+}
+
+static WEBP_INLINE void Load4x16(const uint8_t* const src, int stride,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1) {
+ // row0 = p1[0..7]|p0[0..7]|q0[0..7]|q1[0..7]
+ // row8 = p1[8..15]|p0[8..15]|q0[8..15]|q1[8..15]
+ const uint8x8x4_t row0 = Load4x8(src - 2 + 0 * stride, stride);
+ const uint8x8x4_t row8 = Load4x8(src - 2 + 8 * stride, stride);
+ *p1 = vcombine_u8(row0.val[0], row8.val[0]);
+ *p0 = vcombine_u8(row0.val[1], row8.val[1]);
+ *q0 = vcombine_u8(row0.val[2], row8.val[2]);
+ *q1 = vcombine_u8(row0.val[3], row8.val[3]);
+}
+
+#else // WORK_AROUND_GCC
+
+#define LOADQ_LANE_32b(VALUE, LANE) do { \
+ (VALUE) = vld1q_lane_u32((const uint32_t*)src, (VALUE), (LANE)); \
+ src += stride; \
+} while (0)
+
+static WEBP_INLINE void Load4x16(const uint8_t* src, int stride,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1) {
+ const uint32x4_t zero = vdupq_n_u32(0);
+ uint32x4x4_t in;
+ INIT_VECTOR4(in, zero, zero, zero, zero);
+ src -= 2;
+ LOADQ_LANE_32b(in.val[0], 0);
+ LOADQ_LANE_32b(in.val[1], 0);
+ LOADQ_LANE_32b(in.val[2], 0);
+ LOADQ_LANE_32b(in.val[3], 0);
+ LOADQ_LANE_32b(in.val[0], 1);
+ LOADQ_LANE_32b(in.val[1], 1);
+ LOADQ_LANE_32b(in.val[2], 1);
+ LOADQ_LANE_32b(in.val[3], 1);
+ LOADQ_LANE_32b(in.val[0], 2);
+ LOADQ_LANE_32b(in.val[1], 2);
+ LOADQ_LANE_32b(in.val[2], 2);
+ LOADQ_LANE_32b(in.val[3], 2);
+ LOADQ_LANE_32b(in.val[0], 3);
+ LOADQ_LANE_32b(in.val[1], 3);
+ LOADQ_LANE_32b(in.val[2], 3);
+ LOADQ_LANE_32b(in.val[3], 3);
+ // Transpose four 4x4 parts:
+ {
+ const uint8x16x2_t row01 = vtrnq_u8(vreinterpretq_u8_u32(in.val[0]),
+ vreinterpretq_u8_u32(in.val[1]));
+ const uint8x16x2_t row23 = vtrnq_u8(vreinterpretq_u8_u32(in.val[2]),
+ vreinterpretq_u8_u32(in.val[3]));
+ const uint16x8x2_t row02 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[0]),
+ vreinterpretq_u16_u8(row23.val[0]));
+ const uint16x8x2_t row13 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[1]),
+ vreinterpretq_u16_u8(row23.val[1]));
+ *p1 = vreinterpretq_u8_u16(row02.val[0]);
+ *p0 = vreinterpretq_u8_u16(row13.val[0]);
+ *q0 = vreinterpretq_u8_u16(row02.val[1]);
+ *q1 = vreinterpretq_u8_u16(row13.val[1]);
+ }
+}
+#undef LOADQ_LANE_32b
+
+#endif // !WORK_AROUND_GCC
+
+static WEBP_INLINE void Load8x16(const uint8_t* const src, int stride,
+ uint8x16_t* const p3, uint8x16_t* const p2,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1,
+ uint8x16_t* const q2, uint8x16_t* const q3) {
+ Load4x16(src - 2, stride, p3, p2, p1, p0);
+ Load4x16(src + 2, stride, q0, q1, q2, q3);
+}
+
+static WEBP_INLINE void Load16x4(const uint8_t* const src, int stride,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1) {
+ *p1 = vld1q_u8(src - 2 * stride);
+ *p0 = vld1q_u8(src - 1 * stride);
+ *q0 = vld1q_u8(src + 0 * stride);
+ *q1 = vld1q_u8(src + 1 * stride);
+}
+
+static WEBP_INLINE void Load16x8(const uint8_t* const src, int stride,
+ uint8x16_t* const p3, uint8x16_t* const p2,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1,
+ uint8x16_t* const q2, uint8x16_t* const q3) {
+ Load16x4(src - 2 * stride, stride, p3, p2, p1, p0);
+ Load16x4(src + 2 * stride, stride, q0, q1, q2, q3);
+}
+
+static WEBP_INLINE void Load8x8x2(const uint8_t* const u,
+ const uint8_t* const v,
+ int stride,
+ uint8x16_t* const p3, uint8x16_t* const p2,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1,
+ uint8x16_t* const q2, uint8x16_t* const q3) {
+ // We pack the 8x8 u-samples in the lower half of the uint8x16_t destination
+ // and the v-samples on the higher half.
+ *p3 = vcombine_u8(vld1_u8(u - 4 * stride), vld1_u8(v - 4 * stride));
+ *p2 = vcombine_u8(vld1_u8(u - 3 * stride), vld1_u8(v - 3 * stride));
+ *p1 = vcombine_u8(vld1_u8(u - 2 * stride), vld1_u8(v - 2 * stride));
+ *p0 = vcombine_u8(vld1_u8(u - 1 * stride), vld1_u8(v - 1 * stride));
+ *q0 = vcombine_u8(vld1_u8(u + 0 * stride), vld1_u8(v + 0 * stride));
+ *q1 = vcombine_u8(vld1_u8(u + 1 * stride), vld1_u8(v + 1 * stride));
+ *q2 = vcombine_u8(vld1_u8(u + 2 * stride), vld1_u8(v + 2 * stride));
+ *q3 = vcombine_u8(vld1_u8(u + 3 * stride), vld1_u8(v + 3 * stride));
+}
+
+#if !defined(WORK_AROUND_GCC)
+
+#define LOAD_UV_8(ROW) \
+ vcombine_u8(vld1_u8(u - 4 + (ROW) * stride), vld1_u8(v - 4 + (ROW) * stride))
+
+static WEBP_INLINE void Load8x8x2T(const uint8_t* const u,
+ const uint8_t* const v,
+ int stride,
+ uint8x16_t* const p3, uint8x16_t* const p2,
+ uint8x16_t* const p1, uint8x16_t* const p0,
+ uint8x16_t* const q0, uint8x16_t* const q1,
+ uint8x16_t* const q2, uint8x16_t* const q3) {
+ // We pack the 8x8 u-samples in the lower half of the uint8x16_t destination
+ // and the v-samples on the higher half.
+ const uint8x16_t row0 = LOAD_UV_8(0);
+ const uint8x16_t row1 = LOAD_UV_8(1);
+ const uint8x16_t row2 = LOAD_UV_8(2);
+ const uint8x16_t row3 = LOAD_UV_8(3);
+ const uint8x16_t row4 = LOAD_UV_8(4);
+ const uint8x16_t row5 = LOAD_UV_8(5);
+ const uint8x16_t row6 = LOAD_UV_8(6);
+ const uint8x16_t row7 = LOAD_UV_8(7);
+ // Perform two side-by-side 8x8 transposes
+ // u00 u01 u02 u03 u04 u05 u06 u07 | v00 v01 v02 v03 v04 v05 v06 v07
+ // u10 u11 u12 u13 u14 u15 u16 u17 | v10 v11 v12 ...
+ // u20 u21 u22 u23 u24 u25 u26 u27 | v20 v21 ...
+ // u30 u31 u32 u33 u34 u35 u36 u37 | ...
+ // u40 u41 u42 u43 u44 u45 u46 u47 | ...
+ // u50 u51 u52 u53 u54 u55 u56 u57 | ...
+ // u60 u61 u62 u63 u64 u65 u66 u67 | v60 ...
+ // u70 u71 u72 u73 u74 u75 u76 u77 | v70 v71 v72 ...
+ const uint8x16x2_t row01 = vtrnq_u8(row0, row1); // u00 u10 u02 u12 ...
+ // u01 u11 u03 u13 ...
+ const uint8x16x2_t row23 = vtrnq_u8(row2, row3); // u20 u30 u22 u32 ...
+ // u21 u31 u23 u33 ...
+ const uint8x16x2_t row45 = vtrnq_u8(row4, row5); // ...
+ const uint8x16x2_t row67 = vtrnq_u8(row6, row7); // ...
+ const uint16x8x2_t row02 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[0]),
+ vreinterpretq_u16_u8(row23.val[0]));
+ const uint16x8x2_t row13 = vtrnq_u16(vreinterpretq_u16_u8(row01.val[1]),
+ vreinterpretq_u16_u8(row23.val[1]));
+ const uint16x8x2_t row46 = vtrnq_u16(vreinterpretq_u16_u8(row45.val[0]),
+ vreinterpretq_u16_u8(row67.val[0]));
+ const uint16x8x2_t row57 = vtrnq_u16(vreinterpretq_u16_u8(row45.val[1]),
+ vreinterpretq_u16_u8(row67.val[1]));
+ const uint32x4x2_t row04 = vtrnq_u32(vreinterpretq_u32_u16(row02.val[0]),
+ vreinterpretq_u32_u16(row46.val[0]));
+ const uint32x4x2_t row26 = vtrnq_u32(vreinterpretq_u32_u16(row02.val[1]),
+ vreinterpretq_u32_u16(row46.val[1]));
+ const uint32x4x2_t row15 = vtrnq_u32(vreinterpretq_u32_u16(row13.val[0]),
+ vreinterpretq_u32_u16(row57.val[0]));
+ const uint32x4x2_t row37 = vtrnq_u32(vreinterpretq_u32_u16(row13.val[1]),
+ vreinterpretq_u32_u16(row57.val[1]));
+ *p3 = vreinterpretq_u8_u32(row04.val[0]);
+ *p2 = vreinterpretq_u8_u32(row15.val[0]);
+ *p1 = vreinterpretq_u8_u32(row26.val[0]);
+ *p0 = vreinterpretq_u8_u32(row37.val[0]);
+ *q0 = vreinterpretq_u8_u32(row04.val[1]);
+ *q1 = vreinterpretq_u8_u32(row15.val[1]);
+ *q2 = vreinterpretq_u8_u32(row26.val[1]);
+ *q3 = vreinterpretq_u8_u32(row37.val[1]);
+}
+#undef LOAD_UV_8
+
+#endif // !WORK_AROUND_GCC
+
+static WEBP_INLINE void Store2x8(const uint8x8x2_t v,
+ uint8_t* const dst, int stride) {
+ vst2_lane_u8(dst + 0 * stride, v, 0);
+ vst2_lane_u8(dst + 1 * stride, v, 1);
+ vst2_lane_u8(dst + 2 * stride, v, 2);
+ vst2_lane_u8(dst + 3 * stride, v, 3);
+ vst2_lane_u8(dst + 4 * stride, v, 4);
+ vst2_lane_u8(dst + 5 * stride, v, 5);
+ vst2_lane_u8(dst + 6 * stride, v, 6);
+ vst2_lane_u8(dst + 7 * stride, v, 7);
+}
+
+static WEBP_INLINE void Store2x16(const uint8x16_t p0, const uint8x16_t q0,
+ uint8_t* const dst, int stride) {
+ uint8x8x2_t lo, hi;
+ lo.val[0] = vget_low_u8(p0);
+ lo.val[1] = vget_low_u8(q0);
+ hi.val[0] = vget_high_u8(p0);
+ hi.val[1] = vget_high_u8(q0);
+ Store2x8(lo, dst - 1 + 0 * stride, stride);
+ Store2x8(hi, dst - 1 + 8 * stride, stride);
+}
+
+#if !defined(WORK_AROUND_GCC)
+static WEBP_INLINE void Store4x8(const uint8x8x4_t v,
+ uint8_t* const dst, int stride) {
+ vst4_lane_u8(dst + 0 * stride, v, 0);
+ vst4_lane_u8(dst + 1 * stride, v, 1);
+ vst4_lane_u8(dst + 2 * stride, v, 2);
+ vst4_lane_u8(dst + 3 * stride, v, 3);
+ vst4_lane_u8(dst + 4 * stride, v, 4);
+ vst4_lane_u8(dst + 5 * stride, v, 5);
+ vst4_lane_u8(dst + 6 * stride, v, 6);
+ vst4_lane_u8(dst + 7 * stride, v, 7);
+}
+
+static WEBP_INLINE void Store4x16(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ uint8_t* const dst, int stride) {
+ uint8x8x4_t lo, hi;
+ INIT_VECTOR4(lo,
+ vget_low_u8(p1), vget_low_u8(p0),
+ vget_low_u8(q0), vget_low_u8(q1));
+ INIT_VECTOR4(hi,
+ vget_high_u8(p1), vget_high_u8(p0),
+ vget_high_u8(q0), vget_high_u8(q1));
+ Store4x8(lo, dst - 2 + 0 * stride, stride);
+ Store4x8(hi, dst - 2 + 8 * stride, stride);
+}
+#endif // !WORK_AROUND_GCC
+
+static WEBP_INLINE void Store16x2(const uint8x16_t p0, const uint8x16_t q0,
+ uint8_t* const dst, int stride) {
+ vst1q_u8(dst - stride, p0);
+ vst1q_u8(dst, q0);
+}
+
+static WEBP_INLINE void Store16x4(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ uint8_t* const dst, int stride) {
+ Store16x2(p1, p0, dst - stride, stride);
+ Store16x2(q0, q1, dst + stride, stride);
+}
+
+static WEBP_INLINE void Store8x2x2(const uint8x16_t p0, const uint8x16_t q0,
+ uint8_t* const u, uint8_t* const v,
+ int stride) {
+ // p0 and q0 contain the u+v samples packed in low/high halves.
+ vst1_u8(u - stride, vget_low_u8(p0));
+ vst1_u8(u, vget_low_u8(q0));
+ vst1_u8(v - stride, vget_high_u8(p0));
+ vst1_u8(v, vget_high_u8(q0));
+}
+
+static WEBP_INLINE void Store8x4x2(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ uint8_t* const u, uint8_t* const v,
+ int stride) {
+ // The p1...q1 registers contain the u+v samples packed in low/high halves.
+ Store8x2x2(p1, p0, u - stride, v - stride, stride);
+ Store8x2x2(q0, q1, u + stride, v + stride, stride);
+}
+
+#if !defined(WORK_AROUND_GCC)
+
+#define STORE6_LANE(DST, VAL0, VAL1, LANE) do { \
+ vst3_lane_u8((DST) - 3, (VAL0), (LANE)); \
+ vst3_lane_u8((DST) + 0, (VAL1), (LANE)); \
+ (DST) += stride; \
+} while (0)
+
+static WEBP_INLINE void Store6x8x2(const uint8x16_t p2, const uint8x16_t p1,
+ const uint8x16_t p0, const uint8x16_t q0,
+ const uint8x16_t q1, const uint8x16_t q2,
+ uint8_t* u, uint8_t* v,
+ int stride) {
+ uint8x8x3_t u0, u1, v0, v1;
+ INIT_VECTOR3(u0, vget_low_u8(p2), vget_low_u8(p1), vget_low_u8(p0));
+ INIT_VECTOR3(u1, vget_low_u8(q0), vget_low_u8(q1), vget_low_u8(q2));
+ INIT_VECTOR3(v0, vget_high_u8(p2), vget_high_u8(p1), vget_high_u8(p0));
+ INIT_VECTOR3(v1, vget_high_u8(q0), vget_high_u8(q1), vget_high_u8(q2));
+ STORE6_LANE(u, u0, u1, 0);
+ STORE6_LANE(u, u0, u1, 1);
+ STORE6_LANE(u, u0, u1, 2);
+ STORE6_LANE(u, u0, u1, 3);
+ STORE6_LANE(u, u0, u1, 4);
+ STORE6_LANE(u, u0, u1, 5);
+ STORE6_LANE(u, u0, u1, 6);
+ STORE6_LANE(u, u0, u1, 7);
+ STORE6_LANE(v, v0, v1, 0);
+ STORE6_LANE(v, v0, v1, 1);
+ STORE6_LANE(v, v0, v1, 2);
+ STORE6_LANE(v, v0, v1, 3);
+ STORE6_LANE(v, v0, v1, 4);
+ STORE6_LANE(v, v0, v1, 5);
+ STORE6_LANE(v, v0, v1, 6);
+ STORE6_LANE(v, v0, v1, 7);
+}
+#undef STORE6_LANE
+
+static WEBP_INLINE void Store4x8x2(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ uint8_t* const u, uint8_t* const v,
+ int stride) {
+ uint8x8x4_t u0, v0;
+ INIT_VECTOR4(u0,
+ vget_low_u8(p1), vget_low_u8(p0),
+ vget_low_u8(q0), vget_low_u8(q1));
+ INIT_VECTOR4(v0,
+ vget_high_u8(p1), vget_high_u8(p0),
+ vget_high_u8(q0), vget_high_u8(q1));
+ vst4_lane_u8(u - 2 + 0 * stride, u0, 0);
+ vst4_lane_u8(u - 2 + 1 * stride, u0, 1);
+ vst4_lane_u8(u - 2 + 2 * stride, u0, 2);
+ vst4_lane_u8(u - 2 + 3 * stride, u0, 3);
+ vst4_lane_u8(u - 2 + 4 * stride, u0, 4);
+ vst4_lane_u8(u - 2 + 5 * stride, u0, 5);
+ vst4_lane_u8(u - 2 + 6 * stride, u0, 6);
+ vst4_lane_u8(u - 2 + 7 * stride, u0, 7);
+ vst4_lane_u8(v - 2 + 0 * stride, v0, 0);
+ vst4_lane_u8(v - 2 + 1 * stride, v0, 1);
+ vst4_lane_u8(v - 2 + 2 * stride, v0, 2);
+ vst4_lane_u8(v - 2 + 3 * stride, v0, 3);
+ vst4_lane_u8(v - 2 + 4 * stride, v0, 4);
+ vst4_lane_u8(v - 2 + 5 * stride, v0, 5);
+ vst4_lane_u8(v - 2 + 6 * stride, v0, 6);
+ vst4_lane_u8(v - 2 + 7 * stride, v0, 7);
+}
+
+#endif // !WORK_AROUND_GCC
+
+// Zero extend 'v' to an int16x8_t.
+static WEBP_INLINE int16x8_t ConvertU8ToS16(uint8x8_t v) {
+ return vreinterpretq_s16_u16(vmovl_u8(v));
+}
+
+// Performs unsigned 8b saturation on 'dst01' and 'dst23' storing the result
+// to the corresponding rows of 'dst'.
+static WEBP_INLINE void SaturateAndStore4x4(uint8_t* const dst,
+ const int16x8_t dst01,
+ const int16x8_t dst23) {
+ // Unsigned saturate to 8b.
+ const uint8x8_t dst01_u8 = vqmovun_s16(dst01);
+ const uint8x8_t dst23_u8 = vqmovun_s16(dst23);
+
+ // Store the results.
+ vst1_lane_u32((uint32_t*)(dst + 0 * BPS), vreinterpret_u32_u8(dst01_u8), 0);
+ vst1_lane_u32((uint32_t*)(dst + 1 * BPS), vreinterpret_u32_u8(dst01_u8), 1);
+ vst1_lane_u32((uint32_t*)(dst + 2 * BPS), vreinterpret_u32_u8(dst23_u8), 0);
+ vst1_lane_u32((uint32_t*)(dst + 3 * BPS), vreinterpret_u32_u8(dst23_u8), 1);
+}
+
+static WEBP_INLINE void Add4x4(const int16x8_t row01, const int16x8_t row23,
+ uint8_t* const dst) {
+ uint32x2_t dst01 = vdup_n_u32(0);
+ uint32x2_t dst23 = vdup_n_u32(0);
+
+ // Load the source pixels.
+ dst01 = vld1_lane_u32((uint32_t*)(dst + 0 * BPS), dst01, 0);
+ dst23 = vld1_lane_u32((uint32_t*)(dst + 2 * BPS), dst23, 0);
+ dst01 = vld1_lane_u32((uint32_t*)(dst + 1 * BPS), dst01, 1);
+ dst23 = vld1_lane_u32((uint32_t*)(dst + 3 * BPS), dst23, 1);
+
+ {
+ // Convert to 16b.
+ const int16x8_t dst01_s16 = ConvertU8ToS16(vreinterpret_u8_u32(dst01));
+ const int16x8_t dst23_s16 = ConvertU8ToS16(vreinterpret_u8_u32(dst23));
+
+ // Descale with rounding.
+ const int16x8_t out01 = vrsraq_n_s16(dst01_s16, row01, 3);
+ const int16x8_t out23 = vrsraq_n_s16(dst23_s16, row23, 3);
+ // Add the inverse transform.
+ SaturateAndStore4x4(dst, out01, out23);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static uint8x16_t NeedsFilter(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ int thresh) {
+ const uint8x16_t thresh_v = vdupq_n_u8((uint8_t)thresh);
+ const uint8x16_t a_p0_q0 = vabdq_u8(p0, q0); // abs(p0-q0)
+ const uint8x16_t a_p1_q1 = vabdq_u8(p1, q1); // abs(p1-q1)
+ const uint8x16_t a_p0_q0_2 = vqaddq_u8(a_p0_q0, a_p0_q0); // 2 * abs(p0-q0)
+ const uint8x16_t a_p1_q1_2 = vshrq_n_u8(a_p1_q1, 1); // abs(p1-q1) / 2
+ const uint8x16_t sum = vqaddq_u8(a_p0_q0_2, a_p1_q1_2);
+ const uint8x16_t mask = vcgeq_u8(thresh_v, sum);
+ return mask;
+}
+
+static int8x16_t FlipSign(const uint8x16_t v) {
+ const uint8x16_t sign_bit = vdupq_n_u8(0x80);
+ return vreinterpretq_s8_u8(veorq_u8(v, sign_bit));
+}
+
+static uint8x16_t FlipSignBack(const int8x16_t v) {
+ const int8x16_t sign_bit = vdupq_n_s8(0x80);
+ return vreinterpretq_u8_s8(veorq_s8(v, sign_bit));
+}
+
+static int8x16_t GetBaseDelta(const int8x16_t p1, const int8x16_t p0,
+ const int8x16_t q0, const int8x16_t q1) {
+ const int8x16_t q0_p0 = vqsubq_s8(q0, p0); // (q0-p0)
+ const int8x16_t p1_q1 = vqsubq_s8(p1, q1); // (p1-q1)
+ const int8x16_t s1 = vqaddq_s8(p1_q1, q0_p0); // (p1-q1) + 1 * (q0 - p0)
+ const int8x16_t s2 = vqaddq_s8(q0_p0, s1); // (p1-q1) + 2 * (q0 - p0)
+ const int8x16_t s3 = vqaddq_s8(q0_p0, s2); // (p1-q1) + 3 * (q0 - p0)
+ return s3;
+}
+
+static int8x16_t GetBaseDelta0(const int8x16_t p0, const int8x16_t q0) {
+ const int8x16_t q0_p0 = vqsubq_s8(q0, p0); // (q0-p0)
+ const int8x16_t s1 = vqaddq_s8(q0_p0, q0_p0); // 2 * (q0 - p0)
+ const int8x16_t s2 = vqaddq_s8(q0_p0, s1); // 3 * (q0 - p0)
+ return s2;
+}
+
+//------------------------------------------------------------------------------
+
+static void ApplyFilter2NoFlip(const int8x16_t p0s, const int8x16_t q0s,
+ const int8x16_t delta,
+ int8x16_t* const op0, int8x16_t* const oq0) {
+ const int8x16_t kCst3 = vdupq_n_s8(0x03);
+ const int8x16_t kCst4 = vdupq_n_s8(0x04);
+ const int8x16_t delta_p3 = vqaddq_s8(delta, kCst3);
+ const int8x16_t delta_p4 = vqaddq_s8(delta, kCst4);
+ const int8x16_t delta3 = vshrq_n_s8(delta_p3, 3);
+ const int8x16_t delta4 = vshrq_n_s8(delta_p4, 3);
+ *op0 = vqaddq_s8(p0s, delta3);
+ *oq0 = vqsubq_s8(q0s, delta4);
+}
+
+#if defined(WEBP_USE_INTRINSICS)
+
+static void ApplyFilter2(const int8x16_t p0s, const int8x16_t q0s,
+ const int8x16_t delta,
+ uint8x16_t* const op0, uint8x16_t* const oq0) {
+ const int8x16_t kCst3 = vdupq_n_s8(0x03);
+ const int8x16_t kCst4 = vdupq_n_s8(0x04);
+ const int8x16_t delta_p3 = vqaddq_s8(delta, kCst3);
+ const int8x16_t delta_p4 = vqaddq_s8(delta, kCst4);
+ const int8x16_t delta3 = vshrq_n_s8(delta_p3, 3);
+ const int8x16_t delta4 = vshrq_n_s8(delta_p4, 3);
+ const int8x16_t sp0 = vqaddq_s8(p0s, delta3);
+ const int8x16_t sq0 = vqsubq_s8(q0s, delta4);
+ *op0 = FlipSignBack(sp0);
+ *oq0 = FlipSignBack(sq0);
+}
+
+static void DoFilter2(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ const uint8x16_t mask,
+ uint8x16_t* const op0, uint8x16_t* const oq0) {
+ const int8x16_t p1s = FlipSign(p1);
+ const int8x16_t p0s = FlipSign(p0);
+ const int8x16_t q0s = FlipSign(q0);
+ const int8x16_t q1s = FlipSign(q1);
+ const int8x16_t delta0 = GetBaseDelta(p1s, p0s, q0s, q1s);
+ const int8x16_t delta1 = vandq_s8(delta0, vreinterpretq_s8_u8(mask));
+ ApplyFilter2(p0s, q0s, delta1, op0, oq0);
+}
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+ uint8x16_t p1, p0, q0, q1, op0, oq0;
+ Load16x4(p, stride, &p1, &p0, &q0, &q1);
+ {
+ const uint8x16_t mask = NeedsFilter(p1, p0, q0, q1, thresh);
+ DoFilter2(p1, p0, q0, q1, mask, &op0, &oq0);
+ }
+ Store16x2(op0, oq0, p, stride);
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+ uint8x16_t p1, p0, q0, q1, oq0, op0;
+ Load4x16(p, stride, &p1, &p0, &q0, &q1);
+ {
+ const uint8x16_t mask = NeedsFilter(p1, p0, q0, q1, thresh);
+ DoFilter2(p1, p0, q0, q1, mask, &op0, &oq0);
+ }
+ Store2x16(op0, oq0, p, stride);
+}
+
+#else
+
+#define QRegs "q0", "q1", "q2", "q3", \
+ "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
+
+#define FLIP_SIGN_BIT2(a, b, s) \
+ "veor " #a "," #a "," #s " \n" \
+ "veor " #b "," #b "," #s " \n" \
+
+#define FLIP_SIGN_BIT4(a, b, c, d, s) \
+ FLIP_SIGN_BIT2(a, b, s) \
+ FLIP_SIGN_BIT2(c, d, s) \
+
+#define NEEDS_FILTER(p1, p0, q0, q1, thresh, mask) \
+ "vabd.u8 q15," #p0 "," #q0 " \n" /* abs(p0 - q0) */ \
+ "vabd.u8 q14," #p1 "," #q1 " \n" /* abs(p1 - q1) */ \
+ "vqadd.u8 q15, q15, q15 \n" /* abs(p0 - q0) * 2 */ \
+ "vshr.u8 q14, q14, #1 \n" /* abs(p1 - q1) / 2 */ \
+ "vqadd.u8 q15, q15, q14 \n" /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 */ \
+ "vdup.8 q14, " #thresh " \n" \
+ "vcge.u8 " #mask ", q14, q15 \n" /* mask <= thresh */
+
+#define GET_BASE_DELTA(p1, p0, q0, q1, o) \
+ "vqsub.s8 q15," #q0 "," #p0 " \n" /* (q0 - p0) */ \
+ "vqsub.s8 " #o "," #p1 "," #q1 " \n" /* (p1 - q1) */ \
+ "vqadd.s8 " #o "," #o ", q15 \n" /* (p1 - q1) + 1 * (p0 - q0) */ \
+ "vqadd.s8 " #o "," #o ", q15 \n" /* (p1 - q1) + 2 * (p0 - q0) */ \
+ "vqadd.s8 " #o "," #o ", q15 \n" /* (p1 - q1) + 3 * (p0 - q0) */
+
+#define DO_SIMPLE_FILTER(p0, q0, fl) \
+ "vmov.i8 q15, #0x03 \n" \
+ "vqadd.s8 q15, q15, " #fl " \n" /* filter1 = filter + 3 */ \
+ "vshr.s8 q15, q15, #3 \n" /* filter1 >> 3 */ \
+ "vqadd.s8 " #p0 "," #p0 ", q15 \n" /* p0 += filter1 */ \
+ \
+ "vmov.i8 q15, #0x04 \n" \
+ "vqadd.s8 q15, q15, " #fl " \n" /* filter1 = filter + 4 */ \
+ "vshr.s8 q15, q15, #3 \n" /* filter2 >> 3 */ \
+ "vqsub.s8 " #q0 "," #q0 ", q15 \n" /* q0 -= filter2 */
+
+// Applies filter on 2 pixels (p0 and q0)
+#define DO_FILTER2(p1, p0, q0, q1, thresh) \
+ NEEDS_FILTER(p1, p0, q0, q1, thresh, q9) /* filter mask in q9 */ \
+ "vmov.i8 q10, #0x80 \n" /* sign bit */ \
+ FLIP_SIGN_BIT4(p1, p0, q0, q1, q10) /* convert to signed value */ \
+ GET_BASE_DELTA(p1, p0, q0, q1, q11) /* get filter level */ \
+ "vand q9, q9, q11 \n" /* apply filter mask */ \
+ DO_SIMPLE_FILTER(p0, q0, q9) /* apply filter */ \
+ FLIP_SIGN_BIT2(p0, q0, q10)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+ __asm__ volatile (
+ "sub %[p], %[p], %[stride], lsl #1 \n" // p -= 2 * stride
+
+ "vld1.u8 {q1}, [%[p]], %[stride] \n" // p1
+ "vld1.u8 {q2}, [%[p]], %[stride] \n" // p0
+ "vld1.u8 {q3}, [%[p]], %[stride] \n" // q0
+ "vld1.u8 {q12}, [%[p]] \n" // q1
+
+ DO_FILTER2(q1, q2, q3, q12, %[thresh])
+
+ "sub %[p], %[p], %[stride], lsl #1 \n" // p -= 2 * stride
+
+ "vst1.u8 {q2}, [%[p]], %[stride] \n" // store op0
+ "vst1.u8 {q3}, [%[p]] \n" // store oq0
+ : [p] "+r"(p)
+ : [stride] "r"(stride), [thresh] "r"(thresh)
+ : "memory", QRegs
+ );
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+ __asm__ volatile (
+ "sub r4, %[p], #2 \n" // base1 = p - 2
+ "lsl r6, %[stride], #1 \n" // r6 = 2 * stride
+ "add r5, r4, %[stride] \n" // base2 = base1 + stride
+
+ LOAD8x4(d2, d3, d4, d5, [r4], [r5], r6)
+ LOAD8x4(d24, d25, d26, d27, [r4], [r5], r6)
+ "vswp d3, d24 \n" // p1:q1 p0:q3
+ "vswp d5, d26 \n" // q0:q2 q1:q4
+ "vswp q2, q12 \n" // p1:q1 p0:q2 q0:q3 q1:q4
+
+ DO_FILTER2(q1, q2, q12, q13, %[thresh])
+
+ "sub %[p], %[p], #1 \n" // p - 1
+
+ "vswp d5, d24 \n"
+ STORE8x2(d4, d5, [%[p]], %[stride])
+ STORE8x2(d24, d25, [%[p]], %[stride])
+
+ : [p] "+r"(p)
+ : [stride] "r"(stride), [thresh] "r"(thresh)
+ : "memory", "r4", "r5", "r6", QRegs
+ );
+}
+
+#endif // WEBP_USE_INTRINSICS
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+ uint32_t k;
+ for (k = 3; k != 0; --k) {
+ p += 4 * stride;
+ SimpleVFilter16(p, stride, thresh);
+ }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+ uint32_t k;
+ for (k = 3; k != 0; --k) {
+ p += 4;
+ SimpleHFilter16(p, stride, thresh);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Complex In-loop filtering (Paragraph 15.3)
+
+static uint8x16_t NeedsHev(const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ int hev_thresh) {
+ const uint8x16_t hev_thresh_v = vdupq_n_u8((uint8_t)hev_thresh);
+ const uint8x16_t a_p1_p0 = vabdq_u8(p1, p0); // abs(p1 - p0)
+ const uint8x16_t a_q1_q0 = vabdq_u8(q1, q0); // abs(q1 - q0)
+ const uint8x16_t a_max = vmaxq_u8(a_p1_p0, a_q1_q0);
+ const uint8x16_t mask = vcgtq_u8(a_max, hev_thresh_v);
+ return mask;
+}
+
+static uint8x16_t NeedsFilter2(const uint8x16_t p3, const uint8x16_t p2,
+ const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ const uint8x16_t q2, const uint8x16_t q3,
+ int ithresh, int thresh) {
+ const uint8x16_t ithresh_v = vdupq_n_u8((uint8_t)ithresh);
+ const uint8x16_t a_p3_p2 = vabdq_u8(p3, p2); // abs(p3 - p2)
+ const uint8x16_t a_p2_p1 = vabdq_u8(p2, p1); // abs(p2 - p1)
+ const uint8x16_t a_p1_p0 = vabdq_u8(p1, p0); // abs(p1 - p0)
+ const uint8x16_t a_q3_q2 = vabdq_u8(q3, q2); // abs(q3 - q2)
+ const uint8x16_t a_q2_q1 = vabdq_u8(q2, q1); // abs(q2 - q1)
+ const uint8x16_t a_q1_q0 = vabdq_u8(q1, q0); // abs(q1 - q0)
+ const uint8x16_t max1 = vmaxq_u8(a_p3_p2, a_p2_p1);
+ const uint8x16_t max2 = vmaxq_u8(a_p1_p0, a_q3_q2);
+ const uint8x16_t max3 = vmaxq_u8(a_q2_q1, a_q1_q0);
+ const uint8x16_t max12 = vmaxq_u8(max1, max2);
+ const uint8x16_t max123 = vmaxq_u8(max12, max3);
+ const uint8x16_t mask2 = vcgeq_u8(ithresh_v, max123);
+ const uint8x16_t mask1 = NeedsFilter(p1, p0, q0, q1, thresh);
+ const uint8x16_t mask = vandq_u8(mask1, mask2);
+ return mask;
+}
+
+// 4-points filter
+
+static void ApplyFilter4(
+ const int8x16_t p1, const int8x16_t p0,
+ const int8x16_t q0, const int8x16_t q1,
+ const int8x16_t delta0,
+ uint8x16_t* const op1, uint8x16_t* const op0,
+ uint8x16_t* const oq0, uint8x16_t* const oq1) {
+ const int8x16_t kCst3 = vdupq_n_s8(0x03);
+ const int8x16_t kCst4 = vdupq_n_s8(0x04);
+ const int8x16_t delta1 = vqaddq_s8(delta0, kCst4);
+ const int8x16_t delta2 = vqaddq_s8(delta0, kCst3);
+ const int8x16_t a1 = vshrq_n_s8(delta1, 3);
+ const int8x16_t a2 = vshrq_n_s8(delta2, 3);
+ const int8x16_t a3 = vrshrq_n_s8(a1, 1); // a3 = (a1 + 1) >> 1
+ *op0 = FlipSignBack(vqaddq_s8(p0, a2)); // clip(p0 + a2)
+ *oq0 = FlipSignBack(vqsubq_s8(q0, a1)); // clip(q0 - a1)
+ *op1 = FlipSignBack(vqaddq_s8(p1, a3)); // clip(p1 + a3)
+ *oq1 = FlipSignBack(vqsubq_s8(q1, a3)); // clip(q1 - a3)
+}
+
+static void DoFilter4(
+ const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1,
+ const uint8x16_t mask, const uint8x16_t hev_mask,
+ uint8x16_t* const op1, uint8x16_t* const op0,
+ uint8x16_t* const oq0, uint8x16_t* const oq1) {
+ // This is a fused version of DoFilter2() calling ApplyFilter2 directly
+ const int8x16_t p1s = FlipSign(p1);
+ int8x16_t p0s = FlipSign(p0);
+ int8x16_t q0s = FlipSign(q0);
+ const int8x16_t q1s = FlipSign(q1);
+ const uint8x16_t simple_lf_mask = vandq_u8(mask, hev_mask);
+
+ // do_filter2 part (simple loopfilter on pixels with hev)
+ {
+ const int8x16_t delta = GetBaseDelta(p1s, p0s, q0s, q1s);
+ const int8x16_t simple_lf_delta =
+ vandq_s8(delta, vreinterpretq_s8_u8(simple_lf_mask));
+ ApplyFilter2NoFlip(p0s, q0s, simple_lf_delta, &p0s, &q0s);
+ }
+
+ // do_filter4 part (complex loopfilter on pixels without hev)
+ {
+ const int8x16_t delta0 = GetBaseDelta0(p0s, q0s);
+ // we use: (mask & hev_mask) ^ mask = mask & !hev_mask
+ const uint8x16_t complex_lf_mask = veorq_u8(simple_lf_mask, mask);
+ const int8x16_t complex_lf_delta =
+ vandq_s8(delta0, vreinterpretq_s8_u8(complex_lf_mask));
+ ApplyFilter4(p1s, p0s, q0s, q1s, complex_lf_delta, op1, op0, oq0, oq1);
+ }
+}
+
+// 6-points filter
+
+static void ApplyFilter6(
+ const int8x16_t p2, const int8x16_t p1, const int8x16_t p0,
+ const int8x16_t q0, const int8x16_t q1, const int8x16_t q2,
+ const int8x16_t delta,
+ uint8x16_t* const op2, uint8x16_t* const op1, uint8x16_t* const op0,
+ uint8x16_t* const oq0, uint8x16_t* const oq1, uint8x16_t* const oq2) {
+ // We have to compute: X = (9*a+63) >> 7, Y = (18*a+63)>>7, Z = (27*a+63) >> 7
+ // Turns out, there's a common sub-expression S=9 * a - 1 that can be used
+ // with the special vqrshrn_n_s16 rounding-shift-and-narrow instruction:
+ // X = (S + 64) >> 7, Y = (S + 32) >> 6, Z = (18 * a + S + 64) >> 7
+ const int8x8_t delta_lo = vget_low_s8(delta);
+ const int8x8_t delta_hi = vget_high_s8(delta);
+ const int8x8_t kCst9 = vdup_n_s8(9);
+ const int16x8_t kCstm1 = vdupq_n_s16(-1);
+ const int8x8_t kCst18 = vdup_n_s8(18);
+ const int16x8_t S_lo = vmlal_s8(kCstm1, kCst9, delta_lo); // S = 9 * a - 1
+ const int16x8_t S_hi = vmlal_s8(kCstm1, kCst9, delta_hi);
+ const int16x8_t Z_lo = vmlal_s8(S_lo, kCst18, delta_lo); // S + 18 * a
+ const int16x8_t Z_hi = vmlal_s8(S_hi, kCst18, delta_hi);
+ const int8x8_t a3_lo = vqrshrn_n_s16(S_lo, 7); // (9 * a + 63) >> 7
+ const int8x8_t a3_hi = vqrshrn_n_s16(S_hi, 7);
+ const int8x8_t a2_lo = vqrshrn_n_s16(S_lo, 6); // (9 * a + 31) >> 6
+ const int8x8_t a2_hi = vqrshrn_n_s16(S_hi, 6);
+ const int8x8_t a1_lo = vqrshrn_n_s16(Z_lo, 7); // (27 * a + 63) >> 7
+ const int8x8_t a1_hi = vqrshrn_n_s16(Z_hi, 7);
+ const int8x16_t a1 = vcombine_s8(a1_lo, a1_hi);
+ const int8x16_t a2 = vcombine_s8(a2_lo, a2_hi);
+ const int8x16_t a3 = vcombine_s8(a3_lo, a3_hi);
+
+ *op0 = FlipSignBack(vqaddq_s8(p0, a1)); // clip(p0 + a1)
+ *oq0 = FlipSignBack(vqsubq_s8(q0, a1)); // clip(q0 - q1)
+ *oq1 = FlipSignBack(vqsubq_s8(q1, a2)); // clip(q1 - a2)
+ *op1 = FlipSignBack(vqaddq_s8(p1, a2)); // clip(p1 + a2)
+ *oq2 = FlipSignBack(vqsubq_s8(q2, a3)); // clip(q2 - a3)
+ *op2 = FlipSignBack(vqaddq_s8(p2, a3)); // clip(p2 + a3)
+}
+
+static void DoFilter6(
+ const uint8x16_t p2, const uint8x16_t p1, const uint8x16_t p0,
+ const uint8x16_t q0, const uint8x16_t q1, const uint8x16_t q2,
+ const uint8x16_t mask, const uint8x16_t hev_mask,
+ uint8x16_t* const op2, uint8x16_t* const op1, uint8x16_t* const op0,
+ uint8x16_t* const oq0, uint8x16_t* const oq1, uint8x16_t* const oq2) {
+ // This is a fused version of DoFilter2() calling ApplyFilter2 directly
+ const int8x16_t p2s = FlipSign(p2);
+ const int8x16_t p1s = FlipSign(p1);
+ int8x16_t p0s = FlipSign(p0);
+ int8x16_t q0s = FlipSign(q0);
+ const int8x16_t q1s = FlipSign(q1);
+ const int8x16_t q2s = FlipSign(q2);
+ const uint8x16_t simple_lf_mask = vandq_u8(mask, hev_mask);
+ const int8x16_t delta0 = GetBaseDelta(p1s, p0s, q0s, q1s);
+
+ // do_filter2 part (simple loopfilter on pixels with hev)
+ {
+ const int8x16_t simple_lf_delta =
+ vandq_s8(delta0, vreinterpretq_s8_u8(simple_lf_mask));
+ ApplyFilter2NoFlip(p0s, q0s, simple_lf_delta, &p0s, &q0s);
+ }
+
+ // do_filter6 part (complex loopfilter on pixels without hev)
+ {
+ // we use: (mask & hev_mask) ^ mask = mask & !hev_mask
+ const uint8x16_t complex_lf_mask = veorq_u8(simple_lf_mask, mask);
+ const int8x16_t complex_lf_delta =
+ vandq_s8(delta0, vreinterpretq_s8_u8(complex_lf_mask));
+ ApplyFilter6(p2s, p1s, p0s, q0s, q1s, q2s, complex_lf_delta,
+ op2, op1, op0, oq0, oq1, oq2);
+ }
+}
+
+// on macroblock edges
+
+static void VFilter16(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+ Load16x8(p, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+ ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+ DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+ &op2, &op1, &op0, &oq0, &oq1, &oq2);
+ Store16x2(op2, op1, p - 2 * stride, stride);
+ Store16x2(op0, oq0, p + 0 * stride, stride);
+ Store16x2(oq1, oq2, p + 2 * stride, stride);
+ }
+}
+
+static void HFilter16(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+ Load8x16(p, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+ ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+ DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+ &op2, &op1, &op0, &oq0, &oq1, &oq2);
+ Store2x16(op2, op1, p - 2, stride);
+ Store2x16(op0, oq0, p + 0, stride);
+ Store2x16(oq1, oq2, p + 2, stride);
+ }
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint32_t k;
+ uint8x16_t p3, p2, p1, p0;
+ Load16x4(p + 2 * stride, stride, &p3, &p2, &p1, &p0);
+ for (k = 3; k != 0; --k) {
+ uint8x16_t q0, q1, q2, q3;
+ p += 4 * stride;
+ Load16x4(p + 2 * stride, stride, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask =
+ NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3, ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ // p3 and p2 are not just temporary variables here: they will be
+ // re-used for next span. And q2/q3 will become p1/p0 accordingly.
+ DoFilter4(p1, p0, q0, q1, mask, hev_mask, &p1, &p0, &p3, &p2);
+ Store16x4(p1, p0, p3, p2, p, stride);
+ p1 = q2;
+ p0 = q3;
+ }
+ }
+}
+
+#if !defined(WORK_AROUND_GCC)
+static void HFilter16i(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint32_t k;
+ uint8x16_t p3, p2, p1, p0;
+ Load4x16(p + 2, stride, &p3, &p2, &p1, &p0);
+ for (k = 3; k != 0; --k) {
+ uint8x16_t q0, q1, q2, q3;
+ p += 4;
+ Load4x16(p + 2, stride, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask =
+ NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3, ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ DoFilter4(p1, p0, q0, q1, mask, hev_mask, &p1, &p0, &p3, &p2);
+ Store4x16(p1, p0, p3, p2, p, stride);
+ p1 = q2;
+ p0 = q3;
+ }
+ }
+}
+#endif // !WORK_AROUND_GCC
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+ Load8x8x2(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+ ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+ DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+ &op2, &op1, &op0, &oq0, &oq1, &oq2);
+ Store8x2x2(op2, op1, u - 2 * stride, v - 2 * stride, stride);
+ Store8x2x2(op0, oq0, u + 0 * stride, v + 0 * stride, stride);
+ Store8x2x2(oq1, oq2, u + 2 * stride, v + 2 * stride, stride);
+ }
+}
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+ u += 4 * stride;
+ v += 4 * stride;
+ Load8x8x2(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+ ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ uint8x16_t op1, op0, oq0, oq1;
+ DoFilter4(p1, p0, q0, q1, mask, hev_mask, &op1, &op0, &oq0, &oq1);
+ Store8x4x2(op1, op0, oq0, oq1, u, v, stride);
+ }
+}
+
+#if !defined(WORK_AROUND_GCC)
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+ Load8x8x2T(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+ ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ uint8x16_t op2, op1, op0, oq0, oq1, oq2;
+ DoFilter6(p2, p1, p0, q0, q1, q2, mask, hev_mask,
+ &op2, &op1, &op0, &oq0, &oq1, &oq2);
+ Store6x8x2(op2, op1, op0, oq0, oq1, oq2, u, v, stride);
+ }
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ uint8x16_t p3, p2, p1, p0, q0, q1, q2, q3;
+ u += 4;
+ v += 4;
+ Load8x8x2T(u, v, stride, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3);
+ {
+ const uint8x16_t mask = NeedsFilter2(p3, p2, p1, p0, q0, q1, q2, q3,
+ ithresh, thresh);
+ const uint8x16_t hev_mask = NeedsHev(p1, p0, q0, q1, hev_thresh);
+ uint8x16_t op1, op0, oq0, oq1;
+ DoFilter4(p1, p0, q0, q1, mask, hev_mask, &op1, &op0, &oq0, &oq1);
+ Store4x8x2(op1, op0, oq0, oq1, u, v, stride);
+ }
+}
+#endif // !WORK_AROUND_GCC
+
+//-----------------------------------------------------------------------------
+// Inverse transforms (Paragraph 14.4)
+
+// Technically these are unsigned but vqdmulh is only available in signed.
+// vqdmulh returns high half (effectively >> 16) but also doubles the value,
+// changing the >> 16 to >> 15 and requiring an additional >> 1.
+// We use this to our advantage with kC2. The canonical value is 35468.
+// However, the high bit is set so treating it as signed will give incorrect
+// results. We avoid this by down shifting by 1 here to clear the highest bit.
+// Combined with the doubling effect of vqdmulh we get >> 16.
+// This can not be applied to kC1 because the lowest bit is set. Down shifting
+// the constant would reduce precision.
+
+// libwebp uses a trick to avoid some extra addition that libvpx does.
+// Instead of:
+// temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16);
+// libwebp adds 1 << 16 to cospi8sqrt2minus1 (kC1). However, this causes the
+// same issue with kC1 and vqdmulh that we work around by down shifting kC2
+
+static const int16_t kC1 = 20091;
+static const int16_t kC2 = 17734; // half of kC2, actually. See comment above.
+
+#if defined(WEBP_USE_INTRINSICS)
+static WEBP_INLINE void Transpose8x2(const int16x8_t in0, const int16x8_t in1,
+ int16x8x2_t* const out) {
+ // a0 a1 a2 a3 | b0 b1 b2 b3 => a0 b0 c0 d0 | a1 b1 c1 d1
+ // c0 c1 c2 c3 | d0 d1 d2 d3 a2 b2 c2 d2 | a3 b3 c3 d3
+ const int16x8x2_t tmp0 = vzipq_s16(in0, in1); // a0 c0 a1 c1 a2 c2 ...
+ // b0 d0 b1 d1 b2 d2 ...
+ *out = vzipq_s16(tmp0.val[0], tmp0.val[1]);
+}
+
+static WEBP_INLINE void TransformPass(int16x8x2_t* const rows) {
+ // {rows} = in0 | in4
+ // in8 | in12
+ // B1 = in4 | in12
+ const int16x8_t B1 =
+ vcombine_s16(vget_high_s16(rows->val[0]), vget_high_s16(rows->val[1]));
+ // C0 = kC1 * in4 | kC1 * in12
+ // C1 = kC2 * in4 | kC2 * in12
+ const int16x8_t C0 = vsraq_n_s16(B1, vqdmulhq_n_s16(B1, kC1), 1);
+ const int16x8_t C1 = vqdmulhq_n_s16(B1, kC2);
+ const int16x4_t a = vqadd_s16(vget_low_s16(rows->val[0]),
+ vget_low_s16(rows->val[1])); // in0 + in8
+ const int16x4_t b = vqsub_s16(vget_low_s16(rows->val[0]),
+ vget_low_s16(rows->val[1])); // in0 - in8
+ // c = kC2 * in4 - kC1 * in12
+ // d = kC1 * in4 + kC2 * in12
+ const int16x4_t c = vqsub_s16(vget_low_s16(C1), vget_high_s16(C0));
+ const int16x4_t d = vqadd_s16(vget_low_s16(C0), vget_high_s16(C1));
+ const int16x8_t D0 = vcombine_s16(a, b); // D0 = a | b
+ const int16x8_t D1 = vcombine_s16(d, c); // D1 = d | c
+ const int16x8_t E0 = vqaddq_s16(D0, D1); // a+d | b+c
+ const int16x8_t E_tmp = vqsubq_s16(D0, D1); // a-d | b-c
+ const int16x8_t E1 = vcombine_s16(vget_high_s16(E_tmp), vget_low_s16(E_tmp));
+ Transpose8x2(E0, E1, rows);
+}
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+ int16x8x2_t rows;
+ INIT_VECTOR2(rows, vld1q_s16(in + 0), vld1q_s16(in + 8));
+ TransformPass(&rows);
+ TransformPass(&rows);
+ Add4x4(rows.val[0], rows.val[1], dst);
+}
+
+#else
+
+static void TransformOne(const int16_t* in, uint8_t* dst) {
+ const int kBPS = BPS;
+ // kC1, kC2. Padded because vld1.16 loads 8 bytes
+ const int16_t constants[4] = { kC1, kC2, 0, 0 };
+ /* Adapted from libvpx: vp8/common/arm/neon/shortidct4x4llm_neon.asm */
+ __asm__ volatile (
+ "vld1.16 {q1, q2}, [%[in]] \n"
+ "vld1.16 {d0}, [%[constants]] \n"
+
+ /* d2: in[0]
+ * d3: in[8]
+ * d4: in[4]
+ * d5: in[12]
+ */
+ "vswp d3, d4 \n"
+
+ /* q8 = {in[4], in[12]} * kC1 * 2 >> 16
+ * q9 = {in[4], in[12]} * kC2 >> 16
+ */
+ "vqdmulh.s16 q8, q2, d0[0] \n"
+ "vqdmulh.s16 q9, q2, d0[1] \n"
+
+ /* d22 = a = in[0] + in[8]
+ * d23 = b = in[0] - in[8]
+ */
+ "vqadd.s16 d22, d2, d3 \n"
+ "vqsub.s16 d23, d2, d3 \n"
+
+ /* The multiplication should be x * kC1 >> 16
+ * However, with vqdmulh we get x * kC1 * 2 >> 16
+ * (multiply, double, return high half)
+ * We avoided this in kC2 by pre-shifting the constant.
+ * q8 = in[4]/[12] * kC1 >> 16
+ */
+ "vshr.s16 q8, q8, #1 \n"
+
+ /* Add {in[4], in[12]} back after the multiplication. This is handled by
+ * adding 1 << 16 to kC1 in the libwebp C code.
+ */
+ "vqadd.s16 q8, q2, q8 \n"
+
+ /* d20 = c = in[4]*kC2 - in[12]*kC1
+ * d21 = d = in[4]*kC1 + in[12]*kC2
+ */
+ "vqsub.s16 d20, d18, d17 \n"
+ "vqadd.s16 d21, d19, d16 \n"
+
+ /* d2 = tmp[0] = a + d
+ * d3 = tmp[1] = b + c
+ * d4 = tmp[2] = b - c
+ * d5 = tmp[3] = a - d
+ */
+ "vqadd.s16 d2, d22, d21 \n"
+ "vqadd.s16 d3, d23, d20 \n"
+ "vqsub.s16 d4, d23, d20 \n"
+ "vqsub.s16 d5, d22, d21 \n"
+
+ "vzip.16 q1, q2 \n"
+ "vzip.16 q1, q2 \n"
+
+ "vswp d3, d4 \n"
+
+ /* q8 = {tmp[4], tmp[12]} * kC1 * 2 >> 16
+ * q9 = {tmp[4], tmp[12]} * kC2 >> 16
+ */
+ "vqdmulh.s16 q8, q2, d0[0] \n"
+ "vqdmulh.s16 q9, q2, d0[1] \n"
+
+ /* d22 = a = tmp[0] + tmp[8]
+ * d23 = b = tmp[0] - tmp[8]
+ */
+ "vqadd.s16 d22, d2, d3 \n"
+ "vqsub.s16 d23, d2, d3 \n"
+
+ /* See long winded explanations prior */
+ "vshr.s16 q8, q8, #1 \n"
+ "vqadd.s16 q8, q2, q8 \n"
+
+ /* d20 = c = in[4]*kC2 - in[12]*kC1
+ * d21 = d = in[4]*kC1 + in[12]*kC2
+ */
+ "vqsub.s16 d20, d18, d17 \n"
+ "vqadd.s16 d21, d19, d16 \n"
+
+ /* d2 = tmp[0] = a + d
+ * d3 = tmp[1] = b + c
+ * d4 = tmp[2] = b - c
+ * d5 = tmp[3] = a - d
+ */
+ "vqadd.s16 d2, d22, d21 \n"
+ "vqadd.s16 d3, d23, d20 \n"
+ "vqsub.s16 d4, d23, d20 \n"
+ "vqsub.s16 d5, d22, d21 \n"
+
+ "vld1.32 d6[0], [%[dst]], %[kBPS] \n"
+ "vld1.32 d6[1], [%[dst]], %[kBPS] \n"
+ "vld1.32 d7[0], [%[dst]], %[kBPS] \n"
+ "vld1.32 d7[1], [%[dst]], %[kBPS] \n"
+
+ "sub %[dst], %[dst], %[kBPS], lsl #2 \n"
+
+ /* (val) + 4 >> 3 */
+ "vrshr.s16 d2, d2, #3 \n"
+ "vrshr.s16 d3, d3, #3 \n"
+ "vrshr.s16 d4, d4, #3 \n"
+ "vrshr.s16 d5, d5, #3 \n"
+
+ "vzip.16 q1, q2 \n"
+ "vzip.16 q1, q2 \n"
+
+ /* Must accumulate before saturating */
+ "vmovl.u8 q8, d6 \n"
+ "vmovl.u8 q9, d7 \n"
+
+ "vqadd.s16 q1, q1, q8 \n"
+ "vqadd.s16 q2, q2, q9 \n"
+
+ "vqmovun.s16 d0, q1 \n"
+ "vqmovun.s16 d1, q2 \n"
+
+ "vst1.32 d0[0], [%[dst]], %[kBPS] \n"
+ "vst1.32 d0[1], [%[dst]], %[kBPS] \n"
+ "vst1.32 d1[0], [%[dst]], %[kBPS] \n"
+ "vst1.32 d1[1], [%[dst]] \n"
+
+ : [in] "+r"(in), [dst] "+r"(dst) /* modified registers */
+ : [kBPS] "r"(kBPS), [constants] "r"(constants) /* constants */
+ : "memory", "q0", "q1", "q2", "q8", "q9", "q10", "q11" /* clobbered */
+ );
+}
+
+#endif // WEBP_USE_INTRINSICS
+
+static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
+ TransformOne(in, dst);
+ if (do_two) {
+ TransformOne(in + 16, dst + 4);
+ }
+}
+
+static void TransformDC(const int16_t* in, uint8_t* dst) {
+ const int16x8_t DC = vdupq_n_s16(in[0]);
+ Add4x4(DC, DC, dst);
+}
+
+//------------------------------------------------------------------------------
+
+#define STORE_WHT(dst, col, rows) do { \
+ *dst = vgetq_lane_s32(rows.val[0], col); (dst) += 16; \
+ *dst = vgetq_lane_s32(rows.val[1], col); (dst) += 16; \
+ *dst = vgetq_lane_s32(rows.val[2], col); (dst) += 16; \
+ *dst = vgetq_lane_s32(rows.val[3], col); (dst) += 16; \
+} while (0)
+
+static void TransformWHT(const int16_t* in, int16_t* out) {
+ int32x4x4_t tmp;
+
+ {
+ // Load the source.
+ const int16x4_t in00_03 = vld1_s16(in + 0);
+ const int16x4_t in04_07 = vld1_s16(in + 4);
+ const int16x4_t in08_11 = vld1_s16(in + 8);
+ const int16x4_t in12_15 = vld1_s16(in + 12);
+ const int32x4_t a0 = vaddl_s16(in00_03, in12_15); // in[0..3] + in[12..15]
+ const int32x4_t a1 = vaddl_s16(in04_07, in08_11); // in[4..7] + in[8..11]
+ const int32x4_t a2 = vsubl_s16(in04_07, in08_11); // in[4..7] - in[8..11]
+ const int32x4_t a3 = vsubl_s16(in00_03, in12_15); // in[0..3] - in[12..15]
+ tmp.val[0] = vaddq_s32(a0, a1);
+ tmp.val[1] = vaddq_s32(a3, a2);
+ tmp.val[2] = vsubq_s32(a0, a1);
+ tmp.val[3] = vsubq_s32(a3, a2);
+ // Arrange the temporary results column-wise.
+ tmp = Transpose4x4(tmp);
+ }
+
+ {
+ const int32x4_t kCst3 = vdupq_n_s32(3);
+ const int32x4_t dc = vaddq_s32(tmp.val[0], kCst3); // add rounder
+ const int32x4_t a0 = vaddq_s32(dc, tmp.val[3]);
+ const int32x4_t a1 = vaddq_s32(tmp.val[1], tmp.val[2]);
+ const int32x4_t a2 = vsubq_s32(tmp.val[1], tmp.val[2]);
+ const int32x4_t a3 = vsubq_s32(dc, tmp.val[3]);
+
+ tmp.val[0] = vaddq_s32(a0, a1);
+ tmp.val[1] = vaddq_s32(a3, a2);
+ tmp.val[2] = vsubq_s32(a0, a1);
+ tmp.val[3] = vsubq_s32(a3, a2);
+
+ // right shift the results by 3.
+ tmp.val[0] = vshrq_n_s32(tmp.val[0], 3);
+ tmp.val[1] = vshrq_n_s32(tmp.val[1], 3);
+ tmp.val[2] = vshrq_n_s32(tmp.val[2], 3);
+ tmp.val[3] = vshrq_n_s32(tmp.val[3], 3);
+
+ STORE_WHT(out, 0, tmp);
+ STORE_WHT(out, 1, tmp);
+ STORE_WHT(out, 2, tmp);
+ STORE_WHT(out, 3, tmp);
+ }
+}
+
+#undef STORE_WHT
+
+//------------------------------------------------------------------------------
+
+#define MUL(a, b) (((a) * (b)) >> 16)
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+ static const int kC1_full = 20091 + (1 << 16);
+ static const int kC2_full = 35468;
+ const int16x4_t A = vld1_dup_s16(in);
+ const int16x4_t c4 = vdup_n_s16(MUL(in[4], kC2_full));
+ const int16x4_t d4 = vdup_n_s16(MUL(in[4], kC1_full));
+ const int c1 = MUL(in[1], kC2_full);
+ const int d1 = MUL(in[1], kC1_full);
+ const uint64_t cd = (uint64_t)( d1 & 0xffff) << 0 |
+ (uint64_t)( c1 & 0xffff) << 16 |
+ (uint64_t)(-c1 & 0xffff) << 32 |
+ (uint64_t)(-d1 & 0xffff) << 48;
+ const int16x4_t CD = vcreate_s16(cd);
+ const int16x4_t B = vqadd_s16(A, CD);
+ const int16x8_t m0_m1 = vcombine_s16(vqadd_s16(B, d4), vqadd_s16(B, c4));
+ const int16x8_t m2_m3 = vcombine_s16(vqsub_s16(B, c4), vqsub_s16(B, d4));
+ Add4x4(m0_m1, m2_m3, dst);
+}
+#undef MUL
+
+//------------------------------------------------------------------------------
+// 4x4
+
+static void DC4(uint8_t* dst) { // DC
+ const uint8x8_t A = vld1_u8(dst - BPS); // top row
+ const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
+ const uint16x4_t p1 = vpadd_u16(p0, p0);
+ const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
+ const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
+ const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
+ const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
+ const uint16x8_t s0 = vaddq_u16(L0, L1);
+ const uint16x8_t s1 = vaddq_u16(L2, L3);
+ const uint16x8_t s01 = vaddq_u16(s0, s1);
+ const uint16x8_t sum = vaddq_u16(s01, vcombine_u16(p1, p1));
+ const uint8x8_t dc0 = vrshrn_n_u16(sum, 3); // (sum + 4) >> 3
+ const uint8x8_t dc = vdup_lane_u8(dc0, 0);
+ int i;
+ for (i = 0; i < 4; ++i) {
+ vst1_lane_u32((uint32_t*)(dst + i * BPS), vreinterpret_u32_u8(dc), 0);
+ }
+}
+
+// TrueMotion (4x4 + 8x8)
+static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
+ const uint8x8_t TL = vld1_dup_u8(dst - BPS - 1); // top-left pixel 'A[-1]'
+ const uint8x8_t T = vld1_u8(dst - BPS); // top row 'A[0..3]'
+ const int16x8_t d = vreinterpretq_s16_u16(vsubl_u8(T, TL)); // A[c] - A[-1]
+ int y;
+ for (y = 0; y < size; y += 4) {
+ // left edge
+ const int16x8_t L0 = ConvertU8ToS16(vld1_dup_u8(dst + 0 * BPS - 1));
+ const int16x8_t L1 = ConvertU8ToS16(vld1_dup_u8(dst + 1 * BPS - 1));
+ const int16x8_t L2 = ConvertU8ToS16(vld1_dup_u8(dst + 2 * BPS - 1));
+ const int16x8_t L3 = ConvertU8ToS16(vld1_dup_u8(dst + 3 * BPS - 1));
+ const int16x8_t r0 = vaddq_s16(L0, d); // L[r] + A[c] - A[-1]
+ const int16x8_t r1 = vaddq_s16(L1, d);
+ const int16x8_t r2 = vaddq_s16(L2, d);
+ const int16x8_t r3 = vaddq_s16(L3, d);
+ // Saturate and store the result.
+ const uint32x2_t r0_u32 = vreinterpret_u32_u8(vqmovun_s16(r0));
+ const uint32x2_t r1_u32 = vreinterpret_u32_u8(vqmovun_s16(r1));
+ const uint32x2_t r2_u32 = vreinterpret_u32_u8(vqmovun_s16(r2));
+ const uint32x2_t r3_u32 = vreinterpret_u32_u8(vqmovun_s16(r3));
+ if (size == 4) {
+ vst1_lane_u32((uint32_t*)(dst + 0 * BPS), r0_u32, 0);
+ vst1_lane_u32((uint32_t*)(dst + 1 * BPS), r1_u32, 0);
+ vst1_lane_u32((uint32_t*)(dst + 2 * BPS), r2_u32, 0);
+ vst1_lane_u32((uint32_t*)(dst + 3 * BPS), r3_u32, 0);
+ } else {
+ vst1_u32((uint32_t*)(dst + 0 * BPS), r0_u32);
+ vst1_u32((uint32_t*)(dst + 1 * BPS), r1_u32);
+ vst1_u32((uint32_t*)(dst + 2 * BPS), r2_u32);
+ vst1_u32((uint32_t*)(dst + 3 * BPS), r3_u32);
+ }
+ dst += 4 * BPS;
+ }
+}
+
+static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
+
+static void VE4(uint8_t* dst) { // vertical
+ // NB: avoid vld1_u64 here as an alignment hint may be added -> SIGBUS.
+ const uint64x1_t A0 = vreinterpret_u64_u8(vld1_u8(dst - BPS - 1)); // top row
+ const uint64x1_t A1 = vshr_n_u64(A0, 8);
+ const uint64x1_t A2 = vshr_n_u64(A0, 16);
+ const uint8x8_t ABCDEFGH = vreinterpret_u8_u64(A0);
+ const uint8x8_t BCDEFGH0 = vreinterpret_u8_u64(A1);
+ const uint8x8_t CDEFGH00 = vreinterpret_u8_u64(A2);
+ const uint8x8_t b = vhadd_u8(ABCDEFGH, CDEFGH00);
+ const uint8x8_t avg = vrhadd_u8(b, BCDEFGH0);
+ int i;
+ for (i = 0; i < 4; ++i) {
+ vst1_lane_u32((uint32_t*)(dst + i * BPS), vreinterpret_u32_u8(avg), 0);
+ }
+}
+
+static void RD4(uint8_t* dst) { // Down-right
+ const uint8x8_t XABCD_u8 = vld1_u8(dst - BPS - 1);
+ const uint64x1_t XABCD = vreinterpret_u64_u8(XABCD_u8);
+ const uint64x1_t ____XABC = vshl_n_u64(XABCD, 32);
+ const uint32_t I = dst[-1 + 0 * BPS];
+ const uint32_t J = dst[-1 + 1 * BPS];
+ const uint32_t K = dst[-1 + 2 * BPS];
+ const uint32_t L = dst[-1 + 3 * BPS];
+ const uint64x1_t LKJI____ = vcreate_u64(L | (K << 8) | (J << 16) | (I << 24));
+ const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
+ const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
+ const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
+ const uint8_t D = vget_lane_u8(XABCD_u8, 4);
+ const uint8x8_t JIXABCD_ = vset_lane_u8(D, JIXABC__, 6);
+ const uint8x8_t LKJIXABC_u8 = vreinterpret_u8_u64(LKJIXABC);
+ const uint8x8_t avg1 = vhadd_u8(JIXABCD_, LKJIXABC_u8);
+ const uint8x8_t avg2 = vrhadd_u8(avg1, KJIXABC_);
+ const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
+ const uint32x2_t r3 = vreinterpret_u32_u8(avg2);
+ const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
+ const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
+ const uint32x2_t r0 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
+ vst1_lane_u32((uint32_t*)(dst + 0 * BPS), r0, 0);
+ vst1_lane_u32((uint32_t*)(dst + 1 * BPS), r1, 0);
+ vst1_lane_u32((uint32_t*)(dst + 2 * BPS), r2, 0);
+ vst1_lane_u32((uint32_t*)(dst + 3 * BPS), r3, 0);
+}
+
+static void LD4(uint8_t* dst) { // Down-left
+ // Note using the same shift trick as VE4() is slower here.
+ const uint8x8_t ABCDEFGH = vld1_u8(dst - BPS + 0);
+ const uint8x8_t BCDEFGH0 = vld1_u8(dst - BPS + 1);
+ const uint8x8_t CDEFGH00 = vld1_u8(dst - BPS + 2);
+ const uint8x8_t CDEFGHH0 = vset_lane_u8(dst[-BPS + 7], CDEFGH00, 6);
+ const uint8x8_t avg1 = vhadd_u8(ABCDEFGH, CDEFGHH0);
+ const uint8x8_t avg2 = vrhadd_u8(avg1, BCDEFGH0);
+ const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
+ const uint32x2_t r0 = vreinterpret_u32_u8(avg2);
+ const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
+ const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
+ const uint32x2_t r3 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
+ vst1_lane_u32((uint32_t*)(dst + 0 * BPS), r0, 0);
+ vst1_lane_u32((uint32_t*)(dst + 1 * BPS), r1, 0);
+ vst1_lane_u32((uint32_t*)(dst + 2 * BPS), r2, 0);
+ vst1_lane_u32((uint32_t*)(dst + 3 * BPS), r3, 0);
+}
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static void VE8uv(uint8_t* dst) { // vertical
+ const uint8x8_t top = vld1_u8(dst - BPS);
+ int j;
+ for (j = 0; j < 8; ++j) {
+ vst1_u8(dst + j * BPS, top);
+ }
+}
+
+static void HE8uv(uint8_t* dst) { // horizontal
+ int j;
+ for (j = 0; j < 8; ++j) {
+ const uint8x8_t left = vld1_dup_u8(dst - 1);
+ vst1_u8(dst, left);
+ dst += BPS;
+ }
+}
+
+static WEBP_INLINE void DC8(uint8_t* dst, int do_top, int do_left) {
+ uint16x8_t sum_top;
+ uint16x8_t sum_left;
+ uint8x8_t dc0;
+
+ if (do_top) {
+ const uint8x8_t A = vld1_u8(dst - BPS); // top row
+ const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
+ const uint16x4_t p1 = vpadd_u16(p0, p0);
+ const uint16x4_t p2 = vpadd_u16(p1, p1);
+ sum_top = vcombine_u16(p2, p2);
+ }
+
+ if (do_left) {
+ const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
+ const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
+ const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
+ const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
+ const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + 4 * BPS - 1));
+ const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + 5 * BPS - 1));
+ const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + 6 * BPS - 1));
+ const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + 7 * BPS - 1));
+ const uint16x8_t s0 = vaddq_u16(L0, L1);
+ const uint16x8_t s1 = vaddq_u16(L2, L3);
+ const uint16x8_t s2 = vaddq_u16(L4, L5);
+ const uint16x8_t s3 = vaddq_u16(L6, L7);
+ const uint16x8_t s01 = vaddq_u16(s0, s1);
+ const uint16x8_t s23 = vaddq_u16(s2, s3);
+ sum_left = vaddq_u16(s01, s23);
+ }
+
+ if (do_top && do_left) {
+ const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
+ dc0 = vrshrn_n_u16(sum, 4);
+ } else if (do_top) {
+ dc0 = vrshrn_n_u16(sum_top, 3);
+ } else if (do_left) {
+ dc0 = vrshrn_n_u16(sum_left, 3);
+ } else {
+ dc0 = vdup_n_u8(0x80);
+ }
+
+ {
+ const uint8x8_t dc = vdup_lane_u8(dc0, 0);
+ int i;
+ for (i = 0; i < 8; ++i) {
+ vst1_u32((uint32_t*)(dst + i * BPS), vreinterpret_u32_u8(dc));
+ }
+ }
+}
+
+static void DC8uv(uint8_t* dst) { DC8(dst, 1, 1); }
+static void DC8uvNoTop(uint8_t* dst) { DC8(dst, 0, 1); }
+static void DC8uvNoLeft(uint8_t* dst) { DC8(dst, 1, 0); }
+static void DC8uvNoTopLeft(uint8_t* dst) { DC8(dst, 0, 0); }
+
+static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
+
+//------------------------------------------------------------------------------
+// 16x16
+
+static void VE16(uint8_t* dst) { // vertical
+ const uint8x16_t top = vld1q_u8(dst - BPS);
+ int j;
+ for (j = 0; j < 16; ++j) {
+ vst1q_u8(dst + j * BPS, top);
+ }
+}
+
+static void HE16(uint8_t* dst) { // horizontal
+ int j;
+ for (j = 0; j < 16; ++j) {
+ const uint8x16_t left = vld1q_dup_u8(dst - 1);
+ vst1q_u8(dst, left);
+ dst += BPS;
+ }
+}
+
+static WEBP_INLINE void DC16(uint8_t* dst, int do_top, int do_left) {
+ uint16x8_t sum_top;
+ uint16x8_t sum_left;
+ uint8x8_t dc0;
+
+ if (do_top) {
+ const uint8x16_t A = vld1q_u8(dst - BPS); // top row
+ const uint16x8_t p0 = vpaddlq_u8(A); // cascading summation of the top
+ const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
+ const uint16x4_t p2 = vpadd_u16(p1, p1);
+ const uint16x4_t p3 = vpadd_u16(p2, p2);
+ sum_top = vcombine_u16(p3, p3);
+ }
+
+ if (do_left) {
+ int i;
+ sum_left = vdupq_n_u16(0);
+ for (i = 0; i < 16; i += 8) {
+ const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + (i + 0) * BPS - 1));
+ const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + (i + 1) * BPS - 1));
+ const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + (i + 2) * BPS - 1));
+ const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + (i + 3) * BPS - 1));
+ const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + (i + 4) * BPS - 1));
+ const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + (i + 5) * BPS - 1));
+ const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + (i + 6) * BPS - 1));
+ const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + (i + 7) * BPS - 1));
+ const uint16x8_t s0 = vaddq_u16(L0, L1);
+ const uint16x8_t s1 = vaddq_u16(L2, L3);
+ const uint16x8_t s2 = vaddq_u16(L4, L5);
+ const uint16x8_t s3 = vaddq_u16(L6, L7);
+ const uint16x8_t s01 = vaddq_u16(s0, s1);
+ const uint16x8_t s23 = vaddq_u16(s2, s3);
+ const uint16x8_t sum = vaddq_u16(s01, s23);
+ sum_left = vaddq_u16(sum_left, sum);
+ }
+ }
+
+ if (do_top && do_left) {
+ const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
+ dc0 = vrshrn_n_u16(sum, 5);
+ } else if (do_top) {
+ dc0 = vrshrn_n_u16(sum_top, 4);
+ } else if (do_left) {
+ dc0 = vrshrn_n_u16(sum_left, 4);
+ } else {
+ dc0 = vdup_n_u8(0x80);
+ }
+
+ {
+ const uint8x16_t dc = vdupq_lane_u8(dc0, 0);
+ int i;
+ for (i = 0; i < 16; ++i) {
+ vst1q_u8(dst + i * BPS, dc);
+ }
+ }
+}
+
+static void DC16TopLeft(uint8_t* dst) { DC16(dst, 1, 1); }
+static void DC16NoTop(uint8_t* dst) { DC16(dst, 0, 1); }
+static void DC16NoLeft(uint8_t* dst) { DC16(dst, 1, 0); }
+static void DC16NoTopLeft(uint8_t* dst) { DC16(dst, 0, 0); }
+
+static void TM16(uint8_t* dst) {
+ const uint8x8_t TL = vld1_dup_u8(dst - BPS - 1); // top-left pixel 'A[-1]'
+ const uint8x16_t T = vld1q_u8(dst - BPS); // top row 'A[0..15]'
+ // A[c] - A[-1]
+ const int16x8_t d_lo = vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(T), TL));
+ const int16x8_t d_hi = vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(T), TL));
+ int y;
+ for (y = 0; y < 16; y += 4) {
+ // left edge
+ const int16x8_t L0 = ConvertU8ToS16(vld1_dup_u8(dst + 0 * BPS - 1));
+ const int16x8_t L1 = ConvertU8ToS16(vld1_dup_u8(dst + 1 * BPS - 1));
+ const int16x8_t L2 = ConvertU8ToS16(vld1_dup_u8(dst + 2 * BPS - 1));
+ const int16x8_t L3 = ConvertU8ToS16(vld1_dup_u8(dst + 3 * BPS - 1));
+ const int16x8_t r0_lo = vaddq_s16(L0, d_lo); // L[r] + A[c] - A[-1]
+ const int16x8_t r1_lo = vaddq_s16(L1, d_lo);
+ const int16x8_t r2_lo = vaddq_s16(L2, d_lo);
+ const int16x8_t r3_lo = vaddq_s16(L3, d_lo);
+ const int16x8_t r0_hi = vaddq_s16(L0, d_hi);
+ const int16x8_t r1_hi = vaddq_s16(L1, d_hi);
+ const int16x8_t r2_hi = vaddq_s16(L2, d_hi);
+ const int16x8_t r3_hi = vaddq_s16(L3, d_hi);
+ // Saturate and store the result.
+ const uint8x16_t row0 = vcombine_u8(vqmovun_s16(r0_lo), vqmovun_s16(r0_hi));
+ const uint8x16_t row1 = vcombine_u8(vqmovun_s16(r1_lo), vqmovun_s16(r1_hi));
+ const uint8x16_t row2 = vcombine_u8(vqmovun_s16(r2_lo), vqmovun_s16(r2_hi));
+ const uint8x16_t row3 = vcombine_u8(vqmovun_s16(r3_lo), vqmovun_s16(r3_hi));
+ vst1q_u8(dst + 0 * BPS, row0);
+ vst1q_u8(dst + 1 * BPS, row1);
+ vst1q_u8(dst + 2 * BPS, row2);
+ vst1q_u8(dst + 3 * BPS, row3);
+ dst += 4 * BPS;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitNEON(void) {
+ VP8Transform = TransformTwo;
+ VP8TransformAC3 = TransformAC3;
+ VP8TransformDC = TransformDC;
+ VP8TransformWHT = TransformWHT;
+
+ VP8VFilter16 = VFilter16;
+ VP8VFilter16i = VFilter16i;
+ VP8HFilter16 = HFilter16;
+#if !defined(WORK_AROUND_GCC)
+ VP8HFilter16i = HFilter16i;
+#endif
+ VP8VFilter8 = VFilter8;
+ VP8VFilter8i = VFilter8i;
+#if !defined(WORK_AROUND_GCC)
+ VP8HFilter8 = HFilter8;
+ VP8HFilter8i = HFilter8i;
+#endif
+ VP8SimpleVFilter16 = SimpleVFilter16;
+ VP8SimpleHFilter16 = SimpleHFilter16;
+ VP8SimpleVFilter16i = SimpleVFilter16i;
+ VP8SimpleHFilter16i = SimpleHFilter16i;
+
+ VP8PredLuma4[0] = DC4;
+ VP8PredLuma4[1] = TM4;
+ VP8PredLuma4[2] = VE4;
+ VP8PredLuma4[4] = RD4;
+ VP8PredLuma4[6] = LD4;
+
+ VP8PredLuma16[0] = DC16TopLeft;
+ VP8PredLuma16[1] = TM16;
+ VP8PredLuma16[2] = VE16;
+ VP8PredLuma16[3] = HE16;
+ VP8PredLuma16[4] = DC16NoTop;
+ VP8PredLuma16[5] = DC16NoLeft;
+ VP8PredLuma16[6] = DC16NoTopLeft;
+
+ VP8PredChroma8[0] = DC8uv;
+ VP8PredChroma8[1] = TM8uv;
+ VP8PredChroma8[2] = VE8uv;
+ VP8PredChroma8[3] = HE8uv;
+ VP8PredChroma8[4] = DC8uvNoTop;
+ VP8PredChroma8[5] = DC8uvNoLeft;
+ VP8PredChroma8[6] = DC8uvNoTopLeft;
+}
+
+#else // !WEBP_USE_NEON
+
+WEBP_DSP_INIT_STUB(VP8DspInitNEON)
+
+#endif // WEBP_USE_NEON
diff --git a/media/libwebp/dsp/dec_sse2.c b/media/libwebp/dsp/dec_sse2.c
new file mode 100644
index 000000000..411fb0276
--- /dev/null
+++ b/media/libwebp/dsp/dec_sse2.c
@@ -0,0 +1,1231 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 version of some decoding functions (idct, loop filtering).
+//
+// Author: somnath@google.com (Somnath Banerjee)
+// cduvivier@google.com (Christian Duvivier)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+// The 3-coeff sparse transform in SSE2 is not really faster than the plain-C
+// one it seems => disable it by default. Uncomment the following to enable:
+// #define USE_TRANSFORM_AC3
+
+#include <emmintrin.h>
+#include "./common_sse2.h"
+#include "../dec/vp8i_dec.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Transforms (Paragraph 14.4)
+
+static void Transform(const int16_t* in, uint8_t* dst, int do_two) {
+ // This implementation makes use of 16-bit fixed point versions of two
+ // multiply constants:
+ // K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
+ // K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
+ //
+ // To be able to use signed 16-bit integers, we use the following trick to
+ // have constants within range:
+ // - Associated constants are obtained by subtracting the 16-bit fixed point
+ // version of one:
+ // k = K - (1 << 16) => K = k + (1 << 16)
+ // K1 = 85267 => k1 = 20091
+ // K2 = 35468 => k2 = -30068
+ // - The multiplication of a variable by a constant become the sum of the
+ // variable and the multiplication of that variable by the associated
+ // constant:
+ // (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
+ const __m128i k1 = _mm_set1_epi16(20091);
+ const __m128i k2 = _mm_set1_epi16(-30068);
+ __m128i T0, T1, T2, T3;
+
+ // Load and concatenate the transform coefficients (we'll do two transforms
+ // in parallel). In the case of only one transform, the second half of the
+ // vectors will just contain random value we'll never use nor store.
+ __m128i in0, in1, in2, in3;
+ {
+ in0 = _mm_loadl_epi64((const __m128i*)&in[0]);
+ in1 = _mm_loadl_epi64((const __m128i*)&in[4]);
+ in2 = _mm_loadl_epi64((const __m128i*)&in[8]);
+ in3 = _mm_loadl_epi64((const __m128i*)&in[12]);
+ // a00 a10 a20 a30 x x x x
+ // a01 a11 a21 a31 x x x x
+ // a02 a12 a22 a32 x x x x
+ // a03 a13 a23 a33 x x x x
+ if (do_two) {
+ const __m128i inB0 = _mm_loadl_epi64((const __m128i*)&in[16]);
+ const __m128i inB1 = _mm_loadl_epi64((const __m128i*)&in[20]);
+ const __m128i inB2 = _mm_loadl_epi64((const __m128i*)&in[24]);
+ const __m128i inB3 = _mm_loadl_epi64((const __m128i*)&in[28]);
+ in0 = _mm_unpacklo_epi64(in0, inB0);
+ in1 = _mm_unpacklo_epi64(in1, inB1);
+ in2 = _mm_unpacklo_epi64(in2, inB2);
+ in3 = _mm_unpacklo_epi64(in3, inB3);
+ // a00 a10 a20 a30 b00 b10 b20 b30
+ // a01 a11 a21 a31 b01 b11 b21 b31
+ // a02 a12 a22 a32 b02 b12 b22 b32
+ // a03 a13 a23 a33 b03 b13 b23 b33
+ }
+ }
+
+ // Vertical pass and subsequent transpose.
+ {
+ // First pass, c and d calculations are longer because of the "trick"
+ // multiplications.
+ const __m128i a = _mm_add_epi16(in0, in2);
+ const __m128i b = _mm_sub_epi16(in0, in2);
+ // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
+ const __m128i c1 = _mm_mulhi_epi16(in1, k2);
+ const __m128i c2 = _mm_mulhi_epi16(in3, k1);
+ const __m128i c3 = _mm_sub_epi16(in1, in3);
+ const __m128i c4 = _mm_sub_epi16(c1, c2);
+ const __m128i c = _mm_add_epi16(c3, c4);
+ // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
+ const __m128i d1 = _mm_mulhi_epi16(in1, k1);
+ const __m128i d2 = _mm_mulhi_epi16(in3, k2);
+ const __m128i d3 = _mm_add_epi16(in1, in3);
+ const __m128i d4 = _mm_add_epi16(d1, d2);
+ const __m128i d = _mm_add_epi16(d3, d4);
+
+ // Second pass.
+ const __m128i tmp0 = _mm_add_epi16(a, d);
+ const __m128i tmp1 = _mm_add_epi16(b, c);
+ const __m128i tmp2 = _mm_sub_epi16(b, c);
+ const __m128i tmp3 = _mm_sub_epi16(a, d);
+
+ // Transpose the two 4x4.
+ VP8Transpose_2_4x4_16b(&tmp0, &tmp1, &tmp2, &tmp3, &T0, &T1, &T2, &T3);
+ }
+
+ // Horizontal pass and subsequent transpose.
+ {
+ // First pass, c and d calculations are longer because of the "trick"
+ // multiplications.
+ const __m128i four = _mm_set1_epi16(4);
+ const __m128i dc = _mm_add_epi16(T0, four);
+ const __m128i a = _mm_add_epi16(dc, T2);
+ const __m128i b = _mm_sub_epi16(dc, T2);
+ // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
+ const __m128i c1 = _mm_mulhi_epi16(T1, k2);
+ const __m128i c2 = _mm_mulhi_epi16(T3, k1);
+ const __m128i c3 = _mm_sub_epi16(T1, T3);
+ const __m128i c4 = _mm_sub_epi16(c1, c2);
+ const __m128i c = _mm_add_epi16(c3, c4);
+ // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
+ const __m128i d1 = _mm_mulhi_epi16(T1, k1);
+ const __m128i d2 = _mm_mulhi_epi16(T3, k2);
+ const __m128i d3 = _mm_add_epi16(T1, T3);
+ const __m128i d4 = _mm_add_epi16(d1, d2);
+ const __m128i d = _mm_add_epi16(d3, d4);
+
+ // Second pass.
+ const __m128i tmp0 = _mm_add_epi16(a, d);
+ const __m128i tmp1 = _mm_add_epi16(b, c);
+ const __m128i tmp2 = _mm_sub_epi16(b, c);
+ const __m128i tmp3 = _mm_sub_epi16(a, d);
+ const __m128i shifted0 = _mm_srai_epi16(tmp0, 3);
+ const __m128i shifted1 = _mm_srai_epi16(tmp1, 3);
+ const __m128i shifted2 = _mm_srai_epi16(tmp2, 3);
+ const __m128i shifted3 = _mm_srai_epi16(tmp3, 3);
+
+ // Transpose the two 4x4.
+ VP8Transpose_2_4x4_16b(&shifted0, &shifted1, &shifted2, &shifted3, &T0, &T1,
+ &T2, &T3);
+ }
+
+ // Add inverse transform to 'dst' and store.
+ {
+ const __m128i zero = _mm_setzero_si128();
+ // Load the reference(s).
+ __m128i dst0, dst1, dst2, dst3;
+ if (do_two) {
+ // Load eight bytes/pixels per line.
+ dst0 = _mm_loadl_epi64((__m128i*)(dst + 0 * BPS));
+ dst1 = _mm_loadl_epi64((__m128i*)(dst + 1 * BPS));
+ dst2 = _mm_loadl_epi64((__m128i*)(dst + 2 * BPS));
+ dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
+ } else {
+ // Load four bytes/pixels per line.
+ dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
+ dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
+ dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
+ dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+ }
+ // Convert to 16b.
+ dst0 = _mm_unpacklo_epi8(dst0, zero);
+ dst1 = _mm_unpacklo_epi8(dst1, zero);
+ dst2 = _mm_unpacklo_epi8(dst2, zero);
+ dst3 = _mm_unpacklo_epi8(dst3, zero);
+ // Add the inverse transform(s).
+ dst0 = _mm_add_epi16(dst0, T0);
+ dst1 = _mm_add_epi16(dst1, T1);
+ dst2 = _mm_add_epi16(dst2, T2);
+ dst3 = _mm_add_epi16(dst3, T3);
+ // Unsigned saturate to 8b.
+ dst0 = _mm_packus_epi16(dst0, dst0);
+ dst1 = _mm_packus_epi16(dst1, dst1);
+ dst2 = _mm_packus_epi16(dst2, dst2);
+ dst3 = _mm_packus_epi16(dst3, dst3);
+ // Store the results.
+ if (do_two) {
+ // Store eight bytes/pixels per line.
+ _mm_storel_epi64((__m128i*)(dst + 0 * BPS), dst0);
+ _mm_storel_epi64((__m128i*)(dst + 1 * BPS), dst1);
+ _mm_storel_epi64((__m128i*)(dst + 2 * BPS), dst2);
+ _mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
+ } else {
+ // Store four bytes/pixels per line.
+ WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+ WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+ WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+ WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+ }
+ }
+}
+
+#if defined(USE_TRANSFORM_AC3)
+#define MUL(a, b) (((a) * (b)) >> 16)
+static void TransformAC3(const int16_t* in, uint8_t* dst) {
+ static const int kC1 = 20091 + (1 << 16);
+ static const int kC2 = 35468;
+ const __m128i A = _mm_set1_epi16(in[0] + 4);
+ const __m128i c4 = _mm_set1_epi16(MUL(in[4], kC2));
+ const __m128i d4 = _mm_set1_epi16(MUL(in[4], kC1));
+ const int c1 = MUL(in[1], kC2);
+ const int d1 = MUL(in[1], kC1);
+ const __m128i CD = _mm_set_epi16(0, 0, 0, 0, -d1, -c1, c1, d1);
+ const __m128i B = _mm_adds_epi16(A, CD);
+ const __m128i m0 = _mm_adds_epi16(B, d4);
+ const __m128i m1 = _mm_adds_epi16(B, c4);
+ const __m128i m2 = _mm_subs_epi16(B, c4);
+ const __m128i m3 = _mm_subs_epi16(B, d4);
+ const __m128i zero = _mm_setzero_si128();
+ // Load the source pixels.
+ __m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
+ __m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
+ __m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
+ __m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+ // Convert to 16b.
+ dst0 = _mm_unpacklo_epi8(dst0, zero);
+ dst1 = _mm_unpacklo_epi8(dst1, zero);
+ dst2 = _mm_unpacklo_epi8(dst2, zero);
+ dst3 = _mm_unpacklo_epi8(dst3, zero);
+ // Add the inverse transform.
+ dst0 = _mm_adds_epi16(dst0, _mm_srai_epi16(m0, 3));
+ dst1 = _mm_adds_epi16(dst1, _mm_srai_epi16(m1, 3));
+ dst2 = _mm_adds_epi16(dst2, _mm_srai_epi16(m2, 3));
+ dst3 = _mm_adds_epi16(dst3, _mm_srai_epi16(m3, 3));
+ // Unsigned saturate to 8b.
+ dst0 = _mm_packus_epi16(dst0, dst0);
+ dst1 = _mm_packus_epi16(dst1, dst1);
+ dst2 = _mm_packus_epi16(dst2, dst2);
+ dst3 = _mm_packus_epi16(dst3, dst3);
+ // Store the results.
+ WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+ WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+ WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+ WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+}
+#undef MUL
+#endif // USE_TRANSFORM_AC3
+
+//------------------------------------------------------------------------------
+// Loop Filter (Paragraph 15)
+
+// Compute abs(p - q) = subs(p - q) OR subs(q - p)
+#define MM_ABS(p, q) _mm_or_si128( \
+ _mm_subs_epu8((q), (p)), \
+ _mm_subs_epu8((p), (q)))
+
+// Shift each byte of "x" by 3 bits while preserving by the sign bit.
+static WEBP_INLINE void SignedShift8b(__m128i* const x) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i lo_0 = _mm_unpacklo_epi8(zero, *x);
+ const __m128i hi_0 = _mm_unpackhi_epi8(zero, *x);
+ const __m128i lo_1 = _mm_srai_epi16(lo_0, 3 + 8);
+ const __m128i hi_1 = _mm_srai_epi16(hi_0, 3 + 8);
+ *x = _mm_packs_epi16(lo_1, hi_1);
+}
+
+#define FLIP_SIGN_BIT2(a, b) { \
+ a = _mm_xor_si128(a, sign_bit); \
+ b = _mm_xor_si128(b, sign_bit); \
+}
+
+#define FLIP_SIGN_BIT4(a, b, c, d) { \
+ FLIP_SIGN_BIT2(a, b); \
+ FLIP_SIGN_BIT2(c, d); \
+}
+
+// input/output is uint8_t
+static WEBP_INLINE void GetNotHEV(const __m128i* const p1,
+ const __m128i* const p0,
+ const __m128i* const q0,
+ const __m128i* const q1,
+ int hev_thresh, __m128i* const not_hev) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i t_1 = MM_ABS(*p1, *p0);
+ const __m128i t_2 = MM_ABS(*q1, *q0);
+
+ const __m128i h = _mm_set1_epi8(hev_thresh);
+ const __m128i t_max = _mm_max_epu8(t_1, t_2);
+
+ const __m128i t_max_h = _mm_subs_epu8(t_max, h);
+ *not_hev = _mm_cmpeq_epi8(t_max_h, zero); // not_hev <= t1 && not_hev <= t2
+}
+
+// input pixels are int8_t
+static WEBP_INLINE void GetBaseDelta(const __m128i* const p1,
+ const __m128i* const p0,
+ const __m128i* const q0,
+ const __m128i* const q1,
+ __m128i* const delta) {
+ // beware of addition order, for saturation!
+ const __m128i p1_q1 = _mm_subs_epi8(*p1, *q1); // p1 - q1
+ const __m128i q0_p0 = _mm_subs_epi8(*q0, *p0); // q0 - p0
+ const __m128i s1 = _mm_adds_epi8(p1_q1, q0_p0); // p1 - q1 + 1 * (q0 - p0)
+ const __m128i s2 = _mm_adds_epi8(q0_p0, s1); // p1 - q1 + 2 * (q0 - p0)
+ const __m128i s3 = _mm_adds_epi8(q0_p0, s2); // p1 - q1 + 3 * (q0 - p0)
+ *delta = s3;
+}
+
+// input and output are int8_t
+static WEBP_INLINE void DoSimpleFilter(__m128i* const p0, __m128i* const q0,
+ const __m128i* const fl) {
+ const __m128i k3 = _mm_set1_epi8(3);
+ const __m128i k4 = _mm_set1_epi8(4);
+ __m128i v3 = _mm_adds_epi8(*fl, k3);
+ __m128i v4 = _mm_adds_epi8(*fl, k4);
+
+ SignedShift8b(&v4); // v4 >> 3
+ SignedShift8b(&v3); // v3 >> 3
+ *q0 = _mm_subs_epi8(*q0, v4); // q0 -= v4
+ *p0 = _mm_adds_epi8(*p0, v3); // p0 += v3
+}
+
+// Updates values of 2 pixels at MB edge during complex filtering.
+// Update operations:
+// q = q - delta and p = p + delta; where delta = [(a_hi >> 7), (a_lo >> 7)]
+// Pixels 'pi' and 'qi' are int8_t on input, uint8_t on output (sign flip).
+static WEBP_INLINE void Update2Pixels(__m128i* const pi, __m128i* const qi,
+ const __m128i* const a0_lo,
+ const __m128i* const a0_hi) {
+ const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
+ const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
+ const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
+ const __m128i sign_bit = _mm_set1_epi8(0x80);
+ *pi = _mm_adds_epi8(*pi, delta);
+ *qi = _mm_subs_epi8(*qi, delta);
+ FLIP_SIGN_BIT2(*pi, *qi);
+}
+
+// input pixels are uint8_t
+static WEBP_INLINE void NeedsFilter(const __m128i* const p1,
+ const __m128i* const p0,
+ const __m128i* const q0,
+ const __m128i* const q1,
+ int thresh, __m128i* const mask) {
+ const __m128i m_thresh = _mm_set1_epi8(thresh);
+ const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1)
+ const __m128i kFE = _mm_set1_epi8(0xFE);
+ const __m128i t2 = _mm_and_si128(t1, kFE); // set lsb of each byte to zero
+ const __m128i t3 = _mm_srli_epi16(t2, 1); // abs(p1 - q1) / 2
+
+ const __m128i t4 = MM_ABS(*p0, *q0); // abs(p0 - q0)
+ const __m128i t5 = _mm_adds_epu8(t4, t4); // abs(p0 - q0) * 2
+ const __m128i t6 = _mm_adds_epu8(t5, t3); // abs(p0-q0)*2 + abs(p1-q1)/2
+
+ const __m128i t7 = _mm_subs_epu8(t6, m_thresh); // mask <= m_thresh
+ *mask = _mm_cmpeq_epi8(t7, _mm_setzero_si128());
+}
+
+//------------------------------------------------------------------------------
+// Edge filtering functions
+
+// Applies filter on 2 pixels (p0 and q0)
+static WEBP_INLINE void DoFilter2(__m128i* const p1, __m128i* const p0,
+ __m128i* const q0, __m128i* const q1,
+ int thresh) {
+ __m128i a, mask;
+ const __m128i sign_bit = _mm_set1_epi8(0x80);
+ // convert p1/q1 to int8_t (for GetBaseDelta)
+ const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
+ const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
+
+ NeedsFilter(p1, p0, q0, q1, thresh, &mask);
+
+ FLIP_SIGN_BIT2(*p0, *q0);
+ GetBaseDelta(&p1s, p0, q0, &q1s, &a);
+ a = _mm_and_si128(a, mask); // mask filter values we don't care about
+ DoSimpleFilter(p0, q0, &a);
+ FLIP_SIGN_BIT2(*p0, *q0);
+}
+
+// Applies filter on 4 pixels (p1, p0, q0 and q1)
+static WEBP_INLINE void DoFilter4(__m128i* const p1, __m128i* const p0,
+ __m128i* const q0, __m128i* const q1,
+ const __m128i* const mask, int hev_thresh) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i sign_bit = _mm_set1_epi8(0x80);
+ const __m128i k64 = _mm_set1_epi8(64);
+ const __m128i k3 = _mm_set1_epi8(3);
+ const __m128i k4 = _mm_set1_epi8(4);
+ __m128i not_hev;
+ __m128i t1, t2, t3;
+
+ // compute hev mask
+ GetNotHEV(p1, p0, q0, q1, hev_thresh, &not_hev);
+
+ // convert to signed values
+ FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
+
+ t1 = _mm_subs_epi8(*p1, *q1); // p1 - q1
+ t1 = _mm_andnot_si128(not_hev, t1); // hev(p1 - q1)
+ t2 = _mm_subs_epi8(*q0, *p0); // q0 - p0
+ t1 = _mm_adds_epi8(t1, t2); // hev(p1 - q1) + 1 * (q0 - p0)
+ t1 = _mm_adds_epi8(t1, t2); // hev(p1 - q1) + 2 * (q0 - p0)
+ t1 = _mm_adds_epi8(t1, t2); // hev(p1 - q1) + 3 * (q0 - p0)
+ t1 = _mm_and_si128(t1, *mask); // mask filter values we don't care about
+
+ t2 = _mm_adds_epi8(t1, k3); // 3 * (q0 - p0) + hev(p1 - q1) + 3
+ t3 = _mm_adds_epi8(t1, k4); // 3 * (q0 - p0) + hev(p1 - q1) + 4
+ SignedShift8b(&t2); // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3
+ SignedShift8b(&t3); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
+ *p0 = _mm_adds_epi8(*p0, t2); // p0 += t2
+ *q0 = _mm_subs_epi8(*q0, t3); // q0 -= t3
+ FLIP_SIGN_BIT2(*p0, *q0);
+
+ // this is equivalent to signed (a + 1) >> 1 calculation
+ t2 = _mm_add_epi8(t3, sign_bit);
+ t3 = _mm_avg_epu8(t2, zero);
+ t3 = _mm_sub_epi8(t3, k64);
+
+ t3 = _mm_and_si128(not_hev, t3); // if !hev
+ *q1 = _mm_subs_epi8(*q1, t3); // q1 -= t3
+ *p1 = _mm_adds_epi8(*p1, t3); // p1 += t3
+ FLIP_SIGN_BIT2(*p1, *q1);
+}
+
+// Applies filter on 6 pixels (p2, p1, p0, q0, q1 and q2)
+static WEBP_INLINE void DoFilter6(__m128i* const p2, __m128i* const p1,
+ __m128i* const p0, __m128i* const q0,
+ __m128i* const q1, __m128i* const q2,
+ const __m128i* const mask, int hev_thresh) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i sign_bit = _mm_set1_epi8(0x80);
+ __m128i a, not_hev;
+
+ // compute hev mask
+ GetNotHEV(p1, p0, q0, q1, hev_thresh, &not_hev);
+
+ FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
+ FLIP_SIGN_BIT2(*p2, *q2);
+ GetBaseDelta(p1, p0, q0, q1, &a);
+
+ { // do simple filter on pixels with hev
+ const __m128i m = _mm_andnot_si128(not_hev, *mask);
+ const __m128i f = _mm_and_si128(a, m);
+ DoSimpleFilter(p0, q0, &f);
+ }
+
+ { // do strong filter on pixels with not hev
+ const __m128i k9 = _mm_set1_epi16(0x0900);
+ const __m128i k63 = _mm_set1_epi16(63);
+
+ const __m128i m = _mm_and_si128(not_hev, *mask);
+ const __m128i f = _mm_and_si128(a, m);
+
+ const __m128i f_lo = _mm_unpacklo_epi8(zero, f);
+ const __m128i f_hi = _mm_unpackhi_epi8(zero, f);
+
+ const __m128i f9_lo = _mm_mulhi_epi16(f_lo, k9); // Filter (lo) * 9
+ const __m128i f9_hi = _mm_mulhi_epi16(f_hi, k9); // Filter (hi) * 9
+
+ const __m128i a2_lo = _mm_add_epi16(f9_lo, k63); // Filter * 9 + 63
+ const __m128i a2_hi = _mm_add_epi16(f9_hi, k63); // Filter * 9 + 63
+
+ const __m128i a1_lo = _mm_add_epi16(a2_lo, f9_lo); // Filter * 18 + 63
+ const __m128i a1_hi = _mm_add_epi16(a2_hi, f9_hi); // Filter * 18 + 63
+
+ const __m128i a0_lo = _mm_add_epi16(a1_lo, f9_lo); // Filter * 27 + 63
+ const __m128i a0_hi = _mm_add_epi16(a1_hi, f9_hi); // Filter * 27 + 63
+
+ Update2Pixels(p2, q2, &a2_lo, &a2_hi);
+ Update2Pixels(p1, q1, &a1_lo, &a1_hi);
+ Update2Pixels(p0, q0, &a0_lo, &a0_hi);
+ }
+}
+
+// reads 8 rows across a vertical edge.
+static WEBP_INLINE void Load8x4(const uint8_t* const b, int stride,
+ __m128i* const p, __m128i* const q) {
+ // A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
+ // A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
+ const __m128i A0 = _mm_set_epi32(
+ WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]),
+ WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride]));
+ const __m128i A1 = _mm_set_epi32(
+ WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]),
+ WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride]));
+
+ // B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
+ // B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
+ const __m128i B0 = _mm_unpacklo_epi8(A0, A1);
+ const __m128i B1 = _mm_unpackhi_epi8(A0, A1);
+
+ // C0 = 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+ // C1 = 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40
+ const __m128i C0 = _mm_unpacklo_epi16(B0, B1);
+ const __m128i C1 = _mm_unpackhi_epi16(B0, B1);
+
+ // *p = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+ // *q = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+ *p = _mm_unpacklo_epi32(C0, C1);
+ *q = _mm_unpackhi_epi32(C0, C1);
+}
+
+static WEBP_INLINE void Load16x4(const uint8_t* const r0,
+ const uint8_t* const r8,
+ int stride,
+ __m128i* const p1, __m128i* const p0,
+ __m128i* const q0, __m128i* const q1) {
+ // Assume the pixels around the edge (|) are numbered as follows
+ // 00 01 | 02 03
+ // 10 11 | 12 13
+ // ... | ...
+ // e0 e1 | e2 e3
+ // f0 f1 | f2 f3
+ //
+ // r0 is pointing to the 0th row (00)
+ // r8 is pointing to the 8th row (80)
+
+ // Load
+ // p1 = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+ // q0 = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+ // p0 = f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
+ // q1 = f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
+ Load8x4(r0, stride, p1, q0);
+ Load8x4(r8, stride, p0, q1);
+
+ {
+ // p1 = f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+ // p0 = f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+ // q0 = f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+ // q1 = f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+ const __m128i t1 = *p1;
+ const __m128i t2 = *q0;
+ *p1 = _mm_unpacklo_epi64(t1, *p0);
+ *p0 = _mm_unpackhi_epi64(t1, *p0);
+ *q0 = _mm_unpacklo_epi64(t2, *q1);
+ *q1 = _mm_unpackhi_epi64(t2, *q1);
+ }
+}
+
+static WEBP_INLINE void Store4x4(__m128i* const x, uint8_t* dst, int stride) {
+ int i;
+ for (i = 0; i < 4; ++i, dst += stride) {
+ WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
+ *x = _mm_srli_si128(*x, 4);
+ }
+}
+
+// Transpose back and store
+static WEBP_INLINE void Store16x4(const __m128i* const p1,
+ const __m128i* const p0,
+ const __m128i* const q0,
+ const __m128i* const q1,
+ uint8_t* r0, uint8_t* r8,
+ int stride) {
+ __m128i t1, p1_s, p0_s, q0_s, q1_s;
+
+ // p0 = 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
+ // p1 = f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80
+ t1 = *p0;
+ p0_s = _mm_unpacklo_epi8(*p1, t1);
+ p1_s = _mm_unpackhi_epi8(*p1, t1);
+
+ // q0 = 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
+ // q1 = f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+ t1 = *q0;
+ q0_s = _mm_unpacklo_epi8(t1, *q1);
+ q1_s = _mm_unpackhi_epi8(t1, *q1);
+
+ // p0 = 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00
+ // q0 = 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40
+ t1 = p0_s;
+ p0_s = _mm_unpacklo_epi16(t1, q0_s);
+ q0_s = _mm_unpackhi_epi16(t1, q0_s);
+
+ // p1 = b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80
+ // q1 = f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0
+ t1 = p1_s;
+ p1_s = _mm_unpacklo_epi16(t1, q1_s);
+ q1_s = _mm_unpackhi_epi16(t1, q1_s);
+
+ Store4x4(&p0_s, r0, stride);
+ r0 += 4 * stride;
+ Store4x4(&q0_s, r0, stride);
+
+ Store4x4(&p1_s, r8, stride);
+ r8 += 4 * stride;
+ Store4x4(&q1_s, r8, stride);
+}
+
+//------------------------------------------------------------------------------
+// Simple In-loop filtering (Paragraph 15.2)
+
+static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
+ // Load
+ __m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]);
+ __m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]);
+ __m128i q0 = _mm_loadu_si128((__m128i*)&p[0]);
+ __m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]);
+
+ DoFilter2(&p1, &p0, &q0, &q1, thresh);
+
+ // Store
+ _mm_storeu_si128((__m128i*)&p[-stride], p0);
+ _mm_storeu_si128((__m128i*)&p[0], q0);
+}
+
+static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
+ __m128i p1, p0, q0, q1;
+
+ p -= 2; // beginning of p1
+
+ Load16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
+ DoFilter2(&p1, &p0, &q0, &q1, thresh);
+ Store16x4(&p1, &p0, &q0, &q1, p, p + 8 * stride, stride);
+}
+
+static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
+ int k;
+ for (k = 3; k > 0; --k) {
+ p += 4 * stride;
+ SimpleVFilter16(p, stride, thresh);
+ }
+}
+
+static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
+ int k;
+ for (k = 3; k > 0; --k) {
+ p += 4;
+ SimpleHFilter16(p, stride, thresh);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Complex In-loop filtering (Paragraph 15.3)
+
+#define MAX_DIFF1(p3, p2, p1, p0, m) do { \
+ m = MM_ABS(p1, p0); \
+ m = _mm_max_epu8(m, MM_ABS(p3, p2)); \
+ m = _mm_max_epu8(m, MM_ABS(p2, p1)); \
+} while (0)
+
+#define MAX_DIFF2(p3, p2, p1, p0, m) do { \
+ m = _mm_max_epu8(m, MM_ABS(p1, p0)); \
+ m = _mm_max_epu8(m, MM_ABS(p3, p2)); \
+ m = _mm_max_epu8(m, MM_ABS(p2, p1)); \
+} while (0)
+
+#define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) { \
+ e1 = _mm_loadu_si128((__m128i*)&(p)[0 * stride]); \
+ e2 = _mm_loadu_si128((__m128i*)&(p)[1 * stride]); \
+ e3 = _mm_loadu_si128((__m128i*)&(p)[2 * stride]); \
+ e4 = _mm_loadu_si128((__m128i*)&(p)[3 * stride]); \
+}
+
+#define LOADUV_H_EDGE(p, u, v, stride) do { \
+ const __m128i U = _mm_loadl_epi64((__m128i*)&(u)[(stride)]); \
+ const __m128i V = _mm_loadl_epi64((__m128i*)&(v)[(stride)]); \
+ p = _mm_unpacklo_epi64(U, V); \
+} while (0)
+
+#define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) { \
+ LOADUV_H_EDGE(e1, u, v, 0 * stride); \
+ LOADUV_H_EDGE(e2, u, v, 1 * stride); \
+ LOADUV_H_EDGE(e3, u, v, 2 * stride); \
+ LOADUV_H_EDGE(e4, u, v, 3 * stride); \
+}
+
+#define STOREUV(p, u, v, stride) { \
+ _mm_storel_epi64((__m128i*)&u[(stride)], p); \
+ p = _mm_srli_si128(p, 8); \
+ _mm_storel_epi64((__m128i*)&v[(stride)], p); \
+}
+
+static WEBP_INLINE void ComplexMask(const __m128i* const p1,
+ const __m128i* const p0,
+ const __m128i* const q0,
+ const __m128i* const q1,
+ int thresh, int ithresh,
+ __m128i* const mask) {
+ const __m128i it = _mm_set1_epi8(ithresh);
+ const __m128i diff = _mm_subs_epu8(*mask, it);
+ const __m128i thresh_mask = _mm_cmpeq_epi8(diff, _mm_setzero_si128());
+ __m128i filter_mask;
+ NeedsFilter(p1, p0, q0, q1, thresh, &filter_mask);
+ *mask = _mm_and_si128(thresh_mask, filter_mask);
+}
+
+// on macroblock edges
+static void VFilter16(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ __m128i t1;
+ __m128i mask;
+ __m128i p2, p1, p0, q0, q1, q2;
+
+ // Load p3, p2, p1, p0
+ LOAD_H_EDGES4(p - 4 * stride, stride, t1, p2, p1, p0);
+ MAX_DIFF1(t1, p2, p1, p0, mask);
+
+ // Load q0, q1, q2, q3
+ LOAD_H_EDGES4(p, stride, q0, q1, q2, t1);
+ MAX_DIFF2(t1, q2, q1, q0, mask);
+
+ ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+ DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+ // Store
+ _mm_storeu_si128((__m128i*)&p[-3 * stride], p2);
+ _mm_storeu_si128((__m128i*)&p[-2 * stride], p1);
+ _mm_storeu_si128((__m128i*)&p[-1 * stride], p0);
+ _mm_storeu_si128((__m128i*)&p[+0 * stride], q0);
+ _mm_storeu_si128((__m128i*)&p[+1 * stride], q1);
+ _mm_storeu_si128((__m128i*)&p[+2 * stride], q2);
+}
+
+static void HFilter16(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ __m128i mask;
+ __m128i p3, p2, p1, p0, q0, q1, q2, q3;
+
+ uint8_t* const b = p - 4;
+ Load16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0); // p3, p2, p1, p0
+ MAX_DIFF1(p3, p2, p1, p0, mask);
+
+ Load16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3); // q0, q1, q2, q3
+ MAX_DIFF2(q3, q2, q1, q0, mask);
+
+ ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+ DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+ Store16x4(&p3, &p2, &p1, &p0, b, b + 8 * stride, stride);
+ Store16x4(&q0, &q1, &q2, &q3, p, p + 8 * stride, stride);
+}
+
+// on three inner edges
+static void VFilter16i(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ int k;
+ __m128i p3, p2, p1, p0; // loop invariants
+
+ LOAD_H_EDGES4(p, stride, p3, p2, p1, p0); // prologue
+
+ for (k = 3; k > 0; --k) {
+ __m128i mask, tmp1, tmp2;
+ uint8_t* const b = p + 2 * stride; // beginning of p1
+ p += 4 * stride;
+
+ MAX_DIFF1(p3, p2, p1, p0, mask); // compute partial mask
+ LOAD_H_EDGES4(p, stride, p3, p2, tmp1, tmp2);
+ MAX_DIFF2(p3, p2, tmp1, tmp2, mask);
+
+ // p3 and p2 are not just temporary variables here: they will be
+ // re-used for next span. And q2/q3 will become p1/p0 accordingly.
+ ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
+ DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
+
+ // Store
+ _mm_storeu_si128((__m128i*)&b[0 * stride], p1);
+ _mm_storeu_si128((__m128i*)&b[1 * stride], p0);
+ _mm_storeu_si128((__m128i*)&b[2 * stride], p3);
+ _mm_storeu_si128((__m128i*)&b[3 * stride], p2);
+
+ // rotate samples
+ p1 = tmp1;
+ p0 = tmp2;
+ }
+}
+
+static void HFilter16i(uint8_t* p, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ int k;
+ __m128i p3, p2, p1, p0; // loop invariants
+
+ Load16x4(p, p + 8 * stride, stride, &p3, &p2, &p1, &p0); // prologue
+
+ for (k = 3; k > 0; --k) {
+ __m128i mask, tmp1, tmp2;
+ uint8_t* const b = p + 2; // beginning of p1
+
+ p += 4; // beginning of q0 (and next span)
+
+ MAX_DIFF1(p3, p2, p1, p0, mask); // compute partial mask
+ Load16x4(p, p + 8 * stride, stride, &p3, &p2, &tmp1, &tmp2);
+ MAX_DIFF2(p3, p2, tmp1, tmp2, mask);
+
+ ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
+ DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
+
+ Store16x4(&p1, &p0, &p3, &p2, b, b + 8 * stride, stride);
+
+ // rotate samples
+ p1 = tmp1;
+ p0 = tmp2;
+ }
+}
+
+// 8-pixels wide variant, for chroma filtering
+static void VFilter8(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ __m128i mask;
+ __m128i t1, p2, p1, p0, q0, q1, q2;
+
+ // Load p3, p2, p1, p0
+ LOADUV_H_EDGES4(u - 4 * stride, v - 4 * stride, stride, t1, p2, p1, p0);
+ MAX_DIFF1(t1, p2, p1, p0, mask);
+
+ // Load q0, q1, q2, q3
+ LOADUV_H_EDGES4(u, v, stride, q0, q1, q2, t1);
+ MAX_DIFF2(t1, q2, q1, q0, mask);
+
+ ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+ DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+ // Store
+ STOREUV(p2, u, v, -3 * stride);
+ STOREUV(p1, u, v, -2 * stride);
+ STOREUV(p0, u, v, -1 * stride);
+ STOREUV(q0, u, v, 0 * stride);
+ STOREUV(q1, u, v, 1 * stride);
+ STOREUV(q2, u, v, 2 * stride);
+}
+
+static void HFilter8(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ __m128i mask;
+ __m128i p3, p2, p1, p0, q0, q1, q2, q3;
+
+ uint8_t* const tu = u - 4;
+ uint8_t* const tv = v - 4;
+ Load16x4(tu, tv, stride, &p3, &p2, &p1, &p0); // p3, p2, p1, p0
+ MAX_DIFF1(p3, p2, p1, p0, mask);
+
+ Load16x4(u, v, stride, &q0, &q1, &q2, &q3); // q0, q1, q2, q3
+ MAX_DIFF2(q3, q2, q1, q0, mask);
+
+ ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+ DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
+
+ Store16x4(&p3, &p2, &p1, &p0, tu, tv, stride);
+ Store16x4(&q0, &q1, &q2, &q3, u, v, stride);
+}
+
+static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ __m128i mask;
+ __m128i t1, t2, p1, p0, q0, q1;
+
+ // Load p3, p2, p1, p0
+ LOADUV_H_EDGES4(u, v, stride, t2, t1, p1, p0);
+ MAX_DIFF1(t2, t1, p1, p0, mask);
+
+ u += 4 * stride;
+ v += 4 * stride;
+
+ // Load q0, q1, q2, q3
+ LOADUV_H_EDGES4(u, v, stride, q0, q1, t1, t2);
+ MAX_DIFF2(t2, t1, q1, q0, mask);
+
+ ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+ DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
+
+ // Store
+ STOREUV(p1, u, v, -2 * stride);
+ STOREUV(p0, u, v, -1 * stride);
+ STOREUV(q0, u, v, 0 * stride);
+ STOREUV(q1, u, v, 1 * stride);
+}
+
+static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_thresh) {
+ __m128i mask;
+ __m128i t1, t2, p1, p0, q0, q1;
+ Load16x4(u, v, stride, &t2, &t1, &p1, &p0); // p3, p2, p1, p0
+ MAX_DIFF1(t2, t1, p1, p0, mask);
+
+ u += 4; // beginning of q0
+ v += 4;
+ Load16x4(u, v, stride, &q0, &q1, &t1, &t2); // q0, q1, q2, q3
+ MAX_DIFF2(t2, t1, q1, q0, mask);
+
+ ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
+ DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
+
+ u -= 2; // beginning of p1
+ v -= 2;
+ Store16x4(&p1, &p0, &q0, &q1, u, v, stride);
+}
+
+//------------------------------------------------------------------------------
+// 4x4 predictions
+
+#define DST(x, y) dst[(x) + (y) * BPS]
+#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
+
+// We use the following 8b-arithmetic tricks:
+// (a + 2 * b + c + 2) >> 2 = (AC + b + 1) >> 1
+// where: AC = (a + c) >> 1 = [(a + c + 1) >> 1] - [(a^c) & 1]
+// and:
+// (a + 2 * b + c + 2) >> 2 = (AB + BC + 1) >> 1 - (ab|bc)&lsb
+// where: AC = (a + b + 1) >> 1, BC = (b + c + 1) >> 1
+// and ab = a ^ b, bc = b ^ c, lsb = (AC^BC)&1
+
+static void VE4(uint8_t* dst) { // vertical
+ const __m128i one = _mm_set1_epi8(1);
+ const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
+ const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
+ const __m128i CDEFGH00 = _mm_srli_si128(ABCDEFGH, 2);
+ const __m128i a = _mm_avg_epu8(ABCDEFGH, CDEFGH00);
+ const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
+ const __m128i b = _mm_subs_epu8(a, lsb);
+ const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
+ const uint32_t vals = _mm_cvtsi128_si32(avg);
+ int i;
+ for (i = 0; i < 4; ++i) {
+ WebPUint32ToMem(dst + i * BPS, vals);
+ }
+}
+
+static void LD4(uint8_t* dst) { // Down-Left
+ const __m128i one = _mm_set1_epi8(1);
+ const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
+ const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
+ const __m128i CDEFGH00 = _mm_srli_si128(ABCDEFGH, 2);
+ const __m128i CDEFGHH0 = _mm_insert_epi16(CDEFGH00, dst[-BPS + 7], 3);
+ const __m128i avg1 = _mm_avg_epu8(ABCDEFGH, CDEFGHH0);
+ const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
+ const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
+ const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
+ WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+}
+
+static void VR4(uint8_t* dst) { // Vertical-Right
+ const __m128i one = _mm_set1_epi8(1);
+ const int I = dst[-1 + 0 * BPS];
+ const int J = dst[-1 + 1 * BPS];
+ const int K = dst[-1 + 2 * BPS];
+ const int X = dst[-1 - BPS];
+ const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
+ const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
+ const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
+ const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
+ const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0);
+ const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
+ const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
+ const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
+ const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
+ WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
+ WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
+ WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+ WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+
+ // these two are hard to implement in SSE2, so we keep the C-version:
+ DST(0, 2) = AVG3(J, I, X);
+ DST(0, 3) = AVG3(K, J, I);
+}
+
+static void VL4(uint8_t* dst) { // Vertical-Left
+ const __m128i one = _mm_set1_epi8(1);
+ const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
+ const __m128i BCDEFGH_ = _mm_srli_si128(ABCDEFGH, 1);
+ const __m128i CDEFGH__ = _mm_srli_si128(ABCDEFGH, 2);
+ const __m128i avg1 = _mm_avg_epu8(ABCDEFGH, BCDEFGH_);
+ const __m128i avg2 = _mm_avg_epu8(CDEFGH__, BCDEFGH_);
+ const __m128i avg3 = _mm_avg_epu8(avg1, avg2);
+ const __m128i lsb1 = _mm_and_si128(_mm_xor_si128(avg1, avg2), one);
+ const __m128i ab = _mm_xor_si128(ABCDEFGH, BCDEFGH_);
+ const __m128i bc = _mm_xor_si128(CDEFGH__, BCDEFGH_);
+ const __m128i abbc = _mm_or_si128(ab, bc);
+ const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
+ const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
+ const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+ WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
+ WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
+ WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+ WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+
+ // these two are hard to get and irregular
+ DST(3, 2) = (extra_out >> 0) & 0xff;
+ DST(3, 3) = (extra_out >> 8) & 0xff;
+}
+
+static void RD4(uint8_t* dst) { // Down-right
+ const __m128i one = _mm_set1_epi8(1);
+ const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
+ const __m128i ____XABCD = _mm_slli_si128(XABCD, 4);
+ const uint32_t I = dst[-1 + 0 * BPS];
+ const uint32_t J = dst[-1 + 1 * BPS];
+ const uint32_t K = dst[-1 + 2 * BPS];
+ const uint32_t L = dst[-1 + 3 * BPS];
+ const __m128i LKJI_____ =
+ _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
+ const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
+ const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
+ const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
+ const __m128i avg1 = _mm_avg_epu8(JIXABCD__, LKJIXABCD);
+ const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
+ const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
+ const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
+ WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+}
+
+#undef DST
+#undef AVG3
+
+//------------------------------------------------------------------------------
+// Luma 16x16
+
+static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
+ const uint8_t* top = dst - BPS;
+ const __m128i zero = _mm_setzero_si128();
+ int y;
+ if (size == 4) {
+ const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+ const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
+ for (y = 0; y < 4; ++y, dst += BPS) {
+ const int val = dst[-1] - top[-1];
+ const __m128i base = _mm_set1_epi16(val);
+ const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
+ WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+ }
+ } else if (size == 8) {
+ const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
+ const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
+ for (y = 0; y < 8; ++y, dst += BPS) {
+ const int val = dst[-1] - top[-1];
+ const __m128i base = _mm_set1_epi16(val);
+ const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
+ _mm_storel_epi64((__m128i*)dst, out);
+ }
+ } else {
+ const __m128i top_values = _mm_loadu_si128((const __m128i*)top);
+ const __m128i top_base_0 = _mm_unpacklo_epi8(top_values, zero);
+ const __m128i top_base_1 = _mm_unpackhi_epi8(top_values, zero);
+ for (y = 0; y < 16; ++y, dst += BPS) {
+ const int val = dst[-1] - top[-1];
+ const __m128i base = _mm_set1_epi16(val);
+ const __m128i out_0 = _mm_add_epi16(base, top_base_0);
+ const __m128i out_1 = _mm_add_epi16(base, top_base_1);
+ const __m128i out = _mm_packus_epi16(out_0, out_1);
+ _mm_storeu_si128((__m128i*)dst, out);
+ }
+ }
+}
+
+static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
+static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
+static void TM16(uint8_t* dst) { TrueMotion(dst, 16); }
+
+static void VE16(uint8_t* dst) {
+ const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
+ int j;
+ for (j = 0; j < 16; ++j) {
+ _mm_storeu_si128((__m128i*)(dst + j * BPS), top);
+ }
+}
+
+static void HE16(uint8_t* dst) { // horizontal
+ int j;
+ for (j = 16; j > 0; --j) {
+ const __m128i values = _mm_set1_epi8(dst[-1]);
+ _mm_storeu_si128((__m128i*)dst, values);
+ dst += BPS;
+ }
+}
+
+static WEBP_INLINE void Put16(uint8_t v, uint8_t* dst) {
+ int j;
+ const __m128i values = _mm_set1_epi8(v);
+ for (j = 0; j < 16; ++j) {
+ _mm_storeu_si128((__m128i*)(dst + j * BPS), values);
+ }
+}
+
+static void DC16(uint8_t* dst) { // DC
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
+ const __m128i sad8x2 = _mm_sad_epu8(top, zero);
+ // sum the two sads: sad8x2[0:1] + sad8x2[8:9]
+ const __m128i sum = _mm_add_epi16(sad8x2, _mm_shuffle_epi32(sad8x2, 2));
+ int left = 0;
+ int j;
+ for (j = 0; j < 16; ++j) {
+ left += dst[-1 + j * BPS];
+ }
+ {
+ const int DC = _mm_cvtsi128_si32(sum) + left + 16;
+ Put16(DC >> 5, dst);
+ }
+}
+
+static void DC16NoTop(uint8_t* dst) { // DC with top samples not available
+ int DC = 8;
+ int j;
+ for (j = 0; j < 16; ++j) {
+ DC += dst[-1 + j * BPS];
+ }
+ Put16(DC >> 4, dst);
+}
+
+static void DC16NoLeft(uint8_t* dst) { // DC with left samples not available
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
+ const __m128i sad8x2 = _mm_sad_epu8(top, zero);
+ // sum the two sads: sad8x2[0:1] + sad8x2[8:9]
+ const __m128i sum = _mm_add_epi16(sad8x2, _mm_shuffle_epi32(sad8x2, 2));
+ const int DC = _mm_cvtsi128_si32(sum) + 8;
+ Put16(DC >> 4, dst);
+}
+
+static void DC16NoTopLeft(uint8_t* dst) { // DC with no top and left samples
+ Put16(0x80, dst);
+}
+
+//------------------------------------------------------------------------------
+// Chroma
+
+static void VE8uv(uint8_t* dst) { // vertical
+ int j;
+ const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
+ for (j = 0; j < 8; ++j) {
+ _mm_storel_epi64((__m128i*)(dst + j * BPS), top);
+ }
+}
+
+static void HE8uv(uint8_t* dst) { // horizontal
+ int j;
+ for (j = 0; j < 8; ++j) {
+ const __m128i values = _mm_set1_epi8(dst[-1]);
+ _mm_storel_epi64((__m128i*)dst, values);
+ dst += BPS;
+ }
+}
+
+// helper for chroma-DC predictions
+static WEBP_INLINE void Put8x8uv(uint8_t v, uint8_t* dst) {
+ int j;
+ const __m128i values = _mm_set1_epi8(v);
+ for (j = 0; j < 8; ++j) {
+ _mm_storel_epi64((__m128i*)(dst + j * BPS), values);
+ }
+}
+
+static void DC8uv(uint8_t* dst) { // DC
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
+ const __m128i sum = _mm_sad_epu8(top, zero);
+ int left = 0;
+ int j;
+ for (j = 0; j < 8; ++j) {
+ left += dst[-1 + j * BPS];
+ }
+ {
+ const int DC = _mm_cvtsi128_si32(sum) + left + 8;
+ Put8x8uv(DC >> 4, dst);
+ }
+}
+
+static void DC8uvNoLeft(uint8_t* dst) { // DC with no left samples
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
+ const __m128i sum = _mm_sad_epu8(top, zero);
+ const int DC = _mm_cvtsi128_si32(sum) + 4;
+ Put8x8uv(DC >> 3, dst);
+}
+
+static void DC8uvNoTop(uint8_t* dst) { // DC with no top samples
+ int dc0 = 4;
+ int i;
+ for (i = 0; i < 8; ++i) {
+ dc0 += dst[-1 + i * BPS];
+ }
+ Put8x8uv(dc0 >> 3, dst);
+}
+
+static void DC8uvNoTopLeft(uint8_t* dst) { // DC with nothing
+ Put8x8uv(0x80, dst);
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE2(void) {
+ VP8Transform = Transform;
+#if defined(USE_TRANSFORM_AC3)
+ VP8TransformAC3 = TransformAC3;
+#endif
+
+ VP8VFilter16 = VFilter16;
+ VP8HFilter16 = HFilter16;
+ VP8VFilter8 = VFilter8;
+ VP8HFilter8 = HFilter8;
+ VP8VFilter16i = VFilter16i;
+ VP8HFilter16i = HFilter16i;
+ VP8VFilter8i = VFilter8i;
+ VP8HFilter8i = HFilter8i;
+
+ VP8SimpleVFilter16 = SimpleVFilter16;
+ VP8SimpleHFilter16 = SimpleHFilter16;
+ VP8SimpleVFilter16i = SimpleVFilter16i;
+ VP8SimpleHFilter16i = SimpleHFilter16i;
+
+ VP8PredLuma4[1] = TM4;
+ VP8PredLuma4[2] = VE4;
+ VP8PredLuma4[4] = RD4;
+ VP8PredLuma4[5] = VR4;
+ VP8PredLuma4[6] = LD4;
+ VP8PredLuma4[7] = VL4;
+
+ VP8PredLuma16[0] = DC16;
+ VP8PredLuma16[1] = TM16;
+ VP8PredLuma16[2] = VE16;
+ VP8PredLuma16[3] = HE16;
+ VP8PredLuma16[4] = DC16NoTop;
+ VP8PredLuma16[5] = DC16NoLeft;
+ VP8PredLuma16[6] = DC16NoTopLeft;
+
+ VP8PredChroma8[0] = DC8uv;
+ VP8PredChroma8[1] = TM8uv;
+ VP8PredChroma8[2] = VE8uv;
+ VP8PredChroma8[3] = HE8uv;
+ VP8PredChroma8[4] = DC8uvNoTop;
+ VP8PredChroma8[5] = DC8uvNoLeft;
+ VP8PredChroma8[6] = DC8uvNoTopLeft;
+}
+
+#else // !WEBP_USE_SSE2
+
+WEBP_DSP_INIT_STUB(VP8DspInitSSE2)
+
+#endif // WEBP_USE_SSE2
diff --git a/media/libwebp/dsp/dec_sse41.c b/media/libwebp/dsp/dec_sse41.c
new file mode 100644
index 000000000..4e81ec4d8
--- /dev/null
+++ b/media/libwebp/dsp/dec_sse41.c
@@ -0,0 +1,46 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE4 version of some decoding functions.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE41)
+
+#include <smmintrin.h>
+#include "../dec/vp8i_dec.h"
+#include "../utils/utils.h"
+
+static void HE16(uint8_t* dst) { // horizontal
+ int j;
+ const __m128i kShuffle3 = _mm_set1_epi8(3);
+ for (j = 16; j > 0; --j) {
+ const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4));
+ const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
+ _mm_storeu_si128((__m128i*)dst, values);
+ dst += BPS;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8DspInitSSE41(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE41(void) {
+ VP8PredLuma16[3] = HE16;
+}
+
+#else // !WEBP_USE_SSE41
+
+WEBP_DSP_INIT_STUB(VP8DspInitSSE41)
+
+#endif // WEBP_USE_SSE41
diff --git a/media/libwebp/dsp/dsp.h b/media/libwebp/dsp/dsp.h
new file mode 100644
index 000000000..813fed4a3
--- /dev/null
+++ b/media/libwebp/dsp/dsp.h
@@ -0,0 +1,594 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_DSP_DSP_H_
+#define WEBP_DSP_DSP_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BPS 32 // this is the common stride for enc/dec
+
+//------------------------------------------------------------------------------
+// CPU detection
+
+#if defined(__GNUC__)
+# define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
+# define LOCAL_GCC_PREREQ(maj, min) \
+ (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
+#else
+# define LOCAL_GCC_VERSION 0
+# define LOCAL_GCC_PREREQ(maj, min) 0
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER > 1310 && \
+ (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
+ (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets
+#endif
+
+// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
+// files without intrinsics, allowing the corresponding Init() to be called.
+// Files containing intrinsics will need to be built targeting the instruction
+// set so should succeed on one of the earlier tests.
+#if defined(__SSE2__) || defined(WEBP_MSC_SSE2) || defined(WEBP_HAVE_SSE2)
+#define WEBP_USE_SSE2
+#endif
+
+#if defined(__SSE4_1__) || defined(WEBP_MSC_SSE41) || defined(WEBP_HAVE_SSE41)
+#define WEBP_USE_SSE41
+#endif
+
+#if defined(__AVX2__) || defined(WEBP_HAVE_AVX2)
+#define WEBP_USE_AVX2
+#endif
+
+#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
+#define WEBP_ANDROID_NEON // Android targets that might support NEON
+#endif
+
+// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
+// inline assembly would need to be modified for use with Native Client.
+#if (defined(__ARM_NEON__) || defined(WEBP_ANDROID_NEON) || \
+ defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \
+ !defined(__native_client__)
+#define WEBP_USE_NEON
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
+#define WEBP_USE_NEON
+#define WEBP_USE_INTRINSICS
+#endif
+
+#if defined(__mips__) && !defined(__mips64) && \
+ defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
+#define WEBP_USE_MIPS32
+#if (__mips_isa_rev >= 2)
+#define WEBP_USE_MIPS32_R2
+#if defined(__mips_dspr2) || (__mips_dsp_rev >= 2)
+#define WEBP_USE_MIPS_DSP_R2
+#endif
+#endif
+#endif
+
+#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
+#define WEBP_USE_MSA
+#endif
+
+// This macro prevents thread_sanitizer from reporting known concurrent writes.
+#define WEBP_TSAN_IGNORE_FUNCTION
+#if defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#undef WEBP_TSAN_IGNORE_FUNCTION
+#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
+#endif
+#endif
+
+#define WEBP_UBSAN_IGNORE_UNDEF
+#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
+#if defined(__clang__) && defined(__has_attribute)
+#if __has_attribute(no_sanitize)
+// This macro prevents the undefined behavior sanitizer from reporting
+// failures. This is only meant to silence unaligned loads on platforms that
+// are known to support them.
+#undef WEBP_UBSAN_IGNORE_UNDEF
+#define WEBP_UBSAN_IGNORE_UNDEF \
+ __attribute__((no_sanitize("undefined")))
+
+// This macro prevents the undefined behavior sanitizer from reporting
+// failures related to unsigned integer overflows. This is only meant to
+// silence cases where this well defined behavior is expected.
+#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
+#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
+ __attribute__((no_sanitize("unsigned-integer-overflow")))
+#endif
+#endif
+
+typedef enum {
+ kSSE2,
+ kSSE3,
+ kSlowSSSE3, // special feature for slow SSSE3 architectures
+ kSSE4_1,
+ kAVX,
+ kAVX2,
+ kNEON,
+ kMIPS32,
+ kMIPSdspR2,
+ kMSA
+} CPUFeature;
+// returns true if the CPU supports the feature.
+typedef int (*VP8CPUInfo)(CPUFeature feature);
+WEBP_EXTERN(VP8CPUInfo) VP8GetCPUInfo;
+
+//------------------------------------------------------------------------------
+// Init stub generator
+
+// Defines an init function stub to ensure each module exposes a symbol,
+// avoiding a compiler warning.
+#define WEBP_DSP_INIT_STUB(func) \
+ extern void func(void); \
+ WEBP_TSAN_IGNORE_FUNCTION void func(void) {}
+
+//------------------------------------------------------------------------------
+// Encoding
+
+// Transforms
+// VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms
+// will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4).
+typedef void (*VP8Idct)(const uint8_t* ref, const int16_t* in, uint8_t* dst,
+ int do_two);
+typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out);
+typedef void (*VP8WHT)(const int16_t* in, int16_t* out);
+extern VP8Idct VP8ITransform;
+extern VP8Fdct VP8FTransform;
+extern VP8Fdct VP8FTransform2; // performs two transforms at a time
+extern VP8WHT VP8FTransformWHT;
+// Predictions
+// *dst is the destination block. *top and *left can be NULL.
+typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left,
+ const uint8_t* top);
+typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top);
+extern VP8Intra4Preds VP8EncPredLuma4;
+extern VP8IntraPreds VP8EncPredLuma16;
+extern VP8IntraPreds VP8EncPredChroma8;
+
+typedef int (*VP8Metric)(const uint8_t* pix, const uint8_t* ref);
+extern VP8Metric VP8SSE16x16, VP8SSE16x8, VP8SSE8x8, VP8SSE4x4;
+typedef int (*VP8WMetric)(const uint8_t* pix, const uint8_t* ref,
+ const uint16_t* const weights);
+// The weights for VP8TDisto4x4 and VP8TDisto16x16 contain a row-major
+// 4 by 4 symmetric matrix.
+extern VP8WMetric VP8TDisto4x4, VP8TDisto16x16;
+
+// Compute the average (DC) of four 4x4 blocks.
+// Each sub-4x4 block #i sum is stored in dc[i].
+typedef void (*VP8MeanMetric)(const uint8_t* ref, uint32_t dc[4]);
+extern VP8MeanMetric VP8Mean16x4;
+
+typedef void (*VP8BlockCopy)(const uint8_t* src, uint8_t* dst);
+extern VP8BlockCopy VP8Copy4x4;
+extern VP8BlockCopy VP8Copy16x8;
+// Quantization
+struct VP8Matrix; // forward declaration
+typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16],
+ const struct VP8Matrix* const mtx);
+// Same as VP8QuantizeBlock, but quantizes two consecutive blocks.
+typedef int (*VP8Quantize2Blocks)(int16_t in[32], int16_t out[32],
+ const struct VP8Matrix* const mtx);
+
+extern VP8QuantizeBlock VP8EncQuantizeBlock;
+extern VP8Quantize2Blocks VP8EncQuantize2Blocks;
+
+// specific to 2nd transform:
+typedef int (*VP8QuantizeBlockWHT)(int16_t in[16], int16_t out[16],
+ const struct VP8Matrix* const mtx);
+extern VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT;
+
+extern const int VP8DspScan[16 + 4 + 4];
+
+// Collect histogram for susceptibility calculation.
+#define MAX_COEFF_THRESH 31 // size of histogram used by CollectHistogram.
+typedef struct {
+ // We only need to store max_value and last_non_zero, not the distribution.
+ int max_value;
+ int last_non_zero;
+} VP8Histogram;
+typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
+ int start_block, int end_block,
+ VP8Histogram* const histo);
+extern VP8CHisto VP8CollectHistogram;
+// General-purpose util function to help VP8CollectHistogram().
+void VP8SetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
+ VP8Histogram* const histo);
+
+// must be called before using any of the above
+void VP8EncDspInit(void);
+
+//------------------------------------------------------------------------------
+// cost functions (encoding)
+
+extern const uint16_t VP8EntropyCost[256]; // 8bit fixed-point log(p)
+// approximate cost per level:
+extern const uint16_t VP8LevelFixedCosts[2047 /*MAX_LEVEL*/ + 1];
+extern const uint8_t VP8EncBands[16 + 1];
+
+struct VP8Residual;
+typedef void (*VP8SetResidualCoeffsFunc)(const int16_t* const coeffs,
+ struct VP8Residual* const res);
+extern VP8SetResidualCoeffsFunc VP8SetResidualCoeffs;
+
+// Cost calculation function.
+typedef int (*VP8GetResidualCostFunc)(int ctx0,
+ const struct VP8Residual* const res);
+extern VP8GetResidualCostFunc VP8GetResidualCost;
+
+// must be called before anything using the above
+void VP8EncDspCostInit(void);
+
+//------------------------------------------------------------------------------
+// SSIM / PSNR utils
+
+// struct for accumulating statistical moments
+typedef struct {
+ uint32_t w; // sum(w_i) : sum of weights
+ uint32_t xm, ym; // sum(w_i * x_i), sum(w_i * y_i)
+ uint32_t xxm, xym, yym; // sum(w_i * x_i * x_i), etc.
+} VP8DistoStats;
+
+// Compute the final SSIM value
+// The non-clipped version assumes stats->w = (2 * VP8_SSIM_KERNEL + 1)^2.
+double VP8SSIMFromStats(const VP8DistoStats* const stats);
+double VP8SSIMFromStatsClipped(const VP8DistoStats* const stats);
+
+#define VP8_SSIM_KERNEL 3 // total size of the kernel: 2 * VP8_SSIM_KERNEL + 1
+typedef double (*VP8SSIMGetClippedFunc)(const uint8_t* src1, int stride1,
+ const uint8_t* src2, int stride2,
+ int xo, int yo, // center position
+ int W, int H); // plane dimension
+
+// This version is called with the guarantee that you can load 8 bytes and
+// 8 rows at offset src1 and src2
+typedef double (*VP8SSIMGetFunc)(const uint8_t* src1, int stride1,
+ const uint8_t* src2, int stride2);
+
+extern VP8SSIMGetFunc VP8SSIMGet; // unclipped / unchecked
+extern VP8SSIMGetClippedFunc VP8SSIMGetClipped; // with clipping
+
+typedef uint32_t (*VP8AccumulateSSEFunc)(const uint8_t* src1,
+ const uint8_t* src2, int len);
+extern VP8AccumulateSSEFunc VP8AccumulateSSE;
+
+// must be called before using any of the above directly
+void VP8SSIMDspInit(void);
+
+//------------------------------------------------------------------------------
+// Decoding
+
+typedef void (*VP8DecIdct)(const int16_t* coeffs, uint8_t* dst);
+// when doing two transforms, coeffs is actually int16_t[2][16].
+typedef void (*VP8DecIdct2)(const int16_t* coeffs, uint8_t* dst, int do_two);
+extern VP8DecIdct2 VP8Transform;
+extern VP8DecIdct VP8TransformAC3;
+extern VP8DecIdct VP8TransformUV;
+extern VP8DecIdct VP8TransformDC;
+extern VP8DecIdct VP8TransformDCUV;
+extern VP8WHT VP8TransformWHT;
+
+// *dst is the destination block, with stride BPS. Boundary samples are
+// assumed accessible when needed.
+typedef void (*VP8PredFunc)(uint8_t* dst);
+extern VP8PredFunc VP8PredLuma16[/* NUM_B_DC_MODES */];
+extern VP8PredFunc VP8PredChroma8[/* NUM_B_DC_MODES */];
+extern VP8PredFunc VP8PredLuma4[/* NUM_BMODES */];
+
+// clipping tables (for filtering)
+extern const int8_t* const VP8ksclip1; // clips [-1020, 1020] to [-128, 127]
+extern const int8_t* const VP8ksclip2; // clips [-112, 112] to [-16, 15]
+extern const uint8_t* const VP8kclip1; // clips [-255,511] to [0,255]
+extern const uint8_t* const VP8kabs0; // abs(x) for x in [-255,255]
+// must be called first
+void VP8InitClipTables(void);
+
+// simple filter (only for luma)
+typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh);
+extern VP8SimpleFilterFunc VP8SimpleVFilter16;
+extern VP8SimpleFilterFunc VP8SimpleHFilter16;
+extern VP8SimpleFilterFunc VP8SimpleVFilter16i; // filter 3 inner edges
+extern VP8SimpleFilterFunc VP8SimpleHFilter16i;
+
+// regular filter (on both macroblock edges and inner edges)
+typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride,
+ int thresh, int ithresh, int hev_t);
+typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride,
+ int thresh, int ithresh, int hev_t);
+// on outer edge
+extern VP8LumaFilterFunc VP8VFilter16;
+extern VP8LumaFilterFunc VP8HFilter16;
+extern VP8ChromaFilterFunc VP8VFilter8;
+extern VP8ChromaFilterFunc VP8HFilter8;
+
+// on inner edge
+extern VP8LumaFilterFunc VP8VFilter16i; // filtering 3 inner edges altogether
+extern VP8LumaFilterFunc VP8HFilter16i;
+extern VP8ChromaFilterFunc VP8VFilter8i; // filtering u and v altogether
+extern VP8ChromaFilterFunc VP8HFilter8i;
+
+// Dithering. Combines dithering values (centered around 128) with dst[],
+// according to: dst[] = clip(dst[] + (((dither[]-128) + 8) >> 4)
+#define VP8_DITHER_DESCALE 4
+#define VP8_DITHER_DESCALE_ROUNDER (1 << (VP8_DITHER_DESCALE - 1))
+#define VP8_DITHER_AMP_BITS 7
+#define VP8_DITHER_AMP_CENTER (1 << VP8_DITHER_AMP_BITS)
+extern void (*VP8DitherCombine8x8)(const uint8_t* dither, uint8_t* dst,
+ int dst_stride);
+
+// must be called before anything using the above
+void VP8DspInit(void);
+
+//------------------------------------------------------------------------------
+// WebP I/O
+
+#define FANCY_UPSAMPLING // undefined to remove fancy upsampling support
+
+// Convert a pair of y/u/v lines together to the output rgb/a colorspace.
+// bottom_y can be NULL if only one line of output is needed (at top/bottom).
+typedef void (*WebPUpsampleLinePairFunc)(
+ const uint8_t* top_y, const uint8_t* bottom_y,
+ const uint8_t* top_u, const uint8_t* top_v,
+ const uint8_t* cur_u, const uint8_t* cur_v,
+ uint8_t* top_dst, uint8_t* bottom_dst, int len);
+
+#ifdef FANCY_UPSAMPLING
+
+// Fancy upsampling functions to convert YUV to RGB(A) modes
+extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
+
+#endif // FANCY_UPSAMPLING
+
+// Per-row point-sampling methods.
+typedef void (*WebPSamplerRowFunc)(const uint8_t* y,
+ const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len);
+// Generic function to apply 'WebPSamplerRowFunc' to the whole plane:
+void WebPSamplerProcessPlane(const uint8_t* y, int y_stride,
+ const uint8_t* u, const uint8_t* v, int uv_stride,
+ uint8_t* dst, int dst_stride,
+ int width, int height, WebPSamplerRowFunc func);
+
+// Sampling functions to convert rows of YUV to RGB(A)
+extern WebPSamplerRowFunc WebPSamplers[/* MODE_LAST */];
+
+// General function for converting two lines of ARGB or RGBA.
+// 'alpha_is_last' should be true if 0xff000000 is stored in memory as
+// as 0x00, 0x00, 0x00, 0xff (little endian).
+WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last);
+
+// YUV444->RGB converters
+typedef void (*WebPYUV444Converter)(const uint8_t* y,
+ const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len);
+
+extern WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */];
+
+// Must be called before using the WebPUpsamplers[] (and for premultiplied
+// colorspaces like rgbA, rgbA4444, etc)
+void WebPInitUpsamplers(void);
+// Must be called before using WebPSamplers[]
+void WebPInitSamplers(void);
+// Must be called before using WebPYUV444Converters[]
+void WebPInitYUV444Converters(void);
+
+//------------------------------------------------------------------------------
+// ARGB -> YUV converters
+
+// Convert ARGB samples to luma Y.
+extern void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width);
+// Convert ARGB samples to U/V with downsampling. do_store should be '1' for
+// even lines and '0' for odd ones. 'src_width' is the original width, not
+// the U/V one.
+extern void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v,
+ int src_width, int do_store);
+
+// Convert a row of accumulated (four-values) of rgba32 toward U/V
+extern void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb,
+ uint8_t* u, uint8_t* v, int width);
+
+// Convert RGB or BGR to Y
+extern void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width);
+extern void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width);
+
+// used for plain-C fallback.
+extern void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v,
+ int src_width, int do_store);
+extern void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
+ uint8_t* u, uint8_t* v, int width);
+
+// utilities for accurate RGB->YUV conversion
+extern uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* src, const uint16_t* ref,
+ uint16_t* dst, int len);
+extern void (*WebPSharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref,
+ int16_t* dst, int len);
+extern void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B,
+ int len,
+ const uint16_t* best_y, uint16_t* out);
+
+// Must be called before using the above.
+void WebPInitConvertARGBToYUV(void);
+
+//------------------------------------------------------------------------------
+// Rescaler
+
+struct WebPRescaler;
+
+// Import a row of data and save its contribution in the rescaler.
+// 'channel' denotes the channel number to be imported. 'Expand' corresponds to
+// the wrk->x_expand case. Otherwise, 'Shrink' is to be used.
+typedef void (*WebPRescalerImportRowFunc)(struct WebPRescaler* const wrk,
+ const uint8_t* src);
+
+extern WebPRescalerImportRowFunc WebPRescalerImportRowExpand;
+extern WebPRescalerImportRowFunc WebPRescalerImportRowShrink;
+
+// Export one row (starting at x_out position) from rescaler.
+// 'Expand' corresponds to the wrk->y_expand case.
+// Otherwise 'Shrink' is to be used
+typedef void (*WebPRescalerExportRowFunc)(struct WebPRescaler* const wrk);
+extern WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
+extern WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
+
+// Plain-C implementation, as fall-back.
+extern void WebPRescalerImportRowExpandC(struct WebPRescaler* const wrk,
+ const uint8_t* src);
+extern void WebPRescalerImportRowShrinkC(struct WebPRescaler* const wrk,
+ const uint8_t* src);
+extern void WebPRescalerExportRowExpandC(struct WebPRescaler* const wrk);
+extern void WebPRescalerExportRowShrinkC(struct WebPRescaler* const wrk);
+
+// Main entry calls:
+extern void WebPRescalerImportRow(struct WebPRescaler* const wrk,
+ const uint8_t* src);
+// Export one row (starting at x_out position) from rescaler.
+extern void WebPRescalerExportRow(struct WebPRescaler* const wrk);
+
+// Must be called first before using the above.
+void WebPRescalerDspInit(void);
+
+//------------------------------------------------------------------------------
+// Utilities for processing transparent channel.
+
+// Apply alpha pre-multiply on an rgba, bgra or argb plane of size w * h.
+// alpha_first should be 0 for argb, 1 for rgba or bgra (where alpha is last).
+extern void (*WebPApplyAlphaMultiply)(
+ uint8_t* rgba, int alpha_first, int w, int h, int stride);
+
+// Same, buf specifically for RGBA4444 format
+extern void (*WebPApplyAlphaMultiply4444)(
+ uint8_t* rgba4444, int w, int h, int stride);
+
+// Dispatch the values from alpha[] plane to the ARGB destination 'dst'.
+// Returns true if alpha[] plane has non-trivial values different from 0xff.
+extern int (*WebPDispatchAlpha)(const uint8_t* alpha, int alpha_stride,
+ int width, int height,
+ uint8_t* dst, int dst_stride);
+
+// Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the
+// A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units.
+extern void (*WebPDispatchAlphaToGreen)(const uint8_t* alpha, int alpha_stride,
+ int width, int height,
+ uint32_t* dst, int dst_stride);
+
+// Extract the alpha values from 32b values in argb[] and pack them into alpha[]
+// (this is the opposite of WebPDispatchAlpha).
+// Returns true if there's only trivial 0xff alpha values.
+extern int (*WebPExtractAlpha)(const uint8_t* argb, int argb_stride,
+ int width, int height,
+ uint8_t* alpha, int alpha_stride);
+
+// Extract the green values from 32b values in argb[] and pack them into alpha[]
+// (this is the opposite of WebPDispatchAlphaToGreen).
+extern void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
+
+// Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B).
+// Un-Multiply operation transforms x into x * 255 / A.
+
+// Pre-Multiply or Un-Multiply (if 'inverse' is true) argb values in a row.
+extern void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
+
+// Same a WebPMultARGBRow(), but for several rows.
+void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
+ int inverse);
+
+// Same for a row of single values, with side alpha values.
+extern void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
+ int width, int inverse);
+
+// Same a WebPMultRow(), but for several 'num_rows' rows.
+void WebPMultRows(uint8_t* ptr, int stride,
+ const uint8_t* alpha, int alpha_stride,
+ int width, int num_rows, int inverse);
+
+// Plain-C versions, used as fallback by some implementations.
+void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
+ int width, int inverse);
+void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse);
+
+// To be called first before using the above.
+void WebPInitAlphaProcessing(void);
+
+// ARGB packing function: a/r/g/b input is rgba or bgra order.
+extern void (*VP8PackARGB)(const uint8_t* a, const uint8_t* r,
+ const uint8_t* g, const uint8_t* b, int len,
+ uint32_t* out);
+
+// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
+extern void (*VP8PackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
+ int len, int step, uint32_t* out);
+
+// To be called first before using the above.
+void VP8EncDspARGBInit(void);
+
+//------------------------------------------------------------------------------
+// Filter functions
+
+typedef enum { // Filter types.
+ WEBP_FILTER_NONE = 0,
+ WEBP_FILTER_HORIZONTAL,
+ WEBP_FILTER_VERTICAL,
+ WEBP_FILTER_GRADIENT,
+ WEBP_FILTER_LAST = WEBP_FILTER_GRADIENT + 1, // end marker
+ WEBP_FILTER_BEST, // meta-types
+ WEBP_FILTER_FAST
+} WEBP_FILTER_TYPE;
+
+typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height,
+ int stride, uint8_t* out);
+// In-place un-filtering.
+// Warning! 'prev_line' pointer can be equal to 'cur_line' or 'preds'.
+typedef void (*WebPUnfilterFunc)(const uint8_t* prev_line, const uint8_t* preds,
+ uint8_t* cur_line, int width);
+
+// Filter the given data using the given predictor.
+// 'in' corresponds to a 2-dimensional pixel array of size (stride * height)
+// in raster order.
+// 'stride' is number of bytes per scan line (with possible padding).
+// 'out' should be pre-allocated.
+extern WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
+
+// In-place reconstruct the original data from the given filtered data.
+// The reconstruction will be done for 'num_rows' rows starting from 'row'
+// (assuming rows upto 'row - 1' are already reconstructed).
+extern WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
+
+// To be called first before using the above.
+void VP8FiltersInit(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_DSP_DSP_H_ */
diff --git a/media/libwebp/dsp/filters.c b/media/libwebp/dsp/filters.c
new file mode 100644
index 000000000..65f34aad1
--- /dev/null
+++ b/media/libwebp/dsp/filters.c
@@ -0,0 +1,273 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Spatial prediction using various filters
+//
+// Author: Urvang (urvang@google.com)
+
+#include "./dsp.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Helpful macro.
+
+# define SANITY_CHECK(in, out) \
+ assert(in != NULL); \
+ assert(out != NULL); \
+ assert(width > 0); \
+ assert(height > 0); \
+ assert(stride >= width); \
+ assert(row >= 0 && num_rows > 0 && row + num_rows <= height); \
+ (void)height; // Silence unused warning.
+
+static WEBP_INLINE void PredictLine(const uint8_t* src, const uint8_t* pred,
+ uint8_t* dst, int length, int inverse) {
+ int i;
+ if (inverse) {
+ for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i];
+ } else {
+ for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i];
+ }
+}
+
+//------------------------------------------------------------------------------
+// Horizontal filter.
+
+static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
+ int width, int height, int stride,
+ int row, int num_rows,
+ int inverse, uint8_t* out) {
+ const uint8_t* preds;
+ const size_t start_offset = row * stride;
+ const int last_row = row + num_rows;
+ SANITY_CHECK(in, out);
+ in += start_offset;
+ out += start_offset;
+ preds = inverse ? out : in;
+
+ if (row == 0) {
+ // Leftmost pixel is the same as input for topmost scanline.
+ out[0] = in[0];
+ PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+ row = 1;
+ preds += stride;
+ in += stride;
+ out += stride;
+ }
+
+ // Filter line-by-line.
+ while (row < last_row) {
+ // Leftmost pixel is predicted from above.
+ PredictLine(in, preds - stride, out, 1, inverse);
+ PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+ ++row;
+ preds += stride;
+ in += stride;
+ out += stride;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Vertical filter.
+
+static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
+ int width, int height, int stride,
+ int row, int num_rows,
+ int inverse, uint8_t* out) {
+ const uint8_t* preds;
+ const size_t start_offset = row * stride;
+ const int last_row = row + num_rows;
+ SANITY_CHECK(in, out);
+ in += start_offset;
+ out += start_offset;
+ preds = inverse ? out : in;
+
+ if (row == 0) {
+ // Very first top-left pixel is copied.
+ out[0] = in[0];
+ // Rest of top scan-line is left-predicted.
+ PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+ row = 1;
+ in += stride;
+ out += stride;
+ } else {
+ // We are starting from in-between. Make sure 'preds' points to prev row.
+ preds -= stride;
+ }
+
+ // Filter line-by-line.
+ while (row < last_row) {
+ PredictLine(in, preds, out, width, inverse);
+ ++row;
+ preds += stride;
+ in += stride;
+ out += stride;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Gradient filter.
+
+static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) {
+ const int g = a + b - c;
+ return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit
+}
+
+static WEBP_INLINE void DoGradientFilter(const uint8_t* in,
+ int width, int height, int stride,
+ int row, int num_rows,
+ int inverse, uint8_t* out) {
+ const uint8_t* preds;
+ const size_t start_offset = row * stride;
+ const int last_row = row + num_rows;
+ SANITY_CHECK(in, out);
+ in += start_offset;
+ out += start_offset;
+ preds = inverse ? out : in;
+
+ // left prediction for top scan-line
+ if (row == 0) {
+ out[0] = in[0];
+ PredictLine(in + 1, preds, out + 1, width - 1, inverse);
+ row = 1;
+ preds += stride;
+ in += stride;
+ out += stride;
+ }
+
+ // Filter line-by-line.
+ while (row < last_row) {
+ int w;
+ // leftmost pixel: predict from above.
+ PredictLine(in, preds - stride, out, 1, inverse);
+ for (w = 1; w < width; ++w) {
+ const int pred = GradientPredictor(preds[w - 1],
+ preds[w - stride],
+ preds[w - stride - 1]);
+ out[w] = in[w] + (inverse ? pred : -pred);
+ }
+ ++row;
+ preds += stride;
+ in += stride;
+ out += stride;
+ }
+}
+
+#undef SANITY_CHECK
+
+//------------------------------------------------------------------------------
+
+static void HorizontalFilter(const uint8_t* data, int width, int height,
+ int stride, uint8_t* filtered_data) {
+ DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+static void VerticalFilter(const uint8_t* data, int width, int height,
+ int stride, uint8_t* filtered_data) {
+ DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+
+static void GradientFilter(const uint8_t* data, int width, int height,
+ int stride, uint8_t* filtered_data) {
+ DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data);
+}
+
+
+//------------------------------------------------------------------------------
+
+static void HorizontalUnfilter(const uint8_t* prev, const uint8_t* in,
+ uint8_t* out, int width) {
+ uint8_t pred = (prev == NULL) ? 0 : prev[0];
+ int i;
+ for (i = 0; i < width; ++i) {
+ out[i] = pred + in[i];
+ pred = out[i];
+ }
+}
+
+static void VerticalUnfilter(const uint8_t* prev, const uint8_t* in,
+ uint8_t* out, int width) {
+ if (prev == NULL) {
+ HorizontalUnfilter(NULL, in, out, width);
+ } else {
+ int i;
+ for (i = 0; i < width; ++i) out[i] = prev[i] + in[i];
+ }
+}
+
+static void GradientUnfilter(const uint8_t* prev, const uint8_t* in,
+ uint8_t* out, int width) {
+ if (prev == NULL) {
+ HorizontalUnfilter(NULL, in, out, width);
+ } else {
+ uint8_t top = prev[0], top_left = top, left = top;
+ int i;
+ for (i = 0; i < width; ++i) {
+ top = prev[i]; // need to read this first, in case prev==out
+ left = in[i] + GradientPredictor(left, top, top_left);
+ top_left = top;
+ out[i] = left;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Init function
+
+WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
+WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
+
+extern void VP8FiltersInitMIPSdspR2(void);
+extern void VP8FiltersInitMSA(void);
+extern void VP8FiltersInitNEON(void);
+extern void VP8FiltersInitSSE2(void);
+
+static volatile VP8CPUInfo filters_last_cpuinfo_used =
+ (VP8CPUInfo)&filters_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) {
+ if (filters_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ WebPUnfilters[WEBP_FILTER_NONE] = NULL;
+ WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter;
+ WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter;
+ WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter;
+
+ WebPFilters[WEBP_FILTER_NONE] = NULL;
+ WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
+ WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter;
+ WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter;
+
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ VP8FiltersInitSSE2();
+ }
+#endif
+#if defined(WEBP_USE_NEON)
+ if (VP8GetCPUInfo(kNEON)) {
+ VP8FiltersInitNEON();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ VP8FiltersInitMIPSdspR2();
+ }
+#endif
+#if defined(WEBP_USE_MSA)
+ if (VP8GetCPUInfo(kMSA)) {
+ VP8FiltersInitMSA();
+ }
+#endif
+ }
+ filters_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/media/libwebp/dsp/filters_sse2.c b/media/libwebp/dsp/filters_sse2.c
new file mode 100644
index 000000000..67f77999e
--- /dev/null
+++ b/media/libwebp/dsp/filters_sse2.c
@@ -0,0 +1,330 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 variant of alpha filters
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include <assert.h>
+#include <emmintrin.h>
+#include <stdlib.h>
+#include <string.h>
+
+//------------------------------------------------------------------------------
+// Helpful macro.
+
+# define SANITY_CHECK(in, out) \
+ assert(in != NULL); \
+ assert(out != NULL); \
+ assert(width > 0); \
+ assert(height > 0); \
+ assert(stride >= width); \
+ assert(row >= 0 && num_rows > 0 && row + num_rows <= height); \
+ (void)height; // Silence unused warning.
+
+static void PredictLineTop(const uint8_t* src, const uint8_t* pred,
+ uint8_t* dst, int length) {
+ int i;
+ const int max_pos = length & ~31;
+ assert(length >= 0);
+ for (i = 0; i < max_pos; i += 32) {
+ const __m128i A0 = _mm_loadu_si128((const __m128i*)&src[i + 0]);
+ const __m128i A1 = _mm_loadu_si128((const __m128i*)&src[i + 16]);
+ const __m128i B0 = _mm_loadu_si128((const __m128i*)&pred[i + 0]);
+ const __m128i B1 = _mm_loadu_si128((const __m128i*)&pred[i + 16]);
+ const __m128i C0 = _mm_sub_epi8(A0, B0);
+ const __m128i C1 = _mm_sub_epi8(A1, B1);
+ _mm_storeu_si128((__m128i*)&dst[i + 0], C0);
+ _mm_storeu_si128((__m128i*)&dst[i + 16], C1);
+ }
+ for (; i < length; ++i) dst[i] = src[i] - pred[i];
+}
+
+// Special case for left-based prediction (when preds==dst-1 or preds==src-1).
+static void PredictLineLeft(const uint8_t* src, uint8_t* dst, int length) {
+ int i;
+ const int max_pos = length & ~31;
+ assert(length >= 0);
+ for (i = 0; i < max_pos; i += 32) {
+ const __m128i A0 = _mm_loadu_si128((const __m128i*)(src + i + 0 ));
+ const __m128i B0 = _mm_loadu_si128((const __m128i*)(src + i + 0 - 1));
+ const __m128i A1 = _mm_loadu_si128((const __m128i*)(src + i + 16 ));
+ const __m128i B1 = _mm_loadu_si128((const __m128i*)(src + i + 16 - 1));
+ const __m128i C0 = _mm_sub_epi8(A0, B0);
+ const __m128i C1 = _mm_sub_epi8(A1, B1);
+ _mm_storeu_si128((__m128i*)(dst + i + 0), C0);
+ _mm_storeu_si128((__m128i*)(dst + i + 16), C1);
+ }
+ for (; i < length; ++i) dst[i] = src[i] - src[i - 1];
+}
+
+//------------------------------------------------------------------------------
+// Horizontal filter.
+
+static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
+ int width, int height, int stride,
+ int row, int num_rows,
+ uint8_t* out) {
+ const size_t start_offset = row * stride;
+ const int last_row = row + num_rows;
+ SANITY_CHECK(in, out);
+ in += start_offset;
+ out += start_offset;
+
+ if (row == 0) {
+ // Leftmost pixel is the same as input for topmost scanline.
+ out[0] = in[0];
+ PredictLineLeft(in + 1, out + 1, width - 1);
+ row = 1;
+ in += stride;
+ out += stride;
+ }
+
+ // Filter line-by-line.
+ while (row < last_row) {
+ // Leftmost pixel is predicted from above.
+ out[0] = in[0] - in[-stride];
+ PredictLineLeft(in + 1, out + 1, width - 1);
+ ++row;
+ in += stride;
+ out += stride;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Vertical filter.
+
+static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
+ int width, int height, int stride,
+ int row, int num_rows, uint8_t* out) {
+ const size_t start_offset = row * stride;
+ const int last_row = row + num_rows;
+ SANITY_CHECK(in, out);
+ in += start_offset;
+ out += start_offset;
+
+ if (row == 0) {
+ // Very first top-left pixel is copied.
+ out[0] = in[0];
+ // Rest of top scan-line is left-predicted.
+ PredictLineLeft(in + 1, out + 1, width - 1);
+ row = 1;
+ in += stride;
+ out += stride;
+ }
+
+ // Filter line-by-line.
+ while (row < last_row) {
+ PredictLineTop(in, in - stride, out, width);
+ ++row;
+ in += stride;
+ out += stride;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Gradient filter.
+
+static WEBP_INLINE int GradientPredictorC(uint8_t a, uint8_t b, uint8_t c) {
+ const int g = a + b - c;
+ return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit
+}
+
+static void GradientPredictDirect(const uint8_t* const row,
+ const uint8_t* const top,
+ uint8_t* const out, int length) {
+ const int max_pos = length & ~7;
+ int i;
+ const __m128i zero = _mm_setzero_si128();
+ for (i = 0; i < max_pos; i += 8) {
+ const __m128i A0 = _mm_loadl_epi64((const __m128i*)&row[i - 1]);
+ const __m128i B0 = _mm_loadl_epi64((const __m128i*)&top[i]);
+ const __m128i C0 = _mm_loadl_epi64((const __m128i*)&top[i - 1]);
+ const __m128i D = _mm_loadl_epi64((const __m128i*)&row[i]);
+ const __m128i A1 = _mm_unpacklo_epi8(A0, zero);
+ const __m128i B1 = _mm_unpacklo_epi8(B0, zero);
+ const __m128i C1 = _mm_unpacklo_epi8(C0, zero);
+ const __m128i E = _mm_add_epi16(A1, B1);
+ const __m128i F = _mm_sub_epi16(E, C1);
+ const __m128i G = _mm_packus_epi16(F, zero);
+ const __m128i H = _mm_sub_epi8(D, G);
+ _mm_storel_epi64((__m128i*)(out + i), H);
+ }
+ for (; i < length; ++i) {
+ out[i] = row[i] - GradientPredictorC(row[i - 1], top[i], top[i - 1]);
+ }
+}
+
+static WEBP_INLINE void DoGradientFilter(const uint8_t* in,
+ int width, int height, int stride,
+ int row, int num_rows,
+ uint8_t* out) {
+ const size_t start_offset = row * stride;
+ const int last_row = row + num_rows;
+ SANITY_CHECK(in, out);
+ in += start_offset;
+ out += start_offset;
+
+ // left prediction for top scan-line
+ if (row == 0) {
+ out[0] = in[0];
+ PredictLineLeft(in + 1, out + 1, width - 1);
+ row = 1;
+ in += stride;
+ out += stride;
+ }
+
+ // Filter line-by-line.
+ while (row < last_row) {
+ out[0] = in[0] - in[-stride];
+ GradientPredictDirect(in + 1, in + 1 - stride, out + 1, width - 1);
+ ++row;
+ in += stride;
+ out += stride;
+ }
+}
+
+#undef SANITY_CHECK
+
+//------------------------------------------------------------------------------
+
+static void HorizontalFilter(const uint8_t* data, int width, int height,
+ int stride, uint8_t* filtered_data) {
+ DoHorizontalFilter(data, width, height, stride, 0, height, filtered_data);
+}
+
+static void VerticalFilter(const uint8_t* data, int width, int height,
+ int stride, uint8_t* filtered_data) {
+ DoVerticalFilter(data, width, height, stride, 0, height, filtered_data);
+}
+
+static void GradientFilter(const uint8_t* data, int width, int height,
+ int stride, uint8_t* filtered_data) {
+ DoGradientFilter(data, width, height, stride, 0, height, filtered_data);
+}
+
+//------------------------------------------------------------------------------
+// Inverse transforms
+
+static void HorizontalUnfilter(const uint8_t* prev, const uint8_t* in,
+ uint8_t* out, int width) {
+ int i;
+ __m128i last;
+ out[0] = in[0] + (prev == NULL ? 0 : prev[0]);
+ if (width <= 1) return;
+ last = _mm_set_epi32(0, 0, 0, out[0]);
+ for (i = 1; i + 8 <= width; i += 8) {
+ const __m128i A0 = _mm_loadl_epi64((const __m128i*)(in + i));
+ const __m128i A1 = _mm_add_epi8(A0, last);
+ const __m128i A2 = _mm_slli_si128(A1, 1);
+ const __m128i A3 = _mm_add_epi8(A1, A2);
+ const __m128i A4 = _mm_slli_si128(A3, 2);
+ const __m128i A5 = _mm_add_epi8(A3, A4);
+ const __m128i A6 = _mm_slli_si128(A5, 4);
+ const __m128i A7 = _mm_add_epi8(A5, A6);
+ _mm_storel_epi64((__m128i*)(out + i), A7);
+ last = _mm_srli_epi64(A7, 56);
+ }
+ for (; i < width; ++i) out[i] = in[i] + out[i - 1];
+}
+
+static void VerticalUnfilter(const uint8_t* prev, const uint8_t* in,
+ uint8_t* out, int width) {
+ if (prev == NULL) {
+ HorizontalUnfilter(NULL, in, out, width);
+ } else {
+ int i;
+ const int max_pos = width & ~31;
+ assert(width >= 0);
+ for (i = 0; i < max_pos; i += 32) {
+ const __m128i A0 = _mm_loadu_si128((const __m128i*)&in[i + 0]);
+ const __m128i A1 = _mm_loadu_si128((const __m128i*)&in[i + 16]);
+ const __m128i B0 = _mm_loadu_si128((const __m128i*)&prev[i + 0]);
+ const __m128i B1 = _mm_loadu_si128((const __m128i*)&prev[i + 16]);
+ const __m128i C0 = _mm_add_epi8(A0, B0);
+ const __m128i C1 = _mm_add_epi8(A1, B1);
+ _mm_storeu_si128((__m128i*)&out[i + 0], C0);
+ _mm_storeu_si128((__m128i*)&out[i + 16], C1);
+ }
+ for (; i < width; ++i) out[i] = in[i] + prev[i];
+ }
+}
+
+static void GradientPredictInverse(const uint8_t* const in,
+ const uint8_t* const top,
+ uint8_t* const row, int length) {
+ if (length > 0) {
+ int i;
+ const int max_pos = length & ~7;
+ const __m128i zero = _mm_setzero_si128();
+ __m128i A = _mm_set_epi32(0, 0, 0, row[-1]); // left sample
+ for (i = 0; i < max_pos; i += 8) {
+ const __m128i tmp0 = _mm_loadl_epi64((const __m128i*)&top[i]);
+ const __m128i tmp1 = _mm_loadl_epi64((const __m128i*)&top[i - 1]);
+ const __m128i B = _mm_unpacklo_epi8(tmp0, zero);
+ const __m128i C = _mm_unpacklo_epi8(tmp1, zero);
+ const __m128i D = _mm_loadl_epi64((const __m128i*)&in[i]); // base input
+ const __m128i E = _mm_sub_epi16(B, C); // unclipped gradient basis B - C
+ __m128i out = zero; // accumulator for output
+ __m128i mask_hi = _mm_set_epi32(0, 0, 0, 0xff);
+ int k = 8;
+ while (1) {
+ const __m128i tmp3 = _mm_add_epi16(A, E); // delta = A + B - C
+ const __m128i tmp4 = _mm_packus_epi16(tmp3, zero); // saturate delta
+ const __m128i tmp5 = _mm_add_epi8(tmp4, D); // add to in[]
+ A = _mm_and_si128(tmp5, mask_hi); // 1-complement clip
+ out = _mm_or_si128(out, A); // accumulate output
+ if (--k == 0) break;
+ A = _mm_slli_si128(A, 1); // rotate left sample
+ mask_hi = _mm_slli_si128(mask_hi, 1); // rotate mask
+ A = _mm_unpacklo_epi8(A, zero); // convert 8b->16b
+ }
+ A = _mm_srli_si128(A, 7); // prepare left sample for next iteration
+ _mm_storel_epi64((__m128i*)&row[i], out);
+ }
+ for (; i < length; ++i) {
+ row[i] = in[i] + GradientPredictorC(row[i - 1], top[i], top[i - 1]);
+ }
+ }
+}
+
+static void GradientUnfilter(const uint8_t* prev, const uint8_t* in,
+ uint8_t* out, int width) {
+ if (prev == NULL) {
+ HorizontalUnfilter(NULL, in, out, width);
+ } else {
+ out[0] = in[0] + prev[0]; // predict from above
+ GradientPredictInverse(in + 1, prev + 1, out + 1, width - 1);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8FiltersInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitSSE2(void) {
+ WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter;
+ WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter;
+ WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter;
+
+ WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
+ WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter;
+ WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter;
+}
+
+#else // !WEBP_USE_SSE2
+
+WEBP_DSP_INIT_STUB(VP8FiltersInitSSE2)
+
+#endif // WEBP_USE_SSE2
diff --git a/media/libwebp/dsp/lossless.c b/media/libwebp/dsp/lossless.c
new file mode 100644
index 000000000..20d18f6ec
--- /dev/null
+++ b/media/libwebp/dsp/lossless.c
@@ -0,0 +1,663 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Image transforms and color space conversion methods for lossless decoder.
+//
+// Authors: Vikas Arora (vikaas.arora@gmail.com)
+// Jyrki Alakuijala (jyrki@google.com)
+// Urvang Joshi (urvang@google.com)
+
+#include "./dsp.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include "../dec/vp8li_dec.h"
+#include "../utils/endian_inl_utils.h"
+#include "./lossless.h"
+#include "./lossless_common.h"
+
+#define MAX_DIFF_COST (1e30f)
+
+//------------------------------------------------------------------------------
+// Image transforms.
+
+static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
+ return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
+}
+
+static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
+ return Average2(Average2(a0, a2), a1);
+}
+
+static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
+ uint32_t a2, uint32_t a3) {
+ return Average2(Average2(a0, a1), Average2(a2, a3));
+}
+
+static WEBP_INLINE uint32_t Clip255(uint32_t a) {
+ if (a < 256) {
+ return a;
+ }
+ // return 0, when a is a negative integer.
+ // return 255, when a is positive.
+ return ~a >> 24;
+}
+
+static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
+ return Clip255(a + b - c);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
+ uint32_t c2) {
+ const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24);
+ const int r = AddSubtractComponentFull((c0 >> 16) & 0xff,
+ (c1 >> 16) & 0xff,
+ (c2 >> 16) & 0xff);
+ const int g = AddSubtractComponentFull((c0 >> 8) & 0xff,
+ (c1 >> 8) & 0xff,
+ (c2 >> 8) & 0xff);
+ const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff);
+ return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
+}
+
+static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
+ return Clip255(a + (a - b) / 2);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
+ uint32_t c2) {
+ const uint32_t ave = Average2(c0, c1);
+ const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24);
+ const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff);
+ const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff);
+ const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff);
+ return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
+}
+
+// gcc-4.9 on ARM generates incorrect code in Select() when Sub3() is inlined.
+#if defined(__arm__) && LOCAL_GCC_VERSION == 0x409
+# define LOCAL_INLINE __attribute__ ((noinline))
+#else
+# define LOCAL_INLINE WEBP_INLINE
+#endif
+
+static LOCAL_INLINE int Sub3(int a, int b, int c) {
+ const int pb = b - c;
+ const int pa = a - c;
+ return abs(pb) - abs(pa);
+}
+
+#undef LOCAL_INLINE
+
+static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
+ const int pa_minus_pb =
+ Sub3((a >> 24) , (b >> 24) , (c >> 24) ) +
+ Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) +
+ Sub3((a >> 8) & 0xff, (b >> 8) & 0xff, (c >> 8) & 0xff) +
+ Sub3((a ) & 0xff, (b ) & 0xff, (c ) & 0xff);
+ return (pa_minus_pb <= 0) ? a : b;
+}
+
+//------------------------------------------------------------------------------
+// Predictors
+
+static uint32_t Predictor0(uint32_t left, const uint32_t* const top) {
+ (void)top;
+ (void)left;
+ return ARGB_BLACK;
+}
+static uint32_t Predictor1(uint32_t left, const uint32_t* const top) {
+ (void)top;
+ return left;
+}
+static uint32_t Predictor2(uint32_t left, const uint32_t* const top) {
+ (void)left;
+ return top[0];
+}
+static uint32_t Predictor3(uint32_t left, const uint32_t* const top) {
+ (void)left;
+ return top[1];
+}
+static uint32_t Predictor4(uint32_t left, const uint32_t* const top) {
+ (void)left;
+ return top[-1];
+}
+static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average3(left, top[0], top[1]);
+ return pred;
+}
+static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(left, top[-1]);
+ return pred;
+}
+static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(left, top[0]);
+ return pred;
+}
+static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(top[-1], top[0]);
+ (void)left;
+ return pred;
+}
+static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(top[0], top[1]);
+ (void)left;
+ return pred;
+}
+static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
+ return pred;
+}
+static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Select(top[0], left, top[-1]);
+ return pred;
+}
+static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
+ return pred;
+}
+static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
+ return pred;
+}
+
+GENERATE_PREDICTOR_ADD(Predictor0, PredictorAdd0)
+static void PredictorAdd1(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint32_t left = out[-1];
+ for (i = 0; i < num_pixels; ++i) {
+ out[i] = left = VP8LAddPixels(in[i], left);
+ }
+ (void)upper;
+}
+GENERATE_PREDICTOR_ADD(Predictor2, PredictorAdd2)
+GENERATE_PREDICTOR_ADD(Predictor3, PredictorAdd3)
+GENERATE_PREDICTOR_ADD(Predictor4, PredictorAdd4)
+GENERATE_PREDICTOR_ADD(Predictor5, PredictorAdd5)
+GENERATE_PREDICTOR_ADD(Predictor6, PredictorAdd6)
+GENERATE_PREDICTOR_ADD(Predictor7, PredictorAdd7)
+GENERATE_PREDICTOR_ADD(Predictor8, PredictorAdd8)
+GENERATE_PREDICTOR_ADD(Predictor9, PredictorAdd9)
+GENERATE_PREDICTOR_ADD(Predictor10, PredictorAdd10)
+GENERATE_PREDICTOR_ADD(Predictor11, PredictorAdd11)
+GENERATE_PREDICTOR_ADD(Predictor12, PredictorAdd12)
+GENERATE_PREDICTOR_ADD(Predictor13, PredictorAdd13)
+
+//------------------------------------------------------------------------------
+
+// Inverse prediction.
+static void PredictorInverseTransform(const VP8LTransform* const transform,
+ int y_start, int y_end,
+ const uint32_t* in, uint32_t* out) {
+ const int width = transform->xsize_;
+ if (y_start == 0) { // First Row follows the L (mode=1) mode.
+ PredictorAdd0(in, NULL, 1, out);
+ PredictorAdd1(in + 1, NULL, width - 1, out + 1);
+ in += width;
+ out += width;
+ ++y_start;
+ }
+
+ {
+ int y = y_start;
+ const int tile_width = 1 << transform->bits_;
+ const int mask = tile_width - 1;
+ const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_);
+ const uint32_t* pred_mode_base =
+ transform->data_ + (y >> transform->bits_) * tiles_per_row;
+
+ while (y < y_end) {
+ const uint32_t* pred_mode_src = pred_mode_base;
+ int x = 1;
+ // First pixel follows the T (mode=2) mode.
+ PredictorAdd2(in, out - width, 1, out);
+ // .. the rest:
+ while (x < width) {
+ const VP8LPredictorAddSubFunc pred_func =
+ VP8LPredictorsAdd[((*pred_mode_src++) >> 8) & 0xf];
+ int x_end = (x & ~mask) + tile_width;
+ if (x_end > width) x_end = width;
+ pred_func(in + x, out + x - width, x_end - x, out + x);
+ x = x_end;
+ }
+ in += width;
+ out += width;
+ ++y;
+ if ((y & mask) == 0) { // Use the same mask, since tiles are squares.
+ pred_mode_base += tiles_per_row;
+ }
+ }
+ }
+}
+
+// Add green to blue and red channels (i.e. perform the inverse transform of
+// 'subtract green').
+void VP8LAddGreenToBlueAndRed_C(const uint32_t* src, int num_pixels,
+ uint32_t* dst) {
+ int i;
+ for (i = 0; i < num_pixels; ++i) {
+ const uint32_t argb = src[i];
+ const uint32_t green = ((argb >> 8) & 0xff);
+ uint32_t red_blue = (argb & 0x00ff00ffu);
+ red_blue += (green << 16) | green;
+ red_blue &= 0x00ff00ffu;
+ dst[i] = (argb & 0xff00ff00u) | red_blue;
+ }
+}
+
+static WEBP_INLINE int ColorTransformDelta(int8_t color_pred,
+ int8_t color) {
+ return ((int)color_pred * color) >> 5;
+}
+
+static WEBP_INLINE void ColorCodeToMultipliers(uint32_t color_code,
+ VP8LMultipliers* const m) {
+ m->green_to_red_ = (color_code >> 0) & 0xff;
+ m->green_to_blue_ = (color_code >> 8) & 0xff;
+ m->red_to_blue_ = (color_code >> 16) & 0xff;
+}
+
+void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
+ const uint32_t* src, int num_pixels,
+ uint32_t* dst) {
+ int i;
+ for (i = 0; i < num_pixels; ++i) {
+ const uint32_t argb = src[i];
+ const uint32_t green = argb >> 8;
+ const uint32_t red = argb >> 16;
+ int new_red = red;
+ int new_blue = argb;
+ new_red += ColorTransformDelta(m->green_to_red_, green);
+ new_red &= 0xff;
+ new_blue += ColorTransformDelta(m->green_to_blue_, green);
+ new_blue += ColorTransformDelta(m->red_to_blue_, new_red);
+ new_blue &= 0xff;
+ dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
+ }
+}
+
+// Color space inverse transform.
+static void ColorSpaceInverseTransform(const VP8LTransform* const transform,
+ int y_start, int y_end,
+ const uint32_t* src, uint32_t* dst) {
+ const int width = transform->xsize_;
+ const int tile_width = 1 << transform->bits_;
+ const int mask = tile_width - 1;
+ const int safe_width = width & ~mask;
+ const int remaining_width = width - safe_width;
+ const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_);
+ int y = y_start;
+ const uint32_t* pred_row =
+ transform->data_ + (y >> transform->bits_) * tiles_per_row;
+
+ while (y < y_end) {
+ const uint32_t* pred = pred_row;
+ VP8LMultipliers m = { 0, 0, 0 };
+ const uint32_t* const src_safe_end = src + safe_width;
+ const uint32_t* const src_end = src + width;
+ while (src < src_safe_end) {
+ ColorCodeToMultipliers(*pred++, &m);
+ VP8LTransformColorInverse(&m, src, tile_width, dst);
+ src += tile_width;
+ dst += tile_width;
+ }
+ if (src < src_end) { // Left-overs using C-version.
+ ColorCodeToMultipliers(*pred++, &m);
+ VP8LTransformColorInverse(&m, src, remaining_width, dst);
+ src += remaining_width;
+ dst += remaining_width;
+ }
+ ++y;
+ if ((y & mask) == 0) pred_row += tiles_per_row;
+ }
+}
+
+// Separate out pixels packed together using pixel-bundling.
+// We define two methods for ARGB data (uint32_t) and alpha-only data (uint8_t).
+#define COLOR_INDEX_INVERSE(FUNC_NAME, F_NAME, STATIC_DECL, TYPE, BIT_SUFFIX, \
+ GET_INDEX, GET_VALUE) \
+static void F_NAME(const TYPE* src, const uint32_t* const color_map, \
+ TYPE* dst, int y_start, int y_end, int width) { \
+ int y; \
+ for (y = y_start; y < y_end; ++y) { \
+ int x; \
+ for (x = 0; x < width; ++x) { \
+ *dst++ = GET_VALUE(color_map[GET_INDEX(*src++)]); \
+ } \
+ } \
+} \
+STATIC_DECL void FUNC_NAME(const VP8LTransform* const transform, \
+ int y_start, int y_end, const TYPE* src, \
+ TYPE* dst) { \
+ int y; \
+ const int bits_per_pixel = 8 >> transform->bits_; \
+ const int width = transform->xsize_; \
+ const uint32_t* const color_map = transform->data_; \
+ if (bits_per_pixel < 8) { \
+ const int pixels_per_byte = 1 << transform->bits_; \
+ const int count_mask = pixels_per_byte - 1; \
+ const uint32_t bit_mask = (1 << bits_per_pixel) - 1; \
+ for (y = y_start; y < y_end; ++y) { \
+ uint32_t packed_pixels = 0; \
+ int x; \
+ for (x = 0; x < width; ++x) { \
+ /* We need to load fresh 'packed_pixels' once every */ \
+ /* 'pixels_per_byte' increments of x. Fortunately, pixels_per_byte */ \
+ /* is a power of 2, so can just use a mask for that, instead of */ \
+ /* decrementing a counter. */ \
+ if ((x & count_mask) == 0) packed_pixels = GET_INDEX(*src++); \
+ *dst++ = GET_VALUE(color_map[packed_pixels & bit_mask]); \
+ packed_pixels >>= bits_per_pixel; \
+ } \
+ } \
+ } else { \
+ VP8LMapColor##BIT_SUFFIX(src, color_map, dst, y_start, y_end, width); \
+ } \
+}
+
+COLOR_INDEX_INVERSE(ColorIndexInverseTransform, MapARGB, static, uint32_t, 32b,
+ VP8GetARGBIndex, VP8GetARGBValue)
+COLOR_INDEX_INVERSE(VP8LColorIndexInverseTransformAlpha, MapAlpha, , uint8_t,
+ 8b, VP8GetAlphaIndex, VP8GetAlphaValue)
+
+#undef COLOR_INDEX_INVERSE
+
+void VP8LInverseTransform(const VP8LTransform* const transform,
+ int row_start, int row_end,
+ const uint32_t* const in, uint32_t* const out) {
+ const int width = transform->xsize_;
+ assert(row_start < row_end);
+ assert(row_end <= transform->ysize_);
+ switch (transform->type_) {
+ case SUBTRACT_GREEN:
+ VP8LAddGreenToBlueAndRed(in, (row_end - row_start) * width, out);
+ break;
+ case PREDICTOR_TRANSFORM:
+ PredictorInverseTransform(transform, row_start, row_end, in, out);
+ if (row_end != transform->ysize_) {
+ // The last predicted row in this iteration will be the top-pred row
+ // for the first row in next iteration.
+ memcpy(out - width, out + (row_end - row_start - 1) * width,
+ width * sizeof(*out));
+ }
+ break;
+ case CROSS_COLOR_TRANSFORM:
+ ColorSpaceInverseTransform(transform, row_start, row_end, in, out);
+ break;
+ case COLOR_INDEXING_TRANSFORM:
+ if (in == out && transform->bits_ > 0) {
+ // Move packed pixels to the end of unpacked region, so that unpacking
+ // can occur seamlessly.
+ // Also, note that this is the only transform that applies on
+ // the effective width of VP8LSubSampleSize(xsize_, bits_). All other
+ // transforms work on effective width of xsize_.
+ const int out_stride = (row_end - row_start) * width;
+ const int in_stride = (row_end - row_start) *
+ VP8LSubSampleSize(transform->xsize_, transform->bits_);
+ uint32_t* const src = out + out_stride - in_stride;
+ memmove(src, out, in_stride * sizeof(*src));
+ ColorIndexInverseTransform(transform, row_start, row_end, src, out);
+ } else {
+ ColorIndexInverseTransform(transform, row_start, row_end, in, out);
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Color space conversion.
+
+static int is_big_endian(void) {
+ static const union {
+ uint16_t w;
+ uint8_t b[2];
+ } tmp = { 1 };
+ return (tmp.b[0] != 1);
+}
+
+void VP8LConvertBGRAToRGB_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const src_end = src + num_pixels;
+ while (src < src_end) {
+ const uint32_t argb = *src++;
+ *dst++ = (argb >> 16) & 0xff;
+ *dst++ = (argb >> 8) & 0xff;
+ *dst++ = (argb >> 0) & 0xff;
+ }
+}
+
+void VP8LConvertBGRAToRGBA_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const src_end = src + num_pixels;
+ while (src < src_end) {
+ const uint32_t argb = *src++;
+ *dst++ = (argb >> 16) & 0xff;
+ *dst++ = (argb >> 8) & 0xff;
+ *dst++ = (argb >> 0) & 0xff;
+ *dst++ = (argb >> 24) & 0xff;
+ }
+}
+
+void VP8LConvertBGRAToRGBA4444_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const src_end = src + num_pixels;
+ while (src < src_end) {
+ const uint32_t argb = *src++;
+ const uint8_t rg = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf);
+ const uint8_t ba = ((argb >> 0) & 0xf0) | ((argb >> 28) & 0xf);
+#ifdef WEBP_SWAP_16BIT_CSP
+ *dst++ = ba;
+ *dst++ = rg;
+#else
+ *dst++ = rg;
+ *dst++ = ba;
+#endif
+ }
+}
+
+void VP8LConvertBGRAToRGB565_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const src_end = src + num_pixels;
+ while (src < src_end) {
+ const uint32_t argb = *src++;
+ const uint8_t rg = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7);
+ const uint8_t gb = ((argb >> 5) & 0xe0) | ((argb >> 3) & 0x1f);
+#ifdef WEBP_SWAP_16BIT_CSP
+ *dst++ = gb;
+ *dst++ = rg;
+#else
+ *dst++ = rg;
+ *dst++ = gb;
+#endif
+ }
+}
+
+void VP8LConvertBGRAToBGR_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const src_end = src + num_pixels;
+ while (src < src_end) {
+ const uint32_t argb = *src++;
+ *dst++ = (argb >> 0) & 0xff;
+ *dst++ = (argb >> 8) & 0xff;
+ *dst++ = (argb >> 16) & 0xff;
+ }
+}
+
+static void CopyOrSwap(const uint32_t* src, int num_pixels, uint8_t* dst,
+ int swap_on_big_endian) {
+ if (is_big_endian() == swap_on_big_endian) {
+ const uint32_t* const src_end = src + num_pixels;
+ while (src < src_end) {
+ const uint32_t argb = *src++;
+
+#if !defined(WORDS_BIGENDIAN)
+#if !defined(WEBP_REFERENCE_IMPLEMENTATION)
+ WebPUint32ToMem(dst, BSwap32(argb));
+#else // WEBP_REFERENCE_IMPLEMENTATION
+ dst[0] = (argb >> 24) & 0xff;
+ dst[1] = (argb >> 16) & 0xff;
+ dst[2] = (argb >> 8) & 0xff;
+ dst[3] = (argb >> 0) & 0xff;
+#endif
+#else // WORDS_BIGENDIAN
+ dst[0] = (argb >> 0) & 0xff;
+ dst[1] = (argb >> 8) & 0xff;
+ dst[2] = (argb >> 16) & 0xff;
+ dst[3] = (argb >> 24) & 0xff;
+#endif
+ dst += sizeof(argb);
+ }
+ } else {
+ memcpy(dst, src, num_pixels * sizeof(*src));
+ }
+}
+
+void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
+ WEBP_CSP_MODE out_colorspace, uint8_t* const rgba) {
+ switch (out_colorspace) {
+ case MODE_RGB:
+ VP8LConvertBGRAToRGB(in_data, num_pixels, rgba);
+ break;
+ case MODE_RGBA:
+ VP8LConvertBGRAToRGBA(in_data, num_pixels, rgba);
+ break;
+ case MODE_rgbA:
+ VP8LConvertBGRAToRGBA(in_data, num_pixels, rgba);
+ WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0);
+ break;
+ case MODE_BGR:
+ VP8LConvertBGRAToBGR(in_data, num_pixels, rgba);
+ break;
+ case MODE_BGRA:
+ CopyOrSwap(in_data, num_pixels, rgba, 1);
+ break;
+ case MODE_bgrA:
+ CopyOrSwap(in_data, num_pixels, rgba, 1);
+ WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0);
+ break;
+ case MODE_ARGB:
+ CopyOrSwap(in_data, num_pixels, rgba, 0);
+ break;
+ case MODE_Argb:
+ CopyOrSwap(in_data, num_pixels, rgba, 0);
+ WebPApplyAlphaMultiply(rgba, 1, num_pixels, 1, 0);
+ break;
+ case MODE_RGBA_4444:
+ VP8LConvertBGRAToRGBA4444(in_data, num_pixels, rgba);
+ break;
+ case MODE_rgbA_4444:
+ VP8LConvertBGRAToRGBA4444(in_data, num_pixels, rgba);
+ WebPApplyAlphaMultiply4444(rgba, num_pixels, 1, 0);
+ break;
+ case MODE_RGB_565:
+ VP8LConvertBGRAToRGB565(in_data, num_pixels, rgba);
+ break;
+ default:
+ assert(0); // Code flow should not reach here.
+ }
+}
+
+//------------------------------------------------------------------------------
+
+VP8LProcessDecBlueAndRedFunc VP8LAddGreenToBlueAndRed;
+VP8LPredictorAddSubFunc VP8LPredictorsAdd[16];
+VP8LPredictorFunc VP8LPredictors[16];
+
+// exposed plain-C implementations
+VP8LPredictorAddSubFunc VP8LPredictorsAdd_C[16];
+VP8LPredictorFunc VP8LPredictors_C[16];
+
+VP8LTransformColorInverseFunc VP8LTransformColorInverse;
+
+VP8LConvertFunc VP8LConvertBGRAToRGB;
+VP8LConvertFunc VP8LConvertBGRAToRGBA;
+VP8LConvertFunc VP8LConvertBGRAToRGBA4444;
+VP8LConvertFunc VP8LConvertBGRAToRGB565;
+VP8LConvertFunc VP8LConvertBGRAToBGR;
+
+VP8LMapARGBFunc VP8LMapColor32b;
+VP8LMapAlphaFunc VP8LMapColor8b;
+
+extern void VP8LDspInitSSE2(void);
+extern void VP8LDspInitNEON(void);
+extern void VP8LDspInitMIPSdspR2(void);
+extern void VP8LDspInitMSA(void);
+
+static volatile VP8CPUInfo lossless_last_cpuinfo_used =
+ (VP8CPUInfo)&lossless_last_cpuinfo_used;
+
+#define COPY_PREDICTOR_ARRAY(IN, OUT) do { \
+ (OUT)[0] = IN##0; \
+ (OUT)[1] = IN##1; \
+ (OUT)[2] = IN##2; \
+ (OUT)[3] = IN##3; \
+ (OUT)[4] = IN##4; \
+ (OUT)[5] = IN##5; \
+ (OUT)[6] = IN##6; \
+ (OUT)[7] = IN##7; \
+ (OUT)[8] = IN##8; \
+ (OUT)[9] = IN##9; \
+ (OUT)[10] = IN##10; \
+ (OUT)[11] = IN##11; \
+ (OUT)[12] = IN##12; \
+ (OUT)[13] = IN##13; \
+ (OUT)[14] = IN##0; /* <- padding security sentinels*/ \
+ (OUT)[15] = IN##0; \
+} while (0);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInit(void) {
+ if (lossless_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors)
+ COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors_C)
+ COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd)
+ COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd_C)
+
+ VP8LAddGreenToBlueAndRed = VP8LAddGreenToBlueAndRed_C;
+
+ VP8LTransformColorInverse = VP8LTransformColorInverse_C;
+
+ VP8LConvertBGRAToRGB = VP8LConvertBGRAToRGB_C;
+ VP8LConvertBGRAToRGBA = VP8LConvertBGRAToRGBA_C;
+ VP8LConvertBGRAToRGBA4444 = VP8LConvertBGRAToRGBA4444_C;
+ VP8LConvertBGRAToRGB565 = VP8LConvertBGRAToRGB565_C;
+ VP8LConvertBGRAToBGR = VP8LConvertBGRAToBGR_C;
+
+ VP8LMapColor32b = MapARGB;
+ VP8LMapColor8b = MapAlpha;
+
+ // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ VP8LDspInitSSE2();
+ }
+#endif
+#if defined(WEBP_USE_NEON)
+ if (VP8GetCPUInfo(kNEON)) {
+ VP8LDspInitNEON();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ VP8LDspInitMIPSdspR2();
+ }
+#endif
+#if defined(WEBP_USE_MSA)
+ if (VP8GetCPUInfo(kMSA)) {
+ VP8LDspInitMSA();
+ }
+#endif
+ }
+ lossless_last_cpuinfo_used = VP8GetCPUInfo;
+}
+#undef COPY_PREDICTOR_ARRAY
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dsp/lossless.h b/media/libwebp/dsp/lossless.h
new file mode 100644
index 000000000..352a54e50
--- /dev/null
+++ b/media/libwebp/dsp/lossless.h
@@ -0,0 +1,229 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Image transforms and color space conversion methods for lossless decoder.
+//
+// Authors: Vikas Arora (vikaas.arora@gmail.com)
+// Jyrki Alakuijala (jyrki@google.com)
+
+#ifndef WEBP_DSP_LOSSLESS_H_
+#define WEBP_DSP_LOSSLESS_H_
+
+#include "../webp/types.h"
+#include "../webp/decode.h"
+
+#include "../enc/histogram_enc.h"
+#include "../utils/utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WEBP_EXPERIMENTAL_FEATURES
+#include "../enc/delta_palettization_enc.h"
+#endif // WEBP_EXPERIMENTAL_FEATURES
+
+//------------------------------------------------------------------------------
+// Decoding
+
+typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
+extern VP8LPredictorFunc VP8LPredictors[16];
+extern VP8LPredictorFunc VP8LPredictors_C[16];
+// These Add/Sub function expects upper[-1] and out[-1] to be readable.
+typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
+ const uint32_t* upper, int num_pixels,
+ uint32_t* out);
+extern VP8LPredictorAddSubFunc VP8LPredictorsAdd[16];
+extern VP8LPredictorAddSubFunc VP8LPredictorsAdd_C[16];
+
+typedef void (*VP8LProcessDecBlueAndRedFunc)(const uint32_t* src,
+ int num_pixels, uint32_t* dst);
+extern VP8LProcessDecBlueAndRedFunc VP8LAddGreenToBlueAndRed;
+
+typedef struct {
+ // Note: the members are uint8_t, so that any negative values are
+ // automatically converted to "mod 256" values.
+ uint8_t green_to_red_;
+ uint8_t green_to_blue_;
+ uint8_t red_to_blue_;
+} VP8LMultipliers;
+typedef void (*VP8LTransformColorInverseFunc)(const VP8LMultipliers* const m,
+ const uint32_t* src,
+ int num_pixels, uint32_t* dst);
+extern VP8LTransformColorInverseFunc VP8LTransformColorInverse;
+
+struct VP8LTransform; // Defined in dec/vp8li.h.
+
+// Performs inverse transform of data given transform information, start and end
+// rows. Transform will be applied to rows [row_start, row_end[.
+// The *in and *out pointers refer to source and destination data respectively
+// corresponding to the intermediate row (row_start).
+void VP8LInverseTransform(const struct VP8LTransform* const transform,
+ int row_start, int row_end,
+ const uint32_t* const in, uint32_t* const out);
+
+// Color space conversion.
+typedef void (*VP8LConvertFunc)(const uint32_t* src, int num_pixels,
+ uint8_t* dst);
+extern VP8LConvertFunc VP8LConvertBGRAToRGB;
+extern VP8LConvertFunc VP8LConvertBGRAToRGBA;
+extern VP8LConvertFunc VP8LConvertBGRAToRGBA4444;
+extern VP8LConvertFunc VP8LConvertBGRAToRGB565;
+extern VP8LConvertFunc VP8LConvertBGRAToBGR;
+
+// Converts from BGRA to other color spaces.
+void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
+ WEBP_CSP_MODE out_colorspace, uint8_t* const rgba);
+
+typedef void (*VP8LMapARGBFunc)(const uint32_t* src,
+ const uint32_t* const color_map,
+ uint32_t* dst, int y_start,
+ int y_end, int width);
+typedef void (*VP8LMapAlphaFunc)(const uint8_t* src,
+ const uint32_t* const color_map,
+ uint8_t* dst, int y_start,
+ int y_end, int width);
+
+extern VP8LMapARGBFunc VP8LMapColor32b;
+extern VP8LMapAlphaFunc VP8LMapColor8b;
+
+// Similar to the static method ColorIndexInverseTransform() that is part of
+// lossless.c, but used only for alpha decoding. It takes uint8_t (rather than
+// uint32_t) arguments for 'src' and 'dst'.
+void VP8LColorIndexInverseTransformAlpha(
+ const struct VP8LTransform* const transform, int y_start, int y_end,
+ const uint8_t* src, uint8_t* dst);
+
+// Expose some C-only fallback functions
+void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
+ const uint32_t* src, int num_pixels,
+ uint32_t* dst);
+
+void VP8LConvertBGRAToRGB_C(const uint32_t* src, int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToRGBA_C(const uint32_t* src, int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToRGBA4444_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToRGB565_C(const uint32_t* src,
+ int num_pixels, uint8_t* dst);
+void VP8LConvertBGRAToBGR_C(const uint32_t* src, int num_pixels, uint8_t* dst);
+void VP8LAddGreenToBlueAndRed_C(const uint32_t* src, int num_pixels,
+ uint32_t* dst);
+
+// Must be called before calling any of the above methods.
+void VP8LDspInit(void);
+
+//------------------------------------------------------------------------------
+// Encoding
+
+typedef void (*VP8LProcessEncBlueAndRedFunc)(uint32_t* dst, int num_pixels);
+extern VP8LProcessEncBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
+typedef void (*VP8LTransformColorFunc)(const VP8LMultipliers* const m,
+ uint32_t* const dst, int num_pixels);
+extern VP8LTransformColorFunc VP8LTransformColor;
+typedef void (*VP8LCollectColorBlueTransformsFunc)(
+ const uint32_t* argb, int stride,
+ int tile_width, int tile_height,
+ int green_to_blue, int red_to_blue, int histo[]);
+extern VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
+
+typedef void (*VP8LCollectColorRedTransformsFunc)(
+ const uint32_t* argb, int stride,
+ int tile_width, int tile_height,
+ int green_to_red, int histo[]);
+extern VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
+
+// Expose some C-only fallback functions
+void VP8LTransformColor_C(const VP8LMultipliers* const m,
+ uint32_t* data, int num_pixels);
+void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels);
+void VP8LCollectColorRedTransforms_C(const uint32_t* argb, int stride,
+ int tile_width, int tile_height,
+ int green_to_red, int histo[]);
+void VP8LCollectColorBlueTransforms_C(const uint32_t* argb, int stride,
+ int tile_width, int tile_height,
+ int green_to_blue, int red_to_blue,
+ int histo[]);
+
+extern VP8LPredictorAddSubFunc VP8LPredictorsSub[16];
+extern VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];
+
+// -----------------------------------------------------------------------------
+// Huffman-cost related functions.
+
+typedef double (*VP8LCostFunc)(const uint32_t* population, int length);
+typedef double (*VP8LCostCombinedFunc)(const uint32_t* X, const uint32_t* Y,
+ int length);
+typedef float (*VP8LCombinedShannonEntropyFunc)(const int X[256],
+ const int Y[256]);
+
+extern VP8LCostFunc VP8LExtraCost;
+extern VP8LCostCombinedFunc VP8LExtraCostCombined;
+extern VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;
+
+typedef struct { // small struct to hold counters
+ int counts[2]; // index: 0=zero steak, 1=non-zero streak
+ int streaks[2][2]; // [zero/non-zero][streak<3 / streak>=3]
+} VP8LStreaks;
+
+typedef struct { // small struct to hold bit entropy results
+ double entropy; // entropy
+ uint32_t sum; // sum of the population
+ int nonzeros; // number of non-zero elements in the population
+ uint32_t max_val; // maximum value in the population
+ uint32_t nonzero_code; // index of the last non-zero in the population
+} VP8LBitEntropy;
+
+void VP8LBitEntropyInit(VP8LBitEntropy* const entropy);
+
+// Get the combined symbol bit entropy and Huffman cost stats for the
+// distributions 'X' and 'Y'. Those results can then be refined according to
+// codec specific heuristics.
+typedef void (*VP8LGetCombinedEntropyUnrefinedFunc)(
+ const uint32_t X[], const uint32_t Y[], int length,
+ VP8LBitEntropy* const bit_entropy, VP8LStreaks* const stats);
+extern VP8LGetCombinedEntropyUnrefinedFunc VP8LGetCombinedEntropyUnrefined;
+
+// Get the entropy for the distribution 'X'.
+typedef void (*VP8LGetEntropyUnrefinedFunc)(const uint32_t X[], int length,
+ VP8LBitEntropy* const bit_entropy,
+ VP8LStreaks* const stats);
+extern VP8LGetEntropyUnrefinedFunc VP8LGetEntropyUnrefined;
+
+void VP8LBitsEntropyUnrefined(const uint32_t* const array, int n,
+ VP8LBitEntropy* const entropy);
+
+typedef void (*VP8LHistogramAddFunc)(const VP8LHistogram* const a,
+ const VP8LHistogram* const b,
+ VP8LHistogram* const out);
+extern VP8LHistogramAddFunc VP8LHistogramAdd;
+
+// -----------------------------------------------------------------------------
+// PrefixEncode()
+
+typedef int (*VP8LVectorMismatchFunc)(const uint32_t* const array1,
+ const uint32_t* const array2, int length);
+// Returns the first index where array1 and array2 are different.
+extern VP8LVectorMismatchFunc VP8LVectorMismatch;
+
+typedef void (*VP8LBundleColorMapFunc)(const uint8_t* const row, int width,
+ int xbits, uint32_t* dst);
+extern VP8LBundleColorMapFunc VP8LBundleColorMap;
+void VP8LBundleColorMap_C(const uint8_t* const row, int width, int xbits,
+ uint32_t* dst);
+
+// Must be called before calling any of the above methods.
+void VP8LEncDspInit(void);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WEBP_DSP_LOSSLESS_H_
diff --git a/media/libwebp/dsp/lossless_common.h b/media/libwebp/dsp/lossless_common.h
new file mode 100644
index 000000000..c40f71120
--- /dev/null
+++ b/media/libwebp/dsp/lossless_common.h
@@ -0,0 +1,210 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Image transforms and color space conversion methods for lossless decoder.
+//
+// Authors: Vikas Arora (vikaas.arora@gmail.com)
+// Jyrki Alakuijala (jyrki@google.com)
+// Vincent Rabaud (vrabaud@google.com)
+
+#ifndef WEBP_DSP_LOSSLESS_COMMON_H_
+#define WEBP_DSP_LOSSLESS_COMMON_H_
+
+#include "../webp/types.h"
+
+#include "../utils/utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Decoding
+
+// color mapping related functions.
+static WEBP_INLINE uint32_t VP8GetARGBIndex(uint32_t idx) {
+ return (idx >> 8) & 0xff;
+}
+
+static WEBP_INLINE uint8_t VP8GetAlphaIndex(uint8_t idx) {
+ return idx;
+}
+
+static WEBP_INLINE uint32_t VP8GetARGBValue(uint32_t val) {
+ return val;
+}
+
+static WEBP_INLINE uint8_t VP8GetAlphaValue(uint32_t val) {
+ return (val >> 8) & 0xff;
+}
+
+//------------------------------------------------------------------------------
+// Misc methods.
+
+// Computes sampled size of 'size' when sampling using 'sampling bits'.
+static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size,
+ uint32_t sampling_bits) {
+ return (size + (1 << sampling_bits) - 1) >> sampling_bits;
+}
+
+// Converts near lossless quality into max number of bits shaved off.
+static WEBP_INLINE int VP8LNearLosslessBits(int near_lossless_quality) {
+ // 100 -> 0
+ // 80..99 -> 1
+ // 60..79 -> 2
+ // 40..59 -> 3
+ // 20..39 -> 4
+ // 0..19 -> 5
+ return 5 - near_lossless_quality / 20;
+}
+
+// -----------------------------------------------------------------------------
+// Faster logarithm for integers. Small values use a look-up table.
+
+// The threshold till approximate version of log_2 can be used.
+// Practically, we can get rid of the call to log() as the two values match to
+// very high degree (the ratio of these two is 0.99999x).
+// Keeping a high threshold for now.
+#define APPROX_LOG_WITH_CORRECTION_MAX 65536
+#define APPROX_LOG_MAX 4096
+#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
+#define LOG_LOOKUP_IDX_MAX 256
+extern const float kLog2Table[LOG_LOOKUP_IDX_MAX];
+extern const float kSLog2Table[LOG_LOOKUP_IDX_MAX];
+typedef float (*VP8LFastLog2SlowFunc)(uint32_t v);
+
+extern VP8LFastLog2SlowFunc VP8LFastLog2Slow;
+extern VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
+
+static WEBP_INLINE float VP8LFastLog2(uint32_t v) {
+ return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v);
+}
+// Fast calculation of v * log2(v) for integer input.
+static WEBP_INLINE float VP8LFastSLog2(uint32_t v) {
+ return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v);
+}
+
+// -----------------------------------------------------------------------------
+// PrefixEncode()
+
+static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) {
+ const int log_floor = BitsLog2Floor(n);
+ if (n == (n & ~(n - 1))) { // zero or a power of two.
+ return log_floor;
+ }
+ return log_floor + 1;
+}
+
+// Splitting of distance and length codes into prefixes and
+// extra bits. The prefixes are encoded with an entropy code
+// while the extra bits are stored just as normal bits.
+static WEBP_INLINE void VP8LPrefixEncodeBitsNoLUT(int distance, int* const code,
+ int* const extra_bits) {
+ const int highest_bit = BitsLog2Floor(--distance);
+ const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
+ *extra_bits = highest_bit - 1;
+ *code = 2 * highest_bit + second_highest_bit;
+}
+
+static WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code,
+ int* const extra_bits,
+ int* const extra_bits_value) {
+ const int highest_bit = BitsLog2Floor(--distance);
+ const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
+ *extra_bits = highest_bit - 1;
+ *extra_bits_value = distance & ((1 << *extra_bits) - 1);
+ *code = 2 * highest_bit + second_highest_bit;
+}
+
+#define PREFIX_LOOKUP_IDX_MAX 512
+typedef struct {
+ int8_t code_;
+ int8_t extra_bits_;
+} VP8LPrefixCode;
+
+// These tables are derived using VP8LPrefixEncodeNoLUT.
+extern const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX];
+extern const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX];
+static WEBP_INLINE void VP8LPrefixEncodeBits(int distance, int* const code,
+ int* const extra_bits) {
+ if (distance < PREFIX_LOOKUP_IDX_MAX) {
+ const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance];
+ *code = prefix_code.code_;
+ *extra_bits = prefix_code.extra_bits_;
+ } else {
+ VP8LPrefixEncodeBitsNoLUT(distance, code, extra_bits);
+ }
+}
+
+static WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code,
+ int* const extra_bits,
+ int* const extra_bits_value) {
+ if (distance < PREFIX_LOOKUP_IDX_MAX) {
+ const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance];
+ *code = prefix_code.code_;
+ *extra_bits = prefix_code.extra_bits_;
+ *extra_bits_value = kPrefixEncodeExtraBitsValue[distance];
+ } else {
+ VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value);
+ }
+}
+
+// Sum of each component, mod 256.
+static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
+uint32_t VP8LAddPixels(uint32_t a, uint32_t b) {
+ const uint32_t alpha_and_green = (a & 0xff00ff00u) + (b & 0xff00ff00u);
+ const uint32_t red_and_blue = (a & 0x00ff00ffu) + (b & 0x00ff00ffu);
+ return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
+}
+
+// Difference of each component, mod 256.
+static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
+uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {
+ const uint32_t alpha_and_green =
+ 0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u);
+ const uint32_t red_and_blue =
+ 0xff00ff00u + (a & 0x00ff00ffu) - (b & 0x00ff00ffu);
+ return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
+}
+
+//------------------------------------------------------------------------------
+// Transform-related functions use din both encoding and decoding.
+
+// Macros used to create a batch predictor that iteratively uses a
+// one-pixel predictor.
+
+// The predictor is added to the output pixel (which
+// is therefore considered as a residual) to get the final prediction.
+#define GENERATE_PREDICTOR_ADD(PREDICTOR, PREDICTOR_ADD) \
+static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
+ int num_pixels, uint32_t* out) { \
+ int x; \
+ for (x = 0; x < num_pixels; ++x) { \
+ const uint32_t pred = (PREDICTOR)(out[x - 1], upper + x); \
+ out[x] = VP8LAddPixels(in[x], pred); \
+ } \
+}
+
+// It subtracts the prediction from the input pixel and stores the residual
+// in the output pixel.
+#define GENERATE_PREDICTOR_SUB(PREDICTOR, PREDICTOR_SUB) \
+static void PREDICTOR_SUB(const uint32_t* in, const uint32_t* upper, \
+ int num_pixels, uint32_t* out) { \
+ int x; \
+ for (x = 0; x < num_pixels; ++x) { \
+ const uint32_t pred = (PREDICTOR)(in[x - 1], upper + x); \
+ out[x] = VP8LSubPixels(in[x], pred); \
+ } \
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WEBP_DSP_LOSSLESS_COMMON_H_
diff --git a/media/libwebp/dsp/lossless_neon.c b/media/libwebp/dsp/lossless_neon.c
new file mode 100644
index 000000000..1145d5fad
--- /dev/null
+++ b/media/libwebp/dsp/lossless_neon.c
@@ -0,0 +1,642 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// NEON variant of methods for lossless decoder
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include <arm_neon.h>
+
+#include "./lossless.h"
+#include "./neon.h"
+
+//------------------------------------------------------------------------------
+// Colorspace conversion functions
+
+#if !defined(WORK_AROUND_GCC)
+// gcc 4.6.0 had some trouble (NDK-r9) with this code. We only use it for
+// gcc-4.8.x at least.
+static void ConvertBGRAToRGBA(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~15);
+ for (; src < end; src += 16) {
+ uint8x16x4_t pixel = vld4q_u8((uint8_t*)src);
+ // swap B and R. (VSWP d0,d2 has no intrinsics equivalent!)
+ const uint8x16_t tmp = pixel.val[0];
+ pixel.val[0] = pixel.val[2];
+ pixel.val[2] = tmp;
+ vst4q_u8(dst, pixel);
+ dst += 64;
+ }
+ VP8LConvertBGRAToRGBA_C(src, num_pixels & 15, dst); // left-overs
+}
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~15);
+ for (; src < end; src += 16) {
+ const uint8x16x4_t pixel = vld4q_u8((uint8_t*)src);
+ const uint8x16x3_t tmp = { { pixel.val[0], pixel.val[1], pixel.val[2] } };
+ vst3q_u8(dst, tmp);
+ dst += 48;
+ }
+ VP8LConvertBGRAToBGR_C(src, num_pixels & 15, dst); // left-overs
+}
+
+static void ConvertBGRAToRGB(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~15);
+ for (; src < end; src += 16) {
+ const uint8x16x4_t pixel = vld4q_u8((uint8_t*)src);
+ const uint8x16x3_t tmp = { { pixel.val[2], pixel.val[1], pixel.val[0] } };
+ vst3q_u8(dst, tmp);
+ dst += 48;
+ }
+ VP8LConvertBGRAToRGB_C(src, num_pixels & 15, dst); // left-overs
+}
+
+#else // WORK_AROUND_GCC
+
+// gcc-4.6.0 fallback
+
+static const uint8_t kRGBAShuffle[8] = { 2, 1, 0, 3, 6, 5, 4, 7 };
+
+static void ConvertBGRAToRGBA(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~1);
+ const uint8x8_t shuffle = vld1_u8(kRGBAShuffle);
+ for (; src < end; src += 2) {
+ const uint8x8_t pixels = vld1_u8((uint8_t*)src);
+ vst1_u8(dst, vtbl1_u8(pixels, shuffle));
+ dst += 8;
+ }
+ VP8LConvertBGRAToRGBA_C(src, num_pixels & 1, dst); // left-overs
+}
+
+static const uint8_t kBGRShuffle[3][8] = {
+ { 0, 1, 2, 4, 5, 6, 8, 9 },
+ { 10, 12, 13, 14, 16, 17, 18, 20 },
+ { 21, 22, 24, 25, 26, 28, 29, 30 }
+};
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~7);
+ const uint8x8_t shuffle0 = vld1_u8(kBGRShuffle[0]);
+ const uint8x8_t shuffle1 = vld1_u8(kBGRShuffle[1]);
+ const uint8x8_t shuffle2 = vld1_u8(kBGRShuffle[2]);
+ for (; src < end; src += 8) {
+ uint8x8x4_t pixels;
+ INIT_VECTOR4(pixels,
+ vld1_u8((const uint8_t*)(src + 0)),
+ vld1_u8((const uint8_t*)(src + 2)),
+ vld1_u8((const uint8_t*)(src + 4)),
+ vld1_u8((const uint8_t*)(src + 6)));
+ vst1_u8(dst + 0, vtbl4_u8(pixels, shuffle0));
+ vst1_u8(dst + 8, vtbl4_u8(pixels, shuffle1));
+ vst1_u8(dst + 16, vtbl4_u8(pixels, shuffle2));
+ dst += 8 * 3;
+ }
+ VP8LConvertBGRAToBGR_C(src, num_pixels & 7, dst); // left-overs
+}
+
+static const uint8_t kRGBShuffle[3][8] = {
+ { 2, 1, 0, 6, 5, 4, 10, 9 },
+ { 8, 14, 13, 12, 18, 17, 16, 22 },
+ { 21, 20, 26, 25, 24, 30, 29, 28 }
+};
+
+static void ConvertBGRAToRGB(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~7);
+ const uint8x8_t shuffle0 = vld1_u8(kRGBShuffle[0]);
+ const uint8x8_t shuffle1 = vld1_u8(kRGBShuffle[1]);
+ const uint8x8_t shuffle2 = vld1_u8(kRGBShuffle[2]);
+ for (; src < end; src += 8) {
+ uint8x8x4_t pixels;
+ INIT_VECTOR4(pixels,
+ vld1_u8((const uint8_t*)(src + 0)),
+ vld1_u8((const uint8_t*)(src + 2)),
+ vld1_u8((const uint8_t*)(src + 4)),
+ vld1_u8((const uint8_t*)(src + 6)));
+ vst1_u8(dst + 0, vtbl4_u8(pixels, shuffle0));
+ vst1_u8(dst + 8, vtbl4_u8(pixels, shuffle1));
+ vst1_u8(dst + 16, vtbl4_u8(pixels, shuffle2));
+ dst += 8 * 3;
+ }
+ VP8LConvertBGRAToRGB_C(src, num_pixels & 7, dst); // left-overs
+}
+
+#endif // !WORK_AROUND_GCC
+
+
+//------------------------------------------------------------------------------
+// Predictor Transform
+
+#define LOAD_U32_AS_U8(IN) vreinterpret_u8_u32(vdup_n_u32((IN)))
+#define LOAD_U32P_AS_U8(IN) vreinterpret_u8_u32(vld1_u32((IN)))
+#define LOADQ_U32_AS_U8(IN) vreinterpretq_u8_u32(vdupq_n_u32((IN)))
+#define LOADQ_U32P_AS_U8(IN) vreinterpretq_u8_u32(vld1q_u32((IN)))
+#define GET_U8_AS_U32(IN) vget_lane_u32(vreinterpret_u32_u8((IN)), 0);
+#define GETQ_U8_AS_U32(IN) vgetq_lane_u32(vreinterpretq_u32_u8((IN)), 0);
+#define STOREQ_U8_AS_U32P(OUT, IN) vst1q_u32((OUT), vreinterpretq_u32_u8((IN)));
+#define ROTATE32_LEFT(L) vextq_u8((L), (L), 12) // D|C|B|A -> C|B|A|D
+
+static WEBP_INLINE uint8x8_t Average2_u8_NEON(uint32_t a0, uint32_t a1) {
+ const uint8x8_t A0 = LOAD_U32_AS_U8(a0);
+ const uint8x8_t A1 = LOAD_U32_AS_U8(a1);
+ return vhadd_u8(A0, A1);
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf_NEON(uint32_t c0,
+ uint32_t c1,
+ uint32_t c2) {
+ const uint8x8_t avg = Average2_u8_NEON(c0, c1);
+ // Remove one to c2 when bigger than avg.
+ const uint8x8_t C2 = LOAD_U32_AS_U8(c2);
+ const uint8x8_t cmp = vcgt_u8(C2, avg);
+ const uint8x8_t C2_1 = vadd_u8(C2, cmp);
+ // Compute half of the difference between avg and c2.
+ const int8x8_t diff_avg = vreinterpret_s8_u8(vhsub_u8(avg, C2_1));
+ // Compute the sum with avg and saturate.
+ const int16x8_t avg_16 = vreinterpretq_s16_u16(vmovl_u8(avg));
+ const uint8x8_t res = vqmovun_s16(vaddw_s8(avg_16, diff_avg));
+ const uint32_t output = GET_U8_AS_U32(res);
+ return output;
+}
+
+static WEBP_INLINE uint32_t Average2_NEON(uint32_t a0, uint32_t a1) {
+ const uint8x8_t avg_u8x8 = Average2_u8_NEON(a0, a1);
+ const uint32_t avg = GET_U8_AS_U32(avg_u8x8);
+ return avg;
+}
+
+static WEBP_INLINE uint32_t Average3_NEON(uint32_t a0, uint32_t a1,
+ uint32_t a2) {
+ const uint8x8_t avg0 = Average2_u8_NEON(a0, a2);
+ const uint8x8_t A1 = LOAD_U32_AS_U8(a1);
+ const uint32_t avg = GET_U8_AS_U32(vhadd_u8(avg0, A1));
+ return avg;
+}
+
+static uint32_t Predictor5_NEON(uint32_t left, const uint32_t* const top) {
+ return Average3_NEON(left, top[0], top[1]);
+}
+static uint32_t Predictor6_NEON(uint32_t left, const uint32_t* const top) {
+ return Average2_NEON(left, top[-1]);
+}
+static uint32_t Predictor7_NEON(uint32_t left, const uint32_t* const top) {
+ return Average2_NEON(left, top[0]);
+}
+static uint32_t Predictor13_NEON(uint32_t left, const uint32_t* const top) {
+ return ClampedAddSubtractHalf_NEON(left, top[0], top[-1]);
+}
+
+// Batch versions of those functions.
+
+// Predictor0: ARGB_BLACK.
+static void PredictorAdd0_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ const uint8x16_t black = vreinterpretq_u8_u32(vdupq_n_u32(ARGB_BLACK));
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t res = vaddq_u8(src, black);
+ STOREQ_U8_AS_U32P(&out[i], res);
+ }
+ VP8LPredictorsAdd_C[0](in + i, upper + i, num_pixels - i, out + i);
+}
+
+// Predictor1: left.
+static void PredictorAdd1_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ const uint8x16_t zero = LOADQ_U32_AS_U8(0);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ // a | b | c | d
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ // 0 | a | b | c
+ const uint8x16_t shift0 = vextq_u8(zero, src, 12);
+ // a | a + b | b + c | c + d
+ const uint8x16_t sum0 = vaddq_u8(src, shift0);
+ // 0 | 0 | a | a + b
+ const uint8x16_t shift1 = vextq_u8(zero, sum0, 8);
+ // a | a + b | a + b + c | a + b + c + d
+ const uint8x16_t sum1 = vaddq_u8(sum0, shift1);
+ const uint8x16_t prev = LOADQ_U32_AS_U8(out[i - 1]);
+ const uint8x16_t res = vaddq_u8(sum1, prev);
+ STOREQ_U8_AS_U32P(&out[i], res);
+ }
+ VP8LPredictorsAdd_C[1](in + i, upper + i, num_pixels - i, out + i);
+}
+
+// Macro that adds 32-bit integers from IN using mod 256 arithmetic
+// per 8 bit channel.
+#define GENERATE_PREDICTOR_1(X, IN) \
+static void PredictorAdd##X##_NEON(const uint32_t* in, \
+ const uint32_t* upper, int num_pixels, \
+ uint32_t* out) { \
+ int i; \
+ for (i = 0; i + 4 <= num_pixels; i += 4) { \
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]); \
+ const uint8x16_t other = LOADQ_U32P_AS_U8(&(IN)); \
+ const uint8x16_t res = vaddq_u8(src, other); \
+ STOREQ_U8_AS_U32P(&out[i], res); \
+ } \
+ VP8LPredictorsAdd_C[(X)](in + i, upper + i, num_pixels - i, out + i); \
+}
+// Predictor2: Top.
+GENERATE_PREDICTOR_1(2, upper[i])
+// Predictor3: Top-right.
+GENERATE_PREDICTOR_1(3, upper[i + 1])
+// Predictor4: Top-left.
+GENERATE_PREDICTOR_1(4, upper[i - 1])
+#undef GENERATE_PREDICTOR_1
+
+// Predictor5: average(average(left, TR), T)
+#define DO_PRED5(LANE) do { \
+ const uint8x16_t avgLTR = vhaddq_u8(L, TR); \
+ const uint8x16_t avg = vhaddq_u8(avgLTR, T); \
+ const uint8x16_t res = vaddq_u8(avg, src); \
+ vst1q_lane_u32(&out[i + (LANE)], vreinterpretq_u32_u8(res), (LANE)); \
+ L = ROTATE32_LEFT(res); \
+} while (0)
+
+static void PredictorAdd5_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint8x16_t L = LOADQ_U32_AS_U8(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t T = LOADQ_U32P_AS_U8(&upper[i + 0]);
+ const uint8x16_t TR = LOADQ_U32P_AS_U8(&upper[i + 1]);
+ DO_PRED5(0);
+ DO_PRED5(1);
+ DO_PRED5(2);
+ DO_PRED5(3);
+ }
+ VP8LPredictorsAdd_C[5](in + i, upper + i, num_pixels - i, out + i);
+}
+#undef DO_PRED5
+
+#define DO_PRED67(LANE) do { \
+ const uint8x16_t avg = vhaddq_u8(L, top); \
+ const uint8x16_t res = vaddq_u8(avg, src); \
+ vst1q_lane_u32(&out[i + (LANE)], vreinterpretq_u32_u8(res), (LANE)); \
+ L = ROTATE32_LEFT(res); \
+} while (0)
+
+// Predictor6: average(left, TL)
+static void PredictorAdd6_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint8x16_t L = LOADQ_U32_AS_U8(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t top = LOADQ_U32P_AS_U8(&upper[i - 1]);
+ DO_PRED67(0);
+ DO_PRED67(1);
+ DO_PRED67(2);
+ DO_PRED67(3);
+ }
+ VP8LPredictorsAdd_C[6](in + i, upper + i, num_pixels - i, out + i);
+}
+
+// Predictor7: average(left, T)
+static void PredictorAdd7_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint8x16_t L = LOADQ_U32_AS_U8(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t top = LOADQ_U32P_AS_U8(&upper[i]);
+ DO_PRED67(0);
+ DO_PRED67(1);
+ DO_PRED67(2);
+ DO_PRED67(3);
+ }
+ VP8LPredictorsAdd_C[7](in + i, upper + i, num_pixels - i, out + i);
+}
+#undef DO_PRED67
+
+#define GENERATE_PREDICTOR_2(X, IN) \
+static void PredictorAdd##X##_NEON(const uint32_t* in, \
+ const uint32_t* upper, int num_pixels, \
+ uint32_t* out) { \
+ int i; \
+ for (i = 0; i + 4 <= num_pixels; i += 4) { \
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]); \
+ const uint8x16_t Tother = LOADQ_U32P_AS_U8(&(IN)); \
+ const uint8x16_t T = LOADQ_U32P_AS_U8(&upper[i]); \
+ const uint8x16_t avg = vhaddq_u8(T, Tother); \
+ const uint8x16_t res = vaddq_u8(avg, src); \
+ STOREQ_U8_AS_U32P(&out[i], res); \
+ } \
+ VP8LPredictorsAdd_C[(X)](in + i, upper + i, num_pixels - i, out + i); \
+}
+// Predictor8: average TL T.
+GENERATE_PREDICTOR_2(8, upper[i - 1])
+// Predictor9: average T TR.
+GENERATE_PREDICTOR_2(9, upper[i + 1])
+#undef GENERATE_PREDICTOR_2
+
+// Predictor10: average of (average of (L,TL), average of (T, TR)).
+#define DO_PRED10(LANE) do { \
+ const uint8x16_t avgLTL = vhaddq_u8(L, TL); \
+ const uint8x16_t avg = vhaddq_u8(avgTTR, avgLTL); \
+ const uint8x16_t res = vaddq_u8(avg, src); \
+ vst1q_lane_u32(&out[i + (LANE)], vreinterpretq_u32_u8(res), (LANE)); \
+ L = ROTATE32_LEFT(res); \
+} while (0)
+
+static void PredictorAdd10_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint8x16_t L = LOADQ_U32_AS_U8(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t TL = LOADQ_U32P_AS_U8(&upper[i - 1]);
+ const uint8x16_t T = LOADQ_U32P_AS_U8(&upper[i]);
+ const uint8x16_t TR = LOADQ_U32P_AS_U8(&upper[i + 1]);
+ const uint8x16_t avgTTR = vhaddq_u8(T, TR);
+ DO_PRED10(0);
+ DO_PRED10(1);
+ DO_PRED10(2);
+ DO_PRED10(3);
+ }
+ VP8LPredictorsAdd_C[10](in + i, upper + i, num_pixels - i, out + i);
+}
+#undef DO_PRED10
+
+// Predictor11: select.
+#define DO_PRED11(LANE) do { \
+ const uint8x16_t sumLin = vaddq_u8(L, src); /* in + L */ \
+ const uint8x16_t pLTL = vabdq_u8(L, TL); /* |L - TL| */ \
+ const uint16x8_t sum_LTL = vpaddlq_u8(pLTL); \
+ const uint32x4_t pa = vpaddlq_u16(sum_LTL); \
+ const uint32x4_t mask = vcleq_u32(pa, pb); \
+ const uint8x16_t res = vbslq_u8(vreinterpretq_u8_u32(mask), sumTin, sumLin); \
+ vst1q_lane_u32(&out[i + (LANE)], vreinterpretq_u32_u8(res), (LANE)); \
+ L = ROTATE32_LEFT(res); \
+} while (0)
+
+static void PredictorAdd11_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint8x16_t L = LOADQ_U32_AS_U8(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t T = LOADQ_U32P_AS_U8(&upper[i]);
+ const uint8x16_t TL = LOADQ_U32P_AS_U8(&upper[i - 1]);
+ const uint8x16_t pTTL = vabdq_u8(T, TL); // |T - TL|
+ const uint16x8_t sum_TTL = vpaddlq_u8(pTTL);
+ const uint32x4_t pb = vpaddlq_u16(sum_TTL);
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t sumTin = vaddq_u8(T, src); // in + T
+ DO_PRED11(0);
+ DO_PRED11(1);
+ DO_PRED11(2);
+ DO_PRED11(3);
+ }
+ VP8LPredictorsAdd_C[11](in + i, upper + i, num_pixels - i, out + i);
+}
+#undef DO_PRED11
+
+// Predictor12: ClampedAddSubtractFull.
+#define DO_PRED12(DIFF, LANE) do { \
+ const uint8x8_t pred = \
+ vqmovun_s16(vaddq_s16(vreinterpretq_s16_u16(L), (DIFF))); \
+ const uint8x8_t res = \
+ vadd_u8(pred, (LANE <= 1) ? vget_low_u8(src) : vget_high_u8(src)); \
+ const uint16x8_t res16 = vmovl_u8(res); \
+ vst1_lane_u32(&out[i + (LANE)], vreinterpret_u32_u8(res), (LANE) & 1); \
+ /* rotate in the left predictor for next iteration */ \
+ L = vextq_u16(res16, res16, 4); \
+} while (0)
+
+static void PredictorAdd12_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint16x8_t L = vmovl_u8(LOAD_U32_AS_U8(out[-1]));
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ // load four pixels of source
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ // precompute the difference T - TL once for all, stored as s16
+ const uint8x16_t TL = LOADQ_U32P_AS_U8(&upper[i - 1]);
+ const uint8x16_t T = LOADQ_U32P_AS_U8(&upper[i]);
+ const int16x8_t diff_lo =
+ vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(T), vget_low_u8(TL)));
+ const int16x8_t diff_hi =
+ vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(T), vget_high_u8(TL)));
+ // loop over the four reconstructed pixels
+ DO_PRED12(diff_lo, 0);
+ DO_PRED12(diff_lo, 1);
+ DO_PRED12(diff_hi, 2);
+ DO_PRED12(diff_hi, 3);
+ }
+ VP8LPredictorsAdd_C[12](in + i, upper + i, num_pixels - i, out + i);
+}
+#undef DO_PRED12
+
+// Predictor13: ClampedAddSubtractHalf
+#define DO_PRED13(LANE, LOW_OR_HI) do { \
+ const uint8x16_t avg = vhaddq_u8(L, T); \
+ const uint8x16_t cmp = vcgtq_u8(TL, avg); \
+ const uint8x16_t TL_1 = vaddq_u8(TL, cmp); \
+ /* Compute half of the difference between avg and TL'. */ \
+ const int8x8_t diff_avg = \
+ vreinterpret_s8_u8(LOW_OR_HI(vhsubq_u8(avg, TL_1))); \
+ /* Compute the sum with avg and saturate. */ \
+ const int16x8_t avg_16 = vreinterpretq_s16_u16(vmovl_u8(LOW_OR_HI(avg))); \
+ const uint8x8_t delta = vqmovun_s16(vaddw_s8(avg_16, diff_avg)); \
+ const uint8x8_t res = vadd_u8(LOW_OR_HI(src), delta); \
+ const uint8x16_t res2 = vcombine_u8(res, res); \
+ vst1_lane_u32(&out[i + (LANE)], vreinterpret_u32_u8(res), (LANE) & 1); \
+ L = ROTATE32_LEFT(res2); \
+} while (0)
+
+static void PredictorAdd13_NEON(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ uint8x16_t L = LOADQ_U32_AS_U8(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t src = LOADQ_U32P_AS_U8(&in[i]);
+ const uint8x16_t T = LOADQ_U32P_AS_U8(&upper[i]);
+ const uint8x16_t TL = LOADQ_U32P_AS_U8(&upper[i - 1]);
+ DO_PRED13(0, vget_low_u8);
+ DO_PRED13(1, vget_low_u8);
+ DO_PRED13(2, vget_high_u8);
+ DO_PRED13(3, vget_high_u8);
+ }
+ VP8LPredictorsAdd_C[13](in + i, upper + i, num_pixels - i, out + i);
+}
+#undef DO_PRED13
+
+#undef LOAD_U32_AS_U8
+#undef LOAD_U32P_AS_U8
+#undef LOADQ_U32_AS_U8
+#undef LOADQ_U32P_AS_U8
+#undef GET_U8_AS_U32
+#undef GETQ_U8_AS_U32
+#undef STOREQ_U8_AS_U32P
+#undef ROTATE32_LEFT
+
+//------------------------------------------------------------------------------
+// Subtract-Green Transform
+
+// vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
+// non-standard versions there.
+#if defined(__APPLE__) && defined(__aarch64__) && \
+ defined(__apple_build_version__) && (__apple_build_version__< 6020037)
+#define USE_VTBLQ
+#endif
+
+#ifdef USE_VTBLQ
+// 255 = byte will be zeroed
+static const uint8_t kGreenShuffle[16] = {
+ 1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255
+};
+
+static WEBP_INLINE uint8x16_t DoGreenShuffle(const uint8x16_t argb,
+ const uint8x16_t shuffle) {
+ return vcombine_u8(vtbl1q_u8(argb, vget_low_u8(shuffle)),
+ vtbl1q_u8(argb, vget_high_u8(shuffle)));
+}
+#else // !USE_VTBLQ
+// 255 = byte will be zeroed
+static const uint8_t kGreenShuffle[8] = { 1, 255, 1, 255, 5, 255, 5, 255 };
+
+static WEBP_INLINE uint8x16_t DoGreenShuffle(const uint8x16_t argb,
+ const uint8x8_t shuffle) {
+ return vcombine_u8(vtbl1_u8(vget_low_u8(argb), shuffle),
+ vtbl1_u8(vget_high_u8(argb), shuffle));
+}
+#endif // USE_VTBLQ
+
+static void AddGreenToBlueAndRed(const uint32_t* src, int num_pixels,
+ uint32_t* dst) {
+ const uint32_t* const end = src + (num_pixels & ~3);
+#ifdef USE_VTBLQ
+ const uint8x16_t shuffle = vld1q_u8(kGreenShuffle);
+#else
+ const uint8x8_t shuffle = vld1_u8(kGreenShuffle);
+#endif
+ for (; src < end; src += 4, dst += 4) {
+ const uint8x16_t argb = vld1q_u8((const uint8_t*)src);
+ const uint8x16_t greens = DoGreenShuffle(argb, shuffle);
+ vst1q_u8((uint8_t*)dst, vaddq_u8(argb, greens));
+ }
+ // fallthrough and finish off with plain-C
+ VP8LAddGreenToBlueAndRed_C(src, num_pixels & 3, dst);
+}
+
+//------------------------------------------------------------------------------
+// Color Transform
+
+static void TransformColorInverse(const VP8LMultipliers* const m,
+ const uint32_t* const src, int num_pixels,
+ uint32_t* dst) {
+// sign-extended multiplying constants, pre-shifted by 6.
+#define CST(X) (((int16_t)(m->X << 8)) >> 6)
+ const int16_t rb[8] = {
+ CST(green_to_blue_), CST(green_to_red_),
+ CST(green_to_blue_), CST(green_to_red_),
+ CST(green_to_blue_), CST(green_to_red_),
+ CST(green_to_blue_), CST(green_to_red_)
+ };
+ const int16x8_t mults_rb = vld1q_s16(rb);
+ const int16_t b2[8] = {
+ 0, CST(red_to_blue_), 0, CST(red_to_blue_),
+ 0, CST(red_to_blue_), 0, CST(red_to_blue_),
+ };
+ const int16x8_t mults_b2 = vld1q_s16(b2);
+#undef CST
+#ifdef USE_VTBLQ
+ static const uint8_t kg0g0[16] = {
+ 255, 1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13
+ };
+ const uint8x16_t shuffle = vld1q_u8(kg0g0);
+#else
+ static const uint8_t k0g0g[8] = { 255, 1, 255, 1, 255, 5, 255, 5 };
+ const uint8x8_t shuffle = vld1_u8(k0g0g);
+#endif
+ const uint32x4_t mask_ag = vdupq_n_u32(0xff00ff00u);
+ int i;
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const uint8x16_t in = vld1q_u8((const uint8_t*)(src + i));
+ const uint32x4_t a0g0 = vandq_u32(vreinterpretq_u32_u8(in), mask_ag);
+ // 0 g 0 g
+ const uint8x16_t greens = DoGreenShuffle(in, shuffle);
+ // x dr x db1
+ const int16x8_t A = vqdmulhq_s16(vreinterpretq_s16_u8(greens), mults_rb);
+ // x r' x b'
+ const int8x16_t B = vaddq_s8(vreinterpretq_s8_u8(in),
+ vreinterpretq_s8_s16(A));
+ // r' 0 b' 0
+ const int16x8_t C = vshlq_n_s16(vreinterpretq_s16_s8(B), 8);
+ // x db2 0 0
+ const int16x8_t D = vqdmulhq_s16(C, mults_b2);
+ // 0 x db2 0
+ const uint32x4_t E = vshrq_n_u32(vreinterpretq_u32_s16(D), 8);
+ // r' x b'' 0
+ const int8x16_t F = vaddq_s8(vreinterpretq_s8_u32(E),
+ vreinterpretq_s8_s16(C));
+ // 0 r' 0 b''
+ const uint16x8_t G = vshrq_n_u16(vreinterpretq_u16_s8(F), 8);
+ const uint32x4_t out = vorrq_u32(vreinterpretq_u32_u16(G), a0g0);
+ vst1q_u32(dst + i, out);
+ }
+ // Fall-back to C-version for left-overs.
+ VP8LTransformColorInverse_C(m, src + i, num_pixels - i, dst + i);
+}
+
+#undef USE_VTBLQ
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8LDspInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitNEON(void) {
+ VP8LPredictors[5] = Predictor5_NEON;
+ VP8LPredictors[6] = Predictor6_NEON;
+ VP8LPredictors[7] = Predictor7_NEON;
+ VP8LPredictors[13] = Predictor13_NEON;
+
+ VP8LPredictorsAdd[0] = PredictorAdd0_NEON;
+ VP8LPredictorsAdd[1] = PredictorAdd1_NEON;
+ VP8LPredictorsAdd[2] = PredictorAdd2_NEON;
+ VP8LPredictorsAdd[3] = PredictorAdd3_NEON;
+ VP8LPredictorsAdd[4] = PredictorAdd4_NEON;
+ VP8LPredictorsAdd[5] = PredictorAdd5_NEON;
+ VP8LPredictorsAdd[6] = PredictorAdd6_NEON;
+ VP8LPredictorsAdd[7] = PredictorAdd7_NEON;
+ VP8LPredictorsAdd[8] = PredictorAdd8_NEON;
+ VP8LPredictorsAdd[9] = PredictorAdd9_NEON;
+ VP8LPredictorsAdd[10] = PredictorAdd10_NEON;
+ VP8LPredictorsAdd[11] = PredictorAdd11_NEON;
+ VP8LPredictorsAdd[12] = PredictorAdd12_NEON;
+ VP8LPredictorsAdd[13] = PredictorAdd13_NEON;
+
+ VP8LConvertBGRAToRGBA = ConvertBGRAToRGBA;
+ VP8LConvertBGRAToBGR = ConvertBGRAToBGR;
+ VP8LConvertBGRAToRGB = ConvertBGRAToRGB;
+
+ VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed;
+ VP8LTransformColorInverse = TransformColorInverse;
+}
+
+#else // !WEBP_USE_NEON
+
+WEBP_DSP_INIT_STUB(VP8LDspInitNEON)
+
+#endif // WEBP_USE_NEON
diff --git a/media/libwebp/dsp/lossless_sse2.c b/media/libwebp/dsp/lossless_sse2.c
new file mode 100644
index 000000000..15aae9386
--- /dev/null
+++ b/media/libwebp/dsp/lossless_sse2.c
@@ -0,0 +1,677 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 variant of methods for lossless decoder
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include "./common_sse2.h"
+#include "./lossless.h"
+#include "./lossless_common.h"
+#include <assert.h>
+#include <emmintrin.h>
+
+//------------------------------------------------------------------------------
+// Predictor Transform
+
+static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
+ uint32_t c2) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
+ const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
+ const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+ const __m128i V1 = _mm_add_epi16(C0, C1);
+ const __m128i V2 = _mm_sub_epi16(V1, C2);
+ const __m128i b = _mm_packus_epi16(V2, V2);
+ const uint32_t output = _mm_cvtsi128_si32(b);
+ return output;
+}
+
+static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
+ uint32_t c2) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
+ const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
+ const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+ const __m128i avg = _mm_add_epi16(C1, C0);
+ const __m128i A0 = _mm_srli_epi16(avg, 1);
+ const __m128i A1 = _mm_sub_epi16(A0, B0);
+ const __m128i BgtA = _mm_cmpgt_epi16(B0, A0);
+ const __m128i A2 = _mm_sub_epi16(A1, BgtA);
+ const __m128i A3 = _mm_srai_epi16(A2, 1);
+ const __m128i A4 = _mm_add_epi16(A0, A3);
+ const __m128i A5 = _mm_packus_epi16(A4, A4);
+ const uint32_t output = _mm_cvtsi128_si32(A5);
+ return output;
+}
+
+static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
+ int pa_minus_pb;
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i A0 = _mm_cvtsi32_si128(a);
+ const __m128i B0 = _mm_cvtsi32_si128(b);
+ const __m128i C0 = _mm_cvtsi32_si128(c);
+ const __m128i AC0 = _mm_subs_epu8(A0, C0);
+ const __m128i CA0 = _mm_subs_epu8(C0, A0);
+ const __m128i BC0 = _mm_subs_epu8(B0, C0);
+ const __m128i CB0 = _mm_subs_epu8(C0, B0);
+ const __m128i AC = _mm_or_si128(AC0, CA0);
+ const __m128i BC = _mm_or_si128(BC0, CB0);
+ const __m128i pa = _mm_unpacklo_epi8(AC, zero); // |a - c|
+ const __m128i pb = _mm_unpacklo_epi8(BC, zero); // |b - c|
+ const __m128i diff = _mm_sub_epi16(pb, pa);
+ {
+ int16_t out[8];
+ _mm_storeu_si128((__m128i*)out, diff);
+ pa_minus_pb = out[0] + out[1] + out[2] + out[3];
+ }
+ return (pa_minus_pb <= 0) ? a : b;
+}
+
+static WEBP_INLINE void Average2_m128i(const __m128i* const a0,
+ const __m128i* const a1,
+ __m128i* const avg) {
+ // (a + b) >> 1 = ((a + b + 1) >> 1) - ((a ^ b) & 1)
+ const __m128i ones = _mm_set1_epi8(1);
+ const __m128i avg1 = _mm_avg_epu8(*a0, *a1);
+ const __m128i one = _mm_and_si128(_mm_xor_si128(*a0, *a1), ones);
+ *avg = _mm_sub_epi8(avg1, one);
+}
+
+static WEBP_INLINE void Average2_uint32(const uint32_t a0, const uint32_t a1,
+ __m128i* const avg) {
+ // (a + b) >> 1 = ((a + b + 1) >> 1) - ((a ^ b) & 1)
+ const __m128i ones = _mm_set1_epi8(1);
+ const __m128i A0 = _mm_cvtsi32_si128(a0);
+ const __m128i A1 = _mm_cvtsi32_si128(a1);
+ const __m128i avg1 = _mm_avg_epu8(A0, A1);
+ const __m128i one = _mm_and_si128(_mm_xor_si128(A0, A1), ones);
+ *avg = _mm_sub_epi8(avg1, one);
+}
+
+static WEBP_INLINE __m128i Average2_uint32_16(uint32_t a0, uint32_t a1) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a0), zero);
+ const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+ const __m128i sum = _mm_add_epi16(A1, A0);
+ return _mm_srli_epi16(sum, 1);
+}
+
+static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
+ __m128i output;
+ Average2_uint32(a0, a1, &output);
+ return _mm_cvtsi128_si32(output);
+}
+
+static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i avg1 = Average2_uint32_16(a0, a2);
+ const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+ const __m128i sum = _mm_add_epi16(avg1, A1);
+ const __m128i avg2 = _mm_srli_epi16(sum, 1);
+ const __m128i A2 = _mm_packus_epi16(avg2, avg2);
+ const uint32_t output = _mm_cvtsi128_si32(A2);
+ return output;
+}
+
+static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
+ uint32_t a2, uint32_t a3) {
+ const __m128i avg1 = Average2_uint32_16(a0, a1);
+ const __m128i avg2 = Average2_uint32_16(a2, a3);
+ const __m128i sum = _mm_add_epi16(avg2, avg1);
+ const __m128i avg3 = _mm_srli_epi16(sum, 1);
+ const __m128i A0 = _mm_packus_epi16(avg3, avg3);
+ const uint32_t output = _mm_cvtsi128_si32(A0);
+ return output;
+}
+
+static uint32_t Predictor5_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average3(left, top[0], top[1]);
+ return pred;
+}
+static uint32_t Predictor6_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(left, top[-1]);
+ return pred;
+}
+static uint32_t Predictor7_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(left, top[0]);
+ return pred;
+}
+static uint32_t Predictor8_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(top[-1], top[0]);
+ (void)left;
+ return pred;
+}
+static uint32_t Predictor9_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average2(top[0], top[1]);
+ (void)left;
+ return pred;
+}
+static uint32_t Predictor10_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
+ return pred;
+}
+static uint32_t Predictor11_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = Select(top[0], left, top[-1]);
+ return pred;
+}
+static uint32_t Predictor12_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
+ return pred;
+}
+static uint32_t Predictor13_SSE2(uint32_t left, const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
+ return pred;
+}
+
+// Batch versions of those functions.
+
+// Predictor0: ARGB_BLACK.
+static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
+ const __m128i res = _mm_add_epi8(src, black);
+ _mm_storeu_si128((__m128i*)&out[i], res);
+ }
+ if (i != num_pixels) {
+ VP8LPredictorsAdd_C[0](in + i, upper + i, num_pixels - i, out + i);
+ }
+}
+
+// Predictor1: left.
+static void PredictorAdd1_SSE2(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ __m128i prev = _mm_set1_epi32(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ // a | b | c | d
+ const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
+ // 0 | a | b | c
+ const __m128i shift0 = _mm_slli_si128(src, 4);
+ // a | a + b | b + c | c + d
+ const __m128i sum0 = _mm_add_epi8(src, shift0);
+ // 0 | 0 | a | a + b
+ const __m128i shift1 = _mm_slli_si128(sum0, 8);
+ // a | a + b | a + b + c | a + b + c + d
+ const __m128i sum1 = _mm_add_epi8(sum0, shift1);
+ const __m128i res = _mm_add_epi8(sum1, prev);
+ _mm_storeu_si128((__m128i*)&out[i], res);
+ // replicate prev output on the four lanes
+ prev = _mm_shuffle_epi32(res, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6));
+ }
+ if (i != num_pixels) {
+ VP8LPredictorsAdd_C[1](in + i, upper + i, num_pixels - i, out + i);
+ }
+}
+
+// Macro that adds 32-bit integers from IN using mod 256 arithmetic
+// per 8 bit channel.
+#define GENERATE_PREDICTOR_1(X, IN) \
+static void PredictorAdd##X##_SSE2(const uint32_t* in, const uint32_t* upper, \
+ int num_pixels, uint32_t* out) { \
+ int i; \
+ for (i = 0; i + 4 <= num_pixels; i += 4) { \
+ const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); \
+ const __m128i other = _mm_loadu_si128((const __m128i*)&(IN)); \
+ const __m128i res = _mm_add_epi8(src, other); \
+ _mm_storeu_si128((__m128i*)&out[i], res); \
+ } \
+ if (i != num_pixels) { \
+ VP8LPredictorsAdd_C[(X)](in + i, upper + i, num_pixels - i, out + i); \
+ } \
+}
+
+// Predictor2: Top.
+GENERATE_PREDICTOR_1(2, upper[i])
+// Predictor3: Top-right.
+GENERATE_PREDICTOR_1(3, upper[i + 1])
+// Predictor4: Top-left.
+GENERATE_PREDICTOR_1(4, upper[i - 1])
+#undef GENERATE_PREDICTOR_1
+
+// Due to averages with integers, values cannot be accumulated in parallel for
+// predictors 5 to 7.
+GENERATE_PREDICTOR_ADD(Predictor5_SSE2, PredictorAdd5_SSE2)
+GENERATE_PREDICTOR_ADD(Predictor6_SSE2, PredictorAdd6_SSE2)
+GENERATE_PREDICTOR_ADD(Predictor7_SSE2, PredictorAdd7_SSE2)
+
+#define GENERATE_PREDICTOR_2(X, IN) \
+static void PredictorAdd##X##_SSE2(const uint32_t* in, const uint32_t* upper, \
+ int num_pixels, uint32_t* out) { \
+ int i; \
+ for (i = 0; i + 4 <= num_pixels; i += 4) { \
+ const __m128i Tother = _mm_loadu_si128((const __m128i*)&(IN)); \
+ const __m128i T = _mm_loadu_si128((const __m128i*)&upper[i]); \
+ const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); \
+ __m128i avg, res; \
+ Average2_m128i(&T, &Tother, &avg); \
+ res = _mm_add_epi8(avg, src); \
+ _mm_storeu_si128((__m128i*)&out[i], res); \
+ } \
+ if (i != num_pixels) { \
+ VP8LPredictorsAdd_C[(X)](in + i, upper + i, num_pixels - i, out + i); \
+ } \
+}
+// Predictor8: average TL T.
+GENERATE_PREDICTOR_2(8, upper[i - 1])
+// Predictor9: average T TR.
+GENERATE_PREDICTOR_2(9, upper[i + 1])
+#undef GENERATE_PREDICTOR_2
+
+// Predictor10: average of (average of (L,TL), average of (T, TR)).
+static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i, j;
+ __m128i L = _mm_cvtsi32_si128(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
+ __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
+ const __m128i T = _mm_loadu_si128((const __m128i*)&upper[i]);
+ const __m128i TR = _mm_loadu_si128((const __m128i*)&upper[i + 1]);
+ __m128i avgTTR;
+ Average2_m128i(&T, &TR, &avgTTR);
+ for (j = 0; j < 4; ++j) {
+ __m128i avgLTL, avg;
+ Average2_m128i(&L, &TL, &avgLTL);
+ Average2_m128i(&avgTTR, &avgLTL, &avg);
+ L = _mm_add_epi8(avg, src);
+ out[i + j] = _mm_cvtsi128_si32(L);
+ // Rotate the pre-computed values for the next iteration.
+ avgTTR = _mm_srli_si128(avgTTR, 4);
+ TL = _mm_srli_si128(TL, 4);
+ src = _mm_srli_si128(src, 4);
+ }
+ }
+ if (i != num_pixels) {
+ VP8LPredictorsAdd_C[10](in + i, upper + i, num_pixels - i, out + i);
+ }
+}
+
+// Predictor11: select.
+static void GetSumAbsDiff32(const __m128i* const A, const __m128i* const B,
+ __m128i* const out) {
+ // We can unpack with any value on the upper 32 bits, provided it's the same
+ // on both operands (to that their sum of abs diff is zero). Here we use *A.
+ const __m128i A_lo = _mm_unpacklo_epi32(*A, *A);
+ const __m128i B_lo = _mm_unpacklo_epi32(*B, *A);
+ const __m128i A_hi = _mm_unpackhi_epi32(*A, *A);
+ const __m128i B_hi = _mm_unpackhi_epi32(*B, *A);
+ const __m128i s_lo = _mm_sad_epu8(A_lo, B_lo);
+ const __m128i s_hi = _mm_sad_epu8(A_hi, B_hi);
+ *out = _mm_packs_epi32(s_lo, s_hi);
+}
+
+static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i, j;
+ __m128i L = _mm_cvtsi32_si128(out[-1]);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ __m128i T = _mm_loadu_si128((const __m128i*)&upper[i]);
+ __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
+ __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
+ __m128i pa;
+ GetSumAbsDiff32(&T, &TL, &pa); // pa = sum |T-TL|
+ for (j = 0; j < 4; ++j) {
+ const __m128i L_lo = _mm_unpacklo_epi32(L, L);
+ const __m128i TL_lo = _mm_unpacklo_epi32(TL, L);
+ const __m128i pb = _mm_sad_epu8(L_lo, TL_lo); // pb = sum |L-TL|
+ const __m128i mask = _mm_cmpgt_epi32(pb, pa);
+ const __m128i A = _mm_and_si128(mask, L);
+ const __m128i B = _mm_andnot_si128(mask, T);
+ const __m128i pred = _mm_or_si128(A, B); // pred = (L > T)? L : T
+ L = _mm_add_epi8(src, pred);
+ out[i + j] = _mm_cvtsi128_si32(L);
+ // Shift the pre-computed value for the next iteration.
+ T = _mm_srli_si128(T, 4);
+ TL = _mm_srli_si128(TL, 4);
+ src = _mm_srli_si128(src, 4);
+ pa = _mm_srli_si128(pa, 4);
+ }
+ }
+ if (i != num_pixels) {
+ VP8LPredictorsAdd_C[11](in + i, upper + i, num_pixels - i, out + i);
+ }
+}
+
+// Predictor12: ClampedAddSubtractFull.
+#define DO_PRED12(DIFF, LANE, OUT) \
+do { \
+ const __m128i all = _mm_add_epi16(L, (DIFF)); \
+ const __m128i alls = _mm_packus_epi16(all, all); \
+ const __m128i res = _mm_add_epi8(src, alls); \
+ out[i + (OUT)] = _mm_cvtsi128_si32(res); \
+ L = _mm_unpacklo_epi8(res, zero); \
+ /* Shift the pre-computed value for the next iteration.*/ \
+ if (LANE == 0) (DIFF) = _mm_srli_si128((DIFF), 8); \
+ src = _mm_srli_si128(src, 4); \
+} while (0)
+
+static void PredictorAdd12_SSE2(const uint32_t* in, const uint32_t* upper,
+ int num_pixels, uint32_t* out) {
+ int i;
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i L8 = _mm_cvtsi32_si128(out[-1]);
+ __m128i L = _mm_unpacklo_epi8(L8, zero);
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ // Load 4 pixels at a time.
+ __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
+ const __m128i T = _mm_loadu_si128((const __m128i*)&upper[i]);
+ const __m128i T_lo = _mm_unpacklo_epi8(T, zero);
+ const __m128i T_hi = _mm_unpackhi_epi8(T, zero);
+ const __m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
+ const __m128i TL_lo = _mm_unpacklo_epi8(TL, zero);
+ const __m128i TL_hi = _mm_unpackhi_epi8(TL, zero);
+ __m128i diff_lo = _mm_sub_epi16(T_lo, TL_lo);
+ __m128i diff_hi = _mm_sub_epi16(T_hi, TL_hi);
+ DO_PRED12(diff_lo, 0, 0);
+ DO_PRED12(diff_lo, 1, 1);
+ DO_PRED12(diff_hi, 0, 2);
+ DO_PRED12(diff_hi, 1, 3);
+ }
+ if (i != num_pixels) {
+ VP8LPredictorsAdd_C[12](in + i, upper + i, num_pixels - i, out + i);
+ }
+}
+#undef DO_PRED12
+
+// Due to averages with integers, values cannot be accumulated in parallel for
+// predictors 13.
+GENERATE_PREDICTOR_ADD(Predictor13_SSE2, PredictorAdd13_SSE2)
+
+//------------------------------------------------------------------------------
+// Subtract-Green Transform
+
+static void AddGreenToBlueAndRed(const uint32_t* const src, int num_pixels,
+ uint32_t* dst) {
+ int i;
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const __m128i in = _mm_loadu_si128((const __m128i*)&src[i]); // argb
+ const __m128i A = _mm_srli_epi16(in, 8); // 0 a 0 g
+ const __m128i B = _mm_shufflelo_epi16(A, _MM_SHUFFLE(2, 2, 0, 0));
+ const __m128i C = _mm_shufflehi_epi16(B, _MM_SHUFFLE(2, 2, 0, 0)); // 0g0g
+ const __m128i out = _mm_add_epi8(in, C);
+ _mm_storeu_si128((__m128i*)&dst[i], out);
+ }
+ // fallthrough and finish off with plain-C
+ if (i != num_pixels) {
+ VP8LAddGreenToBlueAndRed_C(src + i, num_pixels - i, dst + i);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Color Transform
+
+static void TransformColorInverse(const VP8LMultipliers* const m,
+ const uint32_t* const src, int num_pixels,
+ uint32_t* dst) {
+// sign-extended multiplying constants, pre-shifted by 5.
+#define CST(X) (((int16_t)(m->X << 8)) >> 5) // sign-extend
+ const __m128i mults_rb = _mm_set_epi16(
+ CST(green_to_red_), CST(green_to_blue_),
+ CST(green_to_red_), CST(green_to_blue_),
+ CST(green_to_red_), CST(green_to_blue_),
+ CST(green_to_red_), CST(green_to_blue_));
+ const __m128i mults_b2 = _mm_set_epi16(
+ CST(red_to_blue_), 0, CST(red_to_blue_), 0,
+ CST(red_to_blue_), 0, CST(red_to_blue_), 0);
+#undef CST
+ const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks
+ int i;
+ for (i = 0; i + 4 <= num_pixels; i += 4) {
+ const __m128i in = _mm_loadu_si128((const __m128i*)&src[i]); // argb
+ const __m128i A = _mm_and_si128(in, mask_ag); // a 0 g 0
+ const __m128i B = _mm_shufflelo_epi16(A, _MM_SHUFFLE(2, 2, 0, 0));
+ const __m128i C = _mm_shufflehi_epi16(B, _MM_SHUFFLE(2, 2, 0, 0)); // g0g0
+ const __m128i D = _mm_mulhi_epi16(C, mults_rb); // x dr x db1
+ const __m128i E = _mm_add_epi8(in, D); // x r' x b'
+ const __m128i F = _mm_slli_epi16(E, 8); // r' 0 b' 0
+ const __m128i G = _mm_mulhi_epi16(F, mults_b2); // x db2 0 0
+ const __m128i H = _mm_srli_epi32(G, 8); // 0 x db2 0
+ const __m128i I = _mm_add_epi8(H, F); // r' x b'' 0
+ const __m128i J = _mm_srli_epi16(I, 8); // 0 r' 0 b''
+ const __m128i out = _mm_or_si128(J, A);
+ _mm_storeu_si128((__m128i*)&dst[i], out);
+ }
+ // Fall-back to C-version for left-overs.
+ if (i != num_pixels) {
+ VP8LTransformColorInverse_C(m, src + i, num_pixels - i, dst + i);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Color-space conversion functions
+
+static void ConvertBGRAToRGB(const uint32_t* src, int num_pixels,
+ uint8_t* dst) {
+ const __m128i* in = (const __m128i*)src;
+ __m128i* out = (__m128i*)dst;
+
+ while (num_pixels >= 32) {
+ // Load the BGRA buffers.
+ __m128i in0 = _mm_loadu_si128(in + 0);
+ __m128i in1 = _mm_loadu_si128(in + 1);
+ __m128i in2 = _mm_loadu_si128(in + 2);
+ __m128i in3 = _mm_loadu_si128(in + 3);
+ __m128i in4 = _mm_loadu_si128(in + 4);
+ __m128i in5 = _mm_loadu_si128(in + 5);
+ __m128i in6 = _mm_loadu_si128(in + 6);
+ __m128i in7 = _mm_loadu_si128(in + 7);
+ VP8L32bToPlanar(&in0, &in1, &in2, &in3);
+ VP8L32bToPlanar(&in4, &in5, &in6, &in7);
+ // At this points, in1/in5 contains red only, in2/in6 green only ...
+ // Pack the colors in 24b RGB.
+ VP8PlanarTo24b(&in1, &in5, &in2, &in6, &in3, &in7);
+ _mm_storeu_si128(out + 0, in1);
+ _mm_storeu_si128(out + 1, in5);
+ _mm_storeu_si128(out + 2, in2);
+ _mm_storeu_si128(out + 3, in6);
+ _mm_storeu_si128(out + 4, in3);
+ _mm_storeu_si128(out + 5, in7);
+ in += 8;
+ out += 6;
+ num_pixels -= 32;
+ }
+ // left-overs
+ if (num_pixels > 0) {
+ VP8LConvertBGRAToRGB_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+ }
+}
+
+static void ConvertBGRAToRGBA(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const __m128i* in = (const __m128i*)src;
+ __m128i* out = (__m128i*)dst;
+ while (num_pixels >= 8) {
+ const __m128i bgra0 = _mm_loadu_si128(in++); // bgra0|bgra1|bgra2|bgra3
+ const __m128i bgra4 = _mm_loadu_si128(in++); // bgra4|bgra5|bgra6|bgra7
+ const __m128i v0l = _mm_unpacklo_epi8(bgra0, bgra4); // b0b4g0g4r0r4a0a4...
+ const __m128i v0h = _mm_unpackhi_epi8(bgra0, bgra4); // b2b6g2g6r2r6a2a6...
+ const __m128i v1l = _mm_unpacklo_epi8(v0l, v0h); // b0b2b4b6g0g2g4g6...
+ const __m128i v1h = _mm_unpackhi_epi8(v0l, v0h); // b1b3b5b7g1g3g5g7...
+ const __m128i v2l = _mm_unpacklo_epi8(v1l, v1h); // b0...b7 | g0...g7
+ const __m128i v2h = _mm_unpackhi_epi8(v1l, v1h); // r0...r7 | a0...a7
+ const __m128i ga0 = _mm_unpackhi_epi64(v2l, v2h); // g0...g7 | a0...a7
+ const __m128i rb0 = _mm_unpacklo_epi64(v2h, v2l); // r0...r7 | b0...b7
+ const __m128i rg0 = _mm_unpacklo_epi8(rb0, ga0); // r0g0r1g1 ... r6g6r7g7
+ const __m128i ba0 = _mm_unpackhi_epi8(rb0, ga0); // b0a0b1a1 ... b6a6b7a7
+ const __m128i rgba0 = _mm_unpacklo_epi16(rg0, ba0); // rgba0|rgba1...
+ const __m128i rgba4 = _mm_unpackhi_epi16(rg0, ba0); // rgba4|rgba5...
+ _mm_storeu_si128(out++, rgba0);
+ _mm_storeu_si128(out++, rgba4);
+ num_pixels -= 8;
+ }
+ // left-overs
+ if (num_pixels > 0) {
+ VP8LConvertBGRAToRGBA_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+ }
+}
+
+static void ConvertBGRAToRGBA4444(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const __m128i mask_0x0f = _mm_set1_epi8(0x0f);
+ const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+ const __m128i* in = (const __m128i*)src;
+ __m128i* out = (__m128i*)dst;
+ while (num_pixels >= 8) {
+ const __m128i bgra0 = _mm_loadu_si128(in++); // bgra0|bgra1|bgra2|bgra3
+ const __m128i bgra4 = _mm_loadu_si128(in++); // bgra4|bgra5|bgra6|bgra7
+ const __m128i v0l = _mm_unpacklo_epi8(bgra0, bgra4); // b0b4g0g4r0r4a0a4...
+ const __m128i v0h = _mm_unpackhi_epi8(bgra0, bgra4); // b2b6g2g6r2r6a2a6...
+ const __m128i v1l = _mm_unpacklo_epi8(v0l, v0h); // b0b2b4b6g0g2g4g6...
+ const __m128i v1h = _mm_unpackhi_epi8(v0l, v0h); // b1b3b5b7g1g3g5g7...
+ const __m128i v2l = _mm_unpacklo_epi8(v1l, v1h); // b0...b7 | g0...g7
+ const __m128i v2h = _mm_unpackhi_epi8(v1l, v1h); // r0...r7 | a0...a7
+ const __m128i ga0 = _mm_unpackhi_epi64(v2l, v2h); // g0...g7 | a0...a7
+ const __m128i rb0 = _mm_unpacklo_epi64(v2h, v2l); // r0...r7 | b0...b7
+ const __m128i ga1 = _mm_srli_epi16(ga0, 4); // g0-|g1-|...|a6-|a7-
+ const __m128i rb1 = _mm_and_si128(rb0, mask_0xf0); // -r0|-r1|...|-b6|-a7
+ const __m128i ga2 = _mm_and_si128(ga1, mask_0x0f); // g0-|g1-|...|a6-|a7-
+ const __m128i rgba0 = _mm_or_si128(ga2, rb1); // rg0..rg7 | ba0..ba7
+ const __m128i rgba1 = _mm_srli_si128(rgba0, 8); // ba0..ba7 | 0
+#ifdef WEBP_SWAP_16BIT_CSP
+ const __m128i rgba = _mm_unpacklo_epi8(rgba1, rgba0); // barg0...barg7
+#else
+ const __m128i rgba = _mm_unpacklo_epi8(rgba0, rgba1); // rgba0...rgba7
+#endif
+ _mm_storeu_si128(out++, rgba);
+ num_pixels -= 8;
+ }
+ // left-overs
+ if (num_pixels > 0) {
+ VP8LConvertBGRAToRGBA4444_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+ }
+}
+
+static void ConvertBGRAToRGB565(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const __m128i mask_0xe0 = _mm_set1_epi8(0xe0);
+ const __m128i mask_0xf8 = _mm_set1_epi8(0xf8);
+ const __m128i mask_0x07 = _mm_set1_epi8(0x07);
+ const __m128i* in = (const __m128i*)src;
+ __m128i* out = (__m128i*)dst;
+ while (num_pixels >= 8) {
+ const __m128i bgra0 = _mm_loadu_si128(in++); // bgra0|bgra1|bgra2|bgra3
+ const __m128i bgra4 = _mm_loadu_si128(in++); // bgra4|bgra5|bgra6|bgra7
+ const __m128i v0l = _mm_unpacklo_epi8(bgra0, bgra4); // b0b4g0g4r0r4a0a4...
+ const __m128i v0h = _mm_unpackhi_epi8(bgra0, bgra4); // b2b6g2g6r2r6a2a6...
+ const __m128i v1l = _mm_unpacklo_epi8(v0l, v0h); // b0b2b4b6g0g2g4g6...
+ const __m128i v1h = _mm_unpackhi_epi8(v0l, v0h); // b1b3b5b7g1g3g5g7...
+ const __m128i v2l = _mm_unpacklo_epi8(v1l, v1h); // b0...b7 | g0...g7
+ const __m128i v2h = _mm_unpackhi_epi8(v1l, v1h); // r0...r7 | a0...a7
+ const __m128i ga0 = _mm_unpackhi_epi64(v2l, v2h); // g0...g7 | a0...a7
+ const __m128i rb0 = _mm_unpacklo_epi64(v2h, v2l); // r0...r7 | b0...b7
+ const __m128i rb1 = _mm_and_si128(rb0, mask_0xf8); // -r0..-r7|-b0..-b7
+ const __m128i g_lo1 = _mm_srli_epi16(ga0, 5);
+ const __m128i g_lo2 = _mm_and_si128(g_lo1, mask_0x07); // g0-...g7-|xx (3b)
+ const __m128i g_hi1 = _mm_slli_epi16(ga0, 3);
+ const __m128i g_hi2 = _mm_and_si128(g_hi1, mask_0xe0); // -g0...-g7|xx (3b)
+ const __m128i b0 = _mm_srli_si128(rb1, 8); // -b0...-b7|0
+ const __m128i rg1 = _mm_or_si128(rb1, g_lo2); // gr0...gr7|xx
+ const __m128i b1 = _mm_srli_epi16(b0, 3);
+ const __m128i gb1 = _mm_or_si128(b1, g_hi2); // bg0...bg7|xx
+#ifdef WEBP_SWAP_16BIT_CSP
+ const __m128i rgba = _mm_unpacklo_epi8(gb1, rg1); // rggb0...rggb7
+#else
+ const __m128i rgba = _mm_unpacklo_epi8(rg1, gb1); // bgrb0...bgrb7
+#endif
+ _mm_storeu_si128(out++, rgba);
+ num_pixels -= 8;
+ }
+ // left-overs
+ if (num_pixels > 0) {
+ VP8LConvertBGRAToRGB565_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
+ }
+}
+
+static void ConvertBGRAToBGR(const uint32_t* src,
+ int num_pixels, uint8_t* dst) {
+ const __m128i mask_l = _mm_set_epi32(0, 0x00ffffff, 0, 0x00ffffff);
+ const __m128i mask_h = _mm_set_epi32(0x00ffffff, 0, 0x00ffffff, 0);
+ const __m128i* in = (const __m128i*)src;
+ const uint8_t* const end = dst + num_pixels * 3;
+ // the last storel_epi64 below writes 8 bytes starting at offset 18
+ while (dst + 26 <= end) {
+ const __m128i bgra0 = _mm_loadu_si128(in++); // bgra0|bgra1|bgra2|bgra3
+ const __m128i bgra4 = _mm_loadu_si128(in++); // bgra4|bgra5|bgra6|bgra7
+ const __m128i a0l = _mm_and_si128(bgra0, mask_l); // bgr0|0|bgr0|0
+ const __m128i a4l = _mm_and_si128(bgra4, mask_l); // bgr0|0|bgr0|0
+ const __m128i a0h = _mm_and_si128(bgra0, mask_h); // 0|bgr0|0|bgr0
+ const __m128i a4h = _mm_and_si128(bgra4, mask_h); // 0|bgr0|0|bgr0
+ const __m128i b0h = _mm_srli_epi64(a0h, 8); // 000b|gr00|000b|gr00
+ const __m128i b4h = _mm_srli_epi64(a4h, 8); // 000b|gr00|000b|gr00
+ const __m128i c0 = _mm_or_si128(a0l, b0h); // rgbrgb00|rgbrgb00
+ const __m128i c4 = _mm_or_si128(a4l, b4h); // rgbrgb00|rgbrgb00
+ const __m128i c2 = _mm_srli_si128(c0, 8);
+ const __m128i c6 = _mm_srli_si128(c4, 8);
+ _mm_storel_epi64((__m128i*)(dst + 0), c0);
+ _mm_storel_epi64((__m128i*)(dst + 6), c2);
+ _mm_storel_epi64((__m128i*)(dst + 12), c4);
+ _mm_storel_epi64((__m128i*)(dst + 18), c6);
+ dst += 24;
+ num_pixels -= 8;
+ }
+ // left-overs
+ if (num_pixels > 0) {
+ VP8LConvertBGRAToBGR_C((const uint32_t*)in, num_pixels, dst);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void VP8LDspInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitSSE2(void) {
+ VP8LPredictors[5] = Predictor5_SSE2;
+ VP8LPredictors[6] = Predictor6_SSE2;
+ VP8LPredictors[7] = Predictor7_SSE2;
+ VP8LPredictors[8] = Predictor8_SSE2;
+ VP8LPredictors[9] = Predictor9_SSE2;
+ VP8LPredictors[10] = Predictor10_SSE2;
+ VP8LPredictors[11] = Predictor11_SSE2;
+ VP8LPredictors[12] = Predictor12_SSE2;
+ VP8LPredictors[13] = Predictor13_SSE2;
+
+ VP8LPredictorsAdd[0] = PredictorAdd0_SSE2;
+ VP8LPredictorsAdd[1] = PredictorAdd1_SSE2;
+ VP8LPredictorsAdd[2] = PredictorAdd2_SSE2;
+ VP8LPredictorsAdd[3] = PredictorAdd3_SSE2;
+ VP8LPredictorsAdd[4] = PredictorAdd4_SSE2;
+ VP8LPredictorsAdd[5] = PredictorAdd5_SSE2;
+ VP8LPredictorsAdd[6] = PredictorAdd6_SSE2;
+ VP8LPredictorsAdd[7] = PredictorAdd7_SSE2;
+ VP8LPredictorsAdd[8] = PredictorAdd8_SSE2;
+ VP8LPredictorsAdd[9] = PredictorAdd9_SSE2;
+ VP8LPredictorsAdd[10] = PredictorAdd10_SSE2;
+ VP8LPredictorsAdd[11] = PredictorAdd11_SSE2;
+ VP8LPredictorsAdd[12] = PredictorAdd12_SSE2;
+ VP8LPredictorsAdd[13] = PredictorAdd13_SSE2;
+
+ VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed;
+ VP8LTransformColorInverse = TransformColorInverse;
+
+ VP8LConvertBGRAToRGB = ConvertBGRAToRGB;
+ VP8LConvertBGRAToRGBA = ConvertBGRAToRGBA;
+ VP8LConvertBGRAToRGBA4444 = ConvertBGRAToRGBA4444;
+ VP8LConvertBGRAToRGB565 = ConvertBGRAToRGB565;
+ VP8LConvertBGRAToBGR = ConvertBGRAToBGR;
+}
+
+#else // !WEBP_USE_SSE2
+
+WEBP_DSP_INIT_STUB(VP8LDspInitSSE2)
+
+#endif // WEBP_USE_SSE2
diff --git a/media/libwebp/dsp/mips_macro.h b/media/libwebp/dsp/mips_macro.h
new file mode 100644
index 000000000..44aba9b71
--- /dev/null
+++ b/media/libwebp/dsp/mips_macro.h
@@ -0,0 +1,200 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MIPS common macros
+
+#ifndef WEBP_DSP_MIPS_MACRO_H_
+#define WEBP_DSP_MIPS_MACRO_H_
+
+#if defined(__GNUC__) && defined(__ANDROID__) && LOCAL_GCC_VERSION == 0x409
+#define WORK_AROUND_GCC
+#endif
+
+#define STR(s) #s
+#define XSTR(s) STR(s)
+
+// O0[31..16 | 15..0] = I0[31..16 | 15..0] + I1[31..16 | 15..0]
+// O1[31..16 | 15..0] = I0[31..16 | 15..0] - I1[31..16 | 15..0]
+// O - output
+// I - input (macro doesn't change it)
+#define ADD_SUB_HALVES(O0, O1, \
+ I0, I1) \
+ "addq.ph %[" #O0 "], %[" #I0 "], %[" #I1 "] \n\t" \
+ "subq.ph %[" #O1 "], %[" #I0 "], %[" #I1 "] \n\t"
+
+// O - output
+// I - input (macro doesn't change it)
+// I[0/1] - offset in bytes
+#define LOAD_IN_X2(O0, O1, \
+ I0, I1) \
+ "lh %[" #O0 "], " #I0 "(%[in]) \n\t" \
+ "lh %[" #O1 "], " #I1 "(%[in]) \n\t"
+
+// I0 - location
+// I1..I9 - offsets in bytes
+#define LOAD_WITH_OFFSET_X4(O0, O1, O2, O3, \
+ I0, I1, I2, I3, I4, I5, I6, I7, I8, I9) \
+ "ulw %[" #O0 "], " #I1 "+" XSTR(I9) "*" #I5 "(%[" #I0 "]) \n\t" \
+ "ulw %[" #O1 "], " #I2 "+" XSTR(I9) "*" #I6 "(%[" #I0 "]) \n\t" \
+ "ulw %[" #O2 "], " #I3 "+" XSTR(I9) "*" #I7 "(%[" #I0 "]) \n\t" \
+ "ulw %[" #O3 "], " #I4 "+" XSTR(I9) "*" #I8 "(%[" #I0 "]) \n\t"
+
+// O - output
+// IO - input/output
+// I - input (macro doesn't change it)
+#define MUL_SHIFT_SUM(O0, O1, O2, O3, O4, O5, O6, O7, \
+ IO0, IO1, IO2, IO3, \
+ I0, I1, I2, I3, I4, I5, I6, I7) \
+ "mul %[" #O0 "], %[" #I0 "], %[kC2] \n\t" \
+ "mul %[" #O1 "], %[" #I0 "], %[kC1] \n\t" \
+ "mul %[" #O2 "], %[" #I1 "], %[kC2] \n\t" \
+ "mul %[" #O3 "], %[" #I1 "], %[kC1] \n\t" \
+ "mul %[" #O4 "], %[" #I2 "], %[kC2] \n\t" \
+ "mul %[" #O5 "], %[" #I2 "], %[kC1] \n\t" \
+ "mul %[" #O6 "], %[" #I3 "], %[kC2] \n\t" \
+ "mul %[" #O7 "], %[" #I3 "], %[kC1] \n\t" \
+ "sra %[" #O0 "], %[" #O0 "], 16 \n\t" \
+ "sra %[" #O1 "], %[" #O1 "], 16 \n\t" \
+ "sra %[" #O2 "], %[" #O2 "], 16 \n\t" \
+ "sra %[" #O3 "], %[" #O3 "], 16 \n\t" \
+ "sra %[" #O4 "], %[" #O4 "], 16 \n\t" \
+ "sra %[" #O5 "], %[" #O5 "], 16 \n\t" \
+ "sra %[" #O6 "], %[" #O6 "], 16 \n\t" \
+ "sra %[" #O7 "], %[" #O7 "], 16 \n\t" \
+ "addu %[" #IO0 "], %[" #IO0 "], %[" #I4 "] \n\t" \
+ "addu %[" #IO1 "], %[" #IO1 "], %[" #I5 "] \n\t" \
+ "subu %[" #IO2 "], %[" #IO2 "], %[" #I6 "] \n\t" \
+ "subu %[" #IO3 "], %[" #IO3 "], %[" #I7 "] \n\t"
+
+// O - output
+// I - input (macro doesn't change it)
+#define INSERT_HALF_X2(O0, O1, \
+ I0, I1) \
+ "ins %[" #O0 "], %[" #I0 "], 16, 16 \n\t" \
+ "ins %[" #O1 "], %[" #I1 "], 16, 16 \n\t"
+
+// O - output
+// I - input (macro doesn't change it)
+#define SRA_16(O0, O1, O2, O3, \
+ I0, I1, I2, I3) \
+ "sra %[" #O0 "], %[" #I0 "], 16 \n\t" \
+ "sra %[" #O1 "], %[" #I1 "], 16 \n\t" \
+ "sra %[" #O2 "], %[" #I2 "], 16 \n\t" \
+ "sra %[" #O3 "], %[" #I3 "], 16 \n\t"
+
+// temp0[31..16 | 15..0] = temp8[31..16 | 15..0] + temp12[31..16 | 15..0]
+// temp1[31..16 | 15..0] = temp8[31..16 | 15..0] - temp12[31..16 | 15..0]
+// temp0[31..16 | 15..0] = temp0[31..16 >> 3 | 15..0 >> 3]
+// temp1[31..16 | 15..0] = temp1[31..16 >> 3 | 15..0 >> 3]
+// O - output
+// I - input (macro doesn't change it)
+#define SHIFT_R_SUM_X2(O0, O1, O2, O3, O4, O5, O6, O7, \
+ I0, I1, I2, I3, I4, I5, I6, I7) \
+ "addq.ph %[" #O0 "], %[" #I0 "], %[" #I4 "] \n\t" \
+ "subq.ph %[" #O1 "], %[" #I0 "], %[" #I4 "] \n\t" \
+ "addq.ph %[" #O2 "], %[" #I1 "], %[" #I5 "] \n\t" \
+ "subq.ph %[" #O3 "], %[" #I1 "], %[" #I5 "] \n\t" \
+ "addq.ph %[" #O4 "], %[" #I2 "], %[" #I6 "] \n\t" \
+ "subq.ph %[" #O5 "], %[" #I2 "], %[" #I6 "] \n\t" \
+ "addq.ph %[" #O6 "], %[" #I3 "], %[" #I7 "] \n\t" \
+ "subq.ph %[" #O7 "], %[" #I3 "], %[" #I7 "] \n\t" \
+ "shra.ph %[" #O0 "], %[" #O0 "], 3 \n\t" \
+ "shra.ph %[" #O1 "], %[" #O1 "], 3 \n\t" \
+ "shra.ph %[" #O2 "], %[" #O2 "], 3 \n\t" \
+ "shra.ph %[" #O3 "], %[" #O3 "], 3 \n\t" \
+ "shra.ph %[" #O4 "], %[" #O4 "], 3 \n\t" \
+ "shra.ph %[" #O5 "], %[" #O5 "], 3 \n\t" \
+ "shra.ph %[" #O6 "], %[" #O6 "], 3 \n\t" \
+ "shra.ph %[" #O7 "], %[" #O7 "], 3 \n\t"
+
+// precrq.ph.w temp0, temp8, temp2
+// temp0 = temp8[31..16] | temp2[31..16]
+// ins temp2, temp8, 16, 16
+// temp2 = temp8[31..16] | temp2[15..0]
+// O - output
+// IO - input/output
+// I - input (macro doesn't change it)
+#define PACK_2_HALVES_TO_WORD(O0, O1, O2, O3, \
+ IO0, IO1, IO2, IO3, \
+ I0, I1, I2, I3) \
+ "precrq.ph.w %[" #O0 "], %[" #I0 "], %[" #IO0 "] \n\t" \
+ "precrq.ph.w %[" #O1 "], %[" #I1 "], %[" #IO1 "] \n\t" \
+ "ins %[" #IO0 "], %[" #I0 "], 16, 16 \n\t" \
+ "ins %[" #IO1 "], %[" #I1 "], 16, 16 \n\t" \
+ "precrq.ph.w %[" #O2 "], %[" #I2 "], %[" #IO2 "] \n\t" \
+ "precrq.ph.w %[" #O3 "], %[" #I3 "], %[" #IO3 "] \n\t" \
+ "ins %[" #IO2 "], %[" #I2 "], 16, 16 \n\t" \
+ "ins %[" #IO3 "], %[" #I3 "], 16, 16 \n\t"
+
+// preceu.ph.qbr temp0, temp8
+// temp0 = 0 | 0 | temp8[23..16] | temp8[7..0]
+// preceu.ph.qbl temp1, temp8
+// temp1 = temp8[23..16] | temp8[7..0] | 0 | 0
+// O - output
+// I - input (macro doesn't change it)
+#define CONVERT_2_BYTES_TO_HALF(O0, O1, O2, O3, O4, O5, O6, O7, \
+ I0, I1, I2, I3) \
+ "preceu.ph.qbr %[" #O0 "], %[" #I0 "] \n\t" \
+ "preceu.ph.qbl %[" #O1 "], %[" #I0 "] \n\t" \
+ "preceu.ph.qbr %[" #O2 "], %[" #I1 "] \n\t" \
+ "preceu.ph.qbl %[" #O3 "], %[" #I1 "] \n\t" \
+ "preceu.ph.qbr %[" #O4 "], %[" #I2 "] \n\t" \
+ "preceu.ph.qbl %[" #O5 "], %[" #I2 "] \n\t" \
+ "preceu.ph.qbr %[" #O6 "], %[" #I3 "] \n\t" \
+ "preceu.ph.qbl %[" #O7 "], %[" #I3 "] \n\t"
+
+// temp0[31..16 | 15..0] = temp0[31..16 | 15..0] + temp8[31..16 | 15..0]
+// temp0[31..16 | 15..0] = temp0[31..16 <<(s) 7 | 15..0 <<(s) 7]
+// temp1..temp7 same as temp0
+// precrqu_s.qb.ph temp0, temp1, temp0:
+// temp0 = temp1[31..24] | temp1[15..8] | temp0[31..24] | temp0[15..8]
+// store temp0 to dst
+// IO - input/output
+// I - input (macro doesn't change it)
+#define STORE_SAT_SUM_X2(IO0, IO1, IO2, IO3, IO4, IO5, IO6, IO7, \
+ I0, I1, I2, I3, I4, I5, I6, I7, \
+ I8, I9, I10, I11, I12, I13) \
+ "addq.ph %[" #IO0 "], %[" #IO0 "], %[" #I0 "] \n\t" \
+ "addq.ph %[" #IO1 "], %[" #IO1 "], %[" #I1 "] \n\t" \
+ "addq.ph %[" #IO2 "], %[" #IO2 "], %[" #I2 "] \n\t" \
+ "addq.ph %[" #IO3 "], %[" #IO3 "], %[" #I3 "] \n\t" \
+ "addq.ph %[" #IO4 "], %[" #IO4 "], %[" #I4 "] \n\t" \
+ "addq.ph %[" #IO5 "], %[" #IO5 "], %[" #I5 "] \n\t" \
+ "addq.ph %[" #IO6 "], %[" #IO6 "], %[" #I6 "] \n\t" \
+ "addq.ph %[" #IO7 "], %[" #IO7 "], %[" #I7 "] \n\t" \
+ "shll_s.ph %[" #IO0 "], %[" #IO0 "], 7 \n\t" \
+ "shll_s.ph %[" #IO1 "], %[" #IO1 "], 7 \n\t" \
+ "shll_s.ph %[" #IO2 "], %[" #IO2 "], 7 \n\t" \
+ "shll_s.ph %[" #IO3 "], %[" #IO3 "], 7 \n\t" \
+ "shll_s.ph %[" #IO4 "], %[" #IO4 "], 7 \n\t" \
+ "shll_s.ph %[" #IO5 "], %[" #IO5 "], 7 \n\t" \
+ "shll_s.ph %[" #IO6 "], %[" #IO6 "], 7 \n\t" \
+ "shll_s.ph %[" #IO7 "], %[" #IO7 "], 7 \n\t" \
+ "precrqu_s.qb.ph %[" #IO0 "], %[" #IO1 "], %[" #IO0 "] \n\t" \
+ "precrqu_s.qb.ph %[" #IO2 "], %[" #IO3 "], %[" #IO2 "] \n\t" \
+ "precrqu_s.qb.ph %[" #IO4 "], %[" #IO5 "], %[" #IO4 "] \n\t" \
+ "precrqu_s.qb.ph %[" #IO6 "], %[" #IO7 "], %[" #IO6 "] \n\t" \
+ "usw %[" #IO0 "], " XSTR(I13) "*" #I9 "(%[" #I8 "]) \n\t" \
+ "usw %[" #IO2 "], " XSTR(I13) "*" #I10 "(%[" #I8 "]) \n\t" \
+ "usw %[" #IO4 "], " XSTR(I13) "*" #I11 "(%[" #I8 "]) \n\t" \
+ "usw %[" #IO6 "], " XSTR(I13) "*" #I12 "(%[" #I8 "]) \n\t"
+
+#define OUTPUT_EARLY_CLOBBER_REGS_10() \
+ : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), \
+ [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6), \
+ [temp7]"=&r"(temp7), [temp8]"=&r"(temp8), [temp9]"=&r"(temp9), \
+ [temp10]"=&r"(temp10)
+
+#define OUTPUT_EARLY_CLOBBER_REGS_18() \
+ OUTPUT_EARLY_CLOBBER_REGS_10(), \
+ [temp11]"=&r"(temp11), [temp12]"=&r"(temp12), [temp13]"=&r"(temp13), \
+ [temp14]"=&r"(temp14), [temp15]"=&r"(temp15), [temp16]"=&r"(temp16), \
+ [temp17]"=&r"(temp17), [temp18]"=&r"(temp18)
+
+#endif // WEBP_DSP_MIPS_MACRO_H_
diff --git a/media/libwebp/dsp/moz.build b/media/libwebp/dsp/moz.build
new file mode 100644
index 000000000..006a691a0
--- /dev/null
+++ b/media/libwebp/dsp/moz.build
@@ -0,0 +1,53 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files('**'):
+ BUG_COMPONENT = ('Core', 'ImageLib')
+
+SOURCES += [
+ 'alpha_processing.c',
+ 'alpha_processing_sse2.c',
+ 'alpha_processing_sse41.c',
+ 'dec.c',
+ 'dec_clip_tables.c',
+ 'dec_neon.c',
+ 'dec_sse2.c',
+ 'dec_sse41.c',
+ 'filters.c',
+ 'filters_sse2.c',
+ 'lossless.c',
+ 'lossless_neon.c',
+ 'lossless_sse2.c',
+ 'rescaler.c',
+ 'rescaler_neon.c',
+ 'rescaler_sse2.c',
+ 'upsampling.c',
+ 'upsampling_neon.c',
+ 'upsampling_sse2.c',
+ 'yuv.c',
+ 'yuv_sse2.c',
+]
+
+if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
+ SOURCES['dec_neon.c'].flags += CONFIG['NEON_FLAGS']
+ SOURCES['lossless_neon.c'].flags += CONFIG['NEON_FLAGS']
+ SOURCES['rescaler_neon.c'].flags += CONFIG['NEON_FLAGS']
+ SOURCES['upsampling_neon.c'].flags += CONFIG['NEON_FLAGS']
+elif CONFIG['INTEL_ARCHITECTURE']:
+ SOURCES['alpha_processing_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['alpha_processing_sse41.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['dec_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['dec_sse41.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['filters_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['lossless_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['rescaler_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['upsampling_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+ SOURCES['yuv_sse2.c'].flags += CONFIG['SSE2_FLAGS']
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
diff --git a/media/libwebp/dsp/msa_macro.h b/media/libwebp/dsp/msa_macro.h
new file mode 100644
index 000000000..d0e5f45e0
--- /dev/null
+++ b/media/libwebp/dsp/msa_macro.h
@@ -0,0 +1,1390 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// MSA common macros
+//
+// Author(s): Prashant Patil (prashant.patil@imgtec.com)
+
+#ifndef WEBP_DSP_MSA_MACRO_H_
+#define WEBP_DSP_MSA_MACRO_H_
+
+#include <stdint.h>
+#include <msa.h>
+
+#if defined(__clang__)
+ #define CLANG_BUILD
+#endif
+
+#ifdef CLANG_BUILD
+ #define ADDVI_H(a, b) __msa_addvi_h((v8i16)a, b)
+ #define ADDVI_W(a, b) __msa_addvi_w((v4i32)a, b)
+ #define SRAI_B(a, b) __msa_srai_b((v16i8)a, b)
+ #define SRAI_H(a, b) __msa_srai_h((v8i16)a, b)
+ #define SRAI_W(a, b) __msa_srai_w((v4i32)a, b)
+ #define SRLI_H(a, b) __msa_srli_h((v8i16)a, b)
+ #define SLLI_B(a, b) __msa_slli_b((v4i32)a, b)
+ #define ANDI_B(a, b) __msa_andi_b((v16u8)a, b)
+ #define ORI_B(a, b) __msa_ori_b((v16u8)a, b)
+#else
+ #define ADDVI_H(a, b) (a + b)
+ #define ADDVI_W(a, b) (a + b)
+ #define SRAI_B(a, b) (a >> b)
+ #define SRAI_H(a, b) (a >> b)
+ #define SRAI_W(a, b) (a >> b)
+ #define SRLI_H(a, b) (a << b)
+ #define SLLI_B(a, b) (a << b)
+ #define ANDI_B(a, b) (a & b)
+ #define ORI_B(a, b) (a | b)
+#endif
+
+#define LD_B(RTYPE, psrc) *((RTYPE*)(psrc))
+#define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
+#define LD_SB(...) LD_B(v16i8, __VA_ARGS__)
+
+#define LD_H(RTYPE, psrc) *((RTYPE*)(psrc))
+#define LD_UH(...) LD_H(v8u16, __VA_ARGS__)
+#define LD_SH(...) LD_H(v8i16, __VA_ARGS__)
+
+#define LD_W(RTYPE, psrc) *((RTYPE*)(psrc))
+#define LD_UW(...) LD_W(v4u32, __VA_ARGS__)
+#define LD_SW(...) LD_W(v4i32, __VA_ARGS__)
+
+#define ST_B(RTYPE, in, pdst) *((RTYPE*)(pdst)) = in
+#define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
+#define ST_SB(...) ST_B(v16i8, __VA_ARGS__)
+
+#define ST_H(RTYPE, in, pdst) *((RTYPE*)(pdst)) = in
+#define ST_UH(...) ST_H(v8u16, __VA_ARGS__)
+#define ST_SH(...) ST_H(v8i16, __VA_ARGS__)
+
+#define ST_W(RTYPE, in, pdst) *((RTYPE*)(pdst)) = in
+#define ST_UW(...) ST_W(v4u32, __VA_ARGS__)
+#define ST_SW(...) ST_W(v4i32, __VA_ARGS__)
+
+#define MSA_LOAD_FUNC(TYPE, INSTR, FUNC_NAME) \
+ static inline TYPE FUNC_NAME(const void* const psrc) { \
+ const uint8_t* const psrc_m = (const uint8_t*)psrc; \
+ TYPE val_m; \
+ asm volatile ( \
+ "" #INSTR " %[val_m], %[psrc_m] \n\t" \
+ : [val_m] "=r" (val_m) \
+ : [psrc_m] "m" (*psrc_m)); \
+ return val_m; \
+ }
+
+#define MSA_LOAD(psrc, FUNC_NAME) FUNC_NAME(psrc)
+
+#define MSA_STORE_FUNC(TYPE, INSTR, FUNC_NAME) \
+ static inline void FUNC_NAME(TYPE val, void* const pdst) { \
+ uint8_t* const pdst_m = (uint8_t*)pdst; \
+ TYPE val_m = val; \
+ asm volatile ( \
+ " " #INSTR " %[val_m], %[pdst_m] \n\t" \
+ : [pdst_m] "=m" (*pdst_m) \
+ : [val_m] "r" (val_m)); \
+ }
+
+#define MSA_STORE(val, pdst, FUNC_NAME) FUNC_NAME(val, pdst)
+
+#if (__mips_isa_rev >= 6)
+ MSA_LOAD_FUNC(uint16_t, lh, msa_lh);
+ #define LH(psrc) MSA_LOAD(psrc, msa_lh)
+ MSA_LOAD_FUNC(uint32_t, lw, msa_lw);
+ #define LW(psrc) MSA_LOAD(psrc, msa_lw)
+ #if (__mips == 64)
+ MSA_LOAD_FUNC(uint64_t, ld, msa_ld);
+ #define LD(psrc) MSA_LOAD(psrc, msa_ld)
+ #else // !(__mips == 64)
+ #define LD(psrc) ((((uint64_t)MSA_LOAD(psrc + 4, msa_lw)) << 32) | \
+ MSA_LOAD(psrc, msa_lw))
+ #endif // (__mips == 64)
+
+ MSA_STORE_FUNC(uint16_t, sh, msa_sh);
+ #define SH(val, pdst) MSA_STORE(val, pdst, msa_sh)
+ MSA_STORE_FUNC(uint32_t, sw, msa_sw);
+ #define SW(val, pdst) MSA_STORE(val, pdst, msa_sw)
+ MSA_STORE_FUNC(uint64_t, sd, msa_sd);
+ #define SD(val, pdst) MSA_STORE(val, pdst, msa_sd)
+#else // !(__mips_isa_rev >= 6)
+ MSA_LOAD_FUNC(uint16_t, ulh, msa_ulh);
+ #define LH(psrc) MSA_LOAD(psrc, msa_ulh)
+ MSA_LOAD_FUNC(uint32_t, ulw, msa_ulw);
+ #define LW(psrc) MSA_LOAD(psrc, msa_ulw)
+ #if (__mips == 64)
+ MSA_LOAD_FUNC(uint64_t, uld, msa_uld);
+ #define LD(psrc) MSA_LOAD(psrc, msa_uld)
+ #else // !(__mips == 64)
+ #define LD(psrc) ((((uint64_t)MSA_LOAD(psrc + 4, msa_ulw)) << 32) | \
+ MSA_LOAD(psrc, msa_ulw))
+ #endif // (__mips == 64)
+
+ MSA_STORE_FUNC(uint16_t, ush, msa_ush);
+ #define SH(val, pdst) MSA_STORE(val, pdst, msa_ush)
+ MSA_STORE_FUNC(uint32_t, usw, msa_usw);
+ #define SW(val, pdst) MSA_STORE(val, pdst, msa_usw)
+ #define SD(val, pdst) do { \
+ uint8_t* const pdst_sd_m = (uint8_t*)(pdst); \
+ const uint32_t val0_m = (uint32_t)(val & 0x00000000FFFFFFFF); \
+ const uint32_t val1_m = (uint32_t)((val >> 32) & 0x00000000FFFFFFFF); \
+ SW(val0_m, pdst_sd_m); \
+ SW(val1_m, pdst_sd_m + 4); \
+ } while (0)
+#endif // (__mips_isa_rev >= 6)
+
+/* Description : Load 4 words with stride
+ * Arguments : Inputs - psrc, stride
+ * Outputs - out0, out1, out2, out3
+ * Details : Load word in 'out0' from (psrc)
+ * Load word in 'out1' from (psrc + stride)
+ * Load word in 'out2' from (psrc + 2 * stride)
+ * Load word in 'out3' from (psrc + 3 * stride)
+ */
+#define LW4(psrc, stride, out0, out1, out2, out3) do { \
+ const uint8_t* ptmp = (const uint8_t*)psrc; \
+ out0 = LW(ptmp); \
+ ptmp += stride; \
+ out1 = LW(ptmp); \
+ ptmp += stride; \
+ out2 = LW(ptmp); \
+ ptmp += stride; \
+ out3 = LW(ptmp); \
+} while (0)
+
+/* Description : Store words with stride
+ * Arguments : Inputs - in0, in1, in2, in3, pdst, stride
+ * Details : Store word from 'in0' to (pdst)
+ * Store word from 'in1' to (pdst + stride)
+ * Store word from 'in2' to (pdst + 2 * stride)
+ * Store word from 'in3' to (pdst + 3 * stride)
+ */
+#define SW4(in0, in1, in2, in3, pdst, stride) do { \
+ uint8_t* ptmp = (uint8_t*)pdst; \
+ SW(in0, ptmp); \
+ ptmp += stride; \
+ SW(in1, ptmp); \
+ ptmp += stride; \
+ SW(in2, ptmp); \
+ ptmp += stride; \
+ SW(in3, ptmp); \
+} while (0)
+
+#define SW3(in0, in1, in2, pdst, stride) do { \
+ uint8_t* ptmp = (uint8_t*)pdst; \
+ SW(in0, ptmp); \
+ ptmp += stride; \
+ SW(in1, ptmp); \
+ ptmp += stride; \
+ SW(in2, ptmp); \
+} while (0)
+
+#define SW2(in0, in1, pdst, stride) do { \
+ uint8_t* ptmp = (uint8_t*)pdst; \
+ SW(in0, ptmp); \
+ ptmp += stride; \
+ SW(in1, ptmp); \
+} while (0)
+
+/* Description : Store 4 double words with stride
+ * Arguments : Inputs - in0, in1, in2, in3, pdst, stride
+ * Details : Store double word from 'in0' to (pdst)
+ * Store double word from 'in1' to (pdst + stride)
+ * Store double word from 'in2' to (pdst + 2 * stride)
+ * Store double word from 'in3' to (pdst + 3 * stride)
+ */
+#define SD4(in0, in1, in2, in3, pdst, stride) do { \
+ uint8_t* ptmp = (uint8_t*)pdst; \
+ SD(in0, ptmp); \
+ ptmp += stride; \
+ SD(in1, ptmp); \
+ ptmp += stride; \
+ SD(in2, ptmp); \
+ ptmp += stride; \
+ SD(in3, ptmp); \
+} while (0)
+
+/* Description : Load vectors with 16 byte elements with stride
+ * Arguments : Inputs - psrc, stride
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Load 16 byte elements in 'out0' from (psrc)
+ * Load 16 byte elements in 'out1' from (psrc + stride)
+ */
+#define LD_B2(RTYPE, psrc, stride, out0, out1) do { \
+ out0 = LD_B(RTYPE, psrc); \
+ out1 = LD_B(RTYPE, psrc + stride); \
+} while (0)
+#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
+#define LD_SB2(...) LD_B2(v16i8, __VA_ARGS__)
+
+#define LD_B3(RTYPE, psrc, stride, out0, out1, out2) do { \
+ LD_B2(RTYPE, psrc, stride, out0, out1); \
+ out2 = LD_B(RTYPE, psrc + 2 * stride); \
+} while (0)
+#define LD_UB3(...) LD_B3(v16u8, __VA_ARGS__)
+#define LD_SB3(...) LD_B3(v16i8, __VA_ARGS__)
+
+#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) do { \
+ LD_B2(RTYPE, psrc, stride, out0, out1); \
+ LD_B2(RTYPE, psrc + 2 * stride , stride, out2, out3); \
+} while (0)
+#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
+#define LD_SB4(...) LD_B4(v16i8, __VA_ARGS__)
+
+#define LD_B8(RTYPE, psrc, stride, \
+ out0, out1, out2, out3, out4, out5, out6, out7) do { \
+ LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3); \
+ LD_B4(RTYPE, psrc + 4 * stride, stride, out4, out5, out6, out7); \
+} while (0)
+#define LD_UB8(...) LD_B8(v16u8, __VA_ARGS__)
+#define LD_SB8(...) LD_B8(v16i8, __VA_ARGS__)
+
+/* Description : Load vectors with 8 halfword elements with stride
+ * Arguments : Inputs - psrc, stride
+ * Outputs - out0, out1
+ * Details : Load 8 halfword elements in 'out0' from (psrc)
+ * Load 8 halfword elements in 'out1' from (psrc + stride)
+ */
+#define LD_H2(RTYPE, psrc, stride, out0, out1) do { \
+ out0 = LD_H(RTYPE, psrc); \
+ out1 = LD_H(RTYPE, psrc + stride); \
+} while (0)
+#define LD_UH2(...) LD_H2(v8u16, __VA_ARGS__)
+#define LD_SH2(...) LD_H2(v8i16, __VA_ARGS__)
+
+/* Description : Load vectors with 4 word elements with stride
+ * Arguments : Inputs - psrc, stride
+ * Outputs - out0, out1, out2, out3
+ * Details : Load 4 word elements in 'out0' from (psrc + 0 * stride)
+ * Load 4 word elements in 'out1' from (psrc + 1 * stride)
+ * Load 4 word elements in 'out2' from (psrc + 2 * stride)
+ * Load 4 word elements in 'out3' from (psrc + 3 * stride)
+ */
+#define LD_W2(RTYPE, psrc, stride, out0, out1) do { \
+ out0 = LD_W(RTYPE, psrc); \
+ out1 = LD_W(RTYPE, psrc + stride); \
+} while (0)
+#define LD_UW2(...) LD_W2(v4u32, __VA_ARGS__)
+#define LD_SW2(...) LD_W2(v4i32, __VA_ARGS__)
+
+#define LD_W3(RTYPE, psrc, stride, out0, out1, out2) do { \
+ LD_W2(RTYPE, psrc, stride, out0, out1); \
+ out2 = LD_W(RTYPE, psrc + 2 * stride); \
+} while (0)
+#define LD_UW3(...) LD_W3(v4u32, __VA_ARGS__)
+#define LD_SW3(...) LD_W3(v4i32, __VA_ARGS__)
+
+#define LD_W4(RTYPE, psrc, stride, out0, out1, out2, out3) do { \
+ LD_W2(RTYPE, psrc, stride, out0, out1); \
+ LD_W2(RTYPE, psrc + 2 * stride, stride, out2, out3); \
+} while (0)
+#define LD_UW4(...) LD_W4(v4u32, __VA_ARGS__)
+#define LD_SW4(...) LD_W4(v4i32, __VA_ARGS__)
+
+/* Description : Store vectors of 16 byte elements with stride
+ * Arguments : Inputs - in0, in1, pdst, stride
+ * Details : Store 16 byte elements from 'in0' to (pdst)
+ * Store 16 byte elements from 'in1' to (pdst + stride)
+ */
+#define ST_B2(RTYPE, in0, in1, pdst, stride) do { \
+ ST_B(RTYPE, in0, pdst); \
+ ST_B(RTYPE, in1, pdst + stride); \
+} while (0)
+#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
+#define ST_SB2(...) ST_B2(v16i8, __VA_ARGS__)
+
+#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) do { \
+ ST_B2(RTYPE, in0, in1, pdst, stride); \
+ ST_B2(RTYPE, in2, in3, pdst + 2 * stride, stride); \
+} while (0)
+#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
+#define ST_SB4(...) ST_B4(v16i8, __VA_ARGS__)
+
+#define ST_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \
+ pdst, stride) do { \
+ ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride); \
+ ST_B4(RTYPE, in4, in5, in6, in7, pdst + 4 * stride, stride); \
+} while (0)
+#define ST_UB8(...) ST_B8(v16u8, __VA_ARGS__)
+
+/* Description : Store vectors of 4 word elements with stride
+ * Arguments : Inputs - in0, in1, in2, in3, pdst, stride
+ * Details : Store 4 word elements from 'in0' to (pdst + 0 * stride)
+ * Store 4 word elements from 'in1' to (pdst + 1 * stride)
+ * Store 4 word elements from 'in2' to (pdst + 2 * stride)
+ * Store 4 word elements from 'in3' to (pdst + 3 * stride)
+ */
+#define ST_W2(RTYPE, in0, in1, pdst, stride) do { \
+ ST_W(RTYPE, in0, pdst); \
+ ST_W(RTYPE, in1, pdst + stride); \
+} while (0)
+#define ST_UW2(...) ST_W2(v4u32, __VA_ARGS__)
+#define ST_SW2(...) ST_W2(v4i32, __VA_ARGS__)
+
+#define ST_W3(RTYPE, in0, in1, in2, pdst, stride) do { \
+ ST_W2(RTYPE, in0, in1, pdst, stride); \
+ ST_W(RTYPE, in2, pdst + 2 * stride); \
+} while (0)
+#define ST_UW3(...) ST_W3(v4u32, __VA_ARGS__)
+#define ST_SW3(...) ST_W3(v4i32, __VA_ARGS__)
+
+#define ST_W4(RTYPE, in0, in1, in2, in3, pdst, stride) do { \
+ ST_W2(RTYPE, in0, in1, pdst, stride); \
+ ST_W2(RTYPE, in2, in3, pdst + 2 * stride, stride); \
+} while (0)
+#define ST_UW4(...) ST_W4(v4u32, __VA_ARGS__)
+#define ST_SW4(...) ST_W4(v4i32, __VA_ARGS__)
+
+/* Description : Store vectors of 8 halfword elements with stride
+ * Arguments : Inputs - in0, in1, pdst, stride
+ * Details : Store 8 halfword elements from 'in0' to (pdst)
+ * Store 8 halfword elements from 'in1' to (pdst + stride)
+ */
+#define ST_H2(RTYPE, in0, in1, pdst, stride) do { \
+ ST_H(RTYPE, in0, pdst); \
+ ST_H(RTYPE, in1, pdst + stride); \
+} while (0)
+#define ST_UH2(...) ST_H2(v8u16, __VA_ARGS__)
+#define ST_SH2(...) ST_H2(v8i16, __VA_ARGS__)
+
+/* Description : Store 2x4 byte block to destination memory from input vector
+ * Arguments : Inputs - in, stidx, pdst, stride
+ * Details : Index 'stidx' halfword element from 'in' vector is copied to
+ * the GP register and stored to (pdst)
+ * Index 'stidx+1' halfword element from 'in' vector is copied to
+ * the GP register and stored to (pdst + stride)
+ * Index 'stidx+2' halfword element from 'in' vector is copied to
+ * the GP register and stored to (pdst + 2 * stride)
+ * Index 'stidx+3' halfword element from 'in' vector is copied to
+ * the GP register and stored to (pdst + 3 * stride)
+ */
+#define ST2x4_UB(in, stidx, pdst, stride) do { \
+ uint8_t* pblk_2x4_m = (uint8_t*)pdst; \
+ const uint16_t out0_m = __msa_copy_s_h((v8i16)in, stidx); \
+ const uint16_t out1_m = __msa_copy_s_h((v8i16)in, stidx + 1); \
+ const uint16_t out2_m = __msa_copy_s_h((v8i16)in, stidx + 2); \
+ const uint16_t out3_m = __msa_copy_s_h((v8i16)in, stidx + 3); \
+ SH(out0_m, pblk_2x4_m); \
+ pblk_2x4_m += stride; \
+ SH(out1_m, pblk_2x4_m); \
+ pblk_2x4_m += stride; \
+ SH(out2_m, pblk_2x4_m); \
+ pblk_2x4_m += stride; \
+ SH(out3_m, pblk_2x4_m); \
+} while (0)
+
+/* Description : Store 4x4 byte block to destination memory from input vector
+ * Arguments : Inputs - in0, in1, pdst, stride
+ * Details : 'Idx0' word element from input vector 'in0' is copied to the
+ * GP register and stored to (pdst)
+ * 'Idx1' word element from input vector 'in0' is copied to the
+ * GP register and stored to (pdst + stride)
+ * 'Idx2' word element from input vector 'in0' is copied to the
+ * GP register and stored to (pdst + 2 * stride)
+ * 'Idx3' word element from input vector 'in0' is copied to the
+ * GP register and stored to (pdst + 3 * stride)
+ */
+#define ST4x4_UB(in0, in1, idx0, idx1, idx2, idx3, pdst, stride) do { \
+ uint8_t* const pblk_4x4_m = (uint8_t*)pdst; \
+ const uint32_t out0_m = __msa_copy_s_w((v4i32)in0, idx0); \
+ const uint32_t out1_m = __msa_copy_s_w((v4i32)in0, idx1); \
+ const uint32_t out2_m = __msa_copy_s_w((v4i32)in1, idx2); \
+ const uint32_t out3_m = __msa_copy_s_w((v4i32)in1, idx3); \
+ SW4(out0_m, out1_m, out2_m, out3_m, pblk_4x4_m, stride); \
+} while (0)
+
+#define ST4x8_UB(in0, in1, pdst, stride) do { \
+ uint8_t* const pblk_4x8 = (uint8_t*)pdst; \
+ ST4x4_UB(in0, in0, 0, 1, 2, 3, pblk_4x8, stride); \
+ ST4x4_UB(in1, in1, 0, 1, 2, 3, pblk_4x8 + 4 * stride, stride); \
+} while (0)
+
+/* Description : Immediate number of elements to slide
+ * Arguments : Inputs - in0, in1, slide_val
+ * Outputs - out
+ * Return Type - as per RTYPE
+ * Details : Byte elements from 'in1' vector are slid into 'in0' by
+ * value specified in the 'slide_val'
+ */
+#define SLDI_B(RTYPE, in0, in1, slide_val) \
+ (RTYPE)__msa_sldi_b((v16i8)in0, (v16i8)in1, slide_val) \
+
+#define SLDI_UB(...) SLDI_B(v16u8, __VA_ARGS__)
+#define SLDI_SB(...) SLDI_B(v16i8, __VA_ARGS__)
+#define SLDI_SH(...) SLDI_B(v8i16, __VA_ARGS__)
+
+/* Description : Shuffle byte vector elements as per mask vector
+ * Arguments : Inputs - in0, in1, in2, in3, mask0, mask1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Byte elements from 'in0' & 'in1' are copied selectively to
+ * 'out0' as per control vector 'mask0'
+ */
+#define VSHF_B(RTYPE, in0, in1, mask) \
+ (RTYPE)__msa_vshf_b((v16i8)mask, (v16i8)in1, (v16i8)in0)
+
+#define VSHF_UB(...) VSHF_B(v16u8, __VA_ARGS__)
+#define VSHF_SB(...) VSHF_B(v16i8, __VA_ARGS__)
+#define VSHF_UH(...) VSHF_B(v8u16, __VA_ARGS__)
+#define VSHF_SH(...) VSHF_B(v8i16, __VA_ARGS__)
+
+#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) do { \
+ out0 = VSHF_B(RTYPE, in0, in1, mask0); \
+ out1 = VSHF_B(RTYPE, in2, in3, mask1); \
+} while (0)
+#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
+#define VSHF_B2_SB(...) VSHF_B2(v16i8, __VA_ARGS__)
+#define VSHF_B2_UH(...) VSHF_B2(v8u16, __VA_ARGS__)
+#define VSHF_B2_SH(...) VSHF_B2(v8i16, __VA_ARGS__)
+
+/* Description : Shuffle halfword vector elements as per mask vector
+ * Arguments : Inputs - in0, in1, in2, in3, mask0, mask1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : halfword elements from 'in0' & 'in1' are copied selectively to
+ * 'out0' as per control vector 'mask0'
+ */
+#define VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) do { \
+ out0 = (RTYPE)__msa_vshf_h((v8i16)mask0, (v8i16)in1, (v8i16)in0); \
+ out1 = (RTYPE)__msa_vshf_h((v8i16)mask1, (v8i16)in3, (v8i16)in2); \
+} while (0)
+#define VSHF_H2_UH(...) VSHF_H2(v8u16, __VA_ARGS__)
+#define VSHF_H2_SH(...) VSHF_H2(v8i16, __VA_ARGS__)
+
+/* Description : Dot product of byte vector elements
+ * Arguments : Inputs - mult0, mult1, cnst0, cnst1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Signed byte elements from 'mult0' are multiplied with
+ * signed byte elements from 'cnst0' producing a result
+ * twice the size of input i.e. signed halfword.
+ * The multiplication result of adjacent odd-even elements
+ * are added together and written to the 'out0' vector
+*/
+#define DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) do { \
+ out0 = (RTYPE)__msa_dotp_s_h((v16i8)mult0, (v16i8)cnst0); \
+ out1 = (RTYPE)__msa_dotp_s_h((v16i8)mult1, (v16i8)cnst1); \
+} while (0)
+#define DOTP_SB2_SH(...) DOTP_SB2(v8i16, __VA_ARGS__)
+
+/* Description : Dot product of halfword vector elements
+ * Arguments : Inputs - mult0, mult1, cnst0, cnst1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Signed halfword elements from 'mult0' are multiplied with
+ * signed halfword elements from 'cnst0' producing a result
+ * twice the size of input i.e. signed word.
+ * The multiplication result of adjacent odd-even elements
+ * are added together and written to the 'out0' vector
+ */
+#define DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) do { \
+ out0 = (RTYPE)__msa_dotp_s_w((v8i16)mult0, (v8i16)cnst0); \
+ out1 = (RTYPE)__msa_dotp_s_w((v8i16)mult1, (v8i16)cnst1); \
+} while (0)
+#define DOTP_SH2_SW(...) DOTP_SH2(v4i32, __VA_ARGS__)
+
+/* Description : Dot product of unsigned word vector elements
+ * Arguments : Inputs - mult0, mult1, cnst0, cnst1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Unsigned word elements from 'mult0' are multiplied with
+ * unsigned word elements from 'cnst0' producing a result
+ * twice the size of input i.e. unsigned double word.
+ * The multiplication result of adjacent odd-even elements
+ * are added together and written to the 'out0' vector
+ */
+#define DOTP_UW2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) do { \
+ out0 = (RTYPE)__msa_dotp_u_d((v4u32)mult0, (v4u32)cnst0); \
+ out1 = (RTYPE)__msa_dotp_u_d((v4u32)mult1, (v4u32)cnst1); \
+} while (0)
+#define DOTP_UW2_UD(...) DOTP_UW2(v2u64, __VA_ARGS__)
+
+/* Description : Dot product & addition of halfword vector elements
+ * Arguments : Inputs - mult0, mult1, cnst0, cnst1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Signed halfword elements from 'mult0' are multiplied with
+ * signed halfword elements from 'cnst0' producing a result
+ * twice the size of input i.e. signed word.
+ * The multiplication result of adjacent odd-even elements
+ * are added to the 'out0' vector
+ */
+#define DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) do { \
+ out0 = (RTYPE)__msa_dpadd_s_w((v4i32)out0, (v8i16)mult0, (v8i16)cnst0); \
+ out1 = (RTYPE)__msa_dpadd_s_w((v4i32)out1, (v8i16)mult1, (v8i16)cnst1); \
+} while (0)
+#define DPADD_SH2_SW(...) DPADD_SH2(v4i32, __VA_ARGS__)
+
+/* Description : Clips all signed halfword elements of input vector
+ * between 0 & 255
+ * Arguments : Input/output - val
+ * Return Type - signed halfword
+ */
+#define CLIP_SH_0_255(val) do { \
+ const v8i16 max_m = __msa_ldi_h(255); \
+ val = __msa_maxi_s_h((v8i16)val, 0); \
+ val = __msa_min_s_h(max_m, (v8i16)val); \
+} while (0)
+
+#define CLIP_SH2_0_255(in0, in1) do { \
+ CLIP_SH_0_255(in0); \
+ CLIP_SH_0_255(in1); \
+} while (0)
+
+#define CLIP_SH4_0_255(in0, in1, in2, in3) do { \
+ CLIP_SH2_0_255(in0, in1); \
+ CLIP_SH2_0_255(in2, in3); \
+} while (0)
+
+/* Description : Clips all unsigned halfword elements of input vector
+ * between 0 & 255
+ * Arguments : Input - in
+ * Output - out_m
+ * Return Type - unsigned halfword
+ */
+#define CLIP_UH_0_255(in) do { \
+ const v8u16 max_m = (v8u16)__msa_ldi_h(255); \
+ in = __msa_maxi_u_h((v8u16) in, 0); \
+ in = __msa_min_u_h((v8u16) max_m, (v8u16) in); \
+} while (0)
+
+#define CLIP_UH2_0_255(in0, in1) do { \
+ CLIP_UH_0_255(in0); \
+ CLIP_UH_0_255(in1); \
+} while (0)
+
+/* Description : Clips all signed word elements of input vector
+ * between 0 & 255
+ * Arguments : Input/output - val
+ * Return Type - signed word
+ */
+#define CLIP_SW_0_255(val) do { \
+ const v4i32 max_m = __msa_ldi_w(255); \
+ val = __msa_maxi_s_w((v4i32)val, 0); \
+ val = __msa_min_s_w(max_m, (v4i32)val); \
+} while (0)
+
+#define CLIP_SW4_0_255(in0, in1, in2, in3) do { \
+ CLIP_SW_0_255(in0); \
+ CLIP_SW_0_255(in1); \
+ CLIP_SW_0_255(in2); \
+ CLIP_SW_0_255(in3); \
+} while (0)
+
+/* Description : Horizontal addition of 4 signed word elements of input vector
+ * Arguments : Input - in (signed word vector)
+ * Output - sum_m (i32 sum)
+ * Return Type - signed word (GP)
+ * Details : 4 signed word elements of 'in' vector are added together and
+ * the resulting integer sum is returned
+ */
+static WEBP_INLINE int32_t func_hadd_sw_s32(v4i32 in) {
+ const v2i64 res0_m = __msa_hadd_s_d((v4i32)in, (v4i32)in);
+ const v2i64 res1_m = __msa_splati_d(res0_m, 1);
+ const v2i64 out = res0_m + res1_m;
+ int32_t sum_m = __msa_copy_s_w((v4i32)out, 0);
+ return sum_m;
+}
+#define HADD_SW_S32(in) func_hadd_sw_s32(in)
+
+/* Description : Horizontal addition of 8 signed halfword elements
+ * Arguments : Input - in (signed halfword vector)
+ * Output - sum_m (s32 sum)
+ * Return Type - signed word
+ * Details : 8 signed halfword elements of input vector are added
+ * together and the resulting integer sum is returned
+ */
+static WEBP_INLINE int32_t func_hadd_sh_s32(v8i16 in) {
+ const v4i32 res = __msa_hadd_s_w(in, in);
+ const v2i64 res0 = __msa_hadd_s_d(res, res);
+ const v2i64 res1 = __msa_splati_d(res0, 1);
+ const v2i64 res2 = res0 + res1;
+ const int32_t sum_m = __msa_copy_s_w((v4i32)res2, 0);
+ return sum_m;
+}
+#define HADD_SH_S32(in) func_hadd_sh_s32(in)
+
+/* Description : Horizontal addition of 8 unsigned halfword elements
+ * Arguments : Input - in (unsigned halfword vector)
+ * Output - sum_m (u32 sum)
+ * Return Type - unsigned word
+ * Details : 8 unsigned halfword elements of input vector are added
+ * together and the resulting integer sum is returned
+ */
+static WEBP_INLINE uint32_t func_hadd_uh_u32(v8u16 in) {
+ uint32_t sum_m;
+ const v4u32 res_m = __msa_hadd_u_w(in, in);
+ v2u64 res0_m = __msa_hadd_u_d(res_m, res_m);
+ v2u64 res1_m = (v2u64)__msa_splati_d((v2i64)res0_m, 1);
+ res0_m = res0_m + res1_m;
+ sum_m = __msa_copy_s_w((v4i32)res0_m, 0);
+ return sum_m;
+}
+#define HADD_UH_U32(in) func_hadd_uh_u32(in)
+
+/* Description : Horizontal addition of signed half word vector elements
+ Arguments : Inputs - in0, in1
+ Outputs - out0, out1
+ Return Type - as per RTYPE
+ Details : Each signed odd half word element from 'in0' is added to
+ even signed half word element from 'in0' (pairwise) and the
+ halfword result is written in 'out0'
+*/
+#define HADD_SH2(RTYPE, in0, in1, out0, out1) do { \
+ out0 = (RTYPE)__msa_hadd_s_w((v8i16)in0, (v8i16)in0); \
+ out1 = (RTYPE)__msa_hadd_s_w((v8i16)in1, (v8i16)in1); \
+} while (0)
+#define HADD_SH2_SW(...) HADD_SH2(v4i32, __VA_ARGS__)
+
+#define HADD_SH4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3) do { \
+ HADD_SH2(RTYPE, in0, in1, out0, out1); \
+ HADD_SH2(RTYPE, in2, in3, out2, out3); \
+} while (0)
+#define HADD_SH4_SW(...) HADD_SH4(v4i32, __VA_ARGS__)
+
+/* Description : Horizontal subtraction of unsigned byte vector elements
+ * Arguments : Inputs - in0, in1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Each unsigned odd byte element from 'in0' is subtracted from
+ * even unsigned byte element from 'in0' (pairwise) and the
+ * halfword result is written to 'out0'
+ */
+#define HSUB_UB2(RTYPE, in0, in1, out0, out1) do { \
+ out0 = (RTYPE)__msa_hsub_u_h((v16u8)in0, (v16u8)in0); \
+ out1 = (RTYPE)__msa_hsub_u_h((v16u8)in1, (v16u8)in1); \
+} while (0)
+#define HSUB_UB2_UH(...) HSUB_UB2(v8u16, __VA_ARGS__)
+#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__)
+#define HSUB_UB2_SW(...) HSUB_UB2(v4i32, __VA_ARGS__)
+
+/* Description : Set element n input vector to GPR value
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Output - out
+ * Return Type - as per RTYPE
+ * Details : Set element 0 in vector 'out' to value specified in 'in0'
+ */
+#define INSERT_W2(RTYPE, in0, in1, out) do { \
+ out = (RTYPE)__msa_insert_w((v4i32)out, 0, in0); \
+ out = (RTYPE)__msa_insert_w((v4i32)out, 1, in1); \
+} while (0)
+#define INSERT_W2_UB(...) INSERT_W2(v16u8, __VA_ARGS__)
+#define INSERT_W2_SB(...) INSERT_W2(v16i8, __VA_ARGS__)
+
+#define INSERT_W4(RTYPE, in0, in1, in2, in3, out) do { \
+ out = (RTYPE)__msa_insert_w((v4i32)out, 0, in0); \
+ out = (RTYPE)__msa_insert_w((v4i32)out, 1, in1); \
+ out = (RTYPE)__msa_insert_w((v4i32)out, 2, in2); \
+ out = (RTYPE)__msa_insert_w((v4i32)out, 3, in3); \
+} while (0)
+#define INSERT_W4_UB(...) INSERT_W4(v16u8, __VA_ARGS__)
+#define INSERT_W4_SB(...) INSERT_W4(v16i8, __VA_ARGS__)
+#define INSERT_W4_SW(...) INSERT_W4(v4i32, __VA_ARGS__)
+
+/* Description : Set element n of double word input vector to GPR value
+ * Arguments : Inputs - in0, in1
+ * Output - out
+ * Return Type - as per RTYPE
+ * Details : Set element 0 in vector 'out' to GPR value specified in 'in0'
+ * Set element 1 in vector 'out' to GPR value specified in 'in1'
+ */
+#define INSERT_D2(RTYPE, in0, in1, out) do { \
+ out = (RTYPE)__msa_insert_d((v2i64)out, 0, in0); \
+ out = (RTYPE)__msa_insert_d((v2i64)out, 1, in1); \
+} while (0)
+#define INSERT_D2_UB(...) INSERT_D2(v16u8, __VA_ARGS__)
+#define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__)
+
+/* Description : Interleave even byte elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even byte elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ */
+#define ILVEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvev_b((v16i8)in1, (v16i8)in0); \
+ out1 = (RTYPE)__msa_ilvev_b((v16i8)in3, (v16i8)in2); \
+} while (0)
+#define ILVEV_B2_UB(...) ILVEV_B2(v16u8, __VA_ARGS__)
+#define ILVEV_B2_SB(...) ILVEV_B2(v16i8, __VA_ARGS__)
+#define ILVEV_B2_UH(...) ILVEV_B2(v8u16, __VA_ARGS__)
+#define ILVEV_B2_SH(...) ILVEV_B2(v8i16, __VA_ARGS__)
+#define ILVEV_B2_SD(...) ILVEV_B2(v2i64, __VA_ARGS__)
+
+/* Description : Interleave odd byte elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Odd byte elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ */
+#define ILVOD_B2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvod_b((v16i8)in1, (v16i8)in0); \
+ out1 = (RTYPE)__msa_ilvod_b((v16i8)in3, (v16i8)in2); \
+} while (0)
+#define ILVOD_B2_UB(...) ILVOD_B2(v16u8, __VA_ARGS__)
+#define ILVOD_B2_SB(...) ILVOD_B2(v16i8, __VA_ARGS__)
+#define ILVOD_B2_UH(...) ILVOD_B2(v8u16, __VA_ARGS__)
+#define ILVOD_B2_SH(...) ILVOD_B2(v8i16, __VA_ARGS__)
+#define ILVOD_B2_SD(...) ILVOD_B2(v2i64, __VA_ARGS__)
+
+/* Description : Interleave even halfword elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even halfword elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ */
+#define ILVEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvev_h((v8i16)in1, (v8i16)in0); \
+ out1 = (RTYPE)__msa_ilvev_h((v8i16)in3, (v8i16)in2); \
+} while (0)
+#define ILVEV_H2_UB(...) ILVEV_H2(v16u8, __VA_ARGS__)
+#define ILVEV_H2_UH(...) ILVEV_H2(v8u16, __VA_ARGS__)
+#define ILVEV_H2_SH(...) ILVEV_H2(v8i16, __VA_ARGS__)
+#define ILVEV_H2_SW(...) ILVEV_H2(v4i32, __VA_ARGS__)
+
+/* Description : Interleave odd halfword elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Odd halfword elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ */
+#define ILVOD_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvod_h((v8i16)in1, (v8i16)in0); \
+ out1 = (RTYPE)__msa_ilvod_h((v8i16)in3, (v8i16)in2); \
+} while (0)
+#define ILVOD_H2_UB(...) ILVOD_H2(v16u8, __VA_ARGS__)
+#define ILVOD_H2_UH(...) ILVOD_H2(v8u16, __VA_ARGS__)
+#define ILVOD_H2_SH(...) ILVOD_H2(v8i16, __VA_ARGS__)
+#define ILVOD_H2_SW(...) ILVOD_H2(v4i32, __VA_ARGS__)
+
+/* Description : Interleave even word elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even word elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ */
+#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvev_w((v4i32)in1, (v4i32)in0); \
+ out1 = (RTYPE)__msa_ilvev_w((v4i32)in3, (v4i32)in2); \
+} while (0)
+#define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__)
+#define ILVEV_W2_SB(...) ILVEV_W2(v16i8, __VA_ARGS__)
+#define ILVEV_W2_UH(...) ILVEV_W2(v8u16, __VA_ARGS__)
+#define ILVEV_W2_SD(...) ILVEV_W2(v2i64, __VA_ARGS__)
+
+/* Description : Interleave even-odd word elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even word elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ * Odd word elements of 'in2' and 'in3' are interleaved
+ * and written to 'out1'
+ */
+#define ILVEVOD_W2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvev_w((v4i32)in1, (v4i32)in0); \
+ out1 = (RTYPE)__msa_ilvod_w((v4i32)in3, (v4i32)in2); \
+} while (0)
+#define ILVEVOD_W2_UB(...) ILVEVOD_W2(v16u8, __VA_ARGS__)
+#define ILVEVOD_W2_UH(...) ILVEVOD_W2(v8u16, __VA_ARGS__)
+#define ILVEVOD_W2_SH(...) ILVEVOD_W2(v8i16, __VA_ARGS__)
+#define ILVEVOD_W2_SW(...) ILVEVOD_W2(v4i32, __VA_ARGS__)
+
+/* Description : Interleave even-odd half-word elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even half-word elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ * Odd half-word elements of 'in2' and 'in3' are interleaved
+ * and written to 'out1'
+ */
+#define ILVEVOD_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvev_h((v8i16)in1, (v8i16)in0); \
+ out1 = (RTYPE)__msa_ilvod_h((v8i16)in3, (v8i16)in2); \
+} while (0)
+#define ILVEVOD_H2_UB(...) ILVEVOD_H2(v16u8, __VA_ARGS__)
+#define ILVEVOD_H2_UH(...) ILVEVOD_H2(v8u16, __VA_ARGS__)
+#define ILVEVOD_H2_SH(...) ILVEVOD_H2(v8i16, __VA_ARGS__)
+#define ILVEVOD_H2_SW(...) ILVEVOD_H2(v4i32, __VA_ARGS__)
+
+/* Description : Interleave even double word elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even double word elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'
+ */
+#define ILVEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvev_d((v2i64)in1, (v2i64)in0); \
+ out1 = (RTYPE)__msa_ilvev_d((v2i64)in3, (v2i64)in2); \
+} while (0)
+#define ILVEV_D2_UB(...) ILVEV_D2(v16u8, __VA_ARGS__)
+#define ILVEV_D2_SB(...) ILVEV_D2(v16i8, __VA_ARGS__)
+#define ILVEV_D2_SW(...) ILVEV_D2(v4i32, __VA_ARGS__)
+#define ILVEV_D2_SD(...) ILVEV_D2(v2i64, __VA_ARGS__)
+
+/* Description : Interleave left half of byte elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Left half of byte elements of 'in0' and 'in1' are interleaved
+ * and written to 'out0'.
+ */
+#define ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \
+ out1 = (RTYPE)__msa_ilvl_b((v16i8)in2, (v16i8)in3); \
+} while (0)
+#define ILVL_B2_UB(...) ILVL_B2(v16u8, __VA_ARGS__)
+#define ILVL_B2_SB(...) ILVL_B2(v16i8, __VA_ARGS__)
+#define ILVL_B2_UH(...) ILVL_B2(v8u16, __VA_ARGS__)
+#define ILVL_B2_SH(...) ILVL_B2(v8i16, __VA_ARGS__)
+#define ILVL_B2_SW(...) ILVL_B2(v4i32, __VA_ARGS__)
+
+/* Description : Interleave right half of byte elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Right half of byte elements of 'in0' and 'in1' are interleaved
+ * and written to out0.
+ */
+#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \
+ out1 = (RTYPE)__msa_ilvr_b((v16i8)in2, (v16i8)in3); \
+} while (0)
+#define ILVR_B2_UB(...) ILVR_B2(v16u8, __VA_ARGS__)
+#define ILVR_B2_SB(...) ILVR_B2(v16i8, __VA_ARGS__)
+#define ILVR_B2_UH(...) ILVR_B2(v8u16, __VA_ARGS__)
+#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__)
+#define ILVR_B2_SW(...) ILVR_B2(v4i32, __VA_ARGS__)
+
+#define ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1); \
+ ILVR_B2(RTYPE, in4, in5, in6, in7, out2, out3); \
+} while (0)
+#define ILVR_B4_UB(...) ILVR_B4(v16u8, __VA_ARGS__)
+#define ILVR_B4_SB(...) ILVR_B4(v16i8, __VA_ARGS__)
+#define ILVR_B4_UH(...) ILVR_B4(v8u16, __VA_ARGS__)
+#define ILVR_B4_SH(...) ILVR_B4(v8i16, __VA_ARGS__)
+#define ILVR_B4_SW(...) ILVR_B4(v4i32, __VA_ARGS__)
+
+/* Description : Interleave right half of halfword elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Right half of halfword elements of 'in0' and 'in1' are
+ * interleaved and written to 'out0'.
+ */
+#define ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvr_h((v8i16)in0, (v8i16)in1); \
+ out1 = (RTYPE)__msa_ilvr_h((v8i16)in2, (v8i16)in3); \
+} while (0)
+#define ILVR_H2_UB(...) ILVR_H2(v16u8, __VA_ARGS__)
+#define ILVR_H2_SH(...) ILVR_H2(v8i16, __VA_ARGS__)
+#define ILVR_H2_SW(...) ILVR_H2(v4i32, __VA_ARGS__)
+
+#define ILVR_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1); \
+ ILVR_H2(RTYPE, in4, in5, in6, in7, out2, out3); \
+} while (0)
+#define ILVR_H4_UB(...) ILVR_H4(v16u8, __VA_ARGS__)
+#define ILVR_H4_SH(...) ILVR_H4(v8i16, __VA_ARGS__)
+#define ILVR_H4_SW(...) ILVR_H4(v4i32, __VA_ARGS__)
+
+/* Description : Interleave right half of double word elements from vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Right half of double word elements of 'in0' and 'in1' are
+ * interleaved and written to 'out0'.
+ */
+#define ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvr_d((v2i64)in0, (v2i64)in1); \
+ out1 = (RTYPE)__msa_ilvr_d((v2i64)in2, (v2i64)in3); \
+} while (0)
+#define ILVR_D2_UB(...) ILVR_D2(v16u8, __VA_ARGS__)
+#define ILVR_D2_SB(...) ILVR_D2(v16i8, __VA_ARGS__)
+#define ILVR_D2_SH(...) ILVR_D2(v8i16, __VA_ARGS__)
+
+#define ILVR_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1); \
+ ILVR_D2(RTYPE, in4, in5, in6, in7, out2, out3); \
+} while (0)
+#define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__)
+#define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__)
+
+/* Description : Interleave both left and right half of input vectors
+ * Arguments : Inputs - in0, in1
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Right half of byte elements from 'in0' and 'in1' are
+ * interleaved and written to 'out0'
+ */
+#define ILVRL_B2(RTYPE, in0, in1, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \
+ out1 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \
+} while (0)
+#define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__)
+#define ILVRL_B2_SB(...) ILVRL_B2(v16i8, __VA_ARGS__)
+#define ILVRL_B2_UH(...) ILVRL_B2(v8u16, __VA_ARGS__)
+#define ILVRL_B2_SH(...) ILVRL_B2(v8i16, __VA_ARGS__)
+#define ILVRL_B2_SW(...) ILVRL_B2(v4i32, __VA_ARGS__)
+
+#define ILVRL_H2(RTYPE, in0, in1, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvr_h((v8i16)in0, (v8i16)in1); \
+ out1 = (RTYPE)__msa_ilvl_h((v8i16)in0, (v8i16)in1); \
+} while (0)
+#define ILVRL_H2_UB(...) ILVRL_H2(v16u8, __VA_ARGS__)
+#define ILVRL_H2_SB(...) ILVRL_H2(v16i8, __VA_ARGS__)
+#define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__)
+#define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__)
+#define ILVRL_H2_UW(...) ILVRL_H2(v4u32, __VA_ARGS__)
+
+#define ILVRL_W2(RTYPE, in0, in1, out0, out1) do { \
+ out0 = (RTYPE)__msa_ilvr_w((v4i32)in0, (v4i32)in1); \
+ out1 = (RTYPE)__msa_ilvl_w((v4i32)in0, (v4i32)in1); \
+} while (0)
+#define ILVRL_W2_UB(...) ILVRL_W2(v16u8, __VA_ARGS__)
+#define ILVRL_W2_SH(...) ILVRL_W2(v8i16, __VA_ARGS__)
+#define ILVRL_W2_SW(...) ILVRL_W2(v4i32, __VA_ARGS__)
+#define ILVRL_W2_UW(...) ILVRL_W2(v4u32, __VA_ARGS__)
+
+/* Description : Pack even byte elements of vector pairs
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even byte elements of 'in0' are copied to the left half of
+ * 'out0' & even byte elements of 'in1' are copied to the right
+ * half of 'out0'.
+ */
+#define PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_pckev_b((v16i8)in0, (v16i8)in1); \
+ out1 = (RTYPE)__msa_pckev_b((v16i8)in2, (v16i8)in3); \
+} while (0)
+#define PCKEV_B2_SB(...) PCKEV_B2(v16i8, __VA_ARGS__)
+#define PCKEV_B2_UB(...) PCKEV_B2(v16u8, __VA_ARGS__)
+#define PCKEV_B2_SH(...) PCKEV_B2(v8i16, __VA_ARGS__)
+#define PCKEV_B2_SW(...) PCKEV_B2(v4i32, __VA_ARGS__)
+
+#define PCKEV_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1); \
+ PCKEV_B2(RTYPE, in4, in5, in6, in7, out2, out3); \
+} while (0)
+#define PCKEV_B4_SB(...) PCKEV_B4(v16i8, __VA_ARGS__)
+#define PCKEV_B4_UB(...) PCKEV_B4(v16u8, __VA_ARGS__)
+#define PCKEV_B4_SH(...) PCKEV_B4(v8i16, __VA_ARGS__)
+#define PCKEV_B4_SW(...) PCKEV_B4(v4i32, __VA_ARGS__)
+
+/* Description : Pack even halfword elements of vector pairs
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even halfword elements of 'in0' are copied to the left half of
+ * 'out0' & even halfword elements of 'in1' are copied to the
+ * right half of 'out0'.
+ */
+#define PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_pckev_h((v8i16)in0, (v8i16)in1); \
+ out1 = (RTYPE)__msa_pckev_h((v8i16)in2, (v8i16)in3); \
+} while (0)
+#define PCKEV_H2_UH(...) PCKEV_H2(v8u16, __VA_ARGS__)
+#define PCKEV_H2_SH(...) PCKEV_H2(v8i16, __VA_ARGS__)
+#define PCKEV_H2_SW(...) PCKEV_H2(v4i32, __VA_ARGS__)
+#define PCKEV_H2_UW(...) PCKEV_H2(v4u32, __VA_ARGS__)
+
+/* Description : Pack even word elements of vector pairs
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Even word elements of 'in0' are copied to the left half of
+ * 'out0' & even word elements of 'in1' are copied to the
+ * right half of 'out0'.
+ */
+#define PCKEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_pckev_w((v4i32)in0, (v4i32)in1); \
+ out1 = (RTYPE)__msa_pckev_w((v4i32)in2, (v4i32)in3); \
+} while (0)
+#define PCKEV_W2_UH(...) PCKEV_W2(v8u16, __VA_ARGS__)
+#define PCKEV_W2_SH(...) PCKEV_W2(v8i16, __VA_ARGS__)
+#define PCKEV_W2_SW(...) PCKEV_W2(v4i32, __VA_ARGS__)
+#define PCKEV_W2_UW(...) PCKEV_W2(v4u32, __VA_ARGS__)
+
+/* Description : Pack odd halfword elements of vector pairs
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Odd halfword elements of 'in0' are copied to the left half of
+ * 'out0' & odd halfword elements of 'in1' are copied to the
+ * right half of 'out0'.
+ */
+#define PCKOD_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_pckod_h((v8i16)in0, (v8i16)in1); \
+ out1 = (RTYPE)__msa_pckod_h((v8i16)in2, (v8i16)in3); \
+} while (0)
+#define PCKOD_H2_UH(...) PCKOD_H2(v8u16, __VA_ARGS__)
+#define PCKOD_H2_SH(...) PCKOD_H2(v8i16, __VA_ARGS__)
+#define PCKOD_H2_SW(...) PCKOD_H2(v4i32, __VA_ARGS__)
+#define PCKOD_H2_UW(...) PCKOD_H2(v4u32, __VA_ARGS__)
+
+/* Description : Arithmetic immediate shift right all elements of word vector
+ * Arguments : Inputs - in0, in1, shift
+ * Outputs - in place operation
+ * Return Type - as per input vector RTYPE
+ * Details : Each element of vector 'in0' is right shifted by 'shift' and
+ * the result is written in-place. 'shift' is a GP variable.
+ */
+#define SRAI_W2(RTYPE, in0, in1, shift_val) do { \
+ in0 = (RTYPE)SRAI_W(in0, shift_val); \
+ in1 = (RTYPE)SRAI_W(in1, shift_val); \
+} while (0)
+#define SRAI_W2_SW(...) SRAI_W2(v4i32, __VA_ARGS__)
+#define SRAI_W2_UW(...) SRAI_W2(v4u32, __VA_ARGS__)
+
+#define SRAI_W4(RTYPE, in0, in1, in2, in3, shift_val) do { \
+ SRAI_W2(RTYPE, in0, in1, shift_val); \
+ SRAI_W2(RTYPE, in2, in3, shift_val); \
+} while (0)
+#define SRAI_W4_SW(...) SRAI_W4(v4i32, __VA_ARGS__)
+#define SRAI_W4_UW(...) SRAI_W4(v4u32, __VA_ARGS__)
+
+/* Description : Arithmetic shift right all elements of half-word vector
+ * Arguments : Inputs - in0, in1, shift
+ * Outputs - in place operation
+ * Return Type - as per input vector RTYPE
+ * Details : Each element of vector 'in0' is right shifted by 'shift' and
+ * the result is written in-place. 'shift' is a GP variable.
+ */
+#define SRAI_H2(RTYPE, in0, in1, shift_val) do { \
+ in0 = (RTYPE)SRAI_H(in0, shift_val); \
+ in1 = (RTYPE)SRAI_H(in1, shift_val); \
+} while (0)
+#define SRAI_H2_SH(...) SRAI_H2(v8i16, __VA_ARGS__)
+#define SRAI_H2_UH(...) SRAI_H2(v8u16, __VA_ARGS__)
+
+/* Description : Arithmetic rounded shift right all elements of word vector
+ * Arguments : Inputs - in0, in1, shift
+ * Outputs - in place operation
+ * Return Type - as per input vector RTYPE
+ * Details : Each element of vector 'in0' is right shifted by 'shift' and
+ * the result is written in-place. 'shift' is a GP variable.
+ */
+#define SRARI_W2(RTYPE, in0, in1, shift) do { \
+ in0 = (RTYPE)__msa_srari_w((v4i32)in0, shift); \
+ in1 = (RTYPE)__msa_srari_w((v4i32)in1, shift); \
+} while (0)
+#define SRARI_W2_SW(...) SRARI_W2(v4i32, __VA_ARGS__)
+
+#define SRARI_W4(RTYPE, in0, in1, in2, in3, shift) do { \
+ SRARI_W2(RTYPE, in0, in1, shift); \
+ SRARI_W2(RTYPE, in2, in3, shift); \
+} while (0)
+#define SRARI_W4_SH(...) SRARI_W4(v8i16, __VA_ARGS__)
+#define SRARI_W4_UW(...) SRARI_W4(v4u32, __VA_ARGS__)
+#define SRARI_W4_SW(...) SRARI_W4(v4i32, __VA_ARGS__)
+
+/* Description : Shift right arithmetic rounded double words
+ * Arguments : Inputs - in0, in1, shift
+ * Outputs - in place operation
+ * Return Type - as per RTYPE
+ * Details : Each element of vector 'in0' is shifted right arithmetically by
+ * the number of bits in the corresponding element in the vector
+ * 'shift'. The last discarded bit is added to shifted value for
+ * rounding and the result is written in-place.
+ * 'shift' is a vector.
+ */
+#define SRAR_D2(RTYPE, in0, in1, shift) do { \
+ in0 = (RTYPE)__msa_srar_d((v2i64)in0, (v2i64)shift); \
+ in1 = (RTYPE)__msa_srar_d((v2i64)in1, (v2i64)shift); \
+} while (0)
+#define SRAR_D2_SW(...) SRAR_D2(v4i32, __VA_ARGS__)
+#define SRAR_D2_SD(...) SRAR_D2(v2i64, __VA_ARGS__)
+#define SRAR_D2_UD(...) SRAR_D2(v2u64, __VA_ARGS__)
+
+#define SRAR_D4(RTYPE, in0, in1, in2, in3, shift) do { \
+ SRAR_D2(RTYPE, in0, in1, shift); \
+ SRAR_D2(RTYPE, in2, in3, shift); \
+} while (0)
+#define SRAR_D4_SD(...) SRAR_D4(v2i64, __VA_ARGS__)
+#define SRAR_D4_UD(...) SRAR_D4(v2u64, __VA_ARGS__)
+
+/* Description : Addition of 2 pairs of half-word vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Details : Each element in 'in0' is added to 'in1' and result is written
+ * to 'out0'.
+ */
+#define ADDVI_H2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)ADDVI_H(in0, in1); \
+ out1 = (RTYPE)ADDVI_H(in2, in3); \
+} while (0)
+#define ADDVI_H2_SH(...) ADDVI_H2(v8i16, __VA_ARGS__)
+#define ADDVI_H2_UH(...) ADDVI_H2(v8u16, __VA_ARGS__)
+
+/* Description : Addition of 2 pairs of word vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Details : Each element in 'in0' is added to 'in1' and result is written
+ * to 'out0'.
+ */
+#define ADDVI_W2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)ADDVI_W(in0, in1); \
+ out1 = (RTYPE)ADDVI_W(in2, in3); \
+} while (0)
+#define ADDVI_W2_SW(...) ADDVI_W2(v4i32, __VA_ARGS__)
+
+/* Description : Fill 2 pairs of word vectors with GP registers
+ * Arguments : Inputs - in0, in1
+ * Outputs - out0, out1
+ * Details : GP register in0 is replicated in each word element of out0
+ * GP register in1 is replicated in each word element of out1
+ */
+#define FILL_W2(RTYPE, in0, in1, out0, out1) do { \
+ out0 = (RTYPE)__msa_fill_w(in0); \
+ out1 = (RTYPE)__msa_fill_w(in1); \
+} while (0)
+#define FILL_W2_SW(...) FILL_W2(v4i32, __VA_ARGS__)
+
+/* Description : Addition of 2 pairs of vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Details : Each element in 'in0' is added to 'in1' and result is written
+ * to 'out0'.
+ */
+#define ADD2(in0, in1, in2, in3, out0, out1) do { \
+ out0 = in0 + in1; \
+ out1 = in2 + in3; \
+} while (0)
+
+#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ ADD2(in0, in1, in2, in3, out0, out1); \
+ ADD2(in4, in5, in6, in7, out2, out3); \
+} while (0)
+
+/* Description : Subtraction of 2 pairs of vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Details : Each element in 'in1' is subtracted from 'in0' and result is
+ * written to 'out0'.
+ */
+#define SUB2(in0, in1, in2, in3, out0, out1) do { \
+ out0 = in0 - in1; \
+ out1 = in2 - in3; \
+} while (0)
+
+#define SUB3(in0, in1, in2, in3, in4, in5, out0, out1, out2) do { \
+ out0 = in0 - in1; \
+ out1 = in2 - in3; \
+ out2 = in4 - in5; \
+} while (0)
+
+#define SUB4(in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ out0 = in0 - in1; \
+ out1 = in2 - in3; \
+ out2 = in4 - in5; \
+ out3 = in6 - in7; \
+} while (0)
+
+/* Description : Addition - Subtraction of input vectors
+ * Arguments : Inputs - in0, in1
+ * Outputs - out0, out1
+ * Details : Each element in 'in1' is added to 'in0' and result is
+ * written to 'out0'.
+ * Each element in 'in1' is subtracted from 'in0' and result is
+ * written to 'out1'.
+ */
+#define ADDSUB2(in0, in1, out0, out1) do { \
+ out0 = in0 + in1; \
+ out1 = in0 - in1; \
+} while (0)
+
+/* Description : Multiplication of pairs of vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1
+ * Details : Each element from 'in0' is multiplied with elements from 'in1'
+ * and the result is written to 'out0'
+ */
+#define MUL2(in0, in1, in2, in3, out0, out1) do { \
+ out0 = in0 * in1; \
+ out1 = in2 * in3; \
+} while (0)
+
+#define MUL4(in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) do { \
+ MUL2(in0, in1, in2, in3, out0, out1); \
+ MUL2(in4, in5, in6, in7, out2, out3); \
+} while (0)
+
+/* Description : Sign extend halfword elements from right half of the vector
+ * Arguments : Input - in (halfword vector)
+ * Output - out (sign extended word vector)
+ * Return Type - signed word
+ * Details : Sign bit of halfword elements from input vector 'in' is
+ * extracted and interleaved with same vector 'in0' to generate
+ * 4 word elements keeping sign intact
+ */
+#define UNPCK_R_SH_SW(in, out) do { \
+ const v8i16 sign_m = __msa_clti_s_h((v8i16)in, 0); \
+ out = (v4i32)__msa_ilvr_h(sign_m, (v8i16)in); \
+} while (0)
+
+/* Description : Sign extend halfword elements from input vector and return
+ * the result in pair of vectors
+ * Arguments : Input - in (halfword vector)
+ * Outputs - out0, out1 (sign extended word vectors)
+ * Return Type - signed word
+ * Details : Sign bit of halfword elements from input vector 'in' is
+ * extracted and interleaved right with same vector 'in0' to
+ * generate 4 signed word elements in 'out0'
+ * Then interleaved left with same vector 'in0' to
+ * generate 4 signed word elements in 'out1'
+ */
+#define UNPCK_SH_SW(in, out0, out1) do { \
+ const v8i16 tmp_m = __msa_clti_s_h((v8i16)in, 0); \
+ ILVRL_H2_SW(tmp_m, in, out0, out1); \
+} while (0)
+
+/* Description : Butterfly of 4 input vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1, out2, out3
+ * Details : Butterfly operation
+ */
+#define BUTTERFLY_4(in0, in1, in2, in3, out0, out1, out2, out3) do { \
+ out0 = in0 + in3; \
+ out1 = in1 + in2; \
+ out2 = in1 - in2; \
+ out3 = in0 - in3; \
+} while (0)
+
+/* Description : Transpose 16x4 block into 4x16 with byte elements in vectors
+ * Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7,
+ * in8, in9, in10, in11, in12, in13, in14, in15
+ * Outputs - out0, out1, out2, out3
+ * Return Type - unsigned byte
+ */
+#define TRANSPOSE16x4_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, \
+ in8, in9, in10, in11, in12, in13, in14, in15, \
+ out0, out1, out2, out3) do { \
+ v2i64 tmp0_m, tmp1_m, tmp2_m, tmp3_m, tmp4_m, tmp5_m; \
+ ILVEV_W2_SD(in0, in4, in8, in12, tmp2_m, tmp3_m); \
+ ILVEV_W2_SD(in1, in5, in9, in13, tmp0_m, tmp1_m); \
+ ILVEV_D2_UB(tmp2_m, tmp3_m, tmp0_m, tmp1_m, out1, out3); \
+ ILVEV_W2_SD(in2, in6, in10, in14, tmp4_m, tmp5_m); \
+ ILVEV_W2_SD(in3, in7, in11, in15, tmp0_m, tmp1_m); \
+ ILVEV_D2_SD(tmp4_m, tmp5_m, tmp0_m, tmp1_m, tmp2_m, tmp3_m); \
+ ILVEV_B2_SD(out1, out3, tmp2_m, tmp3_m, tmp0_m, tmp1_m); \
+ ILVEVOD_H2_UB(tmp0_m, tmp1_m, tmp0_m, tmp1_m, out0, out2); \
+ ILVOD_B2_SD(out1, out3, tmp2_m, tmp3_m, tmp0_m, tmp1_m); \
+ ILVEVOD_H2_UB(tmp0_m, tmp1_m, tmp0_m, tmp1_m, out1, out3); \
+} while (0)
+
+/* Description : Transpose 16x8 block into 8x16 with byte elements in vectors
+ * Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7,
+ * in8, in9, in10, in11, in12, in13, in14, in15
+ * Outputs - out0, out1, out2, out3, out4, out5, out6, out7
+ * Return Type - unsigned byte
+ */
+#define TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, \
+ in8, in9, in10, in11, in12, in13, in14, in15, \
+ out0, out1, out2, out3, out4, out5, \
+ out6, out7) do { \
+ v8i16 tmp0_m, tmp1_m, tmp4_m, tmp5_m, tmp6_m, tmp7_m; \
+ v4i32 tmp2_m, tmp3_m; \
+ ILVEV_D2_UB(in0, in8, in1, in9, out7, out6); \
+ ILVEV_D2_UB(in2, in10, in3, in11, out5, out4); \
+ ILVEV_D2_UB(in4, in12, in5, in13, out3, out2); \
+ ILVEV_D2_UB(in6, in14, in7, in15, out1, out0); \
+ ILVEV_B2_SH(out7, out6, out5, out4, tmp0_m, tmp1_m); \
+ ILVOD_B2_SH(out7, out6, out5, out4, tmp4_m, tmp5_m); \
+ ILVEV_B2_UB(out3, out2, out1, out0, out5, out7); \
+ ILVOD_B2_SH(out3, out2, out1, out0, tmp6_m, tmp7_m); \
+ ILVEV_H2_SW(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m); \
+ ILVEVOD_W2_UB(tmp2_m, tmp3_m, tmp2_m, tmp3_m, out0, out4); \
+ ILVOD_H2_SW(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m); \
+ ILVEVOD_W2_UB(tmp2_m, tmp3_m, tmp2_m, tmp3_m, out2, out6); \
+ ILVEV_H2_SW(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m); \
+ ILVEVOD_W2_UB(tmp2_m, tmp3_m, tmp2_m, tmp3_m, out1, out5); \
+ ILVOD_H2_SW(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m); \
+ ILVEVOD_W2_UB(tmp2_m, tmp3_m, tmp2_m, tmp3_m, out3, out7); \
+} while (0)
+
+/* Description : Transpose 4x4 block with word elements in vectors
+ * Arguments : Inputs - in0, in1, in2, in3
+ * Outputs - out0, out1, out2, out3
+ * Return Type - as per RTYPE
+ */
+#define TRANSPOSE4x4_W(RTYPE, in0, in1, in2, in3, \
+ out0, out1, out2, out3) do { \
+ v4i32 s0_m, s1_m, s2_m, s3_m; \
+ ILVRL_W2_SW(in1, in0, s0_m, s1_m); \
+ ILVRL_W2_SW(in3, in2, s2_m, s3_m); \
+ out0 = (RTYPE)__msa_ilvr_d((v2i64)s2_m, (v2i64)s0_m); \
+ out1 = (RTYPE)__msa_ilvl_d((v2i64)s2_m, (v2i64)s0_m); \
+ out2 = (RTYPE)__msa_ilvr_d((v2i64)s3_m, (v2i64)s1_m); \
+ out3 = (RTYPE)__msa_ilvl_d((v2i64)s3_m, (v2i64)s1_m); \
+} while (0)
+#define TRANSPOSE4x4_SW_SW(...) TRANSPOSE4x4_W(v4i32, __VA_ARGS__)
+
+/* Description : Add block 4x4
+ * Arguments : Inputs - in0, in1, in2, in3, pdst, stride
+ * Details : Least significant 4 bytes from each input vector are added to
+ * the destination bytes, clipped between 0-255 and stored.
+ */
+#define ADDBLK_ST4x4_UB(in0, in1, in2, in3, pdst, stride) do { \
+ uint32_t src0_m, src1_m, src2_m, src3_m; \
+ v8i16 inp0_m, inp1_m, res0_m, res1_m; \
+ v16i8 dst0_m = { 0 }; \
+ v16i8 dst1_m = { 0 }; \
+ const v16i8 zero_m = { 0 }; \
+ ILVR_D2_SH(in1, in0, in3, in2, inp0_m, inp1_m); \
+ LW4(pdst, stride, src0_m, src1_m, src2_m, src3_m); \
+ INSERT_W2_SB(src0_m, src1_m, dst0_m); \
+ INSERT_W2_SB(src2_m, src3_m, dst1_m); \
+ ILVR_B2_SH(zero_m, dst0_m, zero_m, dst1_m, res0_m, res1_m); \
+ ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m); \
+ CLIP_SH2_0_255(res0_m, res1_m); \
+ PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m); \
+ ST4x4_UB(dst0_m, dst1_m, 0, 1, 0, 1, pdst, stride); \
+} while (0)
+
+/* Description : Pack even byte elements, extract 0 & 2 index words from pair
+ * of results and store 4 words in destination memory as per
+ * stride
+ * Arguments : Inputs - in0, in1, in2, in3, pdst, stride
+ */
+#define PCKEV_ST4x4_UB(in0, in1, in2, in3, pdst, stride) do { \
+ v16i8 tmp0_m, tmp1_m; \
+ PCKEV_B2_SB(in1, in0, in3, in2, tmp0_m, tmp1_m); \
+ ST4x4_UB(tmp0_m, tmp1_m, 0, 2, 0, 2, pdst, stride); \
+} while (0)
+
+/* Description : average with rounding (in0 + in1 + 1) / 2.
+ * Arguments : Inputs - in0, in1, in2, in3,
+ * Outputs - out0, out1
+ * Return Type - as per RTYPE
+ * Details : Each unsigned byte element from 'in0' vector is added with
+ * each unsigned byte element from 'in1' vector. Then the average
+ * with rounding is calculated and written to 'out0'
+ */
+#define AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1) do { \
+ out0 = (RTYPE)__msa_aver_u_b((v16u8)in0, (v16u8)in1); \
+ out1 = (RTYPE)__msa_aver_u_b((v16u8)in2, (v16u8)in3); \
+} while (0)
+#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
+
+#endif /* WEBP_DSP_MSA_MACRO_H_ */
diff --git a/media/libwebp/dsp/neon.h b/media/libwebp/dsp/neon.h
new file mode 100644
index 000000000..3b548a685
--- /dev/null
+++ b/media/libwebp/dsp/neon.h
@@ -0,0 +1,100 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// NEON common code.
+
+#ifndef WEBP_DSP_NEON_H_
+#define WEBP_DSP_NEON_H_
+
+#include <arm_neon.h>
+
+#include "./dsp.h"
+
+// Right now, some intrinsics functions seem slower, so we disable them
+// everywhere except aarch64 where the inline assembly is incompatible.
+#if defined(__aarch64__)
+#define WEBP_USE_INTRINSICS // use intrinsics when possible
+#endif
+
+#define INIT_VECTOR2(v, a, b) do { \
+ v.val[0] = a; \
+ v.val[1] = b; \
+} while (0)
+
+#define INIT_VECTOR3(v, a, b, c) do { \
+ v.val[0] = a; \
+ v.val[1] = b; \
+ v.val[2] = c; \
+} while (0)
+
+#define INIT_VECTOR4(v, a, b, c, d) do { \
+ v.val[0] = a; \
+ v.val[1] = b; \
+ v.val[2] = c; \
+ v.val[3] = d; \
+} while (0)
+
+// if using intrinsics, this flag avoids some functions that make gcc-4.6.3
+// crash ("internal compiler error: in immed_double_const, at emit-rtl.").
+// (probably similar to gcc.gnu.org/bugzilla/show_bug.cgi?id=48183)
+#if !(LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
+#define WORK_AROUND_GCC
+#endif
+
+static WEBP_INLINE int32x4x4_t Transpose4x4(const int32x4x4_t rows) {
+ uint64x2x2_t row01, row23;
+
+ row01.val[0] = vreinterpretq_u64_s32(rows.val[0]);
+ row01.val[1] = vreinterpretq_u64_s32(rows.val[1]);
+ row23.val[0] = vreinterpretq_u64_s32(rows.val[2]);
+ row23.val[1] = vreinterpretq_u64_s32(rows.val[3]);
+ // Transpose 64-bit values (there's no vswp equivalent)
+ {
+ const uint64x1_t row0h = vget_high_u64(row01.val[0]);
+ const uint64x1_t row2l = vget_low_u64(row23.val[0]);
+ const uint64x1_t row1h = vget_high_u64(row01.val[1]);
+ const uint64x1_t row3l = vget_low_u64(row23.val[1]);
+ row01.val[0] = vcombine_u64(vget_low_u64(row01.val[0]), row2l);
+ row23.val[0] = vcombine_u64(row0h, vget_high_u64(row23.val[0]));
+ row01.val[1] = vcombine_u64(vget_low_u64(row01.val[1]), row3l);
+ row23.val[1] = vcombine_u64(row1h, vget_high_u64(row23.val[1]));
+ }
+ {
+ const int32x4x2_t out01 = vtrnq_s32(vreinterpretq_s32_u64(row01.val[0]),
+ vreinterpretq_s32_u64(row01.val[1]));
+ const int32x4x2_t out23 = vtrnq_s32(vreinterpretq_s32_u64(row23.val[0]),
+ vreinterpretq_s32_u64(row23.val[1]));
+ int32x4x4_t out;
+ out.val[0] = out01.val[0];
+ out.val[1] = out01.val[1];
+ out.val[2] = out23.val[0];
+ out.val[3] = out23.val[1];
+ return out;
+ }
+}
+
+#if 0 // Useful debug macro.
+#include <stdio.h>
+#define PRINT_REG(REG, SIZE) do { \
+ int i; \
+ printf("%s \t[%d]: 0x", #REG, SIZE); \
+ if (SIZE == 8) { \
+ uint8_t _tmp[8]; \
+ vst1_u8(_tmp, (REG)); \
+ for (i = 0; i < 8; ++i) printf("%.2x ", _tmp[i]); \
+ } else if (SIZE == 16) { \
+ uint16_t _tmp[4]; \
+ vst1_u16(_tmp, (REG)); \
+ for (i = 0; i < 4; ++i) printf("%.4x ", _tmp[i]); \
+ } \
+ printf("\n"); \
+} while (0)
+#endif
+
+#endif // WEBP_DSP_NEON_H_
diff --git a/media/libwebp/dsp/rescaler.c b/media/libwebp/dsp/rescaler.c
new file mode 100644
index 000000000..0f5450235
--- /dev/null
+++ b/media/libwebp/dsp/rescaler.c
@@ -0,0 +1,244 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Rescaling functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <assert.h>
+
+#include "./dsp.h"
+#include "../utils/rescaler_utils.h"
+
+//------------------------------------------------------------------------------
+// Implementations of critical functions ImportRow / ExportRow
+
+#define ROUNDER (WEBP_RESCALER_ONE >> 1)
+#define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+
+//------------------------------------------------------------------------------
+// Row import
+
+void WebPRescalerImportRowExpandC(WebPRescaler* const wrk, const uint8_t* src) {
+ const int x_stride = wrk->num_channels;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ int channel;
+ assert(!WebPRescalerInputDone(wrk));
+ assert(wrk->x_expand);
+ for (channel = 0; channel < x_stride; ++channel) {
+ int x_in = channel;
+ int x_out = channel;
+ // simple bilinear interpolation
+ int accum = wrk->x_add;
+ int left = src[x_in];
+ int right = (wrk->src_width > 1) ? src[x_in + x_stride] : left;
+ x_in += x_stride;
+ while (1) {
+ wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
+ x_out += x_stride;
+ if (x_out >= x_out_max) break;
+ accum -= wrk->x_sub;
+ if (accum < 0) {
+ left = right;
+ x_in += x_stride;
+ assert(x_in < wrk->src_width * x_stride);
+ right = src[x_in];
+ accum += wrk->x_add;
+ }
+ }
+ assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0);
+ }
+}
+
+void WebPRescalerImportRowShrinkC(WebPRescaler* const wrk, const uint8_t* src) {
+ const int x_stride = wrk->num_channels;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ int channel;
+ assert(!WebPRescalerInputDone(wrk));
+ assert(!wrk->x_expand);
+ for (channel = 0; channel < x_stride; ++channel) {
+ int x_in = channel;
+ int x_out = channel;
+ uint32_t sum = 0;
+ int accum = 0;
+ while (x_out < x_out_max) {
+ uint32_t base = 0;
+ accum += wrk->x_add;
+ while (accum > 0) {
+ accum -= wrk->x_sub;
+ assert(x_in < wrk->src_width * x_stride);
+ base = src[x_in];
+ sum += base;
+ x_in += x_stride;
+ }
+ { // Emit next horizontal pixel.
+ const rescaler_t frac = base * (-accum);
+ wrk->frow[x_out] = sum * wrk->x_sub - frac;
+ // fresh fractional start for next pixel
+ sum = (int)MULT_FIX(frac, wrk->fx_scale);
+ }
+ x_out += x_stride;
+ }
+ assert(accum == 0);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Row export
+
+void WebPRescalerExportRowExpandC(WebPRescaler* const wrk) {
+ int x_out;
+ uint8_t* const dst = wrk->dst;
+ rescaler_t* const irow = wrk->irow;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ const rescaler_t* const frow = wrk->frow;
+ assert(!WebPRescalerOutputDone(wrk));
+ assert(wrk->y_accum <= 0);
+ assert(wrk->y_expand);
+ assert(wrk->y_sub != 0);
+ if (wrk->y_accum == 0) {
+ for (x_out = 0; x_out < x_out_max; ++x_out) {
+ const uint32_t J = frow[x_out];
+ const int v = (int)MULT_FIX(J, wrk->fy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ }
+ } else {
+ const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
+ const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B);
+ for (x_out = 0; x_out < x_out_max; ++x_out) {
+ const uint64_t I = (uint64_t)A * frow[x_out]
+ + (uint64_t)B * irow[x_out];
+ const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
+ const int v = (int)MULT_FIX(J, wrk->fy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ }
+ }
+}
+
+void WebPRescalerExportRowShrinkC(WebPRescaler* const wrk) {
+ int x_out;
+ uint8_t* const dst = wrk->dst;
+ rescaler_t* const irow = wrk->irow;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ const rescaler_t* const frow = wrk->frow;
+ const uint32_t yscale = wrk->fy_scale * (-wrk->y_accum);
+ assert(!WebPRescalerOutputDone(wrk));
+ assert(wrk->y_accum <= 0);
+ assert(!wrk->y_expand);
+ if (yscale) {
+ for (x_out = 0; x_out < x_out_max; ++x_out) {
+ const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale);
+ const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ irow[x_out] = frac; // new fractional start
+ }
+ } else {
+ for (x_out = 0; x_out < x_out_max; ++x_out) {
+ const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ irow[x_out] = 0;
+ }
+ }
+}
+
+#undef MULT_FIX
+#undef ROUNDER
+
+//------------------------------------------------------------------------------
+// Main entry calls
+
+void WebPRescalerImportRow(WebPRescaler* const wrk, const uint8_t* src) {
+ assert(!WebPRescalerInputDone(wrk));
+ if (!wrk->x_expand) {
+ WebPRescalerImportRowShrink(wrk, src);
+ } else {
+ WebPRescalerImportRowExpand(wrk, src);
+ }
+}
+
+void WebPRescalerExportRow(WebPRescaler* const wrk) {
+ if (wrk->y_accum <= 0) {
+ assert(!WebPRescalerOutputDone(wrk));
+ if (wrk->y_expand) {
+ WebPRescalerExportRowExpand(wrk);
+ } else if (wrk->fxy_scale) {
+ WebPRescalerExportRowShrink(wrk);
+ } else { // special case
+ int i;
+ assert(wrk->src_height == wrk->dst_height && wrk->x_add == 1);
+ assert(wrk->src_width == 1 && wrk->dst_width <= 2);
+ for (i = 0; i < wrk->num_channels * wrk->dst_width; ++i) {
+ wrk->dst[i] = wrk->irow[i];
+ wrk->irow[i] = 0;
+ }
+ }
+ wrk->y_accum += wrk->y_add;
+ wrk->dst += wrk->dst_stride;
+ ++wrk->dst_y;
+ }
+}
+
+//------------------------------------------------------------------------------
+
+WebPRescalerImportRowFunc WebPRescalerImportRowExpand;
+WebPRescalerImportRowFunc WebPRescalerImportRowShrink;
+
+WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
+WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
+
+extern void WebPRescalerDspInitSSE2(void);
+extern void WebPRescalerDspInitMIPS32(void);
+extern void WebPRescalerDspInitMIPSdspR2(void);
+extern void WebPRescalerDspInitMSA(void);
+extern void WebPRescalerDspInitNEON(void);
+
+static volatile VP8CPUInfo rescaler_last_cpuinfo_used =
+ (VP8CPUInfo)&rescaler_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInit(void) {
+ if (rescaler_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ WebPRescalerImportRowExpand = WebPRescalerImportRowExpandC;
+ WebPRescalerImportRowShrink = WebPRescalerImportRowShrinkC;
+ WebPRescalerExportRowExpand = WebPRescalerExportRowExpandC;
+ WebPRescalerExportRowShrink = WebPRescalerExportRowShrinkC;
+
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ WebPRescalerDspInitSSE2();
+ }
+#endif
+#if defined(WEBP_USE_NEON)
+ if (VP8GetCPUInfo(kNEON)) {
+ WebPRescalerDspInitNEON();
+ }
+#endif
+#if defined(WEBP_USE_MIPS32)
+ if (VP8GetCPUInfo(kMIPS32)) {
+ WebPRescalerDspInitMIPS32();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ WebPRescalerDspInitMIPSdspR2();
+ }
+#endif
+#if defined(WEBP_USE_MSA)
+ if (VP8GetCPUInfo(kMSA)) {
+ WebPRescalerDspInitMSA();
+ }
+#endif
+ }
+ rescaler_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/media/libwebp/dsp/rescaler_neon.c b/media/libwebp/dsp/rescaler_neon.c
new file mode 100644
index 000000000..b2dd8f30c
--- /dev/null
+++ b/media/libwebp/dsp/rescaler_neon.c
@@ -0,0 +1,186 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// NEON version of rescaling functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include <arm_neon.h>
+#include <assert.h>
+#include "./neon.h"
+#include "../utils/rescaler_utils.h"
+
+#define ROUNDER (WEBP_RESCALER_ONE >> 1)
+#define MULT_FIX_C(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+
+#define LOAD_32x4(SRC, DST) const uint32x4_t DST = vld1q_u32((SRC))
+#define LOAD_32x8(SRC, DST0, DST1) \
+ LOAD_32x4(SRC + 0, DST0); \
+ LOAD_32x4(SRC + 4, DST1)
+
+#define STORE_32x8(SRC0, SRC1, DST) do { \
+ vst1q_u32((DST) + 0, SRC0); \
+ vst1q_u32((DST) + 4, SRC1); \
+} while (0);
+
+#if (WEBP_RESCALER_RFIX == 32)
+#define MAKE_HALF_CST(C) vdupq_n_s32((int32_t)((C) >> 1))
+#define MULT_FIX(A, B) /* note: B is actualy scale>>1. See MAKE_HALF_CST */ \
+ vreinterpretq_u32_s32(vqrdmulhq_s32(vreinterpretq_s32_u32((A)), (B)))
+#else
+#error "MULT_FIX/WEBP_RESCALER_RFIX need some more work"
+#endif
+
+static uint32x4_t Interpolate(const rescaler_t* const frow,
+ const rescaler_t* const irow,
+ uint32_t A, uint32_t B) {
+ LOAD_32x4(frow, A0);
+ LOAD_32x4(irow, B0);
+ const uint64x2_t C0 = vmull_n_u32(vget_low_u32(A0), A);
+ const uint64x2_t C1 = vmull_n_u32(vget_high_u32(A0), A);
+ const uint64x2_t D0 = vmlal_n_u32(C0, vget_low_u32(B0), B);
+ const uint64x2_t D1 = vmlal_n_u32(C1, vget_high_u32(B0), B);
+ const uint32x4_t E = vcombine_u32(
+ vrshrn_n_u64(D0, WEBP_RESCALER_RFIX),
+ vrshrn_n_u64(D1, WEBP_RESCALER_RFIX));
+ return E;
+}
+
+static void RescalerExportRowExpand(WebPRescaler* const wrk) {
+ int x_out;
+ uint8_t* const dst = wrk->dst;
+ rescaler_t* const irow = wrk->irow;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ const int max_span = x_out_max & ~7;
+ const rescaler_t* const frow = wrk->frow;
+ const uint32_t fy_scale = wrk->fy_scale;
+ const int32x4_t fy_scale_half = MAKE_HALF_CST(fy_scale);
+ assert(!WebPRescalerOutputDone(wrk));
+ assert(wrk->y_accum <= 0);
+ assert(wrk->y_expand);
+ assert(wrk->y_sub != 0);
+ if (wrk->y_accum == 0) {
+ for (x_out = 0; x_out < max_span; x_out += 8) {
+ LOAD_32x4(frow + x_out + 0, A0);
+ LOAD_32x4(frow + x_out + 4, A1);
+ const uint32x4_t B0 = MULT_FIX(A0, fy_scale_half);
+ const uint32x4_t B1 = MULT_FIX(A1, fy_scale_half);
+ const uint16x4_t C0 = vmovn_u32(B0);
+ const uint16x4_t C1 = vmovn_u32(B1);
+ const uint8x8_t D = vmovn_u16(vcombine_u16(C0, C1));
+ vst1_u8(dst + x_out, D);
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const uint32_t J = frow[x_out];
+ const int v = (int)MULT_FIX_C(J, fy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ }
+ } else {
+ const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
+ const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B);
+ for (x_out = 0; x_out < max_span; x_out += 8) {
+ const uint32x4_t C0 =
+ Interpolate(frow + x_out + 0, irow + x_out + 0, A, B);
+ const uint32x4_t C1 =
+ Interpolate(frow + x_out + 4, irow + x_out + 4, A, B);
+ const uint32x4_t D0 = MULT_FIX(C0, fy_scale_half);
+ const uint32x4_t D1 = MULT_FIX(C1, fy_scale_half);
+ const uint16x4_t E0 = vmovn_u32(D0);
+ const uint16x4_t E1 = vmovn_u32(D1);
+ const uint8x8_t F = vmovn_u16(vcombine_u16(E0, E1));
+ vst1_u8(dst + x_out, F);
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const uint64_t I = (uint64_t)A * frow[x_out]
+ + (uint64_t)B * irow[x_out];
+ const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
+ const int v = (int)MULT_FIX_C(J, fy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ }
+ }
+}
+
+static void RescalerExportRowShrink(WebPRescaler* const wrk) {
+ int x_out;
+ uint8_t* const dst = wrk->dst;
+ rescaler_t* const irow = wrk->irow;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ const int max_span = x_out_max & ~7;
+ const rescaler_t* const frow = wrk->frow;
+ const uint32_t yscale = wrk->fy_scale * (-wrk->y_accum);
+ const uint32_t fxy_scale = wrk->fxy_scale;
+ const uint32x4_t zero = vdupq_n_u32(0);
+ const int32x4_t yscale_half = MAKE_HALF_CST(yscale);
+ const int32x4_t fxy_scale_half = MAKE_HALF_CST(fxy_scale);
+ assert(!WebPRescalerOutputDone(wrk));
+ assert(wrk->y_accum <= 0);
+ assert(!wrk->y_expand);
+ if (yscale) {
+ for (x_out = 0; x_out < max_span; x_out += 8) {
+ LOAD_32x8(frow + x_out, in0, in1);
+ LOAD_32x8(irow + x_out, in2, in3);
+ const uint32x4_t A0 = MULT_FIX(in0, yscale_half);
+ const uint32x4_t A1 = MULT_FIX(in1, yscale_half);
+ const uint32x4_t B0 = vqsubq_u32(in2, A0);
+ const uint32x4_t B1 = vqsubq_u32(in3, A1);
+ const uint32x4_t C0 = MULT_FIX(B0, fxy_scale_half);
+ const uint32x4_t C1 = MULT_FIX(B1, fxy_scale_half);
+ const uint16x4_t D0 = vmovn_u32(C0);
+ const uint16x4_t D1 = vmovn_u32(C1);
+ const uint8x8_t E = vmovn_u16(vcombine_u16(D0, D1));
+ vst1_u8(dst + x_out, E);
+ STORE_32x8(A0, A1, irow + x_out);
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const uint32_t frac = (uint32_t)MULT_FIX_C(frow[x_out], yscale);
+ const int v = (int)MULT_FIX_C(irow[x_out] - frac, wrk->fxy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ irow[x_out] = frac; // new fractional start
+ }
+ } else {
+ for (x_out = 0; x_out < max_span; x_out += 8) {
+ LOAD_32x8(irow + x_out, in0, in1);
+ const uint32x4_t A0 = MULT_FIX(in0, fxy_scale_half);
+ const uint32x4_t A1 = MULT_FIX(in1, fxy_scale_half);
+ const uint16x4_t B0 = vmovn_u32(A0);
+ const uint16x4_t B1 = vmovn_u32(A1);
+ const uint8x8_t C = vmovn_u16(vcombine_u16(B0, B1));
+ vst1_u8(dst + x_out, C);
+ STORE_32x8(zero, zero, irow + x_out);
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const int v = (int)MULT_FIX_C(irow[x_out], fxy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ irow[x_out] = 0;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+extern void WebPRescalerDspInitNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitNEON(void) {
+ WebPRescalerExportRowExpand = RescalerExportRowExpand;
+ WebPRescalerExportRowShrink = RescalerExportRowShrink;
+}
+
+#else // !WEBP_USE_NEON
+
+WEBP_DSP_INIT_STUB(WebPRescalerDspInitNEON)
+
+#endif // WEBP_USE_NEON
diff --git a/media/libwebp/dsp/rescaler_sse2.c b/media/libwebp/dsp/rescaler_sse2.c
new file mode 100644
index 000000000..8271c22e0
--- /dev/null
+++ b/media/libwebp/dsp/rescaler_sse2.c
@@ -0,0 +1,375 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 Rescaling functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <emmintrin.h>
+
+#include <assert.h>
+#include "../utils/rescaler_utils.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// Implementations of critical functions ImportRow / ExportRow
+
+#define ROUNDER (WEBP_RESCALER_ONE >> 1)
+#define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
+
+// input: 8 bytes ABCDEFGH -> output: A0E0B0F0C0G0D0H0
+static void LoadTwoPixels(const uint8_t* const src, __m128i* out) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i A = _mm_loadl_epi64((const __m128i*)(src)); // ABCDEFGH
+ const __m128i B = _mm_unpacklo_epi8(A, zero); // A0B0C0D0E0F0G0H0
+ const __m128i C = _mm_srli_si128(B, 8); // E0F0G0H0
+ *out = _mm_unpacklo_epi16(B, C);
+}
+
+// input: 8 bytes ABCDEFGH -> output: A0B0C0D0E0F0G0H0
+static void LoadHeightPixels(const uint8_t* const src, __m128i* out) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i A = _mm_loadl_epi64((const __m128i*)(src)); // ABCDEFGH
+ *out = _mm_unpacklo_epi8(A, zero);
+}
+
+static void RescalerImportRowExpandSSE2(WebPRescaler* const wrk,
+ const uint8_t* src) {
+ rescaler_t* frow = wrk->frow;
+ const rescaler_t* const frow_end = frow + wrk->dst_width * wrk->num_channels;
+ const int x_add = wrk->x_add;
+ int accum = x_add;
+ __m128i cur_pixels;
+
+ assert(!WebPRescalerInputDone(wrk));
+ assert(wrk->x_expand);
+ if (wrk->num_channels == 4) {
+ if (wrk->src_width < 2) {
+ WebPRescalerImportRowExpandC(wrk, src);
+ return;
+ }
+ LoadTwoPixels(src, &cur_pixels);
+ src += 4;
+ while (1) {
+ const __m128i mult = _mm_set1_epi32(((x_add - accum) << 16) | accum);
+ const __m128i out = _mm_madd_epi16(cur_pixels, mult);
+ _mm_storeu_si128((__m128i*)frow, out);
+ frow += 4;
+ if (frow >= frow_end) break;
+ accum -= wrk->x_sub;
+ if (accum < 0) {
+ LoadTwoPixels(src, &cur_pixels);
+ src += 4;
+ accum += x_add;
+ }
+ }
+ } else {
+ int left;
+ const uint8_t* const src_limit = src + wrk->src_width - 8;
+ if (wrk->src_width < 8) {
+ WebPRescalerImportRowExpandC(wrk, src);
+ return;
+ }
+ LoadHeightPixels(src, &cur_pixels);
+ src += 7;
+ left = 7;
+ while (1) {
+ const __m128i mult = _mm_cvtsi32_si128(((x_add - accum) << 16) | accum);
+ const __m128i out = _mm_madd_epi16(cur_pixels, mult);
+ assert(sizeof(*frow) == sizeof(uint32_t));
+ WebPUint32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
+ frow += 1;
+ if (frow >= frow_end) break;
+ accum -= wrk->x_sub;
+ if (accum < 0) {
+ if (--left) {
+ cur_pixels = _mm_srli_si128(cur_pixels, 2);
+ } else if (src <= src_limit) {
+ LoadHeightPixels(src, &cur_pixels);
+ src += 7;
+ left = 7;
+ } else { // tail
+ cur_pixels = _mm_srli_si128(cur_pixels, 2);
+ cur_pixels = _mm_insert_epi16(cur_pixels, src[1], 1);
+ src += 1;
+ left = 1;
+ }
+ accum += x_add;
+ }
+ }
+ }
+ assert(accum == 0);
+}
+
+static void RescalerImportRowShrinkSSE2(WebPRescaler* const wrk,
+ const uint8_t* src) {
+ const int x_sub = wrk->x_sub;
+ int accum = 0;
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i mult0 = _mm_set1_epi16(x_sub);
+ const __m128i mult1 = _mm_set1_epi32(wrk->fx_scale);
+ const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
+ __m128i sum = zero;
+ rescaler_t* frow = wrk->frow;
+ const rescaler_t* const frow_end = wrk->frow + 4 * wrk->dst_width;
+
+ if (wrk->num_channels != 4 || wrk->x_add > (x_sub << 7)) {
+ WebPRescalerImportRowShrinkC(wrk, src);
+ return;
+ }
+ assert(!WebPRescalerInputDone(wrk));
+ assert(!wrk->x_expand);
+
+ for (; frow < frow_end; frow += 4) {
+ __m128i base = zero;
+ accum += wrk->x_add;
+ while (accum > 0) {
+ const __m128i A = _mm_cvtsi32_si128(WebPMemToUint32(src));
+ src += 4;
+ base = _mm_unpacklo_epi8(A, zero);
+ // To avoid overflow, we need: base * x_add / x_sub < 32768
+ // => x_add < x_sub << 7. That's a 1/128 reduction ratio limit.
+ sum = _mm_add_epi16(sum, base);
+ accum -= x_sub;
+ }
+ { // Emit next horizontal pixel.
+ const __m128i mult = _mm_set1_epi16(-accum);
+ const __m128i frac0 = _mm_mullo_epi16(base, mult); // 16b x 16b -> 32b
+ const __m128i frac1 = _mm_mulhi_epu16(base, mult);
+ const __m128i frac = _mm_unpacklo_epi16(frac0, frac1); // frac is 32b
+ const __m128i A0 = _mm_mullo_epi16(sum, mult0);
+ const __m128i A1 = _mm_mulhi_epu16(sum, mult0);
+ const __m128i B0 = _mm_unpacklo_epi16(A0, A1); // sum * x_sub
+ const __m128i frow_out = _mm_sub_epi32(B0, frac); // sum * x_sub - frac
+ const __m128i D0 = _mm_srli_epi64(frac, 32);
+ const __m128i D1 = _mm_mul_epu32(frac, mult1); // 32b x 16b -> 64b
+ const __m128i D2 = _mm_mul_epu32(D0, mult1);
+ const __m128i E1 = _mm_add_epi64(D1, rounder);
+ const __m128i E2 = _mm_add_epi64(D2, rounder);
+ const __m128i F1 = _mm_shuffle_epi32(E1, 1 | (3 << 2));
+ const __m128i F2 = _mm_shuffle_epi32(E2, 1 | (3 << 2));
+ const __m128i G = _mm_unpacklo_epi32(F1, F2);
+ sum = _mm_packs_epi32(G, zero);
+ _mm_storeu_si128((__m128i*)frow, frow_out);
+ }
+ }
+ assert(accum == 0);
+}
+
+//------------------------------------------------------------------------------
+// Row export
+
+// load *src as epi64, multiply by mult and store result in [out0 ... out3]
+static WEBP_INLINE void LoadDispatchAndMult(const rescaler_t* const src,
+ const __m128i* const mult,
+ __m128i* const out0,
+ __m128i* const out1,
+ __m128i* const out2,
+ __m128i* const out3) {
+ const __m128i A0 = _mm_loadu_si128((const __m128i*)(src + 0));
+ const __m128i A1 = _mm_loadu_si128((const __m128i*)(src + 4));
+ const __m128i A2 = _mm_srli_epi64(A0, 32);
+ const __m128i A3 = _mm_srli_epi64(A1, 32);
+ if (mult != NULL) {
+ *out0 = _mm_mul_epu32(A0, *mult);
+ *out1 = _mm_mul_epu32(A1, *mult);
+ *out2 = _mm_mul_epu32(A2, *mult);
+ *out3 = _mm_mul_epu32(A3, *mult);
+ } else {
+ *out0 = A0;
+ *out1 = A1;
+ *out2 = A2;
+ *out3 = A3;
+ }
+}
+
+static WEBP_INLINE void ProcessRow(const __m128i* const A0,
+ const __m128i* const A1,
+ const __m128i* const A2,
+ const __m128i* const A3,
+ const __m128i* const mult,
+ uint8_t* const dst) {
+ const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
+ const __m128i mask = _mm_set_epi32(0xffffffffu, 0, 0xffffffffu, 0);
+ const __m128i B0 = _mm_mul_epu32(*A0, *mult);
+ const __m128i B1 = _mm_mul_epu32(*A1, *mult);
+ const __m128i B2 = _mm_mul_epu32(*A2, *mult);
+ const __m128i B3 = _mm_mul_epu32(*A3, *mult);
+ const __m128i C0 = _mm_add_epi64(B0, rounder);
+ const __m128i C1 = _mm_add_epi64(B1, rounder);
+ const __m128i C2 = _mm_add_epi64(B2, rounder);
+ const __m128i C3 = _mm_add_epi64(B3, rounder);
+ const __m128i D0 = _mm_srli_epi64(C0, WEBP_RESCALER_RFIX);
+ const __m128i D1 = _mm_srli_epi64(C1, WEBP_RESCALER_RFIX);
+#if (WEBP_RESCALER_FIX < 32)
+ const __m128i D2 =
+ _mm_and_si128(_mm_slli_epi64(C2, 32 - WEBP_RESCALER_RFIX), mask);
+ const __m128i D3 =
+ _mm_and_si128(_mm_slli_epi64(C3, 32 - WEBP_RESCALER_RFIX), mask);
+#else
+ const __m128i D2 = _mm_and_si128(C2, mask);
+ const __m128i D3 = _mm_and_si128(C3, mask);
+#endif
+ const __m128i E0 = _mm_or_si128(D0, D2);
+ const __m128i E1 = _mm_or_si128(D1, D3);
+ const __m128i F = _mm_packs_epi32(E0, E1);
+ const __m128i G = _mm_packus_epi16(F, F);
+ _mm_storel_epi64((__m128i*)dst, G);
+}
+
+static void RescalerExportRowExpandSSE2(WebPRescaler* const wrk) {
+ int x_out;
+ uint8_t* const dst = wrk->dst;
+ rescaler_t* const irow = wrk->irow;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ const rescaler_t* const frow = wrk->frow;
+ const __m128i mult = _mm_set_epi32(0, wrk->fy_scale, 0, wrk->fy_scale);
+
+ assert(!WebPRescalerOutputDone(wrk));
+ assert(wrk->y_accum <= 0 && wrk->y_sub + wrk->y_accum >= 0);
+ assert(wrk->y_expand);
+ if (wrk->y_accum == 0) {
+ for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) {
+ __m128i A0, A1, A2, A3;
+ LoadDispatchAndMult(frow + x_out, NULL, &A0, &A1, &A2, &A3);
+ ProcessRow(&A0, &A1, &A2, &A3, &mult, dst + x_out);
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const uint32_t J = frow[x_out];
+ const int v = (int)MULT_FIX(J, wrk->fy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ }
+ } else {
+ const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
+ const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B);
+ const __m128i mA = _mm_set_epi32(0, A, 0, A);
+ const __m128i mB = _mm_set_epi32(0, B, 0, B);
+ const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
+ for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) {
+ __m128i A0, A1, A2, A3, B0, B1, B2, B3;
+ LoadDispatchAndMult(frow + x_out, &mA, &A0, &A1, &A2, &A3);
+ LoadDispatchAndMult(irow + x_out, &mB, &B0, &B1, &B2, &B3);
+ {
+ const __m128i C0 = _mm_add_epi64(A0, B0);
+ const __m128i C1 = _mm_add_epi64(A1, B1);
+ const __m128i C2 = _mm_add_epi64(A2, B2);
+ const __m128i C3 = _mm_add_epi64(A3, B3);
+ const __m128i D0 = _mm_add_epi64(C0, rounder);
+ const __m128i D1 = _mm_add_epi64(C1, rounder);
+ const __m128i D2 = _mm_add_epi64(C2, rounder);
+ const __m128i D3 = _mm_add_epi64(C3, rounder);
+ const __m128i E0 = _mm_srli_epi64(D0, WEBP_RESCALER_RFIX);
+ const __m128i E1 = _mm_srli_epi64(D1, WEBP_RESCALER_RFIX);
+ const __m128i E2 = _mm_srli_epi64(D2, WEBP_RESCALER_RFIX);
+ const __m128i E3 = _mm_srli_epi64(D3, WEBP_RESCALER_RFIX);
+ ProcessRow(&E0, &E1, &E2, &E3, &mult, dst + x_out);
+ }
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const uint64_t I = (uint64_t)A * frow[x_out]
+ + (uint64_t)B * irow[x_out];
+ const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
+ const int v = (int)MULT_FIX(J, wrk->fy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ }
+ }
+}
+
+static void RescalerExportRowShrinkSSE2(WebPRescaler* const wrk) {
+ int x_out;
+ uint8_t* const dst = wrk->dst;
+ rescaler_t* const irow = wrk->irow;
+ const int x_out_max = wrk->dst_width * wrk->num_channels;
+ const rescaler_t* const frow = wrk->frow;
+ const uint32_t yscale = wrk->fy_scale * (-wrk->y_accum);
+ assert(!WebPRescalerOutputDone(wrk));
+ assert(wrk->y_accum <= 0);
+ assert(!wrk->y_expand);
+ if (yscale) {
+ const int scale_xy = wrk->fxy_scale;
+ const __m128i mult_xy = _mm_set_epi32(0, scale_xy, 0, scale_xy);
+ const __m128i mult_y = _mm_set_epi32(0, yscale, 0, yscale);
+ const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
+ for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) {
+ __m128i A0, A1, A2, A3, B0, B1, B2, B3;
+ LoadDispatchAndMult(irow + x_out, NULL, &A0, &A1, &A2, &A3);
+ LoadDispatchAndMult(frow + x_out, &mult_y, &B0, &B1, &B2, &B3);
+ {
+ const __m128i C0 = _mm_add_epi64(B0, rounder);
+ const __m128i C1 = _mm_add_epi64(B1, rounder);
+ const __m128i C2 = _mm_add_epi64(B2, rounder);
+ const __m128i C3 = _mm_add_epi64(B3, rounder);
+ const __m128i D0 = _mm_srli_epi64(C0, WEBP_RESCALER_RFIX); // = frac
+ const __m128i D1 = _mm_srli_epi64(C1, WEBP_RESCALER_RFIX);
+ const __m128i D2 = _mm_srli_epi64(C2, WEBP_RESCALER_RFIX);
+ const __m128i D3 = _mm_srli_epi64(C3, WEBP_RESCALER_RFIX);
+ const __m128i E0 = _mm_sub_epi64(A0, D0); // irow[x] - frac
+ const __m128i E1 = _mm_sub_epi64(A1, D1);
+ const __m128i E2 = _mm_sub_epi64(A2, D2);
+ const __m128i E3 = _mm_sub_epi64(A3, D3);
+ const __m128i F2 = _mm_slli_epi64(D2, 32);
+ const __m128i F3 = _mm_slli_epi64(D3, 32);
+ const __m128i G0 = _mm_or_si128(D0, F2);
+ const __m128i G1 = _mm_or_si128(D1, F3);
+ _mm_storeu_si128((__m128i*)(irow + x_out + 0), G0);
+ _mm_storeu_si128((__m128i*)(irow + x_out + 4), G1);
+ ProcessRow(&E0, &E1, &E2, &E3, &mult_xy, dst + x_out);
+ }
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const uint32_t frac = (int)MULT_FIX(frow[x_out], yscale);
+ const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ irow[x_out] = frac; // new fractional start
+ }
+ } else {
+ const uint32_t scale = wrk->fxy_scale;
+ const __m128i mult = _mm_set_epi32(0, scale, 0, scale);
+ const __m128i zero = _mm_setzero_si128();
+ for (x_out = 0; x_out + 8 <= x_out_max; x_out += 8) {
+ __m128i A0, A1, A2, A3;
+ LoadDispatchAndMult(irow + x_out, NULL, &A0, &A1, &A2, &A3);
+ _mm_storeu_si128((__m128i*)(irow + x_out + 0), zero);
+ _mm_storeu_si128((__m128i*)(irow + x_out + 4), zero);
+ ProcessRow(&A0, &A1, &A2, &A3, &mult, dst + x_out);
+ }
+ for (; x_out < x_out_max; ++x_out) {
+ const int v = (int)MULT_FIX(irow[x_out], scale);
+ assert(v >= 0 && v <= 255);
+ dst[x_out] = v;
+ irow[x_out] = 0;
+ }
+ }
+}
+
+#undef MULT_FIX
+#undef ROUNDER
+
+//------------------------------------------------------------------------------
+
+extern void WebPRescalerDspInitSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitSSE2(void) {
+ WebPRescalerImportRowExpand = RescalerImportRowExpandSSE2;
+ WebPRescalerImportRowShrink = RescalerImportRowShrinkSSE2;
+ WebPRescalerExportRowExpand = RescalerExportRowExpandSSE2;
+ WebPRescalerExportRowShrink = RescalerExportRowShrinkSSE2;
+}
+
+#else // !WEBP_USE_SSE2
+
+WEBP_DSP_INIT_STUB(WebPRescalerDspInitSSE2)
+
+#endif // WEBP_USE_SSE2
diff --git a/media/libwebp/dsp/upsampling.c b/media/libwebp/dsp/upsampling.c
new file mode 100644
index 000000000..265e722c1
--- /dev/null
+++ b/media/libwebp/dsp/upsampling.c
@@ -0,0 +1,266 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV to RGB upsampling functions.
+//
+// Author: somnath@google.com (Somnath Banerjee)
+
+#include "./dsp.h"
+#include "./yuv.h"
+
+#include <assert.h>
+
+//------------------------------------------------------------------------------
+// Fancy upsampler
+
+#ifdef FANCY_UPSAMPLING
+
+// Fancy upsampling functions to convert YUV to RGB
+WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
+
+// Given samples laid out in a square as:
+// [a b]
+// [c d]
+// we interpolate u/v as:
+// ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16
+// ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16
+
+// We process u and v together stashed into 32bit (16bit each).
+#define LOAD_UV(u, v) ((u) | ((v) << 16))
+
+#define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \
+ const uint8_t* top_u, const uint8_t* top_v, \
+ const uint8_t* cur_u, const uint8_t* cur_v, \
+ uint8_t* top_dst, uint8_t* bottom_dst, int len) { \
+ int x; \
+ const int last_pixel_pair = (len - 1) >> 1; \
+ uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]); /* top-left sample */ \
+ uint32_t l_uv = LOAD_UV(cur_u[0], cur_v[0]); /* left-sample */ \
+ assert(top_y != NULL); \
+ { \
+ const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \
+ FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst); \
+ } \
+ if (bottom_y != NULL) { \
+ const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \
+ FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst); \
+ } \
+ for (x = 1; x <= last_pixel_pair; ++x) { \
+ const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]); /* top sample */ \
+ const uint32_t uv = LOAD_UV(cur_u[x], cur_v[x]); /* sample */ \
+ /* precompute invariant values associated with first and second diagonals*/\
+ const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u; \
+ const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3; \
+ const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3; \
+ { \
+ const uint32_t uv0 = (diag_12 + tl_uv) >> 1; \
+ const uint32_t uv1 = (diag_03 + t_uv) >> 1; \
+ FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \
+ top_dst + (2 * x - 1) * XSTEP); \
+ FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16), \
+ top_dst + (2 * x - 0) * XSTEP); \
+ } \
+ if (bottom_y != NULL) { \
+ const uint32_t uv0 = (diag_03 + l_uv) >> 1; \
+ const uint32_t uv1 = (diag_12 + uv) >> 1; \
+ FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \
+ bottom_dst + (2 * x - 1) * XSTEP); \
+ FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16), \
+ bottom_dst + (2 * x + 0) * XSTEP); \
+ } \
+ tl_uv = t_uv; \
+ l_uv = uv; \
+ } \
+ if (!(len & 1)) { \
+ { \
+ const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \
+ FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16), \
+ top_dst + (len - 1) * XSTEP); \
+ } \
+ if (bottom_y != NULL) { \
+ const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \
+ FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16), \
+ bottom_dst + (len - 1) * XSTEP); \
+ } \
+ } \
+}
+
+// All variants implemented.
+UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3)
+UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3)
+UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
+UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
+UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
+UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2)
+UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2)
+
+#undef LOAD_UV
+#undef UPSAMPLE_FUNC
+
+#endif // FANCY_UPSAMPLING
+
+//------------------------------------------------------------------------------
+
+#if !defined(FANCY_UPSAMPLING)
+#define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC) \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \
+ const uint8_t* top_u, const uint8_t* top_v, \
+ const uint8_t* bot_u, const uint8_t* bot_v, \
+ uint8_t* top_dst, uint8_t* bot_dst, int len) { \
+ const int half_len = len >> 1; \
+ int x; \
+ assert(top_dst != NULL); \
+ { \
+ for (x = 0; x < half_len; ++x) { \
+ FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0); \
+ FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4); \
+ } \
+ if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x); \
+ } \
+ if (bot_dst != NULL) { \
+ for (x = 0; x < half_len; ++x) { \
+ FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0); \
+ FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4); \
+ } \
+ if (len & 1) FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x); \
+ } \
+}
+
+DUAL_SAMPLE_FUNC(DualLineSamplerBGRA, VP8YuvToBgra)
+DUAL_SAMPLE_FUNC(DualLineSamplerARGB, VP8YuvToArgb)
+#undef DUAL_SAMPLE_FUNC
+
+#endif // !FANCY_UPSAMPLING
+
+WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last) {
+ WebPInitUpsamplers();
+ VP8YUVInit();
+#ifdef FANCY_UPSAMPLING
+ return WebPUpsamplers[alpha_is_last ? MODE_BGRA : MODE_ARGB];
+#else
+ return (alpha_is_last ? DualLineSamplerBGRA : DualLineSamplerARGB);
+#endif
+}
+
+//------------------------------------------------------------------------------
+// YUV444 converter
+
+#define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP) \
+extern void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v, \
+ uint8_t* dst, int len); \
+void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v, \
+ uint8_t* dst, int len) { \
+ int i; \
+ for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]); \
+}
+
+YUV444_FUNC(WebPYuv444ToRgbC, VP8YuvToRgb, 3)
+YUV444_FUNC(WebPYuv444ToBgrC, VP8YuvToBgr, 3)
+YUV444_FUNC(WebPYuv444ToRgbaC, VP8YuvToRgba, 4)
+YUV444_FUNC(WebPYuv444ToBgraC, VP8YuvToBgra, 4)
+YUV444_FUNC(WebPYuv444ToArgbC, VP8YuvToArgb, 4)
+YUV444_FUNC(WebPYuv444ToRgba4444C, VP8YuvToRgba4444, 2)
+YUV444_FUNC(WebPYuv444ToRgb565C, VP8YuvToRgb565, 2)
+
+#undef YUV444_FUNC
+
+WebPYUV444Converter WebPYUV444Converters[MODE_LAST];
+
+extern void WebPInitYUV444ConvertersMIPSdspR2(void);
+extern void WebPInitYUV444ConvertersSSE2(void);
+
+static volatile VP8CPUInfo upsampling_last_cpuinfo_used1 =
+ (VP8CPUInfo)&upsampling_last_cpuinfo_used1;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444Converters(void) {
+ if (upsampling_last_cpuinfo_used1 == VP8GetCPUInfo) return;
+
+ WebPYUV444Converters[MODE_RGB] = WebPYuv444ToRgbC;
+ WebPYUV444Converters[MODE_RGBA] = WebPYuv444ToRgbaC;
+ WebPYUV444Converters[MODE_BGR] = WebPYuv444ToBgrC;
+ WebPYUV444Converters[MODE_BGRA] = WebPYuv444ToBgraC;
+ WebPYUV444Converters[MODE_ARGB] = WebPYuv444ToArgbC;
+ WebPYUV444Converters[MODE_RGBA_4444] = WebPYuv444ToRgba4444C;
+ WebPYUV444Converters[MODE_RGB_565] = WebPYuv444ToRgb565C;
+ WebPYUV444Converters[MODE_rgbA] = WebPYuv444ToRgbaC;
+ WebPYUV444Converters[MODE_bgrA] = WebPYuv444ToBgraC;
+ WebPYUV444Converters[MODE_Argb] = WebPYuv444ToArgbC;
+ WebPYUV444Converters[MODE_rgbA_4444] = WebPYuv444ToRgba4444C;
+
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ WebPInitYUV444ConvertersSSE2();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ WebPInitYUV444ConvertersMIPSdspR2();
+ }
+#endif
+ }
+ upsampling_last_cpuinfo_used1 = VP8GetCPUInfo;
+}
+
+//------------------------------------------------------------------------------
+// Main calls
+
+extern void WebPInitUpsamplersSSE2(void);
+extern void WebPInitUpsamplersNEON(void);
+extern void WebPInitUpsamplersMIPSdspR2(void);
+extern void WebPInitUpsamplersMSA(void);
+
+static volatile VP8CPUInfo upsampling_last_cpuinfo_used2 =
+ (VP8CPUInfo)&upsampling_last_cpuinfo_used2;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplers(void) {
+ if (upsampling_last_cpuinfo_used2 == VP8GetCPUInfo) return;
+
+#ifdef FANCY_UPSAMPLING
+ WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
+ WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
+ WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair;
+ WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
+ WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair;
+ WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
+ WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair;
+ WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
+ WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
+ WebPUpsamplers[MODE_Argb] = UpsampleArgbLinePair;
+ WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
+
+ // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ WebPInitUpsamplersSSE2();
+ }
+#endif
+#if defined(WEBP_USE_NEON)
+ if (VP8GetCPUInfo(kNEON)) {
+ WebPInitUpsamplersNEON();
+ }
+#endif
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ WebPInitUpsamplersMIPSdspR2();
+ }
+#endif
+#if defined(WEBP_USE_MSA)
+ if (VP8GetCPUInfo(kMSA)) {
+ WebPInitUpsamplersMSA();
+ }
+#endif
+ }
+#endif // FANCY_UPSAMPLING
+ upsampling_last_cpuinfo_used2 = VP8GetCPUInfo;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/dsp/upsampling_neon.c b/media/libwebp/dsp/upsampling_neon.c
new file mode 100644
index 000000000..d371a834f
--- /dev/null
+++ b/media/libwebp/dsp/upsampling_neon.c
@@ -0,0 +1,281 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// NEON version of YUV to RGB upsampling functions.
+//
+// Author: mans@mansr.com (Mans Rullgard)
+// Based on SSE code by: somnath@google.com (Somnath Banerjee)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_NEON)
+
+#include <assert.h>
+#include <arm_neon.h>
+#include <string.h>
+#include "./neon.h"
+#include "./yuv.h"
+
+#ifdef FANCY_UPSAMPLING
+
+//-----------------------------------------------------------------------------
+// U/V upsampling
+
+// Loads 9 pixels each from rows r1 and r2 and generates 16 pixels.
+#define UPSAMPLE_16PIXELS(r1, r2, out) do { \
+ const uint8x8_t a = vld1_u8(r1 + 0); \
+ const uint8x8_t b = vld1_u8(r1 + 1); \
+ const uint8x8_t c = vld1_u8(r2 + 0); \
+ const uint8x8_t d = vld1_u8(r2 + 1); \
+ /* a + b + c + d */ \
+ const uint16x8_t ad = vaddl_u8(a, d); \
+ const uint16x8_t bc = vaddl_u8(b, c); \
+ const uint16x8_t abcd = vaddq_u16(ad, bc); \
+ /* 3a + b + c + 3d */ \
+ const uint16x8_t al = vaddq_u16(abcd, vshlq_n_u16(ad, 1)); \
+ /* a + 3b + 3c + d */ \
+ const uint16x8_t bl = vaddq_u16(abcd, vshlq_n_u16(bc, 1)); \
+ \
+ const uint8x8_t diag2 = vshrn_n_u16(al, 3); \
+ const uint8x8_t diag1 = vshrn_n_u16(bl, 3); \
+ \
+ const uint8x8_t A = vrhadd_u8(a, diag1); \
+ const uint8x8_t B = vrhadd_u8(b, diag2); \
+ const uint8x8_t C = vrhadd_u8(c, diag2); \
+ const uint8x8_t D = vrhadd_u8(d, diag1); \
+ \
+ uint8x8x2_t A_B, C_D; \
+ INIT_VECTOR2(A_B, A, B); \
+ INIT_VECTOR2(C_D, C, D); \
+ vst2_u8(out + 0, A_B); \
+ vst2_u8(out + 32, C_D); \
+} while (0)
+
+// Turn the macro into a function for reducing code-size when non-critical
+static void Upsample16Pixels(const uint8_t *r1, const uint8_t *r2,
+ uint8_t *out) {
+ UPSAMPLE_16PIXELS(r1, r2, out);
+}
+
+#define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) { \
+ uint8_t r1[9], r2[9]; \
+ memcpy(r1, (tb), (num_pixels)); \
+ memcpy(r2, (bb), (num_pixels)); \
+ /* replicate last byte */ \
+ memset(r1 + (num_pixels), r1[(num_pixels) - 1], 9 - (num_pixels)); \
+ memset(r2 + (num_pixels), r2[(num_pixels) - 1], 9 - (num_pixels)); \
+ Upsample16Pixels(r1, r2, out); \
+}
+
+//-----------------------------------------------------------------------------
+// YUV->RGB conversion
+
+// note: we represent the 33050 large constant as 32768 + 282
+static const int16_t kCoeffs1[4] = { 19077, 26149, 6419, 13320 };
+
+#define v255 vdup_n_u8(255)
+
+#define STORE_Rgb(out, r, g, b) do { \
+ uint8x8x3_t r_g_b; \
+ INIT_VECTOR3(r_g_b, r, g, b); \
+ vst3_u8(out, r_g_b); \
+} while (0)
+
+#define STORE_Bgr(out, r, g, b) do { \
+ uint8x8x3_t b_g_r; \
+ INIT_VECTOR3(b_g_r, b, g, r); \
+ vst3_u8(out, b_g_r); \
+} while (0)
+
+#define STORE_Rgba(out, r, g, b) do { \
+ uint8x8x4_t r_g_b_v255; \
+ INIT_VECTOR4(r_g_b_v255, r, g, b, v255); \
+ vst4_u8(out, r_g_b_v255); \
+} while (0)
+
+#define STORE_Bgra(out, r, g, b) do { \
+ uint8x8x4_t b_g_r_v255; \
+ INIT_VECTOR4(b_g_r_v255, b, g, r, v255); \
+ vst4_u8(out, b_g_r_v255); \
+} while (0)
+
+#define STORE_Argb(out, r, g, b) do { \
+ uint8x8x4_t v255_r_g_b; \
+ INIT_VECTOR4(v255_r_g_b, v255, r, g, b); \
+ vst4_u8(out, v255_r_g_b); \
+} while (0)
+
+#if !defined(WEBP_SWAP_16BIT_CSP)
+#define ZIP_U8(lo, hi) vzip_u8((lo), (hi))
+#else
+#define ZIP_U8(lo, hi) vzip_u8((hi), (lo))
+#endif
+
+#define STORE_Rgba4444(out, r, g, b) do { \
+ const uint8x8_t rg = vsri_n_u8(r, g, 4); /* shift g, insert r */ \
+ const uint8x8_t ba = vsri_n_u8(b, v255, 4); /* shift a, insert b */ \
+ const uint8x8x2_t rgba4444 = ZIP_U8(rg, ba); \
+ vst1q_u8(out, vcombine_u8(rgba4444.val[0], rgba4444.val[1])); \
+} while (0)
+
+#define STORE_Rgb565(out, r, g, b) do { \
+ const uint8x8_t rg = vsri_n_u8(r, g, 5); /* shift g and insert r */ \
+ const uint8x8_t g1 = vshl_n_u8(g, 3); /* pre-shift g: 3bits */ \
+ const uint8x8_t gb = vsri_n_u8(g1, b, 3); /* shift b and insert g */ \
+ const uint8x8x2_t rgb565 = ZIP_U8(rg, gb); \
+ vst1q_u8(out, vcombine_u8(rgb565.val[0], rgb565.val[1])); \
+} while (0)
+
+#define CONVERT8(FMT, XSTEP, N, src_y, src_uv, out, cur_x) do { \
+ int i; \
+ for (i = 0; i < N; i += 8) { \
+ const int off = ((cur_x) + i) * XSTEP; \
+ const uint8x8_t y = vld1_u8((src_y) + (cur_x) + i); \
+ const uint8x8_t u = vld1_u8((src_uv) + i + 0); \
+ const uint8x8_t v = vld1_u8((src_uv) + i + 16); \
+ const int16x8_t Y0 = vreinterpretq_s16_u16(vshll_n_u8(y, 7)); \
+ const int16x8_t U0 = vreinterpretq_s16_u16(vshll_n_u8(u, 7)); \
+ const int16x8_t V0 = vreinterpretq_s16_u16(vshll_n_u8(v, 7)); \
+ const int16x8_t Y1 = vqdmulhq_lane_s16(Y0, coeff1, 0); \
+ const int16x8_t R0 = vqdmulhq_lane_s16(V0, coeff1, 1); \
+ const int16x8_t G0 = vqdmulhq_lane_s16(U0, coeff1, 2); \
+ const int16x8_t G1 = vqdmulhq_lane_s16(V0, coeff1, 3); \
+ const int16x8_t B0 = vqdmulhq_n_s16(U0, 282); \
+ const int16x8_t R1 = vqaddq_s16(Y1, R_Rounder); \
+ const int16x8_t G2 = vqaddq_s16(Y1, G_Rounder); \
+ const int16x8_t B1 = vqaddq_s16(Y1, B_Rounder); \
+ const int16x8_t R2 = vqaddq_s16(R0, R1); \
+ const int16x8_t G3 = vqaddq_s16(G0, G1); \
+ const int16x8_t B2 = vqaddq_s16(B0, B1); \
+ const int16x8_t G4 = vqsubq_s16(G2, G3); \
+ const int16x8_t B3 = vqaddq_s16(B2, U0); \
+ const uint8x8_t R = vqshrun_n_s16(R2, YUV_FIX2); \
+ const uint8x8_t G = vqshrun_n_s16(G4, YUV_FIX2); \
+ const uint8x8_t B = vqshrun_n_s16(B3, YUV_FIX2); \
+ STORE_ ## FMT(out + off, R, G, B); \
+ } \
+} while (0)
+
+#define CONVERT1(FUNC, XSTEP, N, src_y, src_uv, rgb, cur_x) { \
+ int i; \
+ for (i = 0; i < N; i++) { \
+ const int off = ((cur_x) + i) * XSTEP; \
+ const int y = src_y[(cur_x) + i]; \
+ const int u = (src_uv)[i]; \
+ const int v = (src_uv)[i + 16]; \
+ FUNC(y, u, v, rgb + off); \
+ } \
+}
+
+#define CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, uv, \
+ top_dst, bottom_dst, cur_x, len) { \
+ CONVERT8(FMT, XSTEP, len, top_y, uv, top_dst, cur_x); \
+ if (bottom_y != NULL) { \
+ CONVERT8(FMT, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x); \
+ } \
+}
+
+#define CONVERT2RGB_1(FUNC, XSTEP, top_y, bottom_y, uv, \
+ top_dst, bottom_dst, cur_x, len) { \
+ CONVERT1(FUNC, XSTEP, len, top_y, uv, top_dst, cur_x); \
+ if (bottom_y != NULL) { \
+ CONVERT1(FUNC, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x); \
+ } \
+}
+
+#define NEON_UPSAMPLE_FUNC(FUNC_NAME, FMT, XSTEP) \
+static void FUNC_NAME(const uint8_t *top_y, const uint8_t *bottom_y, \
+ const uint8_t *top_u, const uint8_t *top_v, \
+ const uint8_t *cur_u, const uint8_t *cur_v, \
+ uint8_t *top_dst, uint8_t *bottom_dst, int len) { \
+ int block; \
+ /* 16 byte aligned array to cache reconstructed u and v */ \
+ uint8_t uv_buf[2 * 32 + 15]; \
+ uint8_t *const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \
+ const int uv_len = (len + 1) >> 1; \
+ /* 9 pixels must be read-able for each block */ \
+ const int num_blocks = (uv_len - 1) >> 3; \
+ const int leftover = uv_len - num_blocks * 8; \
+ const int last_pos = 1 + 16 * num_blocks; \
+ \
+ const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1; \
+ const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1; \
+ \
+ const int16x4_t coeff1 = vld1_s16(kCoeffs1); \
+ const int16x8_t R_Rounder = vdupq_n_s16(-14234); \
+ const int16x8_t G_Rounder = vdupq_n_s16(8708); \
+ const int16x8_t B_Rounder = vdupq_n_s16(-17685); \
+ \
+ /* Treat the first pixel in regular way */ \
+ assert(top_y != NULL); \
+ { \
+ const int u0 = (top_u[0] + u_diag) >> 1; \
+ const int v0 = (top_v[0] + v_diag) >> 1; \
+ VP8YuvTo ## FMT(top_y[0], u0, v0, top_dst); \
+ } \
+ if (bottom_y != NULL) { \
+ const int u0 = (cur_u[0] + u_diag) >> 1; \
+ const int v0 = (cur_v[0] + v_diag) >> 1; \
+ VP8YuvTo ## FMT(bottom_y[0], u0, v0, bottom_dst); \
+ } \
+ \
+ for (block = 0; block < num_blocks; ++block) { \
+ UPSAMPLE_16PIXELS(top_u, cur_u, r_uv); \
+ UPSAMPLE_16PIXELS(top_v, cur_v, r_uv + 16); \
+ CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, r_uv, \
+ top_dst, bottom_dst, 16 * block + 1, 16); \
+ top_u += 8; \
+ cur_u += 8; \
+ top_v += 8; \
+ cur_v += 8; \
+ } \
+ \
+ UPSAMPLE_LAST_BLOCK(top_u, cur_u, leftover, r_uv); \
+ UPSAMPLE_LAST_BLOCK(top_v, cur_v, leftover, r_uv + 16); \
+ CONVERT2RGB_1(VP8YuvTo ## FMT, XSTEP, top_y, bottom_y, r_uv, \
+ top_dst, bottom_dst, last_pos, len - last_pos); \
+}
+
+// NEON variants of the fancy upsampler.
+NEON_UPSAMPLE_FUNC(UpsampleRgbLinePair, Rgb, 3)
+NEON_UPSAMPLE_FUNC(UpsampleBgrLinePair, Bgr, 3)
+NEON_UPSAMPLE_FUNC(UpsampleRgbaLinePair, Rgba, 4)
+NEON_UPSAMPLE_FUNC(UpsampleBgraLinePair, Bgra, 4)
+NEON_UPSAMPLE_FUNC(UpsampleArgbLinePair, Argb, 4)
+NEON_UPSAMPLE_FUNC(UpsampleRgba4444LinePair, Rgba4444, 2)
+NEON_UPSAMPLE_FUNC(UpsampleRgb565LinePair, Rgb565, 2)
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
+
+extern void WebPInitUpsamplersNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersNEON(void) {
+ WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
+ WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
+ WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair;
+ WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
+ WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair;
+ WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
+ WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
+ WebPUpsamplers[MODE_Argb] = UpsampleArgbLinePair;
+ WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair;
+ WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
+ WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
+}
+
+#endif // FANCY_UPSAMPLING
+
+#endif // WEBP_USE_NEON
+
+#if !(defined(FANCY_UPSAMPLING) && defined(WEBP_USE_NEON))
+WEBP_DSP_INIT_STUB(WebPInitUpsamplersNEON)
+#endif
diff --git a/media/libwebp/dsp/upsampling_sse2.c b/media/libwebp/dsp/upsampling_sse2.c
new file mode 100644
index 000000000..b5b668900
--- /dev/null
+++ b/media/libwebp/dsp/upsampling_sse2.c
@@ -0,0 +1,249 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// SSE2 version of YUV to RGB upsampling functions.
+//
+// Author: somnath@google.com (Somnath Banerjee)
+
+#include "./dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include <assert.h>
+#include <emmintrin.h>
+#include <string.h>
+#include "./yuv.h"
+
+#ifdef FANCY_UPSAMPLING
+
+// We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows
+// u = (9*a + 3*b + 3*c + d + 8) / 16
+// = (a + (a + 3*b + 3*c + d) / 8 + 1) / 2
+// = (a + m + 1) / 2
+// where m = (a + 3*b + 3*c + d) / 8
+// = ((a + b + c + d) / 2 + b + c) / 4
+//
+// Let's say k = (a + b + c + d) / 4.
+// We can compute k as
+// k = (s + t + 1) / 2 - ((a^d) | (b^c) | (s^t)) & 1
+// where s = (a + d + 1) / 2 and t = (b + c + 1) / 2
+//
+// Then m can be written as
+// m = (k + t + 1) / 2 - (((b^c) & (s^t)) | (k^t)) & 1
+
+// Computes out = (k + in + 1) / 2 - ((ij & (s^t)) | (k^in)) & 1
+#define GET_M(ij, in, out) do { \
+ const __m128i tmp0 = _mm_avg_epu8(k, (in)); /* (k + in + 1) / 2 */ \
+ const __m128i tmp1 = _mm_and_si128((ij), st); /* (ij) & (s^t) */ \
+ const __m128i tmp2 = _mm_xor_si128(k, (in)); /* (k^in) */ \
+ const __m128i tmp3 = _mm_or_si128(tmp1, tmp2); /* ((ij) & (s^t)) | (k^in) */\
+ const __m128i tmp4 = _mm_and_si128(tmp3, one); /* & 1 -> lsb_correction */ \
+ (out) = _mm_sub_epi8(tmp0, tmp4); /* (k + in + 1) / 2 - lsb_correction */ \
+} while (0)
+
+// pack and store two alternating pixel rows
+#define PACK_AND_STORE(a, b, da, db, out) do { \
+ const __m128i t_a = _mm_avg_epu8(a, da); /* (9a + 3b + 3c + d + 8) / 16 */ \
+ const __m128i t_b = _mm_avg_epu8(b, db); /* (3a + 9b + c + 3d + 8) / 16 */ \
+ const __m128i t_1 = _mm_unpacklo_epi8(t_a, t_b); \
+ const __m128i t_2 = _mm_unpackhi_epi8(t_a, t_b); \
+ _mm_store_si128(((__m128i*)(out)) + 0, t_1); \
+ _mm_store_si128(((__m128i*)(out)) + 1, t_2); \
+} while (0)
+
+// Loads 17 pixels each from rows r1 and r2 and generates 32 pixels.
+#define UPSAMPLE_32PIXELS(r1, r2, out) { \
+ const __m128i one = _mm_set1_epi8(1); \
+ const __m128i a = _mm_loadu_si128((const __m128i*)&(r1)[0]); \
+ const __m128i b = _mm_loadu_si128((const __m128i*)&(r1)[1]); \
+ const __m128i c = _mm_loadu_si128((const __m128i*)&(r2)[0]); \
+ const __m128i d = _mm_loadu_si128((const __m128i*)&(r2)[1]); \
+ \
+ const __m128i s = _mm_avg_epu8(a, d); /* s = (a + d + 1) / 2 */ \
+ const __m128i t = _mm_avg_epu8(b, c); /* t = (b + c + 1) / 2 */ \
+ const __m128i st = _mm_xor_si128(s, t); /* st = s^t */ \
+ \
+ const __m128i ad = _mm_xor_si128(a, d); /* ad = a^d */ \
+ const __m128i bc = _mm_xor_si128(b, c); /* bc = b^c */ \
+ \
+ const __m128i t1 = _mm_or_si128(ad, bc); /* (a^d) | (b^c) */ \
+ const __m128i t2 = _mm_or_si128(t1, st); /* (a^d) | (b^c) | (s^t) */ \
+ const __m128i t3 = _mm_and_si128(t2, one); /* (a^d) | (b^c) | (s^t) & 1 */ \
+ const __m128i t4 = _mm_avg_epu8(s, t); \
+ const __m128i k = _mm_sub_epi8(t4, t3); /* k = (a + b + c + d) / 4 */ \
+ __m128i diag1, diag2; \
+ \
+ GET_M(bc, t, diag1); /* diag1 = (a + 3b + 3c + d) / 8 */ \
+ GET_M(ad, s, diag2); /* diag2 = (3a + b + c + 3d) / 8 */ \
+ \
+ /* pack the alternate pixels */ \
+ PACK_AND_STORE(a, b, diag1, diag2, out + 0); /* store top */ \
+ PACK_AND_STORE(c, d, diag2, diag1, out + 2 * 32); /* store bottom */ \
+}
+
+// Turn the macro into a function for reducing code-size when non-critical
+static void Upsample32Pixels(const uint8_t r1[], const uint8_t r2[],
+ uint8_t* const out) {
+ UPSAMPLE_32PIXELS(r1, r2, out);
+}
+
+#define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) { \
+ uint8_t r1[17], r2[17]; \
+ memcpy(r1, (tb), (num_pixels)); \
+ memcpy(r2, (bb), (num_pixels)); \
+ /* replicate last byte */ \
+ memset(r1 + (num_pixels), r1[(num_pixels) - 1], 17 - (num_pixels)); \
+ memset(r2 + (num_pixels), r2[(num_pixels) - 1], 17 - (num_pixels)); \
+ /* using the shared function instead of the macro saves ~3k code size */ \
+ Upsample32Pixels(r1, r2, out); \
+}
+
+#define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, \
+ top_dst, bottom_dst, cur_x, num_pixels) { \
+ int n; \
+ for (n = 0; n < (num_pixels); ++n) { \
+ FUNC(top_y[(cur_x) + n], r_u[n], r_v[n], \
+ top_dst + ((cur_x) + n) * XSTEP); \
+ } \
+ if (bottom_y != NULL) { \
+ for (n = 0; n < (num_pixels); ++n) { \
+ FUNC(bottom_y[(cur_x) + n], r_u[64 + n], r_v[64 + n], \
+ bottom_dst + ((cur_x) + n) * XSTEP); \
+ } \
+ } \
+}
+
+#define CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, \
+ top_dst, bottom_dst, cur_x) do { \
+ FUNC##32(top_y + (cur_x), r_u, r_v, top_dst + (cur_x) * XSTEP); \
+ if (bottom_y != NULL) { \
+ FUNC##32(bottom_y + (cur_x), r_u + 64, r_v + 64, \
+ bottom_dst + (cur_x) * XSTEP); \
+ } \
+} while (0)
+
+#define SSE2_UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \
+static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \
+ const uint8_t* top_u, const uint8_t* top_v, \
+ const uint8_t* cur_u, const uint8_t* cur_v, \
+ uint8_t* top_dst, uint8_t* bottom_dst, int len) { \
+ int uv_pos, pos; \
+ /* 16byte-aligned array to cache reconstructed u and v */ \
+ uint8_t uv_buf[4 * 32 + 15]; \
+ uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \
+ uint8_t* const r_v = r_u + 32; \
+ \
+ assert(top_y != NULL); \
+ { /* Treat the first pixel in regular way */ \
+ const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1; \
+ const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1; \
+ const int u0_t = (top_u[0] + u_diag) >> 1; \
+ const int v0_t = (top_v[0] + v_diag) >> 1; \
+ FUNC(top_y[0], u0_t, v0_t, top_dst); \
+ if (bottom_y != NULL) { \
+ const int u0_b = (cur_u[0] + u_diag) >> 1; \
+ const int v0_b = (cur_v[0] + v_diag) >> 1; \
+ FUNC(bottom_y[0], u0_b, v0_b, bottom_dst); \
+ } \
+ } \
+ /* For UPSAMPLE_32PIXELS, 17 u/v values must be read-able for each block */ \
+ for (pos = 1, uv_pos = 0; pos + 32 + 1 <= len; pos += 32, uv_pos += 16) { \
+ UPSAMPLE_32PIXELS(top_u + uv_pos, cur_u + uv_pos, r_u); \
+ UPSAMPLE_32PIXELS(top_v + uv_pos, cur_v + uv_pos, r_v); \
+ CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, pos); \
+ } \
+ if (len > 1) { \
+ const int left_over = ((len + 1) >> 1) - (pos >> 1); \
+ assert(left_over > 0); \
+ UPSAMPLE_LAST_BLOCK(top_u + uv_pos, cur_u + uv_pos, left_over, r_u); \
+ UPSAMPLE_LAST_BLOCK(top_v + uv_pos, cur_v + uv_pos, left_over, r_v); \
+ CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, \
+ pos, len - pos); \
+ } \
+}
+
+// SSE2 variants of the fancy upsampler.
+SSE2_UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3)
+SSE2_UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3)
+SSE2_UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
+SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
+SSE2_UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
+SSE2_UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2)
+SSE2_UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2)
+
+#undef GET_M
+#undef PACK_AND_STORE
+#undef UPSAMPLE_32PIXELS
+#undef UPSAMPLE_LAST_BLOCK
+#undef CONVERT2RGB
+#undef CONVERT2RGB_32
+#undef SSE2_UPSAMPLE_FUNC
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
+
+extern void WebPInitUpsamplersSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplersSSE2(void) {
+ WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
+ WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
+ WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair;
+ WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
+ WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair;
+ WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
+ WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
+ WebPUpsamplers[MODE_Argb] = UpsampleArgbLinePair;
+ WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair;
+ WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
+ WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
+}
+
+#endif // FANCY_UPSAMPLING
+
+//------------------------------------------------------------------------------
+
+extern WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */];
+extern void WebPInitYUV444ConvertersSSE2(void);
+
+#define YUV444_FUNC(FUNC_NAME, CALL, XSTEP) \
+extern void WebP##FUNC_NAME##C(const uint8_t* y, const uint8_t* u, \
+ const uint8_t* v, uint8_t* dst, int len); \
+static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v, \
+ uint8_t* dst, int len) { \
+ int i; \
+ const int max_len = len & ~31; \
+ for (i = 0; i < max_len; i += 32) CALL(y + i, u + i, v + i, dst + i * XSTEP);\
+ if (i < len) { /* C-fallback */ \
+ WebP##FUNC_NAME##C(y + i, u + i, v + i, dst + i * XSTEP, len - i); \
+ } \
+}
+
+YUV444_FUNC(Yuv444ToRgba, VP8YuvToRgba32, 4);
+YUV444_FUNC(Yuv444ToBgra, VP8YuvToBgra32, 4);
+YUV444_FUNC(Yuv444ToRgb, VP8YuvToRgb32, 3);
+YUV444_FUNC(Yuv444ToBgr, VP8YuvToBgr32, 3);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444ConvertersSSE2(void) {
+ WebPYUV444Converters[MODE_RGBA] = Yuv444ToRgba;
+ WebPYUV444Converters[MODE_BGRA] = Yuv444ToBgra;
+ WebPYUV444Converters[MODE_RGB] = Yuv444ToRgb;
+ WebPYUV444Converters[MODE_BGR] = Yuv444ToBgr;
+}
+
+#else
+
+WEBP_DSP_INIT_STUB(WebPInitYUV444ConvertersSSE2)
+
+#endif // WEBP_USE_SSE2
+
+#if !(defined(FANCY_UPSAMPLING) && defined(WEBP_USE_SSE2))
+WEBP_DSP_INIT_STUB(WebPInitUpsamplersSSE2)
+#endif
diff --git a/media/libwebp/dsp/yuv.c b/media/libwebp/dsp/yuv.c
new file mode 100644
index 000000000..dd7d9dedf
--- /dev/null
+++ b/media/libwebp/dsp/yuv.c
@@ -0,0 +1,337 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV->RGB conversion functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./yuv.h"
+
+#include <stdlib.h>
+
+#if defined(WEBP_YUV_USE_TABLE)
+
+static int done = 0;
+
+static WEBP_INLINE uint8_t clip(int v, int max_value) {
+ return v < 0 ? 0 : v > max_value ? max_value : v;
+}
+
+int16_t VP8kVToR[256], VP8kUToB[256];
+int32_t VP8kVToG[256], VP8kUToG[256];
+uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
+uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {
+ int i;
+ if (done) {
+ return;
+ }
+#ifndef USE_YUVj
+ for (i = 0; i < 256; ++i) {
+ VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX;
+ VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF;
+ VP8kVToG[i] = -45773 * (i - 128);
+ VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX;
+ }
+ for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
+ const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX;
+ VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255);
+ VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15);
+ }
+#else
+ for (i = 0; i < 256; ++i) {
+ VP8kVToR[i] = (91881 * (i - 128) + YUV_HALF) >> YUV_FIX;
+ VP8kUToG[i] = -22554 * (i - 128) + YUV_HALF;
+ VP8kVToG[i] = -46802 * (i - 128);
+ VP8kUToB[i] = (116130 * (i - 128) + YUV_HALF) >> YUV_FIX;
+ }
+ for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
+ const int k = i;
+ VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255);
+ VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15);
+ }
+#endif
+
+ done = 1;
+}
+
+#else
+
+WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {}
+
+#endif // WEBP_YUV_USE_TABLE
+
+//-----------------------------------------------------------------------------
+// Plain-C version
+
+#define ROW_FUNC(FUNC_NAME, FUNC, XSTEP) \
+static void FUNC_NAME(const uint8_t* y, \
+ const uint8_t* u, const uint8_t* v, \
+ uint8_t* dst, int len) { \
+ const uint8_t* const end = dst + (len & ~1) * XSTEP; \
+ while (dst != end) { \
+ FUNC(y[0], u[0], v[0], dst); \
+ FUNC(y[1], u[0], v[0], dst + XSTEP); \
+ y += 2; \
+ ++u; \
+ ++v; \
+ dst += 2 * XSTEP; \
+ } \
+ if (len & 1) { \
+ FUNC(y[0], u[0], v[0], dst); \
+ } \
+} \
+
+// All variants implemented.
+ROW_FUNC(YuvToRgbRow, VP8YuvToRgb, 3)
+ROW_FUNC(YuvToBgrRow, VP8YuvToBgr, 3)
+ROW_FUNC(YuvToRgbaRow, VP8YuvToRgba, 4)
+ROW_FUNC(YuvToBgraRow, VP8YuvToBgra, 4)
+ROW_FUNC(YuvToArgbRow, VP8YuvToArgb, 4)
+ROW_FUNC(YuvToRgba4444Row, VP8YuvToRgba4444, 2)
+ROW_FUNC(YuvToRgb565Row, VP8YuvToRgb565, 2)
+
+#undef ROW_FUNC
+
+// Main call for processing a plane with a WebPSamplerRowFunc function:
+void WebPSamplerProcessPlane(const uint8_t* y, int y_stride,
+ const uint8_t* u, const uint8_t* v, int uv_stride,
+ uint8_t* dst, int dst_stride,
+ int width, int height, WebPSamplerRowFunc func) {
+ int j;
+ for (j = 0; j < height; ++j) {
+ func(y, u, v, dst, width);
+ y += y_stride;
+ if (j & 1) {
+ u += uv_stride;
+ v += uv_stride;
+ }
+ dst += dst_stride;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Main call
+
+WebPSamplerRowFunc WebPSamplers[MODE_LAST];
+
+extern void WebPInitSamplersSSE2(void);
+extern void WebPInitSamplersMIPS32(void);
+extern void WebPInitSamplersMIPSdspR2(void);
+
+static volatile VP8CPUInfo yuv_last_cpuinfo_used =
+ (VP8CPUInfo)&yuv_last_cpuinfo_used;
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) {
+ if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ WebPSamplers[MODE_RGB] = YuvToRgbRow;
+ WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
+ WebPSamplers[MODE_BGR] = YuvToBgrRow;
+ WebPSamplers[MODE_BGRA] = YuvToBgraRow;
+ WebPSamplers[MODE_ARGB] = YuvToArgbRow;
+ WebPSamplers[MODE_RGBA_4444] = YuvToRgba4444Row;
+ WebPSamplers[MODE_RGB_565] = YuvToRgb565Row;
+ WebPSamplers[MODE_rgbA] = YuvToRgbaRow;
+ WebPSamplers[MODE_bgrA] = YuvToBgraRow;
+ WebPSamplers[MODE_Argb] = YuvToArgbRow;
+ WebPSamplers[MODE_rgbA_4444] = YuvToRgba4444Row;
+
+ // If defined, use CPUInfo() to overwrite some pointers with faster versions.
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ WebPInitSamplersSSE2();
+ }
+#endif // WEBP_USE_SSE2
+#if defined(WEBP_USE_MIPS32)
+ if (VP8GetCPUInfo(kMIPS32)) {
+ WebPInitSamplersMIPS32();
+ }
+#endif // WEBP_USE_MIPS32
+#if defined(WEBP_USE_MIPS_DSP_R2)
+ if (VP8GetCPUInfo(kMIPSdspR2)) {
+ WebPInitSamplersMIPSdspR2();
+ }
+#endif // WEBP_USE_MIPS_DSP_R2
+ }
+ yuv_last_cpuinfo_used = VP8GetCPUInfo;
+}
+
+//-----------------------------------------------------------------------------
+// ARGB -> YUV converters
+
+static void ConvertARGBToY(const uint32_t* argb, uint8_t* y, int width) {
+ int i;
+ for (i = 0; i < width; ++i) {
+ const uint32_t p = argb[i];
+ y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff,
+ YUV_HALF);
+ }
+}
+
+void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v,
+ int src_width, int do_store) {
+ // No rounding. Last pixel is dealt with separately.
+ const int uv_width = src_width >> 1;
+ int i;
+ for (i = 0; i < uv_width; ++i) {
+ const uint32_t v0 = argb[2 * i + 0];
+ const uint32_t v1 = argb[2 * i + 1];
+ // VP8RGBToU/V expects four accumulated pixels. Hence we need to
+ // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less.
+ const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe);
+ const int g = ((v0 >> 7) & 0x1fe) + ((v1 >> 7) & 0x1fe);
+ const int b = ((v0 << 1) & 0x1fe) + ((v1 << 1) & 0x1fe);
+ const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
+ const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
+ if (do_store) {
+ u[i] = tmp_u;
+ v[i] = tmp_v;
+ } else {
+ // Approximated average-of-four. But it's an acceptable diff.
+ u[i] = (u[i] + tmp_u + 1) >> 1;
+ v[i] = (v[i] + tmp_v + 1) >> 1;
+ }
+ }
+ if (src_width & 1) { // last pixel
+ const uint32_t v0 = argb[2 * i + 0];
+ const int r = (v0 >> 14) & 0x3fc;
+ const int g = (v0 >> 6) & 0x3fc;
+ const int b = (v0 << 2) & 0x3fc;
+ const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
+ const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
+ if (do_store) {
+ u[i] = tmp_u;
+ v[i] = tmp_v;
+ } else {
+ u[i] = (u[i] + tmp_u + 1) >> 1;
+ v[i] = (v[i] + tmp_v + 1) >> 1;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+static void ConvertRGB24ToY(const uint8_t* rgb, uint8_t* y, int width) {
+ int i;
+ for (i = 0; i < width; ++i, rgb += 3) {
+ y[i] = VP8RGBToY(rgb[0], rgb[1], rgb[2], YUV_HALF);
+ }
+}
+
+static void ConvertBGR24ToY(const uint8_t* bgr, uint8_t* y, int width) {
+ int i;
+ for (i = 0; i < width; ++i, bgr += 3) {
+ y[i] = VP8RGBToY(bgr[2], bgr[1], bgr[0], YUV_HALF);
+ }
+}
+
+void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
+ uint8_t* u, uint8_t* v, int width) {
+ int i;
+ for (i = 0; i < width; i += 1, rgb += 4) {
+ const int r = rgb[0], g = rgb[1], b = rgb[2];
+ u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2);
+ v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+#define MAX_Y ((1 << 10) - 1) // 10b precision over 16b-arithmetic
+static uint16_t clip_y(int v) {
+ return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
+}
+
+static uint64_t SharpYUVUpdateY_C(const uint16_t* ref, const uint16_t* src,
+ uint16_t* dst, int len) {
+ uint64_t diff = 0;
+ int i;
+ for (i = 0; i < len; ++i) {
+ const int diff_y = ref[i] - src[i];
+ const int new_y = (int)dst[i] + diff_y;
+ dst[i] = clip_y(new_y);
+ diff += (uint64_t)abs(diff_y);
+ }
+ return diff;
+}
+
+static void SharpYUVUpdateRGB_C(const int16_t* ref, const int16_t* src,
+ int16_t* dst, int len) {
+ int i;
+ for (i = 0; i < len; ++i) {
+ const int diff_uv = ref[i] - src[i];
+ dst[i] += diff_uv;
+ }
+}
+
+static void SharpYUVFilterRow_C(const int16_t* A, const int16_t* B, int len,
+ const uint16_t* best_y, uint16_t* out) {
+ int i;
+ for (i = 0; i < len; ++i, ++A, ++B) {
+ const int v0 = (A[0] * 9 + A[1] * 3 + B[0] * 3 + B[1] + 8) >> 4;
+ const int v1 = (A[1] * 9 + A[0] * 3 + B[1] * 3 + B[0] + 8) >> 4;
+ out[2 * i + 0] = clip_y(best_y[2 * i + 0] + v0);
+ out[2 * i + 1] = clip_y(best_y[2 * i + 1] + v1);
+ }
+}
+
+#undef MAX_Y
+
+//-----------------------------------------------------------------------------
+
+void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width);
+void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width);
+void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb,
+ uint8_t* u, uint8_t* v, int width);
+
+void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width);
+void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v,
+ int src_width, int do_store);
+
+uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* ref, const uint16_t* src,
+ uint16_t* dst, int len);
+void (*WebPSharpYUVUpdateRGB)(const int16_t* ref, const int16_t* src,
+ int16_t* dst, int len);
+void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len,
+ const uint16_t* best_y, uint16_t* out);
+
+static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used =
+ (VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used;
+
+extern void WebPInitConvertARGBToYUVSSE2(void);
+extern void WebPInitSharpYUVSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) {
+ if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
+
+ WebPConvertARGBToY = ConvertARGBToY;
+ WebPConvertARGBToUV = WebPConvertARGBToUV_C;
+
+ WebPConvertRGB24ToY = ConvertRGB24ToY;
+ WebPConvertBGR24ToY = ConvertBGR24ToY;
+
+ WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C;
+
+ WebPSharpYUVUpdateY = SharpYUVUpdateY_C;
+ WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_C;
+ WebPSharpYUVFilterRow = SharpYUVFilterRow_C;
+
+ if (VP8GetCPUInfo != NULL) {
+#if defined(WEBP_USE_SSE2)
+ if (VP8GetCPUInfo(kSSE2)) {
+ WebPInitConvertARGBToYUVSSE2();
+ WebPInitSharpYUVSSE2();
+ }
+#endif // WEBP_USE_SSE2
+ }
+ rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo;
+}
diff --git a/media/libwebp/dsp/yuv.h b/media/libwebp/dsp/yuv.h
new file mode 100644
index 000000000..1d33b5863
--- /dev/null
+++ b/media/libwebp/dsp/yuv.h
@@ -0,0 +1,238 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// inline YUV<->RGB conversion function
+//
+// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
+// More information at: http://en.wikipedia.org/wiki/YCbCr
+// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
+// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
+// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
+// We use 16bit fixed point operations for RGB->YUV conversion (YUV_FIX).
+//
+// For the Y'CbCr to RGB conversion, the BT.601 specification reads:
+// R = 1.164 * (Y-16) + 1.596 * (V-128)
+// G = 1.164 * (Y-16) - 0.813 * (V-128) - 0.391 * (U-128)
+// B = 1.164 * (Y-16) + 2.018 * (U-128)
+// where Y is in the [16,235] range, and U/V in the [16,240] range.
+//
+// The fixed-point implementation used here is:
+// R = (19077 . y + 26149 . v - 14234) >> 6
+// G = (19077 . y - 6419 . u - 13320 . v + 8708) >> 6
+// B = (19077 . y + 33050 . u - 17685) >> 6
+// where the '.' operator is the mulhi_epu16 variant:
+// a . b = ((a << 8) * b) >> 16
+// that preserves 8 bits of fractional precision before final descaling.
+
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_DSP_YUV_H_
+#define WEBP_DSP_YUV_H_
+
+#include "./dsp.h"
+#include "../dec/vp8_dec.h"
+
+#if defined(WEBP_EXPERIMENTAL_FEATURES)
+// Do NOT activate this feature for real compression. This is only experimental!
+// This flag is for comparison purpose against JPEG's "YUVj" natural colorspace.
+// This colorspace is close to Rec.601's Y'CbCr model with the notable
+// difference of allowing larger range for luma/chroma.
+// See http://en.wikipedia.org/wiki/YCbCr#JPEG_conversion paragraph, and its
+// difference with http://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion
+// #define USE_YUVj
+#endif
+
+//------------------------------------------------------------------------------
+// YUV -> RGB conversion
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ YUV_FIX = 16, // fixed-point precision for RGB->YUV
+ YUV_HALF = 1 << (YUV_FIX - 1),
+ YUV_MASK = (256 << YUV_FIX) - 1,
+ YUV_RANGE_MIN = -227, // min value of r/g/b output
+ YUV_RANGE_MAX = 256 + 226, // max value of r/g/b output
+
+ YUV_FIX2 = 6, // fixed-point precision for YUV->RGB
+ YUV_HALF2 = 1 << YUV_FIX2 >> 1,
+ YUV_MASK2 = (256 << YUV_FIX2) - 1
+};
+
+//------------------------------------------------------------------------------
+// slower on x86 by ~7-8%, but bit-exact with the SSE2/NEON version
+
+static WEBP_INLINE int MultHi(int v, int coeff) { // _mm_mulhi_epu16 emulation
+ return (v * coeff) >> 8;
+}
+
+static WEBP_INLINE int VP8Clip8(int v) {
+ return ((v & ~YUV_MASK2) == 0) ? (v >> YUV_FIX2) : (v < 0) ? 0 : 255;
+}
+
+static WEBP_INLINE int VP8YUVToR(int y, int v) {
+ return VP8Clip8(MultHi(y, 19077) + MultHi(v, 26149) - 14234);
+}
+
+static WEBP_INLINE int VP8YUVToG(int y, int u, int v) {
+ return VP8Clip8(MultHi(y, 19077) - MultHi(u, 6419) - MultHi(v, 13320) + 8708);
+}
+
+static WEBP_INLINE int VP8YUVToB(int y, int u) {
+ return VP8Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685);
+}
+
+static WEBP_INLINE void VP8YuvToRgb(int y, int u, int v,
+ uint8_t* const rgb) {
+ rgb[0] = VP8YUVToR(y, v);
+ rgb[1] = VP8YUVToG(y, u, v);
+ rgb[2] = VP8YUVToB(y, u);
+}
+
+static WEBP_INLINE void VP8YuvToBgr(int y, int u, int v,
+ uint8_t* const bgr) {
+ bgr[0] = VP8YUVToB(y, u);
+ bgr[1] = VP8YUVToG(y, u, v);
+ bgr[2] = VP8YUVToR(y, v);
+}
+
+static WEBP_INLINE void VP8YuvToRgb565(int y, int u, int v,
+ uint8_t* const rgb) {
+ const int r = VP8YUVToR(y, v); // 5 usable bits
+ const int g = VP8YUVToG(y, u, v); // 6 usable bits
+ const int b = VP8YUVToB(y, u); // 5 usable bits
+ const int rg = (r & 0xf8) | (g >> 5);
+ const int gb = ((g << 3) & 0xe0) | (b >> 3);
+#ifdef WEBP_SWAP_16BIT_CSP
+ rgb[0] = gb;
+ rgb[1] = rg;
+#else
+ rgb[0] = rg;
+ rgb[1] = gb;
+#endif
+}
+
+static WEBP_INLINE void VP8YuvToRgba4444(int y, int u, int v,
+ uint8_t* const argb) {
+ const int r = VP8YUVToR(y, v); // 4 usable bits
+ const int g = VP8YUVToG(y, u, v); // 4 usable bits
+ const int b = VP8YUVToB(y, u); // 4 usable bits
+ const int rg = (r & 0xf0) | (g >> 4);
+ const int ba = (b & 0xf0) | 0x0f; // overwrite the lower 4 bits
+#ifdef WEBP_SWAP_16BIT_CSP
+ argb[0] = ba;
+ argb[1] = rg;
+#else
+ argb[0] = rg;
+ argb[1] = ba;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Alpha handling variants
+
+static WEBP_INLINE void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
+ uint8_t* const argb) {
+ argb[0] = 0xff;
+ VP8YuvToRgb(y, u, v, argb + 1);
+}
+
+static WEBP_INLINE void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
+ uint8_t* const bgra) {
+ VP8YuvToBgr(y, u, v, bgra);
+ bgra[3] = 0xff;
+}
+
+static WEBP_INLINE void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
+ uint8_t* const rgba) {
+ VP8YuvToRgb(y, u, v, rgba);
+ rgba[3] = 0xff;
+}
+
+// Must be called before everything, to initialize the tables.
+void VP8YUVInit(void);
+
+//-----------------------------------------------------------------------------
+// SSE2 extra functions (mostly for upsampling_sse2.c)
+
+#if defined(WEBP_USE_SSE2)
+
+// Process 32 pixels and store the result (16b, 24b or 32b per pixel) in *dst.
+void VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+void VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+void VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+void VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+void VP8YuvToArgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+void VP8YuvToRgba444432(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+void VP8YuvToRgb56532(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst);
+
+#endif // WEBP_USE_SSE2
+
+//------------------------------------------------------------------------------
+// RGB -> YUV conversion
+
+// Stub functions that can be called with various rounding values:
+static WEBP_INLINE int VP8ClipUV(int uv, int rounding) {
+ uv = (uv + rounding + (128 << (YUV_FIX + 2))) >> (YUV_FIX + 2);
+ return ((uv & ~0xff) == 0) ? uv : (uv < 0) ? 0 : 255;
+}
+
+#ifndef USE_YUVj
+
+static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
+ const int luma = 16839 * r + 33059 * g + 6420 * b;
+ return (luma + rounding + (16 << YUV_FIX)) >> YUV_FIX; // no need to clip
+}
+
+static WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
+ const int u = -9719 * r - 19081 * g + 28800 * b;
+ return VP8ClipUV(u, rounding);
+}
+
+static WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
+ const int v = +28800 * r - 24116 * g - 4684 * b;
+ return VP8ClipUV(v, rounding);
+}
+
+#else
+
+// This JPEG-YUV colorspace, only for comparison!
+// These are also 16bit precision coefficients from Rec.601, but with full
+// [0..255] output range.
+static WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
+ const int luma = 19595 * r + 38470 * g + 7471 * b;
+ return (luma + rounding) >> YUV_FIX; // no need to clip
+}
+
+static WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
+ const int u = -11058 * r - 21710 * g + 32768 * b;
+ return VP8ClipUV(u, rounding);
+}
+
+static WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
+ const int v = 32768 * r - 27439 * g - 5329 * b;
+ return VP8ClipUV(v, rounding);
+}
+
+#endif // USE_YUVj
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_DSP_YUV_H_ */
diff --git a/media/libwebp/dsp/yuv_sse2.c b/media/libwebp/dsp/yuv_sse2.c
new file mode 100644
index 000000000..e33c2bbaf
--- /dev/null
+++ b/media/libwebp/dsp/yuv_sse2.c
@@ -0,0 +1,863 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// YUV->RGB conversion functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./yuv.h"
+
+#if defined(WEBP_USE_SSE2)
+
+#include "./common_sse2.h"
+#include <stdlib.h>
+#include <emmintrin.h>
+
+//-----------------------------------------------------------------------------
+// Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
+
+// These constants are 14b fixed-point version of ITU-R BT.601 constants.
+// R = (19077 * y + 26149 * v - 14234) >> 6
+// G = (19077 * y - 6419 * u - 13320 * v + 8708) >> 6
+// B = (19077 * y + 33050 * u - 17685) >> 6
+static void ConvertYUV444ToRGB(const __m128i* const Y0,
+ const __m128i* const U0,
+ const __m128i* const V0,
+ __m128i* const R,
+ __m128i* const G,
+ __m128i* const B) {
+ const __m128i k19077 = _mm_set1_epi16(19077);
+ const __m128i k26149 = _mm_set1_epi16(26149);
+ const __m128i k14234 = _mm_set1_epi16(14234);
+ // 33050 doesn't fit in a signed short: only use this with unsigned arithmetic
+ const __m128i k33050 = _mm_set1_epi16((short)33050);
+ const __m128i k17685 = _mm_set1_epi16(17685);
+ const __m128i k6419 = _mm_set1_epi16(6419);
+ const __m128i k13320 = _mm_set1_epi16(13320);
+ const __m128i k8708 = _mm_set1_epi16(8708);
+
+ const __m128i Y1 = _mm_mulhi_epu16(*Y0, k19077);
+
+ const __m128i R0 = _mm_mulhi_epu16(*V0, k26149);
+ const __m128i R1 = _mm_sub_epi16(Y1, k14234);
+ const __m128i R2 = _mm_add_epi16(R1, R0);
+
+ const __m128i G0 = _mm_mulhi_epu16(*U0, k6419);
+ const __m128i G1 = _mm_mulhi_epu16(*V0, k13320);
+ const __m128i G2 = _mm_add_epi16(Y1, k8708);
+ const __m128i G3 = _mm_add_epi16(G0, G1);
+ const __m128i G4 = _mm_sub_epi16(G2, G3);
+
+ // be careful with the saturated *unsigned* arithmetic here!
+ const __m128i B0 = _mm_mulhi_epu16(*U0, k33050);
+ const __m128i B1 = _mm_adds_epu16(B0, Y1);
+ const __m128i B2 = _mm_subs_epu16(B1, k17685);
+
+ // use logical shift for B2, which can be larger than 32767
+ *R = _mm_srai_epi16(R2, 6); // range: [-14234, 30815]
+ *G = _mm_srai_epi16(G4, 6); // range: [-10953, 27710]
+ *B = _mm_srli_epi16(B2, 6); // range: [0, 34238]
+}
+
+// Load the bytes into the *upper* part of 16b words. That's "<< 8", basically.
+static WEBP_INLINE __m128i Load_HI_16(const uint8_t* src) {
+ const __m128i zero = _mm_setzero_si128();
+ return _mm_unpacklo_epi8(zero, _mm_loadl_epi64((const __m128i*)src));
+}
+
+// Load and replicate the U/V samples
+static WEBP_INLINE __m128i Load_UV_HI_8(const uint8_t* src) {
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+ const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
+ return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples
+}
+
+// Convert 32 samples of YUV444 to R/G/B
+static void YUV444ToRGB(const uint8_t* const y,
+ const uint8_t* const u,
+ const uint8_t* const v,
+ __m128i* const R, __m128i* const G, __m128i* const B) {
+ const __m128i Y0 = Load_HI_16(y), U0 = Load_HI_16(u), V0 = Load_HI_16(v);
+ ConvertYUV444ToRGB(&Y0, &U0, &V0, R, G, B);
+}
+
+// Convert 32 samples of YUV420 to R/G/B
+static void YUV420ToRGB(const uint8_t* const y,
+ const uint8_t* const u,
+ const uint8_t* const v,
+ __m128i* const R, __m128i* const G, __m128i* const B) {
+ const __m128i Y0 = Load_HI_16(y), U0 = Load_UV_HI_8(u), V0 = Load_UV_HI_8(v);
+ ConvertYUV444ToRGB(&Y0, &U0, &V0, R, G, B);
+}
+
+// Pack R/G/B/A results into 32b output.
+static WEBP_INLINE void PackAndStore4(const __m128i* const R,
+ const __m128i* const G,
+ const __m128i* const B,
+ const __m128i* const A,
+ uint8_t* const dst) {
+ const __m128i rb = _mm_packus_epi16(*R, *B);
+ const __m128i ga = _mm_packus_epi16(*G, *A);
+ const __m128i rg = _mm_unpacklo_epi8(rb, ga);
+ const __m128i ba = _mm_unpackhi_epi8(rb, ga);
+ const __m128i RGBA_lo = _mm_unpacklo_epi16(rg, ba);
+ const __m128i RGBA_hi = _mm_unpackhi_epi16(rg, ba);
+ _mm_storeu_si128((__m128i*)(dst + 0), RGBA_lo);
+ _mm_storeu_si128((__m128i*)(dst + 16), RGBA_hi);
+}
+
+// Pack R/G/B/A results into 16b output.
+static WEBP_INLINE void PackAndStore4444(const __m128i* const R,
+ const __m128i* const G,
+ const __m128i* const B,
+ const __m128i* const A,
+ uint8_t* const dst) {
+#if !defined(WEBP_SWAP_16BIT_CSP)
+ const __m128i rg0 = _mm_packus_epi16(*R, *G);
+ const __m128i ba0 = _mm_packus_epi16(*B, *A);
+#else
+ const __m128i rg0 = _mm_packus_epi16(*B, *A);
+ const __m128i ba0 = _mm_packus_epi16(*R, *G);
+#endif
+ const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+ const __m128i rb1 = _mm_unpacklo_epi8(rg0, ba0); // rbrbrbrbrb...
+ const __m128i ga1 = _mm_unpackhi_epi8(rg0, ba0); // gagagagaga...
+ const __m128i rb2 = _mm_and_si128(rb1, mask_0xf0);
+ const __m128i ga2 = _mm_srli_epi16(_mm_and_si128(ga1, mask_0xf0), 4);
+ const __m128i rgba4444 = _mm_or_si128(rb2, ga2);
+ _mm_storeu_si128((__m128i*)dst, rgba4444);
+}
+
+// Pack R/G/B results into 16b output.
+static WEBP_INLINE void PackAndStore565(const __m128i* const R,
+ const __m128i* const G,
+ const __m128i* const B,
+ uint8_t* const dst) {
+ const __m128i r0 = _mm_packus_epi16(*R, *R);
+ const __m128i g0 = _mm_packus_epi16(*G, *G);
+ const __m128i b0 = _mm_packus_epi16(*B, *B);
+ const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8(0xf8));
+ const __m128i b1 = _mm_and_si128(_mm_srli_epi16(b0, 3), _mm_set1_epi8(0x1f));
+ const __m128i g1 = _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0xe0)), 5);
+ const __m128i g2 = _mm_slli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0x1c)), 3);
+ const __m128i rg = _mm_or_si128(r1, g1);
+ const __m128i gb = _mm_or_si128(g2, b1);
+#if !defined(WEBP_SWAP_16BIT_CSP)
+ const __m128i rgb565 = _mm_unpacklo_epi8(rg, gb);
+#else
+ const __m128i rgb565 = _mm_unpacklo_epi8(gb, rg);
+#endif
+ _mm_storeu_si128((__m128i*)dst, rgb565);
+}
+
+// Pack the planar buffers
+// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
+// triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ...
+static WEBP_INLINE void PlanarTo24b(__m128i* const in0, __m128i* const in1,
+ __m128i* const in2, __m128i* const in3,
+ __m128i* const in4, __m128i* const in5,
+ uint8_t* const rgb) {
+ // The input is 6 registers of sixteen 8b but for the sake of explanation,
+ // let's take 6 registers of four 8b values.
+ // To pack, we will keep taking one every two 8b integer and move it
+ // around as follows:
+ // Input:
+ // r0r1r2r3 | r4r5r6r7 | g0g1g2g3 | g4g5g6g7 | b0b1b2b3 | b4b5b6b7
+ // Split the 6 registers in two sets of 3 registers: the first set as the even
+ // 8b bytes, the second the odd ones:
+ // r0r2r4r6 | g0g2g4g6 | b0b2b4b6 | r1r3r5r7 | g1g3g5g7 | b1b3b5b7
+ // Repeat the same permutations twice more:
+ // r0r4g0g4 | b0b4r1r5 | g1g5b1b5 | r2r6g2g6 | b2b6r3r7 | g3g7b3b7
+ // r0g0b0r1 | g1b1r2g2 | b2r3g3b3 | r4g4b4r5 | g5b5r6g6 | b6r7g7b7
+ VP8PlanarTo24b(in0, in1, in2, in3, in4, in5);
+
+ _mm_storeu_si128((__m128i*)(rgb + 0), *in0);
+ _mm_storeu_si128((__m128i*)(rgb + 16), *in1);
+ _mm_storeu_si128((__m128i*)(rgb + 32), *in2);
+ _mm_storeu_si128((__m128i*)(rgb + 48), *in3);
+ _mm_storeu_si128((__m128i*)(rgb + 64), *in4);
+ _mm_storeu_si128((__m128i*)(rgb + 80), *in5);
+}
+
+void VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n < 32; n += 8, dst += 32) {
+ __m128i R, G, B;
+ YUV444ToRGB(y + n, u + n, v + n, &R, &G, &B);
+ PackAndStore4(&R, &G, &B, &kAlpha, dst);
+ }
+}
+
+void VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n < 32; n += 8, dst += 32) {
+ __m128i R, G, B;
+ YUV444ToRGB(y + n, u + n, v + n, &R, &G, &B);
+ PackAndStore4(&B, &G, &R, &kAlpha, dst);
+ }
+}
+
+void VP8YuvToArgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n < 32; n += 8, dst += 32) {
+ __m128i R, G, B;
+ YUV444ToRGB(y + n, u + n, v + n, &R, &G, &B);
+ PackAndStore4(&kAlpha, &R, &G, &B, dst);
+ }
+}
+
+void VP8YuvToRgba444432(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n < 32; n += 8, dst += 16) {
+ __m128i R, G, B;
+ YUV444ToRGB(y + n, u + n, v + n, &R, &G, &B);
+ PackAndStore4444(&R, &G, &B, &kAlpha, dst);
+ }
+}
+
+void VP8YuvToRgb56532(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ int n;
+ for (n = 0; n < 32; n += 8, dst += 16) {
+ __m128i R, G, B;
+ YUV444ToRGB(y + n, u + n, v + n, &R, &G, &B);
+ PackAndStore565(&R, &G, &B, dst);
+ }
+}
+
+void VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ __m128i R0, R1, R2, R3, G0, G1, G2, G3, B0, B1, B2, B3;
+ __m128i rgb0, rgb1, rgb2, rgb3, rgb4, rgb5;
+
+ YUV444ToRGB(y + 0, u + 0, v + 0, &R0, &G0, &B0);
+ YUV444ToRGB(y + 8, u + 8, v + 8, &R1, &G1, &B1);
+ YUV444ToRGB(y + 16, u + 16, v + 16, &R2, &G2, &B2);
+ YUV444ToRGB(y + 24, u + 24, v + 24, &R3, &G3, &B3);
+
+ // Cast to 8b and store as RRRRGGGGBBBB.
+ rgb0 = _mm_packus_epi16(R0, R1);
+ rgb1 = _mm_packus_epi16(R2, R3);
+ rgb2 = _mm_packus_epi16(G0, G1);
+ rgb3 = _mm_packus_epi16(G2, G3);
+ rgb4 = _mm_packus_epi16(B0, B1);
+ rgb5 = _mm_packus_epi16(B2, B3);
+
+ // Pack as RGBRGBRGBRGB.
+ PlanarTo24b(&rgb0, &rgb1, &rgb2, &rgb3, &rgb4, &rgb5, dst);
+}
+
+void VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst) {
+ __m128i R0, R1, R2, R3, G0, G1, G2, G3, B0, B1, B2, B3;
+ __m128i bgr0, bgr1, bgr2, bgr3, bgr4, bgr5;
+
+ YUV444ToRGB(y + 0, u + 0, v + 0, &R0, &G0, &B0);
+ YUV444ToRGB(y + 8, u + 8, v + 8, &R1, &G1, &B1);
+ YUV444ToRGB(y + 16, u + 16, v + 16, &R2, &G2, &B2);
+ YUV444ToRGB(y + 24, u + 24, v + 24, &R3, &G3, &B3);
+
+ // Cast to 8b and store as BBBBGGGGRRRR.
+ bgr0 = _mm_packus_epi16(B0, B1);
+ bgr1 = _mm_packus_epi16(B2, B3);
+ bgr2 = _mm_packus_epi16(G0, G1);
+ bgr3 = _mm_packus_epi16(G2, G3);
+ bgr4 = _mm_packus_epi16(R0, R1);
+ bgr5= _mm_packus_epi16(R2, R3);
+
+ // Pack as BGRBGRBGRBGR.
+ PlanarTo24b(&bgr0, &bgr1, &bgr2, &bgr3, &bgr4, &bgr5, dst);
+}
+
+//-----------------------------------------------------------------------------
+// Arbitrary-length row conversion functions
+
+static void YuvToRgbaRow(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n + 8 <= len; n += 8, dst += 32) {
+ __m128i R, G, B;
+ YUV420ToRGB(y, u, v, &R, &G, &B);
+ PackAndStore4(&R, &G, &B, &kAlpha, dst);
+ y += 8;
+ u += 4;
+ v += 4;
+ }
+ for (; n < len; ++n) { // Finish off
+ VP8YuvToRgba(y[0], u[0], v[0], dst);
+ dst += 4;
+ y += 1;
+ u += (n & 1);
+ v += (n & 1);
+ }
+}
+
+static void YuvToBgraRow(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n + 8 <= len; n += 8, dst += 32) {
+ __m128i R, G, B;
+ YUV420ToRGB(y, u, v, &R, &G, &B);
+ PackAndStore4(&B, &G, &R, &kAlpha, dst);
+ y += 8;
+ u += 4;
+ v += 4;
+ }
+ for (; n < len; ++n) { // Finish off
+ VP8YuvToBgra(y[0], u[0], v[0], dst);
+ dst += 4;
+ y += 1;
+ u += (n & 1);
+ v += (n & 1);
+ }
+}
+
+static void YuvToArgbRow(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len) {
+ const __m128i kAlpha = _mm_set1_epi16(255);
+ int n;
+ for (n = 0; n + 8 <= len; n += 8, dst += 32) {
+ __m128i R, G, B;
+ YUV420ToRGB(y, u, v, &R, &G, &B);
+ PackAndStore4(&kAlpha, &R, &G, &B, dst);
+ y += 8;
+ u += 4;
+ v += 4;
+ }
+ for (; n < len; ++n) { // Finish off
+ VP8YuvToArgb(y[0], u[0], v[0], dst);
+ dst += 4;
+ y += 1;
+ u += (n & 1);
+ v += (n & 1);
+ }
+}
+
+static void YuvToRgbRow(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len) {
+ int n;
+ for (n = 0; n + 32 <= len; n += 32, dst += 32 * 3) {
+ __m128i R0, R1, R2, R3, G0, G1, G2, G3, B0, B1, B2, B3;
+ __m128i rgb0, rgb1, rgb2, rgb3, rgb4, rgb5;
+
+ YUV420ToRGB(y + 0, u + 0, v + 0, &R0, &G0, &B0);
+ YUV420ToRGB(y + 8, u + 4, v + 4, &R1, &G1, &B1);
+ YUV420ToRGB(y + 16, u + 8, v + 8, &R2, &G2, &B2);
+ YUV420ToRGB(y + 24, u + 12, v + 12, &R3, &G3, &B3);
+
+ // Cast to 8b and store as RRRRGGGGBBBB.
+ rgb0 = _mm_packus_epi16(R0, R1);
+ rgb1 = _mm_packus_epi16(R2, R3);
+ rgb2 = _mm_packus_epi16(G0, G1);
+ rgb3 = _mm_packus_epi16(G2, G3);
+ rgb4 = _mm_packus_epi16(B0, B1);
+ rgb5 = _mm_packus_epi16(B2, B3);
+
+ // Pack as RGBRGBRGBRGB.
+ PlanarTo24b(&rgb0, &rgb1, &rgb2, &rgb3, &rgb4, &rgb5, dst);
+
+ y += 32;
+ u += 16;
+ v += 16;
+ }
+ for (; n < len; ++n) { // Finish off
+ VP8YuvToRgb(y[0], u[0], v[0], dst);
+ dst += 3;
+ y += 1;
+ u += (n & 1);
+ v += (n & 1);
+ }
+}
+
+static void YuvToBgrRow(const uint8_t* y, const uint8_t* u, const uint8_t* v,
+ uint8_t* dst, int len) {
+ int n;
+ for (n = 0; n + 32 <= len; n += 32, dst += 32 * 3) {
+ __m128i R0, R1, R2, R3, G0, G1, G2, G3, B0, B1, B2, B3;
+ __m128i bgr0, bgr1, bgr2, bgr3, bgr4, bgr5;
+
+ YUV420ToRGB(y + 0, u + 0, v + 0, &R0, &G0, &B0);
+ YUV420ToRGB(y + 8, u + 4, v + 4, &R1, &G1, &B1);
+ YUV420ToRGB(y + 16, u + 8, v + 8, &R2, &G2, &B2);
+ YUV420ToRGB(y + 24, u + 12, v + 12, &R3, &G3, &B3);
+
+ // Cast to 8b and store as BBBBGGGGRRRR.
+ bgr0 = _mm_packus_epi16(B0, B1);
+ bgr1 = _mm_packus_epi16(B2, B3);
+ bgr2 = _mm_packus_epi16(G0, G1);
+ bgr3 = _mm_packus_epi16(G2, G3);
+ bgr4 = _mm_packus_epi16(R0, R1);
+ bgr5 = _mm_packus_epi16(R2, R3);
+
+ // Pack as BGRBGRBGRBGR.
+ PlanarTo24b(&bgr0, &bgr1, &bgr2, &bgr3, &bgr4, &bgr5, dst);
+
+ y += 32;
+ u += 16;
+ v += 16;
+ }
+ for (; n < len; ++n) { // Finish off
+ VP8YuvToBgr(y[0], u[0], v[0], dst);
+ dst += 3;
+ y += 1;
+ u += (n & 1);
+ v += (n & 1);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Entry point
+
+extern void WebPInitSamplersSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplersSSE2(void) {
+ WebPSamplers[MODE_RGB] = YuvToRgbRow;
+ WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
+ WebPSamplers[MODE_BGR] = YuvToBgrRow;
+ WebPSamplers[MODE_BGRA] = YuvToBgraRow;
+ WebPSamplers[MODE_ARGB] = YuvToArgbRow;
+}
+
+//------------------------------------------------------------------------------
+// RGB24/32 -> YUV converters
+
+// Load eight 16b-words from *src.
+#define LOAD_16(src) _mm_loadu_si128((const __m128i*)(src))
+// Store either 16b-words into *dst
+#define STORE_16(V, dst) _mm_storeu_si128((__m128i*)(dst), (V))
+
+// Function that inserts a value of the second half of the in buffer in between
+// every two char of the first half.
+static WEBP_INLINE void RGB24PackedToPlanarHelper(
+ const __m128i* const in /*in[6]*/, __m128i* const out /*out[6]*/) {
+ out[0] = _mm_unpacklo_epi8(in[0], in[3]);
+ out[1] = _mm_unpackhi_epi8(in[0], in[3]);
+ out[2] = _mm_unpacklo_epi8(in[1], in[4]);
+ out[3] = _mm_unpackhi_epi8(in[1], in[4]);
+ out[4] = _mm_unpacklo_epi8(in[2], in[5]);
+ out[5] = _mm_unpackhi_epi8(in[2], in[5]);
+}
+
+// Unpack the 8b input rgbrgbrgbrgb ... as contiguous registers:
+// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
+// Similar to PlanarTo24bHelper(), but in reverse order.
+static WEBP_INLINE void RGB24PackedToPlanar(const uint8_t* const rgb,
+ __m128i* const out /*out[6]*/) {
+ __m128i tmp[6];
+ tmp[0] = _mm_loadu_si128((const __m128i*)(rgb + 0));
+ tmp[1] = _mm_loadu_si128((const __m128i*)(rgb + 16));
+ tmp[2] = _mm_loadu_si128((const __m128i*)(rgb + 32));
+ tmp[3] = _mm_loadu_si128((const __m128i*)(rgb + 48));
+ tmp[4] = _mm_loadu_si128((const __m128i*)(rgb + 64));
+ tmp[5] = _mm_loadu_si128((const __m128i*)(rgb + 80));
+
+ RGB24PackedToPlanarHelper(tmp, out);
+ RGB24PackedToPlanarHelper(out, tmp);
+ RGB24PackedToPlanarHelper(tmp, out);
+ RGB24PackedToPlanarHelper(out, tmp);
+ RGB24PackedToPlanarHelper(tmp, out);
+}
+
+// Convert 8 packed ARGB to r[], g[], b[]
+static WEBP_INLINE void RGB32PackedToPlanar(const uint32_t* const argb,
+ __m128i* const rgb /*in[6]*/) {
+ const __m128i zero = _mm_setzero_si128();
+ __m128i a0 = LOAD_16(argb + 0);
+ __m128i a1 = LOAD_16(argb + 4);
+ __m128i a2 = LOAD_16(argb + 8);
+ __m128i a3 = LOAD_16(argb + 12);
+ VP8L32bToPlanar(&a0, &a1, &a2, &a3);
+ rgb[0] = _mm_unpacklo_epi8(a1, zero);
+ rgb[1] = _mm_unpackhi_epi8(a1, zero);
+ rgb[2] = _mm_unpacklo_epi8(a2, zero);
+ rgb[3] = _mm_unpackhi_epi8(a2, zero);
+ rgb[4] = _mm_unpacklo_epi8(a3, zero);
+ rgb[5] = _mm_unpackhi_epi8(a3, zero);
+}
+
+// This macro computes (RG * MULT_RG + GB * MULT_GB + ROUNDER) >> DESCALE_FIX
+// It's a macro and not a function because we need to use immediate values with
+// srai_epi32, e.g.
+#define TRANSFORM(RG_LO, RG_HI, GB_LO, GB_HI, MULT_RG, MULT_GB, \
+ ROUNDER, DESCALE_FIX, OUT) do { \
+ const __m128i V0_lo = _mm_madd_epi16(RG_LO, MULT_RG); \
+ const __m128i V0_hi = _mm_madd_epi16(RG_HI, MULT_RG); \
+ const __m128i V1_lo = _mm_madd_epi16(GB_LO, MULT_GB); \
+ const __m128i V1_hi = _mm_madd_epi16(GB_HI, MULT_GB); \
+ const __m128i V2_lo = _mm_add_epi32(V0_lo, V1_lo); \
+ const __m128i V2_hi = _mm_add_epi32(V0_hi, V1_hi); \
+ const __m128i V3_lo = _mm_add_epi32(V2_lo, ROUNDER); \
+ const __m128i V3_hi = _mm_add_epi32(V2_hi, ROUNDER); \
+ const __m128i V5_lo = _mm_srai_epi32(V3_lo, DESCALE_FIX); \
+ const __m128i V5_hi = _mm_srai_epi32(V3_hi, DESCALE_FIX); \
+ (OUT) = _mm_packs_epi32(V5_lo, V5_hi); \
+} while (0)
+
+#define MK_CST_16(A, B) _mm_set_epi16((B), (A), (B), (A), (B), (A), (B), (A))
+static WEBP_INLINE void ConvertRGBToY(const __m128i* const R,
+ const __m128i* const G,
+ const __m128i* const B,
+ __m128i* const Y) {
+ const __m128i kRG_y = MK_CST_16(16839, 33059 - 16384);
+ const __m128i kGB_y = MK_CST_16(16384, 6420);
+ const __m128i kHALF_Y = _mm_set1_epi32((16 << YUV_FIX) + YUV_HALF);
+
+ const __m128i RG_lo = _mm_unpacklo_epi16(*R, *G);
+ const __m128i RG_hi = _mm_unpackhi_epi16(*R, *G);
+ const __m128i GB_lo = _mm_unpacklo_epi16(*G, *B);
+ const __m128i GB_hi = _mm_unpackhi_epi16(*G, *B);
+ TRANSFORM(RG_lo, RG_hi, GB_lo, GB_hi, kRG_y, kGB_y, kHALF_Y, YUV_FIX, *Y);
+}
+
+static WEBP_INLINE void ConvertRGBToUV(const __m128i* const R,
+ const __m128i* const G,
+ const __m128i* const B,
+ __m128i* const U, __m128i* const V) {
+ const __m128i kRG_u = MK_CST_16(-9719, -19081);
+ const __m128i kGB_u = MK_CST_16(0, 28800);
+ const __m128i kRG_v = MK_CST_16(28800, 0);
+ const __m128i kGB_v = MK_CST_16(-24116, -4684);
+ const __m128i kHALF_UV = _mm_set1_epi32(((128 << YUV_FIX) + YUV_HALF) << 2);
+
+ const __m128i RG_lo = _mm_unpacklo_epi16(*R, *G);
+ const __m128i RG_hi = _mm_unpackhi_epi16(*R, *G);
+ const __m128i GB_lo = _mm_unpacklo_epi16(*G, *B);
+ const __m128i GB_hi = _mm_unpackhi_epi16(*G, *B);
+ TRANSFORM(RG_lo, RG_hi, GB_lo, GB_hi, kRG_u, kGB_u,
+ kHALF_UV, YUV_FIX + 2, *U);
+ TRANSFORM(RG_lo, RG_hi, GB_lo, GB_hi, kRG_v, kGB_v,
+ kHALF_UV, YUV_FIX + 2, *V);
+}
+
+#undef MK_CST_16
+#undef TRANSFORM
+
+static void ConvertRGB24ToY(const uint8_t* rgb, uint8_t* y, int width) {
+ const int max_width = width & ~31;
+ int i;
+ for (i = 0; i < max_width; rgb += 3 * 16 * 2) {
+ __m128i rgb_plane[6];
+ int j;
+
+ RGB24PackedToPlanar(rgb, rgb_plane);
+
+ for (j = 0; j < 2; ++j, i += 16) {
+ const __m128i zero = _mm_setzero_si128();
+ __m128i r, g, b, Y0, Y1;
+
+ // Convert to 16-bit Y.
+ r = _mm_unpacklo_epi8(rgb_plane[0 + j], zero);
+ g = _mm_unpacklo_epi8(rgb_plane[2 + j], zero);
+ b = _mm_unpacklo_epi8(rgb_plane[4 + j], zero);
+ ConvertRGBToY(&r, &g, &b, &Y0);
+
+ // Convert to 16-bit Y.
+ r = _mm_unpackhi_epi8(rgb_plane[0 + j], zero);
+ g = _mm_unpackhi_epi8(rgb_plane[2 + j], zero);
+ b = _mm_unpackhi_epi8(rgb_plane[4 + j], zero);
+ ConvertRGBToY(&r, &g, &b, &Y1);
+
+ // Cast to 8-bit and store.
+ STORE_16(_mm_packus_epi16(Y0, Y1), y + i);
+ }
+ }
+ for (; i < width; ++i, rgb += 3) { // left-over
+ y[i] = VP8RGBToY(rgb[0], rgb[1], rgb[2], YUV_HALF);
+ }
+}
+
+static void ConvertBGR24ToY(const uint8_t* bgr, uint8_t* y, int width) {
+ const int max_width = width & ~31;
+ int i;
+ for (i = 0; i < max_width; bgr += 3 * 16 * 2) {
+ __m128i bgr_plane[6];
+ int j;
+
+ RGB24PackedToPlanar(bgr, bgr_plane);
+
+ for (j = 0; j < 2; ++j, i += 16) {
+ const __m128i zero = _mm_setzero_si128();
+ __m128i r, g, b, Y0, Y1;
+
+ // Convert to 16-bit Y.
+ b = _mm_unpacklo_epi8(bgr_plane[0 + j], zero);
+ g = _mm_unpacklo_epi8(bgr_plane[2 + j], zero);
+ r = _mm_unpacklo_epi8(bgr_plane[4 + j], zero);
+ ConvertRGBToY(&r, &g, &b, &Y0);
+
+ // Convert to 16-bit Y.
+ b = _mm_unpackhi_epi8(bgr_plane[0 + j], zero);
+ g = _mm_unpackhi_epi8(bgr_plane[2 + j], zero);
+ r = _mm_unpackhi_epi8(bgr_plane[4 + j], zero);
+ ConvertRGBToY(&r, &g, &b, &Y1);
+
+ // Cast to 8-bit and store.
+ STORE_16(_mm_packus_epi16(Y0, Y1), y + i);
+ }
+ }
+ for (; i < width; ++i, bgr += 3) { // left-over
+ y[i] = VP8RGBToY(bgr[2], bgr[1], bgr[0], YUV_HALF);
+ }
+}
+
+static void ConvertARGBToY(const uint32_t* argb, uint8_t* y, int width) {
+ const int max_width = width & ~15;
+ int i;
+ for (i = 0; i < max_width; i += 16) {
+ __m128i Y0, Y1, rgb[6];
+ RGB32PackedToPlanar(&argb[i], rgb);
+ ConvertRGBToY(&rgb[0], &rgb[2], &rgb[4], &Y0);
+ ConvertRGBToY(&rgb[1], &rgb[3], &rgb[5], &Y1);
+ STORE_16(_mm_packus_epi16(Y0, Y1), y + i);
+ }
+ for (; i < width; ++i) { // left-over
+ const uint32_t p = argb[i];
+ y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff,
+ YUV_HALF);
+ }
+}
+
+// Horizontal add (doubled) of two 16b values, result is 16b.
+// in: A | B | C | D | ... -> out: 2*(A+B) | 2*(C+D) | ...
+static void HorizontalAddPack(const __m128i* const A, const __m128i* const B,
+ __m128i* const out) {
+ const __m128i k2 = _mm_set1_epi16(2);
+ const __m128i C = _mm_madd_epi16(*A, k2);
+ const __m128i D = _mm_madd_epi16(*B, k2);
+ *out = _mm_packs_epi32(C, D);
+}
+
+static void ConvertARGBToUV(const uint32_t* argb, uint8_t* u, uint8_t* v,
+ int src_width, int do_store) {
+ const int max_width = src_width & ~31;
+ int i;
+ for (i = 0; i < max_width; i += 32, u += 16, v += 16) {
+ __m128i rgb[6], U0, V0, U1, V1;
+ RGB32PackedToPlanar(&argb[i], rgb);
+ HorizontalAddPack(&rgb[0], &rgb[1], &rgb[0]);
+ HorizontalAddPack(&rgb[2], &rgb[3], &rgb[2]);
+ HorizontalAddPack(&rgb[4], &rgb[5], &rgb[4]);
+ ConvertRGBToUV(&rgb[0], &rgb[2], &rgb[4], &U0, &V0);
+
+ RGB32PackedToPlanar(&argb[i + 16], rgb);
+ HorizontalAddPack(&rgb[0], &rgb[1], &rgb[0]);
+ HorizontalAddPack(&rgb[2], &rgb[3], &rgb[2]);
+ HorizontalAddPack(&rgb[4], &rgb[5], &rgb[4]);
+ ConvertRGBToUV(&rgb[0], &rgb[2], &rgb[4], &U1, &V1);
+
+ U0 = _mm_packus_epi16(U0, U1);
+ V0 = _mm_packus_epi16(V0, V1);
+ if (!do_store) {
+ const __m128i prev_u = LOAD_16(u);
+ const __m128i prev_v = LOAD_16(v);
+ U0 = _mm_avg_epu8(U0, prev_u);
+ V0 = _mm_avg_epu8(V0, prev_v);
+ }
+ STORE_16(U0, u);
+ STORE_16(V0, v);
+ }
+ if (i < src_width) { // left-over
+ WebPConvertARGBToUV_C(argb + i, u, v, src_width - i, do_store);
+ }
+}
+
+// Convert 16 packed ARGB 16b-values to r[], g[], b[]
+static WEBP_INLINE void RGBA32PackedToPlanar_16b(const uint16_t* const rgbx,
+ __m128i* const r,
+ __m128i* const g,
+ __m128i* const b) {
+ const __m128i in0 = LOAD_16(rgbx + 0); // r0 | g0 | b0 |x| r1 | g1 | b1 |x
+ const __m128i in1 = LOAD_16(rgbx + 8); // r2 | g2 | b2 |x| r3 | g3 | b3 |x
+ const __m128i in2 = LOAD_16(rgbx + 16); // r4 | ...
+ const __m128i in3 = LOAD_16(rgbx + 24); // r6 | ...
+ // column-wise transpose
+ const __m128i A0 = _mm_unpacklo_epi16(in0, in1);
+ const __m128i A1 = _mm_unpackhi_epi16(in0, in1);
+ const __m128i A2 = _mm_unpacklo_epi16(in2, in3);
+ const __m128i A3 = _mm_unpackhi_epi16(in2, in3);
+ const __m128i B0 = _mm_unpacklo_epi16(A0, A1); // r0 r1 r2 r3 | g0 g1 ..
+ const __m128i B1 = _mm_unpackhi_epi16(A0, A1); // b0 b1 b2 b3 | x x x x
+ const __m128i B2 = _mm_unpacklo_epi16(A2, A3); // r4 r5 r6 r7 | g4 g5 ..
+ const __m128i B3 = _mm_unpackhi_epi16(A2, A3); // b4 b5 b6 b7 | x x x x
+ *r = _mm_unpacklo_epi64(B0, B2);
+ *g = _mm_unpackhi_epi64(B0, B2);
+ *b = _mm_unpacklo_epi64(B1, B3);
+}
+
+static void ConvertRGBA32ToUV(const uint16_t* rgb,
+ uint8_t* u, uint8_t* v, int width) {
+ const int max_width = width & ~15;
+ const uint16_t* const last_rgb = rgb + 4 * max_width;
+ while (rgb < last_rgb) {
+ __m128i r, g, b, U0, V0, U1, V1;
+ RGBA32PackedToPlanar_16b(rgb + 0, &r, &g, &b);
+ ConvertRGBToUV(&r, &g, &b, &U0, &V0);
+ RGBA32PackedToPlanar_16b(rgb + 32, &r, &g, &b);
+ ConvertRGBToUV(&r, &g, &b, &U1, &V1);
+ STORE_16(_mm_packus_epi16(U0, U1), u);
+ STORE_16(_mm_packus_epi16(V0, V1), v);
+ u += 16;
+ v += 16;
+ rgb += 2 * 32;
+ }
+ if (max_width < width) { // left-over
+ WebPConvertRGBA32ToUV_C(rgb, u, v, width - max_width);
+ }
+}
+
+//------------------------------------------------------------------------------
+
+extern void WebPInitConvertARGBToYUVSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUVSSE2(void) {
+ WebPConvertARGBToY = ConvertARGBToY;
+ WebPConvertARGBToUV = ConvertARGBToUV;
+
+ WebPConvertRGB24ToY = ConvertRGB24ToY;
+ WebPConvertBGR24ToY = ConvertBGR24ToY;
+
+ WebPConvertRGBA32ToUV = ConvertRGBA32ToUV;
+}
+
+//------------------------------------------------------------------------------
+
+#define MAX_Y ((1 << 10) - 1) // 10b precision over 16b-arithmetic
+static uint16_t clip_y(int v) {
+ return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
+}
+
+static uint64_t SharpYUVUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
+ uint16_t* dst, int len) {
+ uint64_t diff = 0;
+ uint32_t tmp[4];
+ int i;
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i max = _mm_set1_epi16(MAX_Y);
+ const __m128i one = _mm_set1_epi16(1);
+ __m128i sum = zero;
+
+ for (i = 0; i + 8 <= len; i += 8) {
+ const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
+ const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
+ const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
+ const __m128i D = _mm_sub_epi16(A, B); // diff_y
+ const __m128i E = _mm_cmpgt_epi16(zero, D); // sign (-1 or 0)
+ const __m128i F = _mm_add_epi16(C, D); // new_y
+ const __m128i G = _mm_or_si128(E, one); // -1 or 1
+ const __m128i H = _mm_max_epi16(_mm_min_epi16(F, max), zero);
+ const __m128i I = _mm_madd_epi16(D, G); // sum(abs(...))
+ _mm_storeu_si128((__m128i*)(dst + i), H);
+ sum = _mm_add_epi32(sum, I);
+ }
+ _mm_storeu_si128((__m128i*)tmp, sum);
+ diff = tmp[3] + tmp[2] + tmp[1] + tmp[0];
+ for (; i < len; ++i) {
+ const int diff_y = ref[i] - src[i];
+ const int new_y = (int)dst[i] + diff_y;
+ dst[i] = clip_y(new_y);
+ diff += (uint64_t)abs(diff_y);
+ }
+ return diff;
+}
+
+static void SharpYUVUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
+ int16_t* dst, int len) {
+ int i = 0;
+ for (i = 0; i + 8 <= len; i += 8) {
+ const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
+ const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
+ const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
+ const __m128i D = _mm_sub_epi16(A, B); // diff_uv
+ const __m128i E = _mm_add_epi16(C, D); // new_uv
+ _mm_storeu_si128((__m128i*)(dst + i), E);
+ }
+ for (; i < len; ++i) {
+ const int diff_uv = ref[i] - src[i];
+ dst[i] += diff_uv;
+ }
+}
+
+static void SharpYUVFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
+ const uint16_t* best_y, uint16_t* out) {
+ int i;
+ const __m128i kCst8 = _mm_set1_epi16(8);
+ const __m128i max = _mm_set1_epi16(MAX_Y);
+ const __m128i zero = _mm_setzero_si128();
+ for (i = 0; i + 8 <= len; i += 8) {
+ const __m128i a0 = _mm_loadu_si128((const __m128i*)(A + i + 0));
+ const __m128i a1 = _mm_loadu_si128((const __m128i*)(A + i + 1));
+ const __m128i b0 = _mm_loadu_si128((const __m128i*)(B + i + 0));
+ const __m128i b1 = _mm_loadu_si128((const __m128i*)(B + i + 1));
+ const __m128i a0b1 = _mm_add_epi16(a0, b1);
+ const __m128i a1b0 = _mm_add_epi16(a1, b0);
+ const __m128i a0a1b0b1 = _mm_add_epi16(a0b1, a1b0); // A0+A1+B0+B1
+ const __m128i a0a1b0b1_8 = _mm_add_epi16(a0a1b0b1, kCst8);
+ const __m128i a0b1_2 = _mm_add_epi16(a0b1, a0b1); // 2*(A0+B1)
+ const __m128i a1b0_2 = _mm_add_epi16(a1b0, a1b0); // 2*(A1+B0)
+ const __m128i c0 = _mm_srai_epi16(_mm_add_epi16(a0b1_2, a0a1b0b1_8), 3);
+ const __m128i c1 = _mm_srai_epi16(_mm_add_epi16(a1b0_2, a0a1b0b1_8), 3);
+ const __m128i d0 = _mm_add_epi16(c1, a0);
+ const __m128i d1 = _mm_add_epi16(c0, a1);
+ const __m128i e0 = _mm_srai_epi16(d0, 1);
+ const __m128i e1 = _mm_srai_epi16(d1, 1);
+ const __m128i f0 = _mm_unpacklo_epi16(e0, e1);
+ const __m128i f1 = _mm_unpackhi_epi16(e0, e1);
+ const __m128i g0 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
+ const __m128i g1 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 8));
+ const __m128i h0 = _mm_add_epi16(g0, f0);
+ const __m128i h1 = _mm_add_epi16(g1, f1);
+ const __m128i i0 = _mm_max_epi16(_mm_min_epi16(h0, max), zero);
+ const __m128i i1 = _mm_max_epi16(_mm_min_epi16(h1, max), zero);
+ _mm_storeu_si128((__m128i*)(out + 2 * i + 0), i0);
+ _mm_storeu_si128((__m128i*)(out + 2 * i + 8), i1);
+ }
+ for (; i < len; ++i) {
+ // (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
+ // = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
+ // We reuse the common sub-expressions.
+ const int a0b1 = A[i + 0] + B[i + 1];
+ const int a1b0 = A[i + 1] + B[i + 0];
+ const int a0a1b0b1 = a0b1 + a1b0 + 8;
+ const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+ const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+ out[2 * i + 0] = clip_y(best_y[2 * i + 0] + v0);
+ out[2 * i + 1] = clip_y(best_y[2 * i + 1] + v1);
+ }
+}
+
+#undef MAX_Y
+
+//------------------------------------------------------------------------------
+
+extern void WebPInitSharpYUVSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSharpYUVSSE2(void) {
+ WebPSharpYUVUpdateY = SharpYUVUpdateY_SSE2;
+ WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_SSE2;
+ WebPSharpYUVFilterRow = SharpYUVFilterRow_SSE2;
+}
+
+#else // !WEBP_USE_SSE2
+
+WEBP_DSP_INIT_STUB(WebPInitSamplersSSE2)
+WEBP_DSP_INIT_STUB(WebPInitConvertARGBToYUVSSE2)
+WEBP_DSP_INIT_STUB(WebPInitSharpYUVSSE2)
+
+#endif // WEBP_USE_SSE2
diff --git a/media/libwebp/enc/backward_references_enc.h b/media/libwebp/enc/backward_references_enc.h
new file mode 100644
index 000000000..3a19aa763
--- /dev/null
+++ b/media/libwebp/enc/backward_references_enc.h
@@ -0,0 +1,207 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki@google.com)
+//
+
+#ifndef WEBP_ENC_BACKWARD_REFERENCES_H_
+#define WEBP_ENC_BACKWARD_REFERENCES_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include "../webp/types.h"
+#include "../webp/format_constants.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The maximum allowed limit is 11.
+#define MAX_COLOR_CACHE_BITS 10
+
+// -----------------------------------------------------------------------------
+// PixOrCopy
+
+enum Mode {
+ kLiteral,
+ kCacheIdx,
+ kCopy,
+ kNone
+};
+
+typedef struct {
+ // mode as uint8_t to make the memory layout to be exactly 8 bytes.
+ uint8_t mode;
+ uint16_t len;
+ uint32_t argb_or_distance;
+} PixOrCopy;
+
+static WEBP_INLINE PixOrCopy PixOrCopyCreateCopy(uint32_t distance,
+ uint16_t len) {
+ PixOrCopy retval;
+ retval.mode = kCopy;
+ retval.argb_or_distance = distance;
+ retval.len = len;
+ return retval;
+}
+
+static WEBP_INLINE PixOrCopy PixOrCopyCreateCacheIdx(int idx) {
+ PixOrCopy retval;
+ assert(idx >= 0);
+ assert(idx < (1 << MAX_COLOR_CACHE_BITS));
+ retval.mode = kCacheIdx;
+ retval.argb_or_distance = idx;
+ retval.len = 1;
+ return retval;
+}
+
+static WEBP_INLINE PixOrCopy PixOrCopyCreateLiteral(uint32_t argb) {
+ PixOrCopy retval;
+ retval.mode = kLiteral;
+ retval.argb_or_distance = argb;
+ retval.len = 1;
+ return retval;
+}
+
+static WEBP_INLINE int PixOrCopyIsLiteral(const PixOrCopy* const p) {
+ return (p->mode == kLiteral);
+}
+
+static WEBP_INLINE int PixOrCopyIsCacheIdx(const PixOrCopy* const p) {
+ return (p->mode == kCacheIdx);
+}
+
+static WEBP_INLINE int PixOrCopyIsCopy(const PixOrCopy* const p) {
+ return (p->mode == kCopy);
+}
+
+static WEBP_INLINE uint32_t PixOrCopyLiteral(const PixOrCopy* const p,
+ int component) {
+ assert(p->mode == kLiteral);
+ return (p->argb_or_distance >> (component * 8)) & 0xff;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyLength(const PixOrCopy* const p) {
+ return p->len;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyArgb(const PixOrCopy* const p) {
+ assert(p->mode == kLiteral);
+ return p->argb_or_distance;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyCacheIdx(const PixOrCopy* const p) {
+ assert(p->mode == kCacheIdx);
+ assert(p->argb_or_distance < (1U << MAX_COLOR_CACHE_BITS));
+ return p->argb_or_distance;
+}
+
+static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) {
+ assert(p->mode == kCopy);
+ return p->argb_or_distance;
+}
+
+// -----------------------------------------------------------------------------
+// VP8LHashChain
+
+#define HASH_BITS 18
+#define HASH_SIZE (1 << HASH_BITS)
+
+typedef struct VP8LHashChain VP8LHashChain;
+struct VP8LHashChain {
+ // The 20 most significant bits contain the offset at which the best match
+ // is found. These 20 bits are the limit defined by GetWindowSizeForHashChain
+ // (through WINDOW_SIZE = 1<<20).
+ // The lower 12 bits contain the length of the match. The 12 bit limit is
+ // defined in MaxFindCopyLength with MAX_LENGTH=4096.
+ uint32_t* offset_length_;
+ // This is the maximum size of the hash_chain that can be constructed.
+ // Typically this is the pixel count (width x height) for a given image.
+ int size_;
+};
+
+// Must be called first, to set size.
+int VP8LHashChainInit(VP8LHashChain* const p, int size);
+// Pre-compute the best matches for argb.
+int VP8LHashChainFill(VP8LHashChain* const p, int quality,
+ const uint32_t* const argb, int xsize, int ysize,
+ int low_effort);
+void VP8LHashChainClear(VP8LHashChain* const p); // release memory
+
+// -----------------------------------------------------------------------------
+// VP8LBackwardRefs (block-based backward-references storage)
+
+// maximum number of reference blocks the image will be segmented into
+#define MAX_REFS_BLOCK_PER_IMAGE 16
+
+typedef struct PixOrCopyBlock PixOrCopyBlock; // forward declaration
+typedef struct VP8LBackwardRefs VP8LBackwardRefs;
+
+// Container for blocks chain
+struct VP8LBackwardRefs {
+ int block_size_; // common block-size
+ int error_; // set to true if some memory error occurred
+ PixOrCopyBlock* refs_; // list of currently used blocks
+ PixOrCopyBlock** tail_; // for list recycling
+ PixOrCopyBlock* free_blocks_; // free-list
+ PixOrCopyBlock* last_block_; // used for adding new refs (internal)
+};
+
+// Initialize the object. 'block_size' is the common block size to store
+// references (typically, width * height / MAX_REFS_BLOCK_PER_IMAGE).
+void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size);
+// Release memory for backward references.
+void VP8LBackwardRefsClear(VP8LBackwardRefs* const refs);
+// Copies the 'src' backward refs to the 'dst'. Returns 0 in case of error.
+int VP8LBackwardRefsCopy(const VP8LBackwardRefs* const src,
+ VP8LBackwardRefs* const dst);
+
+// Cursor for iterating on references content
+typedef struct {
+ // public:
+ PixOrCopy* cur_pos; // current position
+ // private:
+ PixOrCopyBlock* cur_block_; // current block in the refs list
+ const PixOrCopy* last_pos_; // sentinel for switching to next block
+} VP8LRefsCursor;
+
+// Returns a cursor positioned at the beginning of the references list.
+VP8LRefsCursor VP8LRefsCursorInit(const VP8LBackwardRefs* const refs);
+// Returns true if cursor is pointing at a valid position.
+static WEBP_INLINE int VP8LRefsCursorOk(const VP8LRefsCursor* const c) {
+ return (c->cur_pos != NULL);
+}
+// Move to next block of references. Internal, not to be called directly.
+void VP8LRefsCursorNextBlock(VP8LRefsCursor* const c);
+// Move to next position, or NULL. Should not be called if !VP8LRefsCursorOk().
+static WEBP_INLINE void VP8LRefsCursorNext(VP8LRefsCursor* const c) {
+ assert(c != NULL);
+ assert(VP8LRefsCursorOk(c));
+ if (++c->cur_pos == c->last_pos_) VP8LRefsCursorNextBlock(c);
+}
+
+// -----------------------------------------------------------------------------
+// Main entry points
+
+// Evaluates best possible backward references for specified quality.
+// The input cache_bits to 'VP8LGetBackwardReferences' sets the maximum cache
+// bits to use (passing 0 implies disabling the local color cache).
+// The optimal cache bits is evaluated and set for the *cache_bits parameter.
+// The return value is the pointer to the best of the two backward refs viz,
+// refs[0] or refs[1].
+VP8LBackwardRefs* VP8LGetBackwardReferences(
+ int width, int height, const uint32_t* const argb, int quality,
+ int low_effort, int* const cache_bits,
+ const VP8LHashChain* const hash_chain, VP8LBackwardRefs refs[2]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // WEBP_ENC_BACKWARD_REFERENCES_H_
diff --git a/media/libwebp/enc/cost_enc.h b/media/libwebp/enc/cost_enc.h
new file mode 100644
index 000000000..99e4b37aa
--- /dev/null
+++ b/media/libwebp/enc/cost_enc.h
@@ -0,0 +1,82 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Cost tables for level and modes.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_ENC_COST_H_
+#define WEBP_ENC_COST_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include "./vp8i_enc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// On-the-fly info about the current set of residuals. Handy to avoid
+// passing zillions of params.
+typedef struct VP8Residual VP8Residual;
+struct VP8Residual {
+ int first;
+ int last;
+ const int16_t* coeffs;
+
+ int coeff_type;
+ ProbaArray* prob;
+ StatsArray* stats;
+ CostArrayPtr costs;
+};
+
+void VP8InitResidual(int first, int coeff_type,
+ VP8Encoder* const enc, VP8Residual* const res);
+
+int VP8RecordCoeffs(int ctx, const VP8Residual* const res);
+
+// Record proba context used.
+static WEBP_INLINE int VP8RecordStats(int bit, proba_t* const stats) {
+ proba_t p = *stats;
+ // An overflow is inbound. Note we handle this at 0xfffe0000u instead of
+ // 0xffff0000u to make sure p + 1u does not overflow.
+ if (p >= 0xfffe0000u) {
+ p = ((p + 1u) >> 1) & 0x7fff7fffu; // -> divide the stats by 2.
+ }
+ // record bit count (lower 16 bits) and increment total count (upper 16 bits).
+ p += 0x00010000u + bit;
+ *stats = p;
+ return bit;
+}
+
+// Cost of coding one event with probability 'proba'.
+static WEBP_INLINE int VP8BitCost(int bit, uint8_t proba) {
+ return !bit ? VP8EntropyCost[proba] : VP8EntropyCost[255 - proba];
+}
+
+// Level cost calculations
+extern const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2];
+void VP8CalculateLevelCosts(VP8EncProba* const proba);
+static WEBP_INLINE int VP8LevelCost(const uint16_t* const table, int level) {
+ return VP8LevelFixedCosts[level]
+ + table[(level > MAX_VARIABLE_LEVEL) ? MAX_VARIABLE_LEVEL : level];
+}
+
+// Mode costs
+extern const uint16_t VP8FixedCostsUV[4];
+extern const uint16_t VP8FixedCostsI16[4];
+extern const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES];
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_ENC_COST_H_ */
diff --git a/media/libwebp/enc/delta_palettization_enc.h b/media/libwebp/enc/delta_palettization_enc.h
new file mode 100644
index 000000000..63048ec6e
--- /dev/null
+++ b/media/libwebp/enc/delta_palettization_enc.h
@@ -0,0 +1,25 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Mislav Bradac (mislavm@google.com)
+//
+
+#ifndef WEBP_ENC_DELTA_PALETTIZATION_H_
+#define WEBP_ENC_DELTA_PALETTIZATION_H_
+
+#include "../webp/encode.h"
+#include "../enc/vp8li_enc.h"
+
+// Replaces enc->argb_[] input by a palettizable approximation of it,
+// and generates optimal enc->palette_[].
+// This function can revert enc->use_palette_ / enc->use_predict_ flag
+// if delta-palettization is not producing expected saving.
+WebPEncodingError WebPSearchOptimalDeltaPalette(VP8LEncoder* const enc);
+
+#endif // WEBP_ENC_DELTA_PALETTIZATION_H_
diff --git a/media/libwebp/enc/histogram_enc.h b/media/libwebp/enc/histogram_enc.h
new file mode 100644
index 000000000..a9d258a16
--- /dev/null
+++ b/media/libwebp/enc/histogram_enc.h
@@ -0,0 +1,123 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki@google.com)
+//
+// Models the histograms of literal and distance codes.
+
+#ifndef WEBP_ENC_HISTOGRAM_H_
+#define WEBP_ENC_HISTOGRAM_H_
+
+#include <string.h>
+
+#include "./backward_references_enc.h"
+#include "../webp/format_constants.h"
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Not a trivial literal symbol.
+#define VP8L_NON_TRIVIAL_SYM (0xffffffff)
+
+// A simple container for histograms of data.
+typedef struct {
+ // literal_ contains green literal, palette-code and
+ // copy-length-prefix histogram
+ uint32_t* literal_; // Pointer to the allocated buffer for literal.
+ uint32_t red_[NUM_LITERAL_CODES];
+ uint32_t blue_[NUM_LITERAL_CODES];
+ uint32_t alpha_[NUM_LITERAL_CODES];
+ // Backward reference prefix-code histogram.
+ uint32_t distance_[NUM_DISTANCE_CODES];
+ int palette_code_bits_;
+ uint32_t trivial_symbol_; // True, if histograms for Red, Blue & Alpha
+ // literal symbols are single valued.
+ double bit_cost_; // cached value of bit cost.
+ double literal_cost_; // Cached values of dominant entropy costs:
+ double red_cost_; // literal, red & blue.
+ double blue_cost_;
+} VP8LHistogram;
+
+// Collection of histograms with fixed capacity, allocated as one
+// big memory chunk. Can be destroyed by calling WebPSafeFree().
+typedef struct {
+ int size; // number of slots currently in use
+ int max_size; // maximum capacity
+ VP8LHistogram** histograms;
+} VP8LHistogramSet;
+
+// Create the histogram.
+//
+// The input data is the PixOrCopy data, which models the literals, stop
+// codes and backward references (both distances and lengths). Also: if
+// palette_code_bits is >= 0, initialize the histogram with this value.
+void VP8LHistogramCreate(VP8LHistogram* const p,
+ const VP8LBackwardRefs* const refs,
+ int palette_code_bits);
+
+// Return the size of the histogram for a given palette_code_bits.
+int VP8LGetHistogramSize(int palette_code_bits);
+
+// Set the palette_code_bits and reset the stats.
+void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits);
+
+// Collect all the references into a histogram (without reset)
+void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs,
+ VP8LHistogram* const histo);
+
+// Free the memory allocated for the histogram.
+void VP8LFreeHistogram(VP8LHistogram* const histo);
+
+// Free the memory allocated for the histogram set.
+void VP8LFreeHistogramSet(VP8LHistogramSet* const histo);
+
+// Allocate an array of pointer to histograms, allocated and initialized
+// using 'cache_bits'. Return NULL in case of memory error.
+VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits);
+
+// Allocate and initialize histogram object with specified 'cache_bits'.
+// Returns NULL in case of memory error.
+// Special case of VP8LAllocateHistogramSet, with size equals 1.
+VP8LHistogram* VP8LAllocateHistogram(int cache_bits);
+
+// Accumulate a token 'v' into a histogram.
+void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
+ const PixOrCopy* const v);
+
+static WEBP_INLINE int VP8LHistogramNumCodes(int palette_code_bits) {
+ return NUM_LITERAL_CODES + NUM_LENGTH_CODES +
+ ((palette_code_bits > 0) ? (1 << palette_code_bits) : 0);
+}
+
+// Builds the histogram image.
+int VP8LGetHistoImageSymbols(int xsize, int ysize,
+ const VP8LBackwardRefs* const refs,
+ int quality, int low_effort,
+ int histogram_bits, int cache_bits,
+ VP8LHistogramSet* const image_in,
+ VP8LHistogramSet* const tmp_histos,
+ uint16_t* const histogram_symbols);
+
+// Returns the entropy for the symbols in the input array.
+// Also sets trivial_symbol to the code value, if the array has only one code
+// value. Otherwise, set it to VP8L_NON_TRIVIAL_SYM.
+double VP8LBitsEntropy(const uint32_t* const array, int n,
+ uint32_t* const trivial_symbol);
+
+// Estimate how many bits the combined entropy of literals and distance
+// approximately maps to.
+double VP8LHistogramEstimateBits(const VP8LHistogram* const p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // WEBP_ENC_HISTOGRAM_H_
diff --git a/media/libwebp/enc/vp8i_enc.h b/media/libwebp/enc/vp8i_enc.h
new file mode 100644
index 000000000..93c95ecbf
--- /dev/null
+++ b/media/libwebp/enc/vp8i_enc.h
@@ -0,0 +1,520 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebP encoder: internal header.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_ENC_VP8ENCI_H_
+#define WEBP_ENC_VP8ENCI_H_
+
+#include <string.h> // for memcpy()
+#include "../dec/common_dec.h"
+#include "../dsp/dsp.h"
+#include "../utils/bit_writer_utils.h"
+#include "../utils/thread_utils.h"
+#include "../utils/utils.h"
+#include "../webp/encode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Various defines and enums
+
+// version numbers
+#define ENC_MAJ_VERSION 0
+#define ENC_MIN_VERSION 6
+#define ENC_REV_VERSION 0
+
+enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
+ MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
+ MAX_LEVEL = 2047 // max level (note: max codable is 2047 + 67)
+ };
+
+typedef enum { // Rate-distortion optimization levels
+ RD_OPT_NONE = 0, // no rd-opt
+ RD_OPT_BASIC = 1, // basic scoring (no trellis)
+ RD_OPT_TRELLIS = 2, // perform trellis-quant on the final decision only
+ RD_OPT_TRELLIS_ALL = 3 // trellis-quant for every scoring (much slower)
+} VP8RDLevel;
+
+// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
+// The original or reconstructed samples can be accessed using VP8Scan[].
+// The predicted blocks can be accessed using offsets to yuv_p_ and
+// the arrays VP8*ModeOffsets[].
+// * YUV Samples area (yuv_in_/yuv_out_/yuv_out2_)
+// (see VP8Scan[] for accessing the blocks, along with
+// Y_OFF_ENC/U_OFF_ENC/V_OFF_ENC):
+// +----+----+
+// Y_OFF_ENC |YYYY|UUVV|
+// U_OFF_ENC |YYYY|UUVV|
+// V_OFF_ENC |YYYY|....| <- 25% wasted U/V area
+// |YYYY|....|
+// +----+----+
+// * Prediction area ('yuv_p_', size = PRED_SIZE_ENC)
+// Intra16 predictions (16x16 block each, two per row):
+// |I16DC16|I16TM16|
+// |I16VE16|I16HE16|
+// Chroma U/V predictions (16x8 block each, two per row):
+// |C8DC8|C8TM8|
+// |C8VE8|C8HE8|
+// Intra 4x4 predictions (4x4 block each)
+// |I4DC4 I4TM4 I4VE4 I4HE4|I4RD4 I4VR4 I4LD4 I4VL4|
+// |I4HD4 I4HU4 I4TMP .....|.......................| <- ~31% wasted
+#define YUV_SIZE_ENC (BPS * 16)
+#define PRED_SIZE_ENC (32 * BPS + 16 * BPS + 8 * BPS) // I16+Chroma+I4 preds
+#define Y_OFF_ENC (0)
+#define U_OFF_ENC (16)
+#define V_OFF_ENC (16 + 8)
+
+extern const int VP8Scan[16]; // in quant.c
+extern const int VP8UVModeOffsets[4]; // in analyze.c
+extern const int VP8I16ModeOffsets[4];
+extern const int VP8I4ModeOffsets[NUM_BMODES];
+
+// Layout of prediction blocks
+// intra 16x16
+#define I16DC16 (0 * 16 * BPS)
+#define I16TM16 (I16DC16 + 16)
+#define I16VE16 (1 * 16 * BPS)
+#define I16HE16 (I16VE16 + 16)
+// chroma 8x8, two U/V blocks side by side (hence: 16x8 each)
+#define C8DC8 (2 * 16 * BPS)
+#define C8TM8 (C8DC8 + 1 * 16)
+#define C8VE8 (2 * 16 * BPS + 8 * BPS)
+#define C8HE8 (C8VE8 + 1 * 16)
+// intra 4x4
+#define I4DC4 (3 * 16 * BPS + 0)
+#define I4TM4 (I4DC4 + 4)
+#define I4VE4 (I4DC4 + 8)
+#define I4HE4 (I4DC4 + 12)
+#define I4RD4 (I4DC4 + 16)
+#define I4VR4 (I4DC4 + 20)
+#define I4LD4 (I4DC4 + 24)
+#define I4VL4 (I4DC4 + 28)
+#define I4HD4 (3 * 16 * BPS + 4 * BPS)
+#define I4HU4 (I4HD4 + 4)
+#define I4TMP (I4HD4 + 8)
+
+typedef int64_t score_t; // type used for scores, rate, distortion
+// Note that MAX_COST is not the maximum allowed by sizeof(score_t),
+// in order to allow overflowing computations.
+#define MAX_COST ((score_t)0x7fffffffffffffLL)
+
+#define QFIX 17
+#define BIAS(b) ((b) << (QFIX - 8))
+// Fun fact: this is the _only_ line where we're actually being lossy and
+// discarding bits.
+static WEBP_INLINE int QUANTDIV(uint32_t n, uint32_t iQ, uint32_t B) {
+ return (int)((n * iQ + B) >> QFIX);
+}
+
+// Uncomment the following to remove token-buffer code:
+// #define DISABLE_TOKEN_BUFFER
+
+//------------------------------------------------------------------------------
+// Headers
+
+typedef uint32_t proba_t; // 16b + 16b
+typedef uint8_t ProbaArray[NUM_CTX][NUM_PROBAS];
+typedef proba_t StatsArray[NUM_CTX][NUM_PROBAS];
+typedef uint16_t CostArray[NUM_CTX][MAX_VARIABLE_LEVEL + 1];
+typedef const uint16_t* (*CostArrayPtr)[NUM_CTX]; // for easy casting
+typedef const uint16_t* CostArrayMap[16][NUM_CTX];
+typedef double LFStats[NUM_MB_SEGMENTS][MAX_LF_LEVELS]; // filter stats
+
+typedef struct VP8Encoder VP8Encoder;
+
+// segment features
+typedef struct {
+ int num_segments_; // Actual number of segments. 1 segment only = unused.
+ int update_map_; // whether to update the segment map or not.
+ // must be 0 if there's only 1 segment.
+ int size_; // bit-cost for transmitting the segment map
+} VP8EncSegmentHeader;
+
+// Struct collecting all frame-persistent probabilities.
+typedef struct {
+ uint8_t segments_[3]; // probabilities for segment tree
+ uint8_t skip_proba_; // final probability of being skipped.
+ ProbaArray coeffs_[NUM_TYPES][NUM_BANDS]; // 1056 bytes
+ StatsArray stats_[NUM_TYPES][NUM_BANDS]; // 4224 bytes
+ CostArray level_cost_[NUM_TYPES][NUM_BANDS]; // 13056 bytes
+ CostArrayMap remapped_costs_[NUM_TYPES]; // 1536 bytes
+ int dirty_; // if true, need to call VP8CalculateLevelCosts()
+ int use_skip_proba_; // Note: we always use skip_proba for now.
+ int nb_skip_; // number of skipped blocks
+} VP8EncProba;
+
+// Filter parameters. Not actually used in the code (we don't perform
+// the in-loop filtering), but filled from user's config
+typedef struct {
+ int simple_; // filtering type: 0=complex, 1=simple
+ int level_; // base filter level [0..63]
+ int sharpness_; // [0..7]
+ int i4x4_lf_delta_; // delta filter level for i4x4 relative to i16x16
+} VP8EncFilterHeader;
+
+//------------------------------------------------------------------------------
+// Informations about the macroblocks.
+
+typedef struct {
+ // block type
+ unsigned int type_:2; // 0=i4x4, 1=i16x16
+ unsigned int uv_mode_:2;
+ unsigned int skip_:1;
+ unsigned int segment_:2;
+ uint8_t alpha_; // quantization-susceptibility
+} VP8MBInfo;
+
+typedef struct VP8Matrix {
+ uint16_t q_[16]; // quantizer steps
+ uint16_t iq_[16]; // reciprocals, fixed point.
+ uint32_t bias_[16]; // rounding bias
+ uint32_t zthresh_[16]; // value below which a coefficient is zeroed
+ uint16_t sharpen_[16]; // frequency boosters for slight sharpening
+} VP8Matrix;
+
+typedef struct {
+ VP8Matrix y1_, y2_, uv_; // quantization matrices
+ int alpha_; // quant-susceptibility, range [-127,127]. Zero is neutral.
+ // Lower values indicate a lower risk of blurriness.
+ int beta_; // filter-susceptibility, range [0,255].
+ int quant_; // final segment quantizer.
+ int fstrength_; // final in-loop filtering strength
+ int max_edge_; // max edge delta (for filtering strength)
+ int min_disto_; // minimum distortion required to trigger filtering record
+ // reactivities
+ int lambda_i16_, lambda_i4_, lambda_uv_;
+ int lambda_mode_, lambda_trellis_, tlambda_;
+ int lambda_trellis_i16_, lambda_trellis_i4_, lambda_trellis_uv_;
+
+ // lambda values for distortion-based evaluation
+ score_t i4_penalty_; // penalty for using Intra4
+} VP8SegmentInfo;
+
+// Handy transient struct to accumulate score and info during RD-optimization
+// and mode evaluation.
+typedef struct {
+ score_t D, SD; // Distortion, spectral distortion
+ score_t H, R, score; // header bits, rate, score.
+ int16_t y_dc_levels[16]; // Quantized levels for luma-DC, luma-AC, chroma.
+ int16_t y_ac_levels[16][16];
+ int16_t uv_levels[4 + 4][16];
+ int mode_i16; // mode number for intra16 prediction
+ uint8_t modes_i4[16]; // mode numbers for intra4 predictions
+ int mode_uv; // mode number of chroma prediction
+ uint32_t nz; // non-zero blocks
+} VP8ModeScore;
+
+// Iterator structure to iterate through macroblocks, pointing to the
+// right neighbouring data (samples, predictions, contexts, ...)
+typedef struct {
+ int x_, y_; // current macroblock
+ uint8_t* yuv_in_; // input samples
+ uint8_t* yuv_out_; // output samples
+ uint8_t* yuv_out2_; // secondary buffer swapped with yuv_out_.
+ uint8_t* yuv_p_; // scratch buffer for prediction
+ VP8Encoder* enc_; // back-pointer
+ VP8MBInfo* mb_; // current macroblock
+ VP8BitWriter* bw_; // current bit-writer
+ uint8_t* preds_; // intra mode predictors (4x4 blocks)
+ uint32_t* nz_; // non-zero pattern
+ uint8_t i4_boundary_[37]; // 32+5 boundary samples needed by intra4x4
+ uint8_t* i4_top_; // pointer to the current top boundary sample
+ int i4_; // current intra4x4 mode being tested
+ int top_nz_[9]; // top-non-zero context.
+ int left_nz_[9]; // left-non-zero. left_nz[8] is independent.
+ uint64_t bit_count_[4][3]; // bit counters for coded levels.
+ uint64_t luma_bits_; // macroblock bit-cost for luma
+ uint64_t uv_bits_; // macroblock bit-cost for chroma
+ LFStats* lf_stats_; // filter stats (borrowed from enc_)
+ int do_trellis_; // if true, perform extra level optimisation
+ int count_down_; // number of mb still to be processed
+ int count_down0_; // starting counter value (for progress)
+ int percent0_; // saved initial progress percent
+
+ uint8_t* y_left_; // left luma samples (addressable from index -1 to 15).
+ uint8_t* u_left_; // left u samples (addressable from index -1 to 7)
+ uint8_t* v_left_; // left v samples (addressable from index -1 to 7)
+
+ uint8_t* y_top_; // top luma samples at position 'x_'
+ uint8_t* uv_top_; // top u/v samples at position 'x_', packed as 16 bytes
+
+ // memory for storing y/u/v_left_
+ uint8_t yuv_left_mem_[17 + 16 + 16 + 8 + WEBP_ALIGN_CST];
+ // memory for yuv_*
+ uint8_t yuv_mem_[3 * YUV_SIZE_ENC + PRED_SIZE_ENC + WEBP_ALIGN_CST];
+} VP8EncIterator;
+
+ // in iterator.c
+// must be called first
+void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it);
+// restart a scan
+void VP8IteratorReset(VP8EncIterator* const it);
+// reset iterator position to row 'y'
+void VP8IteratorSetRow(VP8EncIterator* const it, int y);
+// set count down (=number of iterations to go)
+void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down);
+// return true if iteration is finished
+int VP8IteratorIsDone(const VP8EncIterator* const it);
+// Import uncompressed samples from source.
+// If tmp_32 is not NULL, import boundary samples too.
+// tmp_32 is a 32-bytes scratch buffer that must be aligned in memory.
+void VP8IteratorImport(VP8EncIterator* const it, uint8_t* tmp_32);
+// export decimated samples
+void VP8IteratorExport(const VP8EncIterator* const it);
+// go to next macroblock. Returns false if not finished.
+int VP8IteratorNext(VP8EncIterator* const it);
+// save the yuv_out_ boundary values to top_/left_ arrays for next iterations.
+void VP8IteratorSaveBoundary(VP8EncIterator* const it);
+// Report progression based on macroblock rows. Return 0 for user-abort request.
+int VP8IteratorProgress(const VP8EncIterator* const it,
+ int final_delta_percent);
+// Intra4x4 iterations
+void VP8IteratorStartI4(VP8EncIterator* const it);
+// returns true if not done.
+int VP8IteratorRotateI4(VP8EncIterator* const it,
+ const uint8_t* const yuv_out);
+
+// Non-zero context setup/teardown
+void VP8IteratorNzToBytes(VP8EncIterator* const it);
+void VP8IteratorBytesToNz(VP8EncIterator* const it);
+
+// Helper functions to set mode properties
+void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode);
+void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes);
+void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode);
+void VP8SetSkip(const VP8EncIterator* const it, int skip);
+void VP8SetSegment(const VP8EncIterator* const it, int segment);
+
+//------------------------------------------------------------------------------
+// Paginated token buffer
+
+typedef struct VP8Tokens VP8Tokens; // struct details in token.c
+
+typedef struct {
+#if !defined(DISABLE_TOKEN_BUFFER)
+ VP8Tokens* pages_; // first page
+ VP8Tokens** last_page_; // last page
+ uint16_t* tokens_; // set to (*last_page_)->tokens_
+ int left_; // how many free tokens left before the page is full
+ int page_size_; // number of tokens per page
+#endif
+ int error_; // true in case of malloc error
+} VP8TBuffer;
+
+// initialize an empty buffer
+void VP8TBufferInit(VP8TBuffer* const b, int page_size);
+void VP8TBufferClear(VP8TBuffer* const b); // de-allocate pages memory
+
+#if !defined(DISABLE_TOKEN_BUFFER)
+
+// Finalizes bitstream when probabilities are known.
+// Deletes the allocated token memory if final_pass is true.
+int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
+ const uint8_t* const probas, int final_pass);
+
+// record the coding of coefficients without knowing the probabilities yet
+int VP8RecordCoeffTokens(int ctx, const struct VP8Residual* const res,
+ VP8TBuffer* const tokens);
+
+// Estimate the final coded size given a set of 'probas'.
+size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas);
+
+// unused for now
+void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats);
+
+#endif // !DISABLE_TOKEN_BUFFER
+
+//------------------------------------------------------------------------------
+// VP8Encoder
+
+struct VP8Encoder {
+ const WebPConfig* config_; // user configuration and parameters
+ WebPPicture* pic_; // input / output picture
+
+ // headers
+ VP8EncFilterHeader filter_hdr_; // filtering information
+ VP8EncSegmentHeader segment_hdr_; // segment information
+
+ int profile_; // VP8's profile, deduced from Config.
+
+ // dimension, in macroblock units.
+ int mb_w_, mb_h_;
+ int preds_w_; // stride of the *preds_ prediction plane (=4*mb_w + 1)
+
+ // number of partitions (1, 2, 4 or 8 = MAX_NUM_PARTITIONS)
+ int num_parts_;
+
+ // per-partition boolean decoders.
+ VP8BitWriter bw_; // part0
+ VP8BitWriter parts_[MAX_NUM_PARTITIONS]; // token partitions
+ VP8TBuffer tokens_; // token buffer
+
+ int percent_; // for progress
+
+ // transparency blob
+ int has_alpha_;
+ uint8_t* alpha_data_; // non-NULL if transparency is present
+ uint32_t alpha_data_size_;
+ WebPWorker alpha_worker_;
+
+ // quantization info (one set of DC/AC dequant factor per segment)
+ VP8SegmentInfo dqm_[NUM_MB_SEGMENTS];
+ int base_quant_; // nominal quantizer value. Only used
+ // for relative coding of segments' quant.
+ int alpha_; // global susceptibility (<=> complexity)
+ int uv_alpha_; // U/V quantization susceptibility
+ // global offset of quantizers, shared by all segments
+ int dq_y1_dc_;
+ int dq_y2_dc_, dq_y2_ac_;
+ int dq_uv_dc_, dq_uv_ac_;
+
+ // probabilities and statistics
+ VP8EncProba proba_;
+ uint64_t sse_[4]; // sum of Y/U/V/A squared errors for all macroblocks
+ uint64_t sse_count_; // pixel count for the sse_[] stats
+ int coded_size_;
+ int residual_bytes_[3][4];
+ int block_count_[3];
+
+ // quality/speed settings
+ int method_; // 0=fastest, 6=best/slowest.
+ VP8RDLevel rd_opt_level_; // Deduced from method_.
+ int max_i4_header_bits_; // partition #0 safeness factor
+ int mb_header_limit_; // rough limit for header bits per MB
+ int thread_level_; // derived from config->thread_level
+ int do_search_; // derived from config->target_XXX
+ int use_tokens_; // if true, use token buffer
+
+ // Memory
+ VP8MBInfo* mb_info_; // contextual macroblock infos (mb_w_ + 1)
+ uint8_t* preds_; // predictions modes: (4*mb_w+1) * (4*mb_h+1)
+ uint32_t* nz_; // non-zero bit context: mb_w+1
+ uint8_t* y_top_; // top luma samples.
+ uint8_t* uv_top_; // top u/v samples.
+ // U and V are packed into 16 bytes (8 U + 8 V)
+ LFStats* lf_stats_; // autofilter stats (if NULL, autofilter is off)
+};
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+ // in tree.c
+extern const uint8_t VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
+extern const uint8_t
+ VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
+// Reset the token probabilities to their initial (default) values
+void VP8DefaultProbas(VP8Encoder* const enc);
+// Write the token probabilities
+void VP8WriteProbas(VP8BitWriter* const bw, const VP8EncProba* const probas);
+// Writes the partition #0 modes (that is: all intra modes)
+void VP8CodeIntraModes(VP8Encoder* const enc);
+
+ // in syntax.c
+// Generates the final bitstream by coding the partition0 and headers,
+// and appending an assembly of all the pre-coded token partitions.
+// Return true if everything is ok.
+int VP8EncWrite(VP8Encoder* const enc);
+// Release memory allocated for bit-writing in VP8EncLoop & seq.
+void VP8EncFreeBitWriters(VP8Encoder* const enc);
+
+ // in frame.c
+extern const uint8_t VP8Cat3[];
+extern const uint8_t VP8Cat4[];
+extern const uint8_t VP8Cat5[];
+extern const uint8_t VP8Cat6[];
+
+// Form all the four Intra16x16 predictions in the yuv_p_ cache
+void VP8MakeLuma16Preds(const VP8EncIterator* const it);
+// Form all the four Chroma8x8 predictions in the yuv_p_ cache
+void VP8MakeChroma8Preds(const VP8EncIterator* const it);
+// Form all the ten Intra4x4 predictions in the yuv_p_ cache
+// for the 4x4 block it->i4_
+void VP8MakeIntra4Preds(const VP8EncIterator* const it);
+// Rate calculation
+int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd);
+int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]);
+int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd);
+// Main coding calls
+int VP8EncLoop(VP8Encoder* const enc);
+int VP8EncTokenLoop(VP8Encoder* const enc);
+
+ // in webpenc.c
+// Assign an error code to a picture. Return false for convenience.
+int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error);
+int WebPReportProgress(const WebPPicture* const pic,
+ int percent, int* const percent_store);
+
+ // in analysis.c
+// Main analysis loop. Decides the segmentations and complexity.
+// Assigns a first guess for Intra16 and uvmode_ prediction modes.
+int VP8EncAnalyze(VP8Encoder* const enc);
+
+ // in quant.c
+// Sets up segment's quantization values, base_quant_ and filter strengths.
+void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
+// Pick best modes and fills the levels. Returns true if skipped.
+int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
+ VP8RDLevel rd_opt);
+
+ // in alpha.c
+void VP8EncInitAlpha(VP8Encoder* const enc); // initialize alpha compression
+int VP8EncStartAlpha(VP8Encoder* const enc); // start alpha coding process
+int VP8EncFinishAlpha(VP8Encoder* const enc); // finalize compressed data
+int VP8EncDeleteAlpha(VP8Encoder* const enc); // delete compressed data
+
+// autofilter
+void VP8InitFilter(VP8EncIterator* const it);
+void VP8StoreFilterStats(VP8EncIterator* const it);
+void VP8AdjustFilterStrength(VP8EncIterator* const it);
+
+// returns the approximate filtering strength needed to smooth a edge
+// step of 'delta', given a sharpness parameter 'sharpness'.
+int VP8FilterStrengthFromDelta(int sharpness, int delta);
+
+ // misc utils for picture_*.c:
+
+// Remove reference to the ARGB/YUVA buffer (doesn't free anything).
+void WebPPictureResetBuffers(WebPPicture* const picture);
+
+// Allocates ARGB buffer of given dimension (previous one is always free'd).
+// Preserves the YUV(A) buffer. Returns false in case of error (invalid param,
+// out-of-memory).
+int WebPPictureAllocARGB(WebPPicture* const picture, int width, int height);
+
+// Allocates YUVA buffer of given dimension (previous one is always free'd).
+// Uses picture->csp to determine whether an alpha buffer is needed.
+// Preserves the ARGB buffer.
+// Returns false in case of error (invalid param, out-of-memory).
+int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height);
+
+// Clean-up the RGB samples under fully transparent area, to help lossless
+// compressibility (no guarantee, though). Assumes that pic->use_argb is true.
+void WebPCleanupTransparentAreaLossless(WebPPicture* const pic);
+
+ // in near_lossless.c
+// Near lossless preprocessing in RGB color-space.
+int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality);
+// Near lossless adjustment for predictors.
+void VP8ApplyNearLosslessPredict(int xsize, int ysize, int pred_bits,
+ const uint32_t* argb_orig,
+ uint32_t* argb, uint32_t* argb_scratch,
+ const uint32_t* const transform_data,
+ int quality, int subtract_green);
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_ENC_VP8ENCI_H_ */
diff --git a/media/libwebp/enc/vp8li_enc.h b/media/libwebp/enc/vp8li_enc.h
new file mode 100644
index 000000000..8c5fbcbb2
--- /dev/null
+++ b/media/libwebp/enc/vp8li_enc.h
@@ -0,0 +1,95 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Lossless encoder: internal header.
+//
+// Author: Vikas Arora (vikaas.arora@gmail.com)
+
+#ifndef WEBP_ENC_VP8LI_H_
+#define WEBP_ENC_VP8LI_H_
+
+#include "./backward_references_enc.h"
+#include "./histogram_enc.h"
+#include "../utils/bit_writer_utils.h"
+#include "../webp/encode.h"
+#include "../webp/format_constants.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// maximum value of transform_bits_ in VP8LEncoder.
+#define MAX_TRANSFORM_BITS 6
+
+typedef struct {
+ const WebPConfig* config_; // user configuration and parameters
+ const WebPPicture* pic_; // input picture.
+
+ uint32_t* argb_; // Transformed argb image data.
+ uint32_t* argb_scratch_; // Scratch memory for argb rows
+ // (used for prediction).
+ uint32_t* transform_data_; // Scratch memory for transform data.
+ uint32_t* transform_mem_; // Currently allocated memory.
+ size_t transform_mem_size_; // Currently allocated memory size.
+
+ int current_width_; // Corresponds to packed image width.
+
+ // Encoding parameters derived from quality parameter.
+ int histo_bits_;
+ int transform_bits_; // <= MAX_TRANSFORM_BITS.
+ int cache_bits_; // If equal to 0, don't use color cache.
+
+ // Encoding parameters derived from image characteristics.
+ int use_cross_color_;
+ int use_subtract_green_;
+ int use_predict_;
+ int use_palette_;
+ int palette_size_;
+ uint32_t palette_[MAX_PALETTE_SIZE];
+
+ // Some 'scratch' (potentially large) objects.
+ struct VP8LBackwardRefs refs_[2]; // Backward Refs array corresponding to
+ // LZ77 & RLE coding.
+ VP8LHashChain hash_chain_; // HashChain data for constructing
+ // backward references.
+} VP8LEncoder;
+
+//------------------------------------------------------------------------------
+// internal functions. Not public.
+
+// Encodes the picture.
+// Returns 0 if config or picture is NULL or picture doesn't have valid argb
+// input.
+int VP8LEncodeImage(const WebPConfig* const config,
+ const WebPPicture* const picture);
+
+// Encodes the main image stream using the supplied bit writer.
+// If 'use_cache' is false, disables the use of color cache.
+WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
+ const WebPPicture* const picture,
+ VP8LBitWriter* const bw, int use_cache);
+
+//------------------------------------------------------------------------------
+// Image transforms in predictor.c.
+
+void VP8LResidualImage(int width, int height, int bits, int low_effort,
+ uint32_t* const argb, uint32_t* const argb_scratch,
+ uint32_t* const image, int near_lossless, int exact,
+ int used_subtract_green);
+
+void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
+ uint32_t* const argb, uint32_t* image);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_ENC_VP8LI_H_ */
diff --git a/media/libwebp/moz.build b/media/libwebp/moz.build
new file mode 100644
index 000000000..7d3aa9d0f
--- /dev/null
+++ b/media/libwebp/moz.build
@@ -0,0 +1,28 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files('**'):
+ BUG_COMPONENT = ('Core', 'ImageLib')
+
+EXPORTS.webp += [
+ 'webp/decode.h',
+ 'webp/demux.h',
+ 'webp/mux_types.h',
+ 'webp/types.h',
+]
+
+DIRS += [
+ 'dec',
+ 'demux',
+ 'dsp',
+ 'moz',
+ 'utils',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
diff --git a/media/libwebp/moz/cpu.cpp b/media/libwebp/moz/cpu.cpp
new file mode 100644
index 000000000..39b9f3500
--- /dev/null
+++ b/media/libwebp/moz/cpu.cpp
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* This file replaces the CPU info methods originally implemented in
+ * src/dsp/cpu.c, due to missing dependencies for Andriod builds. It
+ * controls if NEON/SSE/etc is used. */
+
+#include "../dsp/dsp.h"
+#include "mozilla/arm.h"
+#include "mozilla/SSE.h"
+
+static int MozCPUInfo(CPUFeature feature)
+{
+ switch (feature) {
+#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
+ case kSSE2:
+ return mozilla::supports_sse2();
+ case kSSE3:
+ return mozilla::supports_sse3();
+ case kSSE4_1:
+ return mozilla::supports_sse4_1();
+ case kAVX:
+ return mozilla::supports_avx();
+ case kAVX2:
+ return mozilla::supports_avx2();
+#endif
+#if defined(WEBP_USE_NEON) || defined(WEBP_ANDROID_NEON)
+ case kNEON:
+ return mozilla::supports_neon();
+#endif
+#if defined(WEBP_USE_MIPS32) || defined(WEBP_USE_MIPS_DSP_R2) || defined(WEBP_USE_MSA)
+ case kMIPS32:
+ case kMIPSdspR2:
+ case kMSA:
+ return 1;
+#endif
+ default:
+ return 0;
+ }
+}
+
+VP8CPUInfo VP8GetCPUInfo = MozCPUInfo;
diff --git a/media/libwebp/moz/moz.build b/media/libwebp/moz/moz.build
new file mode 100644
index 000000000..c60474f45
--- /dev/null
+++ b/media/libwebp/moz/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files('**'):
+ BUG_COMPONENT = ('Core', 'ImageLib')
+
+SOURCES += [
+ 'cpu.cpp',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
diff --git a/media/libwebp/update.sh b/media/libwebp/update.sh
new file mode 100644
index 000000000..57cd45996
--- /dev/null
+++ b/media/libwebp/update.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#
+# Usage: ./update.sh <libwebp_directory>
+#
+# Copies the needed files from a directory containing the original
+# libwebp source.
+
+cp $1/AUTHORS .
+cp $1/COPYING .
+cp $1/NEWS .
+cp $1/PATENTS .
+cp $1/README .
+cp $1/README.mux .
+
+mkdir -p webp
+cp $1/src/webp/*.h webp
+
+mkdir -p dec
+cp $1/src/dec/*.h dec
+cp $1/src/dec/alpha_dec.c dec
+cp $1/src/dec/buffer_dec.c dec
+cp $1/src/dec/frame_dec.c dec
+cp $1/src/dec/idec_dec.c dec
+cp $1/src/dec/io_dec.c dec
+cp $1/src/dec/quant_dec.c dec
+cp $1/src/dec/tree_dec.c dec
+cp $1/src/dec/vp8_dec.c dec
+cp $1/src/dec/vp8l_dec.c dec
+cp $1/src/dec/webp_dec.c dec
+
+mkdir -p demux
+cp $1/src/demux/demux.c demux
+
+mkdir -p dsp
+cp $1/src/dsp/*.h dsp
+cp $1/src/dsp/alpha_processing.c dsp
+cp $1/src/dsp/alpha_processing_sse2.c dsp
+cp $1/src/dsp/alpha_processing_sse41.c dsp
+cp $1/src/dsp/dec.c dsp
+cp $1/src/dsp/dec_clip_tables.c dsp
+cp $1/src/dsp/dec_neon.c dsp
+cp $1/src/dsp/dec_sse2.c dsp
+cp $1/src/dsp/dec_sse41.c dsp
+cp $1/src/dsp/filters.c dsp
+cp $1/src/dsp/filters_sse2.c dsp
+cp $1/src/dsp/lossless.c dsp
+cp $1/src/dsp/lossless_neon.c dsp
+cp $1/src/dsp/lossless_sse2.c dsp
+cp $1/src/dsp/rescaler.c dsp
+cp $1/src/dsp/rescaler_neon.c dsp
+cp $1/src/dsp/rescaler_sse2.c dsp
+cp $1/src/dsp/upsampling.c dsp
+cp $1/src/dsp/upsampling_neon.c dsp
+cp $1/src/dsp/upsampling_sse2.c dsp
+cp $1/src/dsp/yuv.c dsp
+cp $1/src/dsp/yuv_sse2.c dsp
+
+mkdir -p enc
+cp $1/src/enc/*.h enc
+
+mkdir -p utils
+cp $1/src/utils/*.h utils
+cp $1/src/utils/bit_reader_utils.c utils
+cp $1/src/utils/color_cache_utils.c utils
+cp $1/src/utils/filters_utils.c utils
+cp $1/src/utils/huffman_utils.c utils
+cp $1/src/utils/quant_levels_dec_utils.c utils
+cp $1/src/utils/quant_levels_utils.c utils
+cp $1/src/utils/random_utils.c utils
+cp $1/src/utils/rescaler_utils.c utils
+cp $1/src/utils/thread_utils.c utils
+cp $1/src/utils/utils.c utils
diff --git a/media/libwebp/utils/bit_reader_inl_utils.h b/media/libwebp/utils/bit_reader_inl_utils.h
new file mode 100644
index 000000000..fd7fb0446
--- /dev/null
+++ b/media/libwebp/utils/bit_reader_inl_utils.h
@@ -0,0 +1,190 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Specific inlined methods for boolean decoder [VP8GetBit() ...]
+// This file should be included by the .c sources that actually need to call
+// these methods.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_UTILS_BIT_READER_INL_H_
+#define WEBP_UTILS_BIT_READER_INL_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include <string.h> // for memcpy
+
+#include "../dsp/dsp.h"
+#include "./bit_reader_utils.h"
+#include "./endian_inl_utils.h"
+#include "./utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Derived type lbit_t = natural type for memory I/O
+
+#if (BITS > 32)
+typedef uint64_t lbit_t;
+#elif (BITS > 16)
+typedef uint32_t lbit_t;
+#elif (BITS > 8)
+typedef uint16_t lbit_t;
+#else
+typedef uint8_t lbit_t;
+#endif
+
+extern const uint8_t kVP8Log2Range[128];
+extern const uint8_t kVP8NewRange[128];
+
+// special case for the tail byte-reading
+void VP8LoadFinalBytes(VP8BitReader* const br);
+
+//------------------------------------------------------------------------------
+// Inlined critical functions
+
+// makes sure br->value_ has at least BITS bits worth of data
+static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE
+void VP8LoadNewBytes(VP8BitReader* const br) {
+ assert(br != NULL && br->buf_ != NULL);
+ // Read 'BITS' bits at a time if possible.
+ if (br->buf_ < br->buf_max_) {
+ // convert memory type to register type (with some zero'ing!)
+ bit_t bits;
+#if defined(WEBP_USE_MIPS32)
+ // This is needed because of un-aligned read.
+ lbit_t in_bits;
+ lbit_t* p_buf_ = (lbit_t*)br->buf_;
+ __asm__ volatile(
+ ".set push \n\t"
+ ".set at \n\t"
+ ".set macro \n\t"
+ "ulw %[in_bits], 0(%[p_buf_]) \n\t"
+ ".set pop \n\t"
+ : [in_bits]"=r"(in_bits)
+ : [p_buf_]"r"(p_buf_)
+ : "memory", "at"
+ );
+#else
+ lbit_t in_bits;
+ memcpy(&in_bits, br->buf_, sizeof(in_bits));
+#endif
+ br->buf_ += BITS >> 3;
+#if !defined(WORDS_BIGENDIAN)
+#if (BITS > 32)
+ bits = BSwap64(in_bits);
+ bits >>= 64 - BITS;
+#elif (BITS >= 24)
+ bits = BSwap32(in_bits);
+ bits >>= (32 - BITS);
+#elif (BITS == 16)
+ bits = BSwap16(in_bits);
+#else // BITS == 8
+ bits = (bit_t)in_bits;
+#endif // BITS > 32
+#else // WORDS_BIGENDIAN
+ bits = (bit_t)in_bits;
+ if (BITS != 8 * sizeof(bit_t)) bits >>= (8 * sizeof(bit_t) - BITS);
+#endif
+ br->value_ = bits | (br->value_ << BITS);
+ br->bits_ += BITS;
+ } else {
+ VP8LoadFinalBytes(br); // no need to be inlined
+ }
+}
+
+// Read a bit with proba 'prob'. Speed-critical function!
+static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
+ // Don't move this declaration! It makes a big speed difference to store
+ // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
+ // alter br->range_ value.
+ range_t range = br->range_;
+ if (br->bits_ < 0) {
+ VP8LoadNewBytes(br);
+ }
+ {
+ const int pos = br->bits_;
+ const range_t split = (range * prob) >> 8;
+ const range_t value = (range_t)(br->value_ >> pos);
+ const int bit = (value > split);
+ if (bit) {
+ range -= split;
+ br->value_ -= (bit_t)(split + 1) << pos;
+ } else {
+ range = split + 1;
+ }
+ {
+ const int shift = 7 ^ BitsLog2Floor(range);
+ range <<= shift;
+ br->bits_ -= shift;
+ }
+ br->range_ = range - 1;
+ return bit;
+ }
+}
+
+// simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here)
+static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
+int VP8GetSigned(VP8BitReader* const br, int v) {
+ if (br->bits_ < 0) {
+ VP8LoadNewBytes(br);
+ }
+ {
+ const int pos = br->bits_;
+ const range_t split = br->range_ >> 1;
+ const range_t value = (range_t)(br->value_ >> pos);
+ const int32_t mask = (int32_t)(split - value) >> 31; // -1 or 0
+ br->bits_ -= 1;
+ br->range_ += mask;
+ br->range_ |= 1;
+ br->value_ -= (bit_t)((split + 1) & mask) << pos;
+ return (v ^ mask) - mask;
+ }
+}
+
+static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) {
+ // Don't move this declaration! It makes a big speed difference to store
+ // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
+ // alter br->range_ value.
+ range_t range = br->range_;
+ if (br->bits_ < 0) {
+ VP8LoadNewBytes(br);
+ }
+ {
+ const int pos = br->bits_;
+ const range_t split = (range * prob) >> 8;
+ const range_t value = (range_t)(br->value_ >> pos);
+ int bit; // Don't use 'const int bit = (value > split);", it's slower.
+ if (value > split) {
+ range -= split + 1;
+ br->value_ -= (bit_t)(split + 1) << pos;
+ bit = 1;
+ } else {
+ range = split;
+ bit = 0;
+ }
+ if (range <= (range_t)0x7e) {
+ const int shift = kVP8Log2Range[range];
+ range = kVP8NewRange[range];
+ br->bits_ -= shift;
+ }
+ br->range_ = range;
+ return bit;
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WEBP_UTILS_BIT_READER_INL_H_
diff --git a/media/libwebp/utils/bit_reader_utils.c b/media/libwebp/utils/bit_reader_utils.c
new file mode 100644
index 000000000..c3157e8fe
--- /dev/null
+++ b/media/libwebp/utils/bit_reader_utils.c
@@ -0,0 +1,222 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Boolean decoder non-inlined methods
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "./bit_reader_inl_utils.h"
+#include "../utils/utils.h"
+
+//------------------------------------------------------------------------------
+// VP8BitReader
+
+void VP8BitReaderSetBuffer(VP8BitReader* const br,
+ const uint8_t* const start,
+ size_t size) {
+ br->buf_ = start;
+ br->buf_end_ = start + size;
+ br->buf_max_ =
+ (size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1
+ : start;
+}
+
+void VP8InitBitReader(VP8BitReader* const br,
+ const uint8_t* const start, size_t size) {
+ assert(br != NULL);
+ assert(start != NULL);
+ assert(size < (1u << 31)); // limit ensured by format and upstream checks
+ br->range_ = 255 - 1;
+ br->value_ = 0;
+ br->bits_ = -8; // to load the very first 8bits
+ br->eof_ = 0;
+ VP8BitReaderSetBuffer(br, start, size);
+ VP8LoadNewBytes(br);
+}
+
+void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
+ if (br->buf_ != NULL) {
+ br->buf_ += offset;
+ br->buf_end_ += offset;
+ br->buf_max_ += offset;
+ }
+}
+
+const uint8_t kVP8Log2Range[128] = {
+ 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0
+};
+
+// range = ((range - 1) << kVP8Log2Range[range]) + 1
+const uint8_t kVP8NewRange[128] = {
+ 127, 127, 191, 127, 159, 191, 223, 127,
+ 143, 159, 175, 191, 207, 223, 239, 127,
+ 135, 143, 151, 159, 167, 175, 183, 191,
+ 199, 207, 215, 223, 231, 239, 247, 127,
+ 131, 135, 139, 143, 147, 151, 155, 159,
+ 163, 167, 171, 175, 179, 183, 187, 191,
+ 195, 199, 203, 207, 211, 215, 219, 223,
+ 227, 231, 235, 239, 243, 247, 251, 127,
+ 129, 131, 133, 135, 137, 139, 141, 143,
+ 145, 147, 149, 151, 153, 155, 157, 159,
+ 161, 163, 165, 167, 169, 171, 173, 175,
+ 177, 179, 181, 183, 185, 187, 189, 191,
+ 193, 195, 197, 199, 201, 203, 205, 207,
+ 209, 211, 213, 215, 217, 219, 221, 223,
+ 225, 227, 229, 231, 233, 235, 237, 239,
+ 241, 243, 245, 247, 249, 251, 253, 127
+};
+
+void VP8LoadFinalBytes(VP8BitReader* const br) {
+ assert(br != NULL && br->buf_ != NULL);
+ // Only read 8bits at a time
+ if (br->buf_ < br->buf_end_) {
+ br->bits_ += 8;
+ br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
+ } else if (!br->eof_) {
+ br->value_ <<= 8;
+ br->bits_ += 8;
+ br->eof_ = 1;
+ } else {
+ br->bits_ = 0; // This is to avoid undefined behaviour with shifts.
+ }
+}
+
+//------------------------------------------------------------------------------
+// Higher-level calls
+
+uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
+ uint32_t v = 0;
+ while (bits-- > 0) {
+ v |= VP8GetBit(br, 0x80) << bits;
+ }
+ return v;
+}
+
+int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
+ const int value = VP8GetValue(br, bits);
+ return VP8Get(br) ? -value : value;
+}
+
+//------------------------------------------------------------------------------
+// VP8LBitReader
+
+#define VP8L_LOG8_WBITS 4 // Number of bytes needed to store VP8L_WBITS bits.
+
+#if defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
+ defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64__) || defined(_M_X64)
+#define VP8L_USE_FAST_LOAD
+#endif
+
+static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = {
+ 0,
+ 0x000001, 0x000003, 0x000007, 0x00000f,
+ 0x00001f, 0x00003f, 0x00007f, 0x0000ff,
+ 0x0001ff, 0x0003ff, 0x0007ff, 0x000fff,
+ 0x001fff, 0x003fff, 0x007fff, 0x00ffff,
+ 0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff,
+ 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff
+};
+
+void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start,
+ size_t length) {
+ size_t i;
+ vp8l_val_t value = 0;
+ assert(br != NULL);
+ assert(start != NULL);
+ assert(length < 0xfffffff8u); // can't happen with a RIFF chunk.
+
+ br->len_ = length;
+ br->val_ = 0;
+ br->bit_pos_ = 0;
+ br->eos_ = 0;
+
+ if (length > sizeof(br->val_)) {
+ length = sizeof(br->val_);
+ }
+ for (i = 0; i < length; ++i) {
+ value |= (vp8l_val_t)start[i] << (8 * i);
+ }
+ br->val_ = value;
+ br->pos_ = length;
+ br->buf_ = start;
+}
+
+void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
+ const uint8_t* const buf, size_t len) {
+ assert(br != NULL);
+ assert(buf != NULL);
+ assert(len < 0xfffffff8u); // can't happen with a RIFF chunk.
+ br->buf_ = buf;
+ br->len_ = len;
+ // pos_ > len_ should be considered a param error.
+ br->eos_ = (br->pos_ > br->len_) || VP8LIsEndOfStream(br);
+}
+
+static void VP8LSetEndOfStream(VP8LBitReader* const br) {
+ br->eos_ = 1;
+ br->bit_pos_ = 0; // To avoid undefined behaviour with shifts.
+}
+
+// If not at EOS, reload up to VP8L_LBITS byte-by-byte
+static void ShiftBytes(VP8LBitReader* const br) {
+ while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
+ br->val_ >>= 8;
+ br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8);
+ ++br->pos_;
+ br->bit_pos_ -= 8;
+ }
+ if (VP8LIsEndOfStream(br)) {
+ VP8LSetEndOfStream(br);
+ }
+}
+
+void VP8LDoFillBitWindow(VP8LBitReader* const br) {
+ assert(br->bit_pos_ >= VP8L_WBITS);
+#if defined(VP8L_USE_FAST_LOAD)
+ if (br->pos_ + sizeof(br->val_) < br->len_) {
+ br->val_ >>= VP8L_WBITS;
+ br->bit_pos_ -= VP8L_WBITS;
+ br->val_ |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf_ + br->pos_)) <<
+ (VP8L_LBITS - VP8L_WBITS);
+ br->pos_ += VP8L_LOG8_WBITS;
+ return;
+ }
+#endif
+ ShiftBytes(br); // Slow path.
+}
+
+uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
+ assert(n_bits >= 0);
+ // Flag an error if end_of_stream or n_bits is more than allowed limit.
+ if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
+ const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
+ const int new_bits = br->bit_pos_ + n_bits;
+ br->bit_pos_ = new_bits;
+ ShiftBytes(br);
+ return val;
+ } else {
+ VP8LSetEndOfStream(br);
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/utils/bit_reader_utils.h b/media/libwebp/utils/bit_reader_utils.h
new file mode 100644
index 000000000..ec3426cd1
--- /dev/null
+++ b/media/libwebp/utils/bit_reader_utils.h
@@ -0,0 +1,174 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Boolean decoder
+//
+// Author: Skal (pascal.massimino@gmail.com)
+// Vikas Arora (vikaas.arora@gmail.com)
+
+#ifndef WEBP_UTILS_BIT_READER_H_
+#define WEBP_UTILS_BIT_READER_H_
+
+#include <assert.h>
+#ifdef _MSC_VER
+#include <stdlib.h> // _byteswap_ulong
+#endif
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The Boolean decoder needs to maintain infinite precision on the value_ field.
+// However, since range_ is only 8bit, we only need an active window of 8 bits
+// for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls
+// below 128, range_ is updated, and fresh bits read from the bitstream are
+// brought in as LSB. To avoid reading the fresh bits one by one (slow), we
+// cache BITS of them ahead. The total of (BITS + 8) bits must fit into a
+// natural register (with type bit_t). To fetch BITS bits from bitstream we
+// use a type lbit_t.
+//
+// BITS can be any multiple of 8 from 8 to 56 (inclusive).
+// Pick values that fit natural register size.
+
+#if defined(__i386__) || defined(_M_IX86) // x86 32bit
+#define BITS 24
+#elif defined(__x86_64__) || defined(_M_X64) // x86 64bit
+#define BITS 56
+#elif defined(__arm__) || defined(_M_ARM) // ARM
+#define BITS 24
+#elif defined(__aarch64__) // ARM 64bit
+#define BITS 56
+#elif defined(__mips__) // MIPS
+#define BITS 24
+#else // reasonable default
+#define BITS 24
+#endif
+
+//------------------------------------------------------------------------------
+// Derived types and constants:
+// bit_t = natural register type for storing 'value_' (which is BITS+8 bits)
+// range_t = register for 'range_' (which is 8bits only)
+
+#if (BITS > 24)
+typedef uint64_t bit_t;
+#else
+typedef uint32_t bit_t;
+#endif
+
+typedef uint32_t range_t;
+
+//------------------------------------------------------------------------------
+// Bitreader
+
+typedef struct VP8BitReader VP8BitReader;
+struct VP8BitReader {
+ // boolean decoder (keep the field ordering as is!)
+ bit_t value_; // current value
+ range_t range_; // current range minus 1. In [127, 254] interval.
+ int bits_; // number of valid bits left
+ // read buffer
+ const uint8_t* buf_; // next byte to be read
+ const uint8_t* buf_end_; // end of read buffer
+ const uint8_t* buf_max_; // max packed-read position on buffer
+ int eof_; // true if input is exhausted
+};
+
+// Initialize the bit reader and the boolean decoder.
+void VP8InitBitReader(VP8BitReader* const br,
+ const uint8_t* const start, size_t size);
+// Sets the working read buffer.
+void VP8BitReaderSetBuffer(VP8BitReader* const br,
+ const uint8_t* const start, size_t size);
+
+// Update internal pointers to displace the byte buffer by the
+// relative offset 'offset'.
+void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);
+
+// return the next value made of 'num_bits' bits
+uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
+static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
+ return VP8GetValue(br, 1);
+}
+
+// return the next value with sign-extension.
+int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
+
+// bit_reader_inl.h will implement the following methods:
+// static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob)
+// static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v)
+// and should be included by the .c files that actually need them.
+// This is to avoid recompiling the whole library whenever this file is touched,
+// and also allowing platform-specific ad-hoc hacks.
+
+// -----------------------------------------------------------------------------
+// Bitreader for lossless format
+
+// maximum number of bits (inclusive) the bit-reader can handle:
+#define VP8L_MAX_NUM_BIT_READ 24
+
+#define VP8L_LBITS 64 // Number of bits prefetched (= bit-size of vp8l_val_t).
+#define VP8L_WBITS 32 // Minimum number of bytes ready after VP8LFillBitWindow.
+
+typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit.
+
+typedef struct {
+ vp8l_val_t val_; // pre-fetched bits
+ const uint8_t* buf_; // input byte buffer
+ size_t len_; // buffer length
+ size_t pos_; // byte position in buf_
+ int bit_pos_; // current bit-reading position in val_
+ int eos_; // true if a bit was read past the end of buffer
+} VP8LBitReader;
+
+void VP8LInitBitReader(VP8LBitReader* const br,
+ const uint8_t* const start,
+ size_t length);
+
+// Sets a new data buffer.
+void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
+ const uint8_t* const buffer, size_t length);
+
+// Reads the specified number of bits from read buffer.
+// Flags an error in case end_of_stream or n_bits is more than the allowed limit
+// of VP8L_MAX_NUM_BIT_READ (inclusive).
+// Flags eos_ if this read attempt is going to cross the read buffer.
+uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
+
+// Return the prefetched bits, so they can be looked up.
+static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
+ return (uint32_t)(br->val_ >> (br->bit_pos_ & (VP8L_LBITS - 1)));
+}
+
+// Returns true if there was an attempt at reading bit past the end of
+// the buffer. Doesn't set br->eos_ flag.
+static WEBP_INLINE int VP8LIsEndOfStream(const VP8LBitReader* const br) {
+ assert(br->pos_ <= br->len_);
+ return br->eos_ || ((br->pos_ == br->len_) && (br->bit_pos_ > VP8L_LBITS));
+}
+
+// For jumping over a number of bits in the bit stream when accessed with
+// VP8LPrefetchBits and VP8LFillBitWindow.
+static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {
+ br->bit_pos_ = val;
+ br->eos_ = VP8LIsEndOfStream(br);
+}
+
+// Advances the read buffer by 4 bytes to make room for reading next 32 bits.
+// Speed critical, but infrequent part of the code can be non-inlined.
+extern void VP8LDoFillBitWindow(VP8LBitReader* const br);
+static WEBP_INLINE void VP8LFillBitWindow(VP8LBitReader* const br) {
+ if (br->bit_pos_ >= VP8L_WBITS) VP8LDoFillBitWindow(br);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_BIT_READER_H_ */
diff --git a/media/libwebp/utils/bit_writer_utils.h b/media/libwebp/utils/bit_writer_utils.h
new file mode 100644
index 000000000..9c02bbc06
--- /dev/null
+++ b/media/libwebp/utils/bit_writer_utils.h
@@ -0,0 +1,146 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Bit writing and boolean coder
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_UTILS_BIT_WRITER_H_
+#define WEBP_UTILS_BIT_WRITER_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Bit-writing
+
+typedef struct VP8BitWriter VP8BitWriter;
+struct VP8BitWriter {
+ int32_t range_; // range-1
+ int32_t value_;
+ int run_; // number of outstanding bits
+ int nb_bits_; // number of pending bits
+ uint8_t* buf_; // internal buffer. Re-allocated regularly. Not owned.
+ size_t pos_;
+ size_t max_pos_;
+ int error_; // true in case of error
+};
+
+// Initialize the object. Allocates some initial memory based on expected_size.
+int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size);
+// Finalize the bitstream coding. Returns a pointer to the internal buffer.
+uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
+// Release any pending memory and zeroes the object. Not a mandatory call.
+// Only useful in case of error, when the internal buffer hasn't been grabbed!
+void VP8BitWriterWipeOut(VP8BitWriter* const bw);
+
+int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
+int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
+void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
+void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
+
+// Appends some bytes to the internal buffer. Data is copied.
+int VP8BitWriterAppend(VP8BitWriter* const bw,
+ const uint8_t* data, size_t size);
+
+// return approximate write position (in bits)
+static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
+ const uint64_t nb_bits = 8 + bw->nb_bits_; // bw->nb_bits_ is <= 0, note
+ return (bw->pos_ + bw->run_) * 8 + nb_bits;
+}
+
+// Returns a pointer to the internal buffer.
+static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
+ return bw->buf_;
+}
+// Returns the size of the internal buffer.
+static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
+ return bw->pos_;
+}
+
+//------------------------------------------------------------------------------
+// VP8LBitWriter
+
+#if defined(__x86_64__) || defined(_M_X64) // 64bit
+typedef uint64_t vp8l_atype_t; // accumulator type
+typedef uint32_t vp8l_wtype_t; // writing type
+#define WSWAP HToLE32
+#define VP8L_WRITER_BYTES 4 // sizeof(vp8l_wtype_t)
+#define VP8L_WRITER_BITS 32 // 8 * sizeof(vp8l_wtype_t)
+#define VP8L_WRITER_MAX_BITS 64 // 8 * sizeof(vp8l_atype_t)
+#else
+typedef uint32_t vp8l_atype_t;
+typedef uint16_t vp8l_wtype_t;
+#define WSWAP HToLE16
+#define VP8L_WRITER_BYTES 2
+#define VP8L_WRITER_BITS 16
+#define VP8L_WRITER_MAX_BITS 32
+#endif
+
+typedef struct {
+ vp8l_atype_t bits_; // bit accumulator
+ int used_; // number of bits used in accumulator
+ uint8_t* buf_; // start of buffer
+ uint8_t* cur_; // current write position
+ uint8_t* end_; // end of buffer
+
+ // After all bits are written (VP8LBitWriterFinish()), the caller must observe
+ // the state of error_. A value of 1 indicates that a memory allocation
+ // failure has happened during bit writing. A value of 0 indicates successful
+ // writing of bits.
+ int error_;
+} VP8LBitWriter;
+
+static WEBP_INLINE size_t VP8LBitWriterNumBytes(VP8LBitWriter* const bw) {
+ return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
+}
+
+// Returns false in case of memory allocation error.
+int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
+// Finalize the bitstream coding. Returns a pointer to the internal buffer.
+uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
+// Release any pending memory and zeroes the object.
+void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
+
+// Internal function for VP8LPutBits flushing 32 bits from the written state.
+void VP8LPutBitsFlushBits(VP8LBitWriter* const bw);
+
+// PutBits internal function used in the 16 bit vp8l_wtype_t case.
+void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
+
+// This function writes bits into bytes in increasing addresses (little endian),
+// and within a byte least-significant-bit first.
+// This function can write up to 32 bits in one go, but VP8LBitReader can only
+// read 24 bits max (VP8L_MAX_NUM_BIT_READ).
+// VP8LBitWriter's error_ flag is set in case of memory allocation error.
+static WEBP_INLINE void VP8LPutBits(VP8LBitWriter* const bw,
+ uint32_t bits, int n_bits) {
+ if (sizeof(vp8l_wtype_t) == 4) {
+ if (n_bits > 0) {
+ if (bw->used_ >= 32) {
+ VP8LPutBitsFlushBits(bw);
+ }
+ bw->bits_ |= (vp8l_atype_t)bits << bw->used_;
+ bw->used_ += n_bits;
+ }
+ } else {
+ VP8LPutBitsInternal(bw, bits, n_bits);
+ }
+}
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_BIT_WRITER_H_ */
diff --git a/media/libwebp/utils/color_cache_utils.c b/media/libwebp/utils/color_cache_utils.c
new file mode 100644
index 000000000..0172590c4
--- /dev/null
+++ b/media/libwebp/utils/color_cache_utils.c
@@ -0,0 +1,49 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Color Cache for WebP Lossless
+//
+// Author: Jyrki Alakuijala (jyrki@google.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "./color_cache_utils.h"
+#include "./utils.h"
+
+//------------------------------------------------------------------------------
+// VP8LColorCache.
+
+int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
+ const int hash_size = 1 << hash_bits;
+ assert(cc != NULL);
+ assert(hash_bits > 0);
+ cc->colors_ = (uint32_t*)WebPSafeCalloc((uint64_t)hash_size,
+ sizeof(*cc->colors_));
+ if (cc->colors_ == NULL) return 0;
+ cc->hash_shift_ = 32 - hash_bits;
+ cc->hash_bits_ = hash_bits;
+ return 1;
+}
+
+void VP8LColorCacheClear(VP8LColorCache* const cc) {
+ if (cc != NULL) {
+ WebPSafeFree(cc->colors_);
+ cc->colors_ = NULL;
+ }
+}
+
+void VP8LColorCacheCopy(const VP8LColorCache* const src,
+ VP8LColorCache* const dst) {
+ assert(src != NULL);
+ assert(dst != NULL);
+ assert(src->hash_bits_ == dst->hash_bits_);
+ memcpy(dst->colors_, src->colors_,
+ ((size_t)1u << dst->hash_bits_) * sizeof(*dst->colors_));
+}
diff --git a/media/libwebp/utils/color_cache_utils.h b/media/libwebp/utils/color_cache_utils.h
new file mode 100644
index 000000000..c373e6b36
--- /dev/null
+++ b/media/libwebp/utils/color_cache_utils.h
@@ -0,0 +1,85 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Color Cache for WebP Lossless
+//
+// Authors: Jyrki Alakuijala (jyrki@google.com)
+// Urvang Joshi (urvang@google.com)
+
+#ifndef WEBP_UTILS_COLOR_CACHE_H_
+#define WEBP_UTILS_COLOR_CACHE_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Main color cache struct.
+typedef struct {
+ uint32_t *colors_; // color entries
+ int hash_shift_; // Hash shift: 32 - hash_bits_.
+ int hash_bits_;
+} VP8LColorCache;
+
+static const uint64_t kHashMul = 0x1e35a7bdull;
+
+static WEBP_INLINE int HashPix(uint32_t argb, int shift) {
+ return (int)(((argb * kHashMul) & 0xffffffffu) >> shift);
+}
+
+static WEBP_INLINE uint32_t VP8LColorCacheLookup(
+ const VP8LColorCache* const cc, uint32_t key) {
+ assert((key >> cc->hash_bits_) == 0u);
+ return cc->colors_[key];
+}
+
+static WEBP_INLINE void VP8LColorCacheSet(const VP8LColorCache* const cc,
+ uint32_t key, uint32_t argb) {
+ assert((key >> cc->hash_bits_) == 0u);
+ cc->colors_[key] = argb;
+}
+
+static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache* const cc,
+ uint32_t argb) {
+ const int key = HashPix(argb, cc->hash_shift_);
+ cc->colors_[key] = argb;
+}
+
+static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache* const cc,
+ uint32_t argb) {
+ return HashPix(argb, cc->hash_shift_);
+}
+
+// Return the key if cc contains argb, and -1 otherwise.
+static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc,
+ uint32_t argb) {
+ const int key = HashPix(argb, cc->hash_shift_);
+ return (cc->colors_[key] == argb) ? key : -1;
+}
+
+//------------------------------------------------------------------------------
+
+// Initializes the color cache with 'hash_bits' bits for the keys.
+// Returns false in case of memory error.
+int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits);
+
+void VP8LColorCacheCopy(const VP8LColorCache* const src,
+ VP8LColorCache* const dst);
+
+// Delete the memory associated to color cache.
+void VP8LColorCacheClear(VP8LColorCache* const color_cache);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // WEBP_UTILS_COLOR_CACHE_H_
diff --git a/media/libwebp/utils/endian_inl_utils.h b/media/libwebp/utils/endian_inl_utils.h
new file mode 100644
index 000000000..e11260ff7
--- /dev/null
+++ b/media/libwebp/utils/endian_inl_utils.h
@@ -0,0 +1,100 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Endian related functions.
+
+#ifndef WEBP_UTILS_ENDIAN_INL_H_
+#define WEBP_UTILS_ENDIAN_INL_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "../dsp/dsp.h"
+#include "../webp/types.h"
+
+// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
+#if !defined(WORDS_BIGENDIAN) && \
+ (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
+ (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
+#define WORDS_BIGENDIAN
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+#define HToLE32 BSwap32
+#define HToLE16 BSwap16
+#else
+#define HToLE32(x) (x)
+#define HToLE16(x) (x)
+#endif
+
+#if !defined(HAVE_CONFIG_H)
+#if LOCAL_GCC_PREREQ(4,8) || __has_builtin(__builtin_bswap16)
+#define HAVE_BUILTIN_BSWAP16
+#endif
+#if LOCAL_GCC_PREREQ(4,3) || __has_builtin(__builtin_bswap32)
+#define HAVE_BUILTIN_BSWAP32
+#endif
+#if LOCAL_GCC_PREREQ(4,3) || __has_builtin(__builtin_bswap64)
+#define HAVE_BUILTIN_BSWAP64
+#endif
+#endif // !HAVE_CONFIG_H
+
+static WEBP_INLINE uint16_t BSwap16(uint16_t x) {
+#if defined(HAVE_BUILTIN_BSWAP16)
+ return __builtin_bswap16(x);
+#elif defined(_MSC_VER)
+ return _byteswap_ushort(x);
+#else
+ // gcc will recognize a 'rorw $8, ...' here:
+ return (x >> 8) | ((x & 0xff) << 8);
+#endif // HAVE_BUILTIN_BSWAP16
+}
+
+static WEBP_INLINE uint32_t BSwap32(uint32_t x) {
+#if defined(WEBP_USE_MIPS32_R2)
+ uint32_t ret;
+ __asm__ volatile (
+ "wsbh %[ret], %[x] \n\t"
+ "rotr %[ret], %[ret], 16 \n\t"
+ : [ret]"=r"(ret)
+ : [x]"r"(x)
+ );
+ return ret;
+#elif defined(HAVE_BUILTIN_BSWAP32)
+ return __builtin_bswap32(x);
+#elif defined(__i386__) || defined(__x86_64__)
+ uint32_t swapped_bytes;
+ __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x));
+ return swapped_bytes;
+#elif defined(_MSC_VER)
+ return (uint32_t)_byteswap_ulong(x);
+#else
+ return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
+#endif // HAVE_BUILTIN_BSWAP32
+}
+
+static WEBP_INLINE uint64_t BSwap64(uint64_t x) {
+#if defined(HAVE_BUILTIN_BSWAP64)
+ return __builtin_bswap64(x);
+#elif defined(__x86_64__)
+ uint64_t swapped_bytes;
+ __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x));
+ return swapped_bytes;
+#elif defined(_MSC_VER)
+ return (uint64_t)_byteswap_uint64(x);
+#else // generic code for swapping 64-bit values (suggested by bdb@)
+ x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32);
+ x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16);
+ x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8);
+ return x;
+#endif // HAVE_BUILTIN_BSWAP64
+}
+
+#endif // WEBP_UTILS_ENDIAN_INL_H_
diff --git a/media/libwebp/utils/filters_utils.c b/media/libwebp/utils/filters_utils.c
new file mode 100644
index 000000000..49c1d18a2
--- /dev/null
+++ b/media/libwebp/utils/filters_utils.c
@@ -0,0 +1,76 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// filter estimation
+//
+// Author: Urvang (urvang@google.com)
+
+#include "./filters_utils.h"
+#include <stdlib.h>
+#include <string.h>
+
+// -----------------------------------------------------------------------------
+// Quick estimate of a potentially interesting filter mode to try.
+
+#define SMAX 16
+#define SDIFF(a, b) (abs((a) - (b)) >> 4) // Scoring diff, in [0..SMAX)
+
+static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) {
+ const int g = a + b - c;
+ return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit
+}
+
+WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t* data,
+ int width, int height, int stride) {
+ int i, j;
+ int bins[WEBP_FILTER_LAST][SMAX];
+ memset(bins, 0, sizeof(bins));
+
+ // We only sample every other pixels. That's enough.
+ for (j = 2; j < height - 1; j += 2) {
+ const uint8_t* const p = data + j * stride;
+ int mean = p[0];
+ for (i = 2; i < width - 1; i += 2) {
+ const int diff0 = SDIFF(p[i], mean);
+ const int diff1 = SDIFF(p[i], p[i - 1]);
+ const int diff2 = SDIFF(p[i], p[i - width]);
+ const int grad_pred =
+ GradientPredictor(p[i - 1], p[i - width], p[i - width - 1]);
+ const int diff3 = SDIFF(p[i], grad_pred);
+ bins[WEBP_FILTER_NONE][diff0] = 1;
+ bins[WEBP_FILTER_HORIZONTAL][diff1] = 1;
+ bins[WEBP_FILTER_VERTICAL][diff2] = 1;
+ bins[WEBP_FILTER_GRADIENT][diff3] = 1;
+ mean = (3 * mean + p[i] + 2) >> 2;
+ }
+ }
+ {
+ int filter;
+ WEBP_FILTER_TYPE best_filter = WEBP_FILTER_NONE;
+ int best_score = 0x7fffffff;
+ for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) {
+ int score = 0;
+ for (i = 0; i < SMAX; ++i) {
+ if (bins[filter][i] > 0) {
+ score += i;
+ }
+ }
+ if (score < best_score) {
+ best_score = score;
+ best_filter = (WEBP_FILTER_TYPE)filter;
+ }
+ }
+ return best_filter;
+ }
+}
+
+#undef SMAX
+#undef SDIFF
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/utils/filters_utils.h b/media/libwebp/utils/filters_utils.h
new file mode 100644
index 000000000..088b132fc
--- /dev/null
+++ b/media/libwebp/utils/filters_utils.h
@@ -0,0 +1,32 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Spatial prediction using various filters
+//
+// Author: Urvang (urvang@google.com)
+
+#ifndef WEBP_UTILS_FILTERS_H_
+#define WEBP_UTILS_FILTERS_H_
+
+#include "../webp/types.h"
+#include "../dsp/dsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Fast estimate of a potentially good filter.
+WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t* data,
+ int width, int height, int stride);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_FILTERS_H_ */
diff --git a/media/libwebp/utils/huffman_encode_utils.h b/media/libwebp/utils/huffman_encode_utils.h
new file mode 100644
index 000000000..a15716514
--- /dev/null
+++ b/media/libwebp/utils/huffman_encode_utils.h
@@ -0,0 +1,60 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Author: Jyrki Alakuijala (jyrki@google.com)
+//
+// Entropy encoding (Huffman) for webp lossless
+
+#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
+#define WEBP_UTILS_HUFFMAN_ENCODE_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Struct for holding the tree header in coded form.
+typedef struct {
+ uint8_t code; // value (0..15) or escape code (16,17,18)
+ uint8_t extra_bits; // extra bits for escape codes
+} HuffmanTreeToken;
+
+// Struct to represent the tree codes (depth and bits array).
+typedef struct {
+ int num_symbols; // Number of symbols.
+ uint8_t* code_lengths; // Code lengths of the symbols.
+ uint16_t* codes; // Symbol Codes.
+} HuffmanTreeCode;
+
+// Struct to represent the Huffman tree.
+typedef struct {
+ uint32_t total_count_; // Symbol frequency.
+ int value_; // Symbol value.
+ int pool_index_left_; // Index for the left sub-tree.
+ int pool_index_right_; // Index for the right sub-tree.
+} HuffmanTree;
+
+// Turn the Huffman tree into a token sequence.
+// Returns the number of tokens used.
+int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
+ HuffmanTreeToken* tokens, int max_tokens);
+
+// Create an optimized tree, and tokenize it.
+// 'buf_rle' and 'huff_tree' are pre-allocated and the 'tree' is the constructed
+// huffman code tree.
+void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
+ uint8_t* const buf_rle, HuffmanTree* const huff_tree,
+ HuffmanTreeCode* const tree);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // WEBP_UTILS_HUFFMAN_ENCODE_H_
diff --git a/media/libwebp/utils/huffman_utils.c b/media/libwebp/utils/huffman_utils.c
new file mode 100644
index 000000000..008b5d746
--- /dev/null
+++ b/media/libwebp/utils/huffman_utils.c
@@ -0,0 +1,223 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for building and looking up Huffman trees.
+//
+// Author: Urvang Joshi (urvang@google.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "./huffman_utils.h"
+#include "./utils.h"
+#include "../webp/format_constants.h"
+
+// Huffman data read via DecodeImageStream is represented in two (red and green)
+// bytes.
+#define MAX_HTREE_GROUPS 0x10000
+
+HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups) {
+ HTreeGroup* const htree_groups =
+ (HTreeGroup*)WebPSafeMalloc(num_htree_groups, sizeof(*htree_groups));
+ if (htree_groups == NULL) {
+ return NULL;
+ }
+ assert(num_htree_groups <= MAX_HTREE_GROUPS);
+ return htree_groups;
+}
+
+void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups) {
+ if (htree_groups != NULL) {
+ WebPSafeFree(htree_groups);
+ }
+}
+
+// Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the
+// bit-wise reversal of the len least significant bits of key.
+static WEBP_INLINE uint32_t GetNextKey(uint32_t key, int len) {
+ uint32_t step = 1 << (len - 1);
+ while (key & step) {
+ step >>= 1;
+ }
+ return step ? (key & (step - 1)) + step : key;
+}
+
+// Stores code in table[0], table[step], table[2*step], ..., table[end].
+// Assumes that end is an integer multiple of step.
+static WEBP_INLINE void ReplicateValue(HuffmanCode* table,
+ int step, int end,
+ HuffmanCode code) {
+ assert(end % step == 0);
+ do {
+ end -= step;
+ table[end] = code;
+ } while (end > 0);
+}
+
+// Returns the table width of the next 2nd level table. count is the histogram
+// of bit lengths for the remaining symbols, len is the code length of the next
+// processed symbol
+static WEBP_INLINE int NextTableBitSize(const int* const count,
+ int len, int root_bits) {
+ int left = 1 << (len - root_bits);
+ while (len < MAX_ALLOWED_CODE_LENGTH) {
+ left -= count[len];
+ if (left <= 0) break;
+ ++len;
+ left <<= 1;
+ }
+ return len - root_bits;
+}
+
+// sorted[code_lengths_size] is a pre-allocated array for sorting symbols
+// by code length.
+static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size,
+ uint16_t sorted[]) {
+ HuffmanCode* table = root_table; // next available space in table
+ int total_size = 1 << root_bits; // total size root table + 2nd level table
+ int len; // current code length
+ int symbol; // symbol index in original or sorted table
+ // number of codes of each length:
+ int count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
+ // offsets in sorted table for each length:
+ int offset[MAX_ALLOWED_CODE_LENGTH + 1];
+
+ assert(code_lengths_size != 0);
+ assert(code_lengths != NULL);
+ assert(root_table != NULL);
+ assert(root_bits > 0);
+
+ // Build histogram of code lengths.
+ for (symbol = 0; symbol < code_lengths_size; ++symbol) {
+ if (code_lengths[symbol] > MAX_ALLOWED_CODE_LENGTH) {
+ return 0;
+ }
+ ++count[code_lengths[symbol]];
+ }
+
+ // Error, all code lengths are zeros.
+ if (count[0] == code_lengths_size) {
+ return 0;
+ }
+
+ // Generate offsets into sorted symbol table by code length.
+ offset[1] = 0;
+ for (len = 1; len < MAX_ALLOWED_CODE_LENGTH; ++len) {
+ if (count[len] > (1 << len)) {
+ return 0;
+ }
+ offset[len + 1] = offset[len] + count[len];
+ }
+
+ // Sort symbols by length, by symbol order within each length.
+ for (symbol = 0; symbol < code_lengths_size; ++symbol) {
+ const int symbol_code_length = code_lengths[symbol];
+ if (code_lengths[symbol] > 0) {
+ sorted[offset[symbol_code_length]++] = symbol;
+ }
+ }
+
+ // Special case code with only one value.
+ if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
+ HuffmanCode code;
+ code.bits = 0;
+ code.value = (uint16_t)sorted[0];
+ ReplicateValue(table, 1, total_size, code);
+ return total_size;
+ }
+
+ {
+ int step; // step size to replicate values in current table
+ uint32_t low = -1; // low bits for current root entry
+ uint32_t mask = total_size - 1; // mask for low bits
+ uint32_t key = 0; // reversed prefix code
+ int num_nodes = 1; // number of Huffman tree nodes
+ int num_open = 1; // number of open branches in current tree level
+ int table_bits = root_bits; // key length of current table
+ int table_size = 1 << table_bits; // size of current table
+ symbol = 0;
+ // Fill in root table.
+ for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) {
+ num_open <<= 1;
+ num_nodes += num_open;
+ num_open -= count[len];
+ if (num_open < 0) {
+ return 0;
+ }
+ for (; count[len] > 0; --count[len]) {
+ HuffmanCode code;
+ code.bits = (uint8_t)len;
+ code.value = (uint16_t)sorted[symbol++];
+ ReplicateValue(&table[key], step, table_size, code);
+ key = GetNextKey(key, len);
+ }
+ }
+
+ // Fill in 2nd level tables and add pointers to root table.
+ for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH;
+ ++len, step <<= 1) {
+ num_open <<= 1;
+ num_nodes += num_open;
+ num_open -= count[len];
+ if (num_open < 0) {
+ return 0;
+ }
+ for (; count[len] > 0; --count[len]) {
+ HuffmanCode code;
+ if ((key & mask) != low) {
+ table += table_size;
+ table_bits = NextTableBitSize(count, len, root_bits);
+ table_size = 1 << table_bits;
+ total_size += table_size;
+ low = key & mask;
+ root_table[low].bits = (uint8_t)(table_bits + root_bits);
+ root_table[low].value = (uint16_t)((table - root_table) - low);
+ }
+ code.bits = (uint8_t)(len - root_bits);
+ code.value = (uint16_t)sorted[symbol++];
+ ReplicateValue(&table[key >> root_bits], step, table_size, code);
+ key = GetNextKey(key, len);
+ }
+ }
+
+ // Check if tree is full.
+ if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) {
+ return 0;
+ }
+ }
+
+ return total_size;
+}
+
+// Maximum code_lengths_size is 2328 (reached for 11-bit color_cache_bits).
+// More commonly, the value is around ~280.
+#define MAX_CODE_LENGTHS_SIZE \
+ ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
+// Cut-off value for switching between heap and stack allocation.
+#define SORTED_SIZE_CUTOFF 512
+int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size) {
+ int total_size;
+ assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
+ if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+ // use local stack-allocated array.
+ uint16_t sorted[SORTED_SIZE_CUTOFF];
+ total_size = BuildHuffmanTable(root_table, root_bits,
+ code_lengths, code_lengths_size, sorted);
+ } else { // rare case. Use heap allocation.
+ uint16_t* const sorted =
+ (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
+ if (sorted == NULL) return 0;
+ total_size = BuildHuffmanTable(root_table, root_bits,
+ code_lengths, code_lengths_size, sorted);
+ WebPSafeFree(sorted);
+ }
+ return total_size;
+}
diff --git a/media/libwebp/utils/huffman_utils.h b/media/libwebp/utils/huffman_utils.h
new file mode 100644
index 000000000..c6dd6aaa4
--- /dev/null
+++ b/media/libwebp/utils/huffman_utils.h
@@ -0,0 +1,88 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Utilities for building and looking up Huffman trees.
+//
+// Author: Urvang Joshi (urvang@google.com)
+
+#ifndef WEBP_UTILS_HUFFMAN_H_
+#define WEBP_UTILS_HUFFMAN_H_
+
+#include <assert.h>
+#include "../webp/format_constants.h"
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HUFFMAN_TABLE_BITS 8
+#define HUFFMAN_TABLE_MASK ((1 << HUFFMAN_TABLE_BITS) - 1)
+
+#define LENGTHS_TABLE_BITS 7
+#define LENGTHS_TABLE_MASK ((1 << LENGTHS_TABLE_BITS) - 1)
+
+
+// Huffman lookup table entry
+typedef struct {
+ uint8_t bits; // number of bits used for this symbol
+ uint16_t value; // symbol value or table offset
+} HuffmanCode;
+
+// long version for holding 32b values
+typedef struct {
+ int bits; // number of bits used for this symbol,
+ // or an impossible value if not a literal code.
+ uint32_t value; // 32b packed ARGB value if literal,
+ // or non-literal symbol otherwise
+} HuffmanCode32;
+
+#define HUFFMAN_PACKED_BITS 6
+#define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
+
+// Huffman table group.
+// Includes special handling for the following cases:
+// - is_trivial_literal: one common literal base for RED/BLUE/ALPHA (not GREEN)
+// - is_trivial_code: only 1 code (no bit is read from bitstream)
+// - use_packed_table: few enough literal symbols, so all the bit codes
+// can fit into a small look-up table packed_table[]
+// The common literal base, if applicable, is stored in 'literal_arb'.
+typedef struct HTreeGroup HTreeGroup;
+struct HTreeGroup {
+ HuffmanCode* htrees[HUFFMAN_CODES_PER_META_CODE];
+ int is_trivial_literal; // True, if huffman trees for Red, Blue & Alpha
+ // Symbols are trivial (have a single code).
+ uint32_t literal_arb; // If is_trivial_literal is true, this is the
+ // ARGB value of the pixel, with Green channel
+ // being set to zero.
+ int is_trivial_code; // true if is_trivial_literal with only one code
+ int use_packed_table; // use packed table below for short literal code
+ // table mapping input bits to a packed values, or escape case to literal code
+ HuffmanCode32 packed_table[HUFFMAN_PACKED_TABLE_SIZE];
+};
+
+// Creates the instance of HTreeGroup with specified number of tree-groups.
+HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups);
+
+// Releases the memory allocated for HTreeGroup.
+void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
+
+// Builds Huffman lookup table assuming code lengths are in symbol order.
+// The 'code_lengths' is pre-allocated temporary memory buffer used for creating
+// the huffman table.
+// Returns built table size or 0 in case of error (invalid tree or
+// memory error).
+int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WEBP_UTILS_HUFFMAN_H_
diff --git a/media/libwebp/utils/moz.build b/media/libwebp/utils/moz.build
new file mode 100644
index 000000000..9fb274e9a
--- /dev/null
+++ b/media/libwebp/utils/moz.build
@@ -0,0 +1,26 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files('**'):
+ BUG_COMPONENT = ('Core', 'ImageLib')
+
+SOURCES += [
+ 'bit_reader_utils.c',
+ 'color_cache_utils.c',
+ 'filters_utils.c',
+ 'huffman_utils.c',
+ 'quant_levels_dec_utils.c',
+ 'quant_levels_utils.c',
+ 'random_utils.c',
+ 'rescaler_utils.c',
+ 'thread_utils.c',
+ 'utils.c',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
diff --git a/media/libwebp/utils/quant_levels_dec_utils.c b/media/libwebp/utils/quant_levels_dec_utils.c
new file mode 100644
index 000000000..d4d23d314
--- /dev/null
+++ b/media/libwebp/utils/quant_levels_dec_utils.c
@@ -0,0 +1,284 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Implement gradient smoothing: we replace a current alpha value by its
+// surrounding average if it's close enough (that is: the change will be less
+// than the minimum distance between two quantized level).
+// We use sliding window for computing the 2d moving average.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include "./quant_levels_dec_utils.h"
+
+#include <string.h> // for memset
+
+#include "./utils.h"
+
+// #define USE_DITHERING // uncomment to enable ordered dithering (not vital)
+
+#define FIX 16 // fix-point precision for averaging
+#define LFIX 2 // extra precision for look-up table
+#define LUT_SIZE ((1 << (8 + LFIX)) - 1) // look-up table size
+
+#if defined(USE_DITHERING)
+
+#define DFIX 4 // extra precision for ordered dithering
+#define DSIZE 4 // dithering size (must be a power of two)
+// cf. http://en.wikipedia.org/wiki/Ordered_dithering
+static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
+ { 0, 8, 2, 10 }, // coefficients are in DFIX fixed-point precision
+ { 12, 4, 14, 6 },
+ { 3, 11, 1, 9 },
+ { 15, 7, 13, 5 }
+};
+
+#else
+#define DFIX 0
+#endif
+
+typedef struct {
+ int width_, height_; // dimension
+ int stride_; // stride in bytes
+ int row_; // current input row being processed
+ uint8_t* src_; // input pointer
+ uint8_t* dst_; // output pointer
+
+ int radius_; // filter radius (=delay)
+ int scale_; // normalization factor, in FIX bits precision
+
+ void* mem_; // all memory
+
+ // various scratch buffers
+ uint16_t* start_;
+ uint16_t* cur_;
+ uint16_t* end_;
+ uint16_t* top_;
+ uint16_t* average_;
+
+ // input levels distribution
+ int num_levels_; // number of quantized levels
+ int min_, max_; // min and max level values
+ int min_level_dist_; // smallest distance between two consecutive levels
+
+ int16_t* correction_; // size = 1 + 2*LUT_SIZE -> ~4k memory
+} SmoothParams;
+
+//------------------------------------------------------------------------------
+
+#define CLIP_MASK (int)(~0U << (8 + DFIX))
+static WEBP_INLINE uint8_t clip_8b(int v) {
+ return (!(v & CLIP_MASK)) ? (uint8_t)(v >> DFIX) : (v < 0) ? 0u : 255u;
+}
+
+// vertical accumulation
+static void VFilter(SmoothParams* const p) {
+ const uint8_t* src = p->src_;
+ const int w = p->width_;
+ uint16_t* const cur = p->cur_;
+ const uint16_t* const top = p->top_;
+ uint16_t* const out = p->end_;
+ uint16_t sum = 0; // all arithmetic is modulo 16bit
+ int x;
+
+ for (x = 0; x < w; ++x) {
+ uint16_t new_value;
+ sum += src[x];
+ new_value = top[x] + sum;
+ out[x] = new_value - cur[x]; // vertical sum of 'r' pixels.
+ cur[x] = new_value;
+ }
+ // move input pointers one row down
+ p->top_ = p->cur_;
+ p->cur_ += w;
+ if (p->cur_ == p->end_) p->cur_ = p->start_; // roll-over
+ // We replicate edges, as it's somewhat easier as a boundary condition.
+ // That's why we don't update the 'src' pointer on top/bottom area:
+ if (p->row_ >= 0 && p->row_ < p->height_ - 1) {
+ p->src_ += p->stride_;
+ }
+}
+
+// horizontal accumulation. We use mirror replication of missing pixels, as it's
+// a little easier to implement (surprisingly).
+static void HFilter(SmoothParams* const p) {
+ const uint16_t* const in = p->end_;
+ uint16_t* const out = p->average_;
+ const uint32_t scale = p->scale_;
+ const int w = p->width_;
+ const int r = p->radius_;
+
+ int x;
+ for (x = 0; x <= r; ++x) { // left mirroring
+ const uint16_t delta = in[x + r - 1] + in[r - x];
+ out[x] = (delta * scale) >> FIX;
+ }
+ for (; x < w - r; ++x) { // bulk middle run
+ const uint16_t delta = in[x + r] - in[x - r - 1];
+ out[x] = (delta * scale) >> FIX;
+ }
+ for (; x < w; ++x) { // right mirroring
+ const uint16_t delta =
+ 2 * in[w - 1] - in[2 * w - 2 - r - x] - in[x - r - 1];
+ out[x] = (delta * scale) >> FIX;
+ }
+}
+
+// emit one filtered output row
+static void ApplyFilter(SmoothParams* const p) {
+ const uint16_t* const average = p->average_;
+ const int w = p->width_;
+ const int16_t* const correction = p->correction_;
+#if defined(USE_DITHERING)
+ const uint8_t* const dither = kOrderedDither[p->row_ % DSIZE];
+#endif
+ uint8_t* const dst = p->dst_;
+ int x;
+ for (x = 0; x < w; ++x) {
+ const int v = dst[x];
+ if (v < p->max_ && v > p->min_) {
+ const int c = (v << DFIX) + correction[average[x] - (v << LFIX)];
+#if defined(USE_DITHERING)
+ dst[x] = clip_8b(c + dither[x % DSIZE]);
+#else
+ dst[x] = clip_8b(c);
+#endif
+ }
+ }
+ p->dst_ += p->stride_; // advance output pointer
+}
+
+//------------------------------------------------------------------------------
+// Initialize correction table
+
+static void InitCorrectionLUT(int16_t* const lut, int min_dist) {
+ // The correction curve is:
+ // f(x) = x for x <= threshold2
+ // f(x) = 0 for x >= threshold1
+ // and a linear interpolation for range x=[threshold2, threshold1]
+ // (along with f(-x) = -f(x) symmetry).
+ // Note that: threshold2 = 3/4 * threshold1
+ const int threshold1 = min_dist << LFIX;
+ const int threshold2 = (3 * threshold1) >> 2;
+ const int max_threshold = threshold2 << DFIX;
+ const int delta = threshold1 - threshold2;
+ int i;
+ for (i = 1; i <= LUT_SIZE; ++i) {
+ int c = (i <= threshold2) ? (i << DFIX)
+ : (i < threshold1) ? max_threshold * (threshold1 - i) / delta
+ : 0;
+ c >>= LFIX;
+ lut[+i] = +c;
+ lut[-i] = -c;
+ }
+ lut[0] = 0;
+}
+
+static void CountLevels(SmoothParams* const p) {
+ int i, j, last_level;
+ uint8_t used_levels[256] = { 0 };
+ const uint8_t* data = p->src_;
+ p->min_ = 255;
+ p->max_ = 0;
+ for (j = 0; j < p->height_; ++j) {
+ for (i = 0; i < p->width_; ++i) {
+ const int v = data[i];
+ if (v < p->min_) p->min_ = v;
+ if (v > p->max_) p->max_ = v;
+ used_levels[v] = 1;
+ }
+ data += p->stride_;
+ }
+ // Compute the mininum distance between two non-zero levels.
+ p->min_level_dist_ = p->max_ - p->min_;
+ last_level = -1;
+ for (i = 0; i < 256; ++i) {
+ if (used_levels[i]) {
+ ++p->num_levels_;
+ if (last_level >= 0) {
+ const int level_dist = i - last_level;
+ if (level_dist < p->min_level_dist_) {
+ p->min_level_dist_ = level_dist;
+ }
+ }
+ last_level = i;
+ }
+ }
+}
+
+// Initialize all params.
+static int InitParams(uint8_t* const data, int width, int height, int stride,
+ int radius, SmoothParams* const p) {
+ const int R = 2 * radius + 1; // total size of the kernel
+
+ const size_t size_scratch_m = (R + 1) * width * sizeof(*p->start_);
+ const size_t size_m = width * sizeof(*p->average_);
+ const size_t size_lut = (1 + 2 * LUT_SIZE) * sizeof(*p->correction_);
+ const size_t total_size = size_scratch_m + size_m + size_lut;
+ uint8_t* mem = (uint8_t*)WebPSafeMalloc(1U, total_size);
+
+ if (mem == NULL) return 0;
+ p->mem_ = (void*)mem;
+
+ p->start_ = (uint16_t*)mem;
+ p->cur_ = p->start_;
+ p->end_ = p->start_ + R * width;
+ p->top_ = p->end_ - width;
+ memset(p->top_, 0, width * sizeof(*p->top_));
+ mem += size_scratch_m;
+
+ p->average_ = (uint16_t*)mem;
+ mem += size_m;
+
+ p->width_ = width;
+ p->height_ = height;
+ p->stride_ = stride;
+ p->src_ = data;
+ p->dst_ = data;
+ p->radius_ = radius;
+ p->scale_ = (1 << (FIX + LFIX)) / (R * R); // normalization constant
+ p->row_ = -radius;
+
+ // analyze the input distribution so we can best-fit the threshold
+ CountLevels(p);
+
+ // correction table
+ p->correction_ = ((int16_t*)mem) + LUT_SIZE;
+ InitCorrectionLUT(p->correction_, p->min_level_dist_);
+
+ return 1;
+}
+
+static void CleanupParams(SmoothParams* const p) {
+ WebPSafeFree(p->mem_);
+}
+
+int WebPDequantizeLevels(uint8_t* const data, int width, int height, int stride,
+ int strength) {
+ const int radius = 4 * strength / 100;
+ if (strength < 0 || strength > 100) return 0;
+ if (data == NULL || width <= 0 || height <= 0) return 0; // bad params
+ if (radius > 0) {
+ SmoothParams p;
+ memset(&p, 0, sizeof(p));
+ if (!InitParams(data, width, height, stride, radius, &p)) return 0;
+ if (p.num_levels_ > 2) {
+ for (; p.row_ < p.height_; ++p.row_) {
+ VFilter(&p); // accumulate average of input
+ // Need to wait few rows in order to prime the filter,
+ // before emitting some output.
+ if (p.row_ >= p.radius_) {
+ HFilter(&p);
+ ApplyFilter(&p);
+ }
+ }
+ }
+ CleanupParams(&p);
+ }
+ return 1;
+}
diff --git a/media/libwebp/utils/quant_levels_dec_utils.h b/media/libwebp/utils/quant_levels_dec_utils.h
new file mode 100644
index 000000000..59a13495d
--- /dev/null
+++ b/media/libwebp/utils/quant_levels_dec_utils.h
@@ -0,0 +1,35 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha plane de-quantization utility
+//
+// Author: Vikas Arora (vikasa@google.com)
+
+#ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_
+#define WEBP_UTILS_QUANT_LEVELS_DEC_H_
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Apply post-processing to input 'data' of size 'width'x'height' assuming that
+// the source was quantized to a reduced number of levels. 'stride' is in bytes.
+// Strength is in [0..100] and controls the amount of dithering applied.
+// Returns false in case of error (data is NULL, invalid parameters,
+// malloc failure, ...).
+int WebPDequantizeLevels(uint8_t* const data, int width, int height, int stride,
+ int strength);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_QUANT_LEVELS_DEC_H_ */
diff --git a/media/libwebp/utils/quant_levels_utils.c b/media/libwebp/utils/quant_levels_utils.c
new file mode 100644
index 000000000..73174e8ab
--- /dev/null
+++ b/media/libwebp/utils/quant_levels_utils.c
@@ -0,0 +1,140 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Quantize levels for specified number of quantization-levels ([2, 256]).
+// Min and max values are preserved (usual 0 and 255 for alpha plane).
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <assert.h>
+
+#include "./quant_levels_utils.h"
+
+#define NUM_SYMBOLS 256
+
+#define MAX_ITER 6 // Maximum number of convergence steps.
+#define ERROR_THRESHOLD 1e-4 // MSE stopping criterion.
+
+// -----------------------------------------------------------------------------
+// Quantize levels.
+
+int QuantizeLevels(uint8_t* const data, int width, int height,
+ int num_levels, uint64_t* const sse) {
+ int freq[NUM_SYMBOLS] = { 0 };
+ int q_level[NUM_SYMBOLS] = { 0 };
+ double inv_q_level[NUM_SYMBOLS] = { 0 };
+ int min_s = 255, max_s = 0;
+ const size_t data_size = height * width;
+ int i, num_levels_in, iter;
+ double last_err = 1.e38, err = 0.;
+ const double err_threshold = ERROR_THRESHOLD * data_size;
+
+ if (data == NULL) {
+ return 0;
+ }
+
+ if (width <= 0 || height <= 0) {
+ return 0;
+ }
+
+ if (num_levels < 2 || num_levels > 256) {
+ return 0;
+ }
+
+ {
+ size_t n;
+ num_levels_in = 0;
+ for (n = 0; n < data_size; ++n) {
+ num_levels_in += (freq[data[n]] == 0);
+ if (min_s > data[n]) min_s = data[n];
+ if (max_s < data[n]) max_s = data[n];
+ ++freq[data[n]];
+ }
+ }
+
+ if (num_levels_in <= num_levels) goto End; // nothing to do!
+
+ // Start with uniformly spread centroids.
+ for (i = 0; i < num_levels; ++i) {
+ inv_q_level[i] = min_s + (double)(max_s - min_s) * i / (num_levels - 1);
+ }
+
+ // Fixed values. Won't be changed.
+ q_level[min_s] = 0;
+ q_level[max_s] = num_levels - 1;
+ assert(inv_q_level[0] == min_s);
+ assert(inv_q_level[num_levels - 1] == max_s);
+
+ // k-Means iterations.
+ for (iter = 0; iter < MAX_ITER; ++iter) {
+ double q_sum[NUM_SYMBOLS] = { 0 };
+ double q_count[NUM_SYMBOLS] = { 0 };
+ int s, slot = 0;
+
+ // Assign classes to representatives.
+ for (s = min_s; s <= max_s; ++s) {
+ // Keep track of the nearest neighbour 'slot'
+ while (slot < num_levels - 1 &&
+ 2 * s > inv_q_level[slot] + inv_q_level[slot + 1]) {
+ ++slot;
+ }
+ if (freq[s] > 0) {
+ q_sum[slot] += s * freq[s];
+ q_count[slot] += freq[s];
+ }
+ q_level[s] = slot;
+ }
+
+ // Assign new representatives to classes.
+ if (num_levels > 2) {
+ for (slot = 1; slot < num_levels - 1; ++slot) {
+ const double count = q_count[slot];
+ if (count > 0.) {
+ inv_q_level[slot] = q_sum[slot] / count;
+ }
+ }
+ }
+
+ // Compute convergence error.
+ err = 0.;
+ for (s = min_s; s <= max_s; ++s) {
+ const double error = s - inv_q_level[q_level[s]];
+ err += freq[s] * error * error;
+ }
+
+ // Check for convergence: we stop as soon as the error is no
+ // longer improving.
+ if (last_err - err < err_threshold) break;
+ last_err = err;
+ }
+
+ // Remap the alpha plane to quantized values.
+ {
+ // double->int rounding operation can be costly, so we do it
+ // once for all before remapping. We also perform the data[] -> slot
+ // mapping, while at it (avoid one indirection in the final loop).
+ uint8_t map[NUM_SYMBOLS];
+ int s;
+ size_t n;
+ for (s = min_s; s <= max_s; ++s) {
+ const int slot = q_level[s];
+ map[s] = (uint8_t)(inv_q_level[slot] + .5);
+ }
+ // Final pass.
+ for (n = 0; n < data_size; ++n) {
+ data[n] = map[data[n]];
+ }
+ }
+ End:
+ // Store sum of squared error if needed.
+ if (sse != NULL) *sse = (uint64_t)err;
+
+ return 1;
+}
+
diff --git a/media/libwebp/utils/quant_levels_utils.h b/media/libwebp/utils/quant_levels_utils.h
new file mode 100644
index 000000000..1cb5a32ca
--- /dev/null
+++ b/media/libwebp/utils/quant_levels_utils.h
@@ -0,0 +1,36 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Alpha plane quantization utility
+//
+// Author: Vikas Arora (vikasa@google.com)
+
+#ifndef WEBP_UTILS_QUANT_LEVELS_H_
+#define WEBP_UTILS_QUANT_LEVELS_H_
+
+#include <stdlib.h>
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Replace the input 'data' of size 'width'x'height' with 'num-levels'
+// quantized values. If not NULL, 'sse' will contain the sum of squared error.
+// Valid range for 'num_levels' is [2, 256].
+// Returns false in case of error (data is NULL, or parameters are invalid).
+int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels,
+ uint64_t* const sse);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_QUANT_LEVELS_H_ */
diff --git a/media/libwebp/utils/random_utils.c b/media/libwebp/utils/random_utils.c
new file mode 100644
index 000000000..9f1e4154a
--- /dev/null
+++ b/media/libwebp/utils/random_utils.c
@@ -0,0 +1,43 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Pseudo-random utilities
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <string.h>
+#include "./random_utils.h"
+
+//------------------------------------------------------------------------------
+
+// 31b-range values
+static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = {
+ 0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828,
+ 0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da,
+ 0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f,
+ 0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2,
+ 0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c,
+ 0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd,
+ 0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3,
+ 0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b,
+ 0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494,
+ 0x27e5ed3c
+};
+
+void VP8InitRandom(VP8Random* const rg, float dithering) {
+ memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_));
+ rg->index1_ = 0;
+ rg->index2_ = 31;
+ rg->amp_ = (dithering < 0.0) ? 0
+ : (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX)
+ : (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering);
+}
+
+//------------------------------------------------------------------------------
+
diff --git a/media/libwebp/utils/random_utils.h b/media/libwebp/utils/random_utils.h
new file mode 100644
index 000000000..c392a615c
--- /dev/null
+++ b/media/libwebp/utils/random_utils.h
@@ -0,0 +1,63 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Pseudo-random utilities
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_UTILS_RANDOM_H_
+#define WEBP_UTILS_RANDOM_H_
+
+#include <assert.h>
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VP8_RANDOM_DITHER_FIX 8 // fixed-point precision for dithering
+#define VP8_RANDOM_TABLE_SIZE 55
+
+typedef struct {
+ int index1_, index2_;
+ uint32_t tab_[VP8_RANDOM_TABLE_SIZE];
+ int amp_;
+} VP8Random;
+
+// Initializes random generator with an amplitude 'dithering' in range [0..1].
+void VP8InitRandom(VP8Random* const rg, float dithering);
+
+// Returns a centered pseudo-random number with 'num_bits' amplitude.
+// (uses D.Knuth's Difference-based random generator).
+// 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision.
+static WEBP_INLINE int VP8RandomBits2(VP8Random* const rg, int num_bits,
+ int amp) {
+ int diff;
+ assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31);
+ diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_];
+ if (diff < 0) diff += (1u << 31);
+ rg->tab_[rg->index1_] = diff;
+ if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0;
+ if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0;
+ // sign-extend, 0-center
+ diff = (int)((uint32_t)diff << 1) >> (32 - num_bits);
+ diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX; // restrict range
+ diff += 1 << (num_bits - 1); // shift back to 0.5-center
+ return diff;
+}
+
+static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) {
+ return VP8RandomBits2(rg, num_bits, rg->amp_);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_RANDOM_H_ */
diff --git a/media/libwebp/utils/rescaler_utils.c b/media/libwebp/utils/rescaler_utils.c
new file mode 100644
index 000000000..0d1f80da2
--- /dev/null
+++ b/media/libwebp/utils/rescaler_utils.c
@@ -0,0 +1,146 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Rescaling functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../dsp/dsp.h"
+#include "./rescaler_utils.h"
+
+//------------------------------------------------------------------------------
+
+void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height,
+ uint8_t* const dst,
+ int dst_width, int dst_height, int dst_stride,
+ int num_channels, rescaler_t* const work) {
+ const int x_add = src_width, x_sub = dst_width;
+ const int y_add = src_height, y_sub = dst_height;
+ wrk->x_expand = (src_width < dst_width);
+ wrk->y_expand = (src_height < dst_height);
+ wrk->src_width = src_width;
+ wrk->src_height = src_height;
+ wrk->dst_width = dst_width;
+ wrk->dst_height = dst_height;
+ wrk->src_y = 0;
+ wrk->dst_y = 0;
+ wrk->dst = dst;
+ wrk->dst_stride = dst_stride;
+ wrk->num_channels = num_channels;
+
+ // for 'x_expand', we use bilinear interpolation
+ wrk->x_add = wrk->x_expand ? (x_sub - 1) : x_add;
+ wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub;
+ if (!wrk->x_expand) { // fx_scale is not used otherwise
+ wrk->fx_scale = WEBP_RESCALER_FRAC(1, wrk->x_sub);
+ }
+ // vertical scaling parameters
+ wrk->y_add = wrk->y_expand ? y_add - 1 : y_add;
+ wrk->y_sub = wrk->y_expand ? y_sub - 1 : y_sub;
+ wrk->y_accum = wrk->y_expand ? wrk->y_sub : wrk->y_add;
+ if (!wrk->y_expand) {
+ // This is WEBP_RESCALER_FRAC(dst_height, x_add * y_add) without the cast.
+ // Its value is <= WEBP_RESCALER_ONE, because dst_height <= wrk->y_add, and
+ // wrk->x_add >= 1;
+ const uint64_t ratio =
+ (uint64_t)dst_height * WEBP_RESCALER_ONE / (wrk->x_add * wrk->y_add);
+ if (ratio != (uint32_t)ratio) {
+ // When ratio == WEBP_RESCALER_ONE, we can't represent the ratio with the
+ // current fixed-point precision. This happens when src_height ==
+ // wrk->y_add (which == src_height), and wrk->x_add == 1.
+ // => We special-case fxy_scale = 0, in WebPRescalerExportRow().
+ wrk->fxy_scale = 0;
+ } else {
+ wrk->fxy_scale = (uint32_t)ratio;
+ }
+ wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->y_sub);
+ } else {
+ wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->x_add);
+ // wrk->fxy_scale is unused here.
+ }
+ wrk->irow = work;
+ wrk->frow = work + num_channels * dst_width;
+ memset(work, 0, 2 * dst_width * num_channels * sizeof(*work));
+
+ WebPRescalerDspInit();
+}
+
+int WebPRescalerGetScaledDimensions(int src_width, int src_height,
+ int* const scaled_width,
+ int* const scaled_height) {
+ assert(scaled_width != NULL);
+ assert(scaled_height != NULL);
+ {
+ int width = *scaled_width;
+ int height = *scaled_height;
+
+ // if width is unspecified, scale original proportionally to height ratio.
+ if (width == 0) {
+ width = (src_width * height + src_height / 2) / src_height;
+ }
+ // if height is unspecified, scale original proportionally to width ratio.
+ if (height == 0) {
+ height = (src_height * width + src_width / 2) / src_width;
+ }
+ // Check if the overall dimensions still make sense.
+ if (width <= 0 || height <= 0) {
+ return 0;
+ }
+
+ *scaled_width = width;
+ *scaled_height = height;
+ return 1;
+ }
+}
+
+//------------------------------------------------------------------------------
+// all-in-one calls
+
+int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) {
+ const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub;
+ return (num_lines > max_num_lines) ? max_num_lines : num_lines;
+}
+
+int WebPRescalerImport(WebPRescaler* const wrk, int num_lines,
+ const uint8_t* src, int src_stride) {
+ int total_imported = 0;
+ while (total_imported < num_lines && !WebPRescalerHasPendingOutput(wrk)) {
+ if (wrk->y_expand) {
+ rescaler_t* const tmp = wrk->irow;
+ wrk->irow = wrk->frow;
+ wrk->frow = tmp;
+ }
+ WebPRescalerImportRow(wrk, src);
+ if (!wrk->y_expand) { // Accumulate the contribution of the new row.
+ int x;
+ for (x = 0; x < wrk->num_channels * wrk->dst_width; ++x) {
+ wrk->irow[x] += wrk->frow[x];
+ }
+ }
+ ++wrk->src_y;
+ src += src_stride;
+ ++total_imported;
+ wrk->y_accum -= wrk->y_sub;
+ }
+ return total_imported;
+}
+
+int WebPRescalerExport(WebPRescaler* const rescaler) {
+ int total_exported = 0;
+ while (WebPRescalerHasPendingOutput(rescaler)) {
+ WebPRescalerExportRow(rescaler);
+ ++total_exported;
+ }
+ return total_exported;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/utils/rescaler_utils.h b/media/libwebp/utils/rescaler_utils.h
new file mode 100644
index 000000000..98b01a76d
--- /dev/null
+++ b/media/libwebp/utils/rescaler_utils.h
@@ -0,0 +1,101 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Rescaling functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_UTILS_RESCALER_H_
+#define WEBP_UTILS_RESCALER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../webp/types.h"
+
+#define WEBP_RESCALER_RFIX 32 // fixed-point precision for multiplies
+#define WEBP_RESCALER_ONE (1ull << WEBP_RESCALER_RFIX)
+#define WEBP_RESCALER_FRAC(x, y) \
+ ((uint32_t)(((uint64_t)(x) << WEBP_RESCALER_RFIX) / (y)))
+
+// Structure used for on-the-fly rescaling
+typedef uint32_t rescaler_t; // type for side-buffer
+typedef struct WebPRescaler WebPRescaler;
+struct WebPRescaler {
+ int x_expand; // true if we're expanding in the x direction
+ int y_expand; // true if we're expanding in the y direction
+ int num_channels; // bytes to jump between pixels
+ uint32_t fx_scale; // fixed-point scaling factors
+ uint32_t fy_scale; // ''
+ uint32_t fxy_scale; // ''
+ int y_accum; // vertical accumulator
+ int y_add, y_sub; // vertical increments
+ int x_add, x_sub; // horizontal increments
+ int src_width, src_height; // source dimensions
+ int dst_width, dst_height; // destination dimensions
+ int src_y, dst_y; // row counters for input and output
+ uint8_t* dst;
+ int dst_stride;
+ rescaler_t* irow, *frow; // work buffer
+};
+
+// Initialize a rescaler given scratch area 'work' and dimensions of src & dst.
+void WebPRescalerInit(WebPRescaler* const rescaler,
+ int src_width, int src_height,
+ uint8_t* const dst,
+ int dst_width, int dst_height, int dst_stride,
+ int num_channels,
+ rescaler_t* const work);
+
+// If either 'scaled_width' or 'scaled_height' (but not both) is 0 the value
+// will be calculated preserving the aspect ratio, otherwise the values are
+// left unmodified. Returns true on success, false if either value is 0 after
+// performing the scaling calculation.
+int WebPRescalerGetScaledDimensions(int src_width, int src_height,
+ int* const scaled_width,
+ int* const scaled_height);
+
+// Returns the number of input lines needed next to produce one output line,
+// considering that the maximum available input lines are 'max_num_lines'.
+int WebPRescaleNeededLines(const WebPRescaler* const rescaler,
+ int max_num_lines);
+
+// Import multiple rows over all channels, until at least one row is ready to
+// be exported. Returns the actual number of lines that were imported.
+int WebPRescalerImport(WebPRescaler* const rescaler, int num_rows,
+ const uint8_t* src, int src_stride);
+
+// Export as many rows as possible. Return the numbers of rows written.
+int WebPRescalerExport(WebPRescaler* const rescaler);
+
+// Return true if input is finished
+static WEBP_INLINE
+int WebPRescalerInputDone(const WebPRescaler* const rescaler) {
+ return (rescaler->src_y >= rescaler->src_height);
+}
+// Return true if output is finished
+static WEBP_INLINE
+int WebPRescalerOutputDone(const WebPRescaler* const rescaler) {
+ return (rescaler->dst_y >= rescaler->dst_height);
+}
+
+// Return true if there are pending output rows ready.
+static WEBP_INLINE
+int WebPRescalerHasPendingOutput(const WebPRescaler* const rescaler) {
+ return !WebPRescalerOutputDone(rescaler) && (rescaler->y_accum <= 0);
+}
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_RESCALER_H_ */
diff --git a/media/libwebp/utils/thread_utils.c b/media/libwebp/utils/thread_utils.c
new file mode 100644
index 000000000..1729060c7
--- /dev/null
+++ b/media/libwebp/utils/thread_utils.c
@@ -0,0 +1,356 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Multi-threaded worker
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <assert.h>
+#include <string.h> // for memset()
+#include "./thread_utils.h"
+#include "./utils.h"
+
+#ifdef WEBP_USE_THREAD
+
+#if defined(_WIN32)
+
+#include <windows.h>
+typedef HANDLE pthread_t;
+typedef CRITICAL_SECTION pthread_mutex_t;
+
+#if _WIN32_WINNT >= 0x0600 // Windows Vista / Server 2008 or greater
+#define USE_WINDOWS_CONDITION_VARIABLE
+typedef CONDITION_VARIABLE pthread_cond_t;
+#else
+typedef struct {
+ HANDLE waiting_sem_;
+ HANDLE received_sem_;
+ HANDLE signal_event_;
+} pthread_cond_t;
+#endif // _WIN32_WINNT >= 0x600
+
+#ifndef WINAPI_FAMILY_PARTITION
+#define WINAPI_PARTITION_DESKTOP 1
+#define WINAPI_FAMILY_PARTITION(x) x
+#endif
+
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#define USE_CREATE_THREAD
+#endif
+
+#else // !_WIN32
+
+#include <pthread.h>
+
+#endif // _WIN32
+
+struct WebPWorkerImpl {
+ pthread_mutex_t mutex_;
+ pthread_cond_t condition_;
+ pthread_t thread_;
+};
+
+#if defined(_WIN32)
+
+//------------------------------------------------------------------------------
+// simplistic pthread emulation layer
+
+#include <process.h>
+
+// _beginthreadex requires __stdcall
+#define THREADFN unsigned int __stdcall
+#define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val)
+
+#if _WIN32_WINNT >= 0x0501 // Windows XP or greater
+#define WaitForSingleObject(obj, timeout) \
+ WaitForSingleObjectEx(obj, timeout, FALSE /*bAlertable*/)
+#endif
+
+static int pthread_create(pthread_t* const thread, const void* attr,
+ unsigned int (__stdcall *start)(void*), void* arg) {
+ (void)attr;
+#ifdef USE_CREATE_THREAD
+ *thread = CreateThread(NULL, /* lpThreadAttributes */
+ 0, /* dwStackSize */
+ start,
+ arg,
+ 0, /* dwStackSize */
+ NULL); /* lpThreadId */
+#else
+ *thread = (pthread_t)_beginthreadex(NULL, /* void *security */
+ 0, /* unsigned stack_size */
+ start,
+ arg,
+ 0, /* unsigned initflag */
+ NULL); /* unsigned *thrdaddr */
+#endif
+ if (*thread == NULL) return 1;
+ SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL);
+ return 0;
+}
+
+static int pthread_join(pthread_t thread, void** value_ptr) {
+ (void)value_ptr;
+ return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 ||
+ CloseHandle(thread) == 0);
+}
+
+// Mutex
+static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) {
+ (void)mutexattr;
+#if _WIN32_WINNT >= 0x0600 // Windows Vista / Server 2008 or greater
+ InitializeCriticalSectionEx(mutex, 0 /*dwSpinCount*/, 0 /*Flags*/);
+#else
+ InitializeCriticalSection(mutex);
+#endif
+ return 0;
+}
+
+static int pthread_mutex_lock(pthread_mutex_t* const mutex) {
+ EnterCriticalSection(mutex);
+ return 0;
+}
+
+static int pthread_mutex_unlock(pthread_mutex_t* const mutex) {
+ LeaveCriticalSection(mutex);
+ return 0;
+}
+
+static int pthread_mutex_destroy(pthread_mutex_t* const mutex) {
+ DeleteCriticalSection(mutex);
+ return 0;
+}
+
+// Condition
+static int pthread_cond_destroy(pthread_cond_t* const condition) {
+ int ok = 1;
+#ifdef USE_WINDOWS_CONDITION_VARIABLE
+ (void)condition;
+#else
+ ok &= (CloseHandle(condition->waiting_sem_) != 0);
+ ok &= (CloseHandle(condition->received_sem_) != 0);
+ ok &= (CloseHandle(condition->signal_event_) != 0);
+#endif
+ return !ok;
+}
+
+static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) {
+ (void)cond_attr;
+#ifdef USE_WINDOWS_CONDITION_VARIABLE
+ InitializeConditionVariable(condition);
+#else
+ condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
+ condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
+ condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (condition->waiting_sem_ == NULL ||
+ condition->received_sem_ == NULL ||
+ condition->signal_event_ == NULL) {
+ pthread_cond_destroy(condition);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+static int pthread_cond_signal(pthread_cond_t* const condition) {
+ int ok = 1;
+#ifdef USE_WINDOWS_CONDITION_VARIABLE
+ WakeConditionVariable(condition);
+#else
+ if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) {
+ // a thread is waiting in pthread_cond_wait: allow it to be notified
+ ok = SetEvent(condition->signal_event_);
+ // wait until the event is consumed so the signaler cannot consume
+ // the event via its own pthread_cond_wait.
+ ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) !=
+ WAIT_OBJECT_0);
+ }
+#endif
+ return !ok;
+}
+
+static int pthread_cond_wait(pthread_cond_t* const condition,
+ pthread_mutex_t* const mutex) {
+ int ok;
+#ifdef USE_WINDOWS_CONDITION_VARIABLE
+ ok = SleepConditionVariableCS(condition, mutex, INFINITE);
+#else
+ // note that there is a consumer available so the signal isn't dropped in
+ // pthread_cond_signal
+ if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) return 1;
+ // now unlock the mutex so pthread_cond_signal may be issued
+ pthread_mutex_unlock(mutex);
+ ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
+ WAIT_OBJECT_0);
+ ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
+ pthread_mutex_lock(mutex);
+#endif
+ return !ok;
+}
+
+#else // !_WIN32
+# define THREADFN void*
+# define THREAD_RETURN(val) val
+#endif // _WIN32
+
+//------------------------------------------------------------------------------
+
+static void Execute(WebPWorker* const worker); // Forward declaration.
+
+static THREADFN ThreadLoop(void* ptr) {
+ WebPWorker* const worker = (WebPWorker*)ptr;
+ int done = 0;
+ while (!done) {
+ pthread_mutex_lock(&worker->impl_->mutex_);
+ while (worker->status_ == OK) { // wait in idling mode
+ pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
+ }
+ if (worker->status_ == WORK) {
+ Execute(worker);
+ worker->status_ = OK;
+ } else if (worker->status_ == NOT_OK) { // finish the worker
+ done = 1;
+ }
+ // signal to the main thread that we're done (for Sync())
+ pthread_cond_signal(&worker->impl_->condition_);
+ pthread_mutex_unlock(&worker->impl_->mutex_);
+ }
+ return THREAD_RETURN(NULL); // Thread is finished
+}
+
+// main thread state control
+static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) {
+ // No-op when attempting to change state on a thread that didn't come up.
+ // Checking status_ without acquiring the lock first would result in a data
+ // race.
+ if (worker->impl_ == NULL) return;
+
+ pthread_mutex_lock(&worker->impl_->mutex_);
+ if (worker->status_ >= OK) {
+ // wait for the worker to finish
+ while (worker->status_ != OK) {
+ pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
+ }
+ // assign new status and release the working thread if needed
+ if (new_status != OK) {
+ worker->status_ = new_status;
+ pthread_cond_signal(&worker->impl_->condition_);
+ }
+ }
+ pthread_mutex_unlock(&worker->impl_->mutex_);
+}
+
+#endif // WEBP_USE_THREAD
+
+//------------------------------------------------------------------------------
+
+static void Init(WebPWorker* const worker) {
+ memset(worker, 0, sizeof(*worker));
+ worker->status_ = NOT_OK;
+}
+
+static int Sync(WebPWorker* const worker) {
+#ifdef WEBP_USE_THREAD
+ ChangeState(worker, OK);
+#endif
+ assert(worker->status_ <= OK);
+ return !worker->had_error;
+}
+
+static int Reset(WebPWorker* const worker) {
+ int ok = 1;
+ worker->had_error = 0;
+ if (worker->status_ < OK) {
+#ifdef WEBP_USE_THREAD
+ worker->impl_ = (WebPWorkerImpl*)WebPSafeCalloc(1, sizeof(*worker->impl_));
+ if (worker->impl_ == NULL) {
+ return 0;
+ }
+ if (pthread_mutex_init(&worker->impl_->mutex_, NULL)) {
+ goto Error;
+ }
+ if (pthread_cond_init(&worker->impl_->condition_, NULL)) {
+ pthread_mutex_destroy(&worker->impl_->mutex_);
+ goto Error;
+ }
+ pthread_mutex_lock(&worker->impl_->mutex_);
+ ok = !pthread_create(&worker->impl_->thread_, NULL, ThreadLoop, worker);
+ if (ok) worker->status_ = OK;
+ pthread_mutex_unlock(&worker->impl_->mutex_);
+ if (!ok) {
+ pthread_mutex_destroy(&worker->impl_->mutex_);
+ pthread_cond_destroy(&worker->impl_->condition_);
+ Error:
+ WebPSafeFree(worker->impl_);
+ worker->impl_ = NULL;
+ return 0;
+ }
+#else
+ worker->status_ = OK;
+#endif
+ } else if (worker->status_ > OK) {
+ ok = Sync(worker);
+ }
+ assert(!ok || (worker->status_ == OK));
+ return ok;
+}
+
+static void Execute(WebPWorker* const worker) {
+ if (worker->hook != NULL) {
+ worker->had_error |= !worker->hook(worker->data1, worker->data2);
+ }
+}
+
+static void Launch(WebPWorker* const worker) {
+#ifdef WEBP_USE_THREAD
+ ChangeState(worker, WORK);
+#else
+ Execute(worker);
+#endif
+}
+
+static void End(WebPWorker* const worker) {
+#ifdef WEBP_USE_THREAD
+ if (worker->impl_ != NULL) {
+ ChangeState(worker, NOT_OK);
+ pthread_join(worker->impl_->thread_, NULL);
+ pthread_mutex_destroy(&worker->impl_->mutex_);
+ pthread_cond_destroy(&worker->impl_->condition_);
+ WebPSafeFree(worker->impl_);
+ worker->impl_ = NULL;
+ }
+#else
+ worker->status_ = NOT_OK;
+ assert(worker->impl_ == NULL);
+#endif
+ assert(worker->status_ == NOT_OK);
+}
+
+//------------------------------------------------------------------------------
+
+static WebPWorkerInterface g_worker_interface = {
+ Init, Reset, Sync, Launch, Execute, End
+};
+
+int WebPSetWorkerInterface(const WebPWorkerInterface* const winterface) {
+ if (winterface == NULL ||
+ winterface->Init == NULL || winterface->Reset == NULL ||
+ winterface->Sync == NULL || winterface->Launch == NULL ||
+ winterface->Execute == NULL || winterface->End == NULL) {
+ return 0;
+ }
+ g_worker_interface = *winterface;
+ return 1;
+}
+
+const WebPWorkerInterface* WebPGetWorkerInterface(void) {
+ return &g_worker_interface;
+}
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/utils/thread_utils.h b/media/libwebp/utils/thread_utils.h
new file mode 100644
index 000000000..840831185
--- /dev/null
+++ b/media/libwebp/utils/thread_utils.h
@@ -0,0 +1,93 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Multi-threaded worker
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_UTILS_THREAD_H_
+#define WEBP_UTILS_THREAD_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// State of the worker thread object
+typedef enum {
+ NOT_OK = 0, // object is unusable
+ OK, // ready to work
+ WORK // busy finishing the current task
+} WebPWorkerStatus;
+
+// Function to be called by the worker thread. Takes two opaque pointers as
+// arguments (data1 and data2), and should return false in case of error.
+typedef int (*WebPWorkerHook)(void*, void*);
+
+// Platform-dependent implementation details for the worker.
+typedef struct WebPWorkerImpl WebPWorkerImpl;
+
+// Synchronization object used to launch job in the worker thread
+typedef struct {
+ WebPWorkerImpl* impl_;
+ WebPWorkerStatus status_;
+ WebPWorkerHook hook; // hook to call
+ void* data1; // first argument passed to 'hook'
+ void* data2; // second argument passed to 'hook'
+ int had_error; // return value of the last call to 'hook'
+} WebPWorker;
+
+// The interface for all thread-worker related functions. All these functions
+// must be implemented.
+typedef struct {
+ // Must be called first, before any other method.
+ void (*Init)(WebPWorker* const worker);
+ // Must be called to initialize the object and spawn the thread. Re-entrant.
+ // Will potentially launch the thread. Returns false in case of error.
+ int (*Reset)(WebPWorker* const worker);
+ // Makes sure the previous work is finished. Returns true if worker->had_error
+ // was not set and no error condition was triggered by the working thread.
+ int (*Sync)(WebPWorker* const worker);
+ // Triggers the thread to call hook() with data1 and data2 arguments. These
+ // hook/data1/data2 values can be changed at any time before calling this
+ // function, but not be changed afterward until the next call to Sync().
+ void (*Launch)(WebPWorker* const worker);
+ // This function is similar to Launch() except that it calls the
+ // hook directly instead of using a thread. Convenient to bypass the thread
+ // mechanism while still using the WebPWorker structs. Sync() must
+ // still be called afterward (for error reporting).
+ void (*Execute)(WebPWorker* const worker);
+ // Kill the thread and terminate the object. To use the object again, one
+ // must call Reset() again.
+ void (*End)(WebPWorker* const worker);
+} WebPWorkerInterface;
+
+// Install a new set of threading functions, overriding the defaults. This
+// should be done before any workers are started, i.e., before any encoding or
+// decoding takes place. The contents of the interface struct are copied, it
+// is safe to free the corresponding memory after this call. This function is
+// not thread-safe. Return false in case of invalid pointer or methods.
+WEBP_EXTERN(int) WebPSetWorkerInterface(
+ const WebPWorkerInterface* const winterface);
+
+// Retrieve the currently set thread worker interface.
+WEBP_EXTERN(const WebPWorkerInterface*) WebPGetWorkerInterface(void);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_THREAD_H_ */
diff --git a/media/libwebp/utils/utils.c b/media/libwebp/utils/utils.c
new file mode 100644
index 000000000..504d924b6
--- /dev/null
+++ b/media/libwebp/utils/utils.c
@@ -0,0 +1,330 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Misc. common utility functions
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#include <stdlib.h>
+#include <string.h> // for memcpy()
+#include "../webp/decode.h"
+#include "../webp/encode.h"
+#include "../webp/format_constants.h" // for MAX_PALETTE_SIZE
+#include "./utils.h"
+
+// If PRINT_MEM_INFO is defined, extra info (like total memory used, number of
+// alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
+// and not multi-thread safe!).
+// An interesting alternative is valgrind's 'massif' tool:
+// http://valgrind.org/docs/manual/ms-manual.html
+// Here is an example command line:
+/* valgrind --tool=massif --massif-out-file=massif.out \
+ --stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc
+ ms_print massif.out
+*/
+// In addition:
+// * if PRINT_MEM_TRAFFIC is defined, all the details of the malloc/free cycles
+// are printed.
+// * if MALLOC_FAIL_AT is defined, the global environment variable
+// $MALLOC_FAIL_AT is used to simulate a memory error when calloc or malloc
+// is called for the nth time. Example usage:
+// export MALLOC_FAIL_AT=50 && ./examples/cwebp input.png
+// * if MALLOC_LIMIT is defined, the global environment variable $MALLOC_LIMIT
+// sets the maximum amount of memory (in bytes) made available to libwebp.
+// This can be used to emulate environment with very limited memory.
+// Example: export MALLOC_LIMIT=64000000 && ./examples/dwebp picture.webp
+
+// #define PRINT_MEM_INFO
+// #define PRINT_MEM_TRAFFIC
+// #define MALLOC_FAIL_AT
+// #define MALLOC_LIMIT
+
+//------------------------------------------------------------------------------
+// Checked memory allocation
+
+#if defined(PRINT_MEM_INFO)
+
+#include <stdio.h>
+
+static int num_malloc_calls = 0;
+static int num_calloc_calls = 0;
+static int num_free_calls = 0;
+static int countdown_to_fail = 0; // 0 = off
+
+typedef struct MemBlock MemBlock;
+struct MemBlock {
+ void* ptr_;
+ size_t size_;
+ MemBlock* next_;
+};
+
+static MemBlock* all_blocks = NULL;
+static size_t total_mem = 0;
+static size_t total_mem_allocated = 0;
+static size_t high_water_mark = 0;
+static size_t mem_limit = 0;
+
+static int exit_registered = 0;
+
+static void PrintMemInfo(void) {
+ fprintf(stderr, "\nMEMORY INFO:\n");
+ fprintf(stderr, "num calls to: malloc = %4d\n", num_malloc_calls);
+ fprintf(stderr, " calloc = %4d\n", num_calloc_calls);
+ fprintf(stderr, " free = %4d\n", num_free_calls);
+ fprintf(stderr, "total_mem: %u\n", (uint32_t)total_mem);
+ fprintf(stderr, "total_mem allocated: %u\n", (uint32_t)total_mem_allocated);
+ fprintf(stderr, "high-water mark: %u\n", (uint32_t)high_water_mark);
+ while (all_blocks != NULL) {
+ MemBlock* b = all_blocks;
+ all_blocks = b->next_;
+ free(b);
+ }
+}
+
+static void Increment(int* const v) {
+ if (!exit_registered) {
+#if defined(MALLOC_FAIL_AT)
+ {
+ const char* const malloc_fail_at_str = getenv("MALLOC_FAIL_AT");
+ if (malloc_fail_at_str != NULL) {
+ countdown_to_fail = atoi(malloc_fail_at_str);
+ }
+ }
+#endif
+#if defined(MALLOC_LIMIT)
+ {
+ const char* const malloc_limit_str = getenv("MALLOC_LIMIT");
+ if (malloc_limit_str != NULL) {
+ mem_limit = atoi(malloc_limit_str);
+ }
+ }
+#endif
+ (void)countdown_to_fail;
+ (void)mem_limit;
+ atexit(PrintMemInfo);
+ exit_registered = 1;
+ }
+ ++*v;
+}
+
+static void AddMem(void* ptr, size_t size) {
+ if (ptr != NULL) {
+ MemBlock* const b = (MemBlock*)malloc(sizeof(*b));
+ if (b == NULL) abort();
+ b->next_ = all_blocks;
+ all_blocks = b;
+ b->ptr_ = ptr;
+ b->size_ = size;
+ total_mem += size;
+ total_mem_allocated += size;
+#if defined(PRINT_MEM_TRAFFIC)
+#if defined(MALLOC_FAIL_AT)
+ fprintf(stderr, "fail-count: %5d [mem=%u]\n",
+ num_malloc_calls + num_calloc_calls, (uint32_t)total_mem);
+#else
+ fprintf(stderr, "Mem: %u (+%u)\n", (uint32_t)total_mem, (uint32_t)size);
+#endif
+#endif
+ if (total_mem > high_water_mark) high_water_mark = total_mem;
+ }
+}
+
+static void SubMem(void* ptr) {
+ if (ptr != NULL) {
+ MemBlock** b = &all_blocks;
+ // Inefficient search, but that's just for debugging.
+ while (*b != NULL && (*b)->ptr_ != ptr) b = &(*b)->next_;
+ if (*b == NULL) {
+ fprintf(stderr, "Invalid pointer free! (%p)\n", ptr);
+ abort();
+ }
+ {
+ MemBlock* const block = *b;
+ *b = block->next_;
+ total_mem -= block->size_;
+#if defined(PRINT_MEM_TRAFFIC)
+ fprintf(stderr, "Mem: %u (-%u)\n",
+ (uint32_t)total_mem, (uint32_t)block->size_);
+#endif
+ free(block);
+ }
+ }
+}
+
+#else
+#define Increment(v) do {} while (0)
+#define AddMem(p, s) do {} while (0)
+#define SubMem(p) do {} while (0)
+#endif
+
+// Returns 0 in case of overflow of nmemb * size.
+static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
+ const uint64_t total_size = nmemb * size;
+ if (nmemb == 0) return 1;
+ if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0;
+ if (total_size != (size_t)total_size) return 0;
+#if defined(PRINT_MEM_INFO) && defined(MALLOC_FAIL_AT)
+ if (countdown_to_fail > 0 && --countdown_to_fail == 0) {
+ return 0; // fake fail!
+ }
+#endif
+#if defined(MALLOC_LIMIT)
+ if (mem_limit > 0) {
+ const uint64_t new_total_mem = (uint64_t)total_mem + total_size;
+ if (new_total_mem != (size_t)new_total_mem ||
+ new_total_mem > mem_limit) {
+ return 0; // fake fail!
+ }
+ }
+#endif
+
+ return 1;
+}
+
+void* WebPSafeMalloc(uint64_t nmemb, size_t size) {
+ void* ptr;
+ Increment(&num_malloc_calls);
+ if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL;
+ assert(nmemb * size > 0);
+ ptr = malloc((size_t)(nmemb * size));
+ AddMem(ptr, (size_t)(nmemb * size));
+ return ptr;
+}
+
+void* WebPSafeCalloc(uint64_t nmemb, size_t size) {
+ void* ptr;
+ Increment(&num_calloc_calls);
+ if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL;
+ assert(nmemb * size > 0);
+ ptr = calloc((size_t)nmemb, size);
+ AddMem(ptr, (size_t)(nmemb * size));
+ return ptr;
+}
+
+void WebPSafeFree(void* const ptr) {
+ if (ptr != NULL) {
+ Increment(&num_free_calls);
+ SubMem(ptr);
+ }
+ free(ptr);
+}
+
+// Public API function.
+void WebPFree(void* ptr) {
+ free(ptr);
+}
+
+//------------------------------------------------------------------------------
+
+void WebPCopyPlane(const uint8_t* src, int src_stride,
+ uint8_t* dst, int dst_stride, int width, int height) {
+ assert(src != NULL && dst != NULL);
+ assert(src_stride >= width && dst_stride >= width);
+ while (height-- > 0) {
+ memcpy(dst, src, width);
+ src += src_stride;
+ dst += dst_stride;
+ }
+}
+
+void WebPCopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
+ assert(src != NULL && dst != NULL);
+ assert(src->width == dst->width && src->height == dst->height);
+ assert(src->use_argb && dst->use_argb);
+ WebPCopyPlane((uint8_t*)src->argb, 4 * src->argb_stride, (uint8_t*)dst->argb,
+ 4 * dst->argb_stride, 4 * src->width, src->height);
+}
+
+//------------------------------------------------------------------------------
+
+#define COLOR_HASH_SIZE (MAX_PALETTE_SIZE * 4)
+#define COLOR_HASH_RIGHT_SHIFT 22 // 32 - log2(COLOR_HASH_SIZE).
+
+int WebPGetColorPalette(const WebPPicture* const pic, uint32_t* const palette) {
+ int i;
+ int x, y;
+ int num_colors = 0;
+ uint8_t in_use[COLOR_HASH_SIZE] = { 0 };
+ uint32_t colors[COLOR_HASH_SIZE];
+ static const uint64_t kHashMul = 0x1e35a7bdull;
+ const uint32_t* argb = pic->argb;
+ const int width = pic->width;
+ const int height = pic->height;
+ uint32_t last_pix = ~argb[0]; // so we're sure that last_pix != argb[0]
+ assert(pic != NULL);
+ assert(pic->use_argb);
+
+ for (y = 0; y < height; ++y) {
+ for (x = 0; x < width; ++x) {
+ int key;
+ if (argb[x] == last_pix) {
+ continue;
+ }
+ last_pix = argb[x];
+ key = ((last_pix * kHashMul) & 0xffffffffu) >> COLOR_HASH_RIGHT_SHIFT;
+ while (1) {
+ if (!in_use[key]) {
+ colors[key] = last_pix;
+ in_use[key] = 1;
+ ++num_colors;
+ if (num_colors > MAX_PALETTE_SIZE) {
+ return MAX_PALETTE_SIZE + 1; // Exact count not needed.
+ }
+ break;
+ } else if (colors[key] == last_pix) {
+ break; // The color is already there.
+ } else {
+ // Some other color sits here, so do linear conflict resolution.
+ ++key;
+ key &= (COLOR_HASH_SIZE - 1); // Key mask.
+ }
+ }
+ }
+ argb += pic->argb_stride;
+ }
+
+ if (palette != NULL) { // Fill the colors into palette.
+ num_colors = 0;
+ for (i = 0; i < COLOR_HASH_SIZE; ++i) {
+ if (in_use[i]) {
+ palette[num_colors] = colors[i];
+ ++num_colors;
+ }
+ }
+ }
+ return num_colors;
+}
+
+#undef COLOR_HASH_SIZE
+#undef COLOR_HASH_RIGHT_SHIFT
+
+//------------------------------------------------------------------------------
+
+#if defined(WEBP_NEED_LOG_TABLE_8BIT)
+const uint8_t WebPLogTable8bit[256] = { // 31 ^ clz(i)
+ 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+#endif
+
+//------------------------------------------------------------------------------
diff --git a/media/libwebp/utils/utils.h b/media/libwebp/utils/utils.h
new file mode 100644
index 000000000..3ab459050
--- /dev/null
+++ b/media/libwebp/utils/utils.h
@@ -0,0 +1,178 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Misc. common utility functions
+//
+// Authors: Skal (pascal.massimino@gmail.com)
+// Urvang (urvang@google.com)
+
+#ifndef WEBP_UTILS_UTILS_H_
+#define WEBP_UTILS_UTILS_H_
+
+#ifdef HAVE_CONFIG_H
+#include "../webp/config.h"
+#endif
+
+#include <assert.h>
+#include <limits.h>
+
+#include "../dsp/dsp.h"
+#include "../webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------------------------------------------------------------
+// Memory allocation
+
+// This is the maximum memory amount that libwebp will ever try to allocate.
+#ifndef WEBP_MAX_ALLOCABLE_MEMORY
+#if SIZE_MAX > (1ULL << 34)
+#define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 34)
+#else
+// For 32-bit targets keep this below INT_MAX to avoid valgrind warnings.
+#define WEBP_MAX_ALLOCABLE_MEMORY ((1ULL << 31) - (1 << 16))
+#endif
+#endif // WEBP_MAX_ALLOCABLE_MEMORY
+
+// size-checking safe malloc/calloc: verify that the requested size is not too
+// large, or return NULL. You don't need to call these for constructs like
+// malloc(sizeof(foo)), but only if there's picture-dependent size involved
+// somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this
+// safe malloc() borrows the signature from calloc(), pointing at the dangerous
+// underlying multiply involved.
+WEBP_EXTERN(void*) WebPSafeMalloc(uint64_t nmemb, size_t size);
+// Note that WebPSafeCalloc() expects the second argument type to be 'size_t'
+// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.
+WEBP_EXTERN(void*) WebPSafeCalloc(uint64_t nmemb, size_t size);
+
+// Companion deallocation function to the above allocations.
+WEBP_EXTERN(void) WebPSafeFree(void* const ptr);
+
+//------------------------------------------------------------------------------
+// Alignment
+
+#define WEBP_ALIGN_CST 31
+#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST)
+
+#include <string.h>
+// memcpy() is the safe way of moving potentially unaligned 32b memory.
+static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) {
+ uint32_t A;
+ memcpy(&A, (const int*)ptr, sizeof(A));
+ return A;
+}
+static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
+ memcpy(ptr, &val, sizeof(val));
+}
+
+//------------------------------------------------------------------------------
+// Reading/writing data.
+
+// Read 16, 24 or 32 bits stored in little-endian order.
+static WEBP_INLINE int GetLE16(const uint8_t* const data) {
+ return (int)(data[0] << 0) | (data[1] << 8);
+}
+
+static WEBP_INLINE int GetLE24(const uint8_t* const data) {
+ return GetLE16(data) | (data[2] << 16);
+}
+
+static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {
+ return GetLE16(data) | ((uint32_t)GetLE16(data + 2) << 16);
+}
+
+// Store 16, 24 or 32 bits in little-endian order.
+static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
+ assert(val < (1 << 16));
+ data[0] = (val >> 0);
+ data[1] = (val >> 8);
+}
+
+static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
+ assert(val < (1 << 24));
+ PutLE16(data, val & 0xffff);
+ data[2] = (val >> 16);
+}
+
+static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {
+ PutLE16(data, (int)(val & 0xffff));
+ PutLE16(data + 2, (int)(val >> 16));
+}
+
+// Returns 31 ^ clz(n) = log2(n). This is the default C-implementation, either
+// based on table or not. Can be used as fallback if clz() is not available.
+#define WEBP_NEED_LOG_TABLE_8BIT
+extern const uint8_t WebPLogTable8bit[256];
+static WEBP_INLINE int WebPLog2FloorC(uint32_t n) {
+ int log = 0;
+ while (n >= 256) {
+ log += 8;
+ n >>= 8;
+ }
+ return log + WebPLogTable8bit[n];
+}
+
+// Returns (int)floor(log2(n)). n must be > 0.
+// use GNU builtins where available.
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+ return 31 ^ __builtin_clz(n);
+}
+#elif defined(_MSC_VER) && _MSC_VER > 1310 && \
+ (defined(_M_X64) || defined(_M_IX86))
+#include <intrin.h>
+#pragma intrinsic(_BitScanReverse)
+
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
+ unsigned long first_set_bit;
+ _BitScanReverse(&first_set_bit, n);
+ return first_set_bit;
+}
+#else // default: use the C-version.
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) { return WebPLog2FloorC(n); }
+#endif
+
+//------------------------------------------------------------------------------
+// Pixel copying.
+
+struct WebPPicture;
+
+// Copy width x height pixels from 'src' to 'dst' honoring the strides.
+WEBP_EXTERN(void) WebPCopyPlane(const uint8_t* src, int src_stride,
+ uint8_t* dst, int dst_stride,
+ int width, int height);
+
+// Copy ARGB pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are
+// assumed to be already allocated and using ARGB data.
+WEBP_EXTERN(void) WebPCopyPixels(const struct WebPPicture* const src,
+ struct WebPPicture* const dst);
+
+//------------------------------------------------------------------------------
+// Unique colors.
+
+// Returns count of unique colors in 'pic', assuming pic->use_argb is true.
+// If the unique color count is more than MAX_PALETTE_SIZE, returns
+// MAX_PALETTE_SIZE+1.
+// If 'palette' is not NULL and number of unique colors is less than or equal to
+// MAX_PALETTE_SIZE, also outputs the actual unique colors into 'palette'.
+// Note: 'palette' is assumed to be an array already allocated with at least
+// MAX_PALETTE_SIZE elements.
+WEBP_EXTERN(int) WebPGetColorPalette(const struct WebPPicture* const pic,
+ uint32_t* const palette);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_UTILS_UTILS_H_ */
diff --git a/media/libwebp/webp/config.h b/media/libwebp/webp/config.h
new file mode 100644
index 000000000..dd31c3cfa
--- /dev/null
+++ b/media/libwebp/webp/config.h
@@ -0,0 +1,147 @@
+/* src/webp/config.h. Generated from config.h.in by configure. */
+/* src/webp/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Set to 1 if __builtin_bswap16 is available */
+#define HAVE_BUILTIN_BSWAP16 1
+
+/* Set to 1 if __builtin_bswap32 is available */
+#define HAVE_BUILTIN_BSWAP32 1
+
+/* Set to 1 if __builtin_bswap64 is available */
+#define HAVE_BUILTIN_BSWAP64 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <GLUT/glut.h> header file. */
+/* #undef HAVE_GLUT_GLUT_H */
+
+/* Define to 1 if you have the <GL/glut.h> header file. */
+/* #undef HAVE_GL_GLUT_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <OpenGL/glut.h> header file. */
+/* #undef HAVE_OPENGL_GLUT_H */
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#define HAVE_PTHREAD_PRIO_INHERIT 1
+
+/* Define to 1 if you have the <shlwapi.h> header file. */
+/* #undef HAVE_SHLWAPI_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <wincodec.h> header file. */
+/* #undef HAVE_WINCODEC_H */
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "libwebp"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://bugs.chromium.org/p/webp"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libwebp"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libwebp 0.5.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libwebp"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://developers.google.com/speed/webp"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.5.1"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.5.1"
+
+/* Enable experimental code */
+/* #undef WEBP_EXPERIMENTAL_FEATURES */
+
+/* Set to 1 if AVX2 is supported */
+#define WEBP_HAVE_AVX2 1
+
+/* Set to 1 if GIF library is installed */
+#define WEBP_HAVE_GIF 1
+
+/* Set to 1 if OpenGL is supported */
+/* #undef WEBP_HAVE_GL */
+
+/* Set to 1 if JPEG library is installed */
+#define WEBP_HAVE_JPEG 1
+
+/* Set to 1 if NEON is supported */
+/* #undef WEBP_HAVE_NEON */
+
+/* Set to 1 if runtime detection of NEON is enabled */
+/* #undef WEBP_HAVE_NEON_RTCD */
+
+/* Set to 1 if PNG library is installed */
+#define WEBP_HAVE_PNG 1
+
+/* Set to 1 if SSE2 is supported */
+#define WEBP_HAVE_SSE2 1
+
+/* Set to 1 if SSE4.1 is supported */
+#define WEBP_HAVE_SSE41 1
+
+/* Set to 1 if TIFF library is installed */
+#define WEBP_HAVE_TIFF 1
+
+/* Undefine this to disable thread support. */
+#define WEBP_USE_THREAD 1
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* # undef WORDS_BIGENDIAN */
+# endif
+#endif
diff --git a/media/libwebp/webp/decode.h b/media/libwebp/webp/decode.h
new file mode 100644
index 000000000..4c5e74ac3
--- /dev/null
+++ b/media/libwebp/webp/decode.h
@@ -0,0 +1,493 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Main decoding functions for WebP images.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_DECODE_H_
+#define WEBP_WEBP_DECODE_H_
+
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_DECODER_ABI_VERSION 0x0208 // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum VP8StatusCode VP8StatusCode;
+// typedef enum WEBP_CSP_MODE WEBP_CSP_MODE;
+typedef struct WebPRGBABuffer WebPRGBABuffer;
+typedef struct WebPYUVABuffer WebPYUVABuffer;
+typedef struct WebPDecBuffer WebPDecBuffer;
+typedef struct WebPIDecoder WebPIDecoder;
+typedef struct WebPBitstreamFeatures WebPBitstreamFeatures;
+typedef struct WebPDecoderOptions WebPDecoderOptions;
+typedef struct WebPDecoderConfig WebPDecoderConfig;
+
+// Return the decoder's version number, packed in hexadecimal using 8bits for
+// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetDecoderVersion(void);
+
+// Retrieve basic header information: width, height.
+// This function will also validate the header, returning true on success,
+// false otherwise. '*width' and '*height' are only valid on successful return.
+// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
+WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
+// with the dimensions in *width and *height. The ordering of samples in
+// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
+// The returned pointer should be deleted calling WebPFree().
+// Returns NULL in case of error.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
+// If the bitstream contains transparency, it is ignored.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+
+// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
+// returned is the Y samples buffer. Upon return, *u and *v will point to
+// the U and V chroma data. These U and V buffers need NOT be passed to
+// WebPFree(), unlike the returned Y luma one. The dimension of the U and V
+// planes are both (*width + 1) / 2 and (*height + 1)/ 2.
+// Upon return, the Y buffer has a stride returned as '*stride', while U and V
+// have a common stride returned as '*uv_stride'.
+// Return NULL in case of error.
+// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
+WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size,
+ int* width, int* height,
+ uint8_t** u, uint8_t** v,
+ int* stride, int* uv_stride);
+
+// Releases memory returned by the WebPDecode*() functions above.
+WEBP_EXTERN(void) WebPFree(void* ptr);
+
+// These five functions are variants of the above ones, that decode the image
+// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
+// available in this buffer is indicated by 'output_buffer_size'. If this
+// storage is not sufficient (or an error occurred), NULL is returned.
+// Otherwise, output_buffer is returned, for convenience.
+// The parameter 'output_stride' specifies the distance (in bytes)
+// between scanlines. Hence, output_buffer_size is expected to be at least
+// output_stride x picture-height.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// RGB and BGR variants. Here too the transparency information, if present,
+// will be dropped and ignored.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
+// into pre-allocated luma/chroma plane buffers. This function requires the
+// strides to be passed: one for the luma plane and one for each of the
+// chroma ones. The size of each plane buffer is passed as 'luma_size',
+// 'u_size' and 'v_size' respectively.
+// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
+// during decoding (or because some buffers were found to be too small).
+WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride);
+
+//------------------------------------------------------------------------------
+// Output colorspaces and buffer
+
+// Colorspaces
+// Note: the naming describes the byte-ordering of packed samples in memory.
+// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
+// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
+// RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
+// RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
+// RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
+// In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
+// these two modes:
+// RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
+// RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
+
+typedef enum WEBP_CSP_MODE {
+ MODE_RGB = 0, MODE_RGBA = 1,
+ MODE_BGR = 2, MODE_BGRA = 3,
+ MODE_ARGB = 4, MODE_RGBA_4444 = 5,
+ MODE_RGB_565 = 6,
+ // RGB-premultiplied transparent modes (alpha value is preserved)
+ MODE_rgbA = 7,
+ MODE_bgrA = 8,
+ MODE_Argb = 9,
+ MODE_rgbA_4444 = 10,
+ // YUV modes must come after RGB ones.
+ MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0
+ MODE_LAST = 13
+} WEBP_CSP_MODE;
+
+// Some useful macros:
+static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
+ return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
+ mode == MODE_rgbA_4444);
+}
+
+static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
+ return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
+ mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
+ WebPIsPremultipliedMode(mode));
+}
+
+static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
+ return (mode < MODE_YUV);
+}
+
+//------------------------------------------------------------------------------
+// WebPDecBuffer: Generic structure for describing the output sample buffer.
+
+struct WebPRGBABuffer { // view as RGBA
+ uint8_t* rgba; // pointer to RGBA samples
+ int stride; // stride in bytes from one scanline to the next.
+ size_t size; // total size of the *rgba buffer.
+};
+
+struct WebPYUVABuffer { // view as YUVA
+ uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples
+ int y_stride; // luma stride
+ int u_stride, v_stride; // chroma strides
+ int a_stride; // alpha stride
+ size_t y_size; // luma plane size
+ size_t u_size, v_size; // chroma planes size
+ size_t a_size; // alpha-plane size
+};
+
+// Output buffer
+struct WebPDecBuffer {
+ WEBP_CSP_MODE colorspace; // Colorspace.
+ int width, height; // Dimensions.
+ int is_external_memory; // If non-zero, 'internal_memory' pointer is not
+ // used. If value is '2' or more, the external
+ // memory is considered 'slow' and multiple
+ // read/write will be avoided.
+ union {
+ WebPRGBABuffer RGBA;
+ WebPYUVABuffer YUVA;
+ } u; // Nameless union of buffer parameters.
+ uint32_t pad[4]; // padding for later use
+
+ uint8_t* private_memory; // Internally allocated memory (only when
+ // is_external_memory is 0). Should not be used
+ // externally, but accessed via the buffer union.
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int);
+
+// Initialize the structure as empty. Must be called before any other use.
+// Returns false in case of version mismatch
+static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
+ return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
+}
+
+// Free any memory associated with the buffer. Must always be called last.
+// Note: doesn't free the 'buffer' structure itself.
+WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer);
+
+//------------------------------------------------------------------------------
+// Enumeration of the status codes
+
+typedef enum VP8StatusCode {
+ VP8_STATUS_OK = 0,
+ VP8_STATUS_OUT_OF_MEMORY,
+ VP8_STATUS_INVALID_PARAM,
+ VP8_STATUS_BITSTREAM_ERROR,
+ VP8_STATUS_UNSUPPORTED_FEATURE,
+ VP8_STATUS_SUSPENDED,
+ VP8_STATUS_USER_ABORT,
+ VP8_STATUS_NOT_ENOUGH_DATA
+} VP8StatusCode;
+
+//------------------------------------------------------------------------------
+// Incremental decoding
+//
+// This API allows streamlined decoding of partial data.
+// Picture can be incrementally decoded as data become available thanks to the
+// WebPIDecoder object. This object can be left in a SUSPENDED state if the
+// picture is only partially decoded, pending additional input.
+// Code example:
+//
+// WebPInitDecBuffer(&output_buffer);
+// output_buffer.colorspace = mode;
+// ...
+// WebPIDecoder* idec = WebPINewDecoder(&output_buffer);
+// while (additional_data_is_available) {
+// // ... (get additional data in some new_data[] buffer)
+// status = WebPIAppend(idec, new_data, new_data_size);
+// if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
+// break; // an error occurred.
+// }
+//
+// // The above call decodes the current available buffer.
+// // Part of the image can now be refreshed by calling
+// // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
+// }
+// WebPIDelete(idec);
+
+// Creates a new incremental decoder with the supplied buffer parameter.
+// This output_buffer can be passed NULL, in which case a default output buffer
+// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
+// is kept, which means that the lifespan of 'output_buffer' must be larger than
+// that of the returned WebPIDecoder object.
+// The supplied 'output_buffer' content MUST NOT be changed between calls to
+// WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
+// not set to 0. In such a case, it is allowed to modify the pointers, size and
+// stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
+// within valid bounds.
+// All other fields of WebPDecBuffer MUST remain constant between calls.
+// Returns NULL if the allocation failed.
+WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer);
+
+// This function allocates and initializes an incremental-decoder object, which
+// will output the RGB/A samples specified by 'csp' into a preallocated
+// buffer 'output_buffer'. The size of this buffer is at least
+// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
+// is specified by 'output_stride'.
+// Additionally, output_buffer can be passed NULL in which case the output
+// buffer will be allocated automatically when the decoding starts. The
+// colorspace 'csp' is taken into account for allocating this buffer. All other
+// parameters are ignored.
+// Returns NULL if the allocation failed, or if some parameters are invalid.
+WEBP_EXTERN(WebPIDecoder*) WebPINewRGB(
+ WEBP_CSP_MODE csp,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// This function allocates and initializes an incremental-decoder object, which
+// will output the raw luma/chroma samples into a preallocated planes if
+// supplied. The luma plane is specified by its pointer 'luma', its size
+// 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
+// is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
+// plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
+// can be pass NULL in case one is not interested in the transparency plane.
+// Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
+// In this case, the output buffer will be automatically allocated (using
+// MODE_YUVA) when decoding starts. All parameters are then ignored.
+// Returns NULL if the allocation failed or if a parameter is invalid.
+WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA(
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride,
+ uint8_t* a, size_t a_size, int a_stride);
+
+// Deprecated version of the above, without the alpha plane.
+// Kept for backward compatibility.
+WEBP_EXTERN(WebPIDecoder*) WebPINewYUV(
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride);
+
+// Deletes the WebPIDecoder object and associated memory. Must always be called
+// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
+WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec);
+
+// Copies and decodes the next available data. Returns VP8_STATUS_OK when
+// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
+// data is expected. Returns error in other cases.
+WEBP_EXTERN(VP8StatusCode) WebPIAppend(
+ WebPIDecoder* idec, const uint8_t* data, size_t data_size);
+
+// A variant of the above function to be used when data buffer contains
+// partial data from the beginning. In this case data buffer is not copied
+// to the internal memory.
+// Note that the value of the 'data' pointer can change between calls to
+// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
+WEBP_EXTERN(VP8StatusCode) WebPIUpdate(
+ WebPIDecoder* idec, const uint8_t* data, size_t data_size);
+
+// Returns the RGB/A image decoded so far. Returns NULL if output params
+// are not initialized yet. The RGB/A output type corresponds to the colorspace
+// specified during call to WebPINewDecoder() or WebPINewRGB().
+// *last_y is the index of last decoded row in raster scan order. Some pointers
+// (*last_y, *width etc.) can be NULL if corresponding information is not
+// needed.
+WEBP_EXTERN(uint8_t*) WebPIDecGetRGB(
+ const WebPIDecoder* idec, int* last_y,
+ int* width, int* height, int* stride);
+
+// Same as above function to get a YUVA image. Returns pointer to the luma
+// plane or NULL in case of error. If there is no alpha information
+// the alpha pointer '*a' will be returned NULL.
+WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA(
+ const WebPIDecoder* idec, int* last_y,
+ uint8_t** u, uint8_t** v, uint8_t** a,
+ int* width, int* height, int* stride, int* uv_stride, int* a_stride);
+
+// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
+// alpha information (if present). Kept for backward compatibility.
+static WEBP_INLINE uint8_t* WebPIDecGetYUV(
+ const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
+ int* width, int* height, int* stride, int* uv_stride) {
+ return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
+ stride, uv_stride, NULL);
+}
+
+// Generic call to retrieve information about the displayable area.
+// If non NULL, the left/right/width/height pointers are filled with the visible
+// rectangular area so far.
+// Returns NULL in case the incremental decoder object is in an invalid state.
+// Otherwise returns the pointer to the internal representation. This structure
+// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
+WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea(
+ const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
+
+//------------------------------------------------------------------------------
+// Advanced decoding parametrization
+//
+// Code sample for using the advanced decoding API
+/*
+ // A) Init a configuration object
+ WebPDecoderConfig config;
+ CHECK(WebPInitDecoderConfig(&config));
+
+ // B) optional: retrieve the bitstream's features.
+ CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
+
+ // C) Adjust 'config', if needed
+ config.no_fancy_upsampling = 1;
+ config.output.colorspace = MODE_BGRA;
+ // etc.
+
+ // Note that you can also make config.output point to an externally
+ // supplied memory buffer, provided it's big enough to store the decoded
+ // picture. Otherwise, config.output will just be used to allocate memory
+ // and store the decoded picture.
+
+ // D) Decode!
+ CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+ // E) Decoded image is now in config.output (and config.output.u.RGBA)
+
+ // F) Reclaim memory allocated in config's object. It's safe to call
+ // this function even if the memory is external and wasn't allocated
+ // by WebPDecode().
+ WebPFreeDecBuffer(&config.output);
+*/
+
+// Features gathered from the bitstream
+struct WebPBitstreamFeatures {
+ int width; // Width in pixels, as read from the bitstream.
+ int height; // Height in pixels, as read from the bitstream.
+ int has_alpha; // True if the bitstream contains an alpha channel.
+ int has_animation; // True if the bitstream is an animation.
+ int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
+
+ uint32_t pad[5]; // padding for later use
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal(
+ const uint8_t*, size_t, WebPBitstreamFeatures*, int);
+
+// Retrieve features from the bitstream. The *features structure is filled
+// with information gathered from the bitstream.
+// Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
+// VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
+// features from headers. Returns error in other cases.
+static WEBP_INLINE VP8StatusCode WebPGetFeatures(
+ const uint8_t* data, size_t data_size,
+ WebPBitstreamFeatures* features) {
+ return WebPGetFeaturesInternal(data, data_size, features,
+ WEBP_DECODER_ABI_VERSION);
+}
+
+// Decoding options
+struct WebPDecoderOptions {
+ int bypass_filtering; // if true, skip the in-loop filtering
+ int no_fancy_upsampling; // if true, use faster pointwise upsampler
+ int use_cropping; // if true, cropping is applied _first_
+ int crop_left, crop_top; // top-left position for cropping.
+ // Will be snapped to even values.
+ int crop_width, crop_height; // dimension of the cropping area
+ int use_scaling; // if true, scaling is applied _afterward_
+ int scaled_width, scaled_height; // final resolution
+ int use_threads; // if true, use multi-threaded decoding
+ int dithering_strength; // dithering strength (0=Off, 100=full)
+ int flip; // flip output vertically
+ int alpha_dithering_strength; // alpha dithering strength in [0..100]
+
+ uint32_t pad[5]; // padding for later use
+};
+
+// Main object storing the configuration for advanced decoding.
+struct WebPDecoderConfig {
+ WebPBitstreamFeatures input; // Immutable bitstream features (optional)
+ WebPDecBuffer output; // Output buffer (can point to external mem)
+ WebPDecoderOptions options; // Decoding options
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
+
+// Initialize the configuration as empty. This function must always be
+// called first, unless WebPGetFeatures() is to be called.
+// Returns false in case of mismatched version.
+static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
+ return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
+}
+
+// Instantiate a new incremental decoder object with the requested
+// configuration. The bitstream can be passed using 'data' and 'data_size'
+// parameter, in which case the features will be parsed and stored into
+// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
+// Note that 'config' can be NULL too, in which case a default configuration
+// is used. If 'config' is not NULL, it must outlive the WebPIDecoder object
+// as some references to its fields will be used. No internal copy of 'config'
+// is made.
+// The return WebPIDecoder object must always be deleted calling WebPIDelete().
+// Returns NULL in case of error (and config->status will then reflect
+// the error condition, if available).
+WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size,
+ WebPDecoderConfig* config);
+
+// Non-incremental version. This version decodes the full data at once, taking
+// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
+// if the decoding was successful). Note that 'config' cannot be NULL.
+WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size,
+ WebPDecoderConfig* config);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_DECODE_H_ */
diff --git a/media/libwebp/webp/demux.h b/media/libwebp/webp/demux.h
new file mode 100644
index 000000000..454f6914b
--- /dev/null
+++ b/media/libwebp/webp/demux.h
@@ -0,0 +1,358 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Demux API.
+// Enables extraction of image and extended format data from WebP files.
+
+// Code Example: Demuxing WebP data to extract all the frames, ICC profile
+// and EXIF/XMP metadata.
+/*
+ WebPDemuxer* demux = WebPDemux(&webp_data);
+
+ uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+ uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+ // ... (Get information about the features present in the WebP file).
+ uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+
+ // ... (Iterate over all frames).
+ WebPIterator iter;
+ if (WebPDemuxGetFrame(demux, 1, &iter)) {
+ do {
+ // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
+ // ... and get other frame properties like width, height, offsets etc.
+ // ... see 'struct WebPIterator' below for more info).
+ } while (WebPDemuxNextFrame(&iter));
+ WebPDemuxReleaseIterator(&iter);
+ }
+
+ // ... (Extract metadata).
+ WebPChunkIterator chunk_iter;
+ if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
+ // ... (Consume the ICC profile in 'chunk_iter.chunk').
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
+ // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
+ // ... (Consume the XMP metadata in 'chunk_iter.chunk').
+ WebPDemuxReleaseChunkIterator(&chunk_iter);
+ WebPDemuxDelete(demux);
+*/
+
+#ifndef WEBP_WEBP_DEMUX_H_
+#define WEBP_WEBP_DEMUX_H_
+
+#include "./decode.h" // for WEBP_CSP_MODE
+#include "./mux_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPDemuxState WebPDemuxState;
+// typedef enum WebPFormatFeature WebPFormatFeature;
+typedef struct WebPDemuxer WebPDemuxer;
+typedef struct WebPIterator WebPIterator;
+typedef struct WebPChunkIterator WebPChunkIterator;
+typedef struct WebPAnimInfo WebPAnimInfo;
+typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions;
+
+//------------------------------------------------------------------------------
+
+// Returns the version number of the demux library, packed in hexadecimal using
+// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetDemuxVersion(void);
+
+//------------------------------------------------------------------------------
+// Life of a Demux object
+
+typedef enum WebPDemuxState {
+ WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing.
+ WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header.
+ WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete,
+ // data may be available.
+ WEBP_DEMUX_DONE = 2 // Entire file has been parsed.
+} WebPDemuxState;
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal(
+ const WebPData*, int, WebPDemuxState*, int);
+
+// Parses the full WebP file given by 'data'. For single images the WebP file
+// header alone or the file header and the chunk header may be absent.
+// Returns a WebPDemuxer object on successful parse, NULL otherwise.
+static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
+ return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
+}
+
+// Parses the possibly incomplete WebP file given by 'data'.
+// If 'state' is non-NULL it will be set to indicate the status of the demuxer.
+// Returns NULL in case of error or if there isn't enough data to start parsing;
+// and a WebPDemuxer object on successful parse.
+// Note that WebPDemuxer keeps internal pointers to 'data' memory segment.
+// If this data is volatile, the demuxer object should be deleted (by calling
+// WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.
+// This is usually an inexpensive operation.
+static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
+ const WebPData* data, WebPDemuxState* state) {
+ return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
+}
+
+// Frees memory associated with 'dmux'.
+WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux);
+
+//------------------------------------------------------------------------------
+// Data/information extraction.
+
+typedef enum WebPFormatFeature {
+ WEBP_FF_FORMAT_FLAGS, // Extended format flags present in the 'VP8X' chunk.
+ WEBP_FF_CANVAS_WIDTH,
+ WEBP_FF_CANVAS_HEIGHT,
+ WEBP_FF_LOOP_COUNT,
+ WEBP_FF_BACKGROUND_COLOR,
+ WEBP_FF_FRAME_COUNT // Number of frames present in the demux object.
+ // In case of a partial demux, this is the number of
+ // frames seen so far, with the last frame possibly
+ // being partial.
+} WebPFormatFeature;
+
+// Get the 'feature' value from the 'dmux'.
+// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
+// returned a state > WEBP_DEMUX_PARSING_HEADER.
+WEBP_EXTERN(uint32_t) WebPDemuxGetI(
+ const WebPDemuxer* dmux, WebPFormatFeature feature);
+
+//------------------------------------------------------------------------------
+// Frame iteration.
+
+struct WebPIterator {
+ int frame_num;
+ int num_frames; // equivalent to WEBP_FF_FRAME_COUNT.
+ int x_offset, y_offset; // offset relative to the canvas.
+ int width, height; // dimensions of this frame.
+ int duration; // display duration in milliseconds.
+ WebPMuxAnimDispose dispose_method; // dispose method for the frame.
+ int complete; // true if 'fragment' contains a full frame. partial images
+ // may still be decoded with the WebP incremental decoder.
+ WebPData fragment; // The frame given by 'frame_num'. Note for historical
+ // reasons this is called a fragment.
+ int has_alpha; // True if the frame contains transparency.
+ WebPMuxAnimBlend blend_method; // Blend operation for the frame.
+
+ uint32_t pad[2]; // padding for later use.
+ void* private_; // for internal use only.
+};
+
+// Retrieves frame 'frame_number' from 'dmux'.
+// 'iter->fragment' points to the frame on return from this function.
+// Setting 'frame_number' equal to 0 will return the last frame of the image.
+// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
+// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
+// NOTE: 'dmux' must persist for the lifetime of 'iter'.
+WEBP_EXTERN(int) WebPDemuxGetFrame(
+ const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
+
+// Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or
+// previous ('iter->frame_num' - 1) frame. These functions do not loop.
+// Returns true on success, false otherwise.
+WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter);
+WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter);
+
+// Releases any memory associated with 'iter'.
+// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
+// iter. Also, must be called before destroying the associated WebPDemuxer with
+// WebPDemuxDelete().
+WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter);
+
+//------------------------------------------------------------------------------
+// Chunk iteration.
+
+struct WebPChunkIterator {
+ // The current and total number of chunks with the fourcc given to
+ // WebPDemuxGetChunk().
+ int chunk_num;
+ int num_chunks;
+ WebPData chunk; // The payload of the chunk.
+
+ uint32_t pad[6]; // padding for later use
+ void* private_;
+};
+
+// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
+// 'dmux'.
+// 'fourcc' is a character array containing the fourcc of the chunk to return,
+// e.g., "ICCP", "XMP ", "EXIF", etc.
+// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
+// Returns true if the chunk is found, false otherwise. Image related chunk
+// payloads are accessed through WebPDemuxGetFrame() and related functions.
+// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
+// NOTE: 'dmux' must persist for the lifetime of the iterator.
+WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux,
+ const char fourcc[4], int chunk_number,
+ WebPChunkIterator* iter);
+
+// Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous
+// ('iter->chunk_num' - 1) chunk. These functions do not loop.
+// Returns true on success, false otherwise.
+WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter);
+WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter);
+
+// Releases any memory associated with 'iter'.
+// Must be called before destroying the associated WebPDemuxer with
+// WebPDemuxDelete().
+WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
+
+//------------------------------------------------------------------------------
+// WebPAnimDecoder API
+//
+// This API allows decoding (possibly) animated WebP images.
+//
+// Code Example:
+/*
+ WebPAnimDecoderOptions dec_options;
+ WebPAnimDecoderOptionsInit(&dec_options);
+ // Tune 'dec_options' as needed.
+ WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
+ WebPAnimInfo anim_info;
+ WebPAnimDecoderGetInfo(dec, &anim_info);
+ for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
+ while (WebPAnimDecoderHasMoreFrames(dec)) {
+ uint8_t* buf;
+ int timestamp;
+ WebPAnimDecoderGetNext(dec, &buf, &timestamp);
+ // ... (Render 'buf' based on 'timestamp').
+ // ... (Do NOT free 'buf', as it is owned by 'dec').
+ }
+ WebPAnimDecoderReset(dec);
+ }
+ const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
+ // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
+ WebPAnimDecoderDelete(dec);
+*/
+
+typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object.
+
+// Global options.
+struct WebPAnimDecoderOptions {
+ // Output colorspace. Only the following modes are supported:
+ // MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA.
+ WEBP_CSP_MODE color_mode;
+ int use_threads; // If true, use multi-threaded decoding.
+ uint32_t padding[7]; // Padding for later use.
+};
+
+// Internal, version-checked, entry point.
+WEBP_EXTERN(int) WebPAnimDecoderOptionsInitInternal(
+ WebPAnimDecoderOptions*, int);
+
+// Should always be called, to initialize a fresh WebPAnimDecoderOptions
+// structure before modification. Returns false in case of version mismatch.
+// WebPAnimDecoderOptionsInit() must have succeeded before using the
+// 'dec_options' object.
+static WEBP_INLINE int WebPAnimDecoderOptionsInit(
+ WebPAnimDecoderOptions* dec_options) {
+ return WebPAnimDecoderOptionsInitInternal(dec_options,
+ WEBP_DEMUX_ABI_VERSION);
+}
+
+// Internal, version-checked, entry point.
+WEBP_EXTERN(WebPAnimDecoder*) WebPAnimDecoderNewInternal(
+ const WebPData*, const WebPAnimDecoderOptions*, int);
+
+// Creates and initializes a WebPAnimDecoder object.
+// Parameters:
+// webp_data - (in) WebP bitstream. This should remain unchanged during the
+// lifetime of the output WebPAnimDecoder object.
+// dec_options - (in) decoding options. Can be passed NULL to choose
+// reasonable defaults (in particular, color mode MODE_RGBA
+// will be picked).
+// Returns:
+// A pointer to the newly created WebPAnimDecoder object, or NULL in case of
+// parsing error, invalid option or memory error.
+static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew(
+ const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) {
+ return WebPAnimDecoderNewInternal(webp_data, dec_options,
+ WEBP_DEMUX_ABI_VERSION);
+}
+
+// Global information about the animation..
+struct WebPAnimInfo {
+ uint32_t canvas_width;
+ uint32_t canvas_height;
+ uint32_t loop_count;
+ uint32_t bgcolor;
+ uint32_t frame_count;
+ uint32_t pad[4]; // padding for later use
+};
+
+// Get global information about the animation.
+// Parameters:
+// dec - (in) decoder instance to get information from.
+// info - (out) global information fetched from the animation.
+// Returns:
+// True on success.
+WEBP_EXTERN(int) WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec,
+ WebPAnimInfo* info);
+
+// Fetch the next frame from 'dec' based on options supplied to
+// WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size
+// 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The
+// returned buffer 'buf' is valid only until the next call to
+// WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete().
+// Parameters:
+// dec - (in/out) decoder instance from which the next frame is to be fetched.
+// buf - (out) decoded frame.
+// timestamp - (out) timestamp of the frame in milliseconds.
+// Returns:
+// False if any of the arguments are NULL, or if there is a parsing or
+// decoding error, or if there are no more frames. Otherwise, returns true.
+WEBP_EXTERN(int) WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
+ uint8_t** buf, int* timestamp);
+
+// Check if there are more frames left to decode.
+// Parameters:
+// dec - (in) decoder instance to be checked.
+// Returns:
+// True if 'dec' is not NULL and some frames are yet to be decoded.
+// Otherwise, returns false.
+WEBP_EXTERN(int) WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec);
+
+// Resets the WebPAnimDecoder object, so that next call to
+// WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be
+// helpful when all frames need to be decoded multiple times (e.g.
+// info.loop_count times) without destroying and recreating the 'dec' object.
+// Parameters:
+// dec - (in/out) decoder instance to be reset
+WEBP_EXTERN(void) WebPAnimDecoderReset(WebPAnimDecoder* dec);
+
+// Grab the internal demuxer object.
+// Getting the demuxer object can be useful if one wants to use operations only
+// available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned
+// demuxer object is owned by 'dec' and is valid only until the next call to
+// WebPAnimDecoderDelete().
+//
+// Parameters:
+// dec - (in) decoder instance from which the demuxer object is to be fetched.
+WEBP_EXTERN(const WebPDemuxer*) WebPAnimDecoderGetDemuxer(
+ const WebPAnimDecoder* dec);
+
+// Deletes the WebPAnimDecoder object.
+// Parameters:
+// dec - (in/out) decoder instance to be deleted
+WEBP_EXTERN(void) WebPAnimDecoderDelete(WebPAnimDecoder* dec);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_DEMUX_H_ */
diff --git a/media/libwebp/webp/encode.h b/media/libwebp/webp/encode.h
new file mode 100644
index 000000000..35fde1d05
--- /dev/null
+++ b/media/libwebp/webp/encode.h
@@ -0,0 +1,542 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// WebP encoder: main interface
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_ENCODE_H_
+#define WEBP_WEBP_ENCODE_H_
+
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPImageHint WebPImageHint;
+// typedef enum WebPEncCSP WebPEncCSP;
+// typedef enum WebPPreset WebPPreset;
+// typedef enum WebPEncodingError WebPEncodingError;
+typedef struct WebPConfig WebPConfig;
+typedef struct WebPPicture WebPPicture; // main structure for I/O
+typedef struct WebPAuxStats WebPAuxStats;
+typedef struct WebPMemoryWriter WebPMemoryWriter;
+
+// Return the encoder's version number, packed in hexadecimal using 8bits for
+// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetEncoderVersion(void);
+
+//------------------------------------------------------------------------------
+// One-stop-shop call! No questions asked:
+
+// Returns the size of the compressed data (pointed to by *output), or 0 if
+// an error occurred. The compressed data must be released by the caller
+// using the call 'WebPFree(*output)'.
+// These functions compress using the lossy format, and the quality_factor
+// can go from 0 (smaller output, lower quality) to 100 (best quality,
+// larger output).
+WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeBGR(const uint8_t* bgr,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeRGBA(const uint8_t* rgba,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+
+// These functions are the equivalent of the above, but compressing in a
+// lossless manner. Files are usually larger than lossy format, but will
+// not suffer any compression loss.
+WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb,
+ int width, int height, int stride,
+ uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr,
+ int width, int height, int stride,
+ uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba,
+ int width, int height, int stride,
+ uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra,
+ int width, int height, int stride,
+ uint8_t** output);
+
+// Releases memory returned by the WebPEncode*() functions above.
+WEBP_EXTERN(void) WebPFree(void* ptr);
+
+//------------------------------------------------------------------------------
+// Coding parameters
+
+// Image characteristics hint for the underlying encoder.
+typedef enum WebPImageHint {
+ WEBP_HINT_DEFAULT = 0, // default preset.
+ WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot
+ WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting
+ WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc).
+ WEBP_HINT_LAST
+} WebPImageHint;
+
+// Compression parameters.
+struct WebPConfig {
+ int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
+ float quality; // between 0 (smallest file) and 100 (biggest)
+ int method; // quality/speed trade-off (0=fast, 6=slower-better)
+
+ WebPImageHint image_hint; // Hint for image type (lossless only for now).
+
+ // Parameters related to lossy compression only:
+ int target_size; // if non-zero, set the desired target size in bytes.
+ // Takes precedence over the 'compression' parameter.
+ float target_PSNR; // if non-zero, specifies the minimal distortion to
+ // try to achieve. Takes precedence over target_size.
+ int segments; // maximum number of segments to use, in [1..4]
+ int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
+ int filter_strength; // range: [0 = off .. 100 = strongest]
+ int filter_sharpness; // range: [0 = off .. 7 = least sharp]
+ int filter_type; // filtering type: 0 = simple, 1 = strong (only used
+ // if filter_strength > 0 or autofilter > 0)
+ int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
+ int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
+ // 1 = compressed with WebP lossless). Default is 1.
+ int alpha_filtering; // Predictive filtering method for alpha plane.
+ // 0: none, 1: fast, 2: best. Default if 1.
+ int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
+ // Default is 100.
+ int pass; // number of entropy-analysis passes (in [1..10]).
+
+ int show_compressed; // if true, export the compressed picture back.
+ // In-loop filtering is not applied.
+ int preprocessing; // preprocessing filter:
+ // 0=none, 1=segment-smooth, 2=pseudo-random dithering
+ int partitions; // log2(number of token partitions) in [0..3]. Default
+ // is set to 0 for easier progressive decoding.
+ int partition_limit; // quality degradation allowed to fit the 512k limit
+ // on prediction modes coding (0: no degradation,
+ // 100: maximum possible degradation).
+ int emulate_jpeg_size; // If true, compression parameters will be remapped
+ // to better match the expected output size from
+ // JPEG compression. Generally, the output size will
+ // be similar but the degradation will be lower.
+ int thread_level; // If non-zero, try and use multi-threaded encoding.
+ int low_memory; // If set, reduce memory usage (but increase CPU use).
+
+ int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off
+ // (default)].
+ int exact; // if non-zero, preserve the exact RGB values under
+ // transparent area. Otherwise, discard this invisible
+ // RGB information for better compression. The default
+ // value is 0.
+
+ int use_delta_palette; // reserved for future lossless feature
+ int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion
+
+ uint32_t pad[2]; // padding for later use
+};
+
+// Enumerate some predefined settings for WebPConfig, depending on the type
+// of source picture. These presets are used when calling WebPConfigPreset().
+typedef enum WebPPreset {
+ WEBP_PRESET_DEFAULT = 0, // default preset.
+ WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot
+ WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting
+ WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details
+ WEBP_PRESET_ICON, // small-sized colorful images
+ WEBP_PRESET_TEXT // text-like
+} WebPPreset;
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
+
+// Should always be called, to initialize a fresh WebPConfig structure before
+// modification. Returns false in case of version mismatch. WebPConfigInit()
+// must have succeeded before using the 'config' object.
+// Note that the default values are lossless=0 and quality=75.
+static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
+ return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
+ WEBP_ENCODER_ABI_VERSION);
+}
+
+// This function will initialize the configuration according to a predefined
+// set of parameters (referred to by 'preset') and a given quality factor.
+// This function can be called as a replacement to WebPConfigInit(). Will
+// return false in case of error.
+static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
+ WebPPreset preset, float quality) {
+ return WebPConfigInitInternal(config, preset, quality,
+ WEBP_ENCODER_ABI_VERSION);
+}
+
+// Activate the lossless compression mode with the desired efficiency level
+// between 0 (fastest, lowest compression) and 9 (slower, best compression).
+// A good default level is '6', providing a fair tradeoff between compression
+// speed and final compressed size.
+// This function will overwrite several fields from config: 'method', 'quality'
+// and 'lossless'. Returns false in case of parameter error.
+WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level);
+
+// Returns true if 'config' is non-NULL and all configuration parameters are
+// within their valid ranges.
+WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config);
+
+//------------------------------------------------------------------------------
+// Input / Output
+// Structure for storing auxiliary statistics (mostly for lossy encoding).
+
+struct WebPAuxStats {
+ int coded_size; // final size
+
+ float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha
+ int block_count[3]; // number of intra4/intra16/skipped macroblocks
+ int header_bytes[2]; // approximate number of bytes spent for header
+ // and mode-partition #0
+ int residual_bytes[3][4]; // approximate number of bytes spent for
+ // DC/AC/uv coefficients for each (0..3) segments.
+ int segment_size[4]; // number of macroblocks in each segments
+ int segment_quant[4]; // quantizer values for each segments
+ int segment_level[4]; // filtering strength for each segments [0..63]
+
+ int alpha_data_size; // size of the transparency data
+ int layer_data_size; // size of the enhancement layer data
+
+ // lossless encoder statistics
+ uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
+ // bit2:subtract-green bit3:color indexing
+ int histogram_bits; // number of precision bits of histogram
+ int transform_bits; // precision bits for transform
+ int cache_bits; // number of bits for color cache lookup
+ int palette_size; // number of color in palette, if used
+ int lossless_size; // final lossless size
+ int lossless_hdr_size; // lossless header (transform, huffman etc) size
+ int lossless_data_size; // lossless image data size
+
+ uint32_t pad[2]; // padding for later use
+};
+
+// Signature for output function. Should return true if writing was successful.
+// data/data_size is the segment of data to write, and 'picture' is for
+// reference (and so one can make use of picture->custom_ptr).
+typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
+ const WebPPicture* picture);
+
+// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
+// the following WebPMemoryWriter object (to be set as a custom_ptr).
+struct WebPMemoryWriter {
+ uint8_t* mem; // final buffer (of size 'max_size', larger than 'size').
+ size_t size; // final size
+ size_t max_size; // total capacity
+ uint32_t pad[1]; // padding for later use
+};
+
+// The following must be called first before any use.
+WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
+
+// The following must be called to deallocate writer->mem memory. The 'writer'
+// object itself is not deallocated.
+WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer);
+// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
+// completion, writer.mem and writer.size will hold the coded data.
+// writer.mem must be freed by calling WebPMemoryWriterClear.
+WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
+ const WebPPicture* picture);
+
+// Progress hook, called from time to time to report progress. It can return
+// false to request an abort of the encoding process, or true otherwise if
+// everything is OK.
+typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
+
+// Color spaces.
+typedef enum WebPEncCSP {
+ // chroma sampling
+ WEBP_YUV420 = 0, // 4:2:0
+ WEBP_YUV420A = 4, // alpha channel variant
+ WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors
+ WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present
+} WebPEncCSP;
+
+// Encoding error conditions.
+typedef enum WebPEncodingError {
+ VP8_ENC_OK = 0,
+ VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects
+ VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits
+ VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL
+ VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid
+ VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height
+ VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k
+ VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M
+ VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes
+ VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G
+ VP8_ENC_ERROR_USER_ABORT, // abort request by user
+ VP8_ENC_ERROR_LAST // list terminator. always last.
+} WebPEncodingError;
+
+// maximum width/height allowed (inclusive), in pixels
+#define WEBP_MAX_DIMENSION 16383
+
+// Main exchange structure (input samples, output bytes, statistics)
+struct WebPPicture {
+ // INPUT
+ //////////////
+ // Main flag for encoder selecting between ARGB or YUV input.
+ // It is recommended to use ARGB input (*argb, argb_stride) for lossless
+ // compression, and YUV input (*y, *u, *v, etc.) for lossy compression
+ // since these are the respective native colorspace for these formats.
+ int use_argb;
+
+ // YUV input (mostly used for input to lossy compression)
+ WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr).
+ int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
+ uint8_t *y, *u, *v; // pointers to luma/chroma planes.
+ int y_stride, uv_stride; // luma/chroma strides.
+ uint8_t* a; // pointer to the alpha plane
+ int a_stride; // stride of the alpha plane
+ uint32_t pad1[2]; // padding for later use
+
+ // ARGB input (mostly used for input to lossless compression)
+ uint32_t* argb; // Pointer to argb (32 bit) plane.
+ int argb_stride; // This is stride in pixels units, not bytes.
+ uint32_t pad2[3]; // padding for later use
+
+ // OUTPUT
+ ///////////////
+ // Byte-emission hook, to store compressed bytes as they are ready.
+ WebPWriterFunction writer; // can be NULL
+ void* custom_ptr; // can be used by the writer.
+
+ // map for extra information (only for lossy compression mode)
+ int extra_info_type; // 1: intra type, 2: segment, 3: quant
+ // 4: intra-16 prediction mode,
+ // 5: chroma prediction mode,
+ // 6: bit cost, 7: distortion
+ uint8_t* extra_info; // if not NULL, points to an array of size
+ // ((width + 15) / 16) * ((height + 15) / 16) that
+ // will be filled with a macroblock map, depending
+ // on extra_info_type.
+
+ // STATS AND REPORTS
+ ///////////////////////////
+ // Pointer to side statistics (updated only if not NULL)
+ WebPAuxStats* stats;
+
+ // Error code for the latest error encountered during encoding
+ WebPEncodingError error_code;
+
+ // If not NULL, report progress during encoding.
+ WebPProgressHook progress_hook;
+
+ void* user_data; // this field is free to be set to any value and
+ // used during callbacks (like progress-report e.g.).
+
+ uint32_t pad3[3]; // padding for later use
+
+ // Unused for now
+ uint8_t *pad4, *pad5;
+ uint32_t pad6[8]; // padding for later use
+
+ // PRIVATE FIELDS
+ ////////////////////
+ void* memory_; // row chunk of memory for yuva planes
+ void* memory_argb_; // and for argb too.
+ void* pad7[2]; // padding for later use
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int);
+
+// Should always be called, to initialize the structure. Returns false in case
+// of version mismatch. WebPPictureInit() must have succeeded before using the
+// 'picture' object.
+// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
+static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
+ return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
+}
+
+//------------------------------------------------------------------------------
+// WebPPicture utils
+
+// Convenience allocation / deallocation based on picture->width/height:
+// Allocate y/u/v buffers as per colorspace/width/height specification.
+// Note! This function will free the previous buffer if needed.
+// Returns false in case of memory error.
+WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture);
+
+// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
+// Note that this function does _not_ free the memory used by the 'picture'
+// object itself.
+// Besides memory (which is reclaimed) all other fields of 'picture' are
+// preserved.
+WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture);
+
+// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst
+// will fully own the copied pixels (this is not a view). The 'dst' picture need
+// not be initialized as its content is overwritten.
+// Returns false in case of memory allocation error.
+WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
+
+// Compute the single distortion for packed planes of samples.
+// 'src' will be compared to 'ref', and the raw distortion stored into
+// '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be
+// stored in '*result'.
+// 'x_step' is the horizontal stride (in bytes) between samples.
+// 'src/ref_stride' is the byte distance between rows.
+// Returns false in case of error (bad parameter, memory allocation error, ...).
+WEBP_EXTERN(int) WebPPlaneDistortion(const uint8_t* src, size_t src_stride,
+ const uint8_t* ref, size_t ref_stride,
+ int width, int height,
+ size_t x_step,
+ int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
+ float* distortion, float* result);
+
+// Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results
+// are in dB, stored in result[] in the B/G/R/A/All order. The distortion is
+// always performed using ARGB samples. Hence if the input is YUV(A), the
+// picture will be internally converted to ARGB (just for the measurement).
+// Warning: this function is rather CPU-intensive.
+WEBP_EXTERN(int) WebPPictureDistortion(
+ const WebPPicture* src, const WebPPicture* ref,
+ int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
+ float result[5]);
+
+// self-crops a picture to the rectangle defined by top/left/width/height.
+// Returns false in case of memory allocation error, or if the rectangle is
+// outside of the source picture.
+// The rectangle for the view is defined by the top-left corner pixel
+// coordinates (left, top) as well as its width and height. This rectangle
+// must be fully be comprised inside the 'src' source picture. If the source
+// picture uses the YUV420 colorspace, the top and left coordinates will be
+// snapped to even values.
+WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture,
+ int left, int top, int width, int height);
+
+// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
+// is defined by the top-left corner pixel coordinates (left, top) as well
+// as its width and height. This rectangle must be fully be comprised inside
+// the 'src' source picture. If the source picture uses the YUV420 colorspace,
+// the top and left coordinates will be snapped to even values.
+// Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
+// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
+// the original dimension will be lost). Picture 'dst' need not be initialized
+// with WebPPictureInit() if it is different from 'src', since its content will
+// be overwritten.
+// Returns false in case of memory allocation error or invalid parameters.
+WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src,
+ int left, int top, int width, int height,
+ WebPPicture* dst);
+
+// Returns true if the 'picture' is actually a view and therefore does
+// not own the memory for pixels.
+WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture);
+
+// Rescale a picture to new dimension width x height.
+// If either 'width' or 'height' (but not both) is 0 the corresponding
+// dimension will be calculated preserving the aspect ratio.
+// No gamma correction is applied.
+// Returns false in case of error (invalid parameter or insufficient memory).
+WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height);
+
+// Colorspace conversion function to import RGB samples.
+// Previous buffer will be free'd, if any.
+// *rgb buffer should have a size of at least height * rgb_stride.
+// Returns false in case of memory error.
+WEBP_EXTERN(int) WebPPictureImportRGB(
+ WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
+// Same, but for RGBA buffer.
+WEBP_EXTERN(int) WebPPictureImportRGBA(
+ WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
+// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
+// input buffer ignoring the alpha channel. Avoids needing to copy the data
+// to a temporary 24-bit RGB buffer to import the RGB only.
+WEBP_EXTERN(int) WebPPictureImportRGBX(
+ WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
+
+// Variants of the above, but taking BGR(A|X) input.
+WEBP_EXTERN(int) WebPPictureImportBGR(
+ WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
+WEBP_EXTERN(int) WebPPictureImportBGRA(
+ WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
+WEBP_EXTERN(int) WebPPictureImportBGRX(
+ WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
+
+// Converts picture->argb data to the YUV420A format. The 'colorspace'
+// parameter is deprecated and should be equal to WEBP_YUV420.
+// Upon return, picture->use_argb is set to false. The presence of real
+// non-opaque transparent values is detected, and 'colorspace' will be
+// adjusted accordingly. Note that this method is lossy.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture,
+ WebPEncCSP /*colorspace = WEBP_YUV420*/);
+
+// Same as WebPPictureARGBToYUVA(), but the conversion is done using
+// pseudo-random dithering with a strength 'dithering' between
+// 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
+// for photographic picture.
+WEBP_EXTERN(int) WebPPictureARGBToYUVADithered(
+ WebPPicture* picture, WebPEncCSP colorspace, float dithering);
+
+// Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion.
+// Downsampling is handled with extra care in case of color clipping. This
+// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
+// and sharper YUV representation.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureSharpARGBToYUVA(WebPPicture* picture);
+// kept for backward compatibility:
+WEBP_EXTERN(int) WebPPictureSmartARGBToYUVA(WebPPicture* picture);
+
+// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
+// The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to
+// ARGB incurs a small loss too.
+// Note that the use of this colorspace is discouraged if one has access to the
+// raw ARGB samples, since using YUV420 is comparatively lossy.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture);
+
+// Helper function: given a width x height plane of RGBA or YUV(A) samples
+// clean-up the YUV or RGB samples under fully transparent area, to help
+// compressibility (no guarantee, though).
+WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture);
+
+// Scan the picture 'picture' for the presence of non fully opaque alpha values.
+// Returns true in such case. Otherwise returns false (indicating that the
+// alpha plane can be ignored altogether e.g.).
+WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture);
+
+// Remove the transparency information (if present) by blending the color with
+// the background color 'background_rgb' (specified as 24bit RGB triplet).
+// After this call, all alpha values are reset to 0xff.
+WEBP_EXTERN(void) WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
+
+//------------------------------------------------------------------------------
+// Main call
+
+// Main encoding call, after config and picture have been initialized.
+// 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
+// and the 'config' object must be a valid one.
+// Returns false in case of error, true otherwise.
+// In case of error, picture->error_code is updated accordingly.
+// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
+// on the value of 'picture->use_argb'. It is highly recommended to use
+// the former for lossy encoding, and the latter for lossless encoding
+// (when config.lossless is true). Automatic conversion from one format to
+// another is provided but they both incur some loss.
+WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_ENCODE_H_ */
diff --git a/media/libwebp/webp/format_constants.h b/media/libwebp/webp/format_constants.h
new file mode 100644
index 000000000..329fc8a3b
--- /dev/null
+++ b/media/libwebp/webp/format_constants.h
@@ -0,0 +1,87 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Internal header for constants related to WebP file format.
+//
+// Author: Urvang (urvang@google.com)
+
+#ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_
+#define WEBP_WEBP_FORMAT_CONSTANTS_H_
+
+// Create fourcc of the chunk from the chunk tag characters.
+#define MKFOURCC(a, b, c, d) ((a) | (b) << 8 | (c) << 16 | (uint32_t)(d) << 24)
+
+// VP8 related constants.
+#define VP8_SIGNATURE 0x9d012a // Signature in VP8 data.
+#define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition
+#define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition
+#define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data.
+
+// VP8L related constants.
+#define VP8L_SIGNATURE_SIZE 1 // VP8L signature size.
+#define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte.
+#define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store
+ // width and height.
+#define VP8L_VERSION_BITS 3 // 3 bits reserved for version.
+#define VP8L_VERSION 0 // version 0
+#define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header.
+
+#define MAX_PALETTE_SIZE 256
+#define MAX_CACHE_BITS 11
+#define HUFFMAN_CODES_PER_META_CODE 5
+#define ARGB_BLACK 0xff000000
+
+#define DEFAULT_CODE_LENGTH 8
+#define MAX_ALLOWED_CODE_LENGTH 15
+
+#define NUM_LITERAL_CODES 256
+#define NUM_LENGTH_CODES 24
+#define NUM_DISTANCE_CODES 40
+#define CODE_LENGTH_CODES 19
+
+#define MIN_HUFFMAN_BITS 2 // min number of Huffman bits
+#define MAX_HUFFMAN_BITS 9 // max number of Huffman bits
+
+#define TRANSFORM_PRESENT 1 // The bit to be written when next data
+ // to be read is a transform.
+#define NUM_TRANSFORMS 4 // Maximum number of allowed transform
+ // in a bitstream.
+typedef enum {
+ PREDICTOR_TRANSFORM = 0,
+ CROSS_COLOR_TRANSFORM = 1,
+ SUBTRACT_GREEN = 2,
+ COLOR_INDEXING_TRANSFORM = 3
+} VP8LImageTransformType;
+
+// Alpha related constants.
+#define ALPHA_HEADER_LEN 1
+#define ALPHA_NO_COMPRESSION 0
+#define ALPHA_LOSSLESS_COMPRESSION 1
+#define ALPHA_PREPROCESSED_LEVELS 1
+
+// Mux related constants.
+#define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L").
+#define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size.
+#define CHUNK_HEADER_SIZE 8 // Size of a chunk header.
+#define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP").
+#define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk.
+#define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk.
+#define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk.
+
+#define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height.
+#define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height.
+#define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count
+#define MAX_DURATION (1 << 24) // maximum duration
+#define MAX_POSITION_OFFSET (1 << 24) // maximum frame x/y offset
+
+// Maximum chunk payload is such that adding the header and padding won't
+// overflow a uint32_t.
+#define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1)
+
+#endif /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */
diff --git a/media/libwebp/webp/mux.h b/media/libwebp/webp/mux.h
new file mode 100644
index 000000000..daccc65e8
--- /dev/null
+++ b/media/libwebp/webp/mux.h
@@ -0,0 +1,530 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// RIFF container manipulation and encoding for WebP images.
+//
+// Authors: Urvang (urvang@google.com)
+// Vikas (vikasa@google.com)
+
+#ifndef WEBP_WEBP_MUX_H_
+#define WEBP_WEBP_MUX_H_
+
+#include "./mux_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_MUX_ABI_VERSION 0x0108 // MAJOR(8b) + MINOR(8b)
+
+//------------------------------------------------------------------------------
+// Mux API
+//
+// This API allows manipulation of WebP container images containing features
+// like color profile, metadata, animation.
+//
+// Code Example#1: Create a WebPMux object with image data, color profile and
+// XMP metadata.
+/*
+ int copy_data = 0;
+ WebPMux* mux = WebPMuxNew();
+ // ... (Prepare image data).
+ WebPMuxSetImage(mux, &image, copy_data);
+ // ... (Prepare ICCP color profile data).
+ WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+ // ... (Prepare XMP metadata).
+ WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
+ // Get data from mux in WebP RIFF format.
+ WebPMuxAssemble(mux, &output_data);
+ WebPMuxDelete(mux);
+ // ... (Consume output_data; e.g. write output_data.bytes to file).
+ WebPDataClear(&output_data);
+*/
+
+// Code Example#2: Get image and color profile data from a WebP file.
+/*
+ int copy_data = 0;
+ // ... (Read data from file).
+ WebPMux* mux = WebPMuxCreate(&data, copy_data);
+ WebPMuxGetFrame(mux, 1, &image);
+ // ... (Consume image; e.g. call WebPDecode() to decode the data).
+ WebPMuxGetChunk(mux, "ICCP", &icc_profile);
+ // ... (Consume icc_data).
+ WebPMuxDelete(mux);
+ free(data);
+*/
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPMuxError WebPMuxError;
+// typedef enum WebPChunkId WebPChunkId;
+typedef struct WebPMux WebPMux; // main opaque object.
+typedef struct WebPMuxFrameInfo WebPMuxFrameInfo;
+typedef struct WebPMuxAnimParams WebPMuxAnimParams;
+typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions;
+
+// Error codes
+typedef enum WebPMuxError {
+ WEBP_MUX_OK = 1,
+ WEBP_MUX_NOT_FOUND = 0,
+ WEBP_MUX_INVALID_ARGUMENT = -1,
+ WEBP_MUX_BAD_DATA = -2,
+ WEBP_MUX_MEMORY_ERROR = -3,
+ WEBP_MUX_NOT_ENOUGH_DATA = -4
+} WebPMuxError;
+
+// IDs for different types of chunks.
+typedef enum WebPChunkId {
+ WEBP_CHUNK_VP8X, // VP8X
+ WEBP_CHUNK_ICCP, // ICCP
+ WEBP_CHUNK_ANIM, // ANIM
+ WEBP_CHUNK_ANMF, // ANMF
+ WEBP_CHUNK_DEPRECATED, // (deprecated from FRGM)
+ WEBP_CHUNK_ALPHA, // ALPH
+ WEBP_CHUNK_IMAGE, // VP8/VP8L
+ WEBP_CHUNK_EXIF, // EXIF
+ WEBP_CHUNK_XMP, // XMP
+ WEBP_CHUNK_UNKNOWN, // Other chunks.
+ WEBP_CHUNK_NIL
+} WebPChunkId;
+
+//------------------------------------------------------------------------------
+
+// Returns the version number of the mux library, packed in hexadecimal using
+// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetMuxVersion(void);
+
+//------------------------------------------------------------------------------
+// Life of a Mux object
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPMux*) WebPNewInternal(int);
+
+// Creates an empty mux object.
+// Returns:
+// A pointer to the newly created empty mux object.
+// Or NULL in case of memory error.
+static WEBP_INLINE WebPMux* WebPMuxNew(void) {
+ return WebPNewInternal(WEBP_MUX_ABI_VERSION);
+}
+
+// Deletes the mux object.
+// Parameters:
+// mux - (in/out) object to be deleted
+WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux);
+
+//------------------------------------------------------------------------------
+// Mux creation.
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int);
+
+// Creates a mux object from raw data given in WebP RIFF format.
+// Parameters:
+// bitstream - (in) the bitstream data in WebP RIFF format
+// copy_data - (in) value 1 indicates given data WILL be copied to the mux
+// object and value 0 indicates data will NOT be copied.
+// Returns:
+// A pointer to the mux object created from given data - on success.
+// NULL - In case of invalid data or memory error.
+static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
+ int copy_data) {
+ return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
+}
+
+//------------------------------------------------------------------------------
+// Non-image chunks.
+
+// Note: Only non-image related chunks should be managed through chunk APIs.
+// (Image related chunks are: "ANMF", "VP8 ", "VP8L" and "ALPH").
+// To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(),
+// WebPMuxGetFrame() and WebPMuxDeleteFrame().
+
+// Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object.
+// Any existing chunk(s) with the same id will be removed.
+// Parameters:
+// mux - (in/out) object to which the chunk is to be added
+// fourcc - (in) a character array containing the fourcc of the given chunk;
+// e.g., "ICCP", "XMP ", "EXIF" etc.
+// chunk_data - (in) the chunk data to be added
+// copy_data - (in) value 1 indicates given data WILL be copied to the mux
+// object and value 0 indicates data will NOT be copied.
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
+// or if fourcc corresponds to an image chunk.
+// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk(
+ WebPMux* mux, const char fourcc[4], const WebPData* chunk_data,
+ int copy_data);
+
+// Gets a reference to the data of the chunk with id 'fourcc' in the mux object.
+// The caller should NOT free the returned data.
+// Parameters:
+// mux - (in) object from which the chunk data is to be fetched
+// fourcc - (in) a character array containing the fourcc of the chunk;
+// e.g., "ICCP", "XMP ", "EXIF" etc.
+// chunk_data - (out) returned chunk data
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
+// or if fourcc corresponds to an image chunk.
+// WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk(
+ const WebPMux* mux, const char fourcc[4], WebPData* chunk_data);
+
+// Deletes the chunk with the given 'fourcc' from the mux object.
+// Parameters:
+// mux - (in/out) object from which the chunk is to be deleted
+// fourcc - (in) a character array containing the fourcc of the chunk;
+// e.g., "ICCP", "XMP ", "EXIF" etc.
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
+// or if fourcc corresponds to an image chunk.
+// WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxDeleteChunk(
+ WebPMux* mux, const char fourcc[4]);
+
+//------------------------------------------------------------------------------
+// Images.
+
+// Encapsulates data about a single frame.
+struct WebPMuxFrameInfo {
+ WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream
+ // or a single-image WebP file.
+ int x_offset; // x-offset of the frame.
+ int y_offset; // y-offset of the frame.
+ int duration; // duration of the frame (in milliseconds).
+
+ WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF
+ // or WEBP_CHUNK_IMAGE
+ WebPMuxAnimDispose dispose_method; // Disposal method for the frame.
+ WebPMuxAnimBlend blend_method; // Blend operation for the frame.
+ uint32_t pad[1]; // padding for later use
+};
+
+// Sets the (non-animated) image in the mux object.
+// Note: Any existing images (including frames) will be removed.
+// Parameters:
+// mux - (in/out) object in which the image is to be set
+// bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image
+// WebP file (non-animated)
+// copy_data - (in) value 1 indicates given data WILL be copied to the mux
+// object and value 0 indicates data will NOT be copied.
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
+// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(
+ WebPMux* mux, const WebPData* bitstream, int copy_data);
+
+// Adds a frame at the end of the mux object.
+// Notes: (1) frame.id should be WEBP_CHUNK_ANMF
+// (2) For setting a non-animated image, use WebPMuxSetImage() instead.
+// (3) Type of frame being pushed must be same as the frames in mux.
+// (4) As WebP only supports even offsets, any odd offset will be snapped
+// to an even location using: offset &= ~1
+// Parameters:
+// mux - (in/out) object to which the frame is to be added
+// frame - (in) frame data.
+// copy_data - (in) value 1 indicates given data WILL be copied to the mux
+// object and value 0 indicates data will NOT be copied.
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL
+// or if content of 'frame' is invalid.
+// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame(
+ WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);
+
+// Gets the nth frame from the mux object.
+// The content of 'frame->bitstream' is allocated using malloc(), and NOT
+// owned by the 'mux' object. It MUST be deallocated by the caller by calling
+// WebPDataClear().
+// nth=0 has a special meaning - last position.
+// Parameters:
+// mux - (in) object from which the info is to be fetched
+// nth - (in) index of the frame in the mux object
+// frame - (out) data of the returned frame
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL.
+// WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object.
+// WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
+// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(
+ const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame);
+
+// Deletes a frame from the mux object.
+// nth=0 has a special meaning - last position.
+// Parameters:
+// mux - (in/out) object from which a frame is to be deleted
+// nth - (in) The position from which the frame is to be deleted
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL.
+// WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
+// before deletion.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);
+
+//------------------------------------------------------------------------------
+// Animation.
+
+// Animation parameters.
+struct WebPMuxAnimParams {
+ uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as:
+ // Bits 00 to 07: Alpha.
+ // Bits 08 to 15: Red.
+ // Bits 16 to 23: Green.
+ // Bits 24 to 31: Blue.
+ int loop_count; // Number of times to repeat the animation [0 = infinite].
+};
+
+// Sets the animation parameters in the mux object. Any existing ANIM chunks
+// will be removed.
+// Parameters:
+// mux - (in/out) object in which ANIM chunk is to be set/added
+// params - (in) animation parameters.
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
+// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetAnimationParams(
+ WebPMux* mux, const WebPMuxAnimParams* params);
+
+// Gets the animation parameters from the mux object.
+// Parameters:
+// mux - (in) object from which the animation parameters to be fetched
+// params - (out) animation parameters extracted from the ANIM chunk
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
+// WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams(
+ const WebPMux* mux, WebPMuxAnimParams* params);
+
+//------------------------------------------------------------------------------
+// Misc Utilities.
+
+// Sets the canvas size for the mux object. The width and height can be
+// specified explicitly or left as zero (0, 0).
+// * When width and height are specified explicitly, then this frame bound is
+// enforced during subsequent calls to WebPMuxAssemble() and an error is
+// reported if any animated frame does not completely fit within the canvas.
+// * When unspecified (0, 0), the constructed canvas will get the frame bounds
+// from the bounding-box over all frames after calling WebPMuxAssemble().
+// Parameters:
+// mux - (in) object to which the canvas size is to be set
+// width - (in) canvas width
+// height - (in) canvas height
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or
+// width or height are invalid or out of bounds
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxSetCanvasSize(WebPMux* mux,
+ int width, int height);
+
+// Gets the canvas size from the mux object.
+// Note: This method assumes that the VP8X chunk, if present, is up-to-date.
+// That is, the mux object hasn't been modified since the last call to
+// WebPMuxAssemble() or WebPMuxCreate().
+// Parameters:
+// mux - (in) object from which the canvas size is to be fetched
+// width - (out) canvas width
+// height - (out) canvas height
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL.
+// WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetCanvasSize(const WebPMux* mux,
+ int* width, int* height);
+
+// Gets the feature flags from the mux object.
+// Note: This method assumes that the VP8X chunk, if present, is up-to-date.
+// That is, the mux object hasn't been modified since the last call to
+// WebPMuxAssemble() or WebPMuxCreate().
+// Parameters:
+// mux - (in) object from which the features are to be fetched
+// flags - (out) the flags specifying which features are present in the
+// mux object. This will be an OR of various flag values.
+// Enum 'WebPFeatureFlags' can be used to test individual flag values.
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL.
+// WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux,
+ uint32_t* flags);
+
+// Gets number of chunks with the given 'id' in the mux object.
+// Parameters:
+// mux - (in) object from which the info is to be fetched
+// id - (in) chunk id specifying the type of chunk
+// num_elements - (out) number of chunks with the given chunk id
+// Returns:
+// WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux,
+ WebPChunkId id, int* num_elements);
+
+// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
+// This function also validates the mux object.
+// Note: The content of 'assembled_data' will be ignored and overwritten.
+// Also, the content of 'assembled_data' is allocated using malloc(), and NOT
+// owned by the 'mux' object. It MUST be deallocated by the caller by calling
+// WebPDataClear(). It's always safe to call WebPDataClear() upon return,
+// even in case of error.
+// Parameters:
+// mux - (in/out) object whose chunks are to be assembled
+// assembled_data - (out) assembled WebP data
+// Returns:
+// WEBP_MUX_BAD_DATA - if mux object is invalid.
+// WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL.
+// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
+// WEBP_MUX_OK - on success.
+WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux,
+ WebPData* assembled_data);
+
+//------------------------------------------------------------------------------
+// WebPAnimEncoder API
+//
+// This API allows encoding (possibly) animated WebP images.
+//
+// Code Example:
+/*
+ WebPAnimEncoderOptions enc_options;
+ WebPAnimEncoderOptionsInit(&enc_options);
+ // Tune 'enc_options' as needed.
+ WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
+ while(<there are more frames>) {
+ WebPConfig config;
+ WebPConfigInit(&config);
+ // Tune 'config' as needed.
+ WebPAnimEncoderAdd(enc, frame, timestamp_ms, &config);
+ }
+ WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL);
+ WebPAnimEncoderAssemble(enc, webp_data);
+ WebPAnimEncoderDelete(enc);
+ // Write the 'webp_data' to a file, or re-mux it further.
+*/
+
+typedef struct WebPAnimEncoder WebPAnimEncoder; // Main opaque object.
+
+// Forward declarations. Defined in encode.h.
+struct WebPPicture;
+struct WebPConfig;
+
+// Global options.
+struct WebPAnimEncoderOptions {
+ WebPMuxAnimParams anim_params; // Animation parameters.
+ int minimize_size; // If true, minimize the output size (slow). Implicitly
+ // disables key-frame insertion.
+ int kmin;
+ int kmax; // Minimum and maximum distance between consecutive key
+ // frames in the output. The library may insert some key
+ // frames as needed to satisfy this criteria.
+ // Note that these conditions should hold: kmax > kmin
+ // and kmin >= kmax / 2 + 1. Also, if kmax <= 0, then
+ // key-frame insertion is disabled; and if kmax == 1,
+ // then all frames will be key-frames (kmin value does
+ // not matter for these special cases).
+ int allow_mixed; // If true, use mixed compression mode; may choose
+ // either lossy and lossless for each frame.
+ int verbose; // If true, print info and warning messages to stderr.
+
+ uint32_t padding[4]; // Padding for later use.
+};
+
+// Internal, version-checked, entry point.
+WEBP_EXTERN(int) WebPAnimEncoderOptionsInitInternal(
+ WebPAnimEncoderOptions*, int);
+
+// Should always be called, to initialize a fresh WebPAnimEncoderOptions
+// structure before modification. Returns false in case of version mismatch.
+// WebPAnimEncoderOptionsInit() must have succeeded before using the
+// 'enc_options' object.
+static WEBP_INLINE int WebPAnimEncoderOptionsInit(
+ WebPAnimEncoderOptions* enc_options) {
+ return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION);
+}
+
+// Internal, version-checked, entry point.
+WEBP_EXTERN(WebPAnimEncoder*) WebPAnimEncoderNewInternal(
+ int, int, const WebPAnimEncoderOptions*, int);
+
+// Creates and initializes a WebPAnimEncoder object.
+// Parameters:
+// width/height - (in) canvas width and height of the animation.
+// enc_options - (in) encoding options; can be passed NULL to pick
+// reasonable defaults.
+// Returns:
+// A pointer to the newly created WebPAnimEncoder object.
+// Or NULL in case of memory error.
+static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew(
+ int width, int height, const WebPAnimEncoderOptions* enc_options) {
+ return WebPAnimEncoderNewInternal(width, height, enc_options,
+ WEBP_MUX_ABI_VERSION);
+}
+
+// Optimize the given frame for WebP, encode it and add it to the
+// WebPAnimEncoder object.
+// The last call to 'WebPAnimEncoderAdd' should be with frame = NULL, which
+// indicates that no more frames are to be added. This call is also used to
+// determine the duration of the last frame.
+// Parameters:
+// enc - (in/out) object to which the frame is to be added.
+// frame - (in/out) frame data in ARGB or YUV(A) format. If it is in YUV(A)
+// format, it will be converted to ARGB, which incurs a small loss.
+// timestamp_ms - (in) timestamp of this frame in milliseconds.
+// Duration of a frame would be calculated as
+// "timestamp of next frame - timestamp of this frame".
+// Hence, timestamps should be in non-decreasing order.
+// config - (in) encoding options; can be passed NULL to pick
+// reasonable defaults.
+// Returns:
+// On error, returns false and frame->error_code is set appropriately.
+// Otherwise, returns true.
+WEBP_EXTERN(int) WebPAnimEncoderAdd(
+ WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms,
+ const struct WebPConfig* config);
+
+// Assemble all frames added so far into a WebP bitstream.
+// This call should be preceded by a call to 'WebPAnimEncoderAdd' with
+// frame = NULL; if not, the duration of the last frame will be internally
+// estimated.
+// Parameters:
+// enc - (in/out) object from which the frames are to be assembled.
+// webp_data - (out) generated WebP bitstream.
+// Returns:
+// True on success.
+WEBP_EXTERN(int) WebPAnimEncoderAssemble(WebPAnimEncoder* enc,
+ WebPData* webp_data);
+
+// Get error string corresponding to the most recent call using 'enc'. The
+// returned string is owned by 'enc' and is valid only until the next call to
+// WebPAnimEncoderAdd() or WebPAnimEncoderAssemble() or WebPAnimEncoderDelete().
+// Parameters:
+// enc - (in/out) object from which the error string is to be fetched.
+// Returns:
+// NULL if 'enc' is NULL. Otherwise, returns the error string if the last call
+// to 'enc' had an error, or an empty string if the last call was a success.
+WEBP_EXTERN(const char*) WebPAnimEncoderGetError(WebPAnimEncoder* enc);
+
+// Deletes the WebPAnimEncoder object.
+// Parameters:
+// enc - (in/out) object to be deleted
+WEBP_EXTERN(void) WebPAnimEncoderDelete(WebPAnimEncoder* enc);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_MUX_H_ */
diff --git a/media/libwebp/webp/mux_types.h b/media/libwebp/webp/mux_types.h
new file mode 100644
index 000000000..b37e2c67a
--- /dev/null
+++ b/media/libwebp/webp/mux_types.h
@@ -0,0 +1,98 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Data-types common to the mux and demux libraries.
+//
+// Author: Urvang (urvang@google.com)
+
+#ifndef WEBP_WEBP_MUX_TYPES_H_
+#define WEBP_WEBP_MUX_TYPES_H_
+
+#include <stdlib.h> // free()
+#include <string.h> // memset()
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPFeatureFlags WebPFeatureFlags;
+// typedef enum WebPMuxAnimDispose WebPMuxAnimDispose;
+// typedef enum WebPMuxAnimBlend WebPMuxAnimBlend;
+typedef struct WebPData WebPData;
+
+// VP8X Feature Flags.
+typedef enum WebPFeatureFlags {
+ ANIMATION_FLAG = 0x00000002,
+ XMP_FLAG = 0x00000004,
+ EXIF_FLAG = 0x00000008,
+ ALPHA_FLAG = 0x00000010,
+ ICCP_FLAG = 0x00000020,
+
+ ALL_VALID_FLAGS = 0x0000003e
+} WebPFeatureFlags;
+
+// Dispose method (animation only). Indicates how the area used by the current
+// frame is to be treated before rendering the next frame on the canvas.
+typedef enum WebPMuxAnimDispose {
+ WEBP_MUX_DISPOSE_NONE, // Do not dispose.
+ WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color.
+} WebPMuxAnimDispose;
+
+// Blend operation (animation only). Indicates how transparent pixels of the
+// current frame are blended with those of the previous canvas.
+typedef enum WebPMuxAnimBlend {
+ WEBP_MUX_BLEND, // Blend.
+ WEBP_MUX_NO_BLEND // Do not blend.
+} WebPMuxAnimBlend;
+
+// Data type used to describe 'raw' data, e.g., chunk data
+// (ICC profile, metadata) and WebP compressed image data.
+struct WebPData {
+ const uint8_t* bytes;
+ size_t size;
+};
+
+// Initializes the contents of the 'webp_data' object with default values.
+static WEBP_INLINE void WebPDataInit(WebPData* webp_data) {
+ if (webp_data != NULL) {
+ memset(webp_data, 0, sizeof(*webp_data));
+ }
+}
+
+// Clears the contents of the 'webp_data' object by calling free(). Does not
+// deallocate the object itself.
+static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
+ if (webp_data != NULL) {
+ free((void*)webp_data->bytes);
+ WebPDataInit(webp_data);
+ }
+}
+
+// Allocates necessary storage for 'dst' and copies the contents of 'src'.
+// Returns true on success.
+static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
+ if (src == NULL || dst == NULL) return 0;
+ WebPDataInit(dst);
+ if (src->bytes != NULL && src->size != 0) {
+ dst->bytes = (uint8_t*)malloc(src->size);
+ if (dst->bytes == NULL) return 0;
+ memcpy((void*)dst->bytes, src->bytes, src->size);
+ dst->size = src->size;
+ }
+ return 1;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_MUX_TYPES_H_ */
diff --git a/media/libwebp/webp/types.h b/media/libwebp/webp/types.h
new file mode 100644
index 000000000..98fff35a1
--- /dev/null
+++ b/media/libwebp/webp/types.h
@@ -0,0 +1,52 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Common types
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_TYPES_H_
+#define WEBP_WEBP_TYPES_H_
+
+#include <stddef.h> // for size_t
+
+#ifndef _MSC_VER
+#include <inttypes.h>
+#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
+ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+#define WEBP_INLINE inline
+#else
+#define WEBP_INLINE
+#endif
+#else
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long int uint64_t;
+typedef long long int int64_t;
+#define WEBP_INLINE __forceinline
+#endif /* _MSC_VER */
+
+#ifndef WEBP_EXTERN
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define WEBP_EXTERN(type) extern __attribute__ ((visibility ("default"))) type
+# else
+# define WEBP_EXTERN(type) extern type
+# endif /* __GNUC__ >= 4 */
+#endif /* WEBP_EXTERN */
+
+// Macro to check ABI compatibility (same major revision number)
+#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
+
+#endif /* WEBP_WEBP_TYPES_H_ */
diff --git a/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py b/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py
index 1bcd4187e..8cdfb56b6 100755
--- a/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py
+++ b/media/webrtc/trunk/testing/gtest/test/gtest_xml_output_unittest.py
@@ -182,7 +182,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
day=int(match.group(3)), hour=int(match.group(4)),
minute=int(match.group(5)), second=int(match.group(6)))
- time_delta = abs(datetime.datetime.now() - date_time_from_xml)
+ time_delta = abs(datetime.datetime.utcnow() - date_time_from_xml)
# timestamp value should be near the current local time
self.assertTrue(time_delta < datetime.timedelta(seconds=600),
'time_delta is %s' % time_delta)
diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h
index df6172f31..c875e3a8c 100644
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -562,9 +562,7 @@
# define MOZ_HAVE_REF_QUALIFIERS
#elif defined(__GNUC__)
# include "mozilla/Compiler.h"
-# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 1)
-# define MOZ_HAVE_REF_QUALIFIERS
-# endif
+# define MOZ_HAVE_REF_QUALIFIERS
#endif
#endif /* __cplusplus */
diff --git a/mfbt/Compiler.h b/mfbt/Compiler.h
index 1bd34d329..a4fb4b5f8 100644
--- a/mfbt/Compiler.h
+++ b/mfbt/Compiler.h
@@ -26,8 +26,8 @@
# define MOZ_GCC_VERSION_AT_MOST(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \
<= ((major) * 10000 + (minor) * 100 + (patchlevel)))
-# if !MOZ_GCC_VERSION_AT_LEAST(4, 8, 0)
-# error "mfbt (and Gecko) require at least gcc 4.8 to build."
+# if !MOZ_GCC_VERSION_AT_LEAST(4, 9, 0)
+# error "mfbt (and Goanna) require at least gcc 4.9 to build."
# endif
#elif defined(_MSC_VER)
diff --git a/mobile/android/config/version.txt b/mobile/android/config/version.txt
new file mode 100644
index 000000000..4e9247c69
--- /dev/null
+++ b/mobile/android/config/version.txt
@@ -0,0 +1 @@
+52.6.0
diff --git a/mobile/android/config/version_display.txt b/mobile/android/config/version_display.txt
new file mode 100644
index 000000000..4e9247c69
--- /dev/null
+++ b/mobile/android/config/version_display.txt
@@ -0,0 +1 @@
+52.6.0
diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh
index b4215ca89..f2c7ec113 100644
--- a/mobile/android/confvars.sh
+++ b/mobile/android/confvars.sh
@@ -5,8 +5,8 @@
MOZ_APP_BASENAME=Fennec
MOZ_APP_VENDOR=Mozilla
-MOZ_APP_VERSION=$FIREFOX_VERSION
-MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION_DISPLAY
+MOZ_APP_VERSION=`cat ${_topsrcdir}/$MOZ_BUILD_APP/config/version.txt`
+MOZ_APP_VERSION_DISPLAY=`cat ${_topsrcdir}/$MOZ_BUILD_APP/config/version_display.txt`
MOZ_APP_UA_NAME=Firefox
MOZ_BRANDING_DIRECTORY=mobile/android/branding/unofficial
diff --git a/mobile/android/extensions/flyweb/install.rdf.in b/mobile/android/extensions/flyweb/install.rdf.in
index 76430412c..dfa7a4262 100644
--- a/mobile/android/extensions/flyweb/install.rdf.in
+++ b/mobile/android/extensions/flyweb/install.rdf.in
@@ -18,9 +18,9 @@
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
- <em:id>{aa3c5121-dab2-40e2-81ca-7ea25febc110}</em:id>
- <em:minVersion>@FIREFOX_VERSION@</em:minVersion>
- <em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
+ <em:id>@MOZ_APP_ID@</em:id>
+ <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
+ <em:maxVersion>@MOZ_APP_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>
diff --git a/mobile/android/extensions/flyweb/moz.build b/mobile/android/extensions/flyweb/moz.build
index f453297e5..975e109e5 100644
--- a/mobile/android/extensions/flyweb/moz.build
+++ b/mobile/android/extensions/flyweb/moz.build
@@ -4,6 +4,9 @@
# 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/.
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+DEFINES['MOZ_APP_ID'] = CONFIG['MOZ_APP_ID']
+
FINAL_TARGET_FILES.features['flyweb@mozilla.org'] += [
'bootstrap.js'
]
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 72eb8524e..321299822 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1117,6 +1117,9 @@ pref("print.print_via_parent", false);
// in a document.
pref("extensions.spellcheck.inline.max-misspellings", 500);
+// Predefined convenience pref for overriding the dictionary
+pref("spellchecker.dictionary.override", "");
+
// Prefs used by libeditor. Prefs specific to seamonkey composer
// belong in comm-central/editor/ui/composer.js
@@ -1142,6 +1145,7 @@ pref("dom.disable_window_open_feature.menubar", false);
pref("dom.disable_window_open_feature.resizable", true);
pref("dom.disable_window_open_feature.minimizable", false);
pref("dom.disable_window_open_feature.status", true);
+pref("dom.disable_window_showModalDialog", true);
pref("dom.allow_scripts_to_close_windows", false);
@@ -1258,6 +1262,7 @@ pref("javascript.options.mem.max", -1);
pref("javascript.options.mem.gc_per_zone", true);
pref("javascript.options.mem.gc_incremental", true);
pref("javascript.options.mem.gc_incremental_slice_ms", 10);
+pref("javascript.options.mem.gc_generational", true);
pref("javascript.options.mem.gc_compacting", true);
pref("javascript.options.mem.log", false);
pref("javascript.options.mem.notify", false);
@@ -4392,7 +4397,7 @@ pref("image.decode-immediately.enabled", false);
pref("image.downscale-during-decode.enabled", true);
// The default Accept header sent for images loaded over HTTP(S)
-pref("image.http.accept", "*/*");
+pref("image.http.accept", "image/webp,image/png,image/*;q=0.8,*/*;q=0.5");
// The threshold for inferring that changes to an <img> element's |src|
// attribute by JavaScript represent an animation, in milliseconds. If the |src|
@@ -4440,10 +4445,17 @@ pref("image.mem.surfacecache.discard_factor", 1);
// automatically determined based on the system's number of cores.
pref("image.multithreaded_decoding.limit", -1);
+// Whether we attempt to decode WebP images or not.
+pref("image.webp.enabled", true);
+
// Limit for the canvas image cache. 0 means we don't limit the size of the
// cache.
pref("canvas.image.cache.limit", 0);
+// Allow track-fobics to deliberately poison canvas data for
+// toDataURL() and getImageData()
+pref("canvas.poisondata", false);
+
// WebGL prefs
#ifdef ANDROID
// Disable MSAA on mobile.
diff --git a/netwerk/base/security-prefs.js b/netwerk/base/security-prefs.js
index 9f42745f7..329a4c6b7 100644
--- a/netwerk/base/security-prefs.js
+++ b/netwerk/base/security-prefs.js
@@ -17,6 +17,7 @@ pref("security.ssl.false_start.require-npn", false);
pref("security.ssl.enable_npn", true);
pref("security.ssl.enable_alpn", true);
+// TLS 1.0-1.2 cipher suites
pref("security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", true);
pref("security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", true);
pref("security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256", true);
@@ -27,11 +28,20 @@ pref("security.ssl3.ecdhe_rsa_aes_128_sha", true);
pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", true);
pref("security.ssl3.ecdhe_rsa_aes_256_sha", true);
pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", true);
-pref("security.ssl3.dhe_rsa_aes_128_sha", true);
-pref("security.ssl3.dhe_rsa_aes_256_sha", true);
+pref("security.ssl3.dhe_rsa_camellia_256_sha", true);
+pref("security.ssl3.dhe_rsa_camellia_128_sha", true);
+pref("security.ssl3.rsa_aes_256_gcm_sha384", true);
+pref("security.ssl3.rsa_aes_256_sha256", true);
+pref("security.ssl3.rsa_camellia_128_sha", true);
+pref("security.ssl3.rsa_camellia_256_sha", true);
pref("security.ssl3.rsa_aes_128_sha", true);
pref("security.ssl3.rsa_aes_256_sha", true);
-pref("security.ssl3.rsa_des_ede3_sha", true);
+// Weak / deprecated
+pref("security.ssl3.dhe_rsa_aes_256_sha", false);
+pref("security.ssl3.dhe_rsa_aes_128_sha", false);
+pref("security.ssl3.rsa_aes_128_gcm_sha256", false);
+pref("security.ssl3.rsa_aes_128_sha256", false);
+pref("security.ssl3.rsa_des_ede3_sha", false);
pref("security.content.signature.root_hash",
"97:E8:BA:9C:F1:2F:B3:DE:53:CC:42:A4:E6:57:7E:D6:4D:F4:93:C2:47:B4:14:FE:A0:36:81:8D:38:23:56:0E");
diff --git a/netwerk/mime/nsMimeTypes.h b/netwerk/mime/nsMimeTypes.h
index 098499a14..215d20507 100644
--- a/netwerk/mime/nsMimeTypes.h
+++ b/netwerk/mime/nsMimeTypes.h
@@ -113,6 +113,7 @@
#define IMAGE_MNG "video/x-mng"
#define IMAGE_JNG "image/x-jng"
#define IMAGE_SVG_XML "image/svg+xml"
+#define IMAGE_WEBP "image/webp"
#define MESSAGE_EXTERNAL_BODY "message/external-body"
#define MESSAGE_NEWS "message/news"
diff --git a/old-configure.in b/old-configure.in
index 85a4157e3..580b0a669 100644
--- a/old-configure.in
+++ b/old-configure.in
@@ -68,7 +68,7 @@ GNOMEUI_VERSION=2.2.0
GCONF_VERSION=1.2.1
STARTUP_NOTIFICATION_VERSION=0.8
DBUS_VERSION=0.60
-SQLITE_VERSION=3.17.0
+SQLITE_VERSION=3.19.3
dnl Set various checks
dnl ========================================================
@@ -839,18 +839,6 @@ if test -z "$MOZILLA_VERSION"; then
AC_MSG_ERROR([failed to read version info from milestone file])
fi
-dnl Get version of various core apps from the version files.
-FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
-FIREFOX_VERSION_DISPLAY=`cat $_topsrcdir/browser/config/version_display.txt`
-
-if test -z "$FIREFOX_VERSION"; then
- AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])
-fi
-
-if test -z "$FIREFOX_VERSION_DISPLAY"; then
- AC_MSG_ERROR([FIREFOX_VERSION_DISPLAY is unexpectedly blank.])
-fi
-
AC_DEFINE_UNQUOTED(MOZILLA_VERSION,"$MOZILLA_VERSION")
AC_DEFINE_UNQUOTED(MOZILLA_VERSION_U,$MOZILLA_VERSION)
AC_DEFINE_UNQUOTED(MOZILLA_UAVERSION,"$MOZILLA_UAVERSION")
@@ -5483,8 +5471,6 @@ AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
AC_SUBST(MOZ_APP_VERSION)
AC_SUBST(MOZ_APP_VERSION_DISPLAY)
AC_SUBST(MOZ_APP_MAXVERSION)
-AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
-AC_SUBST(FIREFOX_VERSION)
AC_SUBST(MOZ_UA_OS_AGNOSTIC)
if test -n "$MOZ_UA_OS_AGNOSTIC"; then
AC_DEFINE(MOZ_UA_OS_AGNOSTIC)
diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp
index 8882ec593..9cf888f69 100644
--- a/parser/htmlparser/nsExpatDriver.cpp
+++ b/parser/htmlparser/nsExpatDriver.cpp
@@ -338,6 +338,9 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver)
NS_IMPL_CYCLE_COLLECTION(nsExpatDriver, mSink, mExtendedSink)
+// We store the tagdepth in a Uint8, so make sure the limit fits in a Uint8.
+PR_STATIC_ASSERT(MAX_XML_TREE_DEPTH <= UINT8_MAX);
+
nsExpatDriver::nsExpatDriver()
: mExpatParser(nullptr),
mInCData(false),
@@ -345,6 +348,7 @@ nsExpatDriver::nsExpatDriver()
mInExternalDTD(false),
mMadeFinalCallToExpat(false),
mIsFinalChunk(false),
+ mTagDepth(0),
mInternalState(NS_OK),
mExpatBuffered(0),
mCatalogData(nullptr),
@@ -359,7 +363,7 @@ nsExpatDriver::~nsExpatDriver()
}
}
-nsresult
+void
nsExpatDriver::HandleStartElement(const char16_t *aValue,
const char16_t **aAtts)
{
@@ -377,13 +381,16 @@ nsExpatDriver::HandleStartElement(const char16_t *aValue,
}
if (mSink) {
+ if (++mTagDepth == MAX_XML_TREE_DEPTH) {
+ MaybeStopParser(NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP);
+ return;
+ }
+
nsresult rv = mSink->
HandleStartElement(aValue, aAtts, attrArrayLength,
XML_GetCurrentLineNumber(mExpatParser));
MaybeStopParser(rv);
}
-
- return NS_OK;
}
nsresult
@@ -395,6 +402,7 @@ nsExpatDriver::HandleEndElement(const char16_t *aValue)
if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = mSink->HandleEndElement(aValue);
+ --mTagDepth;
MaybeStopParser(rv);
}
diff --git a/parser/htmlparser/nsExpatDriver.h b/parser/htmlparser/nsExpatDriver.h
index 1bf022ade..0d62bd09d 100644
--- a/parser/htmlparser/nsExpatDriver.h
+++ b/parser/htmlparser/nsExpatDriver.h
@@ -16,6 +16,9 @@
#include "nsIParser.h"
#include "nsCycleCollectionParticipant.h"
+// Tree depth limit for XML-based files (xml/svg/etc.)
+#define MAX_XML_TREE_DEPTH 200
+
class nsIExpatSink;
class nsIExtendedExpatSink;
struct nsCatalogData;
@@ -37,7 +40,7 @@ public:
const char16_t *aBase,
const char16_t *aSystemId,
const char16_t *aPublicId);
- nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts);
+ void HandleStartElement(const char16_t *aName, const char16_t **aAtts);
nsresult HandleEndElement(const char16_t *aName);
nsresult HandleCharacterData(const char16_t *aCData, const uint32_t aLength);
nsresult HandleComment(const char16_t *aName);
@@ -119,6 +122,8 @@ private:
// Whether we're sure that we won't be getting more buffers to parse from
// Necko
bool mIsFinalChunk;
+
+ uint8_t mTagDepth;
nsresult mInternalState;
diff --git a/python/mock-1.0.0/tests/testhelpers.py b/python/mock-1.0.0/tests/testhelpers.py
index e788da844..f41023c37 100644
--- a/python/mock-1.0.0/tests/testhelpers.py
+++ b/python/mock-1.0.0/tests/testhelpers.py
@@ -41,21 +41,21 @@ class AnyTest(unittest2.TestCase):
def test_any_and_datetime(self):
mock = Mock()
- mock(datetime.now(), foo=datetime.now())
+ mock(datetime.utcnow(), foo=datetime.utcnow())
mock.assert_called_with(ANY, foo=ANY)
def test_any_mock_calls_comparison_order(self):
mock = Mock()
- d = datetime.now()
+ d = datetime.utcnow()
class Foo(object):
def __eq__(self, other):
return False
def __ne__(self, other):
return True
- for d in datetime.now(), Foo():
+ for d in datetime.utcnow(), Foo():
mock.reset_mock()
mock(d, foo=d, bar=d)
diff --git a/python/mozbuild/mozbuild/android_version_code.py b/python/mozbuild/mozbuild/android_version_code.py
index 69ce22b8e..6d9445c63 100644
--- a/python/mozbuild/mozbuild/android_version_code.py
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -79,7 +79,7 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
'''
def hours_since_cutoff(buildid):
# The ID is formatted like YYYYMMDDHHMMSS (using
- # datetime.now().strftime('%Y%m%d%H%M%S'); see build/variables.py).
+ # datetime.utcnow().strftime('%Y%m%d%H%M%S'); see build/variables.py).
# The inverse function is time.strptime.
# N.B.: the time module expresses time as decimal seconds since the
# epoch.
diff --git a/python/mozbuild/mozbuild/jar.py b/python/mozbuild/mozbuild/jar.py
index d40751b69..98333482b 100644
--- a/python/mozbuild/mozbuild/jar.py
+++ b/python/mozbuild/mozbuild/jar.py
@@ -460,7 +460,7 @@ class JarMaker(object):
pp.setMarker('%')
pp.out = outf
pp.do_include(inf)
- pp.failUnused(realsrc)
+ pp.warnUnused(realsrc)
outf.close()
inf.close()
return
diff --git a/python/mozbuild/mozbuild/preprocessor.py b/python/mozbuild/mozbuild/preprocessor.py
index e8aac7057..2e7eed1ca 100644
--- a/python/mozbuild/mozbuild/preprocessor.py
+++ b/python/mozbuild/mozbuild/preprocessor.py
@@ -316,20 +316,13 @@ class Preprocessor:
if defines:
self.context.update(defines)
- def failUnused(self, file):
+ def warnUnused(self, file):
msg = None
if self.actionLevel == 0 and not self.silenceMissingDirectiveWarnings:
- msg = 'no preprocessor directives found'
+ sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file))
elif self.actionLevel == 1:
- msg = 'no useful preprocessor directives found'
- if msg:
- class Fake(object): pass
- fake = Fake()
- fake.context = {
- 'FILE': file,
- 'LINE': None,
- }
- raise Preprocessor.Error(fake, msg, None)
+ sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file))
+ pass
def setMarker(self, aMarker):
"""
@@ -385,7 +378,7 @@ class Preprocessor:
self.out = output
self.do_include(input, False)
- self.failUnused(input.name)
+ self.warnUnused(input.name)
if depfile:
mk = Makefile()
diff --git a/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py b/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
index 2ef93792b..c58fde86e 100644
--- a/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
@@ -313,7 +313,7 @@ class LinuxToolchainTest(BaseToolchainTest):
'/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64_LINUX,
'/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64_LINUX,
}
- GCC_4_7_RESULT = ('Only GCC 4.8 or newer is supported '
+ GCC_4_7_RESULT = ('Only GCC 4.9 or newer is supported '
'(found version 4.7.3).')
GXX_4_7_RESULT = GCC_4_7_RESULT
GCC_4_9_RESULT = CompilerResult(
diff --git a/python/psutil/docs/conf.py b/python/psutil/docs/conf.py
index 9fa163b65..ad880110f 100644
--- a/python/psutil/docs/conf.py
+++ b/python/psutil/docs/conf.py
@@ -18,7 +18,7 @@ import os
PROJECT_NAME = "psutil"
AUTHOR = "Giampaolo Rodola'"
-THIS_YEAR = str(datetime.datetime.now().year)
+THIS_YEAR = str(datetime.datetime.utcnow().year)
HERE = os.path.abspath(os.path.dirname(__file__))
diff --git a/python/psutil/examples/top.py b/python/psutil/examples/top.py
index 7aebef1d4..30df417f5 100755
--- a/python/psutil/examples/top.py
+++ b/python/psutil/examples/top.py
@@ -165,7 +165,7 @@ def print_header(procs_status, num_procs):
st.sort(key=lambda x: x[:3] in ('run', 'sle'), reverse=1)
print_line(" Processes: %s (%s)" % (num_procs, ' '.join(st)))
# load average, uptime
- uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
+ uptime = datetime.utcnow() - datetime.fromtimestamp(psutil.boot_time())
av1, av2, av3 = os.getloadavg()
line = " Load average: %.2f %.2f %.2f Uptime: %s" \
% (av1, av2, av3, str(uptime).split('.')[0])
diff --git a/security/manager/ssl/nsNSSComponent.cpp b/security/manager/ssl/nsNSSComponent.cpp
index d53f846ed..1bcdcc1b0 100644
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1344,12 +1344,16 @@ static const CipherPref sCipherPrefs[] = {
{ "security.ssl3.ecdhe_ecdsa_aes_256_sha",
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true },
- { "security.ssl3.dhe_rsa_aes_128_sha",
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true },
-
+ { "security.ssl3.dhe_rsa_camellia_256_sha",
+ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, true},
{ "security.ssl3.dhe_rsa_aes_256_sha",
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true },
+ { "security.ssl3.dhe_rsa_camellia_128_sha",
+ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, true },
+ { "security.ssl3.dhe_rsa_aes_128_sha",
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true },
+
{ "security.tls13.aes_128_gcm_sha256",
TLS_AES_128_GCM_SHA256, true },
{ "security.tls13.chacha20_poly1305_sha256",
@@ -1357,12 +1361,27 @@ static const CipherPref sCipherPrefs[] = {
{ "security.tls13.aes_256_gcm_sha384",
TLS_AES_256_GCM_SHA384, true },
+ // Deprecated (RSA key exchange):
+ { "security.ssl3.rsa_aes_256_gcm_sha384",
+ TLS_RSA_WITH_AES_256_GCM_SHA384, true },
+ { "security.ssl3.rsa_aes_256_sha256",
+ TLS_RSA_WITH_AES_256_CBC_SHA256, true },
+ {"security.ssl3.rsa_camellia_128_sha",
+ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, true },
+ {"security.ssl3.rsa_camellia_256_sha",
+ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, true },
{ "security.ssl3.rsa_aes_128_sha",
- TLS_RSA_WITH_AES_128_CBC_SHA, true }, // deprecated (RSA key exchange)
+ TLS_RSA_WITH_AES_128_CBC_SHA, true },
{ "security.ssl3.rsa_aes_256_sha",
- TLS_RSA_WITH_AES_256_CBC_SHA, true }, // deprecated (RSA key exchange)
+ TLS_RSA_WITH_AES_256_CBC_SHA, true },
+
+// Expensive/deprecated/weak
+ { "security.ssl3.rsa_aes_128_gcm_sha256",
+ TLS_RSA_WITH_AES_128_GCM_SHA256, false }, // Deprecated
+ { "security.ssl3.rsa_aes_128_sha256",
+ TLS_RSA_WITH_AES_128_CBC_SHA256, false }, // Deprecated
{ "security.ssl3.rsa_des_ede3_sha",
- TLS_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (RSA key exchange, 3DES)
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA, false }, // Weak (3DES)
// All the rest are disabled
diff --git a/security/nss/gtests/google_test/gtest/test/gtest_xml_output_unittest.py b/security/nss/gtests/google_test/gtest/test/gtest_xml_output_unittest.py
index f605d4ee2..467ab1d08 100755
--- a/security/nss/gtests/google_test/gtest/test/gtest_xml_output_unittest.py
+++ b/security/nss/gtests/google_test/gtest/test/gtest_xml_output_unittest.py
@@ -192,7 +192,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
day=int(match.group(3)), hour=int(match.group(4)),
minute=int(match.group(5)), second=int(match.group(6)))
- time_delta = abs(datetime.datetime.now() - date_time_from_xml)
+ time_delta = abs(datetime.datetime.utcnow() - date_time_from_xml)
# timestamp value should be near the current local time
self.assertTrue(time_delta < datetime.timedelta(seconds=600),
'time_delta is %s' % time_delta)
diff --git a/testing/specialpowers/content/specialpowersAPI.js b/testing/specialpowers/content/specialpowersAPI.js
index ee94e84a3..8f1ff7465 100644
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1479,10 +1479,6 @@ SpecialPowersAPI.prototype = {
Cu.schedulePreciseGC(genGCCallback(callback));
},
- setGCZeal: function(zeal) {
- Cu.setGCZeal(zeal);
- },
-
isMainProcess: function() {
try {
return Cc["@mozilla.org/xre/app-info;1"].
diff --git a/toolkit/forgetaboutsite/ForgetAboutSite.jsm b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
index b8cd31ad9..5250ca75d 100644
--- a/toolkit/forgetaboutsite/ForgetAboutSite.jsm
+++ b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
@@ -126,7 +126,7 @@ this.ForgetAboutSite = {
// XXXehsan: is there a better way to do this rather than this
// hacky comparison?
catch (ex) {
- if (ex.message.indexOf("User canceled Master Password entry") == -1) {
+ if (!ex.message.includes("User canceled Master Password entry")) {
throw ex;
}
}
diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js
index 10eb1d100..e23ab3f40 100644
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -2395,14 +2395,16 @@ UpdateService.prototype = {
let lastCheckCode = AUSTLMY.CHK_NO_COMPAT_UPDATE_FOUND;
updates.forEach(function(aUpdate) {
- // Ignore updates for older versions of the application and updates for
- // the same version of the application with the same build ID.
+ // Ignore updates for older versions of the applications and updates for
+ // the same version or build id of the application
if (vc.compare(aUpdate.appVersion, Services.appinfo.version) < 0 ||
- vc.compare(aUpdate.appVersion, Services.appinfo.version) == 0 &&
- aUpdate.buildID == Services.appinfo.appBuildID) {
+ (vc.compare(aUpdate.appVersion, Services.appinfo.version) == 0 &&
+ aUpdate.buildID <= Services.appinfo.appBuildID) ||
+ (vc.compare(aUpdate.appVersion, Services.appinfo.version) == 0 &&
+ aUpdate.buildID == undefined)) {
LOG("UpdateService:selectUpdate - skipping update because the " +
- "update's application version is less than the current " +
- "application version");
+ "update's application version is less than or equal to " +
+ "the current application version.");
lastCheckCode = AUSTLMY.CHK_UPDATE_PREVIOUS_VERSION;
return;
}
diff --git a/tools/docs/conf.py b/tools/docs/conf.py
index 38cea035a..1a919063f 100644
--- a/tools/docs/conf.py
+++ b/tools/docs/conf.py
@@ -42,7 +42,7 @@ templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'Mozilla Source Tree Docs'
-year = datetime.now().year
+year = datetime.utcnow().year
# Grab the version from the source tree's milestone.
# FUTURE Use Python API from bug 941299.
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
index 51a7ee0f6..5afaae319 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -536,6 +536,7 @@ static const nsExtraMimeTypeEntry extraMimeEntries[] =
{ IMAGE_TIFF, "tiff,tif", "TIFF Image" },
{ IMAGE_XBM, "xbm", "XBM Image" },
{ IMAGE_SVG_XML, "svg", "Scalable Vector Graphics" },
+ { IMAGE_WEBP, "webp", "WebP Image" },
{ MESSAGE_RFC822, "eml", "RFC-822 data" },
{ TEXT_PLAIN, "txt,text", "Text File" },
{ TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language" },